Skip to content

Commit

Permalink
greengrass-lite images added - initial commit
Browse files Browse the repository at this point in the history
note that this is still WIP!
  • Loading branch information
thomas-roos committed Nov 28, 2024
1 parent 9d95e11 commit fbc3019
Show file tree
Hide file tree
Showing 55 changed files with 2,426 additions and 48 deletions.
133 changes: 133 additions & 0 deletions .github/workflows/build-gg-artifacts/ec2/create-ec2-ami.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,133 @@
#!/usr/bin/env bash
# Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
# SPDX-License-Identifier: MIT-0
set -ex
[ "$DEBUG" == 'true' ] && set -x

ARGC=$#
if [ $ARGC -lt 3 ]; then
echo "ERROR: Please inform import bucket name as first argument and AMI disk size in GB as second, IMAGE_NAME as third and MACHINE_NAME as last."
echo "E.g.:"
echo "$0 my-test-bucket 4 core-image-minimal aws-ec2-arm64"
exit 1
fi
IMPORT_BUCKET_NAME=$1
AMI_DISK_SIZE_GB=$2
IMAGE_NAME=$3
MACHINE_NAME=$4

# validation steps
# AMI_DISK_SIZE_GB
re='^[0-9]+$'
if ! [[ $AMI_DISK_SIZE_GB =~ $re ]] ; then
echo "AMI_DISK_SIZE needs to be a number only without unit. E.g. '4'." >&2
exit 1
fi

#IMG_DIR=$(bitbake-getvar --value -q DEPLOY_DIR_IMAGE)

#TESTDATA_JSON="${IMG_DIR}/${IMAGE_NAME}-${MACHINE_NAME}.rootfs.testdata.json"
TESTDATA_JSON="${IMAGE_NAME}-${MACHINE_NAME}.rootfs.testdata.json"

DISTRO=$(jq -r '.DISTRO' $TESTDATA_JSON)
DISTRO_CODENAME=$(jq -r '.DISTRO_CODENAME' $TESTDATA_JSON)
DISTRO_NAME=$(jq -r '.DISTRO_NAME' $TESTDATA_JSON)
DISTRO_VERSION=$(jq -r '.DISTRO_VERSION' $TESTDATA_JSON)
BUILDNAME=$(jq -r '.BUILDNAME' $TESTDATA_JSON)
TARGET_ARCH=$(jq -r '.TARGET_ARCH' $TESTDATA_JSON)
# IMAGE_NAME=$(jq -r '.IMAGE_NAME' $TESTDATA_JSON)
IMAGE_ROOTFS_SIZE=$(jq -r '.IMAGE_ROOTFS_SIZE' $TESTDATA_JSON)

echo IMG_DIR=$IMG_DIR
echo DISTRO=$DISTRO
echo DISTRO_CODENAME=$DISTRO_CODENAME
echo DISTRO_NAME=$DISTRO_NAME
echo DISTRO_VERSION=$DISTRO_VERSION
echo BUILDNAME=$BUILDNAME
echo TARGET_ARCH=$TARGET_ARCH
echo IMAGE_ROOTFS_SIZE=$IMAGE_ROOTFS_SIZE
echo AMI_DISK_SIZE_GB=$AMI_DISK_SIZE_GB

echo "Pushing image ${IMAGE_NAME}.wic.vhd to s3://${IMPORT_BUCKET_NAME}"
#aws s3 cp ${IMG_DIR}/${IMAGE_NAME}.wic.vhd s3://${IMPORT_BUCKET_NAME}
aws s3 cp ${IMAGE_NAME}.wic.vhd s3://${IMPORT_BUCKET_NAME}

cat <<EOF > image-import.json
{
"Description": "yocto image",
"Format": "vhd",
"UserBucket": {
"S3Bucket": "${IMPORT_BUCKET_NAME}",
"S3Key": "${IMAGE_NAME}.wic.vhd"
}
}
EOF
echo "Importing image file into snapshot "
IMPORT_TASK_ID=$(aws ec2 import-snapshot --disk-container "file://image-import.json" | jq -r '.ImportTaskId')

