mirror of
https://github.com/flatcar/scripts.git
synced 2025-08-08 21:46:58 +02:00
Currently, the scripts in src/scripts have multiple implementations for handling when common.sh fails to load, some of which are buggy. To simplify the boilerplate, these scripts now just exit if common.sh fails to load. The shell itself will print the following message if common.sh is not found: /usr/lib/crosutils/common.sh: No such file or directory BUG=chromium-os:32442 TEST=Run these scripts with and without common.sh installed. Change-Id: Ie54420b6c649774f9cb039c14c80f4cf6c6ebc07 Reviewed-on: https://gerrit.chromium.org/gerrit/27058 Reviewed-by: David James <davidjames@chromium.org> Tested-by: David James <davidjames@chromium.org> Commit-Ready: David James <davidjames@chromium.org>
154 lines
4.7 KiB
Bash
Executable File
154 lines
4.7 KiB
Bash
Executable File
#!/bin/bash
|
|
|
|
# Copyright (c) 2011 The Chromium OS Authors. All rights reserved.
|
|
# Use of this source code is governed by a BSD-style license that can be
|
|
# found in the LICENSE file.
|
|
|
|
# Load common CrOS utilities. Inside the chroot this file is installed in
|
|
# /usr/lib/crosutils. Outside the chroot we find it relative to the script's
|
|
# location.
|
|
. "$(dirname "$0")/common.sh" || exit 1
|
|
|
|
# Script must run inside the chroot.
|
|
assert_inside_chroot
|
|
|
|
# May not be run as root.
|
|
assert_not_root_user
|
|
|
|
DEFINE_string version "" \
|
|
"Assume current chroot version is this."
|
|
DEFINE_boolean force_latest "${FLAGS_FALSE}" \
|
|
"Assume latest version and recreate the version file"
|
|
DEFINE_boolean skipfirst "${FLAGS_FALSE}" \
|
|
"Skip the first upgrade. This may be dangerous."
|
|
|
|
FLAGS "$@" || exit 1
|
|
|
|
VERSION_FILE=/etc/cros_chroot_version
|
|
UPGRADE_D="$(dirname ${0})/chroot_version_hooks.d"
|
|
|
|
update_version() {
|
|
sudo touch ${VERSION_FILE}
|
|
sudo chown ${USER} ${VERSION_FILE}
|
|
echo "${1}" > "${VERSION_FILE}"
|
|
}
|
|
|
|
######################################################################
|
|
|
|
# Sanity checks:
|
|
if [ -n "${FLAGS_version}" ] && \
|
|
( [ "${FLAGS_skipfirst}" == "${FLAGS_TRUE}" ] || \
|
|
[ "${FLAGS_force_latest}" == "${FLAGS_TRUE}" ] ); then
|
|
error "The option --version cannot be combined with either"
|
|
error "--skipfirst or --force_latest."
|
|
exit 1
|
|
fi
|
|
|
|
if [ "${FLAGS_skipfirst}" == "${FLAGS_TRUE}" ] &&
|
|
[ "${FLAGS_force_latest}" == "${FLAGS_TRUE}" ]; then
|
|
error "--skipfirst and --force_latest cannot be combined."
|
|
exit 1
|
|
fi
|
|
|
|
# Latest version is the version of last upgrade.d file.
|
|
# Name format is ${number}_${short_description}
|
|
# Versions must be -n sorted, that is, the first continuous sequence
|
|
# of numbers is what counts. 12_ is before 111_, etc.
|
|
LATEST_VERSION=$(
|
|
ls "${UPGRADE_D}" | grep "^[0-9]*_" | \
|
|
sort -n | tail -n 1 | cut -f1 -d'_'
|
|
)
|
|
|
|
if [ "${FLAGS_force_latest}" == "${FLAGS_TRUE}" ]; then
|
|
update_version "${LATEST_VERSION}"
|
|
exit 0
|
|
fi
|
|
|
|
# If the file does not exist at all, chroot is old and does not have a version.
|
|
# default goes here
|
|
if ! [ -f "${VERSION_FILE}" ]; then
|
|
info "Chroot of unknown version, initializing to 0"
|
|
update_version 0
|
|
fi
|
|
|
|
CHROOT_VERSION=$(cat "${VERSION_FILE}")
|
|
# Check if version is a number.
|
|
if ! [ "${CHROOT_VERSION}" -ge "0" ] &> /dev/null; then
|
|
error "Your chroot version file ${VERSION_FILE} is bogus: ${CHROOT_VERSION}"
|
|
exit 1
|
|
fi
|
|
|
|
if [ "${FLAGS_skipfirst}" == "${FLAGS_TRUE}" ]; then
|
|
if [ "${CHROOT_VERSION}" -lt "${LATEST_VERSION}" ]; then
|
|
# if the new one is latest, this becomes noop
|
|
CHROOT_VERSION=$(expr ${CHROOT_VERSION} + 1)
|
|
update_version "${CHROOT_VERSION}"
|
|
else
|
|
error "Nothing to skip"
|
|
exit 1
|
|
fi
|
|
fi
|
|
|
|
if [ -n "${FLAGS_version}" ]; then
|
|
# Check if it's a number.
|
|
if ! [ "${FLAGS_version}" -ge "0" ] &> /dev/null; then
|
|
error "Trying to force invalid version: ${FLAGS_version}"
|
|
exit 1
|
|
fi
|
|
|
|
if [ "${FLAGS_version}" -gt "${LATEST_VERSION}" ]; then
|
|
error "Forcing nonexistant version: ${FLAGS_version}"
|
|
exit 1
|
|
fi
|
|
|
|
CHROOT_VERSION="${FLAGS_version}"
|
|
fi
|
|
|
|
|
|
if [ "${LATEST_VERSION}" -gt "${CHROOT_VERSION}" ]; then
|
|
info "Old chroot version (${CHROOT_VERSION}) found, running upgrade hooks"
|
|
|
|
pushd "${UPGRADE_D}" 1> /dev/null
|
|
for n in $(seq "$(expr ${CHROOT_VERSION} + 1)" "${LATEST_VERSION}"); do
|
|
hook=(${n}_*)
|
|
|
|
# Sanity check: if there are multiple ${n}_* files, then CL's landed
|
|
# at the same time and people didn't notice. Let's notice for them.
|
|
if [ ${#hook[@]} -gt 1 ]; then
|
|
error "Fatal: Upgrade ${n} has multiple hooks:"
|
|
error " ${hook[*]}"
|
|
error "Connor MacLeod knows: There can be only one."
|
|
exit 1
|
|
fi
|
|
hook=${hook[0]}
|
|
|
|
# Deprecation check; Deprecation can be done by removing old upgrade
|
|
# scripts and causing too old chroots to have to start over.
|
|
# Upgrades have to form a continuous sequence.
|
|
if ! [ -f ${hook} ]; then
|
|
error "Fatal: Upgrade ${n} doesn't exist."
|
|
error "Your chroot is so old, that some updates have been deprecated!"
|
|
error "You need to re-create it!"
|
|
exit 1
|
|
fi
|
|
|
|
info "Rollup ${hook}"
|
|
|
|
# Attempt the upgrade.
|
|
# NOTE: We source the upgrade scripts because:
|
|
# 1) We can impose set -something on them.
|
|
# 2) They can reuse local variables and functions (fe. from common.sh)
|
|
# Side effect is that the scripts have to be internally enclosed in
|
|
# a code block, otherwise simply running "exit" in any of them would
|
|
# terminate the master script, so we call it in a subshell.
|
|
if ! ( source ${hook} ); then
|
|
error "Fatal: failed to upgrade ${n}!"
|
|
exit 1
|
|
fi
|
|
# Each upgrade is atomic. If a middle upgrade fails, we won't retry
|
|
# all the ones that passed on a previous run.
|
|
update_version "${n}"
|
|
done
|
|
popd 1> /dev/null
|
|
fi
|