#!/bin/sh # Adapted from: https://github.com/balena-os/meta-balena/blob/v2.45.0/meta-balena-common/recipes-containers/balena-supervisor/balena-supervisor/start-balena-supervisor # We still need to include resin-vars on legacy systems if [ -f /usr/sbin/resin-vars ]; then # shellcheck disable=SC1091 . /usr/sbin/resin-vars else # shellcheck disable=SC1091 . /usr/sbin/balena-config-vars fi if ! balena inspect $SUPERVISOR_IMAGE:$SUPERVISOR_TAG > /dev/null; then balena load --input /usr/src/supervisor-image.tar fi if [ -f /mnt/data/backup.tgz.mounted ]; then cp /mnt/data/backup.tgz.mounted /mnt/data/backup.tgz fi # Handle apps.json existence # Keep this before computing SUPERVISOR_CONTAINER_IMAGE_ID APPSJSON=/mnt/data/apps.json if [ ! -f "$APPSJSON" ]; then if [ -d "$APPSJSON" ]; then rm -rf "$APPSJSON" balena rm -f resin_supervisor || true echo '{}' > "$APPSJSON" elif [ ! -e "$APPSJSON" ]; then echo '{}' > "$APPSJSON" fi fi SUPERVISOR_IMAGE_ID=$(balena inspect --format='{{.Id}}' "$SUPERVISOR_IMAGE:$SUPERVISOR_TAG") SUPERVISOR_CONTAINER_IMAGE_ID=$(balena inspect --format='{{.Image}}' resin_supervisor || echo "") # If self-signed root CA exists, add the CA for the specified registry if [ -n "$BALENA_ROOT_CA" ]; then BALENA_DECODED_ROOT_CA="$(echo "${BALENA_ROOT_CA}" | base64 -d -w0)" NODE_EXTRA_CA_CERTS="/etc/ssl/certs/balenaRootCA.pem" CERT_DIR="/mnt/state/root-overlay/etc/docker/certs.d/${REGISTRY_ENDPOINT}" CERT_FILE="${CERT_DIR}/ca.crt" CERT_CONTENTS=$(if [ -e "$CERT_FILE" ]; then echo $(cat "$CERT_FILE"); fi) # Ensure that the contents is correct, install otherwise if [ "$BALENA_DECODED_ROOT_CA" != "$CERT_CONTENTS" ]; then mkdir -p "$CERT_DIR" echo "$BALENA_DECODED_ROOT_CA" > "$CERT_FILE" fi fi hasValueChanged() { KEY="$1" NEW_VALUE="$2" COLLECTION="$3" CURRENT_VALUE=$(echo "$COLLECTION" | jq -r ".$KEY") if [ "$CURRENT_VALUE" != "$NEW_VALUE" ];then echo "$KEY has changed!" else return 1 fi } configIsUnchanged() { SUPERVISOR_CONTAINER_ENV_JSON="$(balena inspect resin_supervisor | jq '.[0].Config.Env | map(.| { (.[0:index("=")]): .[index("=")+1:] }) | add')" if hasValueChanged "BOOT_MOUNTPOINT" "$BOOT_MOUNTPOINT" "$SUPERVISOR_CONTAINER_ENV_JSON" || \ hasValueChanged "REGISTRY_ENDPOINT" "$REGISTRY_ENDPOINT" "$SUPERVISOR_CONTAINER_ENV_JSON" || \ hasValueChanged "MIXPANEL_TOKEN" "$MIXPANEL_TOKEN" "$SUPERVISOR_CONTAINER_ENV_JSON" || \ hasValueChanged "LED_FILE" "${LED_FILE}" "$SUPERVISOR_CONTAINER_ENV_JSON" || \ hasValueChanged "LISTEN_PORT" "$LISTEN_PORT" "$SUPERVISOR_CONTAINER_ENV_JSON" || \ hasValueChanged "SUPERVISOR_IMAGE" "${SUPERVISOR_IMAGE}:${SUPERVISOR_TAG}" "$SUPERVISOR_CONTAINER_ENV_JSON" || \ hasValueChanged "BALENA_ROOT_CA" "$BALENA_DECODED_ROOT_CA" "$SUPERVISOR_CONTAINER_ENV_JSON" || \ hasValueChanged "NODE_EXTRA_CA_CERTS" "$NODE_EXTRA_CA_CERTS" "$SUPERVISOR_CONTAINER_ENV_JSON"; then echo "Container config has changed!" return 1 else echo "Container config has not changed" return 0 fi } runSupervisor() { balena rm --force resin_supervisor || true balena run --privileged --name resin_supervisor \ --restart=always \ --net=host \ --cidenv=SUPERVISOR_CONTAINER_ID \ -v /var/run/balena-engine.sock:/var/run/balena-engine.sock \ -v "$CONFIG_PATH:/boot/config.json" \ -v /mnt/data/apps.json:/boot/apps.json \ -v /resin-data/balena-supervisor:/data \ -v /proc/net/fib_trie:/mnt/fib_trie \ -v /var/log/supervisor-log:/var/log \ -v /:/mnt/root \ -e DOCKER_ROOT=/mnt/root/var/lib/docker \ -e DOCKER_SOCKET=/var/run/balena-engine.sock \ -e "BOOT_MOUNTPOINT=$BOOT_MOUNTPOINT" \ -e "REGISTRY_ENDPOINT=$REGISTRY_ENDPOINT" \ -e "MIXPANEL_TOKEN=$MIXPANEL_TOKEN" \ -e "LED_FILE=${LED_FILE}" \ -e "LISTEN_PORT=$LISTEN_PORT" \ -e "SUPERVISOR_IMAGE=${SUPERVISOR_IMAGE}:${SUPERVISOR_TAG}" \ -e "BALENA_ROOT_CA=$BALENA_DECODED_ROOT_CA" \ -e "NODE_EXTRA_CA_CERTS=$NODE_EXTRA_CA_CERTS" \ "${SUPERVISOR_IMAGE}:${SUPERVISOR_TAG}" \ node /usr/src/app/dist/app.js --inspect-brk } if [ -z "$SUPERVISOR_IMAGE_ID" ]; then # No supervisor image exists on the device, try to pull it systemctl start update-balena-supervisor elif [ "$SUPERVISOR_IMAGE_ID" = "$SUPERVISOR_CONTAINER_IMAGE_ID" ] && configIsUnchanged; then # Supervisor image exists, and the current supervisor container is created from balena start --attach resin_supervisor else # No supervisor container exists or there's a different supervisor image to run runSupervisor fi