This allows us to move platform.initialize to whenever the domain is setup. Thus allowing box code to startup faster the first time around.
212 lines
6.8 KiB
Bash
Executable File
212 lines
6.8 KiB
Bash
Executable File
#!/bin/bash
|
|
|
|
set -eu -o pipefail
|
|
|
|
if [[ ${EUID} -ne 0 ]]; then
|
|
echo "This script should be run as root." > /dev/stderr
|
|
exit 1
|
|
fi
|
|
|
|
# change this to a hash when we make a upgrade release
|
|
readonly LOG_FILE="/var/log/cloudron-setup.log"
|
|
readonly MINIMUM_DISK_SIZE_GB="20" # this is the size of "/" and required to fit in docker images
|
|
readonly MINIMUM_MEMORY="992" # this is mostly reported for 1GB main memory due to 1000 vs 1024
|
|
|
|
# copied from cloudron-resize-fs.sh
|
|
readonly physical_memory=$(free -m | awk '/Mem:/ { print $2 }')
|
|
readonly disk_device="$(for d in $(find /dev -type b); do [ "$(mountpoint -d /)" = "$(mountpoint -x $d)" ] && echo $d && break; done)"
|
|
readonly disk_size_gb=$(fdisk -l ${disk_device} | grep "Disk ${disk_device}" | awk '{ printf "%.0f", $3 }')
|
|
|
|
# verify the system has minimum requirements met
|
|
if [[ "${physical_memory}" -lt "${MINIMUM_MEMORY}" ]]; then
|
|
echo "Error: Cloudron requires atleast 1GB physical memory"
|
|
exit 1
|
|
fi
|
|
|
|
if [[ "${disk_size_gb}" -lt "${MINIMUM_DISK_SIZE_GB}" ]]; then
|
|
echo "Error: Cloudron requires atleast 20GB disk space (Disk space on ${disk_device} is ${disk_size_gb}GB)"
|
|
exit 1
|
|
fi
|
|
|
|
initBaseImage="true"
|
|
# provisioning data
|
|
domain=""
|
|
provider=""
|
|
encryptionKey=""
|
|
restoreUrl=""
|
|
dnsProvider="manual"
|
|
tlsProvider="le-prod"
|
|
versionsUrl="https://s3.amazonaws.com/prod-cloudron-releases/versions.json"
|
|
requestedVersion="latest"
|
|
apiServer="https://api.cloudron.io"
|
|
dataJson=""
|
|
|
|
args=$(getopt -o "" -l "domain:,help,skip-baseimage-init,data:,provider:,encryption-key:,restore-url:,tls-provider:,version:,versions-url:,api-server:,dns-provider:" -n "$0" -- "$@")
|
|
eval set -- "${args}"
|
|
|
|
while true; do
|
|
case "$1" in
|
|
--domain) domain="$2"; shift 2;;
|
|
--help) echo "See https://cloudron.io/references/selfhosting.html on how to install Cloudron"; exit 0;;
|
|
--provider) provider="$2"; shift 2;;
|
|
--encryption-key) encryptionKey="$2"; shift 2;;
|
|
--restore-url) restoreUrl="$2"; shift 2;;
|
|
--tls-provider) tlsProvider="$2"; shift 2;;
|
|
--dns-provider) dnsProvider="$2"; shift 2;;
|
|
--version) requestedVersion="$2"; shift 2;;
|
|
--versions-url) versionsUrl="$2"; shift 2;;
|
|
--api-server) apiServer="$2"; shift 2;;
|
|
--skip-baseimage-init) initBaseImage="false"; shift;;
|
|
--data) dataJson="$2"; shift 2;;
|
|
--) break;;
|
|
*) echo "Unknown option $1"; exit 1;;
|
|
esac
|
|
done
|
|
|
|
# validate arguments in the absence of data
|
|
if [[ -z "${dataJson}" ]]; then
|
|
if [[ -z "${provider}" ]]; then
|
|
echo "--provider is required (generic, scaleway, ec2, digitalocean)"
|
|
exit 1
|
|
elif [[ \
|
|
"${provider}" != "generic" && \
|
|
"${provider}" != "scaleway" && \
|
|
"${provider}" != "ec2" && \
|
|
"${provider}" != "digitalocean" \
|
|
]]; then
|
|
echo "--provider must be one of: generic, scaleway, ec2, digitalocean"
|
|
exit 1
|
|
fi
|
|
|
|
if [[ -z "${dnsProvider}" ]]; then
|
|
echo "--dns-provider is required (noop, manual)"
|
|
exit 1
|
|
elif [[ "${dnsProvider}" != "noop" && "${dnsProvider}" != "manual" ]]; then
|
|
echo "--dns-provider must be one of : manual, noop"
|
|
exit 1
|
|
fi
|
|
fi
|
|
|
|
echo ""
|
|
echo "##############################################"
|
|
echo " Cloudron Setup (${requestedVersion}) "
|
|
echo "##############################################"
|
|
echo ""
|
|
echo " Follow setup logs in a second terminal with:"
|
|
echo " $ tail -f ${LOG_FILE}"
|
|
echo ""
|
|
echo " Join us at https://chat.cloudron.io for any questions."
|
|
echo ""
|
|
|
|
if [[ "${initBaseImage}" == "true" ]]; then
|
|
echo "=> Updating apt and installing script dependancies"
|
|
if ! apt-get update &>> "${LOG_FILE}"; then
|
|
echo "Could not update package repositories"
|
|
exit 1
|
|
fi
|
|
|
|
if ! apt-get install curl python3 ubuntu-standard -y &>> "${LOG_FILE}"; then
|
|
echo "Could not install setup dependencies (curl)"
|
|
exit 1
|
|
fi
|
|
fi
|
|
|
|
echo "=> Checking version"
|
|
releaseJson=$(curl -s "${versionsUrl}")
|
|
if [[ "$requestedVersion" == "latest" ]]; then
|
|
version=$(echo "${releaseJson}" | python3 -c 'import json,sys,collections;obj=json.load(sys.stdin, object_pairs_hook=collections.OrderedDict);latest=list(v for v in obj if "-pre" not in v)[-1];print(latest)')
|
|
else
|
|
version="${requestedVersion}"
|
|
fi
|
|
if ! sourceTarballUrl=$(echo "${releaseJson}" | python3 -c 'import json,sys;obj=json.load(sys.stdin);print(obj[sys.argv[1]]["sourceTarballUrl"])' "${version}"); then
|
|
echo "No source code for version ${requestedVersion}"
|
|
exit 1
|
|
fi
|
|
|
|
# Build data
|
|
if [[ -z "${dataJson}" ]]; then
|
|
if [[ -z "${restoreUrl}" ]]; then
|
|
data=$(cat <<EOF
|
|
{
|
|
"boxVersionsUrl": "${versionsUrl}",
|
|
"fqdn": "${domain}",
|
|
"provider": "${provider}",
|
|
"apiServerOrigin": "${apiServer}",
|
|
"tlsConfig": {
|
|
"provider": "${tlsProvider}"
|
|
},
|
|
"dnsConfig": {
|
|
"provider": "${dnsProvider}"
|
|
},
|
|
"backupConfig" : {
|
|
"provider": "filesystem",
|
|
"backupFolder": "/var/backups",
|
|
"key": "${encryptionKey}"
|
|
},
|
|
"version": "${version}"
|
|
}
|
|
EOF
|
|
)
|
|
else
|
|
data=$(cat <<EOF
|
|
{
|
|
"boxVersionsUrl": "${versionsUrl}",
|
|
"fqdn": "${domain}",
|
|
"provider": "${provider}",
|
|
"apiServerOrigin": "${apiServer}",
|
|
"restore": {
|
|
"url": "${restoreUrl}",
|
|
"key": "${encryptionKey}"
|
|
},
|
|
"version": "${version}"
|
|
}
|
|
EOF
|
|
)
|
|
fi
|
|
else
|
|
data="${dataJson}"
|
|
fi
|
|
|
|
echo "=> Downloading version ${version} ..."
|
|
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 [[ "${initBaseImage}" == "true" ]]; then
|
|
echo "=> Installing base dependencies (this takes some time) ..."
|
|
if ! /bin/bash "${box_src_tmp_dir}/baseimage/initializeBaseUbuntuImage.sh" "${provider}" "../src" &>> "${LOG_FILE}"; then
|
|
echo "Init script failed. See ${LOG_FILE} for details"
|
|
exit 1
|
|
fi
|
|
fi
|
|
|
|
echo "=> Installing version ${version} (this takes some time) ..."
|
|
if ! /bin/bash "${box_src_tmp_dir}/scripts/installer.sh" --data "${data}" &>> "${LOG_FILE}"; then
|
|
echo "Failed to install cloudron. See ${LOG_FILE} for details"
|
|
exit 1
|
|
fi
|
|
|
|
echo -n "=> Waiting for cloudron to be ready (this takes some time) ..."
|
|
while true; do
|
|
echo -n "."
|
|
if journalctl -u box -a | grep "platformReady: " >/dev/null; then
|
|
break
|
|
fi
|
|
sleep 10
|
|
done
|
|
|
|
echo -e "\n\nRebooting this server now to let bootloader changes take effect.\n"
|
|
|
|
if [[ -n "${domain}" ]]; then
|
|
echo -e "Visit https://my.${domain} to finish setup once the server has rebooted.\n"
|
|
else
|
|
echo -e "Visit https://<IP> to finish setup once the server has rebooted.\n"
|
|
fi
|
|
|
|
if [[ "${initBaseImage}" == "true" ]]; then
|
|
systemctl reboot
|
|
fi
|