#!/bin/bash # This script is run before the box code is switched. This means that we can # put network related/curl downloads here. If the script fails, the old code # will continue to run set -eu -o pipefail if [[ ${EUID} -ne 0 ]]; then echo "This script should be run as root." > /dev/stderr exit 1 fi readonly user=yellowtent readonly box_src_dir=/home/${user}/box readonly curl="curl --fail --connect-timeout 20 --retry 10 --retry-delay 2 --max-time 2400" readonly script_dir="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" readonly box_src_tmp_dir="$(realpath ${script_dir}/..)" readonly ubuntu_version=$(lsb_release -rs) readonly ubuntu_codename=$(lsb_release -cs) readonly is_update=$(systemctl is-active box && echo "yes" || echo "no") echo "==> installer: Updating from $(cat $box_src_dir/VERSION) to $(cat $box_src_tmp_dir/VERSION) <==" echo "==> installer: updating docker" readonly docker_version=20.10.3 if [[ $(docker version --format {{.Client.Version}}) != "${docker_version}" ]]; then # there are 3 packages for docker - containerd, CLI and the daemon curl -sL "https://download.docker.com/linux/ubuntu/dists/${ubuntu_codename}/pool/stable/amd64/containerd.io_1.4.3-1_amd64.deb" -o /tmp/containerd.deb curl -sL "https://download.docker.com/linux/ubuntu/dists/${ubuntu_codename}/pool/stable/amd64/docker-ce-cli_${docker_version}~3-0~ubuntu-${ubuntu_codename}_amd64.deb" -o /tmp/docker-ce-cli.deb curl -sL "https://download.docker.com/linux/ubuntu/dists/${ubuntu_codename}/pool/stable/amd64/docker-ce_${docker_version}~3-0~ubuntu-${ubuntu_codename}_amd64.deb" -o /tmp/docker.deb echo "==> installer: Waiting for all dpkg tasks to finish..." while fuser /var/lib/dpkg/lock; do sleep 1 done while ! dpkg --force-confold --configure -a; do echo "==> installer: Failed to fix packages. Retry" sleep 1 done # the latest docker might need newer packages while ! apt update -y; do echo "==> installer: Failed to update packages. Retry" sleep 1 done while ! apt install -y /tmp/containerd.deb /tmp/docker-ce-cli.deb /tmp/docker.deb; do echo "==> installer: Failed to install docker. Retry" sleep 1 done rm /tmp/containerd.deb /tmp/docker-ce-cli.deb /tmp/docker.deb fi readonly nginx_version=$(nginx -v 2>&1) if [[ "${nginx_version}" != *"1.18."* ]]; then echo "==> installer: installing nginx 1.18" curl -sL http://nginx.org/packages/ubuntu/pool/nginx/n/nginx/nginx_1.18.0-2~${ubuntu_codename}_amd64.deb -o /tmp/nginx.deb # apt install with install deps (as opposed to dpkg -i) apt install -y -o Dpkg::Options::="--force-confdef" -o Dpkg::Options::="--force-confold" --force-yes /tmp/nginx.deb rm /tmp/nginx.deb fi # Cloudron 6 on ubuntu 20 installed recommended packages of collectd -> libinotify -> gnome->shell apt remove -y gnome-shell || true apt -y autoremove || true echo "==> installer: updating node" readonly node_version=14.15.4 if [[ "$(node --version)" != "v${node_version}" ]]; then mkdir -p /usr/local/node-${node_version} $curl -sL https://nodejs.org/dist/v${node_version}/node-v${node_version}-linux-x64.tar.gz | tar zxvf - --strip-components=1 -C /usr/local/node-${node_version} ln -sf /usr/local/node-${node_version}/bin/node /usr/bin/node ln -sf /usr/local/node-${node_version}/bin/npm /usr/bin/npm rm -rf /usr/local/node-10.18.1 fi # this is here (and not in updater.js) because rebuild requires the above node for try in `seq 1 10`; do # for reasons unknown, the dtrace package will fail. but rebuilding second time will work # We need --unsafe-perm as we run as root and the folder is owned by root, # however by default npm drops privileges for npm rebuild # https://docs.npmjs.com/misc/config#unsafe-perm if cd "${box_src_tmp_dir}" && npm rebuild --unsafe-perm; then break; fi echo "==> installer: Failed to rebuild, trying again" sleep 5 done if [[ ${try} -eq 10 ]]; then echo "==> installer: npm rebuild failed, giving up" exit 4 fi echo "==> installer: downloading new addon images" images=$(node -e "var i = require('${box_src_tmp_dir}/src/infra_version.js'); console.log(i.baseImages.map(function (x) { return x.tag; }).join(' '), Object.keys(i.images).map(function (x) { return i.images[x].tag; }).join(' '));") echo -e "\tPulling docker images: ${images}" for image in ${images}; do if ! docker pull "${image}"; then # this pulls the image using the sha256 echo "==> installer: Could not pull ${image}" exit 5 fi if ! docker pull "${image%@sha256:*}"; then # this will tag the image for readability echo "==> installer: Could not pull ${image%@sha256:*}" exit 6 fi done echo "==> installer: update cloudron-syslog" CLOUDRON_SYSLOG_DIR=/usr/local/cloudron-syslog CLOUDRON_SYSLOG="${CLOUDRON_SYSLOG_DIR}/bin/cloudron-syslog" CLOUDRON_SYSLOG_VERSION="1.0.3" while [[ ! -f "${CLOUDRON_SYSLOG}" || "$(${CLOUDRON_SYSLOG} --version)" != ${CLOUDRON_SYSLOG_VERSION} ]]; do rm -rf "${CLOUDRON_SYSLOG_DIR}" mkdir -p "${CLOUDRON_SYSLOG_DIR}" if npm install --unsafe-perm -g --prefix "${CLOUDRON_SYSLOG_DIR}" cloudron-syslog@${CLOUDRON_SYSLOG_VERSION}; then break; fi echo "===> installer: Failed to install cloudron-syslog, trying again" sleep 5 done if ! id "${user}" 2>/dev/null; then useradd "${user}" -m fi if [[ "${is_update}" == "yes" ]]; then echo "==> installer: stop box service for update" ${box_src_dir}/setup/stop.sh fi # ensure we are not inside the source directory, which we will remove now cd /root echo "==> installer: switching the box code" rm -rf "${box_src_dir}" mv "${box_src_tmp_dir}" "${box_src_dir}" chown -R "${user}:${user}" "${box_src_dir}" echo "==> installer: calling box setup script" "${box_src_dir}/setup/start.sh"