Skip to content

Commit 7dd98f8

Browse files
ArthurSensroboquat
authored andcommitted
werft/deploy: Trigger VM creation before container builds
Signed-off-by: ArthurSens <arthursens2005@gmail.com>
1 parent d469aa6 commit 7dd98f8

File tree

4 files changed

+49
-30
lines changed

4 files changed

+49
-30
lines changed

.werft/build.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@ async function run(context: any) {
4545
const config = jobConfig(werft, context)
4646

4747
await validateChanges(werft, config)
48-
await prepare(werft)
48+
await prepare(werft, config)
4949
await buildAndPublish(werft, config)
5050
await coverage(werft, config)
5151

.werft/jobs/build/deploy-to-preview-environment.ts

+6-22
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ const STACKDRIVER_SERVICEACCOUNT = JSON.parse(fs.readFileSync(`/mnt/secrets/moni
1919
const phases = {
2020
PREDEPLOY: 'predeploy',
2121
DEPLOY: 'deploy',
22-
VM: 'vm'
22+
VM: 'Ensure VM Readiness'
2323
}
2424

2525
// Werft slices for deploy phase via installer
@@ -38,7 +38,7 @@ const installerSlices = {
3838
}
3939

4040
const vmSlices = {
41-
BOOT_VM: 'Booting VM',
41+
VM_READINESS: 'Waiting for VM readiness',
4242
START_KUBECTL_PORT_FORWARDS: 'Start kubectl port forwards',
4343
COPY_CERT_MANAGER_RESOURCES: 'Copy CertManager resources from core-dev',
4444
INSTALL_LETS_ENCRYPT_ISSUER: 'Install Lets Encrypt issuer',
@@ -101,32 +101,16 @@ export async function deployToPreviewEnvironment(werft: Werft, jobConfig: JobCon
101101
exec(`kubectl get secret ${withVM ? 'preview-envs-authproviders-harvester' : 'preview-envs-authproviders'} --namespace=keys -o jsonpath="{.data.authProviders}" > auth-provider-secret.yml`, { silent: true })
102102

103103
if (withVM) {
104-
werft.phase(phases.VM, "Start VM");
104+
werft.phase(phases.VM, "Ensuring VM is ready for deployment");
105105

106106
werft.log(vmSlices.COPY_CERT_MANAGER_RESOURCES, 'Copy over CertManager resources from core-dev')
107107
exec(`kubectl get secret clouddns-dns01-solver-svc-acct -n certmanager -o yaml | sed 's/namespace: certmanager/namespace: cert-manager/g' > clouddns-dns01-solver-svc-acct.yaml`, { slice: vmSlices.COPY_CERT_MANAGER_RESOURCES })
108108
exec(`kubectl get clusterissuer letsencrypt-issuer-gitpod-core-dev -o yaml | sed 's/letsencrypt-issuer-gitpod-core-dev/letsencrypt-issuer/g' > letsencrypt-issuer.yaml`, { slice: vmSlices.COPY_CERT_MANAGER_RESOURCES })
109109
werft.done(vmSlices.COPY_CERT_MANAGER_RESOURCES)
110110

111-
const existingVM = VM.vmExists({ name: destname })
112-
if (!existingVM) {
113-
werft.log(vmSlices.BOOT_VM, 'Starting VM')
114-
VM.startVM({ name: destname })
115-
werft.currentPhaseSpan.setAttribute("werft.harvester.created_vm", true)
116-
} else if (cleanSlateDeployment) {
117-
werft.log(vmSlices.BOOT_VM, 'Removing existing namespace')
118-
VM.deleteVM({ name: destname })
119-
werft.log(vmSlices.BOOT_VM, 'Starting VM')
120-
VM.startVM({ name: destname })
121-
werft.currentPhaseSpan.setAttribute("werft.harvester.created_vm", true)
122-
} else {
123-
werft.log(vmSlices.BOOT_VM, 'VM already exists')
124-
werft.currentPhaseSpan.setAttribute("werft.harvester.created_vm", false)
125-
}
126-
127-
werft.log(vmSlices.BOOT_VM, 'Waiting for VM to be ready')
128-
VM.waitForVM({ name: destname, timeoutSeconds: 60 * 10, slice: vmSlices.BOOT_VM })
129-
werft.done(vmSlices.BOOT_VM)
111+
werft.log(vmSlices.VM_READINESS, 'Wait for VM readiness')
112+
VM.waitForVMReadiness({ name: destname, timeoutSeconds: 60 * 10, slice: vmSlices.VM_READINESS })
113+
werft.done(vmSlices.VM_READINESS)
130114

131115
werft.log(vmSlices.START_KUBECTL_PORT_FORWARDS, 'Starting SSH port forwarding')
132116
VM.startSSHProxy({ name: destname, slice: vmSlices.START_KUBECTL_PORT_FORWARDS })

.werft/jobs/build/prepare.ts

+41-6
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,26 @@
11
import { exec } from '../../util/shell';
22
import { Werft } from "../../util/werft";
3+
import * as VM from '../../vm/vm'
34
import { GCLOUD_SERVICE_ACCOUNT_PATH } from "./const";
5+
import { JobConfig } from './job-config';
46

57
const phaseName = "prepare";
8+
const prepareSlices = {
9+
CONFIGURE_CORE_DEV: "Configuring core-dev access.",
10+
BOOT_VM: "Booting VM."
11+
}
612

7-
export async function prepare(werft: Werft) {
13+
export async function prepare(werft: Werft, config: JobConfig) {
814
werft.phase(phaseName);
915
try {
16+
werft.log(prepareSlices.CONFIGURE_CORE_DEV, prepareSlices.CONFIGURE_CORE_DEV)
1017
compareWerftAndGitpodImage()
1118
activateCoreDevServiceAccount()
1219
configureDocker()
1320
configureCoreDevAccess()
21+
werft.done(prepareSlices.CONFIGURE_CORE_DEV)
22+
23+
decideHarvesterVMCreation(werft, config)
1424
} catch (err) {
1525
werft.fail(phaseName, err);
1626
}
@@ -27,26 +37,51 @@ function compareWerftAndGitpodImage() {
2737
}
2838

2939
function activateCoreDevServiceAccount() {
30-
const rc = exec(`gcloud auth activate-service-account --key-file "${GCLOUD_SERVICE_ACCOUNT_PATH}"`, { slice: phaseName }).code;
40+
const rc = exec(`gcloud auth activate-service-account --key-file "${GCLOUD_SERVICE_ACCOUNT_PATH}"`, { slice: prepareSlices.CONFIGURE_CORE_DEV }).code;
3141

3242
if (rc != 0) {
3343
throw new Error("Failed to activate core-dev service account.")
3444
}
3545
}
3646

3747
function configureDocker() {
38-
const rcDocker = exec("gcloud auth configure-docker --quiet", { slice: phaseName }).code;
39-
const rcDockerRegistry = exec("gcloud auth configure-docker europe-docker.pkg.dev --quiet", { slice: phaseName }).code;
48+
const rcDocker = exec("gcloud auth configure-docker --quiet", { slice: prepareSlices.CONFIGURE_CORE_DEV }).code;
49+
const rcDockerRegistry = exec("gcloud auth configure-docker europe-docker.pkg.dev --quiet", { slice: prepareSlices.CONFIGURE_CORE_DEV }).code;
4050

4151
if (rcDocker != 0 || rcDockerRegistry != 0) {
4252
throw new Error("Failed to configure docker with gcloud.")
4353
}
4454
}
4555

4656
function configureCoreDevAccess() {
47-
const rc = exec('gcloud container clusters get-credentials core-dev --zone europe-west1-b --project gitpod-core-dev', { slice: phaseName }).code;
57+
const rc = exec('gcloud container clusters get-credentials core-dev --zone europe-west1-b --project gitpod-core-dev', { slice: prepareSlices.CONFIGURE_CORE_DEV }).code;
4858

4959
if (rc != 0) {
5060
throw new Error("Failed to get core-dev kubeconfig credentials.")
5161
}
52-
}
62+
}
63+
64+
function decideHarvesterVMCreation(werft: Werft, config: JobConfig) {
65+
if (config.withVM && !VM.vmExists({ name: config.previewEnvironment.destname })) {
66+
prepareVM(werft, config)
67+
} else {
68+
werft.currentPhaseSpan.setAttribute("werft.harvester.created_vm", false)
69+
}
70+
werft.done(prepareSlices.BOOT_VM)
71+
}
72+
73+
function prepareVM(werft: Werft, config: JobConfig) {
74+
if (config.cleanSlateDeployment) {
75+
werft.log(prepareSlices.BOOT_VM, "Cleaning previously created VM")
76+
VM.deleteVM({ name: config.previewEnvironment.destname })
77+
}
78+
createVM(werft, config, prepareSlices.BOOT_VM)
79+
}
80+
81+
// createVM only triggers the VM creation.
82+
// Readiness is not guaranted.
83+
function createVM(werft: Werft, config: JobConfig, slice: string) {
84+
werft.log(slice, 'Booting VM')
85+
VM.startVM({ name: config.previewEnvironment.destname })
86+
werft.currentPhaseSpan.setAttribute("werft.harvester.created_vm", true)
87+
}

.werft/vm/vm.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -123,7 +123,7 @@ export function vmExists(options: { name: string }) {
123123
* Wait until the VM Instance reaches the Running status.
124124
* If the VM Instance doesn't reach Running before the timeoutMS it will throw an Error.
125125
*/
126-
export function waitForVM(options: { name: string, timeoutSeconds: number, slice: string }) {
126+
export function waitForVMReadiness(options: { name: string, timeoutSeconds: number, slice: string }) {
127127
const werft = getGlobalWerftInstance()
128128
const namespace = `preview-${options.name}`
129129

0 commit comments

Comments
 (0)