#!/bin/bash
+usage () {
+ echo "Usage: launcher COMMAND CONFIG [--skip-prereqs] [--docker-args STRING]"
+ echo "Commands:"
+ echo " start: Start/initialize a container"
+ echo " stop: Stop a running container"
+ echo " restart: Restart a container"
+ echo " destroy: Stop and remove a container"
+ echo " enter: Open a shell to run commands inside the container"
+ echo " logs: View the Docker logs for a container"
+ echo " bootstrap: Bootstrap a container for the config based on a template"
+ echo " run: Run the given command with the config in the context of the last bootstrapped image"
+ echo " rebuild: Rebuild a container (destroy old, bootstrap, start new)"
+ echo " cleanup: Remove all containers that have stopped for > 24 hours"
+ echo " start-cmd: Generate docker command used to start container"
+ echo
+ echo "Options:"
+ echo " --skip-prereqs Don't check launcher prerequisites"
+ echo " --docker-args Extra arguments to pass when running docker"
+ echo " --skip-mac-address Don't assign a mac address"
+ echo " --run-image Override the image used for running the container"
+ exit 1
+}
+
command=$1
config=$2
-opt=$3
+user_args=""
+user_run_image=""
+
+if [[ $command == "run" ]]; then
+ run_command=$3
+fi
+
+while [ ${#} -gt 0 ]; do
+ case "${1}" in
+ --debug)
+ DEBUG="1"
+ ;;
+ --skip-prereqs)
+ SKIP_PREREQS="1"
+ ;;
+ --skip-mac-address)
+ SKIP_MAC_ADDRESS="1"
+ ;;
+ --docker-args)
+ user_args="$2"
+ shift
+ ;;
+ --run-image)
+ user_run_image="$2"
+ shift
+ ;;
+ esac
+
+ shift 1
+done
+
+if [ -z "$command" -o -z "$config" -a "$command" != "cleanup" ]; then
+ usage
+ exit 1
+fi
# Docker doesn't like uppercase characters, spaces or special characters, catch it now before we build everything out and then find out
-re='[A-Z/ !@#$%^&*()+~`=]'
+re='[[:upper:]/ !@#$%^&*()+~`=]'
if [[ $config =~ $re ]];
then
echo
- echo "ERROR: Config name must not contain upper case characters, spaces or special characters. Correct config name and rerun $0."
+ echo "ERROR: Config name '$config' must not contain upper case characters, spaces or special characters. Correct config name and rerun $0."
echo
exit 1
fi
cd "$(dirname "$0")"
-docker_min_version='1.6.0'
-docker_rec_version='1.6.0'
+docker_min_version='17.03.1'
+docker_rec_version='17.06.2'
+git_min_version='1.8.0'
+git_rec_version='1.8.0'
config_file=containers/"$config".yml
cidbootstrap=cids/"$config"_bootstrap.cid
local_discourse=local_discourse
-image=discourse/discourse:1.0.17
-docker_path=`which docker.io || which docker`
-template_path=samples/standalone.yml
-changelog=/tmp/changelog # used to test whether sed did anything
+image="discourse/base:2.0.20190321-0122"
+docker_path=`which docker.io 2> /dev/null || which docker`
+git_path=`which git`
if [ "${SUPERVISED}" = "true" ]; then
restart_policy="--restart=no"
awk -F: '{ print $3 }';`
fi
-
-usage () {
- echo "Usage: launcher COMMAND CONFIG [--skip-prereqs]"
- echo "Commands:"
- echo " start: Start/initialize a container"
- echo " stop: Stop a running container"
- echo " restart: Restart a container"
- echo " destroy: Stop and remove a container"
- echo " enter: Use nsenter to enter a container"
- echo " ssh: Start a bash shell in a running container"
- echo " logs: Docker logs for container"
- echo " bootstrap: Bootstrap a container for the config based on a template"
- echo " rebuild: Rebuild a container (destroy old, bootstrap, start new)"
- echo " memconfig: Configure defaults based on available RAM"
- echo " cleanup: Remove all containers that have stopped for > 24 hours"
- echo
- echo "Options:"
- echo " --skip-prereqs Don't check prerequisites or resource requirements"
- echo " --docker-args Extra arguments to pass when running docker"
- exit 1
-}
-
+# From https://stackoverflow.com/a/44660519/702738
compare_version() {
- declare -a ver_a
- declare -a ver_b
- IFS=. read -a ver_a <<< "$1"
- IFS=. read -a ver_b <<< "$2"
-
- while [[ -n $ver_a ]]; do
- if (( ver_a > ver_b )); then
- return 0
- elif (( ver_b > ver_a )); then
+ if [[ $1 == $2 ]]; then
+ return 1
+ fi
+ local IFS=.
+ local i a=(${1%%[^0-9.]*}) b=(${2%%[^0-9.]*})
+ local arem=${1#${1%%[^0-9.]*}} brem=${2#${2%%[^0-9.]*}}
+ for ((i=0; i<${#a[@]} || i<${#b[@]}; i++)); do
+ if ((10#${a[i]:-0} < 10#${b[i]:-0})); then
return 1
- else
- unset ver_a[0]
- ver_a=("${ver_a[@]}")
- unset ver_b[0]
- ver_b=("${ver_b[@]}")
+ elif ((10#${a[i]:-0} > 10#${b[i]:-0})); then
+ return 0
fi
done
- return 1 # They are equal
+ if [ "$arem" '<' "$brem" ]; then
+ return 1
+ elif [ "$arem" '>' "$brem" ]; then
+ return 0
+ fi
+ return 1
+}
+
+
+install_docker() {
+ echo "Docker is not installed, you will need to install Docker in order to run Launcher"
+ echo "See https://docs.docker.com/installation/"
+ exit 1
}
-prereqs() {
+check_prereqs() {
+
+ if [ -z $docker_path ]; then
+ install_docker
+ fi
# 1. docker daemon running?
# we send stderr to /dev/null cause we don't care about warnings,
# it usually complains about swap which does not matter
test=`$docker_path info 2> /dev/null`
-
if [[ $? -ne 0 ]] ; then
echo "Cannot connect to the docker daemon - verify it is running and you have access"
exit 1
fi
- # 2. running aufs or btrfs
- test=`$docker_path info 2> /dev/null | grep 'Driver: '`
- if [[ "$test" =~ [aufs|btrfs|zfs|overlay] ]] ; then : ; else
- echo "Your Docker installation is not using a supported filesystem if we were to proceed you may have a broken install."
- echo "aufs is the recommended filesystem you should be using (zfs/btrfs and overlay may work as well)"
- echo "You can tell what filesystem you are using by running \"docker info\" and looking at the driver"
- echo ""
- echo "If you wish to continue anyway using your existing unsupported filesystem"
- echo "read the source code of launcher and figure out how to bypass this."
+ # 2. running an approved storage driver?
+ if ! $docker_path info 2> /dev/null | egrep -q '^Storage Driver: (aufs|btrfs|zfs|overlay|overlay2)$'; then
+ echo "Your Docker installation is not using a supported storage driver. If we were to proceed you may have a broken install."
+ echo "aufs is the recommended storage driver, although zfs/btrfs/overlay and overlay2 may work as well."
+ echo "Other storage drivers are known to be problematic."
+ echo "You can tell what filesystem you are using by running \"docker info\" and looking at the 'Storage Driver' line."
+ echo
+ echo "If you wish to continue anyway using your existing unsupported storage driver,"
+ echo "read the source code of launcher and figure out how to bypass this check."
exit 1
fi
test=($($docker_path --version)) # Get docker version string
test=${test[2]//,/} # Get version alone and strip comma if exists
- [[ "$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
-
- # At least minimum version
+ # At least minimum docker version
if compare_version "${docker_min_version}" "${test}"; then
echo "ERROR: Docker version ${test} not supported, please upgrade to at least ${docker_min_version}, or recommended ${docker_rec_version}"
exit 1
fi
- # Recommend best version
+ # Recommend newer docker version
if compare_version "${docker_rec_version}" "${test}"; then
echo "WARNING: Docker version ${test} deprecated, recommend upgrade to ${docker_rec_version} or newer."
fi
echo
echo "Please be patient"
echo
+ fi
+
+ # 5. running recommended git version
+ test=($($git_path --version)) # Get git version string
+ test=${test[2]//,/} # Get version alone and strip comma if exists
+
+ # At least minimum version
+ if compare_version "${git_min_version}" "${test}"; then
+ echo "ERROR: Git version ${test} not supported, please upgrade to at least ${git_min_version}, or recommended ${git_rec_version}"
+ exit 1
+ fi
+ # Recommend best version
+ if compare_version "${git_rec_version}" "${test}"; then
+ echo "WARNING: Git version ${test} deprecated, recommend upgrade to ${git_rec_version} or newer."
fi
- # 5. able to attach stderr / out / tty
+ # 6. able to attach stderr / out / tty
test=`$docker_path run $user_args -i --rm -a stdout -a stderr $image echo working`
if [[ "$test" =~ "working" ]] ; then : ; else
echo "Your Docker installation is not working correctly"
exit 1
fi
-}
-
-check_resources() {
- # Memory
- resources="ok"
- avail_mem="$(LANG=C free -m | grep '^Mem:' | awk '{print $2}')"
- if [ "$avail_mem" -lt 900 ]; then
- resources="insufficient"
- echo "WARNING: You do not appear to have sufficient memory to run Discourse."
+ # 7. enough space for the bootstrap on docker folder
+ folder=`$docker_path info --format '{{.DockerRootDir}}'`
+ safe_folder=${folder:-/var/lib/docker}
+ test=$(($(stat -f --format="%a*%S" $safe_folder)/1024**3 < 5))
+ if [[ $test -ne 0 ]] ; then
+ echo "You have less than 5GB of free space on the disk where $safe_folder is located. You will need more space to continue"
+ df -h $safe_folder
echo
- echo "Your system may not work properly, or future upgrades of Discourse may"
- echo "not complete successfully."
+ read -p "Would you like to attempt to recover space by cleaning docker images and containers in the system?(y/N)" -n 1 -r
echo
- echo "See https://github.com/discourse/discourse/blob/master/docs/INSTALL-cloud.md#create-new-cloud-server"
- elif [ "$avail_mem" -lt 1800 ]; then
- total_swap="$(LANG=C free -m | grep ^Swap: | awk '{print $2}')"
- if [ "$total_swap" -lt 1000 ]; then
- resources="insufficient"
- echo "WARNING: You must have at least 1GB of swap when running with less"
- echo "than 2GB of RAM."
- echo
- echo "Your system may not work properly, or future upgrades of Discourse may"
- echo "not complete successfully."
- echo
- echo "See https://github.com/discourse/discourse/blob/master/docs/INSTALL-cloud.md#set-up-swap-if-needed"
+ if [[ $REPLY =~ ^[Yy]$ ]]
+ then
+ $docker_path system prune -af
+ echo "If the cleanup was successful, you may try again now"
fi
- fi
-
- # Disk space
- free_disk="$(df /var | tail -n 1 | awk '{print $4}')"
- if [ "$free_disk" -lt 5000 ]; then
- resources="insufficient"
- echo "WARNING: You must have at least 5GB of *free* disk space to run Discourse."
- echo
- echo "Insufficient disk space may result in problems running your site, and may"
- echo "not even allow Discourse installation to complete successfully."
- echo
- echo "Please free up some space, or expand your disk, before continuing."
exit 1
fi
-
- if [ -t 0 ] && [ "$resources" != "ok" ]; then
- echo
- read -p "Press ENTER to continue, or Ctrl-C to exit and give your system more resources"
- fi
}
-check_ports() {
- local valid=$(netstat -tln | awk '{print $4}' | grep ":${1}\$")
- if [ -n "$valid" ]; then
- echo "Launcher has detected that port ${1} is in use."
- echo ""
- echo "If you are trying to run Discourse simultaneously with another web server like Apache or nginx, you will need to bind to a different port."
- echo "See https://meta.discourse.org/t/17247 for help."
- echo "To continue anyway, re-run Launcher with --skip-prereqs"
- exit 1
- fi
-}
-
-if [ "$opt" != "--skip-prereqs" ] ; then
- prereqs
-fi
-
-if [ "$opt" == "--docker-args" ] ; then
- user_args=$4
-else
- user_args=""
+if [ -z "$SKIP_PREREQS" ] && [ "$command" != "cleanup" ]; then
+ check_prereqs
fi
-get_ssh_pub_key() {
- local ${ssh_key_locations}
- ssh_key_locations=(
- ~/.ssh/id_ed25519.pub
- ~/.ssh/id_ecdsa.pub
- ~/.ssh/id_rsa.pub
- ~/.ssh/id_dsa.pub
- ~core/.ssh/authorized_keys
- )
-
- local $keyfile
- for keyfile in "${ssh_key_locations[@]}"; do
- if [[ -e ${keyfile} ]] ; then
- ssh_pub_key="$(cat ${keyfile})"
- return 0
- fi
- done
-
- return 0
-}
-
-
-install_docker() {
-
- echo "Docker is not installed, you will need to install Docker in order to run Discourse"
- echo "Please visit https://docs.docker.com/installation/ for instructions on how to do this for your system"
- echo
- echo "If you are running Ubuntu Trusty or later, you can try the following:"
- echo
-
- echo "sudo apt-key adv --keyserver hkp://p80.pool.sks-keyservers.net:80 --recv-keys 58118E89F3A912897C070ADBF76221572C52609D"
- echo "sudo sh -c \"echo deb https://apt.dockerproject.org/repo ubuntu-$(lsb_release -sc) main > /etc/apt/sources.list.d/docker.list\""
- echo "sudo apt-get update"
- echo "sudo apt-get install docker-engine"
-
- exit 1
-}
-
host_run() {
read -r -d '' env_ruby << 'RUBY'
require 'yaml'
"require 'yaml'; puts YAML.load(STDIN.readlines.join)['links'].map{|l| '--link ' << l['link']['name'] << ':' << l['link']['alias'] << ' '}.join"`
}
-set_template_info() {
-
- templates=`cat $config_file | $docker_path run $user_args --rm -i -a stdin -a stdout $image ruby -e \
+find_templates() {
+ local templates=`cat $1 | $docker_path run $user_args --rm -i -a stdin -a stdout $image ruby -e \
"require 'yaml'; puts YAML.load(STDIN.readlines.join)['templates']"`
+ local arrTemplates=${templates// / }
+
+ if [ ! -z "$templates" ]; then
+ for template in "${arrTemplates[@]}"
+ do
+ local nested_templates=$(find_templates $template)
+
+ if [ ! -z "$nested_templates" ]; then
+ templates="$templates $nested_templates"
+ fi
+ done
+
+ echo $templates
+ else
+ echo ""
+ fi
+}
+
+set_template_info() {
+ templates=$(find_templates $config_file)
arrTemplates=(${templates// / })
config_data=$(cat $config_file)
input="hack: true"
-
for template in "${arrTemplates[@]}"
do
[ ! -z $template ] && {
puts env.map{|k,v| "-e\n#{k}=#{v}" }.join("\n")
RUBY
- raw=`exec echo "$input" | $docker_path run $user_args --rm -i -a stdin -a stdout $image ruby -e "$env_ruby"`
+ tmp_input_file=$(mktemp)
+
+ echo "$input" > "$tmp_input_file"
+ raw=`exec cat "$tmp_input_file" | $docker_path run $user_args --rm -i -a stdin -a stdout $image ruby -e "$env_ruby"`
+
+ rm -f "$tmp_input_file"
env=()
ok=1
if [ "$i" == "*ERROR." ]; then
ok=0
elif [ -n "$i" ]; then
- env[${#env[@]}]=$i
+ env[${#env[@]}]="${i//\{\{config\}\}/${config}}"
fi
done <<< "$raw"
if [ "$ok" -ne 1 ]; then
echo "${env[@]}"
- echo "YAML syntax error. Please check your /var/discourse/containers/*.yml config files."
+ echo "YAML syntax error. Please check your containers/*.yml config files."
+ exit 1
+ fi
+
+ # labels
+ read -r -d '' labels_ruby << 'RUBY'
+ require 'yaml'
+
+ input=STDIN.readlines.join
+ labels = {}
+ input.split('_FILE_SEPERATOR_').each do |yml|
+ yml.strip!
+ begin
+ labels.merge!(YAML.load(yml)['labels'] || {})
+ rescue Psych::SyntaxError => e
+ puts e
+ puts "*ERROR."
+ rescue => e
+ puts yml
+ p e
+ end
+ end
+ puts labels.map{|k,v| "-l\n#{k}=#{v}" }.join("\n")
+RUBY
+
+ tmp_input_file=$(mktemp)
+
+ echo "$input" > "$tmp_input_file"
+ raw=`exec cat "$tmp_input_file" | $docker_path run $user_args --rm -i -a stdin -a stdout $image ruby -e "$labels_ruby"`
+
+ rm -f "$tmp_input_file"
+
+ labels=()
+ ok=1
+ while read i; do
+ if [ "$i" == "*ERROR." ]; then
+ ok=0
+ elif [ -n "$i" ]; then
+ labels[${#labels[@]}]=$(echo $i | sed s/{{config}}/${config}/g)
+ fi
+ done <<< "$raw"
+
+ if [ "$ok" -ne 1 ]; then
+ echo "${labels[@]}"
+ echo "YAML syntax error. Please check your containers/*.yml config files."
+ exit 1
+ fi
+
+ # expose
+ read -r -d '' ports_ruby << 'RUBY'
+ require 'yaml'
+
+ input=STDIN.readlines.join
+ ports = []
+ input.split('_FILE_SEPERATOR_').each do |yml|
+ yml.strip!
+ begin
+ ports += (YAML.load(yml)['expose'] || [])
+ rescue Psych::SyntaxError => e
+ puts e
+ puts "*ERROR."
+ rescue => e
+ puts yml
+ p e
+ end
+ end
+ puts ports.map { |p| p.to_s.include?(':') ? "-p\n#{p}" : "--expose\n#{p}" }.join("\n")
+RUBY
+
+ tmp_input_file=$(mktemp)
+
+ echo "$input" > "$tmp_input_file"
+ raw=`exec cat "$tmp_input_file" | $docker_path run $user_args --rm -i -a stdin -a stdout $image ruby -e "$ports_ruby"`
+
+ rm -f "$tmp_input_file"
+
+ ports=()
+ ok=1
+ while read i; do
+ if [ "$i" == "*ERROR." ]; then
+ ok=0
+ elif [ -n "$i" ]; then
+ ports[${#ports[@]}]=$i
+ fi
+ done <<< "$raw"
+
+ if [ "$ok" -ne 1 ]; then
+ echo "${ports[@]}"
+ echo "YAML syntax error. Please check your containers/*.yml config files."
exit 1
fi
+
+ merge_user_args
}
-[ -z $docker_path ] && {
+if [ -z $docker_path ]; then
install_docker
-}
+fi
[ "$command" == "cleanup" ] && {
- echo
- echo "The following command will"
- echo "- Delete all docker images for old containers"
- echo "- Delete all stopped and orphan containers"
- echo
- read -p "Are you sure (Y/n): " -n 1 -r && echo
- if [[ $REPLY =~ ^[Yy]$ || ! $REPLY ]]
- then
- space=$(df /var/lib/docker | awk '{ print $4 }' | grep -v Available)
- echo "Starting Cleanup (bytes free $space)"
+ $docker_path system prune -a
- STATE_DIR=./.gc-state scripts/docker-gc
-
- space=$(df /var/lib/docker | awk '{ print $4 }' | grep -v Available)
- echo "Finished Cleanup (bytes free $space)"
+ if [ -d /var/discourse/shared/standalone/postgres_data_old ]; then
+ echo
+ echo "Old PostgreSQL backup data cluster detected taking up $(du -hs /var/discourse/shared/standalone/postgres_data_old | awk '{print $1}') detected"
+ read -p "Would you like to remove it? (Y/n): " -n 1 -r && echo
+ if [[ $REPLY =~ ^[Yy]$ ]]; then
+ echo "removing old PostgreSQL data cluster at /var/discourse/shared/standalone/postgres_data_old..."
+ rm -rf /var/discourse/shared/standalone/postgres_data_old
else
exit 1
+ fi
fi
- exit 0
-}
-[ $# -lt 2 ] && {
- usage
+ exit 0
}
-if [[ ! -e $config_file && $command -ne "memconfig" ]]
- then
+if [ ! "$command" == "setup" ]; then
+ if [[ ! -e $config_file ]]; then
echo "Config file was not found, ensure $config_file exists"
- echo ""
+ echo
echo "Available configs ( `cd containers && ls -dm *.yml | tr -s '\n' ' ' | awk '{ gsub(/\.yml/, ""); print }'`)"
exit 1
+ fi
fi
-
docker_version=($($docker_path --version))
docker_version=${test[2]//,/}
-
-if compare_version "1.2.0" "$docker_version"; then
- echo "We recommend you upgrade docker, the version you are running has no restart policies, on reboot your container may not start up"
- restart_policy=""
-else
- restart_policy=${restart_policy:---restart=always}
-fi
+restart_policy=${restart_policy:---restart=always}
set_existing_container(){
existing=`$docker_path ps -a | awk '{ print $1, $(NF) }' | grep " $config$" | awk '{ print $1 }'`
}
-run_stop(){
+run_stop() {
set_existing_container
run_image=`cat $config_file | $docker_path run $user_args --rm -i -a stdin -a stdout $image ruby -e \
"require 'yaml'; puts YAML.load(STDIN.readlines.join)['run_image']"`
- if [ -z "$run_image" ]; then
+ if [ -n "$user_run_image" ]; then
+ run_image=$user_run_image
+ elif [ -z "$run_image" ]; then
run_image="$local_discourse/$config"
fi
}
fi
}
-run_memconfig(){
- if [ "$opt" != "--skip-prereqs" ] ; then
- check_resources
- fi
- if [ -f $config_file ]
- then
- cp $config_file $config_file.bak
- echo "Saving $config_file as $config_file.bak"
- else
- echo "Creating $config_file from $template_path"
- if [ ! -f $template_path ]
- then
- echo "$template_path is missing. Exiting."
- exit 1
- fi
- cp $template_path $config_file
- fi
-
- # get free mem
- avail_mem="$(LANG=C free -m | grep '^Mem:' | awk '{print $2}')"
- avail_gb=`expr $(($avail_mem / 950))`
- avail_cores=`grep -c processor /proc/cpuinfo`
- echo "Found $avail_mem (${avail_gb}GB), of memory and $avail_cores cores."
-
- # set db_shared_buffers: "128MB" (1GB) or 256MB * GB
- if [ "$avail_gb" -eq "1" ]
- then
- db_shared_buffers="128"
- else
- db_shared_buffers=`expr $avail_gb \* 256`
- fi
- echo -e "Setting db_shared_buffers to ${db_shared_buffers}GB\c"
- sed -i -e "s/^ #db_shared_buffers:.*/ db_shared_buffers: \"${db_shared_buffers}GB\"/w $changelog" $config_file
- if [ -s $changelog ]
- then
- echo " successfully."
- rm $changelog
- else
- echo -e ". . . oops!\n---> db_shared_buffers not found in $config_file."
- fi
+merge_user_args() {
+ local docker_args
- # set UNICORN_WORKERS: 2*GB or 2*cores (the same on DO)
- if [ "$avail_gb" -le "2" ]
- then
- unicorn_workers=`expr $avail_gb \* 2`
- else
- unicorn_workers=`expr $avail_cores \* 2`
- fi
+ docker_args=`cat $config_file | $docker_path run $user_args --rm -i -a stdout -a stdin $image ruby -e \
+ "require 'yaml'; puts YAML.load(STDIN.readlines.join)['docker_args']"`
- echo -e "Setting UNICORN_WORKERS to $unicorn_workers\c"
- sed -i -e "s/^ #UNICORN_WORKERS:.*/ UNICORN_WORKERS: ${unicorn_workers}/w $changelog" $config_file
- if [ -s $changelog ]
- then
- echo " successfully."
- rm $changelog
- else
- echo -e ". . . oops!\n---> UNICORN_WORKERS not found in $config_file.\n"
+ if [[ -n "$docker_args" ]]; then
+ user_args="$user_args $docker_args"
fi
}
-run_start(){
+run_start() {
- existing=`$docker_path ps | awk '{ print $1, $(NF) }' | grep " $config$" | awk '{ print $1 }'`
- echo $existing
- if [ ! -z $existing ]
+ if [ -z "$START_CMD_ONLY" ]
then
- echo "Nothing to do, your container has already started!"
- exit 1
- fi
+ existing=`$docker_path ps | awk '{ print $1, $(NF) }' | grep " $config$" | awk '{ print $1 }'`
+ echo $existing
+ if [ ! -z $existing ]
+ then
+ echo "Nothing to do, your container has already started!"
+ exit 0
+ fi
- existing=`$docker_path ps -a | awk '{ print $1, $(NF) }' | grep " $config$" | awk '{ print $1 }'`
- if [ ! -z $existing ]
- then
- echo "starting up existing container"
- (
- set -x
- $docker_path start $config
- )
- exit 0
+ existing=`$docker_path ps -a | awk '{ print $1, $(NF) }' | grep " $config$" | awk '{ print $1 }'`
+ if [ ! -z $existing ]
+ then
+ echo "starting up existing container"
+ (
+ set -x
+ $docker_path start $config
+ )
+ exit 0
+ fi
fi
host_run
- ports=`cat $config_file | $docker_path run $user_args --rm -i -a stdout -a stdin $image ruby -e \
- "require 'yaml'; puts YAML.load(STDIN.readlines.join)['expose'].map{|p| \"-p #{p}\"}.join(' ')"`
-
- IFS='-p ' read -a array <<< "$ports"
- for element in "${array[@]}"
- do
- IFS=':' read -a args <<< "$element"
- if [ "${#args[@]}" == "2" ]; then
- check_ports "${args[0]}"
- elif [ "${#args[@]}" == "3" ]; then
- check_ports "${args[1]}"
- fi
- done
-
- docker_args=`cat $config_file | $docker_path run $user_args --rm -i -a stdout -a stdin $image ruby -e \
- "require 'yaml'; puts YAML.load(STDIN.readlines.join)['docker_args']"`
set_template_info
set_volumes
# we got to normalize so we only have allowed strings, this is more comprehensive but lets see how bash does first
# hostname=`$docker_path run $user_args --rm $image ruby -e 'print ARGV[0].gsub(/[^a-zA-Z-]/, "-")' $hostname`
# docker added more hostname rules
- hostname=${hostname/_/-}
+ hostname=${hostname//_/-}
+
+
+ if [ -z "$SKIP_MAC_ADDRESS" ] ; then
+ mac_address="--mac-address $($docker_path run $user_args -i --rm -a stdout -a stderr $image /bin/sh -c "echo $hostname | md5sum | sed 's/^\(..\)\(..\)\(..\)\(..\)\(..\).*$/02:\1:\2:\3:\4:\5/'")"
+ fi
+
+ if [ ! -z "$START_CMD_ONLY" ] ; then
+ docker_path="true"
+ fi
set -x
- $docker_path run $user_args $links $attach_on_run $restart_policy "${env[@]}" -h "$hostname" \
- -e DOCKER_HOST_IP=$docker_ip --name $config -t $ports $volumes $docker_args $run_image $boot_command
+
+ $docker_path run --shm-size=512m $links $attach_on_run $restart_policy "${env[@]}" "${labels[@]}" -h "$hostname" \
+ -e DOCKER_HOST_IP="$docker_ip" --name $config -t "${ports[@]}" $volumes $mac_address $user_args \
+ $run_image $boot_command
)
exit 0
}
-run_bootstrap(){
+run_run() {
+ set_template_info
+ set_volumes
+ set_links
+ set_run_image
+
+ unset ERR
+ (exec $docker_path run --rm --shm-size=512m $user_args $links "${env[@]}" -e DOCKER_HOST_IP="$docker_ip" -i -a stdin -a stdout -a stderr $volumes $run_image \
+ /bin/bash -c "$run_command") || ERR=$?
- if [ "$opt" != "--skip-prereqs" ] ; then
- check_resources
+ if [[ $ERR > 0 ]]; then
+ exit 1
fi
+}
+run_bootstrap() {
host_run
- get_ssh_pub_key
-
# Is the image available?
# If not, pull it here so the user is aware what's happening.
$docker_path history $image >/dev/null 2>&1 || $docker_path pull $image
echo $run_command
- env=("${env[@]}" "-e" "SSH_PUB_KEY=$ssh_pub_key")
+ unset ERR
+
+ tmp_input_file=$(mktemp)
- (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 \
- /bin/bash -c "$run_command") \
- || ($docker_path rm `cat $cidbootstrap` && rm $cidbootstrap)
+ echo "$input" > "$tmp_input_file"
+ (exec cat "$tmp_input_file" | $docker_path run --shm-size=512m $user_args $links "${env[@]}" -e DOCKER_HOST_IP="$docker_ip" --cidfile $cidbootstrap -i -a stdin -a stdout -a stderr $volumes $image \
+ /bin/bash -c "$run_command") || ERR=$?
- [ ! -e $cidbootstrap ] && echo "** FAILED TO BOOTSTRAP ** please scroll up and look for earlier error messages, there may be more than one" && exit 1
+ rm -f "$tmp_input_file"
+
+ unset FAILED
+ # magic exit code that indicates a retry
+ if [[ "$ERR" == 77 ]]; then
+ $docker_path rm `cat $cidbootstrap`
+ rm $cidbootstrap
+ exit 77
+ elif [[ "$ERR" > 0 ]]; then
+ FAILED=TRUE
+ fi
+
+ if [[ $FAILED = "TRUE" ]]; then
+ if [[ ! -z "$DEBUG" ]]; then
+ $docker_path commit `cat $cidbootstrap` $local_discourse/$config-debug || echo 'FAILED TO COMMIT'
+ echo "** DEBUG ** Maintaining image for diagnostics $local_discourse/$config-debug"
+ fi
+
+ $docker_path rm `cat $cidbootstrap`
+ rm $cidbootstrap
+ echo "** FAILED TO BOOTSTRAP ** please scroll up and look for earlier error messages, there may be more than one"
+ exit 1
+ fi
sleep 5
$docker_path rm `cat $cidbootstrap` && rm $cidbootstrap
}
-
-
case "$command" in
bootstrap)
run_bootstrap
exit 0
;;
- enter)
- exec $docker_path exec -it $config /bin/bash --login
+ run)
+ run_run
+ exit 0
;;
- ssh)
- existing=`$docker_path ps | awk '{ print $1, $(NF) }' | grep " $config$" | awk '{ print $1 }'`
-
- if [[ ! -z $existing ]]; then
- address="`$docker_path port $config 22`"
- split=(${address//:/ })
- exec ssh -o StrictHostKeyChecking=no root@${split[0]} -p ${split[1]}
- else
- echo "$config is not running!"
- exit 1
- fi
+ enter)
+ exec $docker_path exec -it $config /bin/bash --login
;;
stop)
exit 0
;;
+ start-cmd)
+ START_CMD_ONLY="1"
+ run_start
+ exit 0;
+ ;;
+
start)
run_start
exit 0
;;
- memconfig)
- run_memconfig
- exit 0
- ;;
-
rebuild)
if [ "$(git symbolic-ref --short HEAD)" == "master" ]; then
- echo "Ensuring discourse docker is up to date"
+ echo "Ensuring launcher is up to date"
git remote update
BASE=$(git merge-base @ @{u})
if [ $LOCAL = $REMOTE ]; then
- echo "Discourse Docker is up-to-date"
+ echo "Launcher is up-to-date"
elif [ $LOCAL = $BASE ]; then
- echo "Updating Discourse Docker"
+ echo "Updating Launcher"
git pull || (echo 'failed to update' && exit 1)
- exec /bin/bash $0 $@
+
+ for (( i=${#BASH_ARGV[@]}-1,j=0; i>=0,j<${#BASH_ARGV[@]}; i--,j++ ))
+ do
+ args[$j]=${BASH_ARGV[$i]}
+ done
+ exec /bin/bash $0 "${args[@]}" # $@ is empty, because of shift at the beginning. Use BASH_ARGV instead.
elif [ $REMOTE = $BASE ]; then
- echo "Your version of Discourse Docker is ahead of origin"
+ echo "Your version of Launcher is ahead of origin"
else
- echo "Discourse Docker has diverged source, this is only expected in Dev mode"
+ echo "Launcher has diverged source, this is only expected in Dev mode"
fi
fi