[COMMON] Fix more and more array bashisms step 2
[oom.git] / kubernetes / helm / plugins / deploy / deploy.sh
1 #!/bin/bash
2
3 usage() {
4 cat << EOF
5 Install (or upgrade) an umbrella Helm Chart, and its subcharts, as separate Helm Releases
6
7 The umbrella Helm Chart is broken apart into a parent release and subchart releases.
8 Subcharts the are disabled (<chart>.enabled=false) will not be installed or upgraded.
9 All releases are grouped and deployed within the same namespace.
10
11
12 The deploy arguments must be a release and chart. The chart
13 argument can be either: a chart reference('stable/onap'), a path to a chart directory,
14 a packaged chart, or a fully qualified URL. For chart references, the latest
15 version will be specified unless the '--version' flag is set.
16
17 To override values in a chart, use either the '--values' flag and pass in a file
18 or use the '--set' flag and pass configuration from the command line, to force string
19 values, use '--set-string'.
20
21 You can specify the '--values'/'-f' flag multiple times. The priority will be given to the
22 last (right-most) file specified. For example, if both myvalues.yaml and override.yaml
23 contained a key called 'Test', the value set in override.yaml would take precedence:
24
25     $ helm deploy demo ./onap --namespace onap -f openstack.yaml -f overrides.yaml
26
27 You can specify the '--set' flag multiple times. The priority will be given to the
28 last (right-most) set specified. For example, if both 'bar' and 'newbar' values are
29 set for a key called 'foo', the 'newbar' value would take precedence:
30
31     $ helm deploy demo local/onap --namespace onap -f overrides.yaml --set log.enabled=false --set vid.enabled=false
32
33 Usage:
34   helm deploy [RELEASE] [CHART] [flags]
35
36 Flags:
37       --namespace string         namespace to install the release into. Defaults to the current kube config namespace.
38       --set stringArray          set values on the command line (can specify multiple or separate values with commas: key1=val1,key2=val2)
39       --set-string stringArray   set STRING values on the command line (can specify multiple or separate values with commas: key1=val1,key2=val2)
40   -f, --values valueFiles        specify values in a YAML file or a URL(can specify multiple) (default [])
41       --verbose                  enables full helm install/upgrade output during deploy
42       --set-last-applied         set the last-applied-configuration annotation on all objects.This annotation is required to restore services using Ark/Veloro backup restore.
43 EOF
44 }
45
46 generate_overrides() {
47   SUBCHART_NAMES=($(cat $COMPUTED_OVERRIDES | grep -v '^\s\s'))
48
49   for index in "${!SUBCHART_NAMES[@]}"; do
50     START=${SUBCHART_NAMES[index]}
51     END=${SUBCHART_NAMES[index+1]}
52     if [ "$START" = "global:" ]; then
53       echo "global:" > $GLOBAL_OVERRIDES
54       cat $COMPUTED_OVERRIDES | sed '/common:/,/consul:/d' \
55         | sed -n '/^'"$START"'/,/'log:'/p' | sed '1d;$d' >> $GLOBAL_OVERRIDES
56     else
57       SUBCHART_DIR="$CACHE_SUBCHART_DIR/$(echo "$START" |cut -d':' -f1)"
58       if [ -d "$SUBCHART_DIR" ]; then
59         if [ -z "$END" ]; then
60           cat $COMPUTED_OVERRIDES | sed -n '/^'"$START"'/,/'"$END"'/p' \
61             | sed '1d;$d' | cut -c3- > $SUBCHART_DIR/subchart-overrides.yaml
62         else
63           cat $COMPUTED_OVERRIDES | sed -n '/^'"$START"'/,/^'"$END"'/p' \
64             | sed '1d;$d' | cut -c3- > $SUBCHART_DIR/subchart-overrides.yaml
65         fi
66       fi
67     fi
68   done
69 }
70
71
72 resolve_deploy_flags() {
73   skip="false"
74   for param in $1; do
75     if [ "$skip" = "false" ]; then
76       if [ "$param" = "-f" ] || \
77          [ "$param" = "--values" ] || \
78          [ "$param" = "--set" ] || \
79          [ "$param" = "--set-string" ] || \
80          [ "$param" = "--version" ]; then
81         skip="true"
82       else
83         DEPLOY_FLAGS="$DEPLOY_FLAGS $param"
84       fi
85     else
86       skip="false"
87     fi
88   done
89   echo "$DEPLOY_FLAGS"
90 }
91
92
93 check_for_dep() {
94     try=0
95     retries=60
96     until (kubectl get deployment -n $HELM_NAMESPACE | grep -P "\b$1\b") >/dev/null 2>&1; do
97         try=$(($try + 1))
98         [ $try -gt $retries ] && exit 1
99         echo "$1 not found. Retry $try/$retries"
100         sleep 10
101     done
102     echo "$1 found. Waiting for pod intialisation"
103     sleep 15
104 }
105
106 deploy_strimzi() {
107   #Deploy the srtimzi-kafka chart in advance. Dependent charts require the entity-operator
108   #for management of the strimzi crds
109   deploy_subchart
110   echo "waiting for ${RELEASE}-strimzi-entity-operator to be deployed"
111   check_for_dep ${RELEASE}-strimzi-entity-operator
112 }
113
114 deploy_subchart() {
115   if [ -z "$SUBCHART_RELEASE" ] || [ "$SUBCHART_RELEASE" = "$subchart" ]; then
116         LOG_FILE=$LOG_DIR/"${RELEASE}-${subchart}".log
117         :> $LOG_FILE
118
119         helm upgrade -i "${RELEASE}-${subchart}" $CACHE_SUBCHART_DIR/$subchart \
120          $DEPLOY_FLAGS -f $GLOBAL_OVERRIDES -f $SUBCHART_OVERRIDES \
121          > $LOG_FILE 2>&1
122
123         if [ "$VERBOSE" = "true" ]; then
124           cat $LOG_FILE
125         else
126           echo "release \"${RELEASE}-${subchart}\" deployed"
127         fi
128         # Add annotation last-applied-configuration if set-last-applied flag is set
129         if [ "$SET_LAST_APPLIED" = "true" ]; then
130           helm get manifest "${RELEASE}-${subchart}" \
131           | kubectl apply set-last-applied --create-annotation -n $HELM_NAMESPACE -f - \
132           > $LOG_FILE.log 2>&1
133         fi
134       fi
135       if [ "$DELAY" = "true" ]; then
136         echo sleep 3m
137         sleep 180
138       fi
139 }
140
141 deploy() {
142   # validate params
143   if [ -z "$1" ] || [ -z "$2" ]; then
144     usage
145     exit 1
146   fi
147
148   RELEASE=$1
149   CHART_URL=$2
150   FLAGS=$(echo ${@} | sed 's/^ *[^ ]* *[^ ]* *//')
151   CHART_REPO="$(echo "$CHART_URL" | cut -d'/' -f1)"
152   CHART_NAME="$(echo "$CHART_URL" | cut -d'/' -f2)"
153
154   CACHE_DIR=~/.local/share/helm/plugins/deploy/cache
155   echo "Use cache dir: $CACHE_DIR"
156   CHART_DIR=$CACHE_DIR/$CHART_NAME
157   CACHE_SUBCHART_DIR=$CHART_DIR-subcharts
158   LOG_DIR=$CHART_DIR/logs
159
160   # determine if verbose output is enabled
161   VERBOSE="false"
162   if expr "$FLAGS" : ".*--verbose.*" ; then
163     FLAGS="$(echo $FLAGS| sed -n 's/--verbose//p')"
164     VERBOSE="true"
165   fi
166   # determine if delay for deployment is enabled
167   DELAY="false"
168   if expr "$FLAGS" : ".*--delay.*" ; then
169     FLAGS="$(echo $FLAGS| sed -n 's/--delay//p')"
170     DELAY="true"
171   fi
172   # determine if set-last-applied flag is enabled
173   SET_LAST_APPLIED="false"
174   if expr "$FLAGS" : ".*--set-last-applied.*" ; then
175     FLAGS="$(echo $FLAGS| sed -n 's/--set-last-applied//p')"
176     SET_LAST_APPLIED="true"
177   fi
178   if expr "$FLAGS" : ".*--dry-run.*" ; then
179     VERBOSE="true"
180     FLAGS="$FLAGS --debug"
181   fi
182
183   # should pass all flags instead
184   NAMESPACE="$(echo $FLAGS | sed -n 's/.*\(namespace\).\s*/\1/p' | cut -c10- | cut -d' ' -f1)"
185
186   VERSION="$(echo $FLAGS | sed -n 's/.*\(version\).\s*/\1/p' | cut -c8- | cut -d' ' -f1)"
187
188   if [ ! -z $VERSION ]; then
189      VERSION="--version $VERSION"
190   fi
191
192   # Remove all override values passed in as arguments. These will be used during dry run
193   # to resolve computed override values. Remaining flags will be passed on during
194   # actual upgrade/install of parent and subcharts.
195   DEPLOY_FLAGS=$(resolve_deploy_flags "$FLAGS")
196
197   # determine if upgrading individual subchart or entire parent + subcharts
198   SUBCHART_RELEASE="$(echo "$RELEASE" |cut -d'-' -f2)"
199   # update specified subchart without parent
200   RELEASE="$(echo "$RELEASE" |cut -d'-' -f1)"
201   if [ "$SUBCHART_RELEASE" = "$RELEASE" ]; then
202     SUBCHART_RELEASE=
203   fi
204
205   # clear previously cached charts
206   rm -rf $CACHE_DIR
207
208   # fetch umbrella chart (parent chart containing subcharts)
209   if [ -d "$CHART_URL" ]; then
210     mkdir -p $CHART_DIR
211     cp -R $CHART_URL/* $CHART_DIR/
212
213     charts=$CHART_DIR/charts/*
214     for subchart in $charts ; do
215       tar xzf ${subchart} -C $CHART_DIR/charts/
216     done
217     rm -rf $CHART_DIR/charts/*.tgz
218   else
219     echo "fetching $CHART_URL"
220     helm fetch $CHART_URL --untar --untardir $CACHE_DIR $VERSION
221   fi
222
223   # create log driectory
224   mkdir -p $LOG_DIR
225
226   # move out subcharts to process separately
227   mkdir -p $CACHE_SUBCHART_DIR
228   mv $CHART_DIR/charts/* $CACHE_SUBCHART_DIR/
229   # temp hack - parent chart needs common subchart
230   mv $CACHE_SUBCHART_DIR/common $CHART_DIR/charts/
231
232  # disable dependencies
233   rm $CHART_DIR/Chart.lock
234   sed -n '1,/dependencies:/p;/description:/,$p' $CHART_DIR/Chart.yaml | grep -v dependencies > $CHART_DIR/deploy_Chart.yaml
235   mv $CHART_DIR/Chart.yaml $CHART_DIR/Chart.deploy
236   mv $CHART_DIR/deploy_Chart.yaml $CHART_DIR/Chart.yaml
237
238   # compute overrides for parent and all subcharts
239   COMPUTED_OVERRIDES=$CACHE_DIR/$CHART_NAME/computed-overrides.yaml
240   helm upgrade -i $RELEASE $CHART_DIR $FLAGS --dry-run --debug \
241    | sed -n '/COMPUTED VALUES:/,/HOOKS:/p' | sed '1d;$d' > $COMPUTED_OVERRIDES
242
243   # extract global overrides to apply to parent and all subcharts
244   GLOBAL_OVERRIDES=$CHART_DIR/global-overrides.yaml
245   generate_overrides $COMPUTED_OVERRIDES $GLOBAL_OVERRIDES
246
247   # upgrade/install parent chart first
248   if [ -z "$SUBCHART_RELEASE" ]; then
249     LOG_FILE=$LOG_DIR/${RELEASE}.log
250     :> $LOG_FILE
251
252     helm upgrade -i $RELEASE $CHART_DIR $DEPLOY_FLAGS -f $COMPUTED_OVERRIDES \
253      > $LOG_FILE.log 2>&1
254
255     if [ "$VERBOSE" = "true" ]; then
256       cat $LOG_FILE
257     else
258       echo "release \"$RELEASE\" deployed"
259     fi
260     # Add annotation last-applied-configuration if set-last-applied flag is set
261     if [ "$SET_LAST_APPLIED" = "true" ]; then
262       helm get manifest ${RELEASE} \
263       | kubectl apply set-last-applied --create-annotation -n $HELM_NAMESPACE -f - \
264       > $LOG_FILE.log 2>&1
265     fi
266   fi
267
268   # upgrade/install each "enabled" subchart
269   cd $CACHE_SUBCHART_DIR/
270   #“helm ls” is an expensive command in that it can take a long time to execute.
271   #So cache the results to prevent repeated execution.
272   ALL_HELM_RELEASES=$(helm ls -q)
273
274     for subchart in strimzi cassandra mariadb-galera postgres ; do
275       SUBCHART_OVERRIDES=$CACHE_SUBCHART_DIR/$subchart/subchart-overrides.yaml
276
277       SUBCHART_ENABLED=0
278       if [ -f $SUBCHART_OVERRIDES ]; then
279         SUBCHART_ENABLED=$(cat $SUBCHART_OVERRIDES | grep -c "^enabled: true")
280       fi
281       if [ "${subchart}" = "strimzi" ] && [ $SUBCHART_ENABLED -eq 1 ]; then
282         deploy_strimzi
283       fi
284       # Deploy them at first
285       if [ $SUBCHART_ENABLED -eq 1 ]; then
286         deploy_subchart
287       else
288         reverse_list=
289         for item in $(echo "$ALL_HELM_RELEASES" | grep "${RELEASE}-${subchart}")
290         do
291           reverse_list="$item $reverse_list"
292         done
293         for item in $reverse_list
294         do
295           helm del $item
296         done
297       fi
298     done
299
300
301     for subchart in * ; do
302       SUBCHART_OVERRIDES=$CACHE_SUBCHART_DIR/$subchart/subchart-overrides.yaml
303
304       SUBCHART_ENABLED=0
305       if [ -f $SUBCHART_OVERRIDES ]; then
306         SUBCHART_ENABLED=$(cat $SUBCHART_OVERRIDES | grep -c "^enabled: true")
307       fi
308       if [ "${subchart}" = "strimzi" ] || [ "${subchart}" = "cassandra" ] || [ "${subchart}" = "mariadb-galera" ] || [ "${subchart}" = "postgres" ]; then
309         SUBCHART_ENABLED=0
310       fi
311       # Deploy the others
312       if [ $SUBCHART_ENABLED -eq 1 ]; then
313         deploy_subchart
314       else
315         reverse_list=
316         for item in $(echo "$ALL_HELM_RELEASES" | grep "${RELEASE}-${subchart}")
317         do
318           reverse_list="$item $reverse_list"
319         done
320         for item in $reverse_list
321         do
322           helm del $item
323         done
324       fi
325     done
326
327   # report on success/failures of installs/upgrades
328   helm ls --all-namespaces | grep -i FAILED | grep $RELEASE
329 }
330 HELM_VER=$(helm version --template "{{.Version}}")
331 echo $HELM_VER
332
333 case "${1:-"help"}" in
334   "help")
335     usage
336     ;;
337   "--help")
338     usage
339     ;;
340   "-h")
341     usage
342     ;;
343   *)
344     deploy $1 $2 $(echo ${@} | sed 's/^ *[^ ]* *[^ ]* *//')
345     ;;
346 esac
347
348 exit 0