Skip to content

Instantly share code, notes, and snippets.

@joshenders
Last active December 11, 2016 10:34
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save joshenders/85d5fb4b0f35e5199e252339c68d178f to your computer and use it in GitHub Desktop.
Save joshenders/85d5fb4b0f35e5199e252339c68d178f to your computer and use it in GitHub Desktop.
reload-vcl patch for config discards and safe stop
--- 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