Created
April 30, 2017 08:00
-
-
Save pracucci/6d506647073d0b37ae899ca95da7aef5 to your computer and use it in GitHub Desktop.
An hacky way to replace K8S configmap from file, optionally signaling a deployment's containers once done. Be aware that a configmap is updated on containers asynchronously and could take some time: a signal delivered before will be totally useless. I still didn't find a way to watch for a configmap update complete event, and a sleep looks even …
This file contains hidden or 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
| #!/bin/bash | |
| # Init | |
| OPT_FROM_FILES= | |
| OPT_DEPLOYMENT= | |
| OPT_CONTAINER= | |
| OPT_SIGNAL= | |
| OPT_YES=0 | |
| # Helper to print usage | |
| usage() { | |
| echo "Replaces a config map from file and (optionally) signal the main process in a container." | |
| echo "" | |
| echo "Usage: kubectl-rollout-configmap [options] <configmap>" | |
| echo "" | |
| echo "Options:" | |
| echo " -f FILE Configmap file or directory" | |
| echo " -s SIGNAL After replacing the configmap signal the pod container(s) in the specified deployment" | |
| echo " -d DEPLOYMENT The name of the deployment whose containers should be signaled" | |
| echo " -c CONTAINER The name of the container should be signaled (required if your pod has multiple containers)" | |
| echo " -y Always yes: do not ask before signaling (please note that it takes some time before a" | |
| echo " configmap is updated on containers, and the signal could be sent before it, making it" | |
| echo " useless)" | |
| echo "" | |
| echo "Examples:" | |
| echo " Replace config map from a file and signal deployment containers" | |
| echo " kubectl-rollout-configmap -f config.yaml -d nginx -s HUP nginx-config" | |
| echo "" | |
| exit 1 | |
| } | |
| # Parse options | |
| while getopts "f:d:c:s:yh" OPTION; do | |
| case "$OPTION" in | |
| f) | |
| OPT_FROM_FILES="${OPT_FROM_FILES} --from-file=${OPTARG}" | |
| ;; | |
| d) | |
| OPT_DEPLOYMENT=$OPTARG | |
| ;; | |
| c) | |
| OPT_CONTAINER=$OPTARG | |
| ;; | |
| s) | |
| OPT_SIGNAL=$OPTARG | |
| ;; | |
| y) | |
| OPT_YES=1 | |
| ;; | |
| h) | |
| usage | |
| ;; | |
| *) | |
| # NOTE: getopts will print an error message | |
| exit 1 | |
| ;; | |
| esac | |
| done | |
| # Get configmap name | |
| shift $(($OPTIND - 1)) | |
| OPT_CONFIGMAP=$@ | |
| if [ -z "$OPT_CONFIGMAP" ]; then | |
| echo "The configmap name is missing. Please run kubectl-rollout-configmap -h for help." | |
| exit 1 | |
| fi | |
| # Check if the configmap already exists | |
| kubectl get configmap $OPT_CONFIGMAP > /dev/null 2> /dev/null | |
| CONFIGMAP_EXISTS=$? | |
| # Currently kubernetes doesn't allow to update a configmap | |
| # from file, so we do create a new temporary configmap, replace | |
| # the original one, delete the temporary one | |
| if [ "$CONFIGMAP_EXISTS" -eq 0 ]; then | |
| UNIQ=$(date | md5 | fold -w 6 | head -n 1) | |
| CONFIGMAP_TMP="${OPT_CONFIGMAP}.${UNIQ}tmp" | |
| (kubectl create configmap $CONFIGMAP_TMP $OPT_FROM_FILES) && \ | |
| (kubectl get configmap $CONFIGMAP_TMP -o yaml | sed "s/${CONFIGMAP_TMP}/${OPT_CONFIGMAP}/g" | sed -E "s/creationTimestamp:.*|resourceVersion:.*|selfLink:.*|uid:.*//g" | kubectl replace configmap $OPT_CONFIGMAP -f -) && \ | |
| (kubectl delete configmap $CONFIGMAP_TMP) | |
| else | |
| kubectl create configmap $OPT_CONFIGMAP $OPT_FROM_FILES | |
| fi | |
| if [ $? -ne 0 ]; then | |
| exit 1 | |
| fi | |
| # Signaling | |
| if [ -n "$OPT_SIGNAL" ]; then | |
| if [ $OPT_YES -eq 0 ]; then | |
| # Ask confirmation | |
| read -p "You are about to send signal $OPT_SIGNAL to $OPT_DEPLOYMENT. Continue? [yes/no] " -r | |
| echo "" | |
| if [ "$REPLY" == "yes" ]; then | |
| CONFIRMED=1 | |
| fi | |
| else | |
| CONFIRMED=1 | |
| fi | |
| if [ -n "$CONFIRMED" ]; then | |
| if [ -n "$OPT_DEPLOYMENT" ] && [ -z "$OPT_CONTAINER" ]; then | |
| # Signal without container selection | |
| kubectl get pods -l app="${OPT_DEPLOYMENT}" -o custom-columns=NAME:.metadata.name --no-headers | \ | |
| xargs -I {} kubectl exec "{}" -- kill -${OPT_SIGNAL} 1 | |
| echo "Signal sent" | |
| elif [ -n "$OPT_DEPLOYMENT" ] && [ -n "$OPT_CONTAINER" ]; then | |
| # Signal with container selection | |
| kubectl get pods -l app="${OPT_DEPLOYMENT}" -o custom-columns=NAME:.metadata.name --no-headers | \ | |
| xargs -I {} kubectl exec "{}" -c "${OPT_CONTAINER}" -- kill -${OPT_SIGNAL} 1 | |
| echo "Signal sent" | |
| else | |
| # Missing required option | |
| echo "Unable to signal because of missing deployment option: please add -d DEPLOYMENT" | |
| exit 1 | |
| fi | |
| fi | |
| fi |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment