Invoking Docker container component with MQTT message in GGv2

0

Good evening great members of the AWS Greengrass community,

I'm working with a docker container as a component in Greengrass v2. I'm trying to invoke the container by sending putting a message on an MQTT topic.

Problem

The issue that I'm facing is that the container does not seem to respond to the MQTT messages that are put in the topic, despite the component having the appropriate permissions to subscribe to the MQTT topic.

This is my configuration for the Docker container component:

{
    "RecipeFormatVersion": "2020-01-25",
    "ComponentName": "DockerContainer",
    "ComponentVersion": "1.0.7",
    "ComponentDescription": "First Docker Container component",
    "ComponentPublisher": "Ed",
    "ComponentDependencies": {
        "aws.greengrass.DockerApplicationManager": {
            "VersionRequirement": "~2.0.0"
        },
        "aws.greengrass.TokenExchangeService": {
            "VersionRequirement": "~2.0.0"
        }
    },
    "ComponentConfiguration": {
        "DefaultConfiguration": {
            "topic": "plense/dockercontainer",
            "message": "Hello World from Plense!",
            "qos": "1",
            "accessControl": {
                "aws.greengrass.ipc.mqttproxy": {
                    "dockercontainer:mqttproxy:1": {
                        "policyDescription": "Allows MQTT connection from AWS IoT Core",
                        "operations": [
                            "aws.greengrass#SubscribeToIoTCore"
                        ],
                        "resources": [
                            "plense/dockercontainer"
                        ]
                    }
                }
            }
        }
    },
    "Manifests": [
        {
            "Platform": {
                "os": "all"
            },
            "Lifecycle": {
                "run": "docker run -v {kernel:rootPath}/ipc.socket:{kernel:rootPath}/ipc.socket -e SVCUID -e AWS_GG_NUCLEUS_DOMAIN_SOCKET_FILEPATH_FOR_COMPONENT -e MQTT_TOPIC=\"{configuration:/topic}\" -e MQTT_MESSAGE=\"{configuration:/message}\" -e MQTT_QOS=\"{configuration:/qos}\" --rm 106005884410.dkr.ecr.eu-central-1.amazonaws.com/ggrepository:first_container_img7"
            },
            "Artifacts": [
                {
                    "URI": "docker:106005884410.dkr.ecr.eu-central-1.amazonaws.com/ggrepository:first_container_img7"
                }
            ]
        }
    ]
}

This is my deployment file:

{
    "targetArn": "arn:aws:iot:eu-central-1:106005884410:thing/plensepi00004",
    "components": {
        "aws.greengrass.Cli": {
            "componentVersion": "2.12.1",
            "configurationUpdate": {
                "merge": "{\"AuthorizedPosixGroups\":\"ggc_group,plense\"}"
            }
        },
        "aws.greengrass.LocalDebugConsole": {
            "componentVersion": "2.4.1"
        },
        "aws.greengrass.LogManager": {
            "componentVersion": "2.3.7",
            "configurationUpdate": {}
        },
        "DockerContainer": {
            "componentVersion": "1.0.7",
            "configurationUpdate": {
                "reset": [
                    ""
                ]
            }
        }
    }
}

This is the code for the actual docker container:

import threading
import traceback
from datetime import datetime
import awsiot.greengrasscoreipc.clientv2 as clientV2

ipc_client = clientV2.GreengrassCoreIPCClientV2()                    

topic = 'plense/dockercontainer'
qos = '1'

def on_stream_event(event):
    try:
        topic_name = event.message.topic_name
        message = str(event.message.payload, 'utf-8')
        print(f'Received new message on topic {topic_name}: {message}')

    except:
        traceback.print_exc()

def on_stream_error(error):
    # Return True to close stream, False to keep stream open.
    return True  

def on_stream_closed():
    pass

def main():
    _, connection = ipc_client.subscribe_to_iot_core(
        topic_name=topic,
        qos=qos, 
        on_stream_event=on_stream_event,
        on_stream_error=on_stream_error,
        on_stream_closed=on_stream_closed
    )
    print('Successfully subscribed to start experiment: ' + topic)
    
    # Keep the main thread alive, or the process will exit.
    event = threading.Event()
    event.wait()

    # To stop subscribing, close the operation stream.
    connection.close()
    ipc_client.close()

if __name__ == "__main__":   
    main()

This is the actual logs from the docker container

2024-02-22T17:12:50.139Z [INFO] (pool-3-thread-35) DockerContainer: shell-runner-start. {scriptName=services.DockerContainer.lifecycle.run, serviceName=DockerContainer, currentState=STARTING, command=["docker run -v /greengrass/v2/ipc.socket:/greengrass/v2/ipc.socket -e SVCUID -e..."]}

As you can see, it seems that the container is not doing anything, i.e. print(f'Received new message on topic {topic_name}: {message}'), when a message is put to the IoTCore MQTT message queue.

I would appreciate any support and guidance in the process.

Hope to hear back soon Ed

  • What logs do you see? Do you see Successfully subscribed to start experiment? Use flush in print, or disable python buffering to avoid confusion: https://docs.aws.amazon.com/greengrass/v2/developerguide/troubleshooting.html#python-component-no-log-output

  • Thank you for your response Michael,

    Flushing the printing messages actually helped me print the messages for troubleshooting purposes when the container component is running.

    I am just a bit confused as of why I have to do it for containers, and not for native components, for instance.

    Best, Ed

  • Hi, the python buffering behavior isn't specific to docker or Greengrass it is just how python chooses to interact with the OS by default. I'm glad that you were able to get it working.

Ed
asked 2 months ago106 views
No Answers

You are not logged in. Log in to post an answer.

A good answer clearly answers the question and provides constructive feedback and encourages professional growth in the question asker.

Guidelines for Answering Questions