-
Notifications
You must be signed in to change notification settings - Fork 0
/
wait-for-deployment
executable file
·134 lines (108 loc) · 3.82 KB
/
wait-for-deployment
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
#!/bin/bash
# Waits for a deployment to complete.
#
# Includes a two-step approach:
#
# 1. Wait for the observed generation to match the specified one.
# 2. Waits for the number of available replicas to match the specified one.
#
# Spawn from my answer to this StackOverflow question: http://stackoverflow.com/questions/37448357/ensure-kubernetes-deployment-has-completed-and-all-pods-are-updated-and-availabl
#
set -o errexit
set -o pipefail
set -o nounset
# -m enables job control which is otherwise only enabled in interactive mode
# http://unix.stackexchange.com/a/196606/73578
set -m
DEFAULT_TIMEOUT=60
DEFAULT_NAMESPACE=default
get_all_pods_logs() {
for pod in $(kubectl get pods -o jsonpath='{.items[*].metadata.name}'); do
kubectl logs $pod
done
}
get_all_pods_describes() {
for pod in $(kubectl get pods -o jsonpath='{.items[*].metadata.name}'); do
kubectl describe pods/$pod
done
}
monitor_timeout() {
local -r wait_pid="$1"
sleep "${timeout}"
echo "Timeout ${timeout} exceeded" >&2
kill "${wait_pid}"
}
get_generation() {
get_deployment_jsonpath '{.metadata.generation}'
}
get_observed_generation() {
get_deployment_jsonpath '{.status.observedGeneration}'
}
get_specified_replicas() {
get_deployment_jsonpath '{.spec.replicas}'
}
get_replicas() {
get_deployment_jsonpath '{.status.replicas}'
}
get_updated_replicas() {
get_deployment_jsonpath '{.status.updatedReplicas}'
}
get_available_replicas() {
get_deployment_jsonpath '{.status.availableReplicas}'
}
get_deployment_jsonpath() {
local -r jsonpath="$1"
kubectl --namespace "${namespace}" get deployment "${deployment}" -o "jsonpath=${jsonpath}"
}
display_usage_and_exit() {
echo "Usage: $(basename "$0") [-n <namespace>] [-t <timeout>] <deployment>" >&2
echo "Arguments:" >&2
echo "deployment REQUIRED: The name of the deployment the script should wait on" >&2
echo "-n OPTIONAL: The namespace the deployment exists in, defaults is the 'default' namespace" >&2
echo "-t OPTIONAL: How long to wait for the deployment to be available, defaults to ${DEFAULT_TIMEOUT} seconds, must be greater than 0" >&2
exit 1
}
namespace=${DEFAULT_NAMESPACE}
timeout=${DEFAULT_TIMEOUT}
while getopts ':n:t:' arg
do
case ${arg} in
n) namespace=${OPTARG};;
t) timeout=${OPTARG};;
*) display_usage_and_exit
esac
done
shift $((OPTIND-1))
if [ "$#" -ne 1 ] ; then
display_usage_and_exit
fi
readonly deployment="$1"
if [[ ${timeout} -le 0 ]]; then
display_usage_and_exit
fi
echo "Waiting for deployment of ${deployment} in namespace ${namespace} with a timeout ${timeout} seconds"
monitor_timeout $$ &
readonly timeout_monitor_pid=$!
trap 'kill -- -${timeout_monitor_pid}' EXIT #Stop timeout monitor
generation=$(get_generation); readonly generation
current_generation=$(get_observed_generation)
echo "Expected generation for deployment ${deployment}: ${generation}"
while [[ ${current_generation} -lt ${generation} ]]; do
sleep .5
echo "Currently observed generation: ${current_generation}"
current_generation=$(get_observed_generation)
done
echo "Observed expected generation: ${current_generation}"
specified_replicas="$(get_specified_replicas)"; readonly specified_replicas
echo "Specified replicas: ${specified_replicas}"
current_replicas=$(get_replicas)
updated_replicas=$(get_updated_replicas)
available_replicas=$(get_available_replicas)
while [[ ${updated_replicas} -lt ${specified_replicas} || ${current_replicas} -gt ${updated_replicas} || ${available_replicas} -lt ${updated_replicas} ]]; do
sleep 20
echo "current/updated/available replicas: ${current_replicas}/${updated_replicas}/${available_replicas}, waiting"
current_replicas=$(get_replicas)
updated_replicas=$(get_updated_replicas)
available_replicas=$(get_available_replicas)
done
echo "Deployment ${deployment} successful. All ${available_replicas} replicas are ready."