Test layer (#23)

* backup old

* Use fork now

* Use new fork for build

* change branch

* Fix errors

* Fix layer
This commit is contained in:
Pascal Vizeli 2017-07-17 21:39:06 +02:00 committed by GitHub
parent 1193004b1e
commit 60ebfa2367
29 changed files with 13 additions and 855 deletions

4
.gitmodules vendored Normal file
View file

@ -0,0 +1,4 @@
[submodule "meta-hassio"]
path = meta-hassio
url = https://github.com/pvizeli/meta-resin
branch = hassio

View file

@ -20,8 +20,8 @@ cleanup() {
trap 'cleanup fail' SIGINT SIGTERM
# Sanity checks
if [ "$#" -ne 3 ]; then
echo "Usage: create_resinos.sh <MACHINE> <HASSIO_VERSION> <RESINOS_HASSIO_VERSION>"
if [ "$#" -ne 2 ]; then
echo "Usage: create_resinos.sh <MACHINE> <RESINOS_HASSIO_VERSION>"
echo "Optional environment: BUILD_DIR, PERSISTENT_WORKDIR, HASSIO_META"
exit 1
fi
@ -36,12 +36,12 @@ NAME="$1"
case "$NAME" in
"raspberrypi" | "raspberrypi2" | "raspberrypi3")
RESIN_REPO="https://github.com/resin-os/resin-raspberrypi"
RESIN_BRANCH="v2.0.5+rev1"
RESIN_BRANCH="v2.0.8+rev1"
MACHINE="$NAME"
;;
"intel-nuc")
RESIN_REPO="https://github.com/resin-os/resin-intel"
RESIN_BRANCH="v2.0.4+rev1"
RESIN_BRANCH="v2.0.9+rev1"
MACHINE="intel-corei7-64"
;;
*)
@ -51,15 +51,13 @@ case "$NAME" in
esac
HOMEASSISTANT_IMAGE="$DOCKER_REPO/$NAME-homeassistant"
HASSIO_VERSION=$2
RESINOS_HASSIO_VERSION=$3
RESINOS_HASSIO_VERSION=$2
PERSISTENT_WORKDIR=${PERSISTENT_WORKDIR:=~/yocto}
BUILD_DIR=${BUILD_DIR:=$SCRIPTPATH}
WORKSPACE=${BUILD_DIR:=$SCRIPTPATH}/resin-$MACHINE
HASSIO_META=${HASSIO_ROOT:=$SCRIPTPATH/../..}
DOWNLOAD_DIR=$PERSISTENT_WORKDIR/shared-downloads
SSTATE_DIR=$PERSISTENT_WORKDIR/$MACHINE/sstate
RESIN_BRANCH=master
echo "[INFO] Checkout repository"
if [ ! -d "$WORKSPACE" ]; then
@ -68,13 +66,11 @@ if [ ! -d "$WORKSPACE" ]; then
fi
echo "[INFO] Inject HassIO yocto layer"
cp -fr $HASSIO_META/meta-hassio $WORKSPACE/layers/
if [ ! -d $WORKSPACE/build/conf ]; then
sed -i 's%${TOPDIR}/../layers/meta-resin/meta-resin-common \\%${TOPDIR}/../layers/meta-resin/meta-resin-common \\\n${TOPDIR}/../layers/meta-hassio \\%g' $WORKSPACE/layers/*/conf/samples/bblayers.conf.sample
fi
rm -rf "$WORKSPACE/layers/meta-resin"
cp -rf "$HASSIO_META/meta-hassio" "$WORKSPACE/layers/meta-resin"
# Additional variables
BARYS_ARGUMENTS_VAR="-a HASSIO_SUPERVISOR_TAG=$HASSIO_VERSION -a HASSIO_MACHINE=$NAME -a HOMEASSISTANT_IMAGE=$HOMEASSISTANT_IMAGE -a RESINOS_HASSIO_VERSION=$RESINOS_HASSIO_VERSION"
BARYS_ARGUMENTS_VAR="-a HASSIO_MACHINE=$NAME -a HOMEASSISTANT_IMAGE=$HOMEASSISTANT_IMAGE -a RESINOS_HASSIO_VERSION=$RESINOS_HASSIO_VERSION"
# Make sure shared directories are in place
mkdir -p $DOWNLOAD_DIR

1
meta-hassio Submodule

@ -0,0 +1 @@
Subproject commit 01917e7589d297768db9b7e5128714657707ec11

View file

@ -1,18 +0,0 @@
# ResinOS - HassIO Image
The image is based on ResinOS and Yocto Linux. It comes with the HassIO supervisor pre-installed. This includes support to update the supervisor over the air. After flashing your host OS will not require any more maintenance! The image does not include Home Assistant, instead it will downloaded when the image boots up for the first time.
After extracting the archive, flash it to a drive using [Etcher](https://etcher.io/).
## Configuring the image
You can configure the WiFi network that the image should connect to after flashing using [`resin-device-toolbox`](https://resinos.io/docs/raspberrypi3/gettingstarted/#install-resin-device-toolbox).
## Developer access to ResinOS host
Create an `authorized_keys` file in the boot partition of your SD card with your public key. After a boot it, you can acces your device as root over ssh on port 22222.
## Troubleshooting
Read logoutput from supervisor:
```bash
journalctl -f -u resin-supervisor.service
docker logs homeassistant
```

View file

@ -1,10 +0,0 @@
BBPATH .= ":${LAYERDIR}"
BBFILES += "${LAYERDIR}/recipes-*/*/*.bb \
${LAYERDIR}/recipes-*/*/*.bbappend"
BBFILE_COLLECTIONS += "hassio"
BBFILE_PATTERN_hassio = "^${LAYERDIR}/"
LAYERVERSION_hassio = "1"
LAYERDEPENDS_hassio = "resin-common"

View file

@ -1,28 +0,0 @@
FILESEXTRAPATHS_prepend := "${THISDIR}/${PN}:"
SUPERVISOR_REPOSITORY_armv5 = "homeassistant/armhf-hassio-supervisor"
SUPERVISOR_REPOSITORY_armv6 = "homeassistant/armhf-hassio-supervisor"
SUPERVISOR_REPOSITORY_armv7a = "homeassistant/armhf-hassio-supervisor"
SUPERVISOR_REPOSITORY_armv7ve = "homeassistant/armhf-hassio-supervisor"
SUPERVISOR_REPOSITORY_aarch64 = "homeassistant/aarch64-hassio-supervisor"
SUPERVISOR_REPOSITORY_x86 = "homeassistant/i386-hassio-supervisor"
SUPERVISOR_REPOSITORY_x86-64 = "homeassistant/amd64-hassio-supervisor"
SUPERVISOR_TAG = "${HASSIO_SUPERVISOR_TAG}"
TARGET_REPOSITORY = "${SUPERVISOR_REPOSITORY}"
TARGET_TAG = "${SUPERVISOR_TAG}"
SYSTEMD_AUTO_ENABLE = "enable"
SYSTEMD_SERVICE_${PN}_remove = "update-resin-supervisor.timer"
SYSTEMD_SERVICE_${PN}_remove = "update-resin-supervisor.service"
do_install_append () {
sed -i -e 's:@HOMEASSISTANT_IMAGE@:${HOMEASSISTANT_IMAGE}:g' ${D}${bindir}/start-resin-supervisor
if ${@bb.utils.contains('DISTRO_FEATURES','systemd','true','false',d)}; then
rm -f ${D}${systemd_unitdir}/system/update-resin-supervisor.timer
rm -f ${D}${systemd_unitdir}/system/update-resin-supervisor.service
fi
}

View file

@ -1,22 +0,0 @@
#!/bin/sh -e
source /usr/sbin/resin-vars
source /etc/resin-supervisor/supervisor.conf
SUPERVISOR_IMAGE_ID=$(docker inspect --format='{{.Id}}' $SUPERVISOR_IMAGE)
SUPERVISOR_CONTAINER_IMAGE_ID=$(docker inspect --format='{{.Image}}' resin_supervisor || echo "")
runSupervisor() {
docker rm --force resin_supervisor || true
docker run --name resin_supervisor \
-v /var/run/docker.sock:/var/run/docker.sock \
-v /var/run/hassio-hc.sock:/var/run/hassio-hc.sock \
-v /resin-data:/data \
-v /var/log/supervisor-log:/var/log \
-e SUPERVISOR_SHARE=/resin-data \
-e SUPERVISOR_NAME=resin_supervisor \
-e HOMEASSISTANT_REPOSITORY=@HOMEASSISTANT_IMAGE@ \
${SUPERVISOR_IMAGE}
}
([ "$SUPERVISOR_IMAGE_ID" == "$SUPERVISOR_CONTAINER_IMAGE_ID" ] && docker start --attach resin_supervisor) || runSupervisor

View file

@ -1,139 +0,0 @@
#!/bin/bash
set -o pipefail
USE_LOCAL=no
# Help function
function update-resin-supervisor-help {
cat << EOF
Wrapper to run supervisor agent updates on resin distributions.
$0 <OPTION>
Options:
-h, --help
Display this help and exit.
-i <SUPERVISOR IMAGE>, --supervisor-image <SUPERVISOR IMAGE>
Set supervisor image to update to.
-t <SUPERVISOR TAG>, --supervisor-tag <SUPERVISOR TAG>
Set supervisor tag to update to.
EOF
}
# Parse arguments
while [[ $# > 0 ]]; do
arg="$1"
case $arg in
-h|--help)
update-resin-supervisor-help
exit 0
;;
-i|--supervisor-image)
if [ -z "$2" ]; then
log ERROR "\"$1\" argument needs a value."
fi
UPDATER_SUPERVISOR_IMAGE=$2
shift
;;
-t|--supervisor-tag)
if [ -z "$2" ]; then
log ERROR "\"$1\" argument needs a value."
fi
UPDATER_SUPERVISOR_TAG=$2
shift
;;
-l|--local-update)
USE_LOCAL=yes
;;
*)
log ERROR "Unrecognized option $1."
;;
esac
shift
done
# Don't souce before parsing args - resin-vars parses args too
source /usr/sbin/resin-vars
source /etc/resin-supervisor/supervisor.conf
# A temporary file used until next reboot
UPDATECONF=/tmp/update-supervisor.conf
function error_handler {
# If docker pull fails, start the old supervisor again and exit
rm -rf $UPDATECONF
systemctl start resin-supervisor
exit 1
}
trap 'error_handler $LINENO' ERR
# use HassIO API for update
if [ "$USE_LOCAL" == "no" ] && [ -f $SUPERVISOR_CONFIG ]; then
echo "Update supervisor with HassIO API"
hassio_api=$($(jq --raw-output ".api_endpoint // empty" $SUPERVISOR_CONFIG))
if [ ! -z $UPDATER_SUPERVISOR_TAG ]; then
payload="{ \"version\": \"$UPDATER_SUPERVISOR_TAG\" }"
else
payload="{}"
fi
curl -s -X GET -d "$payload" "http://$hassio_api/supervisor/update"
fi
if [ -f $SUPERVISOR_CONFIG ]; then
tag=$(jq --raw-output ".hassio_last // empty" $SUPERVISOR_CONFIG)
image_name=$SUPERVISOR_IMAGE
fi
# override from params
if [ ! -z $UPDATER_SUPERVISOR_TAG ]; then
tag=$UPDATER_SUPERVISOR_TAG
fi
if [ ! -z $UPDATER_SUPERVISOR_IMAGE ]; then
image_name=$UPDATER_SUPERVISOR_IMAGE
fi
# Check that we didn't somehow get an empty tag version.
if [ -z $tag ] || [ -z $image_name ]; then
error_handler $LINENO "no tag received"
fi
# Get image id of tag. This will be non-empty only in case it's already downloaded.
echo "Getting image id..."
imageid=$(docker inspect -f '{{.Id}}' "$image_name:$tag") || imageid=""
if [ -n "$imageid" ]; then
echo "Supervisor $image_name:$tag already downloaded."
exit 0
fi
# Try to stop old supervisor to prevent it deleting the intermediate images while downloading the new one
echo "Stop supervisor..."
systemctl stop resin-supervisor
# Pull target version.
echo "Pulling supervisor $image_name:$tag..."
docker pull "$image_name:$tag"
docker rm --force resin_supervisor || true
# Store the tagged image string so resin-supervisor.service can pick it up
echo "SUPERVISOR_IMAGE=$image_name:$tag" > $UPDATECONF
# Run supervisor with the device-type-specific options.
# We give a specific name to the container to guarantee only one running.
echo "Start supervisor..."
systemctl start resin-supervisor
# Mark supervisor as working. This version will run when the device reboots.
echo "Mark pulled tag as latest..."
docker tag "$image_name:$tag" "$image_name:latest"
sed --in-place "s|SUPERVISOR_IMAGE=.*|SUPERVISOR_IMAGE=$image_name|" /etc/resin-supervisor/supervisor.conf
sed --in-place "s|SUPERVISOR_TAG=.*|SUPERVISOR_TAG=$tag|" /etc/resin-supervisor/supervisor.conf
# cleanup old image
echo "!!! Please cleanup old supervisor manual !!!"

View file

@ -1,47 +0,0 @@
#!/bin/bash
set -o errexit
set -o nounset
DOCKER_TIMEOUT=20 # Wait 20 seconds for docker to start
# Default values
PARTITION_SIZE=${PARTITION_SIZE:=1024}
# Create sparse file to hold ext4 resin-data partition
dd if=/dev/zero of=/export/resin-data.img bs=1M count=0 seek=$PARTITION_SIZE
# now partition the newly created file to ext4
mkfs.ext4 -E lazy_itable_init=0,lazy_journal_init=0 -i 8192 -F /export/resin-data.img
# Setup the loop device with the disk image
mkdir /resin-data
mount -o loop /export/resin-data.img /resin-data
# Create the directory structures we use for Resin
mkdir -p /resin-data/docker
mkdir -p /resin-data/resin-data
# Start docker with the created image.
docker daemon -g /resin-data/docker -s aufs &
echo "Waiting for docker to become ready.."
STARTTIME=$(date +%s)
ENDTIME=$(date +%s)
while [ ! -S /var/run/docker.sock ]
do
if [ $(($ENDTIME - $STARTTIME)) -le $DOCKER_TIMEOUT ]; then
sleep 1
ENDTIME=$(date +%s)
else
echo "Timeout while waiting for docker to come up."
exit 1
fi
done
if [ -n "${TARGET_REPOSITORY}" ] && [ -n "${TARGET_TAG}" ]; then
docker pull "$TARGET_REPOSITORY:$TARGET_TAG"
docker pull "$TARGET_REPOSITORY:latest"
fi
kill -TERM $(cat /var/run/docker.pid) && wait $(cat /var/run/docker.pid) && umount /resin-data
echo "Docker export successful."

View file

@ -1,38 +0,0 @@
FILESEXTRAPATHS_prepend := "${THISDIR}/files:"
SRC_URI += " \
file://sync-authorized-keys \
file://sync-authorized-keys.service \
"
SYSTEMD_SERVICE_${PN} += "sync-authorized-keys.service"
FILES_${PN} += " \
${systemd_unitdir} \
${bindir} \
"/home/root/.ssh/" \
"
RDEPENDS_${PN} += "bash"
do_install_append() {
install -d ${D}/home/root/.ssh
install -d ${D}${bindir}
install -m 0755 ${WORKDIR}/sync-authorized-keys ${D}${bindir}
if [ "${RESIN_CONNECTABLE_ENABLE_SERVICES}" = "1" ]; then
rm -fr ${D}${localstatedir}/lib/dropbear/
rm -f ${D}/home/root/.ssh/authorized_keys
fi
if ${@bb.utils.contains('DISTRO_FEATURES','systemd','true','false',d)}; then
install -d ${D}${systemd_unitdir}/system
install -c -m 0644 ${WORKDIR}/sync-authorized-keys.service ${D}${systemd_unitdir}/system
sed -i -e 's,@BASE_BINDIR@,${base_bindir},g' \
-e 's,@SBINDIR@,${sbindir},g' \
-e 's,@BINDIR@,${bindir},g' \
${D}${systemd_unitdir}/system/*.service
fi
}

View file

@ -1,11 +0,0 @@
#!/bin/bash
set -e
BOOT_SSH_KEY=/mnt/boot/authorized_keys
HOME_SSH_KEY=/home/root/.ssh/authorized_keys
if [ -f $BOOT_SSH_KEY ]; then
cp $BOOT_SSH_KEY $HOME_SSH_KEY
chmod 0600 $HOME_SSH_KEY
fi

View file

@ -1,13 +0,0 @@
[Unit]
Description=SSH authorized_keys sync
Requires=home-root-.ssh.mount mnt-boot.mount
After=home-root-.ssh.mount mnt-boot.mount
Before=etc-dropbear.mount
[Service]
Type=oneshot
RemainAfterExit=yes
ExecStart=@BASE_BINDIR@/bash @BINDIR@/sync-authorized-keys
[Install]
WantedBy=multi-user.target

View file

@ -1,2 +0,0 @@
CONNECTIVITY_PACKAGES_remove = "openvpn"

View file

@ -1,4 +0,0 @@
RDEPENDS_${PN}_remove = "resin-connectable"
RDEPENDS_${PN}_remove = "resin-provisioner"
RDEPENDS_${PN}_append = " hassio-host-controll"

Binary file not shown.

Before

Width:  |  Height:  |  Size: 33 KiB

View file

@ -1 +0,0 @@
FILESEXTRAPATHS_prepend := "${THISDIR}/${PN}:"

View file

@ -1,41 +0,0 @@
DESCRIPTION = "hassio device controll"
SECTION = "console/utils"
LICENSE = "Apache-2.0"
LIC_FILES_CHKSUM = "file://${RESIN_COREBASE}/COPYING.Apache-2.0;md5=89aea4e17d99a7cacdbeed46a0096b10"
SRC_URI = " \
file://hassio-hc \
file://hassio-hc.service \
"
inherit allarch systemd
SYSTEMD_SERVICE_${PN} += "hassio-hc.service"
SYSTEMD_AUTO_ENABLE = "enable"
RDEPENDS_${PN} = " \
bash \
socat \
"
FILES_${PN} += " \
${systemd_unitdir} \
${bindir} \
"
do_install() {
install -d ${D}${bindir}
install -m 0775 ${WORKDIR}/hassio-hc ${D}${bindir}/hassio-hc
sed -i -e 's:@RESINOS_HASSIO_VERSION@:${RESINOS_HASSIO_VERSION}:g' ${D}${bindir}/hassio-hc
if ${@bb.utils.contains('DISTRO_FEATURES','systemd','true','false',d)}; then
install -d ${D}${systemd_unitdir}/system
install -c -m 0644 ${WORKDIR}/hassio-hc.service ${D}${systemd_unitdir}/system
sed -i -e 's,@BASE_BINDIR@,${base_bindir},g' \
-e 's,@SBINDIR@,${sbindir},g' \
-e 's,@BINDIR@,${bindir},g' \
${D}${systemd_unitdir}/system/*.service
fi
}

View file

@ -1,66 +0,0 @@
#!/bin/bash
set -e
# shellcheck disable=SC1091
source /usr/sbin/resin-vars
# shellcheck disable=SC1091
source /etc/resin-supervisor/supervisor.conf
VERSION=@RESINOS_HASSIO_VERSION@
#
# MAIN
#
while read -r cmd
do
IFS=" " read -r -a parse <<< "$cmd"
if [ "${parse[0]}" == "info" ]; then
HOSTNAME=$(hostname)
OS=$(uname -o)
LAST=$(curl -s "$ENDPOINT" | jq -e -r '.resinos')
FEATURES="[\"shutdown\", \"reboot\", \"update\", \"hostname\"]"
echo "{ \"type\": \"resinos\", \"version\": \"$VERSION\", \"last_version\": \"$LAST\", \"hostname\": \"$HOSTNAME\", \"features\": $FEATURES, \"os\": \"$OS\" }"
continue
fi
if [ "${parse[0]}" == "reboot" ]; then
systemctl reboot && echo "OK" || echo "ERROR"
continue
fi
if [ "${parse[0]}" == "shutdown" ]; then
systemctl poweroff && echo "OK" || echo "ERROR"
continue
fi
if [ "${parse[0]}" == "update" ]; then
if [ ! -z "${parse[1]}" ]; then
nohup resinhup --hostos-version "${parse[1]}" > /dev/null 2>&1 &
else
nohup resinhup > /dev/null 2>&1 &
fi
sleep 4 && echo "OK"
continue
fi
if [ "${parse[0]}" == "hostname" ]; then
NEW_HOSTNAME="${parse[1]}"
if [ -z "$NEW_HOSTNAME" ]; then
echo "ERROR" && continue
fi
if ! hostname "$NEW_HOSTNAME"
then
echo "ERROR" && continue
fi
# shellcheck disable=SC2005
echo "$(jq ".hostname=\"$NEW_HOSTNAME\"" < "$CONFIG_PATH")" > "$CONFIG_PATH"
echo "$NEW_HOSTNAME" > /etc/hostname
echo "OK" && continue
fi
echo "WRONG"
done

View file

@ -1,11 +0,0 @@
[Unit]
Description=HassIO HostControll
Wants=resin-supervisor.service
Before=resin-supervisor.service
[Service]
Type=simple
ExecStart=@BINDIR@/socat UNIX-LISTEN:/var/run/hassio-hc.sock,fork EXEC:@BINDIR@/hassio-hc
[Install]
WantedBy=resin.target

View file

@ -1,2 +0,0 @@
FILESEXTRAPATHS_prepend := "${THISDIR}/${PN}:"

View file

@ -1,2 +0,0 @@
FILESEXTRAPATHS_prepend := "${THISDIR}/${PN}:"

View file

@ -1,17 +0,0 @@
FILESEXTRAPATHS_prepend := "${THISDIR}/${PN}:"
SRC_URI += " \
file://home-root-.ssh.mount \
"
SYSTEMD_SERVICE_${PN} += " \
home-root-.ssh.mount \
"
do_install_append () {
if ${@bb.utils.contains('DISTRO_FEATURES','systemd','true','false',d)}; then
install -d ${D}${systemd_unitdir}/system
install -c -m 0644 ${WORKDIR}/home-root-.ssh.mount ${D}${systemd_unitdir}/system
fi
}

View file

@ -1,14 +0,0 @@
[Unit]
Description=SSH authorized_keys state bind mount
Requires=mnt-state.mount resin-state-reset.service
After=mnt-state.mount resin-state-reset.service
Before=etc-dropbear.mount
[Mount]
What=/mnt/state/root-overlay/home/root/.ssh
Where=/home/root/.ssh
Type=none
Options=bind
[Install]
WantedBy=resin-bind.target

View file

@ -1,2 +0,0 @@
FILESEXTRAPATHS_prepend := "${THISDIR}/${PN}:"

View file

@ -1,57 +0,0 @@
#!/bin/bash
help () {
cat << EOF
Script for setting resin shell environment
resin-vars [options]
Options:
-h, --help
Display this help and exit.
-c, --config-path CONFIG_PATH
Use a non default config.json file.
Default: /mnt/boot/config.json
EOF
}
# Parse arguments
while [[ $# > 0 ]]; do
key=$1
case $key in
-h|--help)
help
exit 0
;;
-c|--config-path)
CONFIG_PATH=$2
shift
;;
*)
echo "[WARNING] $0 : Argument '$1' unknown. Ignoring."
;;
esac
shift
done
# Resin-boot mountpoint
BOOT_MOUNTPOINT="/mnt/boot"
# HassIO config file
SUPERVISOR_CONFIG="/resin-data/config.json"
# Default values
if [ -z "$CONFIG_PATH" ]; then
CONFIG_PATH=$BOOT_MOUNTPOINT/config.json
fi
# If config.json provides redefinitions for our vars let us rewrite their
# runtime value
if [ -f $CONFIG_PATH ]
then
ENDPOINT=$(jq --raw-output '.endpoint // "https://raw.githubusercontent.com/home-assistant/hassio/master/version.json"' $CONFIG_PATH)
CONFIG_HOSTNAME=$(jq --raw-output '.hostname // "hassio"' $CONFIG_PATH)
PERSISTENT_LOGGING=$(jq --raw-output '.persistentLogging // false' $CONFIG_PATH)
else
echo "[WARNING] $0 : '$CONFIG_PATH' not found."
fi

View file

@ -1,12 +0,0 @@
FILESEXTRAPATHS_prepend := "${THISDIR}/${PN}:"
SRC_URI += "file://resinhup"
do_install_append() {
install -d ${D}${bindir}
install -m 0755 ${WORKDIR}/resinhup ${D}${bindir}
sed -i -e 's:@MACHINE@:${HASSIO_MACHINE}:g' ${D}${bindir}/resinhup
sed -i -e 's:@RESINOS_HASSIO_VERSION@:${RESINOS_HASSIO_VERSION}:g' ${D}${bindir}/resinhup
}

View file

@ -1,276 +0,0 @@
#!/bin/bash
set -e
# Default values
LOGFILE=/tmp/`basename "$0"`.log
LOG=yes
ONLY_SUPERVISOR=no
NOREBOOT=no
DOCKER_REPO=homeassistant
MACHINE=@MACHINE@
RESINOS_HASSIO_VERSION=@RESINOS_HASSIO_VERSION@
# 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.
-n, --nolog
By default tool logs to stdout and file. This flag deactivates log to
$LOGFILE file.
--no-reboot
Dont 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 || true
}
# 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|--resinhup-version)
if [ -z "$2" ]; then
log ERROR "\"$1\" argument needs a value."
fi
RESINHUP_VERSION=$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
;;
-n|--nolog)
LOG=no
;;
--no-reboot)
NOREBOOT=yes
;;
*)
log ERROR "Unrecognized option $1."
;;
esac
shift
done
# load config
source /usr/sbin/resin-vars
# Check that HostOS version was provided
if [ -z "$HOSTOS_VERSION" ]; then
if version=$(curl --silent $ENDPOINT | jq -e -r '.resinos'); then
HOSTOS_VERSION=$version
else
log ERROR "--hostos-version is required."
fi
fi
if [ -z $RESINHUP_VERSION ]; then
if version=$(curl --silent $ENDPOINT | jq -e -r '.resinhup'); then
RESINHUP_VERSION=$version
else
log ERROR "--resinhup-version is required."
fi
fi
# Init log file
# LOGFILE init and header
if [ "$LOG" == "yes" ]; then
echo "================"`basename "$0"`" HEADER START====================" > $LOGFILE
date >> $LOGFILE
fi
# Check if update is needed
log "Detected HassIO version: $RESINOS_HASSIO_VERSION ."
log "Update HassIO to version: $HOSTOS_VERSION ."
if [ $RESINOS_HASSIO_VERSION == $HOSTOS_VERSION ]; then
log "Version $HOSTOS_VERSION is already installed."
exit 0
fi
# protect downgrade
downgrade=$(awk -vn1=$RESINOS_HASSIO_VERSION -vn2=$HOSTOS_VERSION 'BEGIN{print (n1<n2) ? 0:1}')
if [ $downgrade == 1 ]; then
log ERROR "Downgrade are not supported"
exit 0
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
# 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:$MACHINE-$RESINHUP_VERSION
if [ $? -ne 0 ]; then
tryup
log ERROR "Could not pull $DOCKER_REPO/resinhup:$MACHINE-$RESINHUP_VERSION ."
fi
# Run resinhup
log "Running resinhup for version $HOSTOS_VERSION ..."
RESINHUP_STARTTIME=$(date +%s)
# Set options
RESINHUP_ENV="-e VERSION=$HOSTOS_VERSION-$MACHINE -e REMOTE=$DOCKER_REPO/resinos-hassio"
docker run --privileged --rm --net=host $RESINHUP_ENV \
-v /:/host \
-v /lib/modules:/lib/modules:ro \
-v /var/run/docker.sock:/var/run/docker.sock \
$DOCKER_REPO/resinhup:$MACHINE-$RESINHUP_VERSION
RESINHUP_EXIT=$?
docker rmi $DOCKER_REPO/resinhup:$MACHINE-$RESINHUP_VERSION || true
docker rmi $DOCKER_REPO/resinos-hassio:$HOSTOS_VERSION-$MACHINE || true
# 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 " > /dev/null 2>&1 &
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