...
1#!/bin/bash
2
3# Choose colors carefully. If they don't work on both a black
4# background and a white background, pick other colors (so white,
5# yellow, and black are poor choices).
6export RED='\033[1;31m'
7export GRN='\033[1;32m'
8export BLU='\033[1;34m'
9export CYN='\033[1;36m'
10export END='\033[0m'
11
12require() {
13 if [ -z "${!1}" ]; then
14 echo "please set the $1 environment variable" 2>&1
15 exit 1
16 fi
17}
18
19kubectl() {
20 if ! test -f tools/bin/kubectl; then
21 make tools/bin/kubectl >&2
22 fi
23 tools/bin/kubectl "$@"
24}
25
26wait_for_ip() ( # use a subshell so the set +x is local to the function
27 { set +x; } 2>/dev/null # make the set +x be quiet
28 local external_ip=""
29 while true; do
30 external_ip=$(kubectl get svc -n "$1" "$2" --template="{{range .status.loadBalancer.ingress}}{{.ip}}{{end}}")
31 if [ -z "$external_ip" ]; then
32 echo "Waiting for external IP..." 1>&2
33 sleep 10
34 else
35 break
36 fi
37 done
38 echo "$external_ip"
39)
40
41curl_retry() (
42 { set +x; } 2>/dev/null # make the set +x be quiet
43 local tries=0
44 local retry_count=$1
45 echo "retry_count ${retry_count}"
46 shift 1
47 local ok_status_codes=$1
48 echo "ok_status_codes ${ok_status_codes}"
49 shift 1
50 local abort_status_codes=$1
51 echo "abort status codes ${abort_status_codes}"
52 shift 1
53 while [ "${retry_count}" -lt 0 ] || [ "$tries" -lt "${retry_count}" ] ; do
54 local code=$(curl -v --retry 100 --max-time 120 --retry-connrefused -skL -w "%{http_code}" "$@")
55 local curlStatus="$?"
56 echo $curlStatus
57 if [ "$curlStatus" -ne "56" ] && [ "$curlStatus" -ne "18" ] ; then
58 if [ "${ok_status_codes}" == "" ] ; then
59 return 0
60 fi
61 for ok_code in ${ok_status_codes//,/ } ; do
62 if [ "${ok_code}" -eq "${code}" ] ; then
63 echo "Got $code, ready!" 1>&2
64 return 0
65 fi
66 done
67 for bad_code in ${abort_status_codes//,/ } ; do
68 if [ "${bad_code}" -eq "${code}" ] ; then
69 echo "Got $code, aborting" 1>&2
70 return 1
71 fi
72 done
73 fi
74 echo "Curl exited with code $curlStatus and status code ${code}, sleeping for 10 seconds and then retrying... (tries=$tries)" 1>&2
75 sleep 10
76 tries=$((tries+1))
77 done
78 return 1
79)
80
81wait_for_url_output() ( # use a subshell so the set +x is local to the function
82 { set +x; } 2>/dev/null # make the set +x be quiet
83 local status=""
84 local output="${1}"
85 shift 1
86 while true; do
87 status=$(curl --retry 100 --retry-connrefused -k -sL -w "%{http_code}" -o "${output}" "$@")
88 if [ "$status" == "400" ]; then
89 echo "Got $status, aborting" 1>&2
90 exit 1
91 elif [ "$status" != "200" ]; then
92 echo "Got $status, waiting for 200..." 1>&2
93 sleep 10
94 else
95 echo "Ready!" 1>&2
96 break
97 fi
98 done
99)
100
101wait_for_deployment() ( # use a subshell so the set +x is local to the function
102 { set +x; } 2>/dev/null # make the set +x be quiet
103 # Check deployment rollout status every 10 seconds (max 10 minutes) until complete.
104 local attempts=0
105 while true; do
106 if kubectl rollout status "deployment/${2}" -n "$1" 1>&2; then
107 break
108 else
109 CRASHING="$(crashLoops ambassador)"
110 if [ -n "${CRASHING}" ]; then
111 echo "${CRASHING}" 1>&2
112 return 1
113 fi
114 fi
115
116 if [ $attempts -eq 60 ]; then
117 echo "deploy timed out" 1>&2
118 return 1
119 fi
120
121 attempts=$((attempts + 1))
122 sleep 10
123 done
124)
125
126wait_for_kubeconfig() ( # use a subshell so the set +x is local to the function
127 { set +x; } 2>/dev/null # make the set +x be quiet
128 local attempts=0
129 local kubeconfig="${1}"
130 while true; do
131 if kubectl --kubeconfig ${kubeconfig} -n default get service kubernetes; then
132 break
133 fi
134
135 if [ $attempts -eq 60 ]; then
136 echo "kubeconfig ${kubeconfig} timed out" 1>&2
137 return 1
138 fi
139 attempts=$((attempts + 1))
140 sleep 10
141 done
142)
143
144crashLoops() ( # use a subshell so the set +x is local to the function
145 { set +x; } 2>/dev/null # make the set +x be quiet
146 # shellcheck disable=SC2016
147 kubectl get pods -n "$1" -o 'go-template={{range $pod := .items}}{{range .status.containerStatuses}}{{if .state.waiting}}{{$pod.metadata.name}} {{.state.waiting.reason}}{{"\n"}}{{end}}{{end}}{{end}}' | grep CrashLoopBackOff
148)
149
150start_cluster() {
151 local kubeconfig timeout profile retries
152 kubeconfig=${1}
153 timeout=${2:-3600}
154 profile=${3:-default}
155 version=${4:-1.19}
156 retries=2
157 if [ -e "${kubeconfig}" ]; then
158 echo "cannot get cluster, kubeconfig ${kubeconfig} exists" 1>&2
159 return 1
160 fi
161 klusterurl="https://sw.bakerstreet.io/kubeception/api/klusters/ci-?generate=true&timeoutSecs=${timeout}&profile=${profile}&version=${version}"
162 printf "${BLU}Acquiring cluster with K8s version ${version}:\n==${END}\n" 1>&2
163 curl_retry $retries "200,425" "" -o "${kubeconfig}" -H "Authorization: bearer ${KUBECEPTION_TOKEN}" "${klusterurl}" -X PUT
164 ret="$?"
165 if [ "${ret}" -ne "0" ] ; then
166 echo "Unable to aquire cluster, exiting" 1>&2
167 return ${ret}
168 fi
169 cat "${kubeconfig}" 1>&2
170 printf "${BLU}==${END}\n" 1>&2
171}
172
173await_cluster() {
174 local kubeconfig name kconfurl
175 kubeconfig=${1}
176 name="$(head -1 "${kubeconfig}" | cut -c2-)"
177 kconfurl="https://sw.bakerstreet.io/kubeception/api/klusters/${name}"
178 # 100*10s == a little over 15 min. if the kluster isn't ready at that point,
179 # its probably never going ready
180 curl_retry 100 "200" "400" -o "${kubeconfig}" "$kconfurl" -H "Authorization: bearer ${KUBECEPTION_TOKEN}"
181 ret=$?
182 if [ "${ret}" -ne "0" ] ; then
183 echo "Failed waiting for cluster to come up" 1>&2
184 return $ret
185 fi
186 printf "${BLU}Cluster ${name} acquired:\n==${END}\n" 1>&2
187 cat "${kubeconfig}" 1>&2
188 printf "${BLU}==${END}\n" 1>&2
189}
190
191get_cluster() {
192 start_cluster "$@"
193 if [ "$?" != "0" ] ; then
194 return 1
195 fi
196 await_cluster "$@"
197}
198
199del_cluster() {
200 local kubeconfig name
201 kubeconfig=${1}
202 name="$(head -1 "${kubeconfig}" | cut -c2-)"
203 curl -s -H "Authorization: bearer ${KUBECEPTION_TOKEN}" "https://sw.bakerstreet.io/kubeception/api/klusters/${name}" -X DELETE
204 rm -f "${kubeconfig}"
205}
View as plain text