IMPORT_STATUS=$(aws ec2 describe-import-snapshot-tasks --import-task-ids $IMPORT_TASK_ID | jq -r '.ImportSnapshotTasks[].SnapshotTaskDetail.Status')
x=0
# rm image-import.json
while [ "$IMPORT_STATUS" = "active" ] && [ $x -lt 120 ]
do
IMPORT_STATUS=$(aws ec2 describe-import-snapshot-tasks --import-task-ids $IMPORT_TASK_ID | jq -r '.ImportSnapshotTasks[].SnapshotTaskDetail.Status')
IMPORT_STATUS_MSG=$(aws ec2 describe-import-snapshot-tasks --import-task-ids $IMPORT_TASK_ID | jq -r '.ImportSnapshotTasks[].SnapshotTaskDetail.StatusMessage')
echo "Import Status: ${IMPORT_STATUS} / ${IMPORT_STATUS_MSG}"
x=$(( $x + 1 ))
sleep 15
done
if [ $x -eq 120 ]; then
echo "ERROR: Import task taking too long, exiting..."; exit 1;
elif [ "$IMPORT_STATUS" = "completed" ]; then
echo "Import completed Successfully"
else
echo "Import Failed, exiting"; exit 2;
fi

SNAPSHOT_ID=$(aws ec2 describe-import-snapshot-tasks --import-task-ids $IMPORT_TASK_ID | jq -r '.ImportSnapshotTasks[].SnapshotTaskDetail.SnapshotId')

aws ec2 wait snapshot-completed --snapshot-ids $SNAPSHOT_ID

if [[ "$TARGET_ARCH" == "x86_64" ]]; then
ARCHITECTURE="x86_64"
elif [[ "$TARGET_ARCH" == "aarch64" ]]; then
ARCHITECTURE="arm64"
else
echo "Architecture not supported"
exit 1
fi
DESCRIPTION=$(echo "DISTRO=$DISTRO;DISTRO_CODENAME=$DISTRO_CODENAME;DISTRO_NAME=$DISTRO_NAME;DISTRO_VERSION=$DISTRO_VERSION;BUILDNAME=$BUILDNAME;TARGET_ARCH=$ARCHITECTURE;IMAGE_NAME=$IMAGE_NAME" | cut -c -255)

cat <<EOF > register-ami.json
{
"Architecture": "$ARCHITECTURE",
"BlockDeviceMappings": [
{
"DeviceName": "/dev/sda1",
"Ebs": {
"DeleteOnTermination": true,
"SnapshotId": "$SNAPSHOT_ID",
"VolumeSize": ${AMI_DISK_SIZE_GB},
"VolumeType": "gp2"
}
}
],
"Description": "$DESCRIPTION",
"RootDeviceName": "/dev/sda1",
"BootMode": "uefi",
"VirtualizationType": "hvm",
"EnaSupport": true
}
EOF

AMI_NAME=$(echo "${IMAGE_NAME}-${DISTRO}-${DISTRO_CODENAME}-${DISTRO_VERSION}-${BUILDNAME}-${ARCHITECTURE}" | cut -c -128 | sed -e s/+/-/g)
IMAGE_ID=$(aws ec2 describe-images --filters Name=name,Values=${AMI_NAME} | jq -r '.Images[].ImageId')
if [ "$IMAGE_ID" != "" ]; then
echo "Deregistering existing image $IMAGE_ID"
aws ec2 deregister-image --image-id ${IMAGE_ID} 2>&1 > /dev/null
fi
echo "Registering AMI with Snapshot $SNAPSHOT_ID"
AMI_ID=$(aws ec2 register-image --name ${AMI_NAME} --cli-input-json="file://register-ami.json" | jq -r '.ImageId')
echo "AMI name: $AMI_NAME"
echo "AMI ID: $AMI_ID"
rm register-ami.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,123 @@
AWS IoT Greengrass is software that extends cloud capabilities to local
devices. This enables devices to collect and analyze data closer to the
source of information, react autonomously to local events, and communicate
securely with each other on local networks. Local devices can also
communicate securely with AWS IoT Core and export IoT data to the AWS Cloud.
AWS IoT Greengrass developers can use AWS Lambda functions and prebuilt
connectors to create serverless applications that are deployed to devices
for local execution.

