Skip to content

Commit

Permalink
Add support for extended install/upgrade timeouts and handle failed/p…
Browse files Browse the repository at this point in the history
…ending states (#27)

* Consistently use double brackets for tests
* Consistently wrap variables in curly braces
* Eliminate unnecessary cut/cat/sed that can be done in pure bash
* Handle pending-upgrade chart status
* Add timeout support; fix whitespace
* Update build image toolchain

Signed-off-by: Brad Davidson <[email protected]>
  • Loading branch information
brandond authored Jun 8, 2021
1 parent 264e3f9 commit 8e72577
Show file tree
Hide file tree
Showing 3 changed files with 67 additions and 64 deletions.
19 changes: 4 additions & 15 deletions Dockerfile.dapper
Original file line number Diff line number Diff line change
@@ -1,28 +1,17 @@
FROM golang:1.15-alpine
FROM golang:1.16-alpine3.12

ARG DAPPER_HOST_ARCH
ENV ARCH $DAPPER_HOST_ARCH

RUN apk -U add bash git gcc musl-dev docker vim less file curl wget ca-certificates
RUN go get -d golang.org/x/lint/golint && \
git -C /go/src/golang.org/x/lint/golint checkout -b current 738671d3881b9731cc63024d5d88cf28db875626 && \
go install golang.org/x/lint/golint && \
rm -rf /go/src /go/pkg
RUN go get -d github.com/alecthomas/gometalinter && \
git -C /go/src/github.com/alecthomas/gometalinter checkout -b current v3.0.0 && \
go install github.com/alecthomas/gometalinter && \
gometalinter --install && \
rm -rf /go/src /go/pkg
RUN go get -d github.com/rancher/trash && \
git -C /go/src/github.com/rancher/trash checkout -b current v0.2.7 && \
go install github.com/rancher/trash && \
rm -rf /go/src /go/pkg
RUN if [ "$(go env GOARCH)" = "amd64" ]; then \
curl -sL https://install.goreleaser.com/github.com/golangci/golangci-lint.sh | sh -s v1.40.0; \
fi

ENV DAPPER_ENV REPO TAG DRONE_TAG
ENV DAPPER_SOURCE /go/src/github.com/k3s-io/klipper-helm/
ENV DAPPER_OUTPUT ./bin ./dist
ENV DAPPER_DOCKER_SOCKET true
ENV TRASH_CACHE ${DAPPER_SOURCE}/.trash-cache
ENV HOME ${DAPPER_SOURCE}
WORKDIR ${DAPPER_SOURCE}

Expand Down
111 changes: 62 additions & 49 deletions entry
Original file line number Diff line number Diff line change
@@ -1,128 +1,141 @@
#!/bin/bash

helm_update() {
if [ "$HELM" == "helm_v3" ]; then
LINE="$($HELM ls -f "^$NAME\$" --namespace $TARGET_NAMESPACE --output json | jq -r "$JQ_CMD" | tr '[:upper:]' '[:lower:]')"
if [[ "${HELM}" == "helm_v3" ]]; then
LINE="$(${HELM} ls --all -f "^${NAME}\$" --namespace ${TARGET_NAMESPACE} --output json | jq -r "${JQ_CMD}" | tr '[:upper:]' '[:lower:]')"
else
LINE="$($HELM ls --all "^$NAME\$" --output json | jq -r "$JQ_CMD" | tr '[:upper:]' '[:lower:]')"
LINE="$(${HELM} ls --all "^${NAME}\$" --output json | jq -r "${JQ_CMD}" | tr '[:upper:]' '[:lower:]')"
fi
INSTALLED_VERSION=$(echo $LINE | cut -f1 -d,)
STATUS=$(echo $LINE | cut -f2 -d,)
IFS=, read -r INSTALLED_VERSION STATUS _ <<<${LINE}
VALUES=""

for VALUES_FILE in /config/*.yaml; do
VALUES="$VALUES --values $VALUES_FILE"
VALUES="${VALUES} --values ${VALUES_FILE}"
done

if [ "$1" = "delete" ]; then
if [ -z "$INSTALLED_VERSION" ]; then
# Uninstall or delete chart if asked to delete and the chart was found; otherwise no-op
if [[ "$1" = "delete" ]]; then
if [[ -z "${INSTALLED_VERSION}" ]]; then
exit
fi
if [ "$HELM" == "helm_v3" ]; then
$HELM uninstall $NAME --namespace $TARGET_NAMESPACE|| true
if [[ "${HELM}" == "helm_v3" ]]; then
${HELM} uninstall ${NAME} --namespace ${TARGET_NAMESPACE} || true
else
$HELM delete $NAME || true
$HELM "$@" --purge $NAME
${HELM} delete ${NAME} || true
${HELM} "$@" --purge ${NAME}
fi
exit
fi

if [ -z "$INSTALLED_VERSION" ] && [ -z "$STATUS" ]; then
$HELM "$@" $NAME_ARG $NAME $CHART $VALUES
# No current version and status, safe to install
if [[ "${INSTALLED_VERSION}" =~ ^(|null)$ ]] && [[ "${STATUS}" =~ ^(|null)$ ]]; then
${HELM} "$@" ${NAME_ARG} ${NAME} ${CHART} ${TIMEOUT_ARG} ${VALUES}
exit
fi

# Upgrade only if the status is already deployed
if [ "$STATUS" = "deployed" ]; then
echo Already installed $NAME, upgrading
# Upgrade only if the status is already deployed, or if a previous upgrade was interrupted
if [[ "${STATUS}" =~ ^(deployed|pending-upgrade)$ ]]; then
echo Already installed ${NAME}, upgrading
shift 1
$HELM upgrade "$@" $NAME $CHART $VALUES
${HELM} upgrade "$@" ${NAME} ${CHART} ${TIMEOUT_ARG} ${VALUES}
exit
fi

if [ "$STATUS" = "failed" ] || [ "$STATUS" = "deleted" ]; then
if [ "$HELM" == "helm_v3" ]; then
$HELM uninstall $NAME --namespace $TARGET_NAMESPACE
# The chart is in a bad state; try uninstalling it first
if [[ "${STATUS}" =~ ^(deleted|failed|null|unknown)$ ]]; then
if [[ "${HELM}" == "helm_v3" ]]; then
${HELM} uninstall ${NAME} --namespace ${TARGET_NAMESPACE}
else
$HELM "$@" --purge $NAME
${HELM} "$@" --purge ${NAME}
fi
echo Deleted
$HELM "$@" $NAME_ARG $NAME $CHART $VALUES
# Try installing now that we've uninstalled
${HELM} "$@" ${NAME_ARG} ${NAME} ${CHART} ${TIMEOUT_ARG} ${VALUES}
exit
fi

$HELM "$@" $NAME_ARG $NAME $CHART $VALUES
# No special status handling necessary, do whatever we were asked to do
${HELM} "$@" ${NAME_ARG} ${NAME} ${CHART} ${TIMEOUT_ARG} ${VALUES}
}

helm_repo_init() {
# if the chart is url skip repo update
if grep -q -e "https\?://" <<< "$CHART"; then
if grep -q -e "https\?://" <<< "${CHART}"; then
echo "chart path is a url, skipping repo update"
$HELM repo remove stable || true
${HELM} repo remove stable || true
return
fi

if [ "$HELM" == "helm_v3" ]; then
if [[ $CHART == stable/* ]]; then
$HELM repo add stable $STABLE_REPO_URL
$HELM repo update
if [[ "${HELM}" == "helm_v3" ]]; then
if [[ ${CHART} == stable/* ]]; then
${HELM} repo add stable ${STABLE_REPO_URL}
${HELM} repo update
fi
else
$HELM repo update --strict || $HELM repo remove stable
${HELM} repo update --strict || ${HELM} repo remove stable
fi

if [ -n "$REPO" ]; then
$HELM repo add ${NAME%%/*} $REPO
$HELM repo update
if [[ -n "${REPO}" ]]; then
${HELM} repo add ${NAME%%/*} ${REPO}
${HELM} repo update
fi
}

helm_content_decode() {
set -e
ENC_CHART_PATH="/chart/${NAME}.tgz.base64"
CHART_PATH="/${NAME}.tgz"
if [ ! -f "${ENC_CHART_PATH}" ]; then
if [[ ! -f "${ENC_CHART_PATH}" ]]; then
return
fi
cat ${ENC_CHART_PATH} | base64 -d > ${CHART_PATH}
base64 -d ${ENC_CHART_PATH} > ${CHART_PATH}
CHART=${CHART_PATH}
set +e
}

HELM="helm_v3"
NAME_ARG=""
TIMEOUT_ARG=""
JQ_CMD='"\(.[0].app_version),\(.[0].status)"'

set -e -v
CHART=$(sed -e "s/%{KUBERNETES_API}%/${KUBERNETES_SERVICE_HOST}:${KUBERNETES_SERVICE_PORT}/g" <<< "${CHART}")
CHART="${CHART//%\{KUBERNETES_API\}%/${KUBERNETES_SERVICE_HOST}:${KUBERNETES_SERVICE_PORT}}"
set +v -x

cp /var/run/secrets/kubernetes.io/serviceaccount/ca.crt /usr/local/share/ca-certificates/
update-ca-certificates

if [ "$BOOTSTRAP" != "true" ]; then
tiller --listen=127.0.0.1:44134 --storage=secret &
export HELM_HOST=127.0.0.1:44134
if [[ "${BOOTSTRAP}" != "true" ]]; then
tiller --listen=127.0.0.1:44134 --storage=secret &
export HELM_HOST=127.0.0.1:44134

helm_v2 init --skip-refresh --client-only --stable-repo-url $STABLE_REPO_URL
EXIST=$(helm_v2 ls --all "^$NAME\$" --output json | jq -r '.Releases | length')
helm_v2 init --skip-refresh --client-only --stable-repo-url ${STABLE_REPO_URL}
V2_CHART_EXISTS=$(helm_v2 ls --all "^${NAME}\$" --output json | jq -r '.Releases | length')
fi

if [ "$EXIST" == "1" ] || [ "$HELM_VERSION" == "v2" ]; then
if [ "$BOOTSTRAP" == "true" ]; then
echo "Error: bootstrap flag can't be set with helm version 2 charts, please remove the bootstrap flag and update the chart"
exit 1
fi
if [[ "${V2_CHART_EXISTS}" == "1" ]] || [[ "${HELM_VERSION}" == "v2" ]]; then
if [[ "${BOOTSTRAP}" == "true" ]]; then
echo "Error: bootstrap flag can't be set with helm version 2 charts, please remove the bootstrap flag and update the chart"
exit 1
fi
HELM="helm_v2"
NAME_ARG="--name"
JQ_CMD='"\(.Releases[0].AppVersion),\(.Releases[0].Status)"'
fi

if [[ -n "${TIMEOUT}" ]]; then
if [[ "${HELM}" == "helm_v3" ]]; then
TIMEOUT_ARG="--timeout ${TIMEOUT}"
else
echo "Warning: timeout flag can't be set with version 2 charts, using default timeout"
fi
fi

shopt -s nullglob

helm_content_decode
if [ "$1" != "delete" ]; then
helm_repo_init
if [[ "$1" != "delete" ]]; then
helm_repo_init
fi
helm_update "$@"

1 change: 1 addition & 0 deletions package/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -12,3 +12,4 @@ COPY --from=extract /usr/bin/helm_v2 /usr/bin/helm_v3 /usr/bin/tiller /usr/bin/
COPY entry /usr/bin/
ENTRYPOINT ["entry"]
ENV STABLE_REPO_URL=https://charts.helm.sh/stable/
ENV TIMEOUT=

0 comments on commit 8e72577

Please sign in to comment.