-
Notifications
You must be signed in to change notification settings - Fork 207
/
pre_receive.sh
234 lines (191 loc) · 8.73 KB
/
pre_receive.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
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
#!/usr/bin/env bash
#
# Author: "FRITZ Thomas" <fritztho@gmail.com> (http://www.fritzthomas.com)
# GitHub: https://gist.github.com/thomasfr/9691385
#
# The MIT License (MIT)
#
# Copyright (c) 2014-2015 FRITZ Thomas
#
# Copyright 2018 The Gitkube authors
#
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to deal
# in the Software without restriction, including without limitation the rights
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
# copies of the Software, and to permit persons to whom the Software is
# furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included in all
# copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
# SOFTWARE.
# When receiving a new git push, the received branch gets compared to this one.
# If you do not need this, just add a comment
export DEPLOY_ALLOWED_BRANCH="master"
# Repo Name:
export DEPLOY_REPO_NAME=$(basename "$PWD")
REPO_OPTS='{{REPO_OPTS}}'
MANIFEST_OPTS='{{MANIFEST_OPTS}}'
REGISTRY_PREFIX='{{REGISTRY_PREFIX}}'
export DEPLOYMENTS=$(echo ${REPO_OPTS} | jq -c 'keys' | jq -r '.[]')
# This is the root deploy dir.
export BUILD_ROOT="${HOME}/build/${DEPLOY_REPO_NAME}"
###########################################################################################
# export GIT_DIR="$(cd $(dirname $(dirname $0));pwd)"
# export GIT_WORK_TREE="${BUILD_ROOT}"
echo "Gitkube build system : $(date): Initialising"
echo
# Create the build directory
echo "Creating the build directory"
mkdir -p "${BUILD_ROOT}"
# Loop, because it is possible to push more than one branch at a time. (git push --all)
while read oldrev newrev refname
do
# export DEPLOY_BRANCH=$(git rev-parse --symbolic --abbrev-ref $refname)
export DEPLOY_BRANCH=$(expr "$refname" : "refs/heads/\(.*\)")
export DEPLOY_OLDREV="$oldrev"
export DEPLOY_NEWREV="$newrev"
export DEPLOY_REFNAME="$refname"
if [ ! -z "${DEPLOY_ALLOWED_BRANCH}" ]; then
if [ "${DEPLOY_ALLOWED_BRANCH}" != "$DEPLOY_BRANCH" ]; then
echo "Ignoring branch '$DEPLOY_BRANCH' of '${DEPLOY_REPO_NAME}'."
echo "Deployment(s) will not be updated"
continue
fi
fi
echo "Checking out '${DEPLOY_BRANCH}:${DEPLOY_NEWREV}' to '${BUILD_ROOT}'"
git archive $DEPLOY_NEWREV | tar -x -C $BUILD_ROOT
# export PRE_BUILD_HOOK="${BUILD_ROOT}/.hasura/pre-build"
#
# if [ -f $PRE_BUILD_HOOK ]; then
# echo
# echo "Executing pre-build hook"
# $PRE_BUILD_HOOK || exit 1
# fi
MANIFEST_LOC=$(echo $MANIFEST_OPTS | jq -r ".path")
if [ "$MANIFEST_LOC" != "" ]; then
echo
echo "Found manifests directory"
echo
if [ -f "$BUILD_ROOT/$MANIFEST_LOC/Chart.yaml" ]; then
echo "Found helm chart. Applying..."
HELM_OPTS=$(echo $MANIFEST_OPTS | jq -r ".helm")
HELM_RELEASE=$(echo $HELM_OPTS | jq -r ".release")
HELM_VALUES=$(echo $HELM_OPTS | jq -r ".values")
HELM_VALUES_ARGS=""
if [ "$HELM_VALUES" != "null" ]; then
for value in $(echo "$HELM_VALUES" | jq -c '.[]'); do
k=$(echo $value | jq -r '.name')
v=$(echo $value | jq -r '.value')
HELM_VALUES_ARGS="$HELM_VALUES_ARGS --set $k=$v"
done
fi
if [[ ("$HELM_RELEASE" == "") || ("$HELM_RELEASE" == "null") ]]; then
echo
echo "########"
echo "WARNING: No release name specified. Gitkube may not be able to update helm deployments"
echo "########"
echo
helm install ${HELM_VALUES_ARGS} $BUILD_ROOT/$MANIFEST_LOC/ || exit 1
else
helm upgrade ${HELM_VALUES_ARGS} ${HELM_RELEASE} $BUILD_ROOT/$MANIFEST_LOC/ --install --force || exit 1
fi
else
echo "Applying..."
kubectl apply -f $BUILD_ROOT/$MANIFEST_LOC/ || exit 1
fi
fi
echo ""
echo "$(echo $DEPLOYMENTS | wc -w) deployment(s) found in this repo"
echo "Trying to build them..."
echo ""
# Now for each deployment in this repo - build the docker images (there can
# be multiple images in one deployment), and finally update the k8s deployment
for Q_DEPLOYMENT_NAME in $DEPLOYMENTS; do # qualified deployment name
# namespace of the deployment
export K8S_NS=$(echo $Q_DEPLOYMENT_NAME | cut -d '.' -f 1)
# deployment w/o namespace from qualified deployment name
export DEPLOYMENT_NAME=$(echo $Q_DEPLOYMENT_NAME | cut -d '.' -f 2)
echo "Building Docker image for : ${DEPLOYMENT_NAME}"
DEPL_OPTS=$(echo ${REPO_OPTS} | jq -c --arg d $Q_DEPLOYMENT_NAME '.[$d]')
DOCKER_IMAGES=$(echo ${DEPL_OPTS} | jq -c 'keys' | jq -r '.[]')
# Accumulator to gather all the container names and their corresponding
# images. Used later to update a k8s deployment.
K8S_DEPL_IMAGE_SET=""
# there can be multiple images in one deployment - hence loop and build
# docker images
for IMAGE_NAME in $DOCKER_IMAGES; do
DEPL_DOCKER_CONTEXT=$(echo $DEPL_OPTS | jq -c -r --arg i $IMAGE_NAME '.[$i].path')
DEPL_DOCKER_FILE_PATH=$(echo $DEPL_OPTS | jq -c -r --arg i $IMAGE_NAME '.[$i].dockerfile')
NO_CACHE=$(echo $DEPL_OPTS | jq -c -r --arg i $IMAGE_NAME '.[$i].noCache')
RAW_BUILD_ARGS=$(echo $DEPL_OPTS | jq -c -r --arg i $IMAGE_NAME '.[$i].buildArgs')
BUILD_ARGS=""
if [ "$RAW_BUILD_ARGS" != "null" ]; then
for buildarg in $(echo "$RAW_BUILD_ARGS" | jq -c '.[]'); do
key=$(echo $buildarg | jq -r '.name')
value=$(echo $buildarg | jq -r '.value')
BUILD_ARGS="$BUILD_ARGS --build-arg $key=\"$value\""
done
fi
# If dockerfile key is not present in the config, assume default
# Dockerfile in the context path
if [ "${DEPL_DOCKER_FILE_PATH}" == "null" ]; then
DEPL_DOCKER_FILE_PATH="${DEPL_DOCKER_CONTEXT}/Dockerfile"
fi
DOCKERFILE_PATH="${BUILD_ROOT}/${DEPL_DOCKER_FILE_PATH}"
DOCKER_BUILD_CONTEXT="${BUILD_ROOT}/${DEPL_DOCKER_CONTEXT}"
export DEPLOY_IMAGE_NAME="${DEPLOY_REPO_NAME}-${Q_DEPLOYMENT_NAME}-${IMAGE_NAME}"
if [ ! -f ${DOCKERFILE_PATH} ]; then
echo "No Dockerfile present. Exiting"
exit 1
fi
echo ""
export CUR_IMAGE="${DEPLOY_IMAGE_NAME}:${DEPLOY_NEWREV}"
if [ -n "$REGISTRY_PREFIX" ]; then
export CUR_IMAGE="${REGISTRY_PREFIX}/${CUR_IMAGE}"
fi
NO_CACHE_ARGS=""
if [ "${NO_CACHE}" = "true" ]; then
NO_CACHE_ARGS="--no-cache"
fi
echo "Building Docker image : ${CUR_IMAGE}"
docker build $NO_CACHE_ARGS -t "${CUR_IMAGE}" -f "${DOCKERFILE_PATH}" $BUILD_ARGS "${DOCKER_BUILD_CONTEXT}" || exit 1
if [ -n "$REGISTRY_PREFIX" ]; then
echo "pushing ${CUR_IMAGE} to registry"
docker push "${CUR_IMAGE}" || exit 1
fi
# Keep appending "container-name=docker-image-name" in a string.
# Used later to update k8s deployment.
K8S_DEPL_IMAGE_SET="${K8S_DEPL_IMAGE_SET} ${IMAGE_NAME}=${CUR_IMAGE}"
done
echo ""
echo "Updating Kubernetes deployment: $DEPLOYMENT_NAME"
kubectl --namespace=$K8S_NS set image --record deployment/${DEPLOYMENT_NAME} ${K8S_DEPL_IMAGE_SET} || exit 1
timeout 60s kubectl --namespace=$K8S_NS rollout status deployment/${DEPLOYMENT_NAME}
if [ "$?" -ne "0" ]; then
echo ""
echo ""
echo -e "\e[31mUpdating deployment failed: $DEPLOYMENT_NAME \e[0m"
echo -e " \e[36m$ Check deployment logs \e[0m"
echo ""
echo ""
exit 1
fi
kubectl --namespace=$K8S_NS get deployment ${DEPLOYMENT_NAME} || exit 1
done
echo ""
echo "Removing build directory"
rm -rf $BUILD_ROOT
done
echo
echo "Gitkube build system : $(date): Finished build"
echo ""
echo ""
exit 0