Skip to content

Commit a9efe45

Browse files
kylos101csweichel
authored andcommitted
[werft] Integrate Installer with Deploy
The Installer is the default for new Preview Environments. Preview Environments powered by Helm can switch to the Installer if 'with-clean-slate-deployment=true' is specified. Folks can continue using Helm if 'with-helm=true' is specified. Co-authored-by: Christian Weichel <chris@gitpod.io>
1 parent b2969de commit a9efe45

File tree

13 files changed

+763
-74
lines changed

13 files changed

+763
-74
lines changed

.werft/build.ts

Lines changed: 354 additions & 40 deletions
Large diffs are not rendered by default.

.werft/post-process.sh

Lines changed: 330 additions & 0 deletions
Large diffs are not rendered by default.

.werft/util/kubectl.ts

Lines changed: 36 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -5,29 +5,53 @@ import { getGlobalWerftInstance } from './werft';
55

66
export const IS_PREVIEW_APP_LABEL: string = "isPreviewApp";
77

8+
export const helmInstallName = "gitpod";
9+
810
export function setKubectlContextNamespace(namespace: string, shellOpts: ExecOptions) {
911
[
1012
`kubectl config current-context`,
1113
`kubectl config set-context --current --namespace=${namespace}`
1214
].forEach(cmd => exec(cmd, shellOpts));
1315
}
1416

17+
export async function wipePreviewEnvironmentAndNamespace(helmInstallName: string, namespace: string, shellOpts: ExecOptions) {
18+
// wipe preview envs built with installer
19+
await wipePreviewEnvironmentInstaller(namespace, shellOpts);
20+
21+
// wipe preview envs previously built with helm
22+
await wipePreviewEnvironmentHelm(helmInstallName, namespace, shellOpts)
23+
24+
deleteAllWorkspaces(namespace, shellOpts);
25+
26+
await deleteAllUnnamespacedObjects(namespace, shellOpts);
27+
28+
deleteNamespace(true, namespace, shellOpts);
29+
}
30+
1531
export async function wipeAndRecreateNamespace(helmInstallName: string, namespace: string, shellOpts: ExecOptions) {
16-
await wipePreviewEnvironment(helmInstallName, namespace, shellOpts);
32+
await wipePreviewEnvironmentAndNamespace(helmInstallName, namespace, shellOpts);
1733

1834
createNamespace(namespace, shellOpts);
1935
}
2036

