Skip to content

Instantly share code, notes, and snippets.

@theikkila
Last active August 29, 2015 14:07
Show Gist options
  • Save theikkila/fae772486a52a19c2eff to your computer and use it in GitHub Desktop.
Save theikkila/fae772486a52a19c2eff to your computer and use it in GitHub Desktop.
Mesosphere custom HAProxy
#!/bin/bash
set -o errexit -o nounset -o pipefail
function -h {
cat <<USAGE
USAGE: $name <marathon host:port>+
$name install_haproxy_system <marathon host:port>+
Generates a new configuration file for HAProxy from the specified Marathon
servers, replaces the file in /etc/haproxy and restarts the service.
In the second form, installs the script itself, HAProxy and a cronjob that
once a minute pings one of the Marathon servers specified and refreshes
HAProxy if anything has changed. The list of Marathons to ping is stored,
one per line, in:
$cronjob_conf_file
The script is installed as:
$script_path
The cronjob is installed as:
$cronjob
and run as root.
USAGE
}; function --help { -h ;}
export LC_ALL=en_US.UTF-8
name=haproxy-marathon-bridge
cronjob_conf_file=/etc/"$name"/marathons
cronjob=/etc/cron.d/"$name"
script_path=/usr/local/bin/"$name"
function main {
config "$@"
}
function refresh_system_haproxy {
config "$@" > /tmp/haproxy.cfg
if ! diff -q /tmp/haproxy.cfg /etc/haproxy/haproxy.cfg >&2
then
msg "Found changes. Sending reload request to HAProxy..."
cat /tmp/haproxy.cfg > /etc/haproxy/haproxy.cfg
if [[ -f /etc/init/haproxy.conf ]]
then reload haproxy ## In case it switches to Upstart
else /etc/init.d/haproxy reload
fi
fi
}
function install_haproxy_system {
sudo env DEBIAN_FRONTEND=noninteractive aptitude install -y haproxy
sudo sed -i 's/^ENABLED=0/ENABLED=1/' /etc/default/haproxy
install_cronjob "$@"
}
function install_cronjob {
sudo mkdir -p "$(dirname "$cronjob_conf_file")"
[[ -f $cronjob_conf_file ]] || sudo touch "$cronjob_conf_file"
if [[ $# -gt 0 ]]
then printf '%s\n' "$@" | sudo dd of="$cronjob_conf_file"
fi
cat "$0" | sudo dd of="$script_path"
sudo chmod ug+rx "$script_path"
cronjob | sudo dd of="$cronjob"
header | sudo dd of=/etc/haproxy/haproxy.cfg
}
function cronjob {
cat <<EOF
* * * * * root $script_path logged refresh_system_haproxy \$(cat $cronjob_conf_file)
EOF
}
function config {
header
apps "$@"
}
function header {
cat <<\EOF
global
daemon
log 127.0.0.1 local0
log 127.0.0.1 local1 notice
maxconn 4096
defaults
log global
retries 3
maxconn 2000
contimeout 5000
clitimeout 50000
srvtimeout 50000
listen stats
bind 0.0.0.0:9090
balance
mode http
stats enable
stats auth admin:admin
EOF
}
function apps {
(until curl -sSfLk -m 10 -H 'Accept: text/plain' "${1%/}"/v2/tasks; do [ $# -lt 2 ] && return 1 || shift; done) | while read -r txt
do
set -- $txt
local app_name="$1"
local app_port="$2"
shift 2
if [ "${app_port//[0-9]*}" = "" ]
then
cat <<EOF
listen $app_name-$app_port
bind 0.0.0.0:$app_port
mode tcp
option tcplog
balance leastconn
EOF
while [[ $# -ne 0 ]]
do
out " server ${app_name}-$# $1 check"
shift
done
fi
done
}
function logged {
exec 1> >(logger -p user.info -t "$name[$$]")
exec 2> >(logger -p user.notice -t "$name[$$]")
"$@"
}
function msg { out "$*" >&2 ;}
function err { local x=$? ; msg "$*" ; return $(( $x == 0 ? 1 : $x )) ;}
function out { printf '%s\n' "$*" ;}
# If less than 1 argument is provided, print usage and exit. At least one
# argument is required as described in the `USAGE` message.
[ $# -lt 1 ] && { -h; exit 1; }
if [[ ${1:-} ]] && declare -F | cut -d' ' -f3 | fgrep -qx -- "${1:-}"
then "$@"
else main "$@"
fi
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment