You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 

160 lines
4.8 KiB

#!/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 curl 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}"
elif [[ "${1}" == "--repo" ]]; then
update_type="repo"
descriptor="${2}"
if [[ "${descriptor}" != *"#"* ]]; then
descriptor="${descriptor}#master"
fi
repo="${descriptor%%#*}"
branch="${descriptor#*#}"
else
echo "Update requires \"--ota\", \"--path <path>\", or \"--repo user/repo[#branch]\" option."
exit 1
fi
if [[ "${update_type}" == "repo" ]]; then
repo_path="/tmp/umbrel-update/"
rm -rf "${repo_path}" 2> /dev/null || true
mkdir -p "${repo_path}"
git clone --single-branch --branch "${branch}" "https://github.com/${repo}.git" "${repo_path}"
# Patch version to show development build
commit=$(git --git-dir "${repo_path}/.git" rev-parse --short HEAD)
mv "${repo_path}/info.json" "${repo_path}/info.json.orig"
jq \
--arg commit "${commit}" \
'.build = $commit' \
"${repo_path}/info.json.orig" \
> "${repo_path}/info.json"
# Now hand over to the path updater
update_type="path"
update_path="${repo_path}"
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
# Make sure the update-status file isn't stuck in an
# unresolved state (i.e anything except "success" or "failed")
update_state=$(cat "${UMBREL_ROOT}/statuses/update-status.json" | jq .state -r)
# Show error
update_failure_status_file="${UMBREL_ROOT}/statuses/update-failure"
if [[ -f "${update_failure_status_file}" ]]; then
reason=$(cat "${update_failure_status_file}")
rm "${update_failure_status_file}"
cat <<EOF > "${UMBREL_ROOT}/statuses/update-status.json"
{"state": "failed", "progress": 100, "description": "${reason}", "updateTo": ""}
EOF
fi
if [[ "${update_state}" != "success" ]] && [[ "${update_state}" != "failed" ]]; then
# Sleep for a few seconds to make sure the user is on the update view
sleep 8
cat <<EOF > "${UMBREL_ROOT}/statuses/update-status.json"
{"state": "failed", "progress": 100, "description": "An unexpected error occured", "updateTo": ""}
EOF
fi
exit 0