如何从boto3ECS EXECUTE_COMMAND获得输出? [英] How can I get output from boto3 ecs execute_command?

查看:24
本文介绍了如何从boto3ECS EXECUTE_COMMAND获得输出?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个在Fargate上运行的ECS任务,我希望在该任务上运行boto3中的命令并返回输出。我可以在awscli中执行此操作。

➜ aws ecs execute-command --cluster cluster1                                                                                    
    --task abc 
    --container container1 
    --interactive 
    --command 'echo hi'    

The Session Manager plugin was installed successfully. Use the AWS CLI to start a session.

Starting session with SessionId: ecs-execute-command-0f913e47ae7801aeb
hi

Exiting session with sessionId: ecs-execute-command-0f913e47ae7801aeb.

但我无法解决如何在boto3中获取相同输出的问题。

ecs = boto3.client("ecs")
ssm = boto3.client("ssm")
exec_resp = ecs.execute_command(
    cluster=self.cluster,
    task=self.task,
    container=self.container,
    interactive=True,
    command="echo hi",
)
s_active = ssm.describe_sessions(
    State="Active",
    Filters=[
        {
            "key": "SessionId",
            "value": exec_resp["session"]["sessionId"],
        },
    ],
)
# Here I get the document for the active session.
doc_active = ssm.get_document(Name=s_active["Sessions"][0]["DocumentName"])
# Now I wait for the session to finish.
s_history = {}
done = False
while not done:
    s_history = ssm.describe_sessions(
        State="History",
        Filters=[
            {
                "key": "SessionId",
                "value": exec_resp["session"]["sessionId"],
            },
        ],
    )
    done = len(s_history["Sessions"]) > 0
doc_history = ssm.get_document(Name=s_history["Sessions"][0]["DocumentName"])

现在会话正在终止,我得到了另一个文档,但是似乎仍然没有输出。有人从这件事上得到产出了吗?如何?


对于任何前来寻求类似解决方案的人,我已经创建了一个工具来简化此任务。它叫做interloper。这在很大程度上要归功于出色的answer by Andrey

SSM

好的,基本上通过阅读推荐答案会话管理器插件source code,我想出了以下能够仅获取命令输出的简化重新实现: (您需要pip install websocket-client construct)

import json
import uuid

import boto3
import construct as c
import websocket

ecs = boto3.client("ecs")
ssm = boto3.client("ssm")
exec_resp = ecs.execute_command(
    cluster=self.cluster,
    task=self.task,
    container=self.container,
    interactive=True,
    command="ls -la /",
)

session = exec_resp['session']
connection = websocket.create_connection(session['streamUrl'])
try:
    init_payload = {
        "MessageSchemaVersion": "1.0",
        "RequestId": str(uuid.uuid4()),
        "TokenValue": session['tokenValue']
    }
    connection.send(json.dumps(init_payload))

    AgentMessageHeader = c.Struct(
        'HeaderLength' / c.Int32ub,
        'MessageType' / c.PaddedString(32, 'ascii'),
    )

    AgentMessagePayload = c.Struct(
        'PayloadLength' / c.Int32ub,
        'Payload' / c.PaddedString(c.this.PayloadLength, 'ascii')
    )

    while True:
        response = connection.recv()

        message = AgentMessageHeader.parse(response)

        if 'channel_closed' in message.MessageType:
            raise Exception('Channel closed before command output was received')

        if 'output_stream_data' in message.MessageType:
            break

finally:
    connection.close()

payload_message = AgentMessagePayload.parse(response[message.HeaderLength:])

print(payload_message.Payload)

这篇关于如何从boto3ECS EXECUTE_COMMAND获得输出?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