Last active
December 11, 2016 10:34
-
-
Save joshenders/85d5fb4b0f35e5199e252339c68d178f to your computer and use it in GitHub Desktop.
reload-vcl patch for config discards and safe stop
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
--- reload-vcl 2011-10-29 13:24:10.000000000 +0000 | |
+++ /usr/share/varnish/reload-vcl 2016-12-11 09:51:08.696300339 +0000 | |
@@ -1,9 +1,13 @@ | |
#!/bin/sh | |
- | |
+# | |
# reload-varnish: Script to reload varnishd from VCL defined in | |
# /etc/default/varnish. | |
# | |
# Stig Sandbeck Mathisen <ssm@debian.org> | |
+# Josh Enders <jenders@pinterest.com> | |
+ | |
+# Environment | |
+TMPDIR="${TMPDIR:-/tmp}" | |
# Settings | |
defaults=/etc/default/varnish | |
@@ -12,74 +16,75 @@ | |
# Paths | |
varnishadm=/usr/bin/varnishadm | |
date=/bin/date | |
-tempfile=/bin/tempfile | |
+mktemp=/bin/mktemp | |
# Messages | |
# msg_no_varnishadm: varnishadm | |
msg_no_varnishadm="Error: Cannot execute %s\n" | |
msg_no_management="Management port disabled. \$DAEMON_OPTS must contain '-T hostname:port'\n" | |
+ | |
# msg_defaults_not_readable: defaults | |
msg_defaults_not_readable="Error: %s is not readable\n" | |
-# msg_defaults_not_there: defaults | |
-msg_defaults_not_there="Error: %s does not exist\n" | |
+ | |
+# msg_defaults_not_exist: defaults | |
+msg_defaults_not_exist="Error: %s does not exist\n" | |
msg_no_vcl="Error: No VCL file used, nothing to reload\n" | |
msg_usage="Usage: $0 [-h][-c][-q]\n\t-h\tdisplay help\n\t-q\tquiet\n\t-c\tcompile only, do not reload\n" | |
+ | |
+# msg_discard_failed: vcl_last_label | |
+msg_discard_failed="Error: vcl.discard %s failed\n" | |
+ | |
+# msg_discard_ok vcl_last_label | |
+msg_discard_ok="VCL %s discarded\n" | |
+ | |
# msg_compile_only: varnishadm, mgmt_interface, vcl_label | |
msg_compile_only="To activate, run:\n\t%s -T %s \\\\\n\tvcl.use %s\n" | |
+ | |
# msg_compile_failed: vcl_label, vcl_file | |
msg_compile_failed="Error: vcl.load %s %s failed" | |
+ | |
# msg_use_ok: vcl_label | |
msg_use_ok="VCL reloaded, active label is %s\n" | |
+ | |
# msg_use_failed: vcl_label | |
msg_use_failed="Error: vcl.use %s failed\n" | |
+ | |
# msg_secret_not_readable: secret | |
msg_secret_not_readable="Error: Secret file %s is not readable\n" | |
-# msg_secret_not_there: secret | |
-msg_secret_not_there="Error: Secret file %s does not exist\n" | |
-# Generate a label, prefixed with the caller's username, from the | |
-# kernel random uuid generator, fallback to timestamp | |
-if [ -f /proc/sys/kernel/random/uuid ] | |
-then | |
- uuid=$(cat /proc/sys/kernel/random/uuid) | |
- vcl_label="${LOGNAME}${LOGNAME:+:}${uuid}" | |
-else | |
- vcl_label="$($date +${LOGNAME}${LOGNAME:+:}%s.%N)" | |
-fi | |
+# msg_secret_not_exist: secret | |
+msg_secret_not_exist="Error: Secret file %s does not exist\n" | |
# Load defaults file | |
-if [ -f "$defaults" ] | |
-then | |
- if [ -r "$defaults" ] | |
- then | |
- . "$defaults" | |
+if [ -f "$defaults" ]; then | |
+ if [ -r "$defaults" ]; then | |
+ . "$defaults" | |
else | |
- printf >&2 "$msg_defaults_not_readable" $defaults | |
- exit 1 | |
+ printf "$msg_defaults_not_readable" "$defaults" >&2 | |
+ exit 1 | |
fi | |
else | |
- printf >&2 "$msg_defaults_not_there" $defaults | |
+ printf "$msg_defaults_not_exist" "$defaults" >&2 | |
exit 1 | |
fi | |
# parse command line arguments | |
-while getopts hcq flag | |
-do | |
- case $flag in | |
- h) | |
- printf >&2 "$msg_usage" | |
- exit 0 | |
- ;; | |
- c) | |
- compile_only=1 | |
- ;; | |
- q) | |
- quiet=1 | |
- ;; | |
- *) | |
- printf >&2 "$msg_usage\n" | |
- exit 1 | |
- ;; | |
+while getopts hcq flag; do | |
+ case "$flag" in | |
+ h) | |
+ printf "$msg_usage" >&2 | |
+ exit 0 | |
+ ;; | |
+ c) | |
+ compile_only=1 | |
+ ;; | |
+ q) | |
+ quiet=1 | |
+ ;; | |
+ *) | |
+ printf "$msg_usage\n" >&2 | |
+ exit 1 | |
+ ;; | |
esac | |
done | |
@@ -87,87 +92,99 @@ | |
# Extract the -f and the -T option, and (try to) ensure that the | |
# management interface is on the form hostname:address. | |
OPTIND=1 | |
-while getopts a:b:CdFf:g:h:i:l:M:n:P:p:S:s:T:t:u:Vw: flag $DAEMON_OPTS | |
-do | |
- case $flag in | |
- f) | |
- if [ -f "$OPTARG" ]; then | |
- vcl_file="$OPTARG" | |
- fi | |
- ;; | |
- T) | |
- if [ -n "$OPTARG" -a "$OPTARG" != "${OPTARG%%:*}" ] | |
- then | |
- mgmt_interface="$OPTARG" | |
- fi | |
- ;; | |
- S) | |
- secret="$OPTARG" | |
- ;; | |
+ | |
+while getopts a:b:CdFf:g:h:i:l:M:n:P:p:S:s:T:t:u:Vw: flag $DAEMON_OPTS; do | |
+ case "$flag" in | |
+ f) | |
+ if [ -f "$OPTARG" ]; then | |
+ vcl_file="$OPTARG" | |
+ fi | |
+ ;; | |
+ T) | |
+ if [ -n "$OPTARG" -a "$OPTARG" != "${OPTARG%%:*}" ]; then | |
+ mgmt_interface="$OPTARG" | |
+ fi | |
+ ;; | |
+ S) | |
+ secret="$OPTARG" | |
+ ;; | |
esac | |
done | |
# Sanity checks | |
-if [ ! -x "$varnishadm" ] | |
-then | |
- printf >&2 "$msg_no_varnishadm" $varnishadm | |
+if [ ! -x "$varnishadm" ]; then | |
+ printf "$msg_no_varnishadm" "$varnishadm" >&2 | |
exit 1 | |
fi | |
-if [ -z "$mgmt_interface" ] | |
-then | |
- printf >&2 "$msg_no_management" | |
+if [ -z "$mgmt_interface" ]; then | |
+ printf "$msg_no_management" >&2 | |
exit 1 | |
fi | |
-if [ -z "$vcl_file" ] | |
-then | |
- printf >&2 "$msg_no_vcl" | |
+if [ -z "$vcl_file" ]; then | |
+ printf "$msg_no_vcl" >&2 | |
exit 1 | |
fi | |
# Check secret file | |
-if [ -f "$secret" ] | |
- then | |
- if [ ! -r "$secret" ] | |
- then | |
- printf >&2 "$msg_secret_not_readable" $secret | |
- exit 1 | |
- fi | |
+if [ -f "$secret" ]; then | |
+ if [ ! -r "$secret" ]; then | |
+ printf "$msg_secret_not_readable" "$secret" >&2 | |
+ exit 1 | |
+ fi | |
else | |
- printf >&2 "$msg_secret_not_there" $secret | |
- exit 1 | |
+ printf "$msg_secret_not_exist" "$secret" >&2 | |
+ exit 1 | |
fi | |
-logfile=$($tempfile -n /tmp/$vcl_label) | |
+# Generate a name for the config | |
+count=$("$varnishadm" -T "$mgmt_interface" -S "$secret" vcl.list | awk '{ print $3 }' | sort -n | tail -1) | |
+ | |
+# The initial config is conveniently called, "boot" | |
+if [ "$count" = 'boot' ]; then | |
+ count=0 | |
+fi | |
-# Compile and maybe reload | |
-if $varnishadm -T $mgmt_interface -S ${secret} vcl.load $vcl_label $vcl_file | |
-then | |
- if [ -n "$compile_only" ] | |
- then | |
- printf "$msg_compile_only" $varnishadm $mgmt_interface $vcl_label | |
+vcl_label="$((${count}+1))" | |
+logfile=$("$mktemp" "$TMPDIR/${0##*/}-XXXXXXXXXX") | |
+ | |
+# Compile and maybe reload and discard | |
+if "$varnishadm" -T "$mgmt_interface" -S "$secret" vcl.load "$vcl_label" "$vcl_file" >> "$logfile" 2>&1; then | |
+ if [ -n "$compile_only" ]; then | |
+ printf "$msg_compile_only" "$varnishadm" "$mgmt_interface" "$vcl_label" >> "$logfile" 2>&1 | |
else | |
- if $varnishadm -T $mgmt_interface -S ${secret} vcl.use $vcl_label | |
- then | |
- printf "$msg_use_ok" $vcl_label | |
- else | |
- printf "$msg_use_failed" $vcl_label | |
- exitstatus=1 | |
- fi | |
+ if "$varnishadm" -T "$mgmt_interface" -S "$secret" vcl.use "$vcl_label" >> "$logfile" 2>&1; then | |
+ if [ $count -ge $HOLDCOUNT ]; then | |
+ vcl_last_label=$((${count}-${HOLDCOUNT})) | |
+ | |
+ if [ "$vcl_last_label" = 0 ]; then | |
+ vcl_last_label='boot' | |
+ fi | |
+ | |
+ if "$varnishadm" -T "$mgmt_interface" -S "$secret" vcl.discard "$vcl_last_label" >> "$logfile" 2>&1; then | |
+ printf "$msg_discard_ok" "$vcl_last_label" >> "$logfile" | |
+ else | |
+ printf "$msg_discard_failed" "$vcl_last_label" >> "$logfile" | |
+ exitstatus=1 | |
+ fi | |
+ fi | |
+ printf "$msg_use_ok" "$vcl_label" >> "$logfile" | |
+ else | |
+ printf "$msg_use_failed" "$vcl_label" >> "$logfile" | |
+ exitstatus=1 | |
+ fi | |
fi | |
else | |
- printf "$msg_compile_failed" $vcl_label $vcl_file | |
+ printf "$msg_compile_failed" "$vcl_label" "$vcl_file" >> "$logfile" | |
exitstatus=1 | |
-fi | grep -v "^$" > $logfile | |
+fi | |
-# Blather | |
-if [ -z "${quiet}" -o -n "$exitstatus" ] | |
-then | |
- cat >&2 $logfile | |
+if [ -z "${quiet}" -o -n "$exitstatus" ]; then | |
+ cat "$logfile" >&2 | |
fi | |
# Cleanup | |
-rm -f $logfile | |
+rm -f "${logfile:?}" | |
exit $exitstatus |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment