- Newest
- Most votes
- Most comments
Hi flycast.
I tried installing awsiot on the pi directly but that did not solve the issue.
It's probably because Greengrass is running as a different user than what you installed the package for.
https://docs.aws.amazon.com/greengrass/v2/developerguide/develop-greengrass-components.html
The AWS IoT Greengrass Core software runs components as the system user and group, such as ggc_user and ggc_group, that you configure on the core device. This means that components have the permissions of that system user. If you use a system user without a home directory, then components can't use run commands or code that use a home directory. This means that you can't use the pip install some-library --user command to install Python packages for example. If you followed the getting started tutorial to set up your core device, then your system user doesn't have a home directory. For more information about how to configure the user and group that run components, see Configure the user that runs components.
One easy solution is to install the packages during the Install lifecycle of the recipe. See this example in the workshop.
"Lifecycle": {
"Install": "pip3 install awsiotsdk numpy",
"Run": "python3 -u {artifacts:path}/example_publisher.py"
}
Longer term, you may consider to containerize the component.
Thank you both for answering my questions. This is what I LOVE about programming today vs 1976.
Finally, I strongly recommend you add any library dependency in a separate component, which you declare as dependency to the main component. In this way you minimize the downtime of your main component when new versions are deployed. Greengrass stops the component process before executing the install script of the new version, and if you do not have any library installation instruction the install will execute faster. The library installation happens only the first time the component is deployed to the device and every time a new version of the dependency component is available.
That all makes sense to me. How is this done though? In this instance I need awsiotsdk correct? If it is needed as a component I am surprised it isn't provided already by AWS. At any rate, how would I go about creating a component of a dependency and then using it in a different private component?
Hi Flycast,
you can check how dependencies are setup in this component recipe. At line 12 there is a dependency on another private component, which also specifies the acceptable versions using semantic versioning notation (if you are not familiar with it, you can try out the notation here https://semver.npmjs.com/) . You can also specify the DependencyType
as HARD
or SOFT
. Hard dependencies cause the main component to restart in case they are updated, Soft dependencies don't and will be used only upon restart of the main component (see the documentation).
When using private components as dependencies make sure you have created the dependent component in the same account and region of the main component before deploying the main component, or the deployment will fail.
You can find more examples of ready to use, curated private components in the Greengrass Software Catalog
Cheers,
Massimiliano
As @greg_b mentioned, the issue is likely that your library get installed in the wrong location. There are two solutions:
The first, as mentioned by Greg, is to install the package via the lifecycle install script. You can use the -u
flag to install as the current user, but be aware that this might not work in case the install script runs with different privileges than the run or startup scripts. A safer option is to use a virtual environment and install the libraries in the virtual environment (https://docs.python.org/3/library/venv.html). Then, in the run or startup script, you just need to activate the virtual environment. The recommendation is to create the virtual environment in the work folder of the component (eg using via python -m venv ./venv
in the install script. You can check a recipe showing this here https://github.com/awslabs/aws-greengrass-labs-jupyterlab/blob/main/recipes/aws.greengrass.labs.jupyterlab.yaml. By using virtual environments and by keeping them in the component work folder you are also avoiding possible conflicts between libraries and library versions required by different components.
The second would be to package the necessary libraries with your artifact, but this might require that you create the artifact archive on a machine/container that is equivalent to your target device, as some libraries might be dependent on OS and/or CPU architecture.
Finally, I strongly recommend you add any library dependency in a separate component, which you declare as dependency to the main component. In this way you minimize the downtime of your main component when new versions are deployed. Greengrass stops the component process before executing the install script of the new version, and if you do not have any library installation instruction the install phase will execute faster. The library installation happens only the first time the component is deployed to the device and every time a new version of the dependency component is available.
Cheers, Massimiliano
Relevant content
- asked 9 months ago
- Accepted Answerasked 2 years ago
- Accepted Answerasked 3 years ago
- asked 2 years ago
- AWS OFFICIALUpdated 10 months ago
- AWS OFFICIALUpdated 2 years ago
- AWS OFFICIALUpdated a year ago
- AWS OFFICIALUpdated 10 months ago