mirror of
https://github.com/home-assistant/supervisor.git
synced 2025-07-09 18:26:30 +00:00
fix resinhub
This commit is contained in:
parent
e0566d73cc
commit
79eb859d32
@ -1,339 +0,0 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Default values
|
||||
TAG=1.0
|
||||
LOGFILE=/tmp/`basename "$0"`.log
|
||||
LOG=yes
|
||||
ONLY_SUPERVISOR=no
|
||||
NOREBOOT=no
|
||||
DOCKER_REPO=pvizeli
|
||||
|
||||
# Don't run anything before this source as it sets PATH here
|
||||
source /etc/profile
|
||||
|
||||
# Help function
|
||||
function help {
|
||||
cat << EOF
|
||||
Wrapper to run host OS updates on resin distributions.
|
||||
$0 <OPTION>
|
||||
|
||||
Options:
|
||||
-h, --help
|
||||
Display this help and exit.
|
||||
|
||||
-f, --force
|
||||
Run the resinhup tool without fingerprints check and validation.
|
||||
|
||||
--staging
|
||||
Do this update for devices in staging.
|
||||
By default resinhup assumes the devices are in production.
|
||||
|
||||
-t <TAG>, --tag <TAG>
|
||||
Use a specific tag for resinhup image.
|
||||
Default: 1.0 .
|
||||
|
||||
--remote <REMOTE>
|
||||
Run the updater with this remote configuration.
|
||||
This argument will be passed to resinhup and will be used as the location from
|
||||
which the update bundles will be downloaded.
|
||||
|
||||
--hostos-version <HOSTOS_VERSION>
|
||||
Run the updater for this specific HostOS version.
|
||||
This is a mandatory argument.
|
||||
|
||||
--supervisor-registry <SUPERVISOR REGISTRY>
|
||||
Update supervisor getting the image from this registry.
|
||||
|
||||
--supervisor-tag <SUPERVISOR TAG>
|
||||
In the case of a successful host OS update, bring in a newer supervisor too
|
||||
using this tag.
|
||||
|
||||
--only-supervisor
|
||||
Update only the supervisor.
|
||||
|
||||
-n, --nolog
|
||||
By default tool logs to stdout and file. This flag deactivates log to
|
||||
$LOGFILE file.
|
||||
|
||||
--no-reboot
|
||||
Don't reboot if update is successful. This is useful when debugging.
|
||||
EOF
|
||||
}
|
||||
|
||||
# If things fail try to bring board back to the initial state
|
||||
function tryup {
|
||||
systemctl start resin-supervisor > /dev/null 2>&1
|
||||
systemctl start update-resin-supervisor.timer > /dev/null 2>&1
|
||||
/etc/init.d/crond start > /dev/null 2>&1
|
||||
}
|
||||
|
||||
# Catch INT signals and try to bring things back
|
||||
trap ctrl_c INT
|
||||
function ctrl_c() {
|
||||
log "Trapped INT signal"
|
||||
tryup
|
||||
exit 1
|
||||
}
|
||||
|
||||
# Log function helper
|
||||
function log {
|
||||
# Address log levels
|
||||
case $1 in
|
||||
ERROR)
|
||||
loglevel=ERROR
|
||||
shift
|
||||
;;
|
||||
WARN)
|
||||
loglevel=WARNING
|
||||
shift
|
||||
;;
|
||||
*)
|
||||
loglevel=LOG
|
||||
;;
|
||||
esac
|
||||
ENDTIME=$(date +%s)
|
||||
if [ "z$LOG" == "zyes" ]; then
|
||||
printf "[%09d%s%s\n" "$(($ENDTIME - $STARTTIME))" "][$loglevel]" "$1" | tee -a $LOGFILE
|
||||
else
|
||||
printf "[%09d%s%s\n" "$(($ENDTIME - $STARTTIME))" "][$loglevel]" "$1"
|
||||
fi
|
||||
if [ "$loglevel" == "ERROR" ]; then
|
||||
exit 1
|
||||
fi
|
||||
}
|
||||
|
||||
function runPreHacks {
|
||||
local _boot_mountpoint="$(grep $(blkid | grep resin-boot | cut -d ":" -f 1) /proc/mounts | cut -d ' ' -f 2)"
|
||||
|
||||
# we might need to repartition this so make sure it is unmounted
|
||||
log "Make sure resin-boot is unmounted..."
|
||||
if [ -z $_boot_mountpoint ]; then
|
||||
log WARN "Mount point for resin-boot partition could not be found. It is probably already unmounted."
|
||||
# XXX support old devices
|
||||
elif [ $_boot_mountpoint = "/boot" ]; then
|
||||
umount $_boot_mountpoint &> /dev/null
|
||||
fi
|
||||
|
||||
# can't fix label of data partition from container
|
||||
e2label $DATA_MOUNTPOINT resin-data
|
||||
|
||||
# Some devices never actually update /etc/timestamp because they are hard-rebooted.
|
||||
# Force a /etc/timestamp update so we don't get into TLS issues.
|
||||
# This assumes that current date is valid - which should be because we can't remotely
|
||||
# update a device with outdated time (vpn would not be available so ssh would not
|
||||
# work).
|
||||
# Only applies on sysvinit systems
|
||||
if [[ $(readlink /sbin/init) == *"sysvinit"* ]]; then
|
||||
log "Save timestamp..."
|
||||
date -u +%4Y%2m%2d%2H%2M%2S > /etc/timestamp
|
||||
fi
|
||||
}
|
||||
|
||||
# Test if a version is greater than another
|
||||
function version_gt() {
|
||||
test "$(echo "$@" | tr " " "\n" | sort -V | head -n 1)" != "$1"
|
||||
}
|
||||
|
||||
#
|
||||
# MAIN
|
||||
#
|
||||
|
||||
# Log timer
|
||||
STARTTIME=$(date +%s)
|
||||
|
||||
# Parse arguments
|
||||
while [[ $# > 0 ]]; do
|
||||
arg="$1"
|
||||
|
||||
case $arg in
|
||||
-h|--help)
|
||||
help
|
||||
exit 0
|
||||
;;
|
||||
-t|--tag)
|
||||
if [ -z "$2" ]; then
|
||||
log ERROR "\"$1\" argument needs a value."
|
||||
fi
|
||||
TAG=$2
|
||||
shift
|
||||
;;
|
||||
--hostos-version)
|
||||
if [ -z "$2" ]; then
|
||||
log ERROR "\"$1\" argument needs a value."
|
||||
fi
|
||||
HOSTOS_VERSION=$2
|
||||
shift
|
||||
;;
|
||||
--remote)
|
||||
if [ -z "$2" ]; then
|
||||
log ERROR "\"$1\" argument needs a value."
|
||||
fi
|
||||
REMOTE=$2
|
||||
shift
|
||||
;;
|
||||
--supervisor-registry)
|
||||
if [ -z "$2" ]; then
|
||||
log ERROR "\"$1\" argument needs a value."
|
||||
fi
|
||||
SUPERVISOR_REGISTRY=$2
|
||||
shift
|
||||
;;
|
||||
--supervisor-tag)
|
||||
if [ -z "$2" ]; then
|
||||
log ERROR "\"$1\" argument needs a value."
|
||||
fi
|
||||
UPDATER_SUPERVISOR_TAG=$2
|
||||
shift
|
||||
;;
|
||||
--only-supervisor)
|
||||
ONLY_SUPERVISOR=yes
|
||||
;;
|
||||
-n|--nolog)
|
||||
LOG=no
|
||||
;;
|
||||
--no-reboot)
|
||||
NOREBOOT=yes
|
||||
;;
|
||||
*)
|
||||
log ERROR "Unrecognized option $1."
|
||||
;;
|
||||
esac
|
||||
shift
|
||||
done
|
||||
|
||||
# Check that HostOS version was provided
|
||||
if [ -z "$HOSTOS_VERSION" ]; then
|
||||
log ERROR "--hostos-version is required."
|
||||
fi
|
||||
|
||||
# Init log file
|
||||
# LOGFILE init and header
|
||||
if [ "$LOG" == "yes" ]; then
|
||||
echo "================"`basename "$0"`" HEADER START====================" > $LOGFILE
|
||||
date >> $LOGFILE
|
||||
fi
|
||||
|
||||
# Detect DATA_MOUNTPOINT
|
||||
if [ -d /mnt/data ]; then
|
||||
DATA_MOUNTPOINT=/mnt/data
|
||||
elif [ -d /mnt/data-disk ]; then
|
||||
DATA_MOUNTPOINT=/mnt/data-disk
|
||||
else
|
||||
log ERROR "Can't find the resin-data mountpoint."
|
||||
fi
|
||||
|
||||
# Run pre hacks
|
||||
runPreHacks
|
||||
|
||||
# Detect arch
|
||||
source /etc/supervisor.conf
|
||||
arch=`echo "$SUPERVISOR_IMAGE" | sed -n "s/.*\/\([a-zA-Z0-9]*\)-.*/\1/p"`
|
||||
if [ -z "$arch" ]; then
|
||||
log ERROR "Can't detect arch from /etc/supervisor.conf ."
|
||||
else
|
||||
log "Detected arch: $arch ."
|
||||
fi
|
||||
|
||||
# Detect slug
|
||||
source /etc/resinhub.conf
|
||||
slug=$RESINHUB_MACHINE
|
||||
if [ -z $slug ]; then
|
||||
log ERROR "Can't detect slug from /etc/hassio.conf"
|
||||
else
|
||||
log "Detected slug: $slug ."
|
||||
fi
|
||||
|
||||
# We need to stop update-resin-supervisor.timer otherwise it might restart supervisor which
|
||||
# will delete downloaded layers. Same for cron jobs.
|
||||
systemctl stop update-resin-supervisor.timer > /dev/null 2>&1
|
||||
/etc/init.d/crond stop > /dev/null 2>&1 # We might have cron jobs which restart supervisor
|
||||
|
||||
# Supervisor update
|
||||
if [ ! -z "$UPDATER_SUPERVISOR_TAG" ]; then
|
||||
log "Supervisor update requested through arguments ."
|
||||
|
||||
# Default UPDATER_SUPERVISOR_IMAGE to the one in /etc/supervisor.conf
|
||||
if [ -z "$SUPERVISOR_REGISTRY" ]; then
|
||||
UPDATER_SUPERVISOR_IMAGE=$SUPERVISOR_IMAGE
|
||||
else
|
||||
UPDATER_SUPERVISOR_IMAGE="$SUPERVISOR_REGISTRY/resin/$arch-supervisor"
|
||||
fi
|
||||
|
||||
log "Update to supervisor $UPDATER_SUPERVISOR_IMAGE:$UPDATER_SUPERVISOR_TAG..."
|
||||
|
||||
log "Updating supervisor..."
|
||||
if [[ $(readlink /sbin/init) == *"sysvinit"* ]]; then
|
||||
# Supervisor update on sysvinit based OS
|
||||
docker pull "$UPDATER_SUPERVISOR_IMAGE:$UPDATER_SUPERVISOR_TAG"
|
||||
if [ $? -ne 0 ]; then
|
||||
tryup
|
||||
log ERROR "Could not update supervisor to $UPDATER_SUPERVISOR_IMAGE:$UPDATER_SUPERVISOR_TAG ."
|
||||
|
||||
fi
|
||||
docker tag -f "$SUPERVISOR_IMAGE:$SUPERVISOR_TAG" "$SUPERVISOR_IMAGE:latest"
|
||||
else
|
||||
# Supervisor update on systemd based OS
|
||||
/usr/bin/update-resin-supervisor --supervisor-image $UPDATER_SUPERVISOR_IMAGE --supervisor-tag $UPDATER_SUPERVISOR_TAG
|
||||
if [ $? -ne 0 ]; then
|
||||
tryup
|
||||
log ERROR "Could not update supervisor to $UPDATER_SUPERVISOR_IMAGE:$UPDATER_SUPERVISOR_TAG ."
|
||||
fi
|
||||
fi
|
||||
else
|
||||
log "Supervisor update not requested through arguments ."
|
||||
fi
|
||||
|
||||
# That's it if we only wanted supervisor update
|
||||
if [ "$ONLY_SUPERVISOR" == "yes" ]; then
|
||||
log "Update only of the supervisor requested."
|
||||
exit 0
|
||||
fi
|
||||
|
||||
# Avoid supervisor cleaning up resinhup and stop containers
|
||||
log "Stopping all containers..."
|
||||
systemctl stop resin-supervisor > /dev/null 2>&1
|
||||
docker stop $(docker ps -a -q) > /dev/null 2>&1
|
||||
log "Removing all containers..."
|
||||
docker rm $(docker ps -a -q) > /dev/null 2>&1
|
||||
|
||||
# Pull resinhup and tag it accordingly
|
||||
log "Pulling resinhup..."
|
||||
docker pull $DOCKER_REPO/resinhup-$slug:$TAG
|
||||
if [ $? -ne 0 ]; then
|
||||
tryup
|
||||
log ERROR "Could not pull $DOCKER_REPO/resinhup-$slug:$TAG ."
|
||||
fi
|
||||
|
||||
# Run resinhup
|
||||
log "Running resinhup for version $HOSTOS_VERSION ..."
|
||||
RESINHUP_STARTTIME=$(date +%s)
|
||||
|
||||
docker run --privileged --rm --net=host \
|
||||
-v /:/host \
|
||||
-v /lib/modules:/lib/modules:ro \
|
||||
-v /var/run/docker.sock:/var/run/docker.sock \
|
||||
$DOCKER_REPO/resinhup-$slug:$TAG
|
||||
RESINHUP_EXIT=$?
|
||||
# RESINHUP_EXIT
|
||||
# 0 - update done
|
||||
# 2 - only intermediate step was done and will continue after reboot
|
||||
# 3 - device already updated at a requested version or later
|
||||
if [ $RESINHUP_EXIT -eq 0 ] || [ $RESINHUP_EXIT -eq 2 ] || [ $RESINHUP_EXIT -eq 3 ]; then
|
||||
RESINHUP_ENDTIME=$(date +%s)
|
||||
log "Update suceeded in $(($RESINHUP_ENDTIME - $RESINHUP_STARTTIME)) seconds."
|
||||
|
||||
# Everything is fine - Reboot
|
||||
if [ "$NOREBOOT" == "no" ]; then
|
||||
log "Rebooting board in 5 seconds..."
|
||||
nohup bash -c " /bin/sleep 5 ; /sbin/reboot " &
|
||||
else
|
||||
log "'No-reboot' requested."
|
||||
fi
|
||||
else
|
||||
RESINHUP_ENDTIME=$(date +%s)
|
||||
# Don't tryup so support can have a chance to see what went wrong and how to recover
|
||||
log ERROR "Update failed after $(($RESINHUP_ENDTIME - $RESINHUP_STARTTIME)) seconds. Check the logs."
|
||||
fi
|
||||
|
||||
# Success
|
||||
exit $RESINHUP_EXIT
|
Loading…
x
Reference in New Issue
Block a user