diff --git a/.github/README.md b/.github/README.md new file mode 120000 index 0000000..6ca1177 --- /dev/null +++ b/.github/README.md @@ -0,0 +1 @@ +../GL-README.md \ No newline at end of file diff --git a/.github/workflows/build-images.yaml b/.github/workflows/build-images.yaml new file mode 100644 index 0000000..cf5b2ae --- /dev/null +++ b/.github/workflows/build-images.yaml @@ -0,0 +1,74 @@ +name: build-images + +on: + push: + branches: [ main ] + tags: + - '*' + pull_request: + # all branches for now while we're testing. + #branches: [ main ] + +jobs: + build: + runs-on: + labels: ubuntu-22.04-8core + + steps: + - uses: actions/checkout@v4 + + - name: install needed packages + run: | + sudo apt update + sudo apt install binfmt-support + sudo apt install qemu qemu-user-static + sudo update-binfmts --enable + + - name: Detect if release + run: | + if [[ $GITHUB_REF == refs/tags/* ]]; then + echo "IS_RELEASE=1" >> $GITHUB_ENV + else + echo "IS_RELEASE=0" >> $GITHUB_ENV + fi + + - name: Build the full images + run: | + ./dobuild.sh + + # Print output directory files + - name: List output files + run: ls -lh deploy + + - name: Upload built image + if: env.IS_RELEASE == '1' + uses: actions/upload-artifact@v3 + with: + name: rpios-image + path: ./deploy/GroundlightPi-*.img.xz + if-no-files-found: error + + - name: Upload debug artifacts + if: env.IS_RELEASE == '1' + uses: actions/upload-artifact@v3 + with: + name: debug-files + path: | + ./deploy/*.info + ./deploy/build.log + if-no-files-found: error + + release: + if: startsWith(github.ref, 'refs/tags/') + needs: [build] + runs-on: + labels: ubuntu-22.04-8core + steps: + - uses: actions/download-artifact@v3 + with: + name: rpios-image + - uses: softprops/action-gh-release@v1 + with: + files: '**/*' + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} diff --git a/.gitignore b/.gitignore index f01ee89..64c67bf 100644 --- a/.gitignore +++ b/.gitignore @@ -6,3 +6,10 @@ SKIP SKIP_IMAGES .pc *-pc + + +# +# Groundlight additions below +# +*.swp +/deleteme* diff --git a/GL-README.md b/GL-README.md new file mode 100644 index 0000000..b38ec80 --- /dev/null +++ b/GL-README.md @@ -0,0 +1,140 @@ +# Groundlight Pi-Gen: OS images for Raspberry PI with Groundlight Tools + +This repo builds OS images for Groundlight tools and applications, including the bare python SDK, +and the Monitoring Notification Server (MNS). The OS images are available in the [releases](https://github.com/groundlight/groundlight-pi-gen/releases) and can be installed with [Raspberry Pi imager](https://www.raspberrypi.com/software/). + +There are several different images available, depending on your needs, from smallest to largest: + +- **`sdk-only`** - A minimal image with just the Python SDK installed. This is the smallest image, and is suitable for running the SDK on a Raspberry Pi Zero W. It is also suitable for running the SDK on a Raspberry Pi 3 or 4, if you don't need the GUI. +- **`mns-headless`** - an image with the [Groundlight Monitoring Notification Server (MNS)](https://github.com/groundlight/monitoring-notification-server) installed for headless use. "Headless" means it runs the server, which serves HTML pages, but has no browser or GUI to use it from. You need to connect from another machine to use MNS. The MNS provides a simple way to configure cameras, Groundlight detectors, and send notifications conditions are met. +- **`desktop`** - an image with the Groundlight MNS installed, and a desktop GUI with a browser. This is appropriate for a Raspberry Pi which will have a screen attached to it. +- **`edge`** - Not available yet. The Edge Endpoint server is still too resource hungry to run on a Raspberry Pi. Please [leave a comment](https://github.com/groundlight/groundlight-pi-gen/issues/5) if you'd like to use this. + + +## Source Code + +This build system is based on [pi-gen](https://github.com/RPi-Distro/pi-gen). Refer to its [original README](/README.md) for how everything works. The (`gl-config`)[gl-config] file is the key source of control. (What is called "config" in the original.) + +Note that we're tracking the `arm64` branch, not main. (If we build off the main branch, we hit [an issue with missing `arm/v8` docker images](https://github.com/groundlight/monitoring-notification-server/issues/39) and likely others, because we make these funky machines with a 64-bit kernel, but 32-bit applications.) + +### Stages + +- **`sdk-only`** - Saved after `stage-gl1` +- **`mns-headless`** - Saved after `stage-gl2` +- **`desktop`** - Saved after `stage4` + +Refer to the [`gl-config`](./gl-config) and [`gl-config-release`](./gl-config-release) files for the how the stages are used. + + +## Building Images + +We recommend building on an ARM machine (like an m7g instance in ec2). You can build on an x86 machine, but it will take significantly longer, and it's not fast to start with. Building on ARM-powered Macs seems like a good idea, and "should" work, but isn't tested. + +### Building directly + +On the appropriate machine, run: + +``` +./dobuild.sh +``` + +This has code for both +- **local builds** which are faster, but require sudo, and maybe leak resources in a way that require rebooting the build machine. +- **docker builds** which are slower, but don't require sudo, and don't leak resources. + +To re-use the cache from docker builds, run + +``` +CONTINUE=1 ./dobuild.sh +``` + +### But it's so SLOW! + +A full build can take 10s of minutes. But partial builds get cached in a docker volume and will speed things up dramatically. Beware that the caches don't get invalidated automatically or sensibly, so it will lead to problems as you're working on it. + +Also, the best way to speed things up is to skip building stages you don't care about (e.g. `stage3` the desktop environment). You can do this without editing the `glmns-config` file with: + +``` +touch stage3/SKIP +``` + +Also, you can get a bit of a boost by skipping export of the `sdk` variant image: + +``` +touch stage-gl1/SKIP_IMAGES +``` + + +### Troubleshooting + +To start over try + +``` +CLEAN=1 ./dobuild.sh +``` + +**Unmount errors** - try `sudo mv work deleteme-work` + +## Using the images + +After ~10 minutes, and then look in the `deploy/` for a file with a name like +`image_2023-12-06-GroundlightMNS-sdk-qemu.img.xz` which will be ~1GB for now. +(See the `COMPRESSION_LEVEL` setting in (`gl-config`)[gl-config] to trade speed vs size.) + +Copy this to your laptop, and then you can burn it to an SD card using the [Raspberry Pi Image](https://github.com/raspberrypi/rpi-imager). + +TODO: set up some tests inside `qemu` that things are working. +TODO: write those tests into CI/CD actions. + + +## Running the Raspberry Pi Image with QEMU +To emulate the Raspberry Pi image with QEMU, we will first need to install the Linux kernel for QEMU on the +host machine and install other necessary packages required for QEMU to work. To do this, run + +```shell +./setup-qemu-kernel.sh +``` + +This needs to be done only once. It will download a linux kernel(v6.6.8) of 40MB. +If you haven't decompressed the image you wan to use, you can do so by running + +```shell +xz -d +``` + +To run the emulator, go ahead and run + +```shell +./rpistart.sh -i +``` + +You can SSH into it by running + +```shell +ssh -l pi localhost -p 2222 +``` + +By default, the username and password are `pi` and `raspberry` respectively. You can overrride these by setting +the following environment variables before running the `rpistart.sh` script. + +```shell +export USERNAME= +export PASSWORD= +``` + + +## What's up with this file? + +This file is called `GL-README.md` and is elevated to the github repo homepage by a symlink `.github/README.md`. + +## Merging from upstream + +Here's the process + +``` +git remote add upstream https://github.com/RPi-Distro/pi-gen +git fetch upstream +git merge upstream/arm64 +``` + +Then test test test. diff --git a/build-docker.sh b/build-docker.sh index 41e341f..56d3ed3 100755 --- a/build-docker.sh +++ b/build-docker.sh @@ -1,5 +1,5 @@ #!/usr/bin/env bash -# Note: Avoid usage of arrays as MacOS users have an older version of bash (v3.x) which does not supports arrays +# Note: Avoid usage of arrays as MacOS users have an older version of bash (v3.x) which does not support arrays set -eu DIR="$(CDPATH='' cd -- "$(dirname -- "$0")" && pwd)" @@ -38,6 +38,12 @@ do esac done +# check that CONFIG_FILE exists and is readable +if [ ! -r "${CONFIG_FILE}" ]; then + echo "Configuration file '${CONFIG_FILE}' does not exist or is not readable" + exit 1 +fi + # Ensure that the configuration file is an absolute path if test -x /usr/bin/realpath; then CONFIG_FILE=$(realpath -s "$CONFIG_FILE" || realpath "$CONFIG_FILE") diff --git a/build.sh b/build.sh index a96f4e4..d8f5e7f 100755 --- a/build.sh +++ b/build.sh @@ -3,7 +3,8 @@ # shellcheck disable=SC2119 run_sub_stage() { - log "Begin ${SUB_STAGE_DIR}" + log " " + log "---====> substage ${SUB_STAGE_DIR} <====---" pushd "${SUB_STAGE_DIR}" > /dev/null for i in {00..99}; do if [ -f "${i}-debconf" ]; then @@ -81,7 +82,9 @@ EOF run_stage(){ - log "Begin ${STAGE_DIR}" + log " " + log " --------========> STAGE: ${STAGE_DIR} <========----------" + log " " STAGE="$(basename "${STAGE_DIR}")" pushd "${STAGE_DIR}" > /dev/null diff --git a/dobuild.sh b/dobuild.sh new file mode 100755 index 0000000..cdf72a9 --- /dev/null +++ b/dobuild.sh @@ -0,0 +1,62 @@ +#!/bin/bash + +# local build - seems like maybe it's leaking system resources sometimes? +# time sudo $@ ./build.sh -c gl-config +# Instead we'll use docker build, which is slower but more reliable. +# docker build - slower but more reliable. + +set -e # exit on error + +# Move to this script's directory +cd "$(dirname "$0")" + +# See if CLEAN=1 flag was set +if [ "$CLEAN" = "1" ]; then + echo "Clearing out all previous build files" + sudo rm -rf ./deploy ./work + docker rm -v pigen_work || echo "Failed to remove pigen_work, because it doesn't exist, which is fine." +fi + +# check if the IS_RELEASE variable is set to "1" +if [ "$IS_RELEASE" = "1" ]; then + echo "Building release version" + CONFIG_FILE=gl-config-release + rm -rf ./deploy +else + echo "Building dev version" + CONFIG_FILE=gl-config +fi + +time PRESERVE_CONTAINER=1 $@ ./build-docker.sh -c $CONFIG_FILE + +# If it's a release, rename the image files to include the tag name +# and take out the date. +if [ "$IS_RELEASE" = "1" ]; then + TAG_NAME=${GITHUB_REF#refs/tags/} + # See if tag name is set + if [ -z "$TAG_NAME" ]; then + echo "No tag name set. Expecting TAG_NAME for release buid." + exit 1 + fi + + cd deploy + # Loop over every file named "image_*.img.xz" + for file in ./image_*.img.xz; do + # Get the filename without the path + filename=$(basename -- "$file") + + # Files are named like image_2023-12-10-GroundlightPi-sdk.img.xz + # Figure out the variant name by removing the image_date- prefix + variant=$(echo $filename | cut -d '-' -f5-) + # check that $variant is not empty, and does not include "Groundlight" + if [ -z "$variant" ] || [[ "$variant" == *"Groundlight"* ]]; then + echo "Failed to parse filename $filename - got $variant" + exit 1 + fi + new_file="GroundlightPi-$TAG_NAME-$variant" + + # Rename the file + echo "Renaming $file to $new_file" + mv "$file" "$new_file" + done +fi diff --git a/gl-config b/gl-config new file mode 100644 index 0000000..5c76078 --- /dev/null +++ b/gl-config @@ -0,0 +1,40 @@ +# The config file defining the Groundlight MNS image. +IMG_NAME='GroundlightPi' +TARGET_HOSTNAME=GroundlightPi +FIRST_USER_NAME=groundlight + +# +# core functionality +# + +ENABLE_SSH=1 +RELEASE=bookworm +# bookworm is newer and works. bullseye is older, and I think really doesn't. +# Why is this even here? Just as a reminder not to try bullseye without being careful. + +# stage0,1 set up basic linux. +# stage2 gets us a working "lite" headless distribution w/o desktop +# stage-gl1 adds the python SDK and supporting libraries like numpy, opencv, framegrab +# stage-gl2 adds the MNS running in docker +# stage3 adds basic desktop infra +# stage4 makes the desktop usable with apps and such +STAGE_LIST="stage0 stage1 stage2 stage-gl1 stage-gl2 stage3 stage4" + +# +# Options used for development. +# (These get overridden by gl-config-release) +# + +# Makes a qemu-compatible image - this will help testing when we figure it out. +USE_QEMU=1 + +# faster but "experimental" and crashed when I tried it. +#USE_QCOW2=1 + +# Dev settings - compressing is quite slow unless you have lots of cores. (xz parallelizes nicely) +# But big images are slow to download. +DEPLOY_COMPRESSION=xz +COMPRESSION_LEVEL=1 +#DEPLOY_COMPRESSION=none +#COMPRESSION_LEVEL=0 + diff --git a/gl-config-release b/gl-config-release new file mode 100644 index 0000000..682cdab --- /dev/null +++ b/gl-config-release @@ -0,0 +1,16 @@ +source gl-config + +# Turn off QEMU for release builds +USE_QEMU=0 + +# Higher compression takes longer, so it's turned down during dev. +# We should turn it back up when we're ready to publish. +# For reference, with a 3.3GB base .img file +# Times are on a 4 core m7g instance, and include cached build.sh time +# xz level 0 took 1m50s to compress to 1.1GB +# xz level 1 took 2m20s to compress to 986MB +# xz level 3 took 3m30s to compress to 950MB +# xz level 9 took 7m30s to compress to 733MB +# Publish settings: +DEPLOY_COMPRESSION=xz +COMPRESSION_LEVEL=9 \ No newline at end of file diff --git a/rpistart.sh b/rpistart.sh new file mode 100755 index 0000000..16ae8a7 --- /dev/null +++ b/rpistart.sh @@ -0,0 +1,165 @@ +#!/bin/bash + + + +# This script will assume that you've already built the linux kernel for QEMU and copied +# the kernel to the root directory. In addition, it will assume that you've already generated +# the Raspberry Pi OS image and decompressed it. +# To use this script, run the following command +# +# $ ./rpistart.sh -i +# +# needs to be an absolute path: +# Ex. /home/ubuntu/groundlight-pi-gen/deploy/image_2023-12-19-GroundlightPi-desktop-qemu.img +# +# If you don't want to use the default login credentials (username=pi, password=raspberry), you +# can set the USERNAME and PASSWORD as environment variables before running this script. +# +# $ export USERNAME= +# $ export PASSWORD= +# $ ./rpistart.sh -i +# + + +set -ex + + +cd "$(dirname "$0")" + +ROOT_DIR=$HOME +IMAGE_FILE="" +KERNEL_IMAGE=$ROOT_DIR/Image +NUM_RPI_CPU_CORES=4 + + + +while getopts "i:" flag +do + case "${flag}" in + i) + IMAGE_FILE="${OPTARG}" + ;; + *) + ;; + esac +done + +function assert_numeric() { + if ! [[ $1 =~ ^[0-9]+$ ]] || ! [[ $1 =~ ^[0-9]+$ ]]; then + echo "Error: Non-numeric value detected: $1" + exit 1 + fi +} + +# Check that the provided path exists, is absolute and ends with "qemu.img" +if [ ! -f "$IMAGE_FILE" ]; then + echo "Invalid Raspberry Pi OS image: '$IMAGE_FILE'" + exit 1 +elif [[ "$IMAGE_FILE" != /* ]]; then + echo "The image path is not absolute: '$IMAGE_FILE'" + exit 1 +elif [[ "$IMAGE_FILE" != *qemu.img ]]; then + echo "The image does not have the expected 'qemu.img' suffix: '$IMAGE_FILE'" + echo "You probably forgot to decompress the image by running 'xz -d <*.img.xz>'" + exit 1 +fi + + +# Validate that the QEMU kernel image path +if [ ! -f "$KERNEL_IMAGE" ]; then + echo "Invalid path for the Linux kernel for QEMU: '$KERNEL_IMAGE'. Make sure to run './setup-qemu-kernel.sh' first." + exit 1 +fi + +# Mount the image for enabling SSH and configuring username and password and +# accessing the files within the image. +# To mount a specific partition within this image, we must calculate the correct offset where +# the partition starts. This calculation requires two pieces of information: +# * sector size +# * starting offset +# For instance, if a partition starts at sector 8192 and the sector size is 512 bytes, the byte +# offset of the partition is 8192 * 512 bytes from the start of the image. +# +# We have two partitions inside the generated Raspberry Pi image. The first device (partition) +# is the bootable partition, and the second one is the root filesystem. The first partition is +# what will be mounted as /boot in Raspberry Pi, and this is where we'll need to create some files. + +# Extracting sector size +SECTOR_SIZE=$(fdisk -l $IMAGE_FILE | grep "Sector size" | awk '{print $4}') + +# Extracting the start of the first partition +START_SECTOR=$(fdisk -l $IMAGE_FILE | grep -E "\.img1" | awk '{print $2}') + +assert_numeric $SECTOR_SIZE +assert_numeric $START_SECTOR + +# Calculating the offset +OFFSET=$(echo "$SECTOR_SIZE * $START_SECTOR" | bc) + +echo "Sector Size: $SECTOR_SIZE" +echo "Start Sector: $START_SECTOR" +echo "Offset: $OFFSET" + + +# Mount the image in /mnt/rpi directory +sudo mkdir -p /mnt/rpi +if findmnt -M /mnt/rpi > /dev/null; then + echo "/mnt/rpi is already mounted." +else + sudo mount -o loop,offset=${OFFSET} ${IMAGE_FILE} /mnt/rpi +fi + +USERNAME=${USERNAME:-"pi"} +PASSWORD=${PASSWORD:-"raspberry"} + + +# Create an 'ssh' file and 'userconf.txt' in the mounted directory. We will put the +# username and password in 'userconf.txt', which will be used as the default login +# credentials. +if [ -d "/mnt/rpi" ]; then + cd /mnt/rpi + sudo touch ssh + sudo rm -f userconf.txt > /dev/null + + # Create a hashed password with openssl. The -6 option instructs OpenSSL + # to use Sha512. This applies salting (i.e., the hash will be different every time). + # https://www.openssl.org/docs/man1.0.2/man1/passwd.html#:~:text=The%20passwd%20command%20computes%20the,or%20from%20the%20terminal%20otherwise. + HASHED_PASSWORD=$(openssl passwd -6 "${PASSWORD}") + echo "${USERNAME}:${HASHED_PASSWORD}" | sudo tee userconf.txt > /dev/null +else + echo "Image not mounted to /mnt/rpi" + exit 1 +fi + +cd $ROOT_DIR +sudo umount /mnt/rpi + +# Run the QEMU emulator + +# - kernel: This is the path to the QEMU kernel downloaded in step 2 +# - append: Providing the boot arguments directly to the kernel, telling it where to find the +# root filesystem and what type it is. +# - cpu/m: This sets the CPU type and RAM to match a Raspberry Pi +# - machine: This sets the machine we are emulating. `virt` refers to a generic, virtualized +# machine type provided by QEMU +# - smp: Specifies the number of CPU cores +# - drive: Defines a drive with the given parameters. +# - device: Attaches the drive to the VM using a VirtIO block device. bootindex=0 means it will +# be the first boot device. +# - netdev: Sets up a user-mode network backend with ID mynet. It also sets up SSH (forwarding +# TCP connections from host port 2222 to guest port 22). +# - monitor: Opens a QEMU monitor console accessible via Telnet on port 5555. The VM will not +# wait for a monitor connection before starting. +sudo qemu-system-aarch64 \ + -machine virt \ + -cpu cortex-a72 \ + -smp $NUM_RPI_CPU_CORES \ + -m 4G \ + -kernel $KERNEL_IMAGE \ + -append "root=/dev/vda2 rootfstype=ext4 rw panic=0 console=ttyAMA0" \ + -drive format=raw,file=$IMAGE_FILE,if=none,id=hd0,cache=writeback \ + -device virtio-blk,drive=hd0,bootindex=0 \ + -netdev user,id=mynet,hostfwd=tcp::2222-:22 \ + -device virtio-net-pci,netdev=mynet \ + -monitor telnet:127.0.0.1:5555,server,nowait \ + -nographic diff --git a/setup-qemu-kernel.sh b/setup-qemu-kernel.sh new file mode 100755 index 0000000..e45747c --- /dev/null +++ b/setup-qemu-kernel.sh @@ -0,0 +1,64 @@ +#!/bin/bash + + +set -ex + + +cd "$(dirname "$0")" + + +ARCH=arm64 +ROOT_DIR=$HOME +NUM_CORES=${NUM_CORES:-$(nproc)} +IMAGE_FILE="" + +# The most recent linux kernel version at the time of this writing. +# Might need to be updated in the future. +KERNEL_VERSION="linux-6.6.8" + + +# Install the required packages. These include cross-compilers for arm64 +# and required packages for QEMU itself. +sudo apt install -y \ + gcc-aarch64-linux-gnu \ + g++-aarch64-linux-gnu \ + qemu \ + qemubuilder \ + qemu-system-arm \ + qemu-utils \ + qemu-system-data \ + qemu-system \ + flex \ + bison \ + libssl-dev + +# Build the Linux kernel for qemu arm64 +# The kernel can be downloaded from https://www.kernel.org/ +# tar xvJf means: -x: extract, -v: verbose, -J: use the xz compression, -f: specify archive name +if [ -d "$KERNEL_VERSION" ]; then + echo "Directory $KERNEL_VERSION already exists, skipping download and extraction." +else + # Downloading the kernel source + echo "Downloading Linux kernel version $KERNEL_VERSION..." + wget "https://cdn.kernel.org/pub/linux/kernel/v6.x/${KERNEL_VERSION}.tar.xz" + + # Extracting the kernel source + echo "Extracting ${KERNEL_VERSION}.tar.xz..." + tar xvJf "${KERNEL_VERSION}.tar.xz" +fi + +cd "$KERNEL_VERSION" + +# Create a .config file: This requires having flex and bison packages installed: +# Flex (Fast Lexial Analyzer Generator) is used for tokenizing input (breaking it into a series of tokens) +# and Bison takes these tokens and analyzes their structure to understand the higher-level syntax. + +ARCH=${ARCH} CROSS_COMPILE=/bin/aarch64-linux-gnu- make defconfig + +# Use the kvm_guest (kernel virtual machine) config as the base defconfig, which is suitable for qemu +ARCH=${ARCH} CROSS_COMPILE=/bin/aarch64-linux-gnu- make kvm_guest.config + +# Build the kernel (parallelizable if nproc > 1) +ARCH=${ARCH} CROSS_COMPILE=/bin/aarch64-linux-gnu- make -j${NUM_CORES} + +cp arch/${ARCH}/boot/Image ${ROOT_DIR} \ No newline at end of file diff --git a/stage-gl1/00-install-packages/00-packages b/stage-gl1/00-install-packages/00-packages new file mode 100644 index 0000000..0bbfc18 --- /dev/null +++ b/stage-gl1/00-install-packages/00-packages @@ -0,0 +1,19 @@ +# Absolute basics +python3 python-is-python3 + +# We don't install things like python3-pip or many libraries here, because pip and apt don't +# get along, so we'll set up a venv later. + +# We'll set up a venv to get around this. +python3-venv + +# We do install OS's opencv to make sure all the .so files are available. +python3-opencv + +# We need to make sure to install this before framegrab -- required to install the netifaces +# package. In general, python packages which build C code need this to install even through pip +python3-dev + +# Some nice-to-have utilities +iotop nethogs net-tools telnet +git curl wget diff --git a/stage-gl1/01-install-python-libraries/00-run-chroot.sh b/stage-gl1/01-install-python-libraries/00-run-chroot.sh new file mode 100755 index 0000000..a47a733 --- /dev/null +++ b/stage-gl1/01-install-python-libraries/00-run-chroot.sh @@ -0,0 +1,16 @@ +#!/bin/bash -e + +# set up a groundlight virtual environment for python +python3 -m venv /opt/groundlight/gl-py +source /opt/groundlight/gl-py/bin/activate + +# Now install the groundlight python libraries +pip install groundlight +# framegrab will install opencv-python, numpy, and pillow +pip install framegrab + +# add a .bashrc entry to activate the groundlight virtual environment +echo "source /opt/groundlight/gl-py/bin/activate" >> /home/${FIRST_USER_NAME}/.bashrc + +# Make the .env dir globally writable AFTER everything's installed +chmod a+rw -R /opt/groundlight/gl-py diff --git a/stage-gl1/01-install-python-libraries/01-run.sh b/stage-gl1/01-install-python-libraries/01-run.sh new file mode 100755 index 0000000..f6c3ca9 --- /dev/null +++ b/stage-gl1/01-install-python-libraries/01-run.sh @@ -0,0 +1,5 @@ +#!/bin/bash -e + +GL_DIR="${ROOTFS_DIR}/opt/groundlight" + +install -v files/gl-py-README.md "${GL_DIR}/gl-py/README.md" diff --git a/stage-gl1/01-install-python-libraries/files/gl-py-README.md b/stage-gl1/01-install-python-libraries/files/gl-py-README.md new file mode 100644 index 0000000..8bbd3c7 --- /dev/null +++ b/stage-gl1/01-install-python-libraries/files/gl-py-README.md @@ -0,0 +1,21 @@ +# Groundlight Python Libraries +We have set up a python virtual environment (`venv`) for you to use. To activate it, run: + +``` +source /opt/groundlight/gl-py/bin/activate +``` + +(This line is already in your .bashrc file, so you probably don't need to run it yourself.) + +Some might think this is unnecessarily complicated, or not how they'd like to manage their +python systems. We understand. We have chosen this approach because it is the most +natural for many users, especially those who "just want to use pip thank you very much." +This attitude is extremely understandable, however modern python (3.11) and debian/ubuntu +systems have made this difficult with the "externally-managed-environment" feature +which basically prevents you from using pip without a virtual environment. + +If you like `conda`, `mamba`, `poetry`, `pyenv`, or some other python environment manager, +so do we! Please go ahead and use them. Hopefully this default has not gotten in your way. +If it is, please [get in touch](https://github.com/groundlight/groundlight-pi-gen/issues). + +Happy visual understanding! diff --git a/stage2/EXPORT_IMAGE b/stage-gl1/EXPORT_IMAGE similarity index 76% rename from stage2/EXPORT_IMAGE rename to stage-gl1/EXPORT_IMAGE index aa8f936..b7c60b5 100644 --- a/stage2/EXPORT_IMAGE +++ b/stage-gl1/EXPORT_IMAGE @@ -1,4 +1,4 @@ -IMG_SUFFIX="-lite" +IMG_SUFFIX="-sdk-only" if [ "${USE_QEMU}" = "1" ]; then export IMG_SUFFIX="${IMG_SUFFIX}-qemu" fi diff --git a/stage-gl1/prerun.sh b/stage-gl1/prerun.sh new file mode 100755 index 0000000..9acd13c --- /dev/null +++ b/stage-gl1/prerun.sh @@ -0,0 +1,5 @@ +#!/bin/bash -e + +if [ ! -d "${ROOTFS_DIR}" ]; then + copy_previous +fi diff --git a/stage-gl2/00-install-packages/00-packages b/stage-gl2/00-install-packages/00-packages new file mode 100644 index 0000000..128ae56 --- /dev/null +++ b/stage-gl2/00-install-packages/00-packages @@ -0,0 +1,3 @@ +# What the MNS needs +docker.io docker-compose + diff --git a/stage-gl2/01-nms-code/00-run-chroot.sh b/stage-gl2/01-nms-code/00-run-chroot.sh new file mode 100755 index 0000000..bd60709 --- /dev/null +++ b/stage-gl2/01-nms-code/00-run-chroot.sh @@ -0,0 +1,10 @@ +#!/bin/bash -e + +mkdir -p /opt/groundlight +cd /opt/groundlight + +# Make sure the directory we'll clone into is gone, or else git will error. +# (This happens with cached partial builds.) +rm -rf monitoring-notification-server +git clone https://github.com/groundlight/monitoring-notification-server + diff --git a/stage-gl2/02-systemd-service/00-run.sh b/stage-gl2/02-systemd-service/00-run.sh new file mode 100755 index 0000000..5ad8856 --- /dev/null +++ b/stage-gl2/02-systemd-service/00-run.sh @@ -0,0 +1,13 @@ +#!/bin/bash -e + +GL_DIR="${ROOTFS_DIR}/opt/groundlight" +mkdir -p "${GL_DIR}/systemd" + +install -v files/service-up.sh "${GL_DIR}/systemd/" +install -v files/service-down.sh "${GL_DIR}/systemd/" +install -v files/groundlight-mns.service "${ROOTFS_DIR}/etc/systemd/system/" + +on_chroot << EOF +systemctl enable groundlight-mns +EOF + diff --git a/stage-gl2/02-systemd-service/files/groundlight-mns.service b/stage-gl2/02-systemd-service/files/groundlight-mns.service new file mode 100644 index 0000000..db8e8e6 --- /dev/null +++ b/stage-gl2/02-systemd-service/files/groundlight-mns.service @@ -0,0 +1,14 @@ +[Unit] +Description=Groundlight Monitoring Notification Server +Requires=docker.service +After=docker.service + +[Service] +Type=simple +ExecStart=/opt/groundlight/systemd/service-up.sh +ExecStop=/opt/groundlight/systemd/service-down.sh +Restart=always + +[Install] +WantedBy=multi-user.target + diff --git a/stage-gl2/02-systemd-service/files/install-systemd.sh b/stage-gl2/02-systemd-service/files/install-systemd.sh new file mode 100755 index 0000000..1b3cf85 --- /dev/null +++ b/stage-gl2/02-systemd-service/files/install-systemd.sh @@ -0,0 +1,8 @@ +#!/bin/bash + +set -ex + +sudo cp ./groundlight-mns.service /etc/systemd/system/ +sudo systemctl daemon-reload +sudo systemctl enable groundlight-mns + diff --git a/stage-gl2/02-systemd-service/files/service-down.sh b/stage-gl2/02-systemd-service/files/service-down.sh new file mode 100755 index 0000000..e400009 --- /dev/null +++ b/stage-gl2/02-systemd-service/files/service-down.sh @@ -0,0 +1,5 @@ +#!/bin/bash + +cd /opt/groundlight/monitoring-notification-server/deploy/ +docker-compose down + diff --git a/stage-gl2/02-systemd-service/files/service-up.sh b/stage-gl2/02-systemd-service/files/service-up.sh new file mode 100755 index 0000000..9a705b2 --- /dev/null +++ b/stage-gl2/02-systemd-service/files/service-up.sh @@ -0,0 +1,5 @@ +#!/bin/bash + +cd /opt/groundlight/monitoring-notification-server/deploy/ +docker-compose up + diff --git a/stage-gl2/EXPORT_IMAGE b/stage-gl2/EXPORT_IMAGE new file mode 100644 index 0000000..bb5bc59 --- /dev/null +++ b/stage-gl2/EXPORT_IMAGE @@ -0,0 +1,4 @@ +IMG_SUFFIX="-mns-headless" +if [ "${USE_QEMU}" = "1" ]; then + export IMG_SUFFIX="${IMG_SUFFIX}-qemu" +fi diff --git a/stage-gl2/prerun.sh b/stage-gl2/prerun.sh new file mode 100755 index 0000000..9acd13c --- /dev/null +++ b/stage-gl2/prerun.sh @@ -0,0 +1,5 @@ +#!/bin/bash -e + +if [ ! -d "${ROOTFS_DIR}" ]; then + copy_previous +fi diff --git a/stage4/EXPORT_IMAGE b/stage4/EXPORT_IMAGE index 79ec11a..9f2f737 100644 --- a/stage4/EXPORT_IMAGE +++ b/stage4/EXPORT_IMAGE @@ -1,4 +1,4 @@ -IMG_SUFFIX="" +IMG_SUFFIX="-desktop" if [ "${USE_QEMU}" = "1" ]; then export IMG_SUFFIX="${IMG_SUFFIX}-qemu" fi