Increase helm deploy perf by reducing helm ls
[oom.git] / kubernetes / helm / plugins / deploy / deploy.sh
index 07455d7..3416a02 100755 (executable)
@@ -38,25 +38,11 @@ Flags:
       --set stringArray          set values on the command line (can specify multiple or separate values with commas: key1=val1,key2=val2)
       --set-string stringArray   set STRING values on the command line (can specify multiple or separate values with commas: key1=val1,key2=val2)
   -f, --values valueFiles        specify values in a YAML file or a URL(can specify multiple) (default [])
+      --verbose                  enables full helm install/upgrade output during deploy
+      --set-last-applied         set the last-applied-configuration annotation on all objects.This annotation is required to restore services using Ark/Veloro backup restore.
 EOF
 }
 
-parse_yaml() {
-  local prefix=$2
-  local s='[[:space:]]*' w='[a-zA-Z0-9_]*' fs=$(echo @|tr @ '\034')
-  sed -ne "s|^\($s\)\($w\)$s:$s\"\(.*\)\"$s\$|\1$fs\2$fs\3|p" \
-       -e "s|^\($s\)\($w\)$s:$s\(.*\)$s\$|\1$fs\2$fs\3|p"  $1 |
-  awk -F$fs '{
-     indent = length($1)/2;
-     vname[indent] = $2;
-     for (i in vname) {if (i > indent) {delete vname[i]}}
-     if (length($3) > 0) {
-        vn=""; for (i=0; i<indent; i++) {vn=(vn)(vname[i])("_")}
-        printf("%s%s%s=\"%s\"\n", "'$prefix'",vn, $2, $3);
-     }
-  }'
-}
-
 generate_overrides() {
   SUBCHART_NAMES=($(cat $COMPUTED_OVERRIDES | grep -v '^\s\s'))
 
@@ -66,18 +52,47 @@ generate_overrides() {
     if [[ $START == "global:" ]]; then
       echo "global:" > $GLOBAL_OVERRIDES
       cat $COMPUTED_OVERRIDES | sed '/common:/,/consul:/d' \
-        | sed -n '/'"$START"'/,/'log:'/p' | sed '1d;$d' >> $GLOBAL_OVERRIDES  
+        | sed -n '/^'"$START"'/,/'log:'/p' | sed '1d;$d' >> $GLOBAL_OVERRIDES
     else
       SUBCHART_DIR="$CACHE_SUBCHART_DIR/$(cut -d':' -f1 <<<"$START")"
       if [[ -d "$SUBCHART_DIR" ]]; then
-        cat $COMPUTED_OVERRIDES | sed -n '/'"$START"'/,/'"$END"'/p' \
-          | sed '1d;$d' | cut -c3- > $SUBCHART_DIR/subchart-overrides.yaml
+        if [[ -z "$END" ]]; then
+          cat $COMPUTED_OVERRIDES | sed -n '/^'"$START"'/,/'"$END"'/p' \
+            | sed '1d;$d' | cut -c3- > $SUBCHART_DIR/subchart-overrides.yaml
+        else
+          cat $COMPUTED_OVERRIDES | sed -n '/^'"$START"'/,/^'"$END"'/p' \
+            | sed '1d;$d' | cut -c3- > $SUBCHART_DIR/subchart-overrides.yaml
+        fi
       fi
     fi
   done
 }
+resolve_deploy_flags() {
+  flags=($1)
+  n=${#flags[*]}
+  for (( i = 0; i < n; i++ )); do
+    PARAM=${flags[i]}
+    if [[ $PARAM == "-f" || \
+          $PARAM == "--values" || \
+          $PARAM == "--set" || \
+          $PARAM == "--set-string" || \
+          $PARAM == "--version" ]]; then
+       # skip param and its value
+       i=$((i + 1))
+    else
+      DEPLOY_FLAGS="$DEPLOY_FLAGS $PARAM"
+    fi
+  done
+  echo "$DEPLOY_FLAGS"
+}
 
 deploy() {
+  # validate params
+  if [[ -z "$1" || -z "$2" ]]; then
+    usage
+    exit 0
+  fi
+
   RELEASE=$1
   CHART_URL=$2
   FLAGS=${@:3}
@@ -86,24 +101,67 @@ deploy() {
   CACHE_DIR=~/.helm/plugins/deploy/cache
   CHART_DIR=$CACHE_DIR/$CHART_NAME
   CACHE_SUBCHART_DIR=$CHART_DIR-subcharts
+  LOG_DIR=$CHART_DIR/logs
+
+  # determine if verbose output is enabled
+  VERBOSE="false"
+  if [[ $FLAGS = *"--verbose"* ]]; then
+    FLAGS="$(echo $FLAGS| sed -n 's/--verbose//p')"
+    VERBOSE="true"
+  fi
+  # determine if set-last-applied flag is enabled
+  SET_LAST_APPLIED="false"
+  if [[ $FLAGS = *"--set-last-applied"* ]]; then
+    FLAGS="$(echo $FLAGS| sed -n 's/--set-last-applied//p')"
+    SET_LAST_APPLIED="true"
+  fi
+  if [[ $FLAGS = *"--dry-run"* ]]; then
+    VERBOSE="true"
+    FLAGS="$FLAGS --debug"
+  fi
+
   # should pass all flags instead
-  NAMESPACE="$(echo $FLAGS | sed -n 's/.*\(namespace\).\s*/\1/p' | cut -c10-)"
+  NAMESPACE="$(echo $FLAGS | sed -n 's/.*\(namespace\).\s*/\1/p' | cut -c10- | cut -d' ' -f1)"
+
+  VERSION="$(echo $FLAGS | sed -n 's/.*\(version\).\s*/\1/p' | cut -c8- | cut -d' ' -f1)"
+
+  if [ ! -z $VERSION ]; then
+     VERSION="--version $VERSION"
+  fi
+
+  # Remove all override values passed in as arguments. These will be used during dry run
+  # to resolve computed override values. Remaining flags will be passed on during
+  # actual upgrade/install of parent and subcharts.
+  DEPLOY_FLAGS=$(resolve_deploy_flags "$FLAGS")
+
+ # determine if upgrading individual subchart or entire parent + subcharts
+  SUBCHART_RELEASE="$(cut -d'-' -f2 <<<"$RELEASE")"
+  if [[ ! -d "$CACHE_SUBCHART_DIR/$SUBCHART_RELEASE" ]]; then
+    SUBCHART_RELEASE=
+  else
+    # update specified subchart without parent
+    RELEASE="$(cut -d'-' -f1 <<<"$RELEASE")"
+  fi
+
   # clear previously cached charts
   rm -rf $CACHE_DIR
 
+  # create log driectory
+  mkdir -p $LOG_DIR
+
   # fetch umbrella chart (parent chart containing subcharts)
   if [[ -d "$CHART_URL" ]]; then
     mkdir -p $CHART_DIR
     cp -R $CHART_URL/* $CHART_DIR/
 
-    cd $CHART_DIR/charts/
-    for subchart in * ; do
-      tar xzf ${subchart}
+    charts=$CHART_DIR/charts/*
+    for subchart in $charts ; do
+      tar xzf ${subchart} -C $CHART_DIR/charts/
     done
-    rm -rf *.tgz
+    rm -rf $CHART_DIR/charts/*.tgz
   else
-    helm fetch $CHART_URL --untar --untardir $CACHE_DIR
+    echo "fetching $CHART_URL"
+    helm fetch $CHART_URL --untar --untardir $CACHE_DIR $VERSION
   fi
 
   # move out subcharts to process separately
@@ -126,29 +184,72 @@ deploy() {
   generate_overrides $COMPUTED_OVERRIDES $GLOBAL_OVERRIDES
 
   # upgrade/install parent chart first
-  helm upgrade -i $RELEASE $CHART_DIR --namespace $NAMESPACE -f $COMPUTED_OVERRIDES
+  if [[ -z "$SUBCHART_RELEASE" ]]; then
+    LOG_FILE=$LOG_DIR/${RELEASE}.log
+    :> $LOG_FILE
+
+    helm upgrade -i $RELEASE $CHART_DIR $DEPLOY_FLAGS -f $COMPUTED_OVERRIDES \
+     > $LOG_FILE.log 2>&1
 
-  # parse computed overrides - will use to determine if a subchart is "enabled"
-  eval $(parse_yaml $COMPUTED_OVERRIDES "computed_")
+    if [[ $VERBOSE == "true" ]]; then
+      cat $LOG_FILE
+    else
+      echo "release \"$RELEASE\" deployed"
+    fi
+    # Add annotation last-applied-configuration if set-last-applied flag is set
+    if [[ $SET_LAST_APPLIED == "true" ]]; then
+      helm get manifest ${RELEASE} \
+      | kubectl apply set-last-applied --create-annotation -n onap -f - \
+      > $LOG_FILE.log 2>&1
+    fi
+  fi
 
   # upgrade/install each "enabled" subchart
-  cd $CACHE_SUBCHART_DIR
+  cd $CACHE_SUBCHART_DIR/
+  #“helm ls” is an expensive command in that it can take a long time to execute.
+  #So cache the results to prevent repeated execution.
+  ALL_HELM_RELEASES=$(helm ls -q)
   for subchart in * ; do
-    VAR="computed_${subchart}_enabled"
-    COMMAND="$"$VAR
-    eval "SUBCHART_ENABLED=$COMMAND"
-    if [[ $SUBCHART_ENABLED == "true" ]]; then
-      SUBCHART_OVERRIDES=$CACHE_SUBCHART_DIR/$subchart/subchart-overrides.yaml
-      helm upgrade -i "${RELEASE}-${subchart}" $CACHE_SUBCHART_DIR/$subchart \
-       --namespace $NAMESPACE -f $GLOBAL_OVERRIDES -f $SUBCHART_OVERRIDES
+    SUBCHART_OVERRIDES=$CACHE_SUBCHART_DIR/$subchart/subchart-overrides.yaml
+
+    SUBCHART_ENABLED=0
+    if [[ -f $SUBCHART_OVERRIDES ]]; then
+      SUBCHART_ENABLED=$(cat $SUBCHART_OVERRIDES | grep -c "^enabled: true")
+    fi
+
+    if [[ $SUBCHART_ENABLED -eq 1 ]]; then
+      if [[ -z "$SUBCHART_RELEASE" || $SUBCHART_RELEASE == "$subchart" ]]; then
+        LOG_FILE=$LOG_DIR/"${RELEASE}-${subchart}".log
+        :> $LOG_FILE
+
+        helm upgrade -i "${RELEASE}-${subchart}" $CACHE_SUBCHART_DIR/$subchart \
+         $DEPLOY_FLAGS -f $GLOBAL_OVERRIDES -f $SUBCHART_OVERRIDES \
+         > $LOG_FILE 2>&1
+
+        if [[ $VERBOSE == "true" ]]; then
+          cat $LOG_FILE
+        else
+          echo "release \"${RELEASE}-${subchart}\" deployed"
+        fi
+       # Add annotation last-applied-configuration if set-last-applied flag is set
+        if [[ $SET_LAST_APPLIED == "true" ]]; then
+          helm get manifest "${RELEASE}-${subchart}" \
+          | kubectl apply set-last-applied --create-annotation -n onap -f - \
+             > $LOG_FILE.log 2>&1
+        fi
+      fi
+    else
+      array=($(echo "$ALL_HELM_RELEASES" | grep "${RELEASE}-${subchart}"))
+      n=${#array[*]}
+      for (( i = n-1; i >= 0; i-- )); do
+        helm del "${array[i]}" --purge
+      done
     fi
   done
-}
 
-if [[ $# < 2 ]]; then
-  usage
-  exit 0
-fi
+  # report on success/failures of installs/upgrades
+  helm ls | grep FAILED | grep $RELEASE
+}
 
 case "${1:-"help"}" in
   "help")
@@ -165,4 +266,4 @@ case "${1:-"help"}" in
     ;;
 esac
 
-exit 0
\ No newline at end of file
+exit 0