this changes unbound to listen to 127.0.0.150 (150 is roman CL) we cannot only bind on docker bridge because unbound is relied upon for the initial domain setup. docker itself is only initialized when the platform initializes
188 lines
7.0 KiB
Bash
Executable File
188 lines
7.0 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 2>/dev/null) to $(cat $box_src_tmp_dir/VERSION 2>/dev/null)"
|
|
|
|
if [[ "${ubuntu_version}" == "18.04" ]]; then
|
|
log "This Cloudron version requires atleast Ubuntu 20.04. Please upgrade following https://docs.cloudron.io/guides/upgrade-ubuntu-20/"
|
|
exit 2
|
|
fi
|
|
|
|
# switch over to systemd
|
|
systemctl disable unbound || true
|
|
systemctl stop unbound || true
|
|
systemctl enable --now systemd-resolved
|
|
|
|
# https://docs.docker.com/engine/installation/linux/ubuntulinux/
|
|
readonly docker_version="23.0.6"
|
|
readonly containerd_version="1.6.21-1"
|
|
if ! which docker 2>/dev/null || [[ $(docker version --format {{.Client.Version}}) != "${docker_version}" ]]; then
|
|
log "installing/updating docker"
|
|
|
|
# create systemd drop-in file already to make sure images are with correct driver
|
|
mkdir -p /etc/systemd/system/docker.service.d
|
|
echo -e "[Service]\nExecStart=\nExecStart=/usr/bin/dockerd -H fd:// --log-driver=journald --exec-opt native.cgroupdriver=cgroupfs --storage-driver=overlay2 --experimental --ip6tables" > /etc/systemd/system/docker.service.d/cloudron.conf
|
|
|
|
# there are 3 packages for docker - containerd, CLI and the daemon (https://download.docker.com/linux/ubuntu/dists/jammy/pool/stable/amd64/)
|
|
$curl -sL "https://download.docker.com/linux/ubuntu/dists/${ubuntu_codename}/pool/stable/amd64/containerd.io_${containerd_version}_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}-1~ubuntu.${ubuntu_version}~${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}-1~ubuntu.${ubuntu_version}~${ubuntu_codename}_amd64.deb" -o /tmp/docker.deb
|
|
|
|
log "installing docker"
|
|
prepare_apt_once
|
|
apt install -y /tmp/containerd.deb /tmp/docker-ce-cli.deb /tmp/docker.deb
|
|
rm /tmp/containerd.deb /tmp/docker-ce-cli.deb /tmp/docker.deb
|
|
fi
|
|
|
|
# we want atleast nginx 1.14 for TLS v1.3 support. Ubuntu 20/22 already has nginx 1.18
|
|
# Ubuntu 18 OpenSSL does not have TLS v1.3 support, so we use the upstream nginx packages
|
|
readonly nginx_version=$(nginx -v 2>&1)
|
|
if [[ "${ubuntu_version}" == "20.04" ]]; then
|
|
if [[ "${nginx_version}" == *"Ubuntu"* ]]; then
|
|
log "switching nginx to ubuntu package"
|
|
prepare_apt_once
|
|
apt remove -y nginx
|
|
apt install -y nginx-full
|
|
fi
|
|
elif [[ "${ubuntu_version}" == "18.04" ]]; then
|
|
if [[ "${nginx_version}" != *"1.18."* ]]; then
|
|
log "installing/updating 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
|
|
fi
|
|
|
|
readonly old_node_version=18.16.0
|
|
readonly node_version=20.12.2
|
|
if ! which node 2>/dev/null || [[ "$(node --version)" != "v${node_version}" ]]; then
|
|
log "installing/updating node ${node_version}"
|
|
mkdir -p /usr/local/node-${node_version}
|
|
$curl -sL https://nodejs.org/dist/v${node_version}/node-v${node_version}-linux-x64.tar.gz -o /tmp/node.tar.gz
|
|
tar zxvf /tmp/node.tar.gz --strip-components=1 -C /usr/local/node-${node_version}
|
|
rm /tmp/node.tar.gz
|
|
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-${old_node_version}
|
|
fi
|
|
|
|
# note that 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 "const i = require('${box_src_tmp_dir}/src/infra_version.js'); console.log(Object.keys(i.images).map(x => i.images[x]).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
|
|
|
|
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"
|