src: shuttle a expose ID between expose and commit
parent
4d1a78faea
commit
17d922af1a
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
38
src/main.ts
38
src/main.ts
|
@ -37,7 +37,7 @@ async function getBlacksmithAgentClient(): Promise<AxiosInstance> {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Reports a successful build to the local sticky disk manager
|
// 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) {
|
if (!blacksmithDockerBuildId) {
|
||||||
core.warning('No docker build ID found, skipping build completion report');
|
core.warning('No docker build ID found, skipping build completion report');
|
||||||
return;
|
return;
|
||||||
|
@ -48,6 +48,7 @@ async function reportBuildCompleted(exportRes?: ExportRecordResponse, blacksmith
|
||||||
const formData = new FormData();
|
const formData = new FormData();
|
||||||
formData.append('shouldCommit', 'true');
|
formData.append('shouldCommit', 'true');
|
||||||
formData.append('vmID', process.env.VM_ID || '');
|
formData.append('vmID', process.env.VM_ID || '');
|
||||||
|
formData.append('exposeID', exposeId || '');
|
||||||
const retryCondition = (error: AxiosError) => {
|
const retryCondition = (error: AxiosError) => {
|
||||||
return error.response?.status ? error.response.status > 500 : false;
|
return error.response?.status ? error.response.status > 500 : false;
|
||||||
};
|
};
|
||||||
|
@ -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
|
// 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) {
|
if (!dockerBuildId) {
|
||||||
core.warning('No docker build ID found, skipping build completion report');
|
core.warning('No docker build ID found, skipping build completion report');
|
||||||
return;
|
return;
|
||||||
|
@ -102,6 +103,7 @@ async function reportBuildFailed(dockerBuildId: string | null, dockerBuildDurati
|
||||||
const formData = new FormData();
|
const formData = new FormData();
|
||||||
formData.append('shouldCommit', 'false');
|
formData.append('shouldCommit', 'false');
|
||||||
formData.append('vmID', process.env.VM_ID || '');
|
formData.append('vmID', process.env.VM_ID || '');
|
||||||
|
formData.append('exposeID', exposeId || '');
|
||||||
const retryCondition = (error: AxiosError) => {
|
const retryCondition = (error: AxiosError) => {
|
||||||
return error.response?.status ? error.response.status > 500 : false;
|
return error.response?.status ? error.response.status > 500 : false;
|
||||||
};
|
};
|
||||||
|
@ -206,7 +208,7 @@ async function getWithRetry(client: AxiosInstance, url: string, formData: FormDa
|
||||||
throw new Error('Max retries reached');
|
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 client = await getBlacksmithAgentClient();
|
||||||
const formData = new FormData();
|
const formData = new FormData();
|
||||||
// TODO(adityamaru): Support a stickydisk-per-build flag that will namespace the stickydisks by Dockerfile.
|
// TODO(adityamaru): Support a stickydisk-per-build flag that will namespace the stickydisks by Dockerfile.
|
||||||
|
@ -225,7 +227,11 @@ async function getStickyDisk(retryCondition: (error: AxiosError) => boolean, opt
|
||||||
core.debug(`${pair[0]}: ${pair[1]}`);
|
core.debug(`${pair[0]}: ${pair[1]}`);
|
||||||
}
|
}
|
||||||
const response = await getWithRetry(client, '/stickydisks', formData, retryCondition, options);
|
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> {
|
async function getDiskSize(device: string): Promise<number> {
|
||||||
|
@ -419,15 +425,17 @@ async function reportBuilderCreationFailed(stickydiskKey: string) {
|
||||||
// getBuilderAddr mounts a sticky disk for the entity, sets up buildkitd on top of it
|
// getBuilderAddr mounts a sticky disk for the entity, sets up buildkitd on top of it
|
||||||
// and returns the address to the builder.
|
// and returns the address to the builder.
|
||||||
// If it is unable to do so because of a timeout or an error it returns null.
|
// 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 {
|
try {
|
||||||
const retryCondition = (error: AxiosError) => (error.response?.status ? error.response.status >= 500 : error.code === 'ECONNRESET');
|
const retryCondition = (error: AxiosError) => (error.response?.status ? error.response.status >= 500 : error.code === 'ECONNRESET');
|
||||||
const controller = new AbortController();
|
const controller = new AbortController();
|
||||||
const timeoutId = setTimeout(() => controller.abort(), 10000);
|
const timeoutId = setTimeout(() => controller.abort(), 10000);
|
||||||
|
|
||||||
let buildResponse: {docker_build_id: string} | null = null;
|
let buildResponse: {docker_build_id: string} | null = null;
|
||||||
|
let exposeId: string = '';
|
||||||
try {
|
try {
|
||||||
await getStickyDisk(retryCondition, {signal: controller.signal});
|
const stickyDiskResponse = await getStickyDisk(retryCondition, {signal: controller.signal});
|
||||||
|
exposeId = stickyDiskResponse.expose_id;
|
||||||
clearTimeout(timeoutId);
|
clearTimeout(timeoutId);
|
||||||
await maybeFormatBlockDevice(device);
|
await maybeFormatBlockDevice(device);
|
||||||
buildResponse = await reportBuild(dockerfilePath);
|
buildResponse = await reportBuild(dockerfilePath);
|
||||||
|
@ -436,7 +444,7 @@ async function getBuilderAddr(inputs: context.Inputs, dockerfilePath: string): P
|
||||||
core.debug(`${device} has been mounted to ${mountPoint}`);
|
core.debug(`${device} has been mounted to ${mountPoint}`);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
if (error.name === 'AbortError') {
|
if (error.name === 'AbortError') {
|
||||||
return {addr: null};
|
return {addr: null, exposeId: ''};
|
||||||
}
|
}
|
||||||
throw error;
|
throw error;
|
||||||
}
|
}
|
||||||
|
@ -463,7 +471,7 @@ async function getBuilderAddr(inputs: context.Inputs, dockerfilePath: string): P
|
||||||
if (!fs.existsSync('/run/buildkit/buildkitd.sock')) {
|
if (!fs.existsSync('/run/buildkit/buildkitd.sock')) {
|
||||||
throw new Error('buildkitd socket not found after 3s timeout');
|
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) {
|
} catch (error) {
|
||||||
if ((error as AxiosError).response && (error as AxiosError).response!.status === 404) {
|
if ((error as AxiosError).response && (error as AxiosError).response!.status === 404) {
|
||||||
if (!inputs.nofallback) {
|
if (!inputs.nofallback) {
|
||||||
|
@ -472,7 +480,7 @@ async function getBuilderAddr(inputs: context.Inputs, dockerfilePath: string): P
|
||||||
} else {
|
} else {
|
||||||
core.warning(`Error in getBuildkitdAddr: ${(error as Error).message}`);
|
core.warning(`Error in getBuildkitdAddr: ${(error as Error).message}`);
|
||||||
}
|
}
|
||||||
return {addr: null};
|
return {addr: null, exposeId: ''};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -538,7 +546,8 @@ actionsToolkit.run(
|
||||||
|
|
||||||
let builderInfo = {
|
let builderInfo = {
|
||||||
addr: null as string | null,
|
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 () => {
|
await core.group(`Starting Blacksmith builder`, async () => {
|
||||||
const dockerfilePath = context.getDockerfilePath(inputs);
|
const dockerfilePath = context.getDockerfilePath(inputs);
|
||||||
|
@ -554,10 +563,11 @@ actionsToolkit.run(
|
||||||
if (dockerfilePath && dockerfilePath.length > 0) {
|
if (dockerfilePath && dockerfilePath.length > 0) {
|
||||||
core.debug(`Using dockerfile path: ${dockerfilePath}`);
|
core.debug(`Using dockerfile path: ${dockerfilePath}`);
|
||||||
}
|
}
|
||||||
const {addr, buildId} = await getBuilderAddr(inputs, dockerfilePath);
|
const {addr, buildId, exposeId} = await getBuilderAddr(inputs, dockerfilePath);
|
||||||
builderInfo = {
|
builderInfo = {
|
||||||
addr: addr || null,
|
addr: addr || null,
|
||||||
buildId: buildId || null
|
buildId: buildId || null,
|
||||||
|
exposeId: exposeId
|
||||||
};
|
};
|
||||||
if (!builderInfo.addr) {
|
if (!builderInfo.addr) {
|
||||||
await reportBuilderCreationFailed(dockerfilePath);
|
await reportBuilderCreationFailed(dockerfilePath);
|
||||||
|
@ -761,7 +771,7 @@ actionsToolkit.run(
|
||||||
}
|
}
|
||||||
core.info('Unmounted device');
|
core.info('Unmounted device');
|
||||||
if (!buildError) {
|
if (!buildError) {
|
||||||
await reportBuildCompleted(exportRes, builderInfo.buildId, ref, buildDurationSeconds);
|
await reportBuildCompleted(exportRes, builderInfo.buildId, ref, buildDurationSeconds, builderInfo.exposeId);
|
||||||
} else {
|
} else {
|
||||||
try {
|
try {
|
||||||
const buildkitdLog = fs.readFileSync('buildkitd.log', 'utf8');
|
const buildkitdLog = fs.readFileSync('buildkitd.log', 'utf8');
|
||||||
|
@ -770,7 +780,7 @@ actionsToolkit.run(
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
core.warning(`Failed to read buildkitd.log: ${error.message}`);
|
core.warning(`Failed to read buildkitd.log: ${error.message}`);
|
||||||
}
|
}
|
||||||
await reportBuildFailed(builderInfo.buildId, buildDurationSeconds);
|
await reportBuildFailed(builderInfo.buildId, buildDurationSeconds, builderInfo.exposeId);
|
||||||
}
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
core.warning(`Error during Blacksmith builder shutdown: ${error.message}`);
|
core.warning(`Error during Blacksmith builder shutdown: ${error.message}`);
|
||||||
|
|
Loading…
Reference in New Issue