Files
cloudron-box/scripts/cloudron-setup

249 lines
8.5 KiB
Plaintext
Raw Normal View History

2016-10-24 16:18:02 +02:00
#!/bin/bash
2016-10-25 12:00:54 -07:00
set -eu -o pipefail
2016-10-24 16:18:02 +02:00
2016-11-01 15:13:20 +01:00
if [[ ${EUID} -ne 0 ]]; then
echo "This script should be run as root." > /dev/stderr
2017-01-23 12:57:29 -08:00
exit 1
fi
if [[ $(lsb_release -rs) != "16.04" ]]; then
echo "Cloudron requires Ubuntu 16.04" > /dev/stderr
2016-11-01 15:13:20 +01:00
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="19" # this is the size of "/" and required to fit in docker images 19 is a safe bet for different reporting on 20GB min
readonly MINIMUM_MEMORY="990" # this is mostly reported for 1GB main memory (DO 992, EC2 990)
# copied from cloudron-resize-fs.sh
readonly physical_memory=$(free -m | awk '/Mem:/ { print $2 }')
2017-01-03 09:26:08 +01:00
readonly disk_device="$(for d in $(find /dev -type b); do [ "$(mountpoint -d /)" = "$(mountpoint -x $d)" ] && echo $d && break; done)"
readonly disk_size_bytes=$(fdisk -l ${disk_device} | grep "Disk ${disk_device}" | awk '{ printf $5 }')
readonly disk_size_gb=$((${disk_size_bytes}/1024/1024/1024))
# verify the system has minimum requirements met
if [[ "${physical_memory}" -lt "${MINIMUM_MEMORY}" ]]; then
2017-01-03 14:27:01 -08:00
echo "Error: Cloudron requires atleast 1GB physical memory"
exit 1
fi
if [[ "${disk_size_gb}" -lt "${MINIMUM_DISK_SIZE_GB}" ]]; then
2017-01-03 14:27:01 -08:00
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
2016-10-24 16:18:02 +02:00
domain=""
2016-10-26 10:53:25 -07:00
provider=""
encryptionKey=""
restoreUrl=""
dnsProvider="manual"
2016-12-05 17:01:23 +01:00
tlsProvider="le-prod"
versionsUrl="https://s3.amazonaws.com/prod-cloudron-releases/versions.json"
requestedVersion="latest"
apiServerOrigin="https://api.cloudron.io"
dataJson=""
prerelease="false"
2017-02-01 14:06:18 -08:00
sourceTarballUrl=""
rebootServer="true"
2016-10-24 16:18:02 +02:00
args=$(getopt -o "" -l "domain:,help,skip-baseimage-init,data:,provider:,encryption-key:,restore-url:,tls-provider:,version:,versions-url:,api-server:,dns-provider:,env:,prerelease,skip-reboot,source-url:" -n "$0" -- "$@")
2016-10-24 16:18:02 +02:00
eval set -- "${args}"
while true; do
case "$1" in
--domain) domain="$2"; shift 2;;
2016-10-25 13:34:12 -07:00
--help) echo "See https://cloudron.io/references/selfhosting.html on how to install Cloudron"; exit 0;;
2016-10-24 16:18:02 +02:00
--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;;
2017-01-10 20:19:39 -08:00
--env)
if [[ "$2" == "dev" ]]; then
apiServerOrigin="https://api.dev.cloudron.io"
2017-01-10 20:19:39 -08:00
versionsUrl="https://s3.amazonaws.com/dev-cloudron-releases/versions.json"
tlsProvider="le-staging"
2017-01-10 20:19:39 -08:00
prerelease="true"
elif [[ "$2" == "staging" ]]; then
apiServerOrigin="https://api.staging.cloudron.io"
2017-01-10 20:19:39 -08:00
versionsUrl="https://s3.amazonaws.com/staging-cloudron-releases/versions.json"
tlsProvider="le-staging"
2017-01-10 20:19:39 -08:00
prerelease="true"
fi
shift 2;;
--versions-url) versionsUrl="$2"; shift 2;;
--api-server) apiServerOrigin="$2"; shift 2;;
--skip-baseimage-init) initBaseImage="false"; shift;;
--skip-reboot) rebootServer="false"; shift;;
--data) dataJson="$2"; shift 2;;
2017-01-10 20:19:39 -08:00
--prerelease) prerelease="true"; shift;;
2017-02-01 14:06:18 -08:00
--source-url) sourceTarballUrl="$2"; version="0.0.1+custom"; shift 2;;
2016-10-24 16:18:02 +02:00
--) 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
2016-10-26 10:53:25 -07:00
2017-01-12 10:31:54 -08:00
if [[ "${tlsProvider}" != "fallback" && "${tlsProvider}" != "le-prod" && "${tlsProvider}" != "le-staging" ]]; then
echo "--tls-provider must be one of: le-prod, le-staging, fallback"
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
2016-10-25 15:28:26 +02:00
echo ""
echo "##############################################"
echo " Cloudron Setup (${requestedVersion}) "
echo "##############################################"
echo ""
echo " Follow setup logs in a second terminal with:"
echo " $ tail -f ${LOG_FILE}"
echo ""
2016-12-22 13:28:04 -08:00
echo " Join us at https://chat.cloudron.io for any questions."
echo ""
if [[ "${initBaseImage}" == "true" ]]; then
2017-02-12 20:48:36 +01:00
echo "=> Updating apt and installing script dependencies"
if ! apt-get update &>> "${LOG_FILE}"; then
echo "Could not update package repositories"
exit 1
fi
2017-01-05 14:03:54 -08:00
if ! apt-get install curl python3 ubuntu-standard -y &>> "${LOG_FILE}"; then
echo "Could not install setup dependencies (curl)"
exit 1
fi
fi
2016-10-25 13:05:24 -07:00
echo "=> Checking version"
2017-02-01 14:06:18 -08:00
if [[ "${sourceTarballUrl}" == "" ]]; then
releaseJson=$(curl -s "${versionsUrl}")
if [[ "$requestedVersion" == "latest" ]]; then
pre=$([[ "${prerelease}" == "true" ]] && echo "null" || echo "-pre")
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
2016-10-25 13:05:24 -07:00
fi
# Build data
if [[ -z "${dataJson}" ]]; then
if [[ -z "${restoreUrl}" ]]; then
data=$(cat <<EOF
{
"boxVersionsUrl": "${versionsUrl}",
"fqdn": "${domain}",
"provider": "${provider}",
"apiServerOrigin": "${apiServerOrigin}",
"tlsConfig": {
"provider": "${tlsProvider}"
},
"dnsConfig": {
"provider": "${dnsProvider}"
},
"backupConfig" : {
"provider": "filesystem",
"backupFolder": "/var/backups",
"key": "${encryptionKey}"
},
2017-01-10 20:19:39 -08:00
"updateConfig": {
"prerelease": ${prerelease}
},
"version": "${version}"
}
EOF
)
else
data=$(cat <<EOF
{
"boxVersionsUrl": "${versionsUrl}",
"fqdn": "${domain}",
"provider": "${provider}",
"apiServerOrigin": "${apiServerOrigin}",
"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)
2016-12-26 11:57:14 -08:00
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 -n "=> Installing base dependencies and downloading docker images (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
echo ""
fi
echo "=> Installing version ${version} (this takes some time) ..."
2016-12-26 21:15:16 -08:00
if ! /bin/bash "${box_src_tmp_dir}/scripts/installer.sh" --data "${data}" &>> "${LOG_FILE}"; then
2016-10-25 12:47:51 -07:00
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 "."
2017-01-09 12:57:34 -08:00
if status=$(curl -q -f "http://localhost:3000/api/v1/cloudron/status" 2>/dev/null); then
[[ -z "$domain" ]] && break # with no domain, we are up and running
[[ "$status" == *"\"tls\": true"* ]] && break # with a domain, wait for the cert
fi
sleep 10
done
2017-01-05 20:18:57 -08:00
if [[ -n "${domain}" ]]; then
2017-02-14 14:30:54 -08:00
echo -e "\n\nVisit https://my.${domain} to finish setup once the server has rebooted.\n"
2017-01-05 20:18:57 -08:00
else
2017-02-14 14:30:54 -08:00
echo -e "\n\nVisit https://<IP> to finish setup once the server has rebooted.\n"
2017-01-05 20:18:57 -08:00
fi
if [[ "${rebootServer}" == "true" ]]; then
echo -e "\n\nRebooting this server now to let bootloader changes take effect.\n"
systemctl reboot
fi