Skip to content

Commit a6a3605

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

9 files changed

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

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.16"
3434
command:
3535
- /bin/sh
3636
- -c

0 commit comments

Comments
 (0)