mirror of https://github.com/lukechilds/umbrel.git
9 changed files with 696 additions and 72 deletions
@ -1,71 +1,5 @@ |
|||
#!/usr/bin/env bash |
|||
|
|||
check_dependencies () { |
|||
for cmd in "$@"; do |
|||
if ! command -v "$cmd" >/dev/null 2>&1; then |
|||
echo "This script requires \"${cmd}\" to be installed" |
|||
exit 1 |
|||
fi |
|||
done |
|||
} |
|||
UMBREL_ROOT="$(readlink -f $(dirname "${BASH_SOURCE[0]}")/../..)" |
|||
|
|||
check_dependencies jq wget git rsync |
|||
|
|||
# UMBREL_ROOT=/home/umbrel |
|||
UMBREL_ROOT=$(dirname $(readlink -f "${BASH_SOURCE[0]}"))/../.. |
|||
RELEASE=$(cat "$UMBREL_ROOT"/statuses/update-status.json | jq .updateTo -r) |
|||
|
|||
echo |
|||
echo "=======================================" |
|||
echo "============= OTA UPDATE ==============" |
|||
echo "=======================================" |
|||
echo "========== Stage: Download ============" |
|||
echo "=======================================" |
|||
echo |
|||
|
|||
# Make sure an update is not in progres |
|||
if [[ -f "$UMBREL_ROOT/statuses/update-in-progress" ]]; then |
|||
echo "An update is already in progress. Exiting now." |
|||
exit 2 |
|||
fi |
|||
|
|||
echo "Creating lock" |
|||
touch "$UMBREL_ROOT"/statuses/update-in-progress |
|||
|
|||
# Cleanup just in case there's temp stuff lying around from previous update |
|||
echo "Cleaning up any previous mess" |
|||
[[ -d "$UMBREL_ROOT"/.umbrel-"$RELEASE" ]] && rm -rf "$UMBREL_ROOT"/.umbrel-"$RELEASE" |
|||
|
|||
# Update status file |
|||
cat <<EOF > "$UMBREL_ROOT"/statuses/update-status.json |
|||
{"state": "installing", "progress": 10, "description": "Downloading Umbrel $RELEASE", "updateTo": "$RELEASE"} |
|||
EOF |
|||
|
|||
# Clone new release |
|||
echo "Downloading Umbrel $RELEASE" |
|||
mkdir -p "$UMBREL_ROOT"/.umbrel-"$RELEASE" |
|||
cd "$UMBREL_ROOT"/.umbrel-"$RELEASE" |
|||
curl -L "https://github.com/getumbrel/umbrel/archive/$RELEASE.tar.gz" | tar -xz --strip-components=1 |
|||
|
|||
# Run update scripts |
|||
echo "Running update install scripts of the new release" |
|||
cd scripts/update |
|||
UPDATE_INSTALL_SCRIPTS=$(ls *-run.sh) |
|||
for script in $UPDATE_INSTALL_SCRIPTS; do |
|||
if [[ -x $script ]]; then |
|||
echo |
|||
echo "== Begin Update Script $script ==" |
|||
./"$script" "$RELEASE" "$UMBREL_ROOT" |
|||
echo "== End Update Script $script ==" |
|||
echo |
|||
fi |
|||
done |
|||
|
|||
# Delete cloned repo |
|||
echo "Deleting cloned repository" |
|||
[[ -d "$UMBREL_ROOT"/.umbrel-"$RELEASE" ]] && rm -rf "$UMBREL_ROOT"/.umbrel-"$RELEASE" |
|||
|
|||
echo "Removing lock" |
|||
rm -f "$UMBREL_ROOT"/statuses/update-in-progress |
|||
|
|||
exit 0 |
|||
"${UMBREL_ROOT}/scripts/update/update" --ota |
|||
|
@ -0,0 +1,58 @@ |
|||
#!/usr/bin/env bash |
|||
|
|||
set -euo pipefail |
|||
|
|||
UMBREL_ROOT="$(readlink -f $(dirname "${BASH_SOURCE[0]}")/../../..)" |
|||
SD_MOUNT_POINT="/sd-root" |
|||
SD_UMBREL_ROOT="${SD_MOUNT_POINT}${UMBREL_ROOT}" |
|||
|
|||
check_root () { |
|||
if [[ $UID != 0 ]]; then |
|||
echo "This script must be run as root" |
|||
exit 1 |
|||
fi |
|||
} |
|||
|
|||
check_dependencies () { |
|||
for cmd in "$@"; do |
|||
if ! command -v $cmd >/dev/null 2>&1; then |
|||
echo "This script requires \"${cmd}\" to be installed" |
|||
exit 1 |
|||
fi |
|||
done |
|||
} |
|||
|
|||
check_semver_range () { |
|||
local range="${1}" |
|||
local version="${2}" |
|||
"${UMBREL_ROOT}/scripts/umbrel-os/semver" -r "${range}" "${version}" | grep --quiet "^${version}$" |
|||
} |
|||
|
|||
main () { |
|||
check_root |
|||
check_dependencies jq |
|||
echo "Checking if SD card Umbrel is newer than external storage..." |
|||
local external_version=$(cat "${UMBREL_ROOT}/info.json" | jq -r .version | cut -d "-" -f "1") |
|||
local sd_version=$(cat "${SD_UMBREL_ROOT}/info.json" | jq -r .version | cut -d "-" -f "1") |
|||
|
|||
if ! check_semver_range ">${external_version}" "${sd_version}"; then |
|||
echo "No, SD version is not newer, exiting." |
|||
exit 0 |
|||
fi |
|||
|
|||
echo "Yes, SD version is newer." |
|||
# This will fail if we ever have multiple ranges with pre-release tags. |
|||
# e.g `1.2.3-beta <2.0.0` will become `1.2.3` due to striping the `-` |
|||
local update_requirement=$(cat "${SD_UMBREL_ROOT}/info.json" | jq -r .requires | cut -d "-" -f "1") |
|||
|
|||
echo "Checking if the external storage version \"${external_version}\" satisfies update requirement \"${update_requirement}\"..." |
|||
if ! check_semver_range "${update_requirement}" "${external_version}"; then |
|||
echo "No, we can't do an automatic update, exiting." |
|||
exit 0 |
|||
fi |
|||
|
|||
echo "Yes, it does, attempting an automatic update..." |
|||
"${UMBREL_ROOT}/scripts/update/update" --path "${SD_UMBREL_ROOT}" |
|||
} |
|||
|
|||
main |
@ -0,0 +1,521 @@ |
|||
#!/usr/bin/env bash |
|||
|
|||
# https://github.com/qzb/sh-semver |
|||
# Commit: 2ac2437 |
|||
|
|||
_num_part='([0-9]|[1-9][0-9]*)' |
|||
_lab_part='([0-9]|[1-9][0-9]*|[0-9]*[a-zA-Z-][a-zA-Z0-9-]*)' |
|||
_met_part='([0-9A-Za-z-]+)' |
|||
|
|||
RE_NUM="$_num_part(\.$_num_part)*" |
|||
RE_LAB="$_lab_part(\.$_lab_part)*" |
|||
RE_MET="$_met_part(\.$_met_part)*" |
|||
RE_VER="[ \t]*$RE_NUM(-$RE_LAB)?(\+$RE_MET)?" |
|||
|
|||
BRE_DIGIT='[0-9]\{1,\}' |
|||
BRE_ALNUM='[0-9a-zA-Z-]\{1,\}' |
|||
BRE_IDENT="$BRE_ALNUM\(\.$BRE_ALNUM\)*" |
|||
|
|||
BRE_MAJOR="$BRE_DIGIT" |
|||
BRE_MINOR="\(\.$BRE_DIGIT\)\{0,1\}" |
|||
BRE_PATCH="\(\.$BRE_DIGIT\)\{0,1\}" |
|||
BRE_PRERE="\(-$BRE_IDENT\)\{0,1\}" |
|||
BRE_BUILD="\(+$BRE_IDENT\)\{0,1\}" |
|||
BRE_VERSION="${BRE_MAJOR}${BRE_MINOR}${BRE_PATCH}${BRE_PRERE}${BRE_BUILD}" |
|||
|
|||
filter() |
|||
{ |
|||
local text="$1" |
|||
local regex="$2" |
|||
shift 2 |
|||
echo "$text" | grep -E "$@" "$regex" |
|||
} |
|||
|
|||
# Gets number part from normalized version |
|||
get_number() |
|||
{ |
|||
echo "${1%%-*}" |
|||
} |
|||
|
|||
# Gets prerelase part from normalized version |
|||
get_prerelease() |
|||
{ |
|||
local pre_and_meta=${1%+*} |
|||
local pre=${pre_and_meta#*-} |
|||
if [ "$pre" = "$1" ]; then |
|||
echo |
|||
else |
|||
echo "$pre" |
|||
fi |
|||
} |
|||
|
|||
# Gets major number from normalized version |
|||
get_major() |
|||
{ |
|||
echo "${1%%.*}" |
|||
} |
|||
|
|||
# Gets minor number from normalized version |
|||
get_minor() |
|||
{ |
|||
local minor_major_bug=${1%%-*} |
|||
local minor_major=${minor_major_bug%.*} |
|||
local minor=${minor_major#*.} |
|||
|
|||
if [ "$minor" = "$minor_major" ]; then |
|||
echo |
|||
else |
|||
echo "$minor" |
|||
fi |
|||
} |
|||
|
|||
get_bugfix() |
|||
{ |
|||
local minor_major_bug=${1%%-*} |
|||
local bugfix=${minor_major_bug##*.*.} |
|||
|
|||
if [ "$bugfix" = "$minor_major_bug" ]; then |
|||
echo |
|||
else |
|||
echo "$bugfix" |
|||
fi |
|||
} |
|||
|
|||
strip_metadata() |
|||
{ |
|||
echo "${1%+*}" |
|||
} |
|||
|
|||
semver_eq() |
|||
{ |
|||
local ver1 ver2 part1 part2 |
|||
ver1=$(get_number "$1") |
|||
ver2=$(get_number "$2") |
|||
|
|||
local count=1 |
|||
while true; do |
|||
part1=$(echo "$ver1"'.' | cut -d '.' -f $count) |
|||
part2=$(echo "$ver2"'.' | cut -d '.' -f $count) |
|||
|
|||
if [ -z "$part1" ] || [ -z "$part2" ]; then |
|||
break |
|||
fi |
|||
|
|||
if [ "$part1" != "$part2" ]; then |
|||
return 1 |
|||
fi |
|||
|
|||
local count=$(( count + 1 )) |
|||
done |
|||
|
|||
if [ "$(get_prerelease "$1")" = "$(get_prerelease "$2")" ]; then |
|||
return 0 |
|||
else |
|||
return 1 |
|||
fi |
|||
} |
|||
|
|||
semver_lt() |
|||
{ |
|||
local number_a number_b prerelease_a prerelease_b |
|||
number_a=$(get_number "$1") |
|||
number_b=$(get_number "$2") |
|||
prerelease_a=$(get_prerelease "$1") |
|||
prerelease_b=$(get_prerelease "$2") |
|||
|
|||
|
|||
local head_a='' |
|||
local head_b='' |
|||
local rest_a=$number_a. |
|||
local rest_b=$number_b. |
|||
while [ -n "$rest_a" ] || [ -n "$rest_b" ]; do |
|||
head_a=${rest_a%%.*} |
|||
head_b=${rest_b%%.*} |
|||
rest_a=${rest_a#*.} |
|||
rest_b=${rest_b#*.} |
|||
|
|||
if [ -z "$head_a" ] || [ -z "$head_b" ]; then |
|||
return 1 |
|||
fi |
|||
|
|||
if [ "$head_a" -eq "$head_b" ]; then |
|||
continue |
|||
fi |
|||
|
|||
if [ "$head_a" -lt "$head_b" ]; then |
|||
return 0 |
|||
else |
|||
return 1 |
|||
fi |
|||
done |
|||
|
|||
if [ -n "$prerelease_a" ] && [ -z "$prerelease_b" ]; then |
|||
return 0 |
|||
elif [ -z "$prerelease_a" ] && [ -n "$prerelease_b" ]; then |
|||
return 1 |
|||
fi |
|||
|
|||
local head_a='' |
|||
local head_b='' |
|||
local rest_a=$prerelease_a. |
|||
local rest_b=$prerelease_b. |
|||
while [ -n "$rest_a" ] || [ -n "$rest_b" ]; do |
|||
head_a=${rest_a%%.*} |
|||
head_b=${rest_b%%.*} |
|||
rest_a=${rest_a#*.} |
|||
rest_b=${rest_b#*.} |
|||
|
|||
if [ -z "$head_a" ] && [ -n "$head_b" ]; then |
|||
return 0 |
|||
elif [ -n "$head_a" ] && [ -z "$head_b" ]; then |
|||
return 1 |
|||
fi |
|||
|
|||
if [ "$head_a" = "$head_b" ]; then |
|||
continue |
|||
fi |
|||
|
|||
# If both are numbers then compare numerically |
|||
if [ "$head_a" = "${head_a%[!0-9]*}" ] && [ "$head_b" = "${head_b%[!0-9]*}" ]; then |
|||
[ "$head_a" -lt "$head_b" ] && return 0 || return 1 |
|||
# If only a is a number then return true (number has lower precedence than strings) |
|||
elif [ "$head_a" = "${head_a%[!0-9]*}" ]; then |
|||
return 0 |
|||
# If only b is a number then return false |
|||
elif [ "$head_b" = "${head_b%[!0-9]*}" ]; then |
|||
return 1 |
|||
# Finally if of identifiers is a number compare them lexically |
|||
else |
|||
test "$head_a" \< "$head_b" && return 0 || return 1 |
|||
fi |
|||
done |
|||
|
|||
return 1 |
|||
} |
|||
|
|||
semver_gt() |
|||
{ |
|||
if semver_lt "$1" "$2" || semver_eq "$1" "$2"; then |
|||
return 1 |
|||
else |
|||
return 0 |
|||
fi |
|||
} |
|||
|
|||
semver_le() |
|||
{ |
|||
semver_gt "$1" "$2" && return 1 || return 0 |
|||
} |
|||
|
|||
semver_ge() |
|||
{ |
|||
semver_lt "$1" "$2" && return 1 || return 0 |
|||
} |
|||
|
|||
semver_sort() |
|||
{ |
|||
if [ $# -le 1 ]; then |
|||
echo "$1" |
|||
return |
|||
fi |
|||
|
|||
local pivot=$1 |
|||
local args_a=() |
|||
local args_b=() |
|||
|
|||
shift 1 |
|||
|
|||
for ver in "$@"; do |
|||
if semver_le "$ver" "$pivot"; then |
|||
args_a=( "${args_a[@]}" "$ver" ) |
|||
else |
|||
args_b=( "$ver" "${args_b[@]}" ) |
|||
fi |
|||
done |
|||
|
|||
args_a=( $(semver_sort "${args_a[@]}") ) |
|||
args_b=( $(semver_sort "${args_b[@]}") ) |
|||
echo "${args_a[@]}" "$pivot" "${args_b[@]}" |
|||
} |
|||
|
|||
regex_match() |
|||
{ |
|||
local string="$1 " |
|||
local regexp="$2" |
|||
local match |
|||
match="$(eval "echo '$string' | grep -E -o '^[ \t]*($regexp)[ \t]+'")"; |
|||
|
|||
for i in $(seq 0 9); do |
|||
unset "MATCHED_VER_$i" |
|||
unset "MATCHED_NUM_$i" |
|||
done |
|||
unset REST |
|||
|
|||
if [ -z "$match" ]; then |
|||
return 1 |
|||
fi |
|||
|
|||
local match_len=${#match} |
|||
REST="${string:$match_len}" |
|||
|
|||
local part |
|||
local i=1 |
|||
for part in $string; do |
|||
local ver num |
|||
ver="$(eval "echo '$part' | grep -E -o '$RE_VER' | head -n 1 | sed 's/ \t//g'")"; |
|||
num=$(get_number "$ver") |
|||
|
|||
if [ -n "$ver" ]; then |
|||
eval "MATCHED_VER_$i='$ver'" |
|||
eval "MATCHED_NUM_$i='$num'" |
|||
i=$(( i + 1 )) |
|||
fi |
|||
done |
|||
|
|||
return 0 |
|||
} |
|||
|
|||
# Normalizes rules string |
|||
# |
|||
# * replaces chains of whitespaces with single spaces |
|||
# * replaces whitespaces around hyphen operator with "_" |
|||
# * removes wildcards from version numbers (1.2.* -> 1.2) |
|||
# * replaces "x" with "*" |
|||
# * removes whitespace between operators and version numbers |
|||
# * removes leading "v" from version numbers |
|||
# * removes leading and trailing spaces |
|||
normalize_rules() |
|||
{ |
|||
echo " $1" \ |
|||
| sed 's/\\t/ /g' \ |
|||
| sed 's/ / /g' \ |
|||
| sed 's/ \{2,\}/ /g' \ |
|||
| sed 's/ - /_-_/g' \ |
|||
| sed 's/\([~^<>=]\) /\1/g' \ |
|||
| sed 's/\([ _~^<>=]\)v/\1/g' \ |
|||
| sed 's/\.[xX*]//g' \ |
|||
| sed 's/[xX]/*/g' \ |
|||
| sed 's/^ //g' \ |
|||
| sed 's/ $//g' |
|||
} |
|||
|
|||
# Reads rule from provided string |
|||
resolve_rule() |
|||
{ |
|||
local rule operator operands |
|||
rule="$1" |
|||
operator="$( echo "$rule" | sed "s/$BRE_VERSION/#/g" )" |
|||
operands=( $( echo "$rule" | grep -o "$BRE_VERSION") ) |
|||
|
|||
case "$operator" in |
|||
'*') echo "all" ;; |
|||
'#') echo "eq ${operands[0]}" ;; |
|||
'=#') echo "eq ${operands[0]}" ;; |
|||
'<#') echo "lt ${operands[0]}" ;; |
|||
'>#') echo "gt ${operands[0]}" ;; |
|||
'<=#') echo "le ${operands[0]}" ;; |
|||
'>=#') echo "ge ${operands[0]}" ;; |
|||
'#_-_#') echo "ge ${operands[0]}" |
|||
echo "le ${operands[1]}" ;; |
|||
'~#') echo "tilde ${operands[0]}" ;; |
|||
'^#') echo "caret ${operands[0]}" ;; |
|||
*) return 1 |
|||
esac |
|||
} |
|||
|
|||
resolve_rules() |
|||
{ |
|||
local rules |
|||
rules="$(normalize_rules "$1")" |
|||
IFS=' ' read -ra rules <<< "${rules:-all}" |
|||
|
|||
for rule in "${rules[@]}"; do |
|||
resolve_rule "$rule" |
|||
done |
|||
} |
|||
|
|||
rule_eq() |
|||
{ |
|||
local rule_ver="$1" |
|||
local tested_ver="$2" |
|||
|
|||
semver_eq "$tested_ver" "$rule_ver" && return 0 || return 1; |
|||
} |
|||
|
|||
rule_le() |
|||
{ |
|||
local rule_ver="$1" |
|||
local tested_ver="$2" |
|||
|
|||
semver_le "$tested_ver" "$rule_ver" && return 0 || return 1; |
|||
} |
|||
|
|||
rule_lt() |
|||
{ |
|||
local rule_ver="$1" |
|||
local tested_ver="$2" |
|||
|
|||
semver_lt "$tested_ver" "$rule_ver" && return 0 || return 1; |
|||
} |
|||
|
|||
rule_ge() |
|||
{ |
|||
local rule_ver="$1" |
|||
local tested_ver="$2" |
|||
|
|||
semver_ge "$tested_ver" "$rule_ver" && return 0 || return 1; |
|||
} |
|||
|
|||
rule_gt() |
|||
{ |
|||
local rule_ver="$1" |
|||
local tested_ver="$2" |
|||
|
|||
semver_gt "$tested_ver" "$rule_ver" && return 0 || return 1; |
|||
} |
|||
|
|||
rule_tilde() |
|||
{ |
|||
local rule_ver="$1" |
|||
local tested_ver="$2" |
|||
|
|||
if rule_ge "$rule_ver" "$tested_ver"; then |
|||
local rule_major rule_minor |
|||
rule_major=$(get_major "$rule_ver") |
|||
rule_minor=$(get_minor "$rule_ver") |
|||
|
|||
if [ -n "$rule_minor" ] && rule_eq "$rule_major.$rule_minor" "$(get_number "$tested_ver")"; then |
|||
return 0 |
|||
fi |
|||
if [ -z "$rule_minor" ] && rule_eq "$rule_major" "$(get_number "$tested_ver")"; then |
|||
return 0 |
|||
fi |
|||
fi |
|||
|
|||
return 1 |
|||
} |
|||
|
|||
rule_caret() |
|||
{ |
|||
local rule_ver="$1" |
|||
local tested_ver="$2" |
|||
|
|||
if rule_ge "$rule_ver" "$tested_ver"; then |
|||
local rule_major |
|||
rule_major="$(get_major "$rule_ver")" |
|||
|
|||
if [ "$rule_major" != "0" ] && rule_eq "$rule_major" "$(get_number "$tested_ver")"; then |
|||
return 0 |
|||
fi |
|||
if [ "$rule_major" = "0" ] && rule_eq "$rule_ver" "$(get_number "$tested_ver")"; then |
|||
return 0 |
|||
fi |
|||
fi |
|||
|
|||
return 1 |
|||
} |
|||
|
|||
rule_all() |
|||
{ |
|||
return 0 |
|||
} |
|||
|
|||
apply_rules() |
|||
{ |
|||
local rules_string="$1" |
|||
shift |
|||
local versions=( "$@" ) |
|||
|
|||
# Loop over sets of rules (sets of rules are separated with ||) |
|||
for ver in "${versions[@]}"; do |
|||
rules_tail="$rules_string"; |
|||
|
|||
while [ -n "$rules_tail" ]; do |
|||
head="${rules_tail%%||*}" |
|||
|
|||
if [ "$head" = "$rules_tail" ]; then |
|||
rules_string="" |
|||
else |
|||
rules_tail="${rules_tail#*||}" |
|||
fi |
|||
|
|||
#if [ -z "$head" ] || [ -n "$(echo "$head" | grep -E -x '[ \t]*')" ]; then |
|||
#group=$(( $group + 1 )) |
|||
#continue |
|||
#fi |
|||
|
|||
rules="$(resolve_rules "$head")" |
|||
|
|||
# If specified rule cannot be recognised - end with error |
|||
if [ $? -eq 1 ]; then |
|||
exit 1 |
|||
fi |
|||
|
|||
if ! echo "$ver" | grep -q -E -x "[v=]?[ \t]*$RE_VER"; then |
|||
continue |
|||
fi |
|||
|
|||
ver=$(echo "$ver" | grep -E -x "$RE_VER") |
|||
|
|||
success=true |
|||
allow_prerel=false |
|||
if $FORCE_ALLOW_PREREL; then |
|||
allow_prerel=true |
|||
fi |
|||
|
|||
while read -r rule; do |
|||
comparator="${rule%% *}" |
|||
operand="${rule#* }" |
|||
|
|||
if [ -n "$(get_prerelease "$operand")" ] && semver_eq "$(get_number "$operand")" "$(get_number "$ver")" || [ "$rule" = "all" ]; then |
|||
allow_prerel=true |
|||
fi |
|||
|
|||
"rule_$comparator" "$operand" "$ver" |
|||
if [ $? -eq 1 ]; then |
|||
success=false |
|||
break |
|||
fi |
|||
done <<< "$rules" |
|||
|
|||
if $success; then |
|||
if [ -z "$(get_prerelease "$ver")" ] || $allow_prerel; then |
|||
echo "$ver" |
|||
break; |
|||
fi |
|||
fi |
|||
done |
|||
|
|||
group=$(( group + 1 )) |
|||
done |
|||
} |
|||
|
|||
|
|||
|
|||
FORCE_ALLOW_PREREL=false |
|||
USAGE="Usage: $0 [-r <rule>] [<version>... ] |
|||
|
|||
Omitting <version>s reads them from STDIN. |
|||
Omitting -r <rule> simply sorts the versions according to semver ordering." |
|||
|
|||
while getopts ar:h o; do |
|||
case "$o" in |
|||
a) FORCE_ALLOW_PREREL=true ;; |
|||
r) RULES_STRING="$OPTARG||";; |
|||
h) echo "$USAGE" && exit ;; |
|||
?) echo "$USAGE" && exit 1;; |
|||
esac |
|||
done |
|||
|
|||
shift $(( OPTIND-1 )) |
|||
|
|||
VERSIONS=( ${@:-$(cat -)} ) |
|||
|
|||
# Sort versions |
|||
VERSIONS=( $(semver_sort "${VERSIONS[@]}") ) |
|||
|
|||
if [ -z "$RULES_STRING" ]; then |
|||
printf '%s\n' "${VERSIONS[@]}" |
|||
else |
|||
apply_rules "$RULES_STRING" "${VERSIONS[@]}" |
|||
fi |
@ -0,0 +1,109 @@ |
|||
#!/usr/bin/env bash |
|||
|
|||
if [[ $UID != 0 ]]; then |
|||
echo "Update script must be run as root" |
|||
exit 1 |
|||
fi |
|||
|
|||
check_dependencies () { |
|||
for cmd in "$@"; do |
|||
if ! command -v "$cmd" >/dev/null 2>&1; then |
|||
echo "This script requires \"${cmd}\" to be installed" |
|||
exit 1 |
|||
fi |
|||
done |
|||
} |
|||
|
|||
check_dependencies jq wget git rsync |
|||
|
|||
UMBREL_ROOT="$(readlink -f $(dirname "${BASH_SOURCE[0]}")/../..)" |
|||
|
|||
update_type="" |
|||
if [[ "${1}" == "--ota" ]]; then |
|||
update_type="ota" |
|||
elif [[ "${1}" == "--path" ]]; then |
|||
update_type="path" |
|||
update_path="${2}" |
|||
else |
|||
echo "Update requires \"--ota\" or \"--path <path>\" option." |
|||
exit 1 |
|||
fi |
|||
|
|||
if [[ "${update_type}" == "path" ]] && [[ ! -f "${update_path}/.umbrel" ]]; then |
|||
echo "Update path doesn't seem to be an Umbrel install." |
|||
exit 1 |
|||
fi |
|||
|
|||
if [[ "${update_type}" == "ota" ]]; then |
|||
RELEASE=$(cat "$UMBREL_ROOT"/statuses/update-status.json | jq .updateTo -r) |
|||
elif [[ "${update_type}" == "path" ]]; then |
|||
RELEASE=$(cat "$update_path"/info.json | jq .version -r) |
|||
fi |
|||
|
|||
echo |
|||
echo "=======================================" |
|||
echo "=============== UPDATE ================" |
|||
echo "=======================================" |
|||
echo "========== Stage: Download ============" |
|||
echo "=======================================" |
|||
echo |
|||
|
|||
# Make sure an update is not in progres |
|||
if [[ -f "$UMBREL_ROOT/statuses/update-in-progress" ]]; then |
|||
echo "An update is already in progress. Exiting now." |
|||
exit 2 |
|||
fi |
|||
|
|||
echo "Creating lock" |
|||
touch "$UMBREL_ROOT"/statuses/update-in-progress |
|||
|
|||
# Cleanup just in case there's temp stuff lying around from previous update |
|||
echo "Cleaning up any previous mess" |
|||
[[ -d "$UMBREL_ROOT"/.umbrel-"$RELEASE" ]] && rm -rf "$UMBREL_ROOT"/.umbrel-"$RELEASE" |
|||
|
|||
# Update status file |
|||
cat <<EOF > "$UMBREL_ROOT"/statuses/update-status.json |
|||
{"state": "installing", "progress": 10, "description": "Downloading Umbrel $RELEASE", "updateTo": "$RELEASE"} |
|||
EOF |
|||
|
|||
# Download new release |
|||
if [[ "${update_type}" == "ota" ]]; then |
|||
echo "Downloading Umbrel ${RELEASE}" |
|||
mkdir -p "${UMBREL_ROOT}/.umbrel-${RELEASE}" |
|||
cd "${UMBREL_ROOT}/.umbrel-${RELEASE}" |
|||
curl -L "https://github.com/getumbrel/umbrel/archive/$RELEASE.tar.gz" | tar -xz --strip-components=1 |
|||
fi |
|||
|
|||
# Copy over new release from path |
|||
if [[ "${update_type}" == "path" ]]; then |
|||
echo "Copying Umbrel ${RELEASE} from ${update_path}" |
|||
mkdir -p "${UMBREL_ROOT}/.umbrel-${RELEASE}" |
|||
cp --recursive \ |
|||
--archive \ |
|||
--no-target-directory \ |
|||
"${update_path}" "${UMBREL_ROOT}/.umbrel-${RELEASE}" |
|||
cd "${UMBREL_ROOT}/.umbrel-${RELEASE}" |
|||
fi |
|||
|
|||
# Run update scripts |
|||
echo "Running update install scripts of the new release" |
|||
cd scripts/update |
|||
UPDATE_INSTALL_SCRIPTS=$(ls *-run.sh) |
|||
for script in $UPDATE_INSTALL_SCRIPTS; do |
|||
if [[ -x $script ]]; then |
|||
echo |
|||
echo "== Begin Update Script $script ==" |
|||
./"$script" "$RELEASE" "$UMBREL_ROOT" |
|||
echo "== End Update Script $script ==" |
|||
echo |
|||
fi |
|||
done |
|||
|
|||
# Delete cloned repo |
|||
echo "Deleting cloned repository" |
|||
[[ -d "$UMBREL_ROOT"/.umbrel-"$RELEASE" ]] && rm -rf "$UMBREL_ROOT"/.umbrel-"$RELEASE" |
|||
|
|||
echo "Removing lock" |
|||
rm -f "$UMBREL_ROOT"/statuses/update-in-progress |
|||
|
|||
exit 0 |
Loading…
Reference in new issue