AWS Greengrass Lite is the AWS IoT Greengrass runtime for constrained devices.

The Greengrass Lite nucleus provides a smaller alternative to the
Classic nucleus for Greengrass v2 deployments.

Greengrass Lite aims to maintain compatibility with the Classic nucleus,
and implements a subset of its functionality.

This zip file contains a demo image that allow you to start quick with
AWS Greengrass. The image is build to work on Raspberry PI 3,4,5 as it is 64bit.

For the latest version of this image look here:
https://github.com/aws4embeddedlinux/meta-aws-demos/releases

For other installation possibilities look here:
https://github.com/aws-greengrass/aws-greengrass-lite

This image has been build from this source:
{{ VERSION_LINK }}


###############################################################################
#
# INSTALLATION
#
###############################################################################

1. Download rpi imager for your OS (mac, win, linux)
https://www.raspberrypi.com/documentation/computers/getting-started.html#raspberry-pi-imager

2. Select “use custom img” and flash demo image contained in this zip file
on your SD-Card. The RPI imager auto rejects the SD card after it completes flashing the image,
you need to uncheck this option or need to plug in again to transfer the unzipped connection kit.

3. Mount the boot fat partition and copy Connection Kit Zip onto it.
- This needs to be done after you flashed your SD-Card. (Step 2)
- This is done depending on your OS in Explorer, nemo, bash, Finder.
- It is the only fat partition on the sd card

4a) You can configure the ethernet adapter ip address by editing the cmdline.txt
file on the fat partition to append eg.: ip=192.168.0.69::192.168.0.1:255.255.255.0:rpi:eth0:off

4b) You can create a wpa_supplicant.conf file in the fat partition to configure your WIFI.
It uses this https://linux.die.net/man/5/wpa_supplicant.conf format.

network={
ssid="<YOUR NETWORK NAME>"
psk="<YOUR NETWORK PASSWORD>"
}

4c) You can create a wlan.network file in the fat partition to do the ip configuration of your wlan,
default is this, DHCP. It uses this https://www.freedesktop.org/software/systemd/man/latest/systemd.network.html
format.

[Match]
Name=wl*

[Network]
DHCP=ipv4

[DHCP]
RouteMetric=20
ClientIdentifier=mac


static example:

[Match]
Name=wl*

[Network]
DHCP=no
Address=192.168.0.123/24
Gateway=192.168.0.1
DNS=8.8.8.8 8.8.4.4


5. Unmount, remove sd-card, put in Raspberry Pi and boot.

6. Password for "root" user is empty. Please note that this can be a security risk and should be changed
when using device in a public environment! SSH is enabled by default to connect over the network!
You can use the thing name to connect to the device via ssh, this is set as hostname,
and annouced by mdns. Note that underscores in a thing name will be removed!

Login: root
Password:

7. When logged in you can check the status of the installation by running
systemctl status greengrass-lite


###############################################################################
#
# LOCAL COMPONENT DEPLOYMENT HELLO WORLD (component included)
#
###############################################################################

To deploy a local component, run this on your device:

sudo -u ggc_user ggl-cli deploy \
--recipe-dir /usr/components/recipes \
--artifacts-dir /usr/components/artifacts \
--add-component com.example.LiteHelloWorld=0.1.0

Check after successful deployment:
journalctl -f -u \
ggl.com.example.LiteHelloWorld.servicernalctl \
-f -u ggl.com.example.LiteHelloWorld.service

