From 7461ace5d7d6ebbd19948077854fb32d7831392c Mon Sep 17 00:00:00 2001 From: Simon Emms Date: Thu, 18 Aug 2022 11:08:45 +0000 Subject: [PATCH 1/2] [installer]: move the kots install script into a bash file in Installer --- install/installer/BUILD.yaml | 3 + install/installer/leeway.Dockerfile | 1 + install/installer/scripts/kots-install.sh | 345 ++++++++++++++++++ .../kots/manifests/gitpod-config-patch.yaml | 2 + .../gitpod-custom-registry-credentials.yaml | 12 + .../manifests/gitpod-installation-status.yaml | 2 +- .../kots/manifests/gitpod-installer-job.yaml | 345 +----------------- .../kots/manifests/gitpod-kots-config.yaml | 60 +++ .../manifests/gitpod-registry-secret.yaml | 12 + 9 files changed, 443 insertions(+), 339 deletions(-) create mode 100755 install/installer/scripts/kots-install.sh create mode 100644 install/kots/manifests/gitpod-custom-registry-credentials.yaml create mode 100644 install/kots/manifests/gitpod-kots-config.yaml create mode 100644 install/kots/manifests/gitpod-registry-secret.yaml diff --git a/install/installer/BUILD.yaml b/install/installer/BUILD.yaml index 1a1aaca4bbef88..af492994b4d8f9 100644 --- a/install/installer/BUILD.yaml +++ b/install/installer/BUILD.yaml @@ -12,6 +12,7 @@ packages: - "pkg/components/**/*.key" - "pkg/components/**/*.pem" - "pkg/components/**/*.sql" + - "scripts/*.sh" - "third_party/**/*" deps: - components/blobserve:lib @@ -51,6 +52,8 @@ packages: - ["objcopy", "--add-section", "versionManifest=components--all-docker/versions.yaml", "install-installer--raw-app/installer", "installer"] - name: docker type: docker + srcs: + - "scripts/*.sh" deps: - :app argdeps: diff --git a/install/installer/leeway.Dockerfile b/install/installer/leeway.Dockerfile index 0e398efc762bb3..0c82e168ecb93f 100644 --- a/install/installer/leeway.Dockerfile +++ b/install/installer/leeway.Dockerfile @@ -5,6 +5,7 @@ FROM alpine:3.16 COPY --from=alpine/helm:3.8.0 /usr/bin/helm /usr/bin/helm COPY install-installer--app/installer install-installer--app/provenance-bundle.jsonl /app/ +COPY scripts/*.sh /app/scripts/ RUN apk add --no-cache curl jq openssh-keygen yq \ && curl -L "https://dl.k8s.io/release/$(curl -L -s https://dl.k8s.io/release/stable.txt)/bin/linux/amd64/kubectl" -o /usr/local/bin/kubectl \ && chmod +x /usr/local/bin/kubectl diff --git a/install/installer/scripts/kots-install.sh b/install/installer/scripts/kots-install.sh new file mode 100755 index 00000000000000..88b3a68647c6fb --- /dev/null +++ b/install/installer/scripts/kots-install.sh @@ -0,0 +1,345 @@ +#!/bin/sh +# Copyright (c) 2022 Gitpod GmbH. All rights reserved. +# Licensed under the MIT License. See License-MIT.txt in the project root for license information. + +# shellcheck disable=SC2050,SC2153 + +set -e + +echo "Gitpod: Killing any in-progress installations" + +kubectl delete jobs.batch -n "${NAMESPACE}" -l component="gitpod-installer,cursor!=${CURSOR}" --force --grace-period 0 || true +kubectl delete pod -n "${NAMESPACE}" -l component="gitpod-installer,cursor!=${CURSOR}" --force --grace-period 0 || true + +if [ "$(helm status -n "${NAMESPACE}" gitpod -o json | jq '.info.status == "deployed"')" = "false" ]; +then + echo "Gitpod: Deployment in-progress - clearing" + + VERSION="$(helm status -n "${NAMESPACE}" gitpod -o json | jq '.version')" + if [ "${VERSION}" -le 1 ]; + then + echo "Gitpod: Uninstall application" + helm uninstall -n "${NAMESPACE}" gitpod --wait || true + else + echo "Gitpod: Rolling back application" + helm rollback -n "${NAMESPACE}" gitpod --wait || true + fi +fi + +echo "Gitpod: Create a Helm template directory" +rm -Rf "${GITPOD_OBJECTS}" +mkdir -p "${GITPOD_OBJECTS}/templates" +cat <> "${GITPOD_OBJECTS}/Chart.yaml" +apiVersion: v2 +name: gitpod-kots +description: Always ready-to-code +version: "1.0.0" +appVersion: "$(/app/installer version | yq e '.version' -)" +EOF + +echo "Gitpod: Generate the base Installer config" +/app/installer init > "${CONFIG_FILE}" + +echo "Gitpod: auto-detecting ShiftFS support on host machine" +kubectl wait job -n "${NAMESPACE}" --for=condition=complete -l component=shiftfs-module-loader --timeout=30s || true +ENABLE_SHIFTFS=$(kubectl get jobs.batch -n "${NAMESPACE}" -l component=shiftfs-module-loader -o jsonpath='{.items[0].status.succeeded}') + +if [ "${ENABLE_SHIFTFS}" = "1" ]; then + echo "Gitpod: enabling ShiftFS support" + + yq e -i '.workspace.runtime.fsShiftMethod = "shiftfs"' "${CONFIG_FILE}" +fi + +echo "Gitpod: auto-detecting containerd location on host machine" +if [ -d "/mnt/node0${CONTAINERD_DIR_K3S}" ]; then + echo "Gitpod: containerd dir detected as k3s" + + yq e -i ".workspace.runtime.containerdRuntimeDir = \"${CONTAINERD_DIR_K3S}\"" "${CONFIG_FILE}" +elif [ -d "/mnt/node0${CONTAINERD_DIR_AL}" ]; then + echo "Gitpod: containerd dir detected as ${CONTAINERD_DIR_AL}" + + yq e -i ".workspace.runtime.containerdRuntimeDir = \"${CONTAINERD_DIR_AL}\"" "${CONFIG_FILE}" +fi + +if [ -S "/mnt/node0${CONTAINERD_SOCKET_K3S}" ]; then + echo "Gitpod: containerd socket detected as k3s" + + yq e -i ".workspace.runtime.containerdSocket = \"${CONTAINERD_SOCKET_K3S}\"" "${CONFIG_FILE}" +elif [ -S "/mnt/node0${CONTAINERD_SOCKET_AL}" ]; then + echo "Gitpod: containerd socket detected as ${CONTAINERD_SOCKET_AL}" + + yq e -i ".workspace.runtime.containerdSocket = \"${CONTAINERD_SOCKET_AL}\"" "${CONFIG_FILE}" +fi + +echo "Gitpod: Inject the Replicated variables into the config" +yq e -i ".domain = \"${DOMAIN}\"" "${CONFIG_FILE}" +yq e -i '.license.kind = "secret"' "${CONFIG_FILE}" +yq e -i '.license.name = "gitpod-license"' "${CONFIG_FILE}" + +if [ "${OPEN_VSX_URL}" != "" ]; +then + echo "Gitpod: Setting Open VSX Registry URL" + yq e -i ".openVSX.url = \"${OPEN_VSX_URL}\"" "${CONFIG_FILE}" +fi + +if [ "${DB_INCLUSTER_ENABLED}" = "0" ] && [ "${DB_CLOUDSQL_INSTANCE}" != "" ]; +then + echo "Gitpod: configuring CloudSQLProxy" + + yq e -i ".database.inCluster = false" "${CONFIG_FILE}" + yq e -i ".database.cloudSQL.instance = \"${DB_CLOUDSQL_INSTANCE}\"" "${CONFIG_FILE}" + yq e -i ".database.cloudSQL.serviceAccount.kind = \"secret\"" "${CONFIG_FILE}" + yq e -i ".database.cloudSQL.serviceAccount.name = \"cloudsql\"" "${CONFIG_FILE}" +fi + +if [ "${DB_INCLUSTER_ENABLED}" = "0" ] && [ "${DB_CLOUDSQL_INSTANCE}" = "" ]; +then + echo "Gitpod: configuring external database" + + yq e -i ".database.inCluster = false" "${CONFIG_FILE}" + yq e -i ".database.external.certificate.kind = \"secret\"" "${CONFIG_FILE}" + yq e -i ".database.external.certificate.name = \"database\"" "${CONFIG_FILE}" +fi + +if [ "${HAS_LOCAL_REGISTRY}" = "true" ]; +then + echo "Gitpod: configuring mirrored container registry for airgapped installation" + + yq e -i ".repository = \"${LOCAL_REGISTRY_ADDRESS}\"" "${CONFIG_FILE}" + yq e -i ".imagePullSecrets[0].kind = \"secret\"" "${CONFIG_FILE}" + yq e -i ".imagePullSecrets[0].name = \"${IMAGE_PULL_SECRET_NAME}\"" "${CONFIG_FILE}" + yq e -i '.dropImageRepo = true' "${CONFIG_FILE}" + + # Add the registry to the server allowlist - keep docker.io in case it's just using the mirrored registry functionality without being airgapped + yq e -i ".containerRegistry.privateBaseImageAllowList += \"${LOCAL_REGISTRY_HOST}\"" "${CONFIG_FILE}" + yq e -i ".containerRegistry.privateBaseImageAllowList += \"docker.io\"" "${CONFIG_FILE}" +fi + +if [ "${REG_DOCKER_CONFIG_ENABLED}" = "1" ]; +then + echo "Gitpod: extracting servers from the custom registry authentication" + + kubectl get secret \ + -n "${NAMESPACE}" \ + custom-registry-credentials \ + -o jsonpath="{.data.\.dockerconfigjson}" | base64 -d > /tmp/userconfig.json + + # Add the registries to the server allowlist + yq e -i ".containerRegistry.privateBaseImageAllowList += $(jq '.auths' /tmp/userconfig.json | jq -rc 'keys')" "${CONFIG_FILE}" + yq e -i ".containerRegistry.privateBaseImageAllowList += \"docker.io\"" "${CONFIG_FILE}" +fi + +# Output the local registry secret - this is proxy.replicated.com if user hasn't set their own +echo "${LOCAL_REGISTRY_IMAGE_PULL_SECRET}" | base64 -d > /tmp/kotsregistry.json + +if [ "${REG_INCLUSTER_ENABLED}" = "0" ]; +then + echo "Gitpod: configuring external container registry" + + # Get the external-container-registry secret so we can merge the external registry and KOTS registry keys + kubectl get secret external-container-registry \ + --namespace "${NAMESPACE}" \ + -o jsonpath='{.data.\.dockerconfigjson}' | base64 -d > /tmp/gitpodregistry.json + + cat /tmp/kotsregistry.json /tmp/gitpodregistry.json | jq -s '.[0] * .[1]' - - > /tmp/container-registry-secret + + echo "Gitpod: create the container-registry secret" + kubectl create secret docker-registry container-registry \ + --namespace "${NAMESPACE}" \ + --from-file=.dockerconfigjson=/tmp/container-registry-secret \ + -o yaml --dry-run=client > "${GITPOD_OBJECTS}/templates/gitpod.yaml" + + yq e -i ".containerRegistry.inCluster = false" "${CONFIG_FILE}" + yq e -i ".containerRegistry.external.url = \"${REG_URL}\"" "${CONFIG_FILE}" + yq e -i ".containerRegistry.external.certificate.kind = \"secret\"" "${CONFIG_FILE}" + yq e -i ".containerRegistry.external.certificate.name = \"container-registry\"" "${CONFIG_FILE}" +else + if [ "${REG_INCLUSTER_STORAGE}" = "s3" ]; + then + echo "Gitpod: configuring container registry S3 backend" + + yq e -i ".containerRegistry.s3storage.region = \"${REG_INCLUSTER_STORAGE_S3_REGION}\"" "${CONFIG_FILE}" + yq e -i ".containerRegistry.s3storage.endpoint = \"${REG_INCLUSTER_STORAGE_S3_ENDPOINT}\"" "${CONFIG_FILE}" + yq e -i ".containerRegistry.s3storage.bucket = \"${REG_INCLUSTER_STORAGE_S3_BUCKETNAME}\"" "${CONFIG_FILE}" + yq e -i ".containerRegistry.s3storage.certificate.kind = \"secret\"" "${CONFIG_FILE}" + yq e -i ".containerRegistry.s3storage.certificate.name = \"container-registry-s3-backend\"" "${CONFIG_FILE}" + fi +fi + +if [ "${STORE_PROVIDER}" != "incluster" ]; +then + echo "Gitpod: configuring the storage" + + yq e -i ".metadata.region = \"${STORE_REGION}\"" "${CONFIG_FILE}" + yq e -i ".objectStorage.inCluster = false" "${CONFIG_FILE}" + + if [ "${STORE_PROVIDER}" = "azure" ]; + then + echo "Gitpod: configuring storage for Azure" + + yq e -i ".objectStorage.azure.credentials.kind = \"secret\"" "${CONFIG_FILE}" + yq e -i ".objectStorage.azure.credentials.name = \"storage-azure\"" "${CONFIG_FILE}" + fi + + if [ "${STORE_PROVIDER}" = "gcp" ]; + then + echo "Gitpod: configuring storage for GCP" + + yq e -i ".objectStorage.cloudStorage.project = \"${STORE_GCP_PROJECT}\"" "${CONFIG_FILE}" + yq e -i ".objectStorage.cloudStorage.serviceAccount.kind = \"secret\"" "${CONFIG_FILE}" + yq e -i ".objectStorage.cloudStorage.serviceAccount.name = \"storage-gcp\"" "${CONFIG_FILE}" + fi + + if [ "${STORE_PROVIDER}" = "s3" ]; + then + echo "Gitpod: configuring storage for S3" + + yq e -i ".objectStorage.s3.endpoint = \"${STORE_S3_ENDPOINT}\"" "${CONFIG_FILE}" + yq e -i ".objectStorage.s3.bucket = \"${STORE_S3_BUCKET}\"" "${CONFIG_FILE}" + yq e -i ".objectStorage.s3.credentials.kind = \"secret\"" "${CONFIG_FILE}" + yq e -i ".objectStorage.s3.credentials.name = \"storage-s3\"" "${CONFIG_FILE}" + fi +fi + +if [ "${SSH_GATEWAY}" = "1" ]; +then + echo "Gitpod: Generate SSH host key" + ssh-keygen -t rsa -q -N "" -f host.key + kubectl create secret generic ssh-gateway-host-key --from-file=host.key -n "${NAMESPACE}" || echo "SSH Gateway Host Key secret has not been created. Does it exist already?" + yq e -i '.sshGatewayHostKey.kind = "secret"' "${CONFIG_FILE}" + yq e -i '.sshGatewayHostKey.name = "ssh-gateway-host-key"' "${CONFIG_FILE}" +fi + +if [ "${TLS_SELF_SIGNED_ENABLED}" = "1" ]; +then + echo "Gitpod: Generating a self-signed certificate with the internal CA" + yq e -i '.customCACert.kind = "secret"' "${CONFIG_FILE}" + yq e -i '.customCACert.name = "ca-issuer-ca"' "${CONFIG_FILE}" +elif [ "${TLS_SELF_SIGNED_ENABLED}" = "0" ] && [ "${CERT_MANAGER_ENABLED}" = "0" ] && [ "${TLS_CUSTOM_CA_CRT_ENABLED}" = "true" ]; +then + echo "Gitpod: Setting CA to be used for certificate" + yq e -i '.customCACert.kind = "secret"' "${CONFIG_FILE}" + yq e -i '.customCACert.name = "ca-certificate"' "${CONFIG_FILE}" +fi + +if [ "${USER_MANAGEMENT_BLOCK_ENABLED}" = "1" ]; +then + echo "Gitpod: Adding blockNewUsers to config" + yq e -i '.blockNewUsers.enabled = true' "${CONFIG_FILE}" + + for domain in ${USER_MANAGEMENT_BLOCK_PASSLIST} + do + echo "Gitpod: Adding domain \"${domain}\" to blockNewUsers config" + yq e -i ".blockNewUsers.passlist += \"${domain}\"" "${CONFIG_FILE}" + done +fi + +if [ "${ADVANCED_MODE_ENABLED}" = "1" ]; +then + echo "Gitpod: Applying advanced configuration" + + if [ "${COMPONENT_PROXY_SERVICE_SERVICETYPE}" != "" ]; + then + # Empty string defaults to LoadBalancer. This maintains backwards compatibility with the deprecated experimental value + echo "Gitpod: Applying Proxy service type" + yq e -i ".components.proxy.service.serviceType = \"${COMPONENT_PROXY_SERVICE_SERVICETYPE}\"" "${CONFIG_FILE}" + fi + + if [ -s "${CUSTOMIZATION_PATCH_FILE}" ]; + then + CUSTOMIZATION="$(base64 "${CUSTOMIZATION_PATCH_FILE}" -w 0)" + echo "Gitpod: Applying customization patch ${CUSTOMIZATION}" + + # Apply the customization property - if something else is set, this will be ignored + yq e -i ".customization = $(echo "${CUSTOMIZATION}" | base64 -d | yq e -o json '.customization' - | jq -rc) // []" "${CONFIG_FILE}" + fi +else + echo "Gitpod: No advanced configuration applied" +fi + +echo "Gitpod: Update platform telemetry value" +yq eval-all --inplace ".experimental.telemetry.data.platform = \"${DISTRIBUTION}\"" "${CONFIG_FILE}" + +echo "Gitpod: Patch Gitpod config" +base64 -d "${CONFIG_PATCH_FILE}" > /tmp/patch.yaml +config_patch=$(cat /tmp/patch.yaml) +echo "Gitpod: ${CONFIG_PATCH_FILE}=${config_patch}" +yq eval-all --inplace 'select(fileIndex == 0) * select(fileIndex == 1)' "${CONFIG_FILE}" /tmp/patch.yaml + +echo "Gitpod: Generate the Kubernetes objects" +config=$(cat "${CONFIG_FILE}") +echo "Gitpod: ${CONFIG_FILE}=${config}" + +echo "Gitpod: render Kubernetes manifests" +/app/installer render -c "${CONFIG_FILE}" --namespace "${NAMESPACE}" --use-experimental-config >> "${GITPOD_OBJECTS}/templates/gitpod.yaml" + +if [ "${REG_INCLUSTER_ENABLED}" = "1" ]; +then + echo "Gitpod: Add the local registry secret to the in-cluster registry secret" + + # Get the in-cluster registry secret + yq eval-all '(select(.kind == "Secret" and .metadata.name == "builtin-registry-auth") | .data.".dockerconfigjson")' \ + "${GITPOD_OBJECTS}/templates/gitpod.yaml" \ + | base64 -d \ + > /tmp/gitpodregistry.json + + REGISTRY_SECRET="$(cat /tmp/kotsregistry.json /tmp/gitpodregistry.json | jq -s '.[0] * .[1]' - - | base64 -w 0)" + export REGISTRY_SECRET + + echo "Gitpod: update the in-cluster registry secret" + yq eval-all --inplace '(select(.kind == "Secret" and .metadata.name == "builtin-registry-auth") | .data.".dockerconfigjson") |= env(REGISTRY_SECRET)' \ + "${GITPOD_OBJECTS}/templates/gitpod.yaml" +fi + +if [ "${REG_DOCKER_CONFIG_ENABLED}" = "1" ]; +then + # Work out the registry secret to use + if [ "${REG_INCLUSTER_ENABLED}" = "0" ]; + then + export REGISTRY_SECRET_NAME="container-registry" + else + export REGISTRY_SECRET_NAME="builtin-registry-auth" + fi + + echo "Gitpod: Add given extra docker config JSON file to ${REGISTRY_SECRET_NAME}" + yq eval-all '(select(.kind == "Secret" and .metadata.name == env(REGISTRY_SECRET_NAME)) | .data.".dockerconfigjson")' \ + "${GITPOD_OBJECTS}/templates/gitpod.yaml" \ + | base64 -d \ + > /tmp/currentconfig.json + + echo "Gitpod: update the in-cluster registry secret" + REGISTRY_SECRET="$(jq -s '.[0] * .[1]' /tmp/userconfig.json /tmp/currentconfig.json | base64 -w 0)" + export REGISTRY_SECRET + yq eval-all --inplace '(select(.kind == "Secret" and .metadata.name == env(REGISTRY_SECRET_NAME)) | .data.".dockerconfigjson") |= env(REGISTRY_SECRET)' \ + "${GITPOD_OBJECTS}/templates/gitpod.yaml" +fi + +echo "Gitpod: Escape any Golang template values" +# shellcheck disable=SC2016 +sed -i -r 's/(.*\{\{.*)/{{`\1`}}/' "${GITPOD_OBJECTS}/templates/gitpod.yaml" + +# If certificate secret already exists, set the timeout to 5m +CERT_SECRET=$(kubectl get secrets -n "${NAMESPACE}" https-certificates -o jsonpath='{.metadata.name}' || echo '') +HELM_TIMEOUT="5m" +if [ "${CERT_SECRET}" = "" ]; then + HELM_TIMEOUT="1h" +fi + +# The long timeout is to ensure the TLS cert is created (if required) +echo "Gitpod: Apply the Kubernetes objects with timeout of ${HELM_TIMEOUT}" +helm upgrade \ + --atomic \ + --cleanup-on-fail \ + --create-namespace \ + --install \ + --namespace="${NAMESPACE}" \ + --reset-values \ + --timeout "${HELM_TIMEOUT}" \ + --wait \ + gitpod \ + "${GITPOD_OBJECTS}" + +echo "Gitpod: Restarting installation status job" +kubectl delete pod -n "${NAMESPACE}" -l component=gitpod-installer-status || true + +echo "Gitpod: Installer job finished - goodbye" diff --git a/install/kots/manifests/gitpod-config-patch.yaml b/install/kots/manifests/gitpod-config-patch.yaml index b49120367fc37b..fd41df87627b63 100644 --- a/install/kots/manifests/gitpod-config-patch.yaml +++ b/install/kots/manifests/gitpod-config-patch.yaml @@ -10,3 +10,5 @@ metadata: component: gitpod-installer data: gitpod-config-patch.yaml: '{{repl if and (ConfigOptionEquals "advanced_mode_enabled" "1") (ConfigOptionNotEquals "config_patch" "") }}{{repl ConfigOption "config_patch" }}{{repl else }}{{repl printf "{}" | Base64Encode }}{{repl end }}' + customization-patch.yaml: | + repl{{ ConfigOptionData "customization_patch" | default "" | nindent 4 }} diff --git a/install/kots/manifests/gitpod-custom-registry-credentials.yaml b/install/kots/manifests/gitpod-custom-registry-credentials.yaml new file mode 100644 index 00000000000000..b52b1293f98840 --- /dev/null +++ b/install/kots/manifests/gitpod-custom-registry-credentials.yaml @@ -0,0 +1,12 @@ +# Copyright (c) 2022 Gitpod GmbH. All rights reserved. +# Licensed under the MIT License. See License-MIT.txt in the project root for license information. + +apiVersion: v1 +kind: Secret +metadata: + name: custom-registry-credentials + annotations: + kots.io/when: '{{repl ConfigOptionEquals "reg_docker_config_enable" "1" }}' +type: kubernetes.io/dockerconfigjson +data: + .dockerconfigjson: repl{{ ConfigOptionData "reg_docker_config" | Base64Encode | quote }} diff --git a/install/kots/manifests/gitpod-installation-status.yaml b/install/kots/manifests/gitpod-installation-status.yaml index 7ad2d0c604ad5e..b3724f3057c9d8 100644 --- a/install/kots/manifests/gitpod-installation-status.yaml +++ b/install/kots/manifests/gitpod-installation-status.yaml @@ -30,7 +30,7 @@ spec: containers: - name: installation-status # This will normally be the release tag - image: "eu.gcr.io/gitpod-core-dev/build/installer:sje-conditional-psp-removal.4" + image: "eu.gcr.io/gitpod-core-dev/build/installer:sje-move-kots-bash-script.28" command: - /bin/sh - -c diff --git a/install/kots/manifests/gitpod-installer-job.yaml b/install/kots/manifests/gitpod-installer-job.yaml index 28bebf81b49930..0fe7a5629d946c 100644 --- a/install/kots/manifests/gitpod-installer-job.yaml +++ b/install/kots/manifests/gitpod-installer-job.yaml @@ -39,7 +39,7 @@ spec: containers: - name: installer # This will normally be the release tag - image: "eu.gcr.io/gitpod-core-dev/build/installer:sje-conditional-psp-removal.4" + image: "eu.gcr.io/gitpod-core-dev/build/installer:sje-move-kots-bash-script.28" volumeMounts: - mountPath: /config-patch name: config-patch @@ -52,6 +52,8 @@ spec: value: /tmp/gitpod-config.yaml - name: CONFIG_PATCH_FILE value: /config-patch/gitpod-config-patch.yaml + - name: CUSTOMIZATION_PATCH_FILE + value: /config-patch/customization-patch.yaml - name: CONTAINERD_DIR_K3S value: /run/k3s/containerd/io.containerd.runtime.v2.task/k8s.io - name: CONTAINERD_SOCKET_K3S @@ -62,344 +64,11 @@ spec: value: /run/containerd/containerd.sock - name: GITPOD_OBJECTS value: /tmp/gitpod + envFrom: + - configMapRef: + name: gitpod-kots-config command: - - /bin/sh - - -c - args: - - | - set -e - - echo "Gitpod: Killing any in-progress installations" - - kubectl delete jobs.batch -n {{repl Namespace }} -l component=gitpod-installer,cursor!={{repl Cursor }} --force --grace-period 0 || true - kubectl delete pod -n {{repl Namespace }} -l component=gitpod-installer,cursor!={{repl Cursor }} --force --grace-period 0 || true - - if [ "$(helm status -n {{repl Namespace }} gitpod -o json | jq '.info.status == "deployed"')" = "false" ]; - then - echo "Gitpod: Deployment in-progress - clearing" - - VERSION="$(helm status -n {{repl Namespace }} gitpod -o json | jq '.version')" - if [ "${VERSION}" -le 1 ]; - then - echo "Gitpod: Uninstall application" - helm uninstall -n {{repl Namespace }} gitpod --wait || true - else - echo "Gitpod: Rolling back application" - helm rollback -n {{repl Namespace }} gitpod --wait || true - fi - fi - - echo "Gitpod: Create a Helm template directory" - rm -Rf "${GITPOD_OBJECTS}" - mkdir -p "${GITPOD_OBJECTS}/templates" - cat <> "${GITPOD_OBJECTS}/Chart.yaml" - apiVersion: v2 - name: gitpod-kots - description: Always ready-to-code - version: "1.0.0" - appVersion: "$(/app/installer version | yq e '.version' -)" - EOF - - echo "Gitpod: Generate the base Installer config" - /app/installer init > "${CONFIG_FILE}" - - echo "Gitpod: auto-detecting ShiftFS support on host machine" - kubectl wait job -n {{repl Namespace }} --for=condition=complete -l component=shiftfs-module-loader --timeout=30s || true - ENABLE_SHIFTFS=$(kubectl get jobs.batch -n {{repl Namespace }} -l component=shiftfs-module-loader -o jsonpath='{.items[0].status.succeeded}') - - if [ "${ENABLE_SHIFTFS}" = "1" ]; then - echo "Gitpod: enabling ShiftFS support" - - yq e -i '.workspace.runtime.fsShiftMethod = "shiftfs"' "${CONFIG_FILE}" - fi - - echo "Gitpod: auto-detecting containerd location on host machine" - if [ -d "/mnt/node0${CONTAINERD_DIR_K3S}" ]; then - echo "Gitpod: containerd dir detected as k3s" - - yq e -i ".workspace.runtime.containerdRuntimeDir = \"${CONTAINERD_DIR_K3S}\"" "${CONFIG_FILE}" - elif [ -d "/mnt/node0${CONTAINERD_DIR_AL}" ]; then - echo "Gitpod: containerd dir detected as ${CONTAINERD_DIR_AL}" - - yq e -i ".workspace.runtime.containerdRuntimeDir = \"${CONTAINERD_DIR_AL}\"" "${CONFIG_FILE}" - fi - - if [ -S "/mnt/node0${CONTAINERD_SOCKET_K3S}" ]; then - echo "Gitpod: containerd socket detected as k3s" - - yq e -i ".workspace.runtime.containerdSocket = \"${CONTAINERD_SOCKET_K3S}\"" "${CONFIG_FILE}" - elif [ -S "/mnt/node0${CONTAINERD_SOCKET_AL}" ]; then - echo "Gitpod: containerd socket detected as ${CONTAINERD_SOCKET_AL}" - - yq e -i ".workspace.runtime.containerdSocket = \"${CONTAINERD_SOCKET_AL}\"" "${CONFIG_FILE}" - fi - - echo "Gitpod: Inject the Replicated variables into the config" - yq e -i '.domain = "{{repl ConfigOption "domain" }}"' "${CONFIG_FILE}" - yq e -i '.license.kind = "secret"' "${CONFIG_FILE}" - yq e -i '.license.name = "gitpod-license"' "${CONFIG_FILE}" - - if [ '{{repl ConfigOptionNotEquals "openVsxUrl" "" }}' = "true" ]; - then - echo "Gitpod: Setting Open VSX Registry URL" - yq e -i ".openVSX.url = \"{{repl ConfigOption "openVsxUrl" }}\"" "${CONFIG_FILE}" - fi - - if [ '{{repl and (ConfigOptionEquals "db_incluster" "0") (ConfigOptionEquals "db_cloudsql_enabled" "1") }}' = "true" ]; - then - echo "Gitpod: configuring CloudSQLProxy" - - yq e -i ".database.inCluster = false" "${CONFIG_FILE}" - yq e -i ".database.cloudSQL.instance = \"{{repl ConfigOption "db_cloudsql_instance" }}\"" "${CONFIG_FILE}" - yq e -i ".database.cloudSQL.serviceAccount.kind = \"secret\"" "${CONFIG_FILE}" - yq e -i ".database.cloudSQL.serviceAccount.name = \"cloudsql\"" "${CONFIG_FILE}" - fi - - if [ '{{repl and (ConfigOptionEquals "db_incluster" "0") (ConfigOptionEquals "db_cloudsql_enabled" "0") }}' = "true" ]; - then - echo "Gitpod: configuring external database" - - yq e -i ".database.inCluster = false" "${CONFIG_FILE}" - yq e -i ".database.external.certificate.kind = \"secret\"" "${CONFIG_FILE}" - yq e -i ".database.external.certificate.name = \"database\"" "${CONFIG_FILE}" - fi - - if [ '{{repl HasLocalRegistry }}' = "true" ]; - then - echo "Gitpod: configuring mirrored container registry for airgapped installation" - - yq e -i ".repository = \"{{repl LocalRegistryAddress }}\"" "${CONFIG_FILE}" - yq e -i ".imagePullSecrets[0].kind = \"secret\"" "${CONFIG_FILE}" - yq e -i ".imagePullSecrets[0].name = \"{{repl ImagePullSecretName }}\"" "${CONFIG_FILE}" - yq e -i '.dropImageRepo = true' "${CONFIG_FILE}" - - # Add the registry to the server allowlist - keep docker.io in case it's just using the mirrored registry functionality without being airgapped - yq e -i ".containerRegistry.privateBaseImageAllowList += \"{{repl LocalRegistryHost }}\"" "${CONFIG_FILE}" - yq e -i ".containerRegistry.privateBaseImageAllowList += \"docker.io\"" "${CONFIG_FILE}" - fi - - if [ '{{repl ConfigOptionNotEquals "reg_docker_config" "" }}' = "true" ]; - then - DOCKER_CONFIG='{{repl ConfigOptionData "reg_docker_config" | Base64Encode }}' - echo "${DOCKER_CONFIG}" | base64 -d > /tmp/userconfig.json - # Add the registries to the server allowlist - yq e -i ".containerRegistry.privateBaseImageAllowList += $(cat /tmp/userconfig.json | jq '.auths' | jq -rc 'keys')" "${CONFIG_FILE}" - yq e -i ".containerRegistry.privateBaseImageAllowList += \"docker.io\"" "${CONFIG_FILE}" - fi - - # Output the local registry secret - this is proxy.replicated.com if user hasn't set their own - echo "{{repl LocalRegistryImagePullSecret }}" | base64 -d > /tmp/kotsregistry.json - - if [ '{{repl ConfigOptionEquals "reg_incluster" "0" }}' = "true" ]; - then - echo "Gitpod: configuring external container registry" - - # Create a container-registry secret merging the external registry and KOTS registry keys - echo '{{repl printf "{\"auths\": {\"%s\": {\"username\": \"%s\", \"password\": %s, \"auth\": \"%s\"}}}" (ConfigOption "reg_server" | default (ConfigOption "reg_url")) (ConfigOption "reg_username") (ConfigOption "reg_password" | toJson) (printf "%s:%s" (ConfigOption "reg_username") (ConfigOption "reg_password") | Base64Encode) }}' \ - | yq -o=json '.' - \ - > /tmp/gitpodregistry.json - - cat /tmp/kotsregistry.json /tmp/gitpodregistry.json | jq -s '.[0] * .[1]' - - > /tmp/container-registry-secret - - echo "Gitpod: create the container-registry secret" - kubectl create secret docker-registry container-registry \ - --namespace "{{repl Namespace }}" \ - --from-file=.dockerconfigjson=/tmp/container-registry-secret \ - -o yaml --dry-run=client > "${GITPOD_OBJECTS}/templates/gitpod.yaml" - - yq e -i ".containerRegistry.inCluster = false" "${CONFIG_FILE}" - yq e -i ".containerRegistry.external.url = \"{{repl ConfigOption "reg_url" }}\"" "${CONFIG_FILE}" - yq e -i ".containerRegistry.external.certificate.kind = \"secret\"" "${CONFIG_FILE}" - yq e -i ".containerRegistry.external.certificate.name = \"container-registry\"" "${CONFIG_FILE}" - else - if [ '{{repl ConfigOptionEquals "reg_incluster_storage" "s3" }}' = "true" ]; - then - echo "Gitpod: configuring container registry S3 backend" - - yq e -i ".containerRegistry.s3storage.region = \"{{repl ConfigOption "reg_incluster_storage_s3_region" }}\"" "${CONFIG_FILE}" - yq e -i ".containerRegistry.s3storage.endpoint = \"{{repl ConfigOption "reg_incluster_storage_s3_endpoint" }}\"" "${CONFIG_FILE}" - yq e -i ".containerRegistry.s3storage.bucket = \"{{repl ConfigOption "reg_incluster_storage_s3_bucketname" }}\"" "${CONFIG_FILE}" - yq e -i ".containerRegistry.s3storage.certificate.kind = \"secret\"" "${CONFIG_FILE}" - yq e -i ".containerRegistry.s3storage.certificate.name = \"container-registry-s3-backend\"" "${CONFIG_FILE}" - fi - fi - - if [ '{{repl ConfigOptionNotEquals "store_provider" "incluster" }}' = "true" ]; - then - echo "Gitpod: configuring the storage" - - yq e -i ".metadata.region = \"{{repl ConfigOption "store_region" }}\"" "${CONFIG_FILE}" - yq e -i ".objectStorage.inCluster = false" "${CONFIG_FILE}" - - if [ '{{repl ConfigOptionEquals "store_provider" "azure" }}' = "true" ]; - then - echo "Gitpod: configuring storage for Azure" - - yq e -i ".objectStorage.azure.credentials.kind = \"secret\"" "${CONFIG_FILE}" - yq e -i ".objectStorage.azure.credentials.name = \"storage-azure\"" "${CONFIG_FILE}" - fi - - if [ '{{repl ConfigOptionEquals "store_provider" "gcp" }}' = "true" ]; - then - echo "Gitpod: configuring storage for GCP" - - yq e -i ".objectStorage.cloudStorage.project = \"{{repl ConfigOption "store_gcp_project" }}\"" "${CONFIG_FILE}" - yq e -i ".objectStorage.cloudStorage.serviceAccount.kind = \"secret\"" "${CONFIG_FILE}" - yq e -i ".objectStorage.cloudStorage.serviceAccount.name = \"storage-gcp\"" "${CONFIG_FILE}" - fi - - if [ '{{repl ConfigOptionEquals "store_provider" "s3" }}' = "true" ]; - then - echo "Gitpod: configuring storage for S3" - - yq e -i ".objectStorage.s3.endpoint = \"{{repl ConfigOption "store_s3_endpoint" }}\"" "${CONFIG_FILE}" - yq e -i ".objectStorage.s3.bucket = \"{{repl ConfigOption "store_s3_bucket" }}\"" "${CONFIG_FILE}" - yq e -i ".objectStorage.s3.credentials.kind = \"secret\"" "${CONFIG_FILE}" - yq e -i ".objectStorage.s3.credentials.name = \"storage-s3\"" "${CONFIG_FILE}" - fi - fi - - if [ '{{repl ConfigOptionEquals "ssh_gateway" "1" }}' = "true" ]; - then - echo "Gitpod: Generate SSH host key" - ssh-keygen -t rsa -q -N "" -f host.key - kubectl create secret generic ssh-gateway-host-key --from-file=host.key -n {{repl Namespace }} || echo "SSH Gateway Host Key secret has not been created. Does it exist already?" - yq e -i '.sshGatewayHostKey.kind = "secret"' "${CONFIG_FILE}" - yq e -i '.sshGatewayHostKey.name = "ssh-gateway-host-key"' "${CONFIG_FILE}" - fi - - if [ '{{repl ConfigOptionEquals "tls_self_signed_enabled" "1" }}' = "true" ]; - then - echo "Gitpod: Generating a self-signed certificate with the internal CA" - yq e -i '.customCACert.kind = "secret"' "${CONFIG_FILE}" - yq e -i '.customCACert.name = "ca-issuer-ca"' "${CONFIG_FILE}" - elif [ '{{repl and (ConfigOptionEquals "tls_self_signed_enabled" "0") (ConfigOptionEquals "cert_manager_enabled" "0") (ConfigOptionNotEquals "tls_ca_crt" "") }}' = "true" ]; - then - echo "Gitpod: Setting CA to be used for certificate" - yq e -i '.customCACert.kind = "secret"' "${CONFIG_FILE}" - yq e -i '.customCACert.name = "ca-certificate"' "${CONFIG_FILE}" - fi - - if [ '{{repl ConfigOptionEquals "user_management_block_enabled" "1" }}' = "true" ]; - then - echo "Gitpod: Adding blockNewUsers to config" - yq e -i '.blockNewUsers.enabled = true' "${CONFIG_FILE}" - - for domain in {{repl ConfigOption "user_management_block_passlist" }} - do - echo "Gitpod: Adding domain \"${domain}\" to blockNewUsers config" - yq e -i ".blockNewUsers.passlist += \"${domain}\"" "${CONFIG_FILE}" - done - fi - - if [ '{{repl ConfigOptionEquals "advanced_mode_enabled" "1" }}' = "true" ]; - then - echo "Gitpod: Applying advanced configuration" - - if [ '{{repl ConfigOptionNotEquals "component_proxy_service_serviceType" "" }}' = "true" ]; - then - # Empty string defaults to LoadBalancer. This maintains backwards compatibility with the deprecated experimental value - echo "Gitpod: Applying Proxy service type" - yq e -i ".components.proxy.service.serviceType = \"{{repl ConfigOption "component_proxy_service_serviceType" }}\"" "${CONFIG_FILE}" - fi - - if [ '{{repl ConfigOptionNotEquals "customization_patch" "" }}' = "true" ]; - then - CUSTOMIZATION='{{repl ConfigOptionData "customization_patch" | Base64Encode }}' - echo "Gitpod: Applying customization patch ${CUSTOMIZATION}" - - # Apply the customization property - if something else is set, this will be ignored - yq e -i ".customization = $(echo "${CUSTOMIZATION}" | base64 -d | yq e -o json '.customization' - | jq -rc) // []" "${CONFIG_FILE}" - fi - else - echo "Gitpod: No advanced configuration applied" - fi - - echo "Gitpod: Update platform telemetry value" - yq eval-all --inplace '.experimental.telemetry.data.platform = "{{repl Distribution }}"' "${CONFIG_FILE}" - - echo "Gitpod: Patch Gitpod config" - base64 -d "${CONFIG_PATCH_FILE}" > /tmp/patch.yaml - config_patch=$(cat /tmp/patch.yaml) - echo "Gitpod: ${CONFIG_PATCH_FILE}=${config_patch}" - yq eval-all --inplace 'select(fileIndex == 0) * select(fileIndex == 1)' "${CONFIG_FILE}" /tmp/patch.yaml - - echo "Gitpod: Generate the Kubernetes objects" - config=$(cat "${CONFIG_FILE}") - echo "Gitpod: ${CONFIG_FILE}=${config}" - - echo "Gitpod: render Kubernetes manifests" - /app/installer render -c "${CONFIG_FILE}" --namespace {{repl Namespace }} --use-experimental-config >> "${GITPOD_OBJECTS}/templates/gitpod.yaml" - - if [ '{{repl ConfigOptionEquals "reg_incluster" "1" }}' = "true" ]; - then - echo "Gitpod: Add the local registry secret to the in-cluster registry secret" - - # Get the in-cluster registry secret - yq eval-all '(select(.kind == "Secret" and .metadata.name == "builtin-registry-auth") | .data.".dockerconfigjson")' \ - "${GITPOD_OBJECTS}/templates/gitpod.yaml" \ - | base64 -d \ - > /tmp/gitpodregistry.json - - export REGISTRY_SECRET=$(cat /tmp/kotsregistry.json /tmp/gitpodregistry.json | jq -s '.[0] * .[1]' - - | base64 -w 0) - - echo "Gitpod: update the in-cluster registry secret" - yq eval-all --inplace '(select(.kind == "Secret" and .metadata.name == "builtin-registry-auth") | .data.".dockerconfigjson") |= env(REGISTRY_SECRET)' \ - "${GITPOD_OBJECTS}/templates/gitpod.yaml" - fi - - # figure out the secret to use - if [ '{{repl ConfigOptionEquals "reg_incluster" "0" }}' = "true" ]; - then - export REGISTRY_SECRET_NAME="container-registry" - else - export REGISTRY_SECRET_NAME="builtin-registry-auth" - fi - - if [ '{{repl ConfigOptionNotEquals "reg_docker_config" "" }}' = "true" ]; - then - echo "Gitpod: Add given extra docker config json file to ${REGISTRY_SECRET_NAME}" - - yq eval-all '(select(.kind == "Secret" and .metadata.name == env(REGISTRY_SECRET_NAME)) | .data.".dockerconfigjson")' \ - "${GITPOD_OBJECTS}/templates/gitpod.yaml" \ - | base64 -d \ - > /tmp/currentconfig.json - - export REGISTRY_SECRET=$(jq -s '.[0] * .[1]' /tmp/userconfig.json /tmp/currentconfig.json | base64 -w 0) - - echo "Gitpod: update the in-cluster registry secret" - yq eval-all --inplace '(select(.kind == "Secret" and .metadata.name == env(REGISTRY_SECRET_NAME)) | .data.".dockerconfigjson") |= env(REGISTRY_SECRET)' \ - "${GITPOD_OBJECTS}/templates/gitpod.yaml" - fi - - echo "Gitpod: Escape any Golang template values" - sed -i -r 's/(.*\{\{.*)/{{`\1`}}/' "${GITPOD_OBJECTS}/templates/gitpod.yaml" - - # If certificate secret already exists, set the timeout to 5m - CERT_SECRET=$(kubectl get secrets -n {{repl Namespace }} https-certificates -o jsonpath='{.metadata.name}' || echo '') - HELM_TIMEOUT="5m" - if [ "${CERT_SECRET}" = "" ]; then - HELM_TIMEOUT="1h" - fi - - # The long timeout is to ensure the TLS cert is created (if required) - echo "Gitpod: Apply the Kubernetes objects with timeout of ${HELM_TIMEOUT}" - helm upgrade \ - --atomic \ - --cleanup-on-fail \ - --create-namespace \ - --install \ - --namespace="{{repl Namespace }}" \ - --reset-values \ - --timeout "${HELM_TIMEOUT}" \ - --wait \ - gitpod \ - "${GITPOD_OBJECTS}" - - echo "Gitpod: Restarting installation status job" - kubectl delete pod -n {{repl Namespace }} -l component=gitpod-installer-status || true - - echo "Gitpod: Installer job finished - goodbye" + - /app/scripts/kots-install.sh volumes: - name: config-patch configMap: diff --git a/install/kots/manifests/gitpod-kots-config.yaml b/install/kots/manifests/gitpod-kots-config.yaml new file mode 100644 index 00000000000000..f64e1b900c2ace --- /dev/null +++ b/install/kots/manifests/gitpod-kots-config.yaml @@ -0,0 +1,60 @@ +# Copyright (c) 2022 Gitpod GmbH. All rights reserved. +# Licensed under the MIT License. See License-MIT.txt in the project root for license information. + +apiVersion: v1 +kind: ConfigMap +metadata: + name: gitpod-kots-config + labels: + app: gitpod + component: gitpod-installer +data: + # General settings + CURSOR: repl{{ Cursor | quote }} + DISTRIBUTION: repl{{ Distribution | quote }} + DOMAIN: repl{{ ConfigOption "domain" | quote }} + NAMESPACE: repl{{ Namespace | quote }} + OPEN_VSX_URL: repl{{ ConfigOption "openVsxUrl" | quote }} + SSH_GATEWAY: repl{{ ConfigOption "ssh_gateway" | quote }} + + # Database settings + DB_INCLUSTER_ENABLED: repl{{ ConfigOption "db_incluster" | quote }} + DB_CLOUDSQL_ENABLED: repl{{ ConfigOption "db_cloudsql_enabled" | quote }} + DB_CLOUDSQL_INSTANCE: repl{{ ConfigOption "db_cloudsql_instance" | quote }} + + # Airgap settings + HAS_LOCAL_REGISTRY: repl{{ HasLocalRegistry | quote }} + LOCAL_REGISTRY_ADDRESS: repl{{ LocalRegistryAddress | quote }} + LOCAL_REGISTRY_HOST: repl{{ LocalRegistryHost | quote }} + LOCAL_REGISTRY_IMAGE_PULL_SECRET: repl{{ LocalRegistryImagePullSecret | quote }} + IMAGE_PULL_SECRET_NAME: repl{{ ImagePullSecretName | quote }} + + # Registry settings + REG_INCLUSTER_ENABLED: repl{{ ConfigOption "reg_incluster" | quote }} + REG_URL: repl{{ ConfigOption "reg_url" | quote }} + REG_INCLUSTER_STORAGE: repl{{ ConfigOption "reg_incluster_storage" | quote }} + REG_INCLUSTER_STORAGE_S3_REGION: repl{{ ConfigOption "reg_incluster_storage_s3_region" | quote }} + REG_INCLUSTER_STORAGE_S3_ENDPOINT: repl{{ ConfigOption "reg_incluster_storage_s3_endpoint" | quote }} + REG_INCLUSTER_STORAGE_S3_BUCKETNAME: repl{{ ConfigOption "reg_incluster_storage_s3_bucketname" | quote }} + REG_DOCKER_CONFIG_ENABLED: repl{{ ConfigOption "reg_docker_config_enable" | quote }} + + # Storage settings + STORE_PROVIDER: repl{{ ConfigOption "store_provider" | quote }} + STORE_REGION: repl{{ ConfigOption "store_region" | quote }} + STORE_GCP_PROJECT: repl{{ ConfigOption "store_gcp_project" | quote }} + STORE_S3_ENDPOINT: repl{{ ConfigOption "store_s3_endpoint" | quote }} + STORE_S3_BUCKET: repl{{ ConfigOption "store_s3_bucket" | quote }} + + # TLS certificate settings + CERT_MANAGER_ENABLED: repl{{ ConfigOption "cert_manager_enabled" | quote }} + TLS_SELF_SIGNED_ENABLED: repl{{ ConfigOption "tls_self_signed_enabled" | quote }} + TLS_CUSTOM_CA_CRT_ENABLED: repl{{ ConfigOptionNotEquals "tls_ca_crt" "" | quote }} # Use comparison not value + + # User management settings + USER_MANAGEMENT_BLOCK_ENABLED: repl{{ ConfigOption "user_management_block_enabled" | quote }} + USER_MANAGEMENT_BLOCK_PASSLIST: repl{{ ConfigOption "user_management_block_passlist" | quote }} + + # Advanced settings + ADVANCED_MODE_ENABLED: repl{{ ConfigOption "advanced_mode_enabled" | quote }} + COMPONENT_PROXY_SERVICE_SERVICETYPE: repl{{ ConfigOption "component_proxy_service_serviceType" | quote }} + CUSTOMIZATION_PATCH_ENABLED: repl{{ ConfigOptionNotEquals "customization_patch" "" | quote }} # Use comparison not value diff --git a/install/kots/manifests/gitpod-registry-secret.yaml b/install/kots/manifests/gitpod-registry-secret.yaml new file mode 100644 index 00000000000000..de8195056ba5aa --- /dev/null +++ b/install/kots/manifests/gitpod-registry-secret.yaml @@ -0,0 +1,12 @@ +# Copyright (c) 2022 Gitpod GmbH. All rights reserved. +# Licensed under the MIT License. See License-MIT.txt in the project root for license information. + +apiVersion: v1 +kind: Secret +metadata: + name: external-container-registry + annotations: + kots.io/when: '{{repl ConfigOptionEquals "reg_incluster" "0" }}' +type: kubernetes.io/dockerconfigjson +data: + .dockerconfigjson: '{{repl printf "{\"auths\": {\"%s\": {\"username\": \"%s\", \"password\": %s, \"auth\": \"%s\"}}}" (ConfigOption "reg_server" | default (ConfigOption "reg_url")) (ConfigOption "reg_username") (ConfigOption "reg_password" | toJson) (printf "%s:%s" (ConfigOption "reg_username") (ConfigOption "reg_password") | Base64Encode) | Base64Encode }}' From 2dc3af7a8f8f39779ed3c1ff81c2a66adae4aeee Mon Sep 17 00:00:00 2001 From: Simon Emms Date: Mon, 22 Aug 2022 09:05:40 +0000 Subject: [PATCH 2/2] [installer]: move the installation status script to the Installer --- .../scripts/kots-installation-status.sh | 74 +++++++++++++++++++ .../manifests/gitpod-installation-status.yaml | 23 +----- 2 files changed, 78 insertions(+), 19 deletions(-) create mode 100755 install/installer/scripts/kots-installation-status.sh diff --git a/install/installer/scripts/kots-installation-status.sh b/install/installer/scripts/kots-installation-status.sh new file mode 100755 index 00000000000000..5468ef7d9e9d6d --- /dev/null +++ b/install/installer/scripts/kots-installation-status.sh @@ -0,0 +1,74 @@ +#!/bin/sh +# Copyright (c) 2022 Gitpod GmbH. All rights reserved. +# Licensed under the MIT License. See License-MIT.txt in the project root for license information. + +set -e + +cat <