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 for the given 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
user_args=""
+user_run_image=""
if [[ $command == "run" ]]; then
run_command=$3
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='[[:upper:]/ !@#$%^&*()+~`=]'
if [[ $config =~ $re ]];
config_file=containers/"$config".yml
cidbootstrap=cids/"$config"_bootstrap.cid
local_discourse=local_discourse
-image=discourse/base:2.0.20180802
-docker_path=`which docker.io || which docker`
+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
echo
if [[ $REPLY =~ ^[Yy]$ ]]
then
- docker system prune
+ $docker_path system prune -af
echo "If the cleanup was successful, you may try again now"
fi
exit 1
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"
exit 1
fi
+ # labels
read -r -d '' labels_ruby << 'RUBY'
require 'yaml'
input=STDIN.readlines.join
- # default to UTF-8 for the dbs sake
labels = {}
input.split('_FILE_SEPERATOR_').each do |yml|
yml.strip!
puts labels.map{|k,v| "-l\n#{k}=#{v}" }.join("\n")
RUBY
- raw=`exec echo "$input" | $docker_path run $user_args --rm -i -a stdin -a stdout $image ruby -e "$labels_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
echo "YAML syntax error. Please check your containers/*.yml config files."
exit 1
fi
-}
-if [ -z $docker_path ]; then
- install_docker
-fi
+ # expose
+ read -r -d '' ports_ruby << 'RUBY'
+ require 'yaml'
-[ "$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)"
+ 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
- STATE_DIR=./.gc-state scripts/docker-gc
+ tmp_input_file=$(mktemp)
- rm -f shared/standalone/log/var-log/*.txt
+ 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"`
- space=$(df /var/lib/docker | awk '{ print $4 }' | grep -v Available)
- echo "Finished Cleanup (bytes free $space)"
+ rm -f "$tmp_input_file"
- else
+ 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
+ fi
+
+ merge_user_args
+}
+
+if [ -z $docker_path ]; then
+ install_docker
+fi
+
+[ "$command" == "cleanup" ] && {
+ $docker_path system prune -a
if [ -d /var/discourse/shared/standalone/postgres_data_old ]; then
echo
exit 0
}
-if [ -z "$command" -a -z "$config" ]; then
- usage
-fi
-
if [ ! "$command" == "setup" ]; then
if [[ ! -e $config_file ]]; then
echo "Config file was not found, ensure $config_file exists"
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
}
+merge_user_args() {
+ local docker_args
+
+ 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']"`
+
+ if [[ -n "$docker_args" ]]; then
+ user_args="$user_args $docker_args"
+ fi
+}
+
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 0
- 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(' ')"`
-
- 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
set_links
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 --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 $docker_args $user_args \
+ -e DOCKER_HOST_IP="$docker_ip" --name $config -t "${ports[@]}" $volumes $mac_address $user_args \
$run_image $boot_command
)
}
-setup_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 [[ $ERR > 0 ]]; then
+ exit 1
+ fi
+}
+
+run_bootstrap() {
host_run
# Is the image available?
set_volumes
set_links
-}
-run_run() {
- setup_bootstrap
-
- $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 $image \
- /bin/bash --login -c "$run_command"
-}
-
-run_bootstrap() {
- setup_bootstrap
rm -f $cidbootstrap
run_command="cd /pups &&"
echo $run_command
unset ERR
- (exec echo "$input" | $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 \
+
+ tmp_input_file=$(mktemp)
+
+ 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=$?
+ 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
}
-
-
case "$command" in
bootstrap)
run_bootstrap
exit 0
;;
+ start-cmd)
+ START_CMD_ONLY="1"
+ run_start
+ exit 0;
+ ;;
+
start)
run_start
exit 0