Skip to content

Commit 584f17e

Browse files
author
Simon Emms
committed
[installer]: move the kots install script into a bash file in Installer
1 parent 2133092 commit 584f17e

8 files changed

+394
-307
lines changed

install/installer/BUILD.yaml

+3
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ packages:
1212
- "pkg/components/**/*.key"
1313
- "pkg/components/**/*.pem"
1414
- "pkg/components/**/*.sql"
15+
- "scripts/*.sh"
1516
- "third_party/**/*"
1617
deps:
1718
- components/blobserve:lib
@@ -51,6 +52,8 @@ packages:
5152
- ["objcopy", "--add-section", "versionManifest=components--all-docker/versions.yaml", "install-installer--raw-app/installer", "installer"]
5253
- name: docker
5354
type: docker
55+
srcs:
56+
- "scripts/*.sh"
5457
deps:
5558
- :app
5659
argdeps:

install/installer/leeway.Dockerfile

+1
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
FROM alpine:3.16
66
COPY --from=alpine/helm:3.8.0 /usr/bin/helm /usr/bin/helm
77
COPY install-installer--app/installer install-installer--app/provenance-bundle.jsonl /app/
8+
COPY scripts/*.sh /app/scripts/
89
RUN apk add --no-cache curl jq openssh-keygen yq \
910
&& 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 \
1011
&& chmod +x /usr/local/bin/kubectl
+309
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,309 @@
1+
#!/bin/sh
2+
# Copyright (c) 2022 Gitpod GmbH. All rights reserved.
3+
# Licensed under the MIT License. See License-MIT.txt in the project root for license information.
4+
5+
# shellcheck disable=SC2050,SC2153
6+
7+
set -e
8+
9+
echo "Gitpod: Killing any in-progress installations"
10+
11+
kubectl delete jobs.batch -n "${NAMESPACE}" -l component="gitpod-installer,cursor!=${CURSOR}" --force --grace-period 0 || true
12+
kubectl delete pod -n "${NAMESPACE}" -l component="gitpod-installer,cursor!=${CURSOR}" --force --grace-period 0 || true
13+
14+
if [ "$(helm status -n "${NAMESPACE}" gitpod -o json | jq '.info.status == "deployed"')" = "false" ];
15+
then
16+
echo "Gitpod: Deployment in-progress - clearing"
17+
18+
VERSION="$(helm status -n "${NAMESPACE}" gitpod -o json | jq '.version')"
19+
if [ "${VERSION}" -le 1 ];
20+
then
21+
echo "Gitpod: Uninstall application"
22+
helm uninstall -n "${NAMESPACE}" gitpod --wait || true
23+
else
24+
echo "Gitpod: Rolling back application"
25+
helm rollback -n "${NAMESPACE}" gitpod --wait || true
26+
fi
27+
fi
28+
29+
echo "Gitpod: Generate the base Installer config"
30+
/app/installer init > "${CONFIG_FILE}"
31+
32+
echo "Gitpod: auto-detecting ShiftFS support on host machine"
33+
kubectl wait job -n "${NAMESPACE}" --for=condition=complete -l component=shiftfs-module-loader --timeout=30s || true
34+
ENABLE_SHIFTFS=$(kubectl get jobs.batch -n "${NAMESPACE}" -l component=shiftfs-module-loader -o jsonpath='{.items[0].status.succeeded}')
35+
36+
if [ "${ENABLE_SHIFTFS}" = "1" ]; then
37+
echo "Gitpod: enabling ShiftFS support"
38+
39+
yq e -i '.workspace.runtime.fsShiftMethod = "shiftfs"' "${CONFIG_FILE}"
40+
fi
41+
42+
echo "Gitpod: auto-detecting containerd location on host machine"
43+
if [ -d "/mnt/node0${CONTAINERD_DIR_K3S}" ]; then
44+
echo "Gitpod: containerd dir detected as k3s"
45+
46+
yq e -i ".workspace.runtime.containerdRuntimeDir = \"${CONTAINERD_DIR_K3S}\"" "${CONFIG_FILE}"
47+
elif [ -d "/mnt/node0${CONTAINERD_DIR_AL}" ]; then
48+
echo "Gitpod: containerd dir detected as ${CONTAINERD_DIR_AL}"
49+
50+
yq e -i ".workspace.runtime.containerdRuntimeDir = \"${CONTAINERD_DIR_AL}\"" "${CONFIG_FILE}"
51+
fi
52+
53+
if [ -S "/mnt/node0${CONTAINERD_SOCKET_K3S}" ]; then
54+
echo "Gitpod: containerd socket detected as k3s"
55+
56+
yq e -i ".workspace.runtime.containerdSocket = \"${CONTAINERD_SOCKET_K3S}\"" "${CONFIG_FILE}"
57+
elif [ -S "/mnt/node0${CONTAINERD_SOCKET_AL}" ]; then
58+
echo "Gitpod: containerd socket detected as ${CONTAINERD_SOCKET_AL}"
59+
60+
yq e -i ".workspace.runtime.containerdSocket = \"${CONTAINERD_SOCKET_AL}\"" "${CONFIG_FILE}"
61+
fi
62+
63+
echo "Gitpod: Inject the Replicated variables into the config"
64+
yq e -i ".domain = \"${DOMAIN}\"" "${CONFIG_FILE}"
65+
yq e -i '.license.kind = "secret"' "${CONFIG_FILE}"
66+
yq e -i '.license.name = "gitpod-license"' "${CONFIG_FILE}"
67+
68+
if [ "${OPEN_VSX_URL}" != "" ];
69+
then
70+
echo "Gitpod: Setting Open VSX Registry URL"
71+
yq e -i ".openVSX.url = \"${OPEN_VSX_URL}\"" "${CONFIG_FILE}"
72+
fi
73+
74+
if [ "${DB_INCLUSTER_ENABLED}" = "0" ] && [ "${DB_CLOUDSQL_INSTANCE}" = "1" ];
75+
then
76+
echo "Gitpod: configuring CloudSQLProxy"
77+
78+
yq e -i ".database.inCluster = false" "${CONFIG_FILE}"
79+
yq e -i ".database.cloudSQL.instance = \"${DB_INCLUSTER_ENABLED}\"" "${CONFIG_FILE}"
80+
yq e -i ".database.cloudSQL.serviceAccount.kind = \"secret\"" "${CONFIG_FILE}"
81+
yq e -i ".database.cloudSQL.serviceAccount.name = \"cloudsql\"" "${CONFIG_FILE}"
82+
fi
83+
84+
if [ "${DB_INCLUSTER_ENABLED}" = "0" ] && [ "${DB_CLOUDSQL_INSTANCE}" = "0" ];
85+
then
86+
echo "Gitpod: configuring external database"
87+
88+
yq e -i ".database.inCluster = false" "${CONFIG_FILE}"
89+
yq e -i ".database.external.certificate.kind = \"secret\"" "${CONFIG_FILE}"
90+
yq e -i ".database.external.certificate.name = \"database\"" "${CONFIG_FILE}"
91+
fi
92+
93+
if [ "${HAS_LOCAL_REGISTRY}" = "true" ];
94+
then
95+
echo "Gitpod: configuring mirrored container registry for airgapped installation"
96+
97+
yq e -i ".repository = \"${LOCAL_REGISTRY_ADDRESS}\"" "${CONFIG_FILE}"
98+
yq e -i ".imagePullSecrets[0].kind = \"secret\"" "${CONFIG_FILE}"
99+
yq e -i ".imagePullSecrets[0].name = \"${IMAGE_PULL_SECRET_NAME}\"" "${CONFIG_FILE}"
100+
yq e -i '.dropImageRepo = true' "${CONFIG_FILE}"
101+
102+
# Add the registry to the server allowlist - keep docker.io in case it's just using the mirrored registry functionality without being airgapped
103+
yq e -i ".containerRegistry.privateBaseImageAllowList += \"${LOCAL_REGISTRY_HOST}\"" "${CONFIG_FILE}"
104+
yq e -i ".containerRegistry.privateBaseImageAllowList += \"docker.io\"" "${CONFIG_FILE}"
105+
fi
106+
107+
# Output the local registry secret - this is proxy.replicated.com if user hasn't set their own
108+
echo "${LOCAL_REGISTRY_IMAGE_PULL_SECRET}" | base64 -d > /tmp/kotsregistry.json
109+
110+
if [ "${REG_INCLUSTER_ENABLED}" = "0" ];
111+
then
112+
echo "Gitpod: configuring external container registry"
113+
114+
# Get the external-container-registry secret so we can merge the external registry and KOTS registry keys
115+
kubectl get secret external-container-registry \
116+
--namespace "${NAMESPACE}" \
117+
-o jsonpath='{.data.\.dockerconfigjson}' | base64 -d > /tmp/gitpodregistry.json
118+
119+
cat /tmp/kotsregistry.json /tmp/gitpodregistry.json | jq -s '.[0] * .[1]' - - > /tmp/container-registry-secret
120+
121+
echo "Gitpod: create the container-registry secret"
122+
kubectl create secret docker-registry container-registry \
123+
--namespace "${NAMESPACE}" \
124+
--from-file=.dockerconfigjson=/tmp/container-registry-secret \
125+
-o yaml --dry-run=client | \
126+
kubectl replace --namespace "${NAMESPACE}" --force -f -
127+
128+
yq e -i ".containerRegistry.inCluster = false" "${CONFIG_FILE}"
129+
yq e -i ".containerRegistry.external.url = \"${REG_URL}\"" "${CONFIG_FILE}"
130+
yq e -i ".containerRegistry.external.certificate.kind = \"secret\"" "${CONFIG_FILE}"
131+
yq e -i ".containerRegistry.external.certificate.name = \"container-registry\"" "${CONFIG_FILE}"
132+
else
133+
if [ "${REG_INCLUSTER_STORAGE}" = "s3" ];
134+
then
135+
echo "Gitpod: configuring container registry S3 backend"
136+
137+
yq e -i ".containerRegistry.s3storage.region = \"${REG_INCLUSTER_STORAGE_S3_REGION}\"" "${CONFIG_FILE}"
138+
yq e -i ".containerRegistry.s3storage.endpoint = \"${REG_INCLUSTER_STORAGE_S3_ENDPOINT}\"" "${CONFIG_FILE}"
139+
yq e -i ".containerRegistry.s3storage.bucket = \"${REG_INCLUSTER_STORAGE_S3_BUCKETNAME}\"" "${CONFIG_FILE}"
140+
yq e -i ".containerRegistry.s3storage.certificate.kind = \"secret\"" "${CONFIG_FILE}"
141+
yq e -i ".containerRegistry.s3storage.certificate.name = \"container-registry-s3-backend\"" "${CONFIG_FILE}"
142+
fi
143+
fi
144+
145+
if [ "${STORE_PROVIDER}" != "incluster" ];
146+
then
147+
echo "Gitpod: configuring the storage"
148+
149+
yq e -i ".metadata.region = \"${STORE_REGION}\"" "${CONFIG_FILE}"
150+
yq e -i ".objectStorage.inCluster = false" "${CONFIG_FILE}"
151+
152+
if [ "${STORE_PROVIDER}" = "azure" ];
153+
then
154+
echo "Gitpod: configuring storage for Azure"
155+
156+
yq e -i ".objectStorage.azure.credentials.kind = \"secret\"" "${CONFIG_FILE}"
157+
yq e -i ".objectStorage.azure.credentials.name = \"storage-azure\"" "${CONFIG_FILE}"
158+
fi
159+
160+
if [ "${STORE_PROVIDER}" = "gcp" ];
161+
then
162+
echo "Gitpod: configuring storage for GCP"
163+
164+
yq e -i ".objectStorage.cloudStorage.project = \"${STORE_GCP_PROJECT}\"" "${CONFIG_FILE}"
165+
yq e -i ".objectStorage.cloudStorage.serviceAccount.kind = \"secret\"" "${CONFIG_FILE}"
166+
yq e -i ".objectStorage.cloudStorage.serviceAccount.name = \"storage-gcp\"" "${CONFIG_FILE}"
167+
fi
168+
169+
if [ "${STORE_PROVIDER}" = "s3" ];
170+
then
171+
echo "Gitpod: configuring storage for S3"
172+
173+
yq e -i ".objectStorage.s3.endpoint = \"${STORE_S3_ENDPOINT}\"" "${CONFIG_FILE}"
174+
yq e -i ".objectStorage.s3.bucket = \"${STORE_S3_BUCKET}\"" "${CONFIG_FILE}"
175+
yq e -i ".objectStorage.s3.credentials.kind = \"secret\"" "${CONFIG_FILE}"
176+
yq e -i ".objectStorage.s3.credentials.name = \"storage-s3\"" "${CONFIG_FILE}"
177+
fi
178+
fi
179+
180+
if [ "${SSH_GATEWAY}" = "1" ];
181+
then
182+
echo "Gitpod: Generate SSH host key"
183+
ssh-keygen -t rsa -q -N "" -f host.key
184+
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?"
185+
yq e -i '.sshGatewayHostKey.kind = "secret"' "${CONFIG_FILE}"
186+
yq e -i '.sshGatewayHostKey.name = "ssh-gateway-host-key"' "${CONFIG_FILE}"
187+
fi
188+
189+
if [ "${TLS_SELF_SIGNED_ENABLED}" = "1" ];
190+
then
191+
echo "Gitpod: Generating a self-signed certificate with the internal CA"
192+
yq e -i '.customCACert.kind = "secret"' "${CONFIG_FILE}"
193+
yq e -i '.customCACert.name = "ca-issuer-ca"' "${CONFIG_FILE}"
194+
elif [ "${TLS_SELF_SIGNED_ENABLED}" = "0" ] && [ "${CERT_MANAGER_ENABLED}" = "0" ] && [ "${TLS_CUSTOM_CA_CRT_ENABLED}" = "true" ];
195+
then
196+
echo "Gitpod: Setting CA to be used for certificate"
197+
yq e -i '.customCACert.kind = "secret"' "${CONFIG_FILE}"
198+
yq e -i '.customCACert.name = "ca-certificate"' "${CONFIG_FILE}"
199+
fi
200+
201+
if [ "${USER_MANAGEMENT_BLOCK_ENABLED}" = "1" ];
202+
then
203+
echo "Gitpod: Adding blockNewUsers to config"
204+
yq e -i '.blockNewUsers.enabled = true' "${CONFIG_FILE}"
205+
206+
for domain in ${USER_MANAGEMENT_BLOCK_PASSLIST}
207+
do
208+
echo "Gitpod: Adding domain \"${domain}\" to blockNewUsers config"
209+
yq e -i ".blockNewUsers.passlist += \"${domain}\"" "${CONFIG_FILE}"
210+
done
211+
fi
212+
213+
if [ "${ADVANCED_MODE_ENABLED}" = "1" ];
214+
then
215+
echo "Gitpod: Applying advanced configuration"
216+
217+
if [ "${COMPONENT_PROXY_SERVICE_SERVICETYPE}" != "" ];
218+
then
219+
# Empty string defaults to LoadBalancer. This maintains backwards compatibility with the deprecated experimental value
220+
echo "Gitpod: Applying Proxy service type"
221+
yq e -i ".components.proxy.service.serviceType = \"${COMPONENT_PROXY_SERVICE_SERVICETYPE}\"" "${CONFIG_FILE}"
222+
fi
223+
224+
if [ -s "${CUSTOMIZATION_PATCH_FILE}" ];
225+
then
226+
CUSTOMIZATION="$(base64 "${CUSTOMIZATION_PATCH_FILE}")"
227+
echo "Gitpod: Applying customization patch ${CUSTOMIZATION}"
228+
229+
# Apply the customization property - if something else is set, this will be ignored
230+
yq e -i ".customization = $(echo "${CUSTOMIZATION}" | base64 -d | yq e -o json '.customization' - | jq -rc) // []" "${CONFIG_FILE}"
231+
fi
232+
else
233+
echo "Gitpod: No advanced configuration applied"
234+
fi
235+
236+
echo "Gitpod: Update platform telemetry value"
237+
yq eval-all --inplace ".experimental.telemetry.data.platform = \"${DISTRIBUTION}\"" "${CONFIG_FILE}"
238+
239+
echo "Gitpod: Patch Gitpod config"
240+
base64 -d "${CONFIG_PATCH_FILE}" > /tmp/patch.yaml
241+
config_patch=$(cat /tmp/patch.yaml)
242+
echo "Gitpod: ${CONFIG_PATCH_FILE}=${config_patch}"
243+
yq eval-all --inplace 'select(fileIndex == 0) * select(fileIndex == 1)' "${CONFIG_FILE}" /tmp/patch.yaml
244+
245+
echo "Gitpod: Generate the Kubernetes objects"
246+
config=$(cat "${CONFIG_FILE}")
247+
echo "Gitpod: ${CONFIG_FILE}=${config}"
248+
249+
echo "Gitpod: Create a Helm template directory"
250+
rm -Rf "${GITPOD_OBJECTS}"
251+
mkdir -p "${GITPOD_OBJECTS}/templates"
252+
cat <<EOF >> "${GITPOD_OBJECTS}/Chart.yaml"
253+
apiVersion: v2
254+
name: gitpod-kots
255+
description: Always ready-to-code
256+
version: "1.0.0"
257+
appVersion: "$(/app/installer version | yq e '.version' -)"
258+
EOF
259+
260+
echo "Gitpod: render Kubernetes manifests"
261+
/app/installer render -c "${CONFIG_FILE}" --namespace "${NAMESPACE}" --use-experimental-config > "${GITPOD_OBJECTS}/templates/gitpod.yaml"
262+
263+
if [ "${REG_INCLUSTER_ENABLED}" = "1" ];
264+
then
265+
echo "Gitpod: Add the local registry secret to the in-cluster registry secret"
266+
267+
# Get the in-cluster registry secret
268+
yq eval-all '(select(.kind == "Secret" and .metadata.name == "builtin-registry-auth") | .data.".dockerconfigjson")' \
269+
"${GITPOD_OBJECTS}/templates/gitpod.yaml" \
270+
| base64 -d \
271+
> /tmp/gitpodregistry.json
272+
273+
REGISTRY_SECRET="$(cat /tmp/kotsregistry.json /tmp/gitpodregistry.json | jq -s '.[0] * .[1]' - - | base64 -w 0)"
274+
export REGISTRY_SECRET
275+
276+
echo "Gitpod: update the in-cluster registry secret"
277+
yq eval-all --inplace '(select(.kind == "Secret" and .metadata.name == "builtin-registry-auth") | .data.".dockerconfigjson") |= env(REGISTRY_SECRET)' \
278+
"${GITPOD_OBJECTS}/templates/gitpod.yaml"
279+
fi
280+
281+
echo "Gitpod: Escape any Golang template values"
282+
# shellcheck disable=SC2016
283+
sed -i -r 's/(.*\{\{.*)/{{`\1`}}/' "${GITPOD_OBJECTS}/templates/gitpod.yaml"
284+
285+
# If certificate secret already exists, set the timeout to 5m
286+
CERT_SECRET=$(kubectl get secrets -n "${NAMESPACE}" https-certificates -o jsonpath='{.metadata.name}' || echo '')
287+
HELM_TIMEOUT="5m"
288+
if [ "${CERT_SECRET}" = "" ]; then
289+
HELM_TIMEOUT="1h"
290+
fi
291+
292+
# The long timeout is to ensure the TLS cert is created (if required)
293+
echo "Gitpod: Apply the Kubernetes objects with timeout of ${HELM_TIMEOUT}"
294+
helm upgrade \
295+
--atomic \
296+
--cleanup-on-fail \
297+
--create-namespace \
298+
--install \
299+
--namespace="${NAMESPACE}" \
300+
--reset-values \
301+
--timeout "${HELM_TIMEOUT}" \
302+
--wait \
303+
gitpod \
304+
"${GITPOD_OBJECTS}"
305+
306+
echo "Gitpod: Restarting installation status job"
307+
kubectl delete pod -n "${NAMESPACE}" -l component=gitpod-installer-status || true
308+
309+
echo "Gitpod: Installer job finished - goodbye"

install/kots/manifests/gitpod-config-patch.yaml

+2
Original file line numberDiff line numberDiff line change
@@ -10,3 +10,5 @@ metadata:
1010
component: gitpod-installer
1111
data:
1212
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 }}'
13+
customization-patch.yaml: |
14+
repl{{ ConfigOptionData "customization_patch" | default "" | nindent 4 }}

install/kots/manifests/gitpod-installation-status.yaml

+1-1
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ spec:
3030
containers:
3131
- name: installation-status
3232
# This will normally be the release tag
33-
image: "eu.gcr.io/gitpod-core-dev/build/installer:sje-kots-backup.33"
33+
image: "eu.gcr.io/gitpod-core-dev/build/installer:sje-move-kots-bash-script.7"
3434
command:
3535
- /bin/sh
3636
- -c

0 commit comments

Comments
 (0)