this is useful when installing on bare metal, don't want to reboot server since the instructions get lost
253 lines
8.4 KiB
Bash
Executable File
253 lines
8.4 KiB
Bash
Executable File
#!/bin/bash
|
|
|
|
set -eu -o pipefail
|
|
|
|
# change this to a hash when we make a upgrade release
|
|
readonly LOG_FILE="/var/log/cloudron-setup.log"
|
|
readonly MINIMUM_DISK_SIZE_GB="18" # this is the size of "/" and required to fit in docker images 18 is a safe bet for different reporting on 20GB min
|
|
readonly MINIMUM_MEMORY="974" # this is mostly reported for 1GB main memory (DO 992, EC2 990, Linode 989, Serverdiscounter.com 974)
|
|
|
|
readonly curl="curl --fail --connect-timeout 20 --retry 10 --retry-delay 2 --max-time 2400"
|
|
|
|
# copied from cloudron-resize-fs.sh
|
|
readonly rootfs_type=$(LC_ALL=C df --output=fstype / | tail -n1)
|
|
readonly physical_memory=$(LC_ALL=C free -m | awk '/Mem:/ { print $2 }')
|
|
readonly disk_size_bytes=$(LC_ALL=C df --output=size / | tail -n1)
|
|
readonly disk_size_gb=$((${disk_size_bytes}/1024/1024))
|
|
|
|
readonly RED='\033[31m'
|
|
readonly GREEN='\033[32m'
|
|
readonly DONE='\033[m'
|
|
|
|
# verify the system has minimum requirements met
|
|
if [[ "${rootfs_type}" != "ext4" ]]; then
|
|
echo "Error: Cloudron requires '/' to be ext4" # see #364
|
|
exit 1
|
|
fi
|
|
|
|
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 / is ${disk_size_gb}GB)"
|
|
exit 1
|
|
fi
|
|
|
|
if systemctl -q is-active box; then
|
|
echo "Error: Cloudron is already installed. To reinstall, start afresh"
|
|
exit 1
|
|
fi
|
|
|
|
initBaseImage="true"
|
|
# provisioning data
|
|
provider=""
|
|
edition=""
|
|
requestedVersion=""
|
|
apiServerOrigin="https://api.cloudron.io"
|
|
webServerOrigin="https://cloudron.io"
|
|
sourceTarballUrl=""
|
|
rebootServer="true"
|
|
baseDataDir=""
|
|
|
|
args=$(getopt -o "" -l "help,skip-baseimage-init,provider:,version:,env:,edition:,skip-reboot" -n "$0" -- "$@")
|
|
eval set -- "${args}"
|
|
|
|
while true; do
|
|
case "$1" in
|
|
--help) echo "See https://cloudron.io/documentation/installation/ on how to install Cloudron"; exit 0;;
|
|
--provider) provider="$2"; shift 2;;
|
|
--edition) edition="$2"; shift 2;;
|
|
--version) requestedVersion="$2"; shift 2;;
|
|
--env)
|
|
if [[ "$2" == "dev" ]]; then
|
|
apiServerOrigin="https://api.dev.cloudron.io"
|
|
webServerOrigin="https://dev.cloudron.io"
|
|
elif [[ "$2" == "staging" ]]; then
|
|
apiServerOrigin="https://api.staging.cloudron.io"
|
|
webServerOrigin="https://staging.cloudron.io"
|
|
fi
|
|
shift 2;;
|
|
--skip-baseimage-init) initBaseImage="false"; shift;;
|
|
--skip-reboot) rebootServer="false"; shift;;
|
|
--) break;;
|
|
*) echo "Unknown option $1"; exit 1;;
|
|
esac
|
|
done
|
|
|
|
# Only --help works as non-root
|
|
if [[ ${EUID} -ne 0 ]]; then
|
|
echo "This script should be run as root." > /dev/stderr
|
|
exit 1
|
|
fi
|
|
|
|
# Only --help works with mismatched ubuntu
|
|
ubuntu_version=$(lsb_release -rs)
|
|
if [[ "${ubuntu_version}" != "16.04" && "${ubuntu_version}" != "18.04" ]]; then
|
|
echo "Cloudron requires Ubuntu 16.04 or 18.04" > /dev/stderr
|
|
exit 1
|
|
fi
|
|
|
|
# Can only write after we have confirmed script has root access
|
|
echo "Running cloudron-setup with args : $@" > "${LOG_FILE}"
|
|
|
|
# validate arguments in the absence of data
|
|
if [[ -z "${provider}" ]]; then
|
|
echo "--provider is required (azure, digitalocean, ec2, exoscale, gce, hetzner, lightsail, linode, netcup, ovh, rosehosting, scaleway, vultr or generic)"
|
|
exit 1
|
|
elif [[ \
|
|
"${provider}" != "ami" && \
|
|
"${provider}" != "azure" && \
|
|
"${provider}" != "caas" && \
|
|
"${provider}" != "cloudscale" && \
|
|
"${provider}" != "digitalocean" && \
|
|
"${provider}" != "ec2" && \
|
|
"${provider}" != "exoscale" && \
|
|
"${provider}" != "galaxygate" && \
|
|
"${provider}" != "digitalocean" && \
|
|
"${provider}" != "gce" && \
|
|
"${provider}" != "hetzner" && \
|
|
"${provider}" != "lightsail" && \
|
|
"${provider}" != "linode" && \
|
|
"${provider}" != "netcup" && \
|
|
"${provider}" != "ovh" && \
|
|
"${provider}" != "rosehosting" && \
|
|
"${provider}" != "scaleway" && \
|
|
"${provider}" != "vultr" && \
|
|
"${provider}" != "generic" \
|
|
]]; then
|
|
echo "--provider must be one of: azure, cloudscale.ch, digitalocean, ec2, exoscale, galaxygate, gce, hetzner, lightsail, linode, netcup, ovh, rosehosting, scaleway, vultr or generic"
|
|
exit 1
|
|
fi
|
|
|
|
if [[ -n "${baseDataDir}" && ! -d "${baseDataDir}" ]]; then
|
|
echo "${baseDataDir} does not exist"
|
|
exit 1
|
|
fi
|
|
|
|
echo ""
|
|
echo "##############################################"
|
|
echo " Cloudron Setup (${requestedVersion:-latest})"
|
|
echo "##############################################"
|
|
echo ""
|
|
echo " Follow setup logs in a second terminal with:"
|
|
echo " $ tail -f ${LOG_FILE}"
|
|
echo ""
|
|
echo " Join us at https://forum.cloudron.io for any questions."
|
|
echo ""
|
|
|
|
if [[ "${initBaseImage}" == "true" ]]; then
|
|
echo "=> Ensure required apt sources"
|
|
if ! add-apt-repository universe &>> "${LOG_FILE}"; then
|
|
echo "Could not add required apt sources (for nginx-full). See ${LOG_FILE}"
|
|
exit 1
|
|
fi
|
|
|
|
echo "=> Updating apt and installing script dependencies"
|
|
if ! apt-get update &>> "${LOG_FILE}"; then
|
|
echo "Could not update package repositories. See ${LOG_FILE}"
|
|
exit 1
|
|
fi
|
|
|
|
if ! apt-get install curl python3 ubuntu-standard -y &>> "${LOG_FILE}"; then
|
|
echo "Could not install setup dependencies (curl). See ${LOG_FILE}"
|
|
exit 1
|
|
fi
|
|
fi
|
|
|
|
echo "=> Checking version"
|
|
if ! releaseJson=$($curl -s "${apiServerOrigin}/api/v1/releases?boxVersion=${requestedVersion}"); then
|
|
echo "Failed to get release information"
|
|
exit 1
|
|
fi
|
|
|
|
if [[ "$requestedVersion" == "" ]]; then
|
|
version=$(echo "${releaseJson}" | python3 -c 'import json,sys;obj=json.load(sys.stdin);print(obj["version"])')
|
|
else
|
|
version="${requestedVersion}"
|
|
fi
|
|
|
|
if ! sourceTarballUrl=$(echo "${releaseJson}" | python3 -c 'import json,sys;obj=json.load(sys.stdin);print(obj["info"]["sourceTarballUrl"])'); then
|
|
echo "No source code for version '${requestedVersion:-latest}'"
|
|
exit 1
|
|
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 -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
|
|
|
|
# NOTE: this install script only supports 3.x and above
|
|
echo "=> Installing version ${version} (this takes some time) ..."
|
|
if [[ "${version}" =~ 3\.[0-2]+\.[0-9]+ ]]; then
|
|
readonly DATA_FILE="/root/cloudron-install-data.json"
|
|
data=$(cat <<EOF
|
|
{
|
|
"provider": "${provider}",
|
|
"edition": "${edition}",
|
|
"apiServerOrigin": "${apiServerOrigin}",
|
|
"webServerOrigin": "${webServerOrigin}",
|
|
"version": "${version}"
|
|
}
|
|
EOF
|
|
)
|
|
echo "${data}" > "${DATA_FILE}"
|
|
|
|
if ! /bin/bash "${box_src_tmp_dir}/scripts/installer.sh" --data-file "${DATA_FILE}" &>> "${LOG_FILE}"; then
|
|
echo "Failed to install cloudron. See ${LOG_FILE} for details"
|
|
exit 1
|
|
fi
|
|
|
|
rm "${DATA_FILE}"
|
|
else
|
|
mkdir -p /etc/cloudron
|
|
cat > "/etc/cloudron/cloudron.conf" <<CONF_END
|
|
{
|
|
"apiServerOrigin": "${apiServerOrigin}",
|
|
"webServerOrigin": "${webServerOrigin}",
|
|
"provider": "${provider}",
|
|
"edition": "${edition}"
|
|
}
|
|
CONF_END
|
|
|
|
if ! /bin/bash "${box_src_tmp_dir}/scripts/installer.sh" &>> "${LOG_FILE}"; then
|
|
echo "Failed to install cloudron. See ${LOG_FILE} for details"
|
|
exit 1
|
|
fi
|
|
fi
|
|
|
|
echo -n "=> Waiting for cloudron to be ready (this takes some time) ..."
|
|
while true; do
|
|
echo -n "."
|
|
if status=$($curl -q -f "http://localhost:3000/api/v1/cloudron/status" 2>/dev/null); then
|
|
break # we are up and running
|
|
fi
|
|
sleep 10
|
|
done
|
|
|
|
echo -e "\n\n${GREEN}Visit https://<IP> and accept the self-signed certificate to finish setup.${DONE}"
|
|
|
|
if [[ "${rebootServer}" == "true" ]]; then
|
|
systemctl stop box mysql # sometimes mysql ends up having corrupt privilege tables
|
|
|
|
read -p "This server has to rebooted to apply all the settings. Reboot now ? [Y/n] " yn
|
|
yn=${yn:-y}
|
|
case $yn in
|
|
[Yy]* ) systemctl reboot;;
|
|
* ) exit;;
|
|
esac
|
|
fi
|