|
1 | 1 | #!/usr/bin/env bash
|
2 | 2 | set -euo pipefail
|
3 | 3 |
|
| 4 | +export DEBIAN_FRONTEND=noninteractive |
| 5 | +needrestart_conf_dir="/etc/needrestart/conf.d" |
| 6 | +needrestart_conf_file="${needrestart_conf_dir}/temp-disable-for-umbrel-install.conf" |
| 7 | +sudo mkdir -p "${needrestart_conf_dir}" |
| 8 | +echo "# Restart services (l)ist only, (i)nteractive or (a)utomatically. |
| 9 | +\$nrconf{restart} = 'l'; |
| 10 | +# Disable hints on pending kernel upgrades. |
| 11 | +\$nrconf{kernelhints} = 0; " | sudo tee "${needrestart_conf_file}" > /dev/null |
| 12 | +trap "sudo rm -f ${needrestart_conf_file}" EXIT |
| 13 | + |
| 14 | +# Default options |
| 15 | +BOOTSTRAPPED="false" |
| 16 | +PRINT_DOCKER_WARNING="true" |
| 17 | +UPDATE_APT="true" |
| 18 | +INSTALL_APT_DEPS="true" |
| 19 | +INSTALL_AVAHI="true" |
| 20 | +INSTALL_YQ="true" |
| 21 | +INSTALL_DOCKER="true" |
| 22 | +INSTALL_DOCKER_COMPOSE="true" |
| 23 | +INSTALL_START_SCRIPT="true" |
| 24 | +INSTALL_UMBREL="true" |
| 25 | +UMBREL_VERSION="release" |
| 26 | +UMBREL_REPO="getumbrel/umbrel" |
| 27 | +UMBREL_INSTALL_PATH="$HOME/umbrel" |
| 28 | + |
| 29 | +# Parse arguments |
4 | 30 | arguments=${@:-}
|
5 | 31 |
|
6 |
| -# Shim to the old install script but pin to v0.5.4 |
7 |
| -curl https://raw.githubusercontent.com/getumbrel/umbrel/v0.5.4/scripts/install | bash -s -- --version v0.5.4 $arguments |
| 32 | +# if [[ "${arguments}" = *"--bootstrapped"* ]] |
| 33 | +# then |
| 34 | +# BOOTSTRAPPED="true" |
| 35 | +# fi |
| 36 | +# Force bootstrapped |
| 37 | +BOOTSTRAPPED="true" |
| 38 | + |
| 39 | +if [[ "${arguments}" = *"--no-docker-warning"* ]] |
| 40 | +then |
| 41 | + PRINT_DOCKER_WARNING="false" |
| 42 | +fi |
| 43 | + |
| 44 | +if [[ "${arguments}" = *"--no-install-avahi"* ]] |
| 45 | +then |
| 46 | + INSTALL_AVAHI="false" |
| 47 | +fi |
| 48 | + |
| 49 | +if [[ "${arguments}" = *"--no-install-yq"* ]] |
| 50 | +then |
| 51 | + INSTALL_YQ="false" |
| 52 | +fi |
| 53 | + |
| 54 | +if [[ "${arguments}" = *"--no-install-docker"* ]] |
| 55 | +then |
| 56 | + INSTALL_DOCKER="false" |
| 57 | +fi |
| 58 | + |
| 59 | +if [[ "${arguments}" = *"--no-install-compose"* ]] |
| 60 | +then |
| 61 | + INSTALL_DOCKER_COMPOSE="false" |
| 62 | +fi |
| 63 | + |
| 64 | +if [[ "${arguments}" = *"--no-install-start-script"* ]] |
| 65 | +then |
| 66 | + INSTALL_START_SCRIPT="false" |
| 67 | +fi |
| 68 | + |
| 69 | +if [[ "${arguments}" = *"--no-install-umbrel"* ]] |
| 70 | +then |
| 71 | + INSTALL_UMBREL="false" |
| 72 | +fi |
| 73 | + |
| 74 | +if [[ "${arguments}" = *"--no-install-deps"* ]] |
| 75 | +then |
| 76 | + UPDATE_APT="false" |
| 77 | + INSTALL_APT_DEPS="false" |
| 78 | + INSTALL_AVAHI="false" |
| 79 | + INSTALL_YQ="false" |
| 80 | + INSTALL_DOCKER="false" |
| 81 | + INSTALL_DOCKER_COMPOSE="false" |
| 82 | + INSTALL_UMBREL="true" |
| 83 | +fi |
| 84 | + |
| 85 | +# Pin version to v0.5.4 |
| 86 | +# if [[ "${arguments}" = *"--version"* ]] |
| 87 | +# then |
| 88 | +# UMBREL_VERSION="$(echo "${arguments}" | sed 's/.*--version \([^ ]*\).*/\1/')" |
| 89 | +# fi |
| 90 | +UMBREL_VERSION="v0.5.4" |
| 91 | + |
| 92 | +if [[ "${arguments}" = *"--install-path"* ]] |
| 93 | +then |
| 94 | + UMBREL_INSTALL_PATH="$(echo "${arguments}" | sed 's/.*--install-path \([^ ]*\).*/\1/')" |
| 95 | +fi |
| 96 | + |
| 97 | +get_umbrel_version() { |
| 98 | + version="${UMBREL_VERSION}" |
| 99 | + if [[ "${version}" = "release" ]] |
| 100 | + then |
| 101 | + version=$(curl --silent https://api.github.com/repos/${UMBREL_REPO}/releases/latest | sed -n 's/.*"tag_name": "\([^"]*\).*/\1/p') |
| 102 | + fi |
| 103 | + |
| 104 | + echo $version |
| 105 | +} |
| 106 | + |
| 107 | +bootstrap() { |
| 108 | + version=$(get_umbrel_version) |
| 109 | + curl --location --silent "https://raw.githubusercontent.com/${UMBREL_REPO}/${version}/scripts/install" | \ |
| 110 | + bash -s -- --bootstrapped $arguments |
| 111 | +} |
| 112 | + |
| 113 | +update_apt() { |
| 114 | + sudo apt-get update --yes |
| 115 | +} |
| 116 | + |
| 117 | +install_apt_deps() { |
| 118 | + sudo apt-get install --yes fswatch jq rsync curl git gettext-base python3 gnupg |
| 119 | +} |
| 120 | + |
| 121 | +install_avahi() { |
| 122 | + sudo apt-get install --yes avahi-daemon avahi-discover libnss-mdns |
| 123 | +} |
| 124 | + |
| 125 | +install_yq() { |
| 126 | + # Define checksums for yq (4.24.5) |
| 127 | + declare -A yq_sha256 |
| 128 | + yq_sha256["arm64"]="8879e61c0b3b70908160535ea358ec67989ac4435435510e1fcb2eda5d74a0e9" |
| 129 | + yq_sha256["amd64"]="c93a696e13d3076e473c3a43c06fdb98fafd30dc2f43bc771c4917531961c760" |
| 130 | + |
| 131 | + yq_version="v4.24.5" |
| 132 | + system_arch=$(dpkg --print-architecture) |
| 133 | + yq_binary="yq_linux_${system_arch}" |
| 134 | + |
| 135 | + # Download yq from GitHub |
| 136 | + yq_temp_file="/tmp/yq" |
| 137 | + curl -L "https://github.com/mikefarah/yq/releases/download/${yq_version}/${yq_binary}" -o "${yq_temp_file}" |
| 138 | + |
| 139 | + # Check file matches checksum |
| 140 | + if [[ "$(sha256sum "${yq_temp_file}" | awk '{ print $1 }')" == "${yq_sha256[$system_arch]}" ]]; then |
| 141 | + sudo mv "${yq_temp_file}" /usr/bin/yq |
| 142 | + sudo chmod +x /usr/bin/yq |
| 143 | + |
| 144 | + echo "yq installed successfully..." |
| 145 | + else |
| 146 | + echo "yq install failed. sha256sum mismatch" |
| 147 | + exit 1 |
| 148 | + fi |
| 149 | +} |
| 150 | + |
| 151 | +install_docker() { |
| 152 | + # Install Docker |
| 153 | + curl -fsSL https://get.docker.com | sudo sh |
| 154 | +} |
| 155 | + |
| 156 | +install_docker_compose() { |
| 157 | + sudo apt-get install --yes libffi-dev docker-compose |
| 158 | +} |
| 159 | + |
| 160 | +get_arch() { |
| 161 | + machine_arch="$(uname --machine)" |
| 162 | + if [[ "${machine_arch}" = "x86_64" ]] |
| 163 | + then |
| 164 | + binary_arch="amd64" |
| 165 | + elif [[ "${machine_arch}" = "aarch64" ]] |
| 166 | + then |
| 167 | + binary_arch="arm64" |
| 168 | + else |
| 169 | + echo "Unsupported architecture: ${machine_arch}" |
| 170 | + exit 1 |
| 171 | + fi |
| 172 | + |
| 173 | + echo "${binary_arch}" |
| 174 | +} |
| 175 | + |
| 176 | +install_umbrel() { |
| 177 | + version=$(get_umbrel_version) |
| 178 | + binary_arch=$(get_arch) |
| 179 | + curl --location "https://api.github.com/repos/${UMBREL_REPO}/tarball/${version}" | \ |
| 180 | + tar --extract --gzip --strip-components=1 --directory="${UMBREL_INSTALL_PATH}" |
| 181 | + |
| 182 | + binary_url="https://github.com/${UMBREL_REPO}/releases/download/${version}/umbreld-${version}-${binary_arch}.tar.gz" |
| 183 | + curl --fail --location "${binary_url}" | tar --extract --gzip --directory="${UMBREL_INSTALL_PATH}/bin" |
| 184 | +} |
| 185 | + |
| 186 | +install_systemd_service() { |
| 187 | +echo " |
| 188 | +[Unit] |
| 189 | +Wants=network-online.target |
| 190 | +After=network-online.target |
| 191 | +Wants=docker.service |
| 192 | +After=docker.service |
| 193 | +
|
| 194 | +# This prevents us hitting restart rate limits and ensures we keep restarting |
| 195 | +# indefinitely. |
| 196 | +StartLimitInterval=0 |
| 197 | +
|
| 198 | +[Service] |
| 199 | +Type=forking |
| 200 | +TimeoutStartSec=infinity |
| 201 | +TimeoutStopSec=16min |
| 202 | +ExecStart=${UMBREL_INSTALL_PATH}/scripts/start |
| 203 | +ExecStop=${UMBREL_INSTALL_PATH}/scripts/stop |
| 204 | +User=root |
| 205 | +Group=root |
| 206 | +StandardOutput=syslog |
| 207 | +StandardError=syslog |
| 208 | +SyslogIdentifier=umbrel startup |
| 209 | +RemainAfterExit=yes |
| 210 | +Restart=always |
| 211 | +RestartSec=10 |
| 212 | +
|
| 213 | +[Install] |
| 214 | +WantedBy=multi-user.target" | sudo tee "/etc/systemd/system/umbrel-startup.service" |
| 215 | + sudo chmod 644 "/etc/systemd/system/umbrel-startup.service" |
| 216 | + sudo systemctl enable "umbrel-startup.service" |
| 217 | +} |
| 218 | + |
| 219 | +main() { |
| 220 | + if [[ "${BOOTSTRAPPED}" = "false" ]] |
| 221 | + then |
| 222 | + bootstrap |
| 223 | + exit |
| 224 | + fi |
| 225 | + |
| 226 | + if [[ "${INSTALL_UMBREL}" = "true" ]] |
| 227 | + then |
| 228 | + echo "About to install Umbrel in \"${UMBREL_INSTALL_PATH}\"." |
| 229 | + echo "If you would like to install somewhere else you can specify a custom location with:" |
| 230 | + echo |
| 231 | + echo " curl -L https://umbrel.sh | bash -s -- --install-path /some/path" |
| 232 | + echo |
| 233 | + echo "Waiting for 10 seconds..." |
| 234 | + echo |
| 235 | + echo "You may press Ctrl+C now to abort the install." |
| 236 | + echo |
| 237 | + sleep 10 |
| 238 | + fi |
| 239 | + |
| 240 | + if [[ "${PRINT_DOCKER_WARNING}" = "true" ]] && [[ "${INSTALL_DOCKER}" = "true" ]] && command -v docker >/dev/null 2>&1 |
| 241 | + then |
| 242 | + |
| 243 | +cat << 'EOF' |
| 244 | +It looks like you already have Docker installed. Umbrel requires a modern version of Docker so this script will update them with the official Docker install script. |
| 245 | +
|
| 246 | +If you would like to disable this behaviour you can abort this install and run again with --no-install-docker or --no-install-compose. |
| 247 | +
|
| 248 | +You can pass flags to the installer like this: |
| 249 | +
|
| 250 | + curl -L https://umbrel.sh | bash -s -- --no-install-docker --no-install-compose |
| 251 | +
|
| 252 | +Waiting for 30 seconds... |
| 253 | +
|
| 254 | +You may press Ctrl+C now to abort the install. |
| 255 | +
|
| 256 | +EOF |
| 257 | + sleep 30 |
| 258 | + fi |
| 259 | + |
| 260 | + if [[ "${INSTALL_UMBREL}" = "true" ]] |
| 261 | + then |
| 262 | + mkdir -p "${UMBREL_INSTALL_PATH}" |
| 263 | + if [[ "$(ls --almost-all "${UMBREL_INSTALL_PATH}")" ]] |
| 264 | + then |
| 265 | + echo "Error: Umbrel install path \"${UMBREL_INSTALL_PATH}\" already contains files" |
| 266 | + echo "You can install Umbrel in a custom location with:" |
| 267 | + echo |
| 268 | + echo " curl -L https://umbrel.sh | bash -s -- --install-path /some/path" |
| 269 | + exit 1 |
| 270 | + fi |
| 271 | + fi |
| 272 | + |
| 273 | + if [[ "${UPDATE_APT}" = "true" ]] |
| 274 | + then |
| 275 | + update_apt |
| 276 | + fi |
| 277 | + |
| 278 | + if [[ "${INSTALL_APT_DEPS}" = "true" ]] |
| 279 | + then |
| 280 | + install_apt_deps |
| 281 | + fi |
| 282 | + |
| 283 | + if [[ "${INSTALL_AVAHI}" = "true" ]] |
| 284 | + then |
| 285 | + install_avahi |
| 286 | + fi |
| 287 | + |
| 288 | + if [[ "${INSTALL_YQ}" = "true" ]] |
| 289 | + then |
| 290 | + install_yq |
| 291 | + fi |
| 292 | + |
| 293 | + if [[ "${INSTALL_DOCKER}" = "true" ]] |
| 294 | + then |
| 295 | + install_docker |
| 296 | + fi |
| 297 | + |
| 298 | + if [[ "${INSTALL_DOCKER_COMPOSE}" = "true" ]] |
| 299 | + then |
| 300 | + install_docker_compose |
| 301 | + fi |
| 302 | + |
| 303 | + if [[ "${INSTALL_UMBREL}" = "true" ]] |
| 304 | + then |
| 305 | + install_umbrel |
| 306 | + |
| 307 | + if [[ "${INSTALL_START_SCRIPT}" = "true" ]] |
| 308 | + then |
| 309 | + install_systemd_service |
| 310 | + fi |
| 311 | + |
| 312 | + # Do the initial start outside of systemd so we get logs |
| 313 | + sudo ${UMBREL_INSTALL_PATH}/scripts/start |
| 314 | + |
| 315 | + if [[ "${INSTALL_START_SCRIPT}" = "true" ]] |
| 316 | + then |
| 317 | + # Kick off the systemd service again so it's in sync |
| 318 | + sudo systemctl start "umbrel-startup.service" |
| 319 | + fi |
| 320 | + |
| 321 | + echo |
| 322 | + echo "Umbrel has been sucessfully installed!" |
| 323 | + fi |
| 324 | +} |
| 325 | + |
| 326 | +main |
0 commit comments