triggerWorkflowOnComplete param for cloud runner

This commit is contained in:
Frostebite
2023-02-05 00:16:42 +00:00
parent e334dc785a
commit 00c5685d03
21 changed files with 241 additions and 86 deletions

View File

@@ -77,6 +77,9 @@ class AWSTaskRunner {
const containerState = taskData.containers?.[0];
const exitCode = containerState?.exitCode || undefined;
CloudRunnerLogger.log(`Container State: ${JSON.stringify(containerState, undefined, 4)}`);
if (exitCode === undefined) {
CloudRunnerLogger.logWarning(`No exitcode for container`);
}
const wasSuccessful = exitCode === 0 || (exitCode === undefined && taskData.lastStatus === 'RUNNING');
if (wasSuccessful) {
CloudRunnerLogger.log(`Cloud runner job has finished successfully`);

View File

@@ -129,14 +129,27 @@ class Kubernetes implements ProviderInterface {
this.jobName = `unity-builder-job-${this.buildGuid}`;
this.containerName = `main`;
await KubernetesSecret.createSecret(secrets, this.secretName, this.namespace, this.kubeClient);
await this.createNamespacedJob(commands, image, mountdir, workingdir, environment, secrets);
this.setPodNameAndContainerName(await Kubernetes.findPodFromJob(this.kubeClient, this.jobName, this.namespace));
CloudRunnerLogger.log('Watching pod until running');
await KubernetesTaskRunner.watchUntilPodRunning(this.kubeClient, this.podName, this.namespace);
let output = '';
// eslint-disable-next-line no-constant-condition
while (true) {
try {
let existsAlready = false;
let status;
try {
status = await this.kubeClient.readNamespacedPodStatus(this.podName, this.namespace);
CloudRunnerLogger.log(JSON.stringify(status.body.status?.containerStatuses, undefined, 4));
existsAlready = true;
} catch {
// empty
}
if (!existsAlready || status.state?.terminated !== undefined) {
CloudRunnerLogger.log('Job does not exist');
await this.createNamespacedJob(commands, image, mountdir, workingdir, environment, secrets);
const find = await Kubernetes.findPodFromJob(this.kubeClient, this.jobName, this.namespace);
this.setPodNameAndContainerName(find);
CloudRunnerLogger.log('Watching pod until running');
await KubernetesTaskRunner.watchUntilPodRunning(this.kubeClient, this.podName, this.namespace);
}
CloudRunnerLogger.log('Pod running, streaming logs');
output = await KubernetesTaskRunner.runTask(
this.kubeConfig,
@@ -163,11 +176,12 @@ class Kubernetes implements ProviderInterface {
errorParsed = error;
}
const reason = errorParsed.reason || errorParsed.response?.body?.reason || ``;
const errorMessage = errorParsed.message || reason;
const errorMessage =
errorParsed.name || errorParsed.reason || errorParsed.response?.body?.reason || errorParsed.message;
const continueStreaming =
errorMessage.includes(`dial timeout, backstop`) ||
errorMessage.includes(`HttpError`) ||
errorMessage.includes(`HttpError: HTTP request failed`) ||
errorMessage.includes(`an error occurred when try to find container`) ||
errorMessage.includes(`not found`) ||
@@ -192,6 +206,18 @@ class Kubernetes implements ProviderInterface {
}
}
private async doesJobExist(name) {
const jobs = await this.kubeClientBatch.listNamespacedJob(this.namespace);
return jobs.body.items.some((x) => x.metadata?.name === name);
}
private async doesFailedJobExist() {
const podStatus = await this.kubeClient.readNamespacedPodStatus(this.podName, this.namespace);
return podStatus.body.status?.phase === `Failed`;
}
private async createNamespacedJob(
commands: string,
image: string,
@@ -217,12 +243,12 @@ class Kubernetes implements ProviderInterface {
k8s,
);
await new Promise((promise) => setTimeout(promise, 15000));
await this.kubeClientBatch.createNamespacedJob(this.namespace, jobSpec);
const result = await this.kubeClientBatch.createNamespacedJob(this.namespace, jobSpec);
CloudRunnerLogger.log(`Build job created`);
await new Promise((promise) => setTimeout(promise, 5000));
CloudRunnerLogger.log('Job created');
return;
return result.body.metadata?.name;
} catch (error) {
CloudRunnerLogger.log(`Error occured creating job: ${error}`);
throw error;

View File

@@ -7,6 +7,7 @@ import waitUntil from 'async-wait-until';
import { FollowLogStreamService } from '../../services/follow-log-stream-service';
class KubernetesTaskRunner {
static lastReceivedTimestamp: number;
static async runTask(
kubeConfig: KubeConfig,
kubeClient: CoreV1Api,
@@ -33,15 +34,51 @@ class KubernetesTaskRunner {
));
next();
};
// export interface LogOptions {
/**
* Follow the log stream of the pod. Defaults to false.
*/
// follow?: boolean;
/**
* If set, the number of bytes to read from the server before terminating the log output. This may not display a
* complete final line of logging, and may return slightly more or slightly less than the specified limit.
*/
// limitBytes?: number;
/**
* If true, then the output is pretty printed.
*/
// pretty?: boolean;
/**
* Return previous terminated container logs. Defaults to false.
*/
// previous?: boolean;
/**
* A relative time in seconds before the current time from which to show logs. If this value precedes the time a
* pod was started, only logs since the pod start will be returned. If this value is in the future, no logs will
* be returned. Only one of sinceSeconds or sinceTime may be specified.
*/
// sinceSeconds?: number;
/**
* If set, the number of lines from the end of the logs to show. If not specified, logs are shown from the creation
* of the container or sinceSeconds or sinceTime
*/
// tailLines?: number;
/**
* If true, add an RFC3339 or RFC3339Nano timestamp at the beginning of every line of log output. Defaults to false.
*/
// timestamps?: boolean;
// }
const logOptions = {
follow: true,
pretty: false,
previous: false,
previous: true,
timestamps: true,
sinceSeconds: KubernetesTaskRunner.lastReceivedTimestamp,
};
try {
const resultError = await new Promise((resolve) =>
new Log(kubeConfig).log(namespace, podName, containerName, stream, resolve, logOptions),
);
const resultError = await new Log(kubeConfig).log(namespace, podName, containerName, stream, logOptions);
stream.destroy();
if (resultError) {
throw resultError;
@@ -73,6 +110,8 @@ class KubernetesTaskRunner {
if (stream) {
stream.destroy();
}
CloudRunnerLogger.log(JSON.stringify(error));
CloudRunnerLogger.log('k8s task runner failed');
throw error;
}
CloudRunnerLogger.log('end of log stream');