-
Notifications
You must be signed in to change notification settings - Fork 106
/
Copy pathcreate.sh
executable file
·189 lines (162 loc) · 5.98 KB
/
create.sh
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
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
#!/usr/bin/env bash
# Copyright 2018 Google LLC
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# https://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
# Stop immediately if something goes wrong
set -euo pipefail
run_terraform() {
# # Terraform steps:
# TFVARS_FILE="${ROOT}/terraform/terraform.tfvars"
#
# # Remove a pre-existing tfvars file, if it exists
# if [[ -f "${TFVARS_FILE}" ]]
# then
# rm ${TFVARS_FILE}
# fi
# shellcheck source=scripts/generate-tfvars.sh
source "${ROOT}/scripts/generate-tfvars.sh"
VERSION=$(cat "${ROOT}/VERSION")
(cd "$ROOT/terraform"; terraform init -input=false)
(cd "$ROOT/terraform"; terraform apply -input=false -auto-approve \
-var ver="$VERSION")
}
generate_static_ip() {
# Check to make sure static IP hasn't already been created, then register it.
if [[ $(gcloud compute addresses list | grep '^NAME:\sprime-server') = '' ]]; then
gcloud compute addresses create prime-server --global
fi
}
wait_for_cluster() {
# Provisioning a Kubernetes Engine ingress can take some time as a Layer 7
# http load balancer must be configured. This script will check and loop-retry
# getting the external ip address associated with the load balancer then check
# and loop-retry waiting for the endpoint to become healthy.
echo "===================================================="
echo "Initializing the test application. Please be patient, it takes a few\
minutes to complete."
echo "===================================================="
# The outer loop checks for the external IP address associated with the
# HTTP load balancer created by the Kubernetes Engine prime-server ingress. It
# should be created relatively quickly so the loop sleeps for 10 seconds and
# error times out after 100 seconds.
ELAPSED=0
SLEEP=10
MAX_TIME=100
while true; do
IP_ADDRESS=$(kubectl get ingress prime-server --namespace \
default -o jsonpath='{.status.loadBalancer.ingress..ip}')
if [[ -n "$IP_ADDRESS" ]]; then
SERVER_ADDRESS="http://${IP_ADDRESS}"
echo "$SERVER_ADDRESS provisioned!"
# This inner loop is to wait for the server to respond to a health check.
# This can take much longer so we animate the cursor to ensure that the
# user can see that the script has not timed out. We do not have an error
# timeout for acquiring a health check because sometimes this step takes
# unusually long.
while true; do
echo -ne 'waiting for endpoint to become healthy: |\r'
sleep 1
echo -ne 'waiting for endpoint to become healthy: /\r'
sleep 1
echo -ne 'waiting for endpoint to become healthy: -\r'
sleep 1
echo -ne 'waiting for endpoint to become healthy: \\\r'
sleep 1
if [[ "$(curl -s -o /dev/null -w "%{http_code}" "$SERVER_ADDRESS"/)" == \
"200" ]]; then
break
fi
done
echo ""
echo "SUCCESS! $SERVER_ADDRESS is now healthy"
break
fi
if [[ "${ELAPSED}" -gt "${MAX_TIME}" ]]; then
echo "ERROR: ${MAX_TIME} seconds exceeded, no response from kubernetes api."
exit 1
fi
echo "After ${ELAPSED} seconds, endpoint not yet provisioned, waiting..."
sleep "$SLEEP"
ELAPSED=$(( ELAPSED + SLEEP ))
done
}
wait_for_service() {
echo "** Checking for Kubernetes service **"
RESPONSE=""
EXPECTED="Server successfully started!"
COUNTER=0
for _ in {1..60}
do
# An ingress is created that has two backends, they do not become healthy
# at once, and some subsequent calls lead to 404. We want to check service
# endpoint to respond and stop giving 404 at least 20 times.
echo -ne 'waiting for endpoint to become healthy: |\r'
sleep 1
echo -ne 'waiting for endpoint to become healthy: /\r'
sleep 1
echo -ne 'waiting for endpoint to become healthy: -\r'
sleep 1
echo -ne 'waiting for endpoint to become healthy: \\\r'
sleep 1
if [[ "$(curl -s -o /dev/null -w "%{http_code}" "$IP_ADDRESS"/)" == \
"200" ]]; then
COUNTER=$((COUNTER+1))
if [ "$COUNTER" == 10 ]; then
break
fi
else
COUNTER=0 # Our counter needs to be reset until we get only 200's for 20
# consecutive times
fi
done
RESPONSE=$(curl -s "$IP_ADDRESS/")
if [ "$RESPONSE" != "$EXPECTED" ]
then
echo "ERROR - Service failed to start correctly within allotted time"
echo "=> $RESPONSE"
exit 1
fi
echo "** Kubernetes service is up! ** "
}
run_build() {
[ -d "${ROOT}/build" ] || mkdir "${ROOT}/build"
tar -cvzf "$ROOT/build/flask-prime.tgz" -C "$ROOT/container" .
# Cloud Build!
BUILD_DATE=$(date)
if command -v git >/dev/null; then
VCS_REF=$(git rev-parse HEAD)
else
VCS_REF="NO-VCS"
fi
echo "Building container for prime-server version ${VERSION}"
gcloud builds submit "$ROOT/container" \
--config="${ROOT}/container/cloudbuild.yaml" \
--substitutions _VERSION="${VERSION}",_BUILD_DATE="${BUILD_DATE}",_VCS_REF="${VCS_REF}"
}
ROOT="$( cd "$( dirname "${BASH_SOURCE[0]}" )/.." && pwd )"
# shellcheck source=scripts/common.sh
source "$ROOT/scripts/common.sh"
VERSION=$(cat "${ROOT}/VERSION")
check_dependency_installed gcloud
check_dependency_installed terraform
# Enable required GCP services
get_project
enable_project_api "${PROJECT}" compute.googleapis.com
enable_project_api "${PROJECT}" container.googleapis.com
enable_project_api "${PROJECT}" cloudbuild.googleapis.com
run_build
run_terraform
generate_static_ip
kubectl apply -f "${ROOT}/terraform/manifests/" --namespace default
wait_for_cluster
wait_for_service