Skip to content

Instantly share code, notes, and snippets.

@lukehoban
Last active August 4, 2020 21:03
Show Gist options
  • Star 4 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save lukehoban/fd0355ed5b82386bd89c0ffe2a3c916a to your computer and use it in GitHub Desktop.
Save lukehoban/fd0355ed5b82386bd89c0ffe2a3c916a to your computer and use it in GitHub Desktop.
Pulumi program which waits on Jobs during a Kubernetes deployment
import * as pulumi from "@pulumi/pulumi";
import * as k8s from "@pulumi/kubernetes";
import * as k8sOutput from "@pulumi/kubernetes/types/output";
import * as k8sapi from 'kubernetes-client';
const job = new k8s.batch.v1.Job("job", {
spec: {
template: {
spec: {
containers: [{
name: "helloworld",
image: "hello-world",
}],
restartPolicy: "Never",
},
},
},
});
async function waitForJob(jobMetadata: k8sOutput.meta.v1.ObjectMeta): Promise<any> {
if (!pulumi.runtime.isDryRun()) {
// TODO: Note that this needs to be adjusted to use the same configuration as the Pulumi
// Kubernetes provider
const client = new k8sapi.Client1_13({ config: k8sapi.config.fromKubeconfig() });
// Wait for up to 10 minutes
for (let i = 0; i < 60; i++) {
const jobDetails = await client.apis.batch.v1.namespace(jobMetadata.namespace).job(jobMetadata.name).get();
if (jobDetails.body && jobDetails.body.status && jobDetails.body.status.succeeded > 0) {
return jobDetails.body;
}
pulumi.log.info(`Waiting for Job to finish (${i})`, job)
// Wait for 10s between polls
await new Promise(r => setTimeout(r, 10000));
}
throw new Error("timed out waiting for Job to complete");
}
}
// Compute an output value which waits for the Job to be done.
const jobDone = job.metadata.apply(metadata => waitForJob(metadata));
const job2 = new k8s.batch.v1.Job("job2", {
metadata: {
annotations: {
// This is a way to make the `job2` Job depend on the wait logic above. We take
// advantage of this to write the value into an annotation, but we could also ignore the
// value.
"pulumi-waited-on-completion": jobDone.apply(j => j.status.completionTime),
}
},
spec: {
template: {
spec: {
containers: [{
name: "helloworld",
image: "hello-world",
}],
restartPolicy: "Never",
},
},
},
});
const job2Done = job2.metadata.apply(metadata => waitForJob(metadata));
export const jobId = job.id;
export const jobStatus = job.status;
export const jobDoneDetails = jobDone;
export const job2DoneDetails = job2Done;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment