|
| 1 | +#!/bin/bash |
| 2 | +#### |
| 3 | + # Pterodactyl - Panel |
| 4 | + # Copyright (c) 2015 - 2016 Dane Everitt <dane@daneeveritt.com> |
| 5 | + # |
| 6 | + # Permission is hereby granted, free of charge, to any person obtaining a copy |
| 7 | + # of this software and associated documentation files (the "Software"), to deal |
| 8 | + # in the Software without restriction, including without limitation the rights |
| 9 | + # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell |
| 10 | + # copies of the Software, and to permit persons to whom the Software is |
| 11 | + # furnished to do so, subject to the following conditions: |
| 12 | + # |
| 13 | + # The above copyright notice and this permission notice shall be included in all |
| 14 | + # copies or substantial portions of the Software. |
| 15 | + # |
| 16 | + # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
| 17 | + # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
| 18 | + # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE |
| 19 | + # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER |
| 20 | + # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, |
| 21 | + # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE |
| 22 | + # SOFTWARE. |
| 23 | +#### |
| 24 | +set +e |
| 25 | +export DEBIAN_FRONTEND=noninteractive |
| 26 | + |
| 27 | +INSTALL_DIR="/srv/daemon" |
| 28 | +DATA_DIR="{{ $node->daemonBase }}" |
| 29 | +CURRENT_SYSTEM_KERNEL="$(uname -r)" |
| 30 | +DL_VERSION="0.0.1" |
| 31 | + |
| 32 | +command_exists() { |
| 33 | + command -v "$@" > /dev/null 2>&1 |
| 34 | +} |
| 35 | + |
| 36 | +error_message() { |
| 37 | + echo -e "\e[1m\e[97m\e[41m$1\e[0m" |
| 38 | + exit 1 |
| 39 | +} |
| 40 | + |
| 41 | +warning_message() { |
| 42 | + echo -e "\e[43m\e[30m$1\e[0m" |
| 43 | +} |
| 44 | + |
| 45 | +success_message() { |
| 46 | + echo -e "\e[32m$1\e[0m" |
| 47 | +} |
| 48 | + |
| 49 | +running_command() { |
| 50 | + echo -e " ;; \e[47m\e[30m$1\e[0m" |
| 51 | +} |
| 52 | + |
| 53 | +for i in "$@" |
| 54 | +do |
| 55 | + case $i in |
| 56 | + -d|--directory) |
| 57 | + INSTALL_DIR="$2" |
| 58 | + ;; |
| 59 | + -a|--datadir) |
| 60 | + DATA_DIR="$2" |
| 61 | + ;; |
| 62 | + -g|--git) |
| 63 | + USE_GIT=true |
| 64 | + ;; |
| 65 | + -u|--unstable) |
| 66 | + USE_UNSTABLE=true |
| 67 | + USE_GIT=true |
| 68 | + ;; |
| 69 | + -v|--version) |
| 70 | + DL_VERSION="$2" |
| 71 | + ;; |
| 72 | + -h|--help) |
| 73 | + echo "./installer [opts]" |
| 74 | + echo " -d | --directory The directory to install the daemon into. (default: /srv/daemon)" |
| 75 | + echo " -a | --datadir The directory that daemon users will be stored in. (default: /srv/daemon-data)" |
| 76 | + echo " -g | --git Use this flag to download the daemon using a git clone. (default: false)" |
| 77 | + echo " -u | --unstable Install unstable version of the daemon, automatically uses --git flag. (default: false)" |
| 78 | + echo " -v | --version The version of the daemon to download." |
| 79 | + exit |
| 80 | + ;; |
| 81 | + esac |
| 82 | +shift |
| 83 | +done |
| 84 | + |
| 85 | +warning_message "This program will automatically configure your system to run the Pterodactyl Daemon." |
| 86 | +warning_message " - Install Location: $INSTALL_DIR" |
| 87 | +warning_message " - Data Location: $DATA_DIR" |
| 88 | +warning_message "This script will continue in 10 seconds. Press CRTL+C to exit now." |
| 89 | +sleep 10 |
| 90 | + |
| 91 | +# Super basic system detection |
| 92 | +if command_exists apt-get; then |
| 93 | + INSTALL_CMD="apt-get -y" |
| 94 | +elif command_exists yum; then |
| 95 | + INSTALL_CMD="yum -y" |
| 96 | +else |
| 97 | + error_message "No supported repository manager was found." |
| 98 | +fi |
| 99 | + |
| 100 | +if ! command_exists curl; then |
| 101 | + warning_message "No file retrieval method found, installing curl now..." |
| 102 | + running_command "$INSTALL_CMD -y install curl" |
| 103 | + $INSTALL_CMD -y install curl |
| 104 | + if [ "$?" -ne "0" ]; then |
| 105 | + error_message "Unable to install curl and no other method was found for retrieving files." |
| 106 | + fi |
| 107 | +fi |
| 108 | + |
| 109 | +# Determine if the kernel is high enough version. |
| 110 | +if command_exists awk; then |
| 111 | + PROCESSED_KERNEL_VERSION=$(awk -F. '{print $1$2}' <<< $CURRENT_SYSTEM_KERNEL) |
| 112 | +elif command_exists cut; then |
| 113 | + PROCESSED_KERNEL_VERSION=$(cut -d. -f1-2 --output-delimiter='' <<< $CURRENT_SYSTEM_KERNEL) |
| 114 | +else |
| 115 | + error_message "You seem to be missing some core tools that this script needs: awk (or) cut" |
| 116 | +fi |
| 117 | + |
| 118 | +if [ "$PROCESSED_KERNEL_VERSION" -lt "310" ]; then |
| 119 | + error_message "Your kernel version must be at least 3.10 or higher for the daemon to work. You are using $CURRENT_SYSTEM_KERNEL" |
| 120 | +fi |
| 121 | + |
| 122 | +check_cgroups() { |
| 123 | + # Check CGroups |
| 124 | + CGROUP_DIRECTORY_LISTING="$(awk '/[, ](cpu|cpuacct|cpuset|devices|freezer|memory)[, ]/ && $3 == "cgroup" { print $2 }' /proc/mounts | head -n1)" |
| 125 | + if [ ! -z $CGROUP_DIRECTORY_LISTING -a -d $CGROUP_DIRECTORY_LISTING ]; then |
| 126 | + CGROUP_DIRECTORY="$(dirname $CGROUP_DIRECTORY_LISTING 2>&1)" |
| 127 | + if [ -d "$CGROUP_DIRECTORY/cpu" -a -d "$CGROUP_DIRECTORY/cpuacct" -a -d "$CGROUP_DIRECTORY/cpuset" -a -d "$CGROUP_DIRECTORY/devices" -a -d "$CGROUP_DIRECTORY/freezer" -a -d "$CGROUP_DIRECTORY/memory" ]; then |
| 128 | + success_message "cgroups enabled and are valid on this machine." |
| 129 | + else |
| 130 | + error_message "You appear to be missing some important cgroups on this machine." |
| 131 | + fi |
| 132 | + else |
| 133 | + if [ ! -e "/proc/cgroups" ]; then |
| 134 | + error_message "This kernel does not appear to support cgroups! Please see https://gist.github.com/DaneEveritt/0f071f481b4d3fa637d4 for more information." |
| 135 | + elif [ ! -d "/sys/fs/cgroup" ]; then |
| 136 | + error_message "This kernel does not appear to support cgroups! Please see https://gist.github.com/DaneEveritt/0f071f481b4d3fa637d4 for more information." |
| 137 | + fi |
| 138 | + |
| 139 | + if [ ! -f "/tmp/mount_cgroup.sh" ]; then |
| 140 | + # Try to enable cgroups |
| 141 | + warning_message "Attempting to enable cgroups on this machine..." |
| 142 | + running_command "curl -L https://raw.githubusercontent.com/tianon/cgroupfs-mount/master/cgroupfs-mount > /tmp/mount_cgroup.sh" |
| 143 | + curl -L https://raw.githubusercontent.com/tianon/cgroupfs-mount/master/cgroupfs-mount > /tmp/mount_cgroup.sh |
| 144 | + |
| 145 | + running_command "chmod +x /tmp/mount_cgroup.sh" |
| 146 | + chmod +x /tmp/mount_cgroup.sh |
| 147 | + |
| 148 | + running_command "bash /tmp/mount_cgroup.sh" |
| 149 | + bash /tmp/mount_cgroup.sh |
| 150 | + check_cgroups |
| 151 | + else |
| 152 | + rm -rf /tmp/mount_cgroup.sh > /dev/null 2>&1 |
| 153 | + error_message "Failed to enable cgroups on this machine." |
| 154 | + fi |
| 155 | + fi |
| 156 | +} |
| 157 | + |
| 158 | +# Check those groups. |
| 159 | +check_cgroups |
| 160 | + |
| 161 | +# Lets install the dependencies. |
| 162 | +$INSTALL_CMD install linux-image-extra-$CURRENT_SYSTEM_KERNEL |
| 163 | +if [ "$?" -ne "0" ]; then |
| 164 | + warning_message "You appear to have a non-generic kernel meaning we could not install extra kernel tools." |
| 165 | + warning_message "We will continue to install, but some docker enhancements might not work as expected." |
| 166 | + warning_message "Continuing in 10 seconds, press CTRL+C to cancel this script." |
| 167 | + sleep 10 |
| 168 | +fi |
| 169 | + |
| 170 | +success_message "Installing Docker..." |
| 171 | +running_command "curl -L https://get.docker.com/ | sh" |
| 172 | +curl -L https://get.docker.com/ | sh |
| 173 | +if [ "$?" -ne "0" ]; then |
| 174 | + error_message "Unable to install docker, an error occured!" |
| 175 | +fi; |
| 176 | + |
| 177 | +success_message "Installing NodeJS 5.x..." |
| 178 | +running_command "curl -L https://deb.nodesource.com/setup_5.x | sudo -E bash -" |
| 179 | +curl -L https://deb.nodesource.com/setup_5.x | sudo -E bash - |
| 180 | +if [ "$?" -ne "0" ]; then |
| 181 | + error_message "Unable to configure NodeJS, an error occured!" |
| 182 | +fi; |
| 183 | + |
| 184 | +running_command "$INSTALL_CMD install tar nodejs" |
| 185 | +$INSTALL_CMD install tar nodejs |
| 186 | +if [ "$?" -ne "0" ]; then |
| 187 | + error_message "Unable to install NodeJS or Tar, an error occured!" |
| 188 | +fi; |
| 189 | + |
| 190 | +running_command "mkdir -p $INSTALL_DIR $DATA_DIR" |
| 191 | +mkdir -p $INSTALL_DIR $DATA_DIR |
| 192 | +cd $INSTALL_DIR |
| 193 | + |
| 194 | +if [ -z $USE_UNSTABLE -a -z $USE_GIT ]; then |
| 195 | + CLEANUP_PROGRAMS="nodejs docker-engine" |
| 196 | + |
| 197 | + running_command "curl -sI https://github.com/Pterodactyl/Daemon/archive/$DL_VERSION.tar.gz | head -n1 | cut -d$' ' -f2" |
| 198 | + GITHUB_STATUS="$(curl -sI https://github.com/Pterodactyl/Daemon/archive/$DL_VERSION.tar.gz | head -n1 | cut -d$' ' -f2)" |
| 199 | + if [ $GITHUB_STATUS -ne "200" ]; then |
| 200 | + $INSTALL_CMD remove $CLEANUP_PROGRAMS 2>&1 |
| 201 | + error_message "Github returned a non-200 response code ($GITHUB_STATUS)" |
| 202 | + fi |
| 203 | + |
| 204 | + running_command "curl -L \"https://github.com/Pterodactyl/Daemon/archive/$DL_VERSION.tar.gz\" > daemon.tar.gz" |
| 205 | + curl -L "https://github.com/Pterodactyl/Daemon/archive/$DL_VERSION.tar.gz" > daemon.tar.gz |
| 206 | + |
| 207 | + running_command "tar --strip-components=1 -xzvf daemon.tar.gz" |
| 208 | + tar --strip-components=1 -xzvf daemon.tar.gz 2>&1 |
| 209 | + if [ "$?" -ne "0" ]; then |
| 210 | + $INSTALL_CMD remove $CLEANUP_PROGRAMS 2>&1 |
| 211 | + cd ~ && rm -rf $INSTALL_DIR 2>&1 |
| 212 | + error_message "Unable to install the daemon due to an error while attempting to unpack files." |
| 213 | + fi |
| 214 | +elif [ $USE_GIT ]; then |
| 215 | + CLEANUP_PROGRAMS="nodejs docker-engine git" |
| 216 | + running_command "$INSTALL_CMD install git" |
| 217 | + $INSTALL_CMD install git |
| 218 | + |
| 219 | + running_command "git clone https://github.com/Pterodactyl/Daemon.git ." |
| 220 | + git clone https://github.com/Pterodactyl/Daemon.git . |
| 221 | + if [ -z $USE_UNSTABLE ]; then |
| 222 | + running_command "git checkout tags/$DL_VERSION" |
| 223 | + git checkout tags/$DL_VERSION |
| 224 | + fi |
| 225 | + if [ "$?" -ne "0" ]; then |
| 226 | + $INSTALL_CMD remove $CLEANUP_PROGRAMS 2>&1 |
| 227 | + cd ~ && rm -rf $INSTALL_DIR 2>&1 |
| 228 | + error_message "Unable to install the daemon due to an error while attempting to clone files to the server." |
| 229 | + fi |
| 230 | +else |
| 231 | + error_message "Could not match an install method!" |
| 232 | +fi |
| 233 | + |
| 234 | +running_command "npm install --production" |
| 235 | +npm install --production |
| 236 | +if [ "$?" -ne "0" ]; then |
| 237 | + $INSTALL_CMD remove $CLEANUP_PROGRAMS 2>&1 |
| 238 | + cd ~ && rm -rf $INSTALL_DIR 2>&1 |
| 239 | + error_message "Unable to install the daemon due to an error that occured while running npm install." |
| 240 | +fi |
| 241 | + |
| 242 | +running_command "docker run -d --name ptdl-sftp -p 2022:22 -v $DATA_DIR:/sftp-root -v $INSTALL_DIR/config/credentials:/creds quay.io/pterodactyl/scrappy" |
| 243 | +docker run -d --name ptdl-sftp -p 2022:22 -v $DATA_DIR:/sftp-root -v $INSTALL_DIR/config/credentials:/creds quay.io/pterodactyl/scrappy |
| 244 | +if [ "$?" -ne "0" ]; then |
| 245 | + $INSTALL_CMD remove $CLEANUP_PROGRAMS 2>&1 |
| 246 | + cd ~ && rm -rf $INSTALL_DIR 2>&1 |
| 247 | + error_message "Unable to install the daemon due to an error while creating a SFTP container." |
| 248 | +fi |
| 249 | + |
| 250 | +echo '{ |
| 251 | + "web": { |
| 252 | + "listen": {{ $node->daemonListen }}, |
| 253 | + "ssl": { |
| 254 | + "enabled": {{ $node->sceheme === 'https' ? 'true' : 'false' }}, |
| 255 | + "certificate": "/etc/letsencrypt/live/{{ $node->fqdn }}/fullchain.pem", |
| 256 | + "key": "/etc/letsencrypt/live/{{ $node->fqdn }}/privkey.pem" |
| 257 | + } |
| 258 | + }, |
| 259 | + "docker": { |
| 260 | + "socket": "/var/run/docker.sock" |
| 261 | + }, |
| 262 | + "sftp": { |
| 263 | + "path": "{{ $node->daemonBase }}", |
| 264 | + "port": {{ $node->daemonSFTP }}, |
| 265 | + "container": "ptdl-sftp" |
| 266 | + }, |
| 267 | + "logger": { |
| 268 | + "path": "logs/", |
| 269 | + "src": false, |
| 270 | + "level": "info", |
| 271 | + "period": "1d", |
| 272 | + "count": 3 |
| 273 | + }, |
| 274 | + "remote": { |
| 275 | + "download": "{{ route('remote.download') }}", |
| 276 | + "installed": "{{ route('remote.install') }}" |
| 277 | + }, |
| 278 | + "uploads": { |
| 279 | + "maximumSize": 100000000 |
| 280 | + }, |
| 281 | + "keys": [ |
| 282 | + "{{ $node->daemonSecret }}" |
| 283 | + ] |
| 284 | +}' > config/core.json |
| 285 | +if [ "$?" -ne "0" ]; then |
| 286 | + $INSTALL_CMD remove $CLEANUP_PROGRAMS |
| 287 | + cd ~ && rm -rf $INSTALL_DIR 2>&1 |
| 288 | + error_message "An error occured while attempting to save the JSON file." |
| 289 | +fi |
| 290 | + |
| 291 | +success_message "Congratulations, the daemon is now installed." |
| 292 | +exit |
0 commit comments