Skip to content

Commit

Permalink
src: shuttle a expose ID between expose and commit
Browse files Browse the repository at this point in the history
  • Loading branch information
adityamaru committed Dec 2, 2024
1 parent 4d1a78f commit 17d922a
Show file tree
Hide file tree
Showing 3 changed files with 26 additions and 16 deletions.
2 changes: 1 addition & 1 deletion dist/index.js

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion dist/index.js.map

Large diffs are not rendered by default.

38 changes: 24 additions & 14 deletions src/main.ts
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ async function getBlacksmithAgentClient(): Promise<AxiosInstance> {
}

// Reports a successful build to the local sticky disk manager
async function reportBuildCompleted(exportRes?: ExportRecordResponse, blacksmithDockerBuildId?: string | null, buildRef?: string, dockerBuildDurationSeconds?: string) {
async function reportBuildCompleted(exportRes?: ExportRecordResponse, blacksmithDockerBuildId?: string | null, buildRef?: string, dockerBuildDurationSeconds?: string, exposeId?: string) {
if (!blacksmithDockerBuildId) {
core.warning('No docker build ID found, skipping build completion report');
return;
Expand All @@ -48,6 +48,7 @@ async function reportBuildCompleted(exportRes?: ExportRecordResponse, blacksmith
const formData = new FormData();
formData.append('shouldCommit', 'true');
formData.append('vmID', process.env.VM_ID || '');
formData.append('exposeID', exposeId || '');
const retryCondition = (error: AxiosError) => {
return error.response?.status ? error.response.status > 500 : false;
};
Expand Down Expand Up @@ -91,7 +92,7 @@ async function reportBuildCompleted(exportRes?: ExportRecordResponse, blacksmith
}

// Reports a failed build to both the local sticky disk manager and the Blacksmith API
async function reportBuildFailed(dockerBuildId: string | null, dockerBuildDurationSeconds?: string) {
async function reportBuildFailed(dockerBuildId: string | null, dockerBuildDurationSeconds?: string, exposeId?: string | null) {
if (!dockerBuildId) {
core.warning('No docker build ID found, skipping build completion report');
return;
Expand All @@ -102,6 +103,7 @@ async function reportBuildFailed(dockerBuildId: string | null, dockerBuildDurati
const formData = new FormData();
formData.append('shouldCommit', 'false');
formData.append('vmID', process.env.VM_ID || '');
formData.append('exposeID', exposeId || '');
const retryCondition = (error: AxiosError) => {
return error.response?.status ? error.response.status > 500 : false;
};
Expand Down Expand Up @@ -206,7 +208,7 @@ async function getWithRetry(client: AxiosInstance, url: string, formData: FormDa
throw new Error('Max retries reached');
}

async function getStickyDisk(retryCondition: (error: AxiosError) => boolean, options?: {signal?: AbortSignal}): Promise<unknown> {
async function getStickyDisk(retryCondition: (error: AxiosError) => boolean, options?: {signal?: AbortSignal}): Promise<{expose_id: string}> {
const client = await getBlacksmithAgentClient();
const formData = new FormData();
// TODO(adityamaru): Support a stickydisk-per-build flag that will namespace the stickydisks by Dockerfile.
Expand All @@ -225,7 +227,11 @@ async function getStickyDisk(retryCondition: (error: AxiosError) => boolean, opt
core.debug(`${pair[0]}: ${pair[1]}`);
}
const response = await getWithRetry(client, '/stickydisks', formData, retryCondition, options);
return response.data;
// For backward compatibility, if expose_id is set, return it
if (response.data?.expose_id) {
return {expose_id: response.data.expose_id};
}
return {expose_id: ''};
}

async function getDiskSize(device: string): Promise<number> {
Expand Down Expand Up @@ -419,15 +425,17 @@ async function reportBuilderCreationFailed(stickydiskKey: string) {
// getBuilderAddr mounts a sticky disk for the entity, sets up buildkitd on top of it
// and returns the address to the builder.
// If it is unable to do so because of a timeout or an error it returns null.
async function getBuilderAddr(inputs: context.Inputs, dockerfilePath: string): Promise<{addr: string | null; buildId?: string | null}> {
async function getBuilderAddr(inputs: context.Inputs, dockerfilePath: string): Promise<{addr: string | null; buildId?: string | null; exposeId: string}> {
try {
const retryCondition = (error: AxiosError) => (error.response?.status ? error.response.status >= 500 : error.code === 'ECONNRESET');
const controller = new AbortController();
const timeoutId = setTimeout(() => controller.abort(), 10000);

let buildResponse: {docker_build_id: string} | null = null;
let exposeId: string = '';
try {
await getStickyDisk(retryCondition, {signal: controller.signal});
const stickyDiskResponse = await getStickyDisk(retryCondition, {signal: controller.signal});
exposeId = stickyDiskResponse.expose_id;
clearTimeout(timeoutId);
await maybeFormatBlockDevice(device);
buildResponse = await reportBuild(dockerfilePath);
Expand All @@ -436,7 +444,7 @@ async function getBuilderAddr(inputs: context.Inputs, dockerfilePath: string): P
core.debug(`${device} has been mounted to ${mountPoint}`);
} catch (error) {
if (error.name === 'AbortError') {
return {addr: null};
return {addr: null, exposeId: ''};
}
throw error;
}
Expand All @@ -463,7 +471,7 @@ async function getBuilderAddr(inputs: context.Inputs, dockerfilePath: string): P
if (!fs.existsSync('/run/buildkit/buildkitd.sock')) {
throw new Error('buildkitd socket not found after 3s timeout');
}
return {addr: buildkitdAddr, buildId: buildResponse?.docker_build_id};
return {addr: buildkitdAddr, buildId: buildResponse?.docker_build_id, exposeId: exposeId};
} catch (error) {
if ((error as AxiosError).response && (error as AxiosError).response!.status === 404) {
if (!inputs.nofallback) {
Expand All @@ -472,7 +480,7 @@ async function getBuilderAddr(inputs: context.Inputs, dockerfilePath: string): P
} else {
core.warning(`Error in getBuildkitdAddr: ${(error as Error).message}`);
}
return {addr: null};
return {addr: null, exposeId: ''};
}
}

Expand Down Expand Up @@ -538,7 +546,8 @@ actionsToolkit.run(

let builderInfo = {
addr: null as string | null,
buildId: null as string | null
buildId: null as string | null,
exposeId: '' as string
};
await core.group(`Starting Blacksmith builder`, async () => {
const dockerfilePath = context.getDockerfilePath(inputs);
Expand All @@ -554,10 +563,11 @@ actionsToolkit.run(
if (dockerfilePath && dockerfilePath.length > 0) {
core.debug(`Using dockerfile path: ${dockerfilePath}`);
}
const {addr, buildId} = await getBuilderAddr(inputs, dockerfilePath);
const {addr, buildId, exposeId} = await getBuilderAddr(inputs, dockerfilePath);
builderInfo = {
addr: addr || null,
buildId: buildId || null
buildId: buildId || null,
exposeId: exposeId
};
if (!builderInfo.addr) {
await reportBuilderCreationFailed(dockerfilePath);
Expand Down Expand Up @@ -761,7 +771,7 @@ actionsToolkit.run(
}
core.info('Unmounted device');
if (!buildError) {
await reportBuildCompleted(exportRes, builderInfo.buildId, ref, buildDurationSeconds);
await reportBuildCompleted(exportRes, builderInfo.buildId, ref, buildDurationSeconds, builderInfo.exposeId);
} else {
try {
const buildkitdLog = fs.readFileSync('buildkitd.log', 'utf8');
Expand All @@ -770,7 +780,7 @@ actionsToolkit.run(
} catch (error) {
core.warning(`Failed to read buildkitd.log: ${error.message}`);
}
await reportBuildFailed(builderInfo.buildId, buildDurationSeconds);
await reportBuildFailed(builderInfo.buildId, buildDurationSeconds, builderInfo.exposeId);
}
} catch (error) {
core.warning(`Error during Blacksmith builder shutdown: ${error.message}`);
Expand Down

0 comments on commit 17d922a

Please sign in to comment.