| 1 | #!/bin/bash |
| 2 | |
| 3 | command=$1 |
| 4 | config=$2 |
| 5 | opt=$3 |
| 6 | |
| 7 | # Docker doesn't like uppercase characters, spaces or special characters, catch it now before we build everything out and then find out |
| 8 | re='[A-Z/ !@#$%^&*()+~`=]' |
| 9 | if [[ $config =~ $re ]]; |
| 10 | then |
| 11 | echo |
| 12 | echo "ERROR: Config name must not contain upper case characters, spaces or special characters. Correct config name and rerun $0." |
| 13 | echo |
| 14 | exit 1 |
| 15 | fi |
| 16 | |
| 17 | cd "$(dirname "$0")" |
| 18 | |
| 19 | docker_min_version='1.2.0' |
| 20 | docker_rec_version='1.2.0' |
| 21 | |
| 22 | config_file=containers/"$config".yml |
| 23 | cidbootstrap=cids/"$config"_bootstrap.cid |
| 24 | local_discourse=local_discourse |
| 25 | image=samsaffron/discourse:1.0.12 |
| 26 | docker_path=`which docker.io || which docker` |
| 27 | |
| 28 | if [ "${SUPERVISED}" = "true" ]; then |
| 29 | restart_policy="--restart=no" |
| 30 | attach_on_start="-a" |
| 31 | attach_on_run="-a stdout -a stderr" |
| 32 | else |
| 33 | attach_on_run="-d" |
| 34 | fi |
| 35 | |
| 36 | if [ -n "$DOCKER_HOST" ]; then |
| 37 | docker_ip=`sed -e 's/^tcp:\/\/\(.*\):.*$/\1/' <<< "$DOCKER_HOST"` |
| 38 | elif [ -x "$(which ip 2>/dev/null)" ]; then |
| 39 | docker_ip=`ip addr show docker0 | \ |
| 40 | grep 'inet ' | \ |
| 41 | awk '{ split($2,a,"/"); print a[1] }';` |
| 42 | else |
| 43 | docker_ip=`ifconfig | \ |
| 44 | grep -B1 "inet addr" | \ |
| 45 | awk '{ if ( $1 == "inet" ) { print $2 } else if ( $2 == "Link" ) { printf "%s:" ,$1 } }' | \ |
| 46 | grep docker0 | \ |
| 47 | awk -F: '{ print $3 }';` |
| 48 | fi |
| 49 | |
| 50 | |
| 51 | usage () { |
| 52 | echo "Usage: launcher COMMAND CONFIG [--skip-prereqs]" |
| 53 | echo "Commands:" |
| 54 | echo " start: Start/initialize a container" |
| 55 | echo " stop: Stop a running container" |
| 56 | echo " restart: Restart a container" |
| 57 | echo " destroy: Stop and remove a container" |
| 58 | echo " enter: Use nsenter to enter a container" |
| 59 | echo " ssh: Start a bash shell in a running container" |
| 60 | echo " logs: Docker logs for container" |
| 61 | echo " mailtest: Test the mail settings in a container" |
| 62 | echo " bootstrap: Bootstrap a container for the config based on a template" |
| 63 | echo " rebuild: Rebuild a container (destroy old, bootstrap, start new)" |
| 64 | echo " cleanup: Remove all containers that have stopped for > 24 hours" |
| 65 | echo |
| 66 | echo "Options:" |
| 67 | echo " --skip-prereqs Don't check prerequisites" |
| 68 | echo " --docker-args Extra arguments to pass when running docker" |
| 69 | exit 1 |
| 70 | } |
| 71 | |
| 72 | compare_version() { |
| 73 | declare -a ver_a |
| 74 | declare -a ver_b |
| 75 | IFS=. read -a ver_a <<< "$1" |
| 76 | IFS=. read -a ver_b <<< "$2" |
| 77 | |
| 78 | while [[ -n $ver_a ]]; do |
| 79 | if (( ver_a > ver_b )); then |
| 80 | return 0 |
| 81 | elif (( ver_b > ver_a )); then |
| 82 | return 1 |
| 83 | else |
| 84 | unset ver_a[0] |
| 85 | ver_a=("${ver_a[@]}") |
| 86 | unset ver_b[0] |
| 87 | ver_b=("${ver_b[@]}") |
| 88 | fi |
| 89 | done |
| 90 | return 1 # They are equal |
| 91 | } |
| 92 | |
| 93 | prereqs() { |
| 94 | |
| 95 | # 1. docker daemon running? |
| 96 | # we send stderr to /dev/null cause we don't care about warnings, |
| 97 | # it usually complains about swap which does not matter |
| 98 | test=`$docker_path info 2> /dev/null` |
| 99 | |
| 100 | if [[ $? -ne 0 ]] ; then |
| 101 | echo "Cannot connect to the docker daemon - verify it is running and you have access" |
| 102 | exit 1 |
| 103 | fi |
| 104 | |
| 105 | # 2. running aufs or btrfs |
| 106 | test=`$docker_path info 2> /dev/null | grep 'Driver: '` |
| 107 | if [[ "$test" =~ [aufs|btrfs|zfs|overlay] ]] ; then : ; else |
| 108 | echo "Your Docker installation is not using a supported filesystem if we were to proceed you may have a broken install." |
| 109 | echo "aufs is the recommended filesystem you should be using (zfs/btrfs and overlay may work as well)" |
| 110 | echo "You can tell what filesystem you are using by running \"docker info\" and looking at the driver" |
| 111 | echo "" |
| 112 | echo "If you wish to continue anyway using your existing unsupported filesystem" |
| 113 | echo "read the source code of launcher and figure out how to bypass this." |
| 114 | exit 1 |
| 115 | fi |
| 116 | |
| 117 | # 3. running recommended docker version |
| 118 | test=($($docker_path --version)) # Get docker version string |
| 119 | test=${test[2]//,/} # Get version alone and strip comma if exists |
| 120 | |
| 121 | [[ "$test" =~ "0.12.0" ]] && echo "You are running a broken version of Docker, please upgrade ASAP. See: https://meta.discourse.org/t/the-installation-stopped-in-the-middle/16311/ for more details." && exit 1 |
| 122 | |
| 123 | # At least minimum version |
| 124 | if compare_version "${docker_min_version}" "${test}"; then |
| 125 | echo "ERROR: Docker version ${test} not supported, please upgrade to at least ${docker_min_version}, or recommended ${docker_rec_version}" |
| 126 | exit 1 |
| 127 | fi |
| 128 | |
| 129 | # Recommend best version |
| 130 | if compare_version "${docker_rec_version}" "${test}"; then |
| 131 | echo "WARNING: Docker version ${test} deprecated, recommend upgrade to ${docker_rec_version} or newer." |
| 132 | fi |
| 133 | |
| 134 | # 4. discourse docker image is downloaded |
| 135 | test=`$docker_path images | awk '{print $1 ":" $2 }' | grep "$image"` |
| 136 | |
| 137 | if [ -z "$test" ]; then |
| 138 | echo |
| 139 | echo "WARNING: We are about to start downloading the Discourse base image" |
| 140 | echo "This process may take anywhere between a few minutes to an hour, depending on your network speed" |
| 141 | echo |
| 142 | echo "Please be patient" |
| 143 | echo |
| 144 | |
| 145 | fi |
| 146 | |
| 147 | # 5. able to attach stderr / out / tty |
| 148 | test=`$docker_path run $user_args -i --rm -a stdout -a stderr $image echo working` |
| 149 | if [[ "$test" =~ "working" ]] ; then : ; else |
| 150 | echo "Your Docker installation is not working correctly" |
| 151 | echo |
| 152 | echo "See: https://meta.discourse.org/t/docker-error-on-bootstrap/13657/18?u=sam" |
| 153 | exit 1 |
| 154 | fi |
| 155 | } |
| 156 | |
| 157 | if [ "$opt" != "--skip-prereqs" ] ; then |
| 158 | prereqs |
| 159 | fi |
| 160 | |
| 161 | if [ "$opt" == "--docker-args" ] ; then |
| 162 | user_args=$4 |
| 163 | else |
| 164 | user_args="" |
| 165 | fi |
| 166 | |
| 167 | get_ssh_pub_key() { |
| 168 | local ${ssh_key_locations} |
| 169 | ssh_key_locations=( |
| 170 | ~/.ssh/id_ed25519.pub |
| 171 | ~/.ssh/id_ecdsa.pub |
| 172 | ~/.ssh/id_rsa.pub |
| 173 | ~/.ssh/id_dsa.pub |
| 174 | ~core/.ssh/authorized_keys |
| 175 | ) |
| 176 | |
| 177 | local $keyfile |
| 178 | for keyfile in "${ssh_key_locations[@]}"; do |
| 179 | if [[ -e ${keyfile} ]] ; then |
| 180 | ssh_pub_key="$(cat ${keyfile})" |
| 181 | return 0 |
| 182 | fi |
| 183 | done |
| 184 | |
| 185 | return 0 |
| 186 | } |
| 187 | |
| 188 | |
| 189 | install_docker() { |
| 190 | |
| 191 | echo "Docker is not installed, make sure you are running on the 3.8 kernel" |
| 192 | echo "The best supported Docker release is Ubuntu 12.04.03 for it run the following" |
| 193 | echo |
| 194 | echo "sudo apt-get update" |
| 195 | echo "sudo apt-get install linux-image-generic-lts-raring linux-headers-generic-lts-raring" |
| 196 | echo "sudo reboot" |
| 197 | echo |
| 198 | |
| 199 | echo "sudo sh -c \"wget -qO- https://get.docker.io/gpg | apt-key add -\"" |
| 200 | echo "sudo sh -c \"echo deb http://get.docker.io/ubuntu docker main > /etc/apt/sources.list.d/docker.list\"" |
| 201 | echo "sudo apt-get update" |
| 202 | echo "sudo apt-get install lxc-docker" |
| 203 | |
| 204 | exit 1 |
| 205 | } |
| 206 | |
| 207 | host_run() { |
| 208 | read -r -d '' env_ruby << 'RUBY' |
| 209 | require 'yaml' |
| 210 | |
| 211 | input = STDIN.readlines.join |
| 212 | yaml = YAML.load(input) |
| 213 | |
| 214 | if host_run = yaml['host_run'] |
| 215 | params = yaml['params'] || {} |
| 216 | host_run.each do |run| |
| 217 | params.each do |k,v| |
| 218 | run = run.gsub("$#{k}", v) |
| 219 | end |
| 220 | STDOUT.write "#{run}--SEP--" |
| 221 | end |
| 222 | end |
| 223 | RUBY |
| 224 | |
| 225 | host_run=`cat $config_file | $docker_path run $user_args --rm -i -a stdout -a stdin $image ruby -e "$env_ruby"` |
| 226 | |
| 227 | while [ "$host_run" ] ; do |
| 228 | iter=${host_run%%--SEP--*} |
| 229 | echo |
| 230 | echo "Host run: $iter" |
| 231 | $iter || exit 1 |
| 232 | echo |
| 233 | host_run="${host_run#*--SEP--}" |
| 234 | done |
| 235 | } |
| 236 | |
| 237 | |
| 238 | set_volumes() { |
| 239 | volumes=`cat $config_file | $docker_path run $user_args --rm -i -a stdout -a stdin $image ruby -e \ |
| 240 | "require 'yaml'; puts YAML.load(STDIN.readlines.join)['volumes'].map{|v| '-v ' << v['volume']['host'] << ':' << v['volume']['guest'] << ' '}.join"` |
| 241 | } |
| 242 | |
| 243 | set_links() { |
| 244 | links=`cat $config_file | $docker_path run $user_args --rm -i -a stdout -a stdin $image ruby -e \ |
| 245 | "require 'yaml'; puts YAML.load(STDIN.readlines.join)['links'].map{|l| '--link ' << l['link']['name'] << ':' << l['link']['alias'] << ' '}.join"` |
| 246 | } |
| 247 | |
| 248 | set_template_info() { |
| 249 | |
| 250 | templates=`cat $config_file | $docker_path run $user_args --rm -i -a stdin -a stdout $image ruby -e \ |
| 251 | "require 'yaml'; puts YAML.load(STDIN.readlines.join)['templates']"` |
| 252 | |
| 253 | |
| 254 | arrTemplates=(${templates// / }) |
| 255 | config_data=$(cat $config_file) |
| 256 | |
| 257 | input="hack: true" |
| 258 | |
| 259 | |
| 260 | for template in "${arrTemplates[@]}" |
| 261 | do |
| 262 | [ ! -z $template ] && { |
| 263 | input="$input _FILE_SEPERATOR_ $(cat $template)" |
| 264 | } |
| 265 | done |
| 266 | |
| 267 | # we always want our config file last so it takes priority |
| 268 | input="$input _FILE_SEPERATOR_ $config_data" |
| 269 | |
| 270 | read -r -d '' env_ruby << 'RUBY' |
| 271 | require 'yaml' |
| 272 | |
| 273 | input=STDIN.readlines.join |
| 274 | # default to UTF-8 for the dbs sake |
| 275 | env = {'LANG' => 'en_US.UTF-8'} |
| 276 | input.split('_FILE_SEPERATOR_').each do |yml| |
| 277 | yml.strip! |
| 278 | begin |
| 279 | env.merge!(YAML.load(yml)['env'] || {}) |
| 280 | rescue Psych::SyntaxError => e |
| 281 | puts e |
| 282 | puts "*ERROR." |
| 283 | rescue => e |
| 284 | puts yml |
| 285 | p e |
| 286 | end |
| 287 | end |
| 288 | puts env.map{|k,v| "-e\n#{k}=#{v}" }.join("\n") |
| 289 | RUBY |
| 290 | |
| 291 | raw=`exec echo "$input" | $docker_path run $user_args --rm -i -a stdin -a stdout $image ruby -e "$env_ruby"` |
| 292 | |
| 293 | env=() |
| 294 | ok=1 |
| 295 | while read i; do |
| 296 | if [ "$i" == "*ERROR." ]; then |
| 297 | ok=0 |
| 298 | elif [ -n "$i" ]; then |
| 299 | env[${#env[@]}]=$i |
| 300 | fi |
| 301 | done <<< "$raw" |
| 302 | |
| 303 | if [ "$ok" -ne 1 ]; then |
| 304 | echo "${env[@]}" |
| 305 | echo "YAML syntax error. Please check your /var/discourse/containers/*.yml config files." |
| 306 | exit 1 |
| 307 | fi |
| 308 | } |
| 309 | |
| 310 | [ -z $docker_path ] && { |
| 311 | install_docker |
| 312 | } |
| 313 | |
| 314 | [ $command == "cleanup" ] && { |
| 315 | echo |
| 316 | echo "The following command will" |
| 317 | echo "- Delete all docker images for old containers" |
| 318 | echo "- Delete all stopped and orphan containers" |
| 319 | echo |
| 320 | read -p "Are you sure (Y/n): " -n 1 -r && echo |
| 321 | if [[ $REPLY =~ ^[Yy]$ || ! $REPLY ]] |
| 322 | then |
| 323 | space=$(df /var/lib/docker | awk '{ print $4 }' | grep -v Available) |
| 324 | |
| 325 | echo "Starting Cleanup" |
| 326 | |
| 327 | if [[ ! -z `docker ps -aq` ]]; then |
| 328 | docker inspect -f '{{.Id}},{{.State.Running}},{{.State.FinishedAt}}' $(docker ps -qa) | \ |
| 329 | awk -F, 'BEGIN { TIME=strftime("%FT%T.000000000Z",systime()-60*60*24); } $2=="false" && $3 < TIME {print $1;}' | \ |
| 330 | xargs --no-run-if-empty docker rm >/dev/null 2>/dev/null |
| 331 | fi |
| 332 | |
| 333 | docker rmi `docker images -a | grep '<none>' | awk '{print $3}'` 2> /dev/null |
| 334 | |
| 335 | let freed=$space-$(df /var/lib/docker | awk '{ print $4 }' | grep -v Available) |
| 336 | |
| 337 | echo $space |
| 338 | echo $(df /var/lib/docker | awk '{ print $4 }' | grep -v Available) |
| 339 | |
| 340 | |
| 341 | output="$freed" | awk '{sum=$1;hum[1024**3]="GB"; hum[1024**2]="MB"; hum[1024]="KB"; for (x=1024**3;x>=1024; x/=1024){ if (sum>=x) { printf "%.2f %s\n",sum/x,hum[x];break }}}' |
| 342 | [ -z "$output" ] && { |
| 343 | [[ $freed > 0 ]] && { echo "./launcher cleanup cleared up $freed of disk space."; } || { echo "./launcher cleanup has finished, no files were removed."; } |
| 344 | } || { echo "./launcher cleanup cleared up $freed of disk space."; } |
| 345 | else |
| 346 | exit 1 |
| 347 | fi |
| 348 | exit 0 |
| 349 | } |
| 350 | |
| 351 | [ $# -lt 2 ] && { |
| 352 | usage |
| 353 | } |
| 354 | |
| 355 | if [ ! -e $config_file ] |
| 356 | then |
| 357 | echo "Config file was not found, ensure $config_file exists" |
| 358 | echo "" |
| 359 | echo "Available configs ( `cd containers && ls -dm *.yml | tr -s '\n' ' ' | awk '{ gsub(/\.yml/, ""); print }'`)" |
| 360 | exit 1 |
| 361 | fi |
| 362 | |
| 363 | |
| 364 | docker_version=($($docker_path --version)) |
| 365 | docker_version=${test[2]//,/} |
| 366 | |
| 367 | if compare_version "1.2.0" "$docker_version"; then |
| 368 | echo "We recommend you upgrade docker, the version you are running has no restart policies, on reboot your container may not start up" |
| 369 | restart_policy="" |
| 370 | else |
| 371 | restart_policy=${restart_policy:---restart=always} |
| 372 | fi |
| 373 | |
| 374 | |
| 375 | run_mailtest(){ |
| 376 | if [ ! -e $config_file ]; then |
| 377 | echo "Config does not exist: $config_file" >&2 |
| 378 | exit 1 |
| 379 | fi |
| 380 | exec scripts/mailtest $config_file |
| 381 | } |
| 382 | |
| 383 | set_existing_container(){ |
| 384 | existing=`$docker_path ps -a | awk '{ print $1, $(NF) }' | grep " $config$" | awk '{ print $1 }'` |
| 385 | } |
| 386 | |
| 387 | run_stop(){ |
| 388 | |
| 389 | set_existing_container |
| 390 | |
| 391 | if [ ! -z $existing ] |
| 392 | then |
| 393 | ( |
| 394 | set -x |
| 395 | $docker_path stop -t 10 $config |
| 396 | ) |
| 397 | else |
| 398 | echo "$config was not started !" |
| 399 | exit 1 |
| 400 | fi |
| 401 | } |
| 402 | |
| 403 | run_start(){ |
| 404 | |
| 405 | existing=`$docker_path ps | awk '{ print $1, $(NF) }' | grep " $config$" | awk '{ print $1 }'` |
| 406 | echo $existing |
| 407 | if [ ! -z $existing ] |
| 408 | then |
| 409 | echo "Nothing to do, your container has already started!" |
| 410 | exit 1 |
| 411 | fi |
| 412 | |
| 413 | existing=`$docker_path ps -a | awk '{ print $1, $(NF) }' | grep " $config$" | awk '{ print $1 }'` |
| 414 | if [ ! -z $existing ] |
| 415 | then |
| 416 | echo "starting up existing container" |
| 417 | ( |
| 418 | set -x |
| 419 | $docker_path start $config |
| 420 | ) |
| 421 | exit 0 |
| 422 | fi |
| 423 | |
| 424 | host_run |
| 425 | ports=`cat $config_file | $docker_path run $user_args --rm -i -a stdout -a stdin $image ruby -e \ |
| 426 | "require 'yaml'; puts YAML.load(STDIN.readlines.join)['expose'].map{|p| '-p ' << p.to_s << ' '}.join"` |
| 427 | |
| 428 | set_template_info |
| 429 | set_volumes |
| 430 | set_links |
| 431 | |
| 432 | ( |
| 433 | hostname=`hostname` |
| 434 | set -x |
| 435 | $docker_path run $user_args $links $attach_on_run $restart_policy "${env[@]}" -h "$hostname-$config" \ |
| 436 | -e DOCKER_HOST_IP=$docker_ip --name $config -t $ports $volumes $local_discourse/$config /sbin/boot |
| 437 | |
| 438 | ) |
| 439 | exit 0 |
| 440 | |
| 441 | } |
| 442 | |
| 443 | run_bootstrap(){ |
| 444 | |
| 445 | host_run |
| 446 | |
| 447 | get_ssh_pub_key |
| 448 | |
| 449 | # Is the image available? |
| 450 | # If not, pull it here so the user is aware what's happening. |
| 451 | $docker_path history $image >/dev/null 2>&1 || $docker_path pull $image |
| 452 | |
| 453 | set_template_info |
| 454 | |
| 455 | base_image=`cat $config_file | $docker_path run $user_args --rm -i -a stdin -a stdout $image ruby -e \ |
| 456 | "require 'yaml'; puts YAML.load(STDIN.readlines.join)['base_image']"` |
| 457 | |
| 458 | update_pups=`cat $config_file | $docker_path run $user_args --rm -i -a stdin -a stdout $image ruby -e \ |
| 459 | "require 'yaml'; puts YAML.load(STDIN.readlines.join)['update_pups']"` |
| 460 | |
| 461 | if [[ ! X"" = X"$base_image" ]]; then |
| 462 | image=$base_image |
| 463 | fi |
| 464 | |
| 465 | set_volumes |
| 466 | set_links |
| 467 | |
| 468 | rm -f $cidbootstrap |
| 469 | |
| 470 | run_command="cd /pups &&" |
| 471 | if [[ ! "false" = $update_pups ]]; then |
| 472 | run_command="$run_command git pull &&" |
| 473 | fi |
| 474 | run_command="$run_command /pups/bin/pups --stdin" |
| 475 | |
| 476 | echo $run_command |
| 477 | |
| 478 | env=("${env[@]}" "-e" "SSH_PUB_KEY=$ssh_pub_key") |
| 479 | |
| 480 | (exec echo "$input" | $docker_path run $user_args $links "${env[@]}" -e DOCKER_HOST_IP=$docker_ip --cidfile $cidbootstrap -i -a stdin -a stdout -a stderr $volumes $image \ |
| 481 | /bin/bash -c "$run_command") \ |
| 482 | || ($docker_path rm `cat $cidbootstrap` && rm $cidbootstrap) |
| 483 | |
| 484 | [ ! -e $cidbootstrap ] && echo "** FAILED TO BOOTSTRAP ** please scroll up and look for earlier error messages, there may be more than one" && exit 1 |
| 485 | |
| 486 | sleep 5 |
| 487 | |
| 488 | $docker_path commit `cat $cidbootstrap` $local_discourse/$config || echo 'FAILED TO COMMIT' |
| 489 | $docker_path rm `cat $cidbootstrap` && rm $cidbootstrap |
| 490 | } |
| 491 | |
| 492 | case "$command" in |
| 493 | bootstrap) |
| 494 | run_bootstrap |
| 495 | echo "Successfully bootstrapped, to startup use ./launcher start $config" |
| 496 | exit 0 |
| 497 | ;; |
| 498 | |
| 499 | mailtest) |
| 500 | run_mailtest |
| 501 | exit 0 |
| 502 | ;; |
| 503 | |
| 504 | enter) |
| 505 | exec $docker_path exec -it $config /bin/bash |
| 506 | ;; |
| 507 | |
| 508 | ssh) |
| 509 | existing=`$docker_path ps | awk '{ print $1, $(NF) }' | grep " $config$" | awk '{ print $1 }'` |
| 510 | |
| 511 | if [[ ! -z $existing ]]; then |
| 512 | address="`$docker_path port $config 22`" |
| 513 | split=(${address//:/ }) |
| 514 | exec ssh -o StrictHostKeyChecking=no root@${split[0]} -p ${split[1]} |
| 515 | else |
| 516 | echo "$config is not running!" |
| 517 | exit 1 |
| 518 | fi |
| 519 | ;; |
| 520 | |
| 521 | stop) |
| 522 | run_stop |
| 523 | exit 0 |
| 524 | ;; |
| 525 | |
| 526 | logs) |
| 527 | |
| 528 | $docker_path logs $config |
| 529 | exit 0 |
| 530 | ;; |
| 531 | |
| 532 | restart) |
| 533 | run_stop |
| 534 | run_start |
| 535 | exit 0 |
| 536 | ;; |
| 537 | |
| 538 | start) |
| 539 | run_start |
| 540 | exit 0 |
| 541 | ;; |
| 542 | |
| 543 | rebuild) |
| 544 | if [ "$(git symbolic-ref --short HEAD)" == "master" ]; then |
| 545 | echo "Ensuring discourse docker is up to date" |
| 546 | |
| 547 | git remote update |
| 548 | |
| 549 | LOCAL=$(git rev-parse @) |
| 550 | REMOTE=$(git rev-parse @{u}) |
| 551 | BASE=$(git merge-base @ @{u}) |
| 552 | |
| 553 | if [ $LOCAL = $REMOTE ]; then |
| 554 | echo "Discourse Docker is up-to-date" |
| 555 | |
| 556 | elif [ $LOCAL = $BASE ]; then |
| 557 | echo "Updating Discourse Docker" |
| 558 | git pull || (echo 'failed to update' && exit 1) |
| 559 | exec /bin/bash $0 $@ |
| 560 | |
| 561 | elif [ $REMOTE = $BASE ]; then |
| 562 | echo "Your version of Discourse Docker is ahead of origin" |
| 563 | |
| 564 | else |
| 565 | echo "Discourse Docker has diverged source, this is only expected in Dev mode" |
| 566 | fi |
| 567 | |
| 568 | fi |
| 569 | |
| 570 | set_existing_container |
| 571 | |
| 572 | if [ ! -z $existing ] |
| 573 | then |
| 574 | echo "Stopping old container" |
| 575 | ( |
| 576 | set -x |
| 577 | $docker_path stop -t 10 $config |
| 578 | ) |
| 579 | fi |
| 580 | |
| 581 | run_bootstrap |
| 582 | |
| 583 | if [ ! -z $existing ] |
| 584 | then |
| 585 | echo "Removing old container" |
| 586 | ( |
| 587 | set -x |
| 588 | $docker_path rm $config |
| 589 | ) |
| 590 | fi |
| 591 | |
| 592 | run_start |
| 593 | exit 0 |
| 594 | ;; |
| 595 | |
| 596 | |
| 597 | destroy) |
| 598 | (set -x; $docker_path stop -t 10 $config && $docker_path rm $config) || (echo "$config was not found" && exit 0) |
| 599 | exit 0 |
| 600 | ;; |
| 601 | esac |
| 602 | |
| 603 | usage |