Created
September 17, 2020 18:20
-
-
Save xginn8/26f7cddf0da1c79365c3522bb133c3ec to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/bin/sh | |
# | |
# Script to deploy the boot files from rootfs to the boot partition | |
# | |
# This hook is meant to run in the `next` resinOS container | |
# | |
set -o errexit | |
# Variables | |
boot_fingerprint="@RESIN_BOOT_FINGERPRINT@" | |
bootfiles_blacklist="\ | |
/config.json \ | |
/config.txt \ | |
/extlinux/extlinux.conf \ | |
/splash/balena-logo.png \ | |
" | |
boot_mountpoint="/mnt/boot" | |
DURING_UDPATE=${DURING_UPDATE:-0} | |
# Checks if a file is present in the blacklist | |
# Arguments: | |
# $1: file to be checked | |
# Return value: | |
# 0: file is blacklisted | |
# 1: file is not blacklisted | |
isBlacklisted() { | |
local _file="$1" | |
for b in $bootfiles_blacklist; do | |
if [ "$b" = "$_file" ]; then | |
return 0 | |
fi | |
done | |
return 1 | |
} | |
# Checks if a file was modified by verifying its fingerprint | |
# Arguments: | |
# $1: file to be checked | |
# Return value: | |
# 0: file is modified | |
# 1: file is not modified | |
isModified() { | |
local _file="$1" | |
local _current_md5 | |
_current_md5="$(md5sum "$boot_mountpoint/$_file" | awk '{print $1}')" | |
local _initial_md5 | |
_initial_md5="$(grep "$_file" < "$boot_mountpoint/$boot_fingerprint" | awk '{print $1}')" | |
if [ "$_current_md5" != "$_initial_md5" ]; then | |
return 0 | |
else | |
return 1 | |
fi | |
} | |
# Copies a file from /resin-boot to boot partition filesystem atomically and durable | |
# Arguments: | |
# $1: boot partition file | |
copyBootFile() { | |
local _file="$1" | |
mkdir -p "$boot_mountpoint/$(dirname "$_file")" | |
if cp "/resin-boot/$_file" "$boot_mountpoint/$_file.new"; then | |
sync -f $boot_mountpoint | |
mv "$boot_mountpoint/$_file.new" "$boot_mountpoint/$_file" | |
sync -f $boot_mountpoint | |
else | |
if [ "$DURING_UPDATE" = "1" ]; then | |
# Cleanup all new files we deployed | |
find "$boot_mountpoint" -type f -name "*.new" -exec rm -f {} \; | |
for file in $new_deployed_files; do | |
rm -f "$boot_mountpoint/$file" | |
done | |
exit 1 | |
fi | |
fi | |
} | |
# Deploys files to boot partition | |
# Arguments: | |
# $1: file path relative to boot partition's root | |
deploy() { | |
local _file="$1" | |
printf "[INFO] Deploying %s%s..." "${boot_mountpoint}" "${_file}" | |
if isBlacklisted "$_file"; then | |
if [ "$_file" = "/splash/balena-logo.png" ]; then | |
if [ -f "$boot_mountpoint/splash/resin-logo.png" ]; then | |
if isModified "/splash/resin-logo.png"; then | |
# Keep custom logo | |
printf "renaming resin-logo to balena-logo..." | |
sync -f $boot_mountpoint | |
mv $boot_mountpoint/splash/resin-logo.png $boot_mountpoint/splash/balena-logo.png | |
sync -f $boot_mountpoint | |
else | |
# This rebrands from old resin logo | |
printf "replacing resin-logo with balena-logo..." | |
copyBootFile "$_file" | |
rm "$boot_mountpoint/splash/resin-logo.png" | |
fi | |
printf " done.\n" | |
return | |
fi | |
fi | |
printf "file blacklisted. Ignoring.\n" | |
else | |
if [ -f "$boot_mountpoint/$_file" ]; then | |
if isModified "$_file"; then | |
printf " overwriting modified file..." | |
copyBootFile "$_file" | |
printf " done.\n" | |
else | |
copyBootFile "$_file" | |
printf " done.\n" | |
fi | |
else | |
new_deployed_files="$new_deployed_files $_file" | |
printf " new file..." | |
copyBootFile "$_file" | |
printf " done.\n" | |
fi | |
fi | |
} | |
# | |
# MAIN | |
# | |
# Do a dry run for copying the boot files and figure out if we would get in an | |
# out of space situation | |
boot_space="$(df -B1 --output=avail $boot_mountpoint | grep -v Avail)" | |
available="$boot_space" | |
available_threshold="524288" # All sizes in bytes | |
printf "[INFO] Checking if boot partition can accommodate the new update... " | |
for filepath in $(find /resin-boot -type f | sed 's#^/resin-boot##g'); do | |
if isBlacklisted "$filepath"; then | |
continue | |
fi | |
filesize=$(stat --format %s "/resin-boot${filepath}") | |
available="$((available - filesize))" | |
if [ "$available" -lt "$available_threshold" ]; then | |
echo "fail." | |
echo "[ERROR] Boot files copy operations will fail with out of space error." | |
if [ "$DURING_UPDATE" = "1" ]; then | |
exit 1 | |
fi | |
fi | |
if [ -f "${boot_mountpoint}${filepath}" ]; then | |
available="$((available + $(stat --format %s "${boot_mountpoint}${filepath}")))" | |
fi | |
done | |
echo "success." | |
# Deploy all files in the bootfiles list except fingerprint | |
new_deployed_files="" | |
for filepath in $(find /resin-boot -type f | sed 's#^/resin-boot##g'); do | |
if [ "$filepath" != "/$boot_fingerprint" ]; then | |
deploy "$filepath" | |
fi | |
done | |
# Deploy fingerprint last | |
deploy "/$boot_fingerprint" |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment