Skip to content

Commit 6f0f9b2

Browse files
author
Prince Rachit Sinha
authored
[werft] Add sweeper cleanup logic for k3s ws cluster (#4746)
* Update sweeper logic to delete k3s ws preview env and refactor methods and files
1 parent dd3d9de commit 6f0f9b2

File tree

3 files changed

+71
-6
lines changed

3 files changed

+71
-6
lines changed

.werft/util/gcloud.ts

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
import { werft, exec } from './shell';
2+
import { sleep } from './util';
3+
4+
export async function deleteExternalIp(phase: string, name: string, region = "europe-west1") {
5+
const ip = getExternalIp(name)
6+
werft.log(phase, `address describe returned: ${ip}`)
7+
if (ip.indexOf("ERROR:") != -1 || ip == "") {
8+
werft.log(phase, `no external static IP with matching name ${name} found`)
9+
return
10+
}
11+
12+
werft.log(phase, `found external static IP with matching name ${name}, will delete it`)
13+
const cmd = `gcloud compute addresses delete ${name} --region ${region} --quiet`
14+
let attempt = 0;
15+
for (attempt = 0; attempt < 10; attempt++) {
16+
let result = exec(cmd);
17+
if (result.code === 0 && result.stdout.indexOf("Error") == -1) {
18+
werft.log(phase, `external ip with name ${name} and ip ${ip} deleted`);
19+
break;
20+
} else {
21+
werft.log(phase, `external ip with name ${name} and ip ${ip} could not be deleted, will reattempt`)
22+
}
23+
await sleep(5000)
24+
}
25+
if (attempt == 10) {
26+
werft.log(phase, `could not delete the external ip with name ${name} and ip ${ip}`)
27+
}
28+
}
29+
30+
function getExternalIp(name: string, region = "europe-west1") {
31+
return exec(`gcloud compute addresses describe ${name} --region ${region}| grep 'address:' | cut -c 10-`, { silent: true }).trim();
32+
}

.werft/wipe-devstaging.ts

Lines changed: 38 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,23 +1,55 @@
1-
import { werft } from './util/shell';
1+
import { werft, exec } from './util/shell';
22
import { wipePreviewEnvironment, listAllPreviewNamespaces } from './util/kubectl';
3+
import * as fs from 'fs';
4+
import { deleteExternalIp } from './util/gcloud';
35

46

5-
async function wipeDevstaging() {
7+
async function wipePreviewCluster(pathToKubeConfig: string) {
68
const namespace_raw = process.env.NAMESPACE;
79
const namespaces: string[] = [];
810
if (namespace_raw === "<no value>" || !namespace_raw) {
911
werft.log('wipe', "Going to wipe all namespaces");
10-
listAllPreviewNamespaces("")
12+
listAllPreviewNamespaces(pathToKubeConfig)
1113
.map(ns => namespaces.push(ns));
1214
} else {
1315
werft.log('wipe', `Going to wipe namespace ${namespace_raw}`);
1416
namespaces.push(namespace_raw);
1517
}
1618

1719
for (const namespace of namespaces) {
18-
await wipePreviewEnvironment("", "gitpod", namespace, { slice: 'wipe' });
20+
await wipePreviewEnvironment(pathToKubeConfig, "gitpod", namespace, { slice: 'wipe' });
1921
}
20-
werft.done('wipe');
2122
}
2223

23-
wipeDevstaging()
24+
// if we have "/workspace/k3s-external.yaml" present that means a k3s ws cluster
25+
// exists, therefore, delete corresponding preview deployment from that cluster too
26+
// NOTE: Even for a non k3s ws deployment we will attempt to clean the preview.
27+
// This saves us from writing complex logic of querying meta cluster for registered workspaces
28+
// Since we use the same namespace to deploy in both dev and k3s cluster, this is safe
29+
async function k3sCleanup() {
30+
if (fs.existsSync("/workspace/k3s-external.yaml")) {
31+
werft.log("wipe", "found /workspace/k3s-external.yaml, assuming k3s ws cluster deployment exists, will attempt to wipe it")
32+
await wipePreviewCluster("/workspace/k3s-external.yaml")
33+
const namespace_raw = process.env.NAMESPACE;
34+
35+
// Since werft creates static external IP for ws-proxy of k3s using gcloud
36+
// we delete it here. We retry because the ws-proxy-service which binds to this IP might not be deleted immediately
37+
const k3sWsProxyIP =
38+
deleteExternalIp("wipe", namespace_raw)
39+
} else {
40+
werft.log("wipe", `file /workspace/k3s-external.yaml does not exist, no cleanup for k3s cluster`)
41+
}
42+
}
43+
44+
// clean up the dev cluster in gitpod-core-dev
45+
async function devCleanup() {
46+
await wipePreviewCluster("")
47+
}
48+
49+
// sweeper runs in the dev cluster so we need to delete the k3s cluster first and then delete self contained namespace
50+
k3sCleanup().then(() => {
51+
devCleanup()
52+
})
53+
54+
55+
werft.done('wipe');

.werft/wipe-devstaging.yaml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ pod:
3434
3535
export NAMESPACE="{{ .Annotations.namespace }}"
3636
sudo chown -R gitpod:gitpod /workspace
37+
kubectl get secret k3sdev -n werft -ojsonpath='{.data}' | jq -r .[] | base64 -d > /workspace/k3s-external.yaml
3738
3839
npm install shelljs semver ts-node typescript @types/shelljs @types/node @types/semver
3940
npx ts-node .werft/wipe-devstaging.ts

0 commit comments

Comments
 (0)