Last active
May 17, 2024 16:23
-
-
Save lukehoban/fd0355ed5b82386bd89c0ffe2a3c916a to your computer and use it in GitHub Desktop.
Pulumi program which waits on Jobs during a Kubernetes deployment
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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