#!/bin/bash

limit=''
force=''
rotate=''
while test $# -gt 0; do
    case "$1" in
	(-h|--help) cat <<EOF
$0 [OPTIONS] FILES…

OPTIONS

  -h, --help           show this help
  -s, --limit service  limit update to given service
  -f, --force          force update
  -r, --rotate-key     hand the current registry credentials to the
                       services and leave their images as they are

FILES…

  List of stack names or yaml files to deploy. There must be yaml
  files with the same name. The extension .yaml may be given or not.

DESCRIPTION

  Updates the docker images of all services in the given stacks.

  A service carries the registry credentials of the moment it was
  deployed, and a node uses them when it pulls an image. After the
  token of the registry account has been rotated, --rotate-key writes
  the credentials of this machine into every service of the stacks,
  without touching the image any service runs.

EOF
		    exit;;
	(-l|--limit) shift; limit=$1;;
	(-f|--force) force='--force';;
	(-r|--rotate-key) rotate='yes';;
	(*) break;;
    esac
    if test $# -lt 1; then
	echo "error: missing argument, try $0 --help" 1>&2
	exit 1
    fi
    shift
done

for f in $*; do
    name=${f%.yaml}
    file=${name}.yaml
    name=${name##*/}
    echo "upgrading ${name}"
    IFS="
"
    for param in $(sed -n '/^ *\([^:]\+\): *$/{s,,'"${name}"'_\1,;h};/^ *image: */{s///;G;s/\n/ /p}' $file); do
	IFS=" "
	if [ -z "$limit" ] || [[ "${param}" =~ " ${name}_${limit}" ]]; then
	    # --with-registry-auth hands the credentials of this machine to the
	    # nodes that pull the image, as docker-deploy does
	    if test -n "$rotate"; then
		# the service name is the second word of the pair, the image
		# the first: only the credentials are written, the image of the
		# service stays the one it runs
		service=${param#* }
		echo "....rotate key of $service"
		docker service update --with-registry-auth $force $service
	    else
		echo "....update $param: docker service update --image $param"
		docker service update --with-registry-auth $force --image $param
	    fi
	fi
    done
done

