From 61789e3fdae86d111cdc269f4e0d4766f00a5e5e Mon Sep 17 00:00:00 2001 From: Girish Ramakrishnan Date: Fri, 23 Dec 2016 18:28:18 -0800 Subject: [PATCH] Use the installer.sh from the source tarball This redesigns how update works. installer.sh now rebuild the package, stops the old code and starts the new code. Importantly, it does not download the new package, this is left to the caller. cloudron-setup downloads the code and calls installer.sh of the downloaded code. Same goes for updater.sh. This means that installer.sh itself is now easily updatable. Part of #152 --- baseimage/initializeBaseUbuntuImage.sh | 9 ------- scripts/cloudron-setup | 24 +++++++----------- scripts/installer.sh | 35 +++++++++----------------- setup/container.sh | 2 ++ src/scripts/update.sh | 19 ++++++++++++-- 5 files changed, 40 insertions(+), 49 deletions(-) diff --git a/baseimage/initializeBaseUbuntuImage.sh b/baseimage/initializeBaseUbuntuImage.sh index 4a210a8d3..623364093 100644 --- a/baseimage/initializeBaseUbuntuImage.sh +++ b/baseimage/initializeBaseUbuntuImage.sh @@ -2,9 +2,6 @@ set -euv -o pipefail -readonly USER=yellowtent -readonly USER_HOME="/home/${USER}" -readonly INSTALLER_SOURCE_DIR="${USER_HOME}/installer" readonly PROVIDER="${1:-generic}" readonly SOURCE_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" @@ -16,11 +13,6 @@ function die { [[ "$(systemd --version 2>&1)" == *"systemd 229"* ]] || die "Expecting systemd to be 229" -echo "==== Create User ${USER} ====" -if ! id "${USER}"; then - useradd "${USER}" -m -fi - export DEBIAN_FRONTEND=noninteractive echo "=== Upgrade ===" @@ -38,7 +30,6 @@ echo "deb https://apt.dockerproject.org/repo ubuntu-xenial main" > /etc/apt/sour apt-get -y update apt-get -y install aufs-tools linux-image-extra-$(uname -r) linux-image-extra-virtual apt-get -y install docker-engine=1.12.5-0~ubuntu-xenial # apt-cache madison docker-engine -usermod "${USER}" -a -G docker echo "=== Enable memory accounting ==" sed -e 's/^GRUB_CMDLINE_LINUX="\(.*\)"$/GRUB_CMDLINE_LINUX="\1 cgroup_enable=memory swapaccount=1 panic_on_oops=1 panic=5"/' -i /etc/default/grub diff --git a/scripts/cloudron-setup b/scripts/cloudron-setup index 4abbef75e..b3f69d15e 100755 --- a/scripts/cloudron-setup +++ b/scripts/cloudron-setup @@ -8,9 +8,7 @@ if [[ ${EUID} -ne 0 ]]; then fi # change this to a hash when we make a upgrade release -readonly INSTALLER_REVISION=master -readonly INIT_BASESYSTEM_SCRIPT_URL="https://git.cloudron.io/cloudron/box/raw/${INSTALLER_REVISION}/baseimage/initializeBaseUbuntuImage.sh" -readonly INSTALLER_URL="https://git.cloudron.io/cloudron/box/raw/${INSTALLER_REVISION}/scripts/installer.sh" +readonly INIT_BASESYSTEM_SCRIPT_URL="https://git.cloudron.io/cloudron/box/raw/master/baseimage/initializeBaseUbuntuImage.sh" readonly LOG_FILE="/var/log/cloudron-setup.log" initBaseImage="true" @@ -114,16 +112,6 @@ if [[ "${initBaseImage}" == "true" ]]; then rm /tmp/initializeBaseUbuntuImage.sh fi -echo "=> Downloading and running installer for version ${INSTALLER_REVISION}" -if ! curl -s "${INSTALLER_URL}" > /etc/installer.sh; then - echo "Could not download initialization script" - exit 1 -fi -if ! /bin/bash /etc/installer.sh "${provider}" &>> "${LOG_FILE}"; then - echo "Installer failed. See ${LOG_FILE} for details" - exit 1 -fi - echo "=> Checking version" if ! npm install -g cloudron-version@0.1.1 &>> "${LOG_FILE}"; then echo "Failed to install cloudron-version npm package" @@ -180,8 +168,14 @@ EOF ) fi -echo "=> Run installer.sh for version ${version} with ${sourceTarballUrl} ... (this takes some time)" -if ! ${INSTALLER_SOURCE_DIR}/scripts/installer.sh --sourcetarballurl "${sourceTarballUrl}" --data "${data}" &>> "${LOG_FILE}"; then +echo "=> Downloading and running installer for version ${version} ... (this takes some time)" +box_src_tmp_dir=$(mktemp -dt box-src-XXXXXX) + +if ! $curl -sL "${sourceTarballUrl}" | tar -zxf - -C "${box_src_tmp_dir}"; then + echo "Could not download source tarball. See ${LOG_FILE} for details" + exit 1 +fi +if ! /bin/bash "${box_src_tmp_dir}/scripts/installer.sh" --data "${data}" &>> "${LOG_FILE}" &>> "${LOG_FILE}"; then echo "Failed to install cloudron. See ${LOG_FILE} for details" exit 1 fi diff --git a/scripts/installer.sh b/scripts/installer.sh index 1326eb9a6..e800cfe65 100755 --- a/scripts/installer.sh +++ b/scripts/installer.sh @@ -7,30 +7,29 @@ if [[ ${EUID} -ne 0 ]]; then exit 1 fi -readonly BOX_SRC_DIR=/home/yellowtent/box -readonly DATA_DIR=/home/yellowtent/data +readonly USER=yellowtent +readonly BOX_SRC_DIR=/home/${USER}/box readonly CLOUDRON_CONF=/home/yellowtent/configs/cloudron.conf readonly script_dir="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" +readonly box_src_tmp_dir="$(realpath ${script_dir}/..)" readonly json="${script_dir}/../../node_modules/.bin/json" readonly curl="curl --fail --connect-timeout 20 --retry 10 --retry-delay 2 --max-time 300" readonly is_update=$([[ -f "${CLOUDRON_CONF}" ]] && echo "yes" || echo "no") # create a provision file for testing. %q escapes args. %q is reused as much as necessary to satisfy $@ -(echo -e "#!/bin/bash\n"; printf "%q " "${script_dir}/installer.sh" "$@") > /home/yellowtent/provision.sh -chmod +x /home/yellowtent/provision.sh +(echo -e "#!/bin/bash\n"; printf "%q " "${script_dir}/installer.sh" "$@") > /root/provision.sh +chmod +x /root/provision.sh -arg_source_tarball_url="" arg_data="" arg_data_file="" -args=$(getopt -o "" -l "sourcetarballurl:,data:,data-file:" -n "$0" -- "$@") +args=$(getopt -o "" -l "data:,data-file:" -n "$0" -- "$@") eval set -- "${args}" while true; do case "$1" in - --sourcetarballurl) arg_source_tarball_url="$2";; --data) arg_data="$2";; --data-file) arg_data_file="$2";; --) break;; @@ -44,20 +43,6 @@ if [[ ! -z ${arg_data_file} ]]; then arg_data=$(cat "${arg_data_file}") fi -box_src_tmp_dir=$(mktemp -dt box-src-XXXXXX) -echo "Downloading box code from ${arg_source_tarball_url} to ${box_src_tmp_dir}" - -for try in `seq 1 10`; do - if $curl -L "${arg_source_tarball_url}" | tar -zxf - -C "${box_src_tmp_dir}"; then break; fi - echo "Failed to download source tarball, trying again" - sleep 5 -done - -if [[ ${try} -eq 10 ]]; then - echo "Release tarball download failed" - exit 3 -fi - # ensure ownership baked into the tarball is overwritten chown -R root.root "${box_src_tmp_dir}" @@ -77,6 +62,11 @@ if [[ ${try} -eq 10 ]]; then exit 4 fi +echo "==== Create User ${USER} ====" +if ! id "${USER}"; then + useradd "${USER}" -m +fi + if [[ "${is_update}" == "yes" ]]; then echo "Setting up update splash screen" "${box_src_tmp_dir}/setup/splashpage.sh" --data "${arg_data}" # show splash from new code @@ -89,7 +79,7 @@ cd /root # switch the codes rm -rf "${BOX_SRC_DIR}" mv "${box_src_tmp_dir}" "${BOX_SRC_DIR}" -chown -R yellowtent.yellowtent "${BOX_SRC_DIR}" +chown -R "${USER}:${USER}" "${BOX_SRC_DIR}" # create a start file for testing. %q escapes args (echo -e "#!/bin/bash\n"; printf "%q " "${BOX_SRC_DIR}/setup/start.sh" --data "${arg_data}") > /home/yellowtent/setup_start.sh @@ -97,4 +87,3 @@ chmod +x /home/yellowtent/setup_start.sh echo "Calling box setup script" "${BOX_SRC_DIR}/setup/start.sh" --data "${arg_data}" - diff --git a/setup/container.sh b/setup/container.sh index 2ea8224a4..699d5a535 100755 --- a/setup/container.sh +++ b/setup/container.sh @@ -15,6 +15,8 @@ readonly CONFIG_DIR="/home/yellowtent/configs" readonly DATA_DIR="/home/yellowtent/data" readonly provider="${1:-generic}" +usermod "${USER}" -a -G docker + echo "=== Setting up firewall ===" iptables -t filter -N CLOUDRON || true iptables -t filter -F CLOUDRON # empty any existing rules diff --git a/src/scripts/update.sh b/src/scripts/update.sh index a500b264e..f6bafdc62 100755 --- a/src/scripts/update.sh +++ b/src/scripts/update.sh @@ -7,7 +7,6 @@ if [[ ${EUID} -ne 0 ]]; then exit 1 fi -readonly INSTALLER_PATH="/etc/installer.sh" readonly UPDATER_SERVICE="cloudron-updater" readonly DATA_FILE="/tmp/cloudron-update-data.json" @@ -27,6 +26,22 @@ readonly data="${2}" echo "Updating Cloudron with ${sourceTarballUrl}" echo "${data}" +# TODO: pre-download tarball +box_src_tmp_dir=$(mktemp -dt box-src-XXXXXX) +readonly installer_path="${box_src_tmp_dir}/scripts/installer.sh" +echo "Downloading box code from ${sourceTarballUrl} to ${box_src_tmp_dir}" + +for try in `seq 1 10`; do + if curl -L "${sourceTarballUrl}" | tar -zxf - -C "${box_src_tmp_dir}"; then break; fi + echo "Failed to download source tarball, trying again" + sleep 5 +done + +if [[ ${try} -eq 10 ]]; then + echo "Release tarball download failed" + exit 3 +fi + echo "=> reset service ${UPDATER_SERVICE} status in case it failed" if systemctl reset-failed "${UPDATER_SERVICE}"; then echo "=> service has failed earlier" @@ -36,7 +51,7 @@ fi echo "${data}" > "${DATA_FILE}" echo "=> Run installer.sh as cloudron-updater.service" -if ! systemd-run --unit "${UPDATER_SERVICE}" ${INSTALLER_PATH} --sourcetarballurl "${sourceTarballUrl}" --data-file "${DATA_FILE}"; then +if ! systemd-run --unit "${UPDATER_SERVICE}" ${installer_path} --data-file "${DATA_FILE}"; then echo "Failed to install cloudron. See ${LOG_FILE} for details" exit 1 fi