###############################################################################
#
# LICENSE
#
###############################################################################
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
AWS IoT Greengrass is software that extends cloud capabilities to local
devices. This enables devices to collect and analyze data closer to the
source of information, react autonomously to local events, and communicate
securely with each other on local networks. Local devices can also
communicate securely with AWS IoT Core and export IoT data to the AWS Cloud.
AWS IoT Greengrass developers can use AWS Lambda functions and prebuilt
connectors to create serverless applications that are deployed to devices
for local execution.

This zip file contains a demo image that allow you to start quick with
AWS Greengrass. The image is build to work on Raspberry PI 3,4,5 as it is 64bit.

For the latest version of this image look here:
https://github.com/aws4embeddedlinux/meta-aws-demos/releases

For other installation possibilities look here:
https://github.com/aws-greengrass/aws-greengrass-lite

This image has been build from this source:
{{ VERSION_LINK }}


###############################################################################
#
# INSTALLATION
#
###############################################################################

1. Download rpi imager for your OS (mac, win, linux)
https://www.raspberrypi.com/documentation/computers/getting-started.html#raspberry-pi-imager

2. Select “use custom img” and flash demo image contained in this zip file
on your SD-Card. The RPI imager auto rejects the SD card after it completes flashing the image,
you need to uncheck this option or need to plug in again to transfer the unzipped connection kit.

3. Mount the boot fat partition and copy Connection Kit Zip onto it.
- This needs to be done after you flashed your SD-Card. (Step 2)
- This is done depending on your OS in Explorer, nemo, bash, Finder.
- It is the only fat partition on the sd card

4a) You can configure the ethernet adapter ip address by editing the cmdline.txt
file on the fat partition to append eg.: ip=192.168.0.69::192.168.0.1:255.255.255.0:rpi:eth0:off

4b) You can create a wpa_supplicant.conf file in the fat partition to configure your WIFI.
It uses this https://linux.die.net/man/5/wpa_supplicant.conf format.

network={
ssid="<YOUR NETWORK NAME>"
psk="<YOUR NETWORK PASSWORD>"
}

4c) You can create a wlan.network file in the fat partition to do the ip configuration of your wlan,
default is this, DHCP. It uses this https://www.freedesktop.org/software/systemd/man/latest/systemd.network.html
format.

[Match]
Name=wl*

[Network]
DHCP=ipv4

[DHCP]
RouteMetric=20
ClientIdentifier=mac


static example:

[Match]
Name=wl*

[Network]
DHCP=no
Address=192.168.0.123/24
Gateway=192.168.0.1
DNS=8.8.8.8 8.8.4.4


5. Unmount, remove sd-card, put in Raspberry Pi and boot.

6. Password for "root" user is empty. Please note that this can be a security risk and should be changed
when using device in a public environment! SSH is enabled by default to connect over the network!
You can use the thing name to connect to the device via ssh, this is set as hostname,
and annouced by mdns. Note that underscores in a thing name will be removed!

Login: root
Password:

7. When logged in you can check the status of the installation by running
systemctl status greengrass


###############################################################################
#
# LICENSE
#
###############################################################################
17 changes: 17 additions & 0 deletions .github/workflows/build-gg-artifacts/readme-license.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
Third Party Licenses: The demo images include third-party libraries and software
that are subject to respective licenses that can be found inside the image in
the /usr/share/common-licenses directory. It is your responsibility to review
those licenses to make sure that you are accepting of and compliant with the
terms and conditions of those licenses for your use case.

The source code to build demo images is available under the MIT license
(SPDX-License-Identifier: MIT) and can be downloaded here:
https://github.com/aws4embeddedlinux/meta-aws-demos/releases.

THE DEMO IMAGES ARE EXPERIMENTAL AND ARE NOT INTENDED FOR PRODUCTION USE. AS
SUCH THE IMAGES ARE PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL AMAZON OR ANY OF
AMAZON’S AFFILIATES BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE IMAGES OR THE USE OR OTHER DEALINGS IN THE IMAGES.
Loading

0 comments on commit fbc3019

Please sign in to comment.