e51dd8f530
currently, this is only prepared when needed because don't want this to happen on every update
190 lines
6.4 KiB
Bash
Executable File
190 lines
6.4 KiB
Bash
Executable File
#!/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
|
|
|
|
function log() {
|
|
echo -e "$(date +'%Y-%m-%dT%H:%M:%S')" "==> installer: $1"
|
|
}
|
|
|
|
apt_ready="no"
|
|
function prepare_apt_once() {
|
|
[[ "${apt_ready}" == "yes" ]] && return
|
|
|
|
log "Making sure apt is in a good state"
|
|
|
|
log "Waiting for all dpkg tasks to finish..."
|
|
while fuser /var/lib/dpkg/lock; do
|
|
sleep 1
|
|
done
|
|
|
|
# it's unclear what needs to be run first or whether both these command should be run. so keep trying both
|
|
for count in {1..3}; do
|
|
# alternative to apt-install -y --fix-missing ?
|
|
if ! dpkg --force-confold --configure -a; then
|
|
log "dpkg reconfigure failed (try $count)"
|
|
dpkg_configure="no"
|
|
else
|
|
dpkg_configure="yes"
|
|
fi
|
|
|
|
if ! apt update -y; then
|
|
log "apt update failed (try $count)"
|
|
apt_update="no"
|
|
else
|
|
apt_update="yes"
|
|
fi
|
|
|
|
[[ "${dpkg_configure}" == "yes" && "${apt_update}" == "yes" ]] && break
|
|
|
|
sleep 1
|
|
done
|
|
|
|
apt_ready="yes"
|
|
|
|
if [[ "${dpkg_configure}" == "yes" && "${apt_update}" == "yes" ]]; then
|
|
log "apt is ready"
|
|
else
|
|
log "apt is not ready but proceeding anyway"
|
|
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 -q box && echo "yes" || echo "no")
|
|
|
|
log "Updating from $(cat $box_src_dir/VERSION) to $(cat $box_src_tmp_dir/VERSION)"
|
|
|
|
log "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
|
|
|
|
prepare_apt_once
|
|
|
|
while ! apt install -y /tmp/containerd.deb /tmp/docker-ce-cli.deb /tmp/docker.deb; do
|
|
log "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
|
|
log "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
|
|
|
|
prepare_apt_once
|
|
|
|
# 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
|
|
|
|
if ! which mount.nfs; then
|
|
log "installing nfs-common"
|
|
prepare_apt_once
|
|
apt install -y nfs-common
|
|
fi
|
|
|
|
if ! which sshfs; then
|
|
log "installing sshfs"
|
|
prepare_apt_once
|
|
apt install -y sshfs
|
|
fi
|
|
|
|
log "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
|
|
log "Failed to rebuild, trying again"
|
|
sleep 5
|
|
done
|
|
|
|
if [[ ${try} -eq 10 ]]; then
|
|
log "npm rebuild failed, giving up"
|
|
exit 4
|
|
fi
|
|
|
|
log "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(' '));")
|
|
|
|
log "\tPulling docker images: ${images}"
|
|
for image in ${images}; do
|
|
while ! docker pull "${image}"; do # this pulls the image using the sha256
|
|
log "Could not pull ${image}"
|
|
sleep 5
|
|
done
|
|
while ! docker pull "${image%@sha256:*}"; do # this will tag the image for readability
|
|
log "Could not pull ${image%@sha256:*}"
|
|
sleep 5
|
|
done
|
|
done
|
|
|
|
log "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
|
|
log "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
|
|
log "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
|
|
|
|
log "switching the box code"
|
|
rm -rf "${box_src_dir}"
|
|
mv "${box_src_tmp_dir}" "${box_src_dir}"
|
|
chown -R "${user}:${user}" "${box_src_dir}"
|
|
|
|
log "calling box setup script"
|
|
"${box_src_dir}/setup/start.sh"
|