21-
export async function wipePreviewEnvironment(helmInstallName: string, namespace: string, shellOpts: ExecOptions) {
37+
export async function wipePreviewEnvironmentHelm(helmInstallName: string, namespace: string, shellOpts: ExecOptions) {
2238
// uninstall helm first so that:
2339
// - ws-scaler can't create new ghosts in the meantime
2440
// - ws-manager can't start new probes/workspaces
2541
uninstallHelm(helmInstallName, namespace, shellOpts)
42+
}
2643

27-
deleteAllWorkspaces(namespace, shellOpts);
28-
await deleteAllUnnamespacedObjects(namespace, shellOpts);
44+
async function wipePreviewEnvironmentInstaller(namespace: string, shellOpts: ExecOptions) {
45+
const slice = shellOpts.slice || "installer";
46+
const werft = getGlobalWerftInstance();
2947

30-
deleteNamespace(true, namespace, shellOpts);
48+
const hasGitpodConfigmap = (exec(`kubectl -n ${namespace} get configmap gitpod-app`, { slice, dontCheckRc: true })).code === 0;
49+
if (hasGitpodConfigmap) {
50+
werft.log(slice, `${namespace} has Gitpod configmap, proceeding with removal`);
51+
exec(`./.werft/util/uninstall-gitpod.sh ${namespace}`, { slice });
52+
} else {
53+
werft.log(slice, `There is no Gitpod configmap, moving on`);
54+
}
3155
}
3256

3357
function uninstallHelm(installationName: string, namespace: string, shellOpts: ExecOptions) {
@@ -43,6 +67,7 @@ function uninstallHelm(installationName: string, namespace: string, shellOpts: E
4367
exec(`helm --namespace ${namespace} delete ${installationName} --wait`, shellOpts);
4468
}
4569

70+
// Delete pods for running workspaces, even if they are stuck in terminating because of the finalizer decorator
4671
function deleteAllWorkspaces(namespace: string, shellOpts: ExecOptions) {
4772
const objs = exec(`kubectl get pod -l component=workspace --namespace ${namespace} --no-headers -o=custom-columns=:metadata.name`, { ...shellOpts, async: false })
4873
.split("\n")
@@ -74,13 +99,14 @@ async function deleteAllUnnamespacedObjects(namespace: string, shellOpts: ExecOp
7499

75100
const promisedDeletes: Promise<any>[] = [];
76101
for (const resType of ["clusterrole", "clusterrolebinding", "podsecuritypolicy"]) {
77-
werft.log(slice, `Deleting old ${resType}s...`);
102+
werft.log(slice, `Searching and filtering ${resType}s...`);
78103
const objs = exec(`kubectl get ${resType} --no-headers -o=custom-columns=:metadata.name`, { ...shellOpts, slice, async: false })
79104
.split("\n")
80105
.map(o => o.trim())
81106
.filter(o => o.length > 0)
82107
.filter(o => o.startsWith(`${namespace}-ns-`)); // "{{ .Release.Namespace }}-ns-" is the prefix-pattern we use throughout our helm resources for un-namespaced resources
83108

109+
werft.log(slice, `Deleting old ${resType}s...`);
84110
for (const obj of objs) {
85111
promisedDeletes.push(exec(`kubectl delete ${resType} ${obj}`, { ...shellOpts, slice, async: true }) as Promise<any>);
86112
}
@@ -127,7 +153,7 @@ export function deleteNamespace(wait: boolean, namespace: string, shellOpts: Exe
127153
}
128154
}
129155

130-
export function deleteNonNamespaceObjects(namespace: string, destname: string, shellOpts: ExecOptions) {
156+
export async function deleteNonNamespaceObjects(namespace: string, destname: string, shellOpts: ExecOptions) {
131157
exec(`/usr/local/bin/helm3 delete gitpod-${destname} || echo gitpod-${destname} was not installed yet`, { ...shellOpts });
132158

133159
let objs = [];
@@ -141,9 +167,11 @@ export function deleteNonNamespaceObjects(namespace: string, destname: string, s
141167
)
142168
)
143169

170+
const promisedDeletes: Promise<any>[] = [];
144171
objs.forEach(o => {
145-
exec(`kubectl delete ${o.kind} ${o.obj}`, shellOpts);
172+
promisedDeletes.push(exec(`kubectl delete ${o.kind} ${o.obj}`, {...shellOpts, async: true}) as Promise<any>);
146173
});
174+
await Promise.all(promisedDeletes);
147175
}
148176

149177
export interface PortRange {

.werft/util/uninstall-gitpod.sh

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
#!/bin/bash
2+
3+
set -euo pipefail
4+
5+
NAMESPACE=$1
6+
7+
if [[ -z ${NAMESPACE} ]]; then
8+
echo "One or more input params were invalid. The params we received were: ${NAMESPACE}"
9+
exit 1
10+
fi
11+
12+
echo "Removing Gitpod in namespace ${NAMESPACE}"
13+
kubectl get configmap gitpod-app -n "${NAMESPACE}" -o jsonpath='{.data.app\.yaml}' | kubectl delete -f -
14+
15+
echo "Removing Gitpod storage from ${NAMESPACE}"
16+
kubectl -n "${NAMESPACE}" delete pvc data-mysql-0
17+
# the installer includes the minio PVC in it's config mpap, this is a "just in case"
18+
kubectl -n "${NAMESPACE}" delete pvc minio || true
19+
20+
echo "Successfully removed Gitpod from ${NAMESPACE}"

.werft/wipe-devstaging.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import { Werft } from './util/werft'
2-
import { wipePreviewEnvironment, listAllPreviewNamespaces } from './util/kubectl';
2+
import { wipePreviewEnvironmentAndNamespace, listAllPreviewNamespaces, helmInstallName } from './util/kubectl';
33
import * as fs from 'fs';
44
import { deleteExternalIp } from './util/gcloud';
55
import * as Tracing from './observability/tracing'
@@ -23,7 +23,7 @@ async function wipePreviewCluster(shellOpts: ExecOptions) {
2323
}
2424

2525
for (const namespace of namespaces) {
26-
await wipePreviewEnvironment("gitpod", namespace, { ...shellOpts, slice: 'wipe' });
26+
await wipePreviewEnvironmentAndNamespace(helmInstallName, namespace, { ...shellOpts, slice: 'wipe' });
2727
}
2828
}
2929

installer/pkg/components/cluster/certmanager.go

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ package cluster
66

77
import (
88
"fmt"
9+
910
"github.com/gitpod-io/gitpod/installer/pkg/common"
1011
v1 "github.com/jetstack/cert-manager/pkg/apis/certmanager/v1"
1112
cmmeta "github.com/jetstack/cert-manager/pkg/apis/meta/v1"
@@ -22,8 +23,9 @@ func certmanager(ctx *common.RenderContext) ([]runtime.Object, error) {
2223
&v1.Issuer{
2324
TypeMeta: common.TypeMetaCertificateIssuer,
2425
ObjectMeta: metav1.ObjectMeta{
25-
Name: caIssuer,
26-
Labels: common.DefaultLabels(Component),
26+
Name: caIssuer,
27+
Labels: common.DefaultLabels(Component),
28+
Namespace: ctx.Namespace,
2729
},
2830
Spec: v1.IssuerSpec{IssuerConfig: v1.IssuerConfig{
2931
SelfSigned: &v1.SelfSignedIssuer{},

installer/pkg/components/image-builder-mk3/clusterrole.go

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -18,9 +18,8 @@ func clusterrole(ctx *common.RenderContext) ([]runtime.Object, error) {
1818
return []runtime.Object{&rbacv1.ClusterRole{
1919
TypeMeta: common.TypeMetaClusterRole,
2020
ObjectMeta: metav1.ObjectMeta{
21-
Name: fmt.Sprintf("%s-ns-%s", ctx.Namespace, Component),
22-
Namespace: ctx.Namespace,
23-
Labels: common.DefaultLabels(Component),
21+
Name: fmt.Sprintf("%s-ns-%s", ctx.Namespace, Component),
22+
Labels: common.DefaultLabels(Component),
2423
},
2524
Rules: []rbacv1.PolicyRule{{
2625
APIGroups: []string{"policy"},

installer/pkg/components/registry-facade/clusterrole.go

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -19,9 +19,8 @@ func clusterrole(ctx *common.RenderContext) ([]runtime.Object, error) {
1919
&rbacv1.ClusterRole{
2020
TypeMeta: common.TypeMetaClusterRole,
2121
ObjectMeta: metav1.ObjectMeta{
22-
Name: fmt.Sprintf("%s-ns-%s", ctx.Namespace, Component),
23-
Namespace: ctx.Namespace,
24-
Labels: common.DefaultLabels(Component),
22+
Name: fmt.Sprintf("%s-ns-%s", ctx.Namespace, Component),
23+
Labels: common.DefaultLabels(Component),
2524
},
2625
Rules: []rbacv1.PolicyRule{{
2726
APIGroups: []string{"policy"},

installer/pkg/components/registry-facade/podsecuritypolicy.go

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ package registryfacade
66

77
import (
88
"fmt"
9+
910
"github.com/gitpod-io/gitpod/installer/pkg/common"
1011

1112
"k8s.io/api/policy/v1beta1"
@@ -17,9 +18,8 @@ func podsecuritypolicy(ctx *common.RenderContext) ([]runtime.Object, error) {
1718
return []runtime.Object{&v1beta1.PodSecurityPolicy{
1819
TypeMeta: common.TypeMetaPodSecurityPolicy,
1920
ObjectMeta: metav1.ObjectMeta{
20-
Name: fmt.Sprintf("%s-ns-%s", ctx.Namespace, Component),
21-
Namespace: ctx.Namespace,
22-
Labels: common.DefaultLabels(Component),
21+
Name: fmt.Sprintf("%s-ns-%s", ctx.Namespace, Component),
22+
Labels: common.DefaultLabels(Component),
2323
Annotations: map[string]string{
2424
"seccomp.security.alpha.kubernetes.io/allowedProfileNames": "runtime/default",
2525
"apparmor.security.beta.kubernetes.io/allowedProfileNames": "runtime/default",

installer/pkg/components/server/configmap.go

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ package server
77
import (
88
"encoding/json"
99
"fmt"
10+
1011
"github.com/gitpod-io/gitpod/installer/pkg/common"
1112
"github.com/gitpod-io/gitpod/installer/pkg/components/workspace"
1213
corev1 "k8s.io/api/core/v1"
@@ -54,7 +55,7 @@ func configmap(ctx *common.RenderContext) ([]runtime.Object, error) {
5455
MinAgeDays: 14,
5556
MinAgePrebuildDays: 7,
5657
},
57-
EnableLocalApp: false,
58+
EnableLocalApp: true,
5859
AuthProviderConfigs: ctx.Config.AuthProviders,
5960
BuiltinAuthProvidersConfigured: len(ctx.Config.AuthProviders) > 0,
6061
DisableDynamicAuthProviderLogin: false,

0 commit comments

Comments
 (0)