Skip to content

Commit

Permalink
Add layering for OCI (#290)
Browse files Browse the repository at this point in the history
  • Loading branch information
taybenlor authored Jan 22, 2024
1 parent 58ebf49 commit 884c1c0
Show file tree
Hide file tree
Showing 5 changed files with 67 additions and 9 deletions.
9 changes: 8 additions & 1 deletion packages/runtime/lib/elements/container.ts
Original file line number Diff line number Diff line change
Expand Up @@ -211,7 +211,14 @@ export class ContainerElement extends HTMLElement {
return { resultType: "terminated" };
}
console.error(e);
this.terminal.write(`\nRunno crashed: ${e}`);
if (
e != null &&
(e instanceof Error || (typeof e === "object" && "message" in e))
) {
this.terminal.write(
`\n[Crashed] ${(e as any).type ?? "Error"}: ${e.message}\n`
);
}
return { resultType: "crash", error: makeRunnoError(e) };
} finally {
this.workerHost = undefined;
Expand Down
9 changes: 8 additions & 1 deletion packages/runtime/lib/elements/terminal.ts
Original file line number Diff line number Diff line change
Expand Up @@ -120,7 +120,14 @@ export class TerminalElement extends HTMLElement {
return { resultType: "terminated" };
}
console.error(e);
this.terminal.write(`\nRunno crashed: ${e}`);
if (
e != null &&
(e instanceof Error || (typeof e === "object" && "message" in e))
) {
this.terminal.write(
`\n[Crashed] ${(e as any).type ?? "Error"}: ${e.message}\n`
);
}
return { resultType: "crash", error: makeRunnoError(e) };
} finally {
this.workerHost = undefined;
Expand Down
9 changes: 8 additions & 1 deletion packages/runtime/lib/elements/wasi.ts
Original file line number Diff line number Diff line change
Expand Up @@ -227,7 +227,14 @@ export class WASIElement extends HTMLElement {
return { resultType: "terminated" };
}
console.error(e);
this.terminal.write(`\nRunno crashed: ${e}`);
if (
e != null &&
(e instanceof Error || (typeof e === "object" && "message" in e))
) {
this.terminal.write(
`\n[Crashed] ${(e as any).type ?? "Error"}: ${e.message}\n`
);
}
return { resultType: "crash", error: makeRunnoError(e) };
} finally {
this.workerHost = undefined;
Expand Down
31 changes: 27 additions & 4 deletions packages/runtime/lib/oci.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,11 +11,9 @@ type OCIContext = {
export async function extractOCIFile(binary: Uint8Array): Promise<OCIContext> {
const contents = await extractTarGz(binary);

// TODO: throw if the file doesn't exist or whatever
const manifestFile = contents["/manifest.json"];
const manifest = fileToJSON(manifestFile)[0];

// TODO: throw if the file doesn't exist or whatever
const configPath = manifest["Config"];

const config = fileToJSON(contents[`/${configPath}`]);
Expand All @@ -33,9 +31,34 @@ export async function extractOCIFile(binary: Uint8Array): Promise<OCIContext> {
})
);

// TODO: Implement the OCI spec for layering
// OCI spec for layering includes whiteout / deleting files
// https://github.com/opencontainers/image-spec/blob/main/layer.md
const fs = layers.reduce((prev, current) => ({ ...prev, ...current }), {});
const fs = layers.reduce((prev, current) => {
// Whiteout files must be applied first

const entries = Object.entries(current);
for (const [path] of entries) {
if (path.endsWith(".wh..wh..opq")) {
// Opaque whiteout, delete all siblings
const prefix = path.replace(".wh..wh..opq", "");
for (const [existingPath] of Object.entries(prev)) {
if (existingPath.startsWith(prefix)) {
delete prev[existingPath];
}
}
} else if (path.includes(".wh.")) {
// Regular whiteout - just delete this one file
const filename = path.replace(".wh.", "");
delete prev[filename];
}
}

const currentWithoutWhiteouts = Object.fromEntries(
entries.filter(([p]) => !p.includes(".wh."))
);

return { ...prev, ...currentWithoutWhiteouts };
}, {});

return {
fs,
Expand Down
18 changes: 16 additions & 2 deletions packages/runtime/lib/provider.ts
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,14 @@ export class RunnoProvider implements RuntimeMethods {
fs = prepare.fs;
} catch (e) {
console.error(e);
this.terminal.terminal.write(`\nRunno crashed: ${e}\n`);
if (
e != null &&
(e instanceof Error || (typeof e === "object" && "message" in e))
) {
this.terminal.terminal.write(
`\n[Crashed] ${(e as any).type ?? "Error"}: ${e.message}\n`
);
}

return {
resultType: "crash",
Expand All @@ -102,7 +109,14 @@ export class RunnoProvider implements RuntimeMethods {
fs = { ...fs, ...baseFS };
} catch (e) {
console.error(e);
this.terminal.terminal.write(`\nRunno crashed: ${e}\n`);
if (
e != null &&
(e instanceof Error || (typeof e === "object" && "message" in e))
) {
this.terminal.terminal.write(
`\n[Crashed] ${(e as any).type ?? "Error"}: ${e.message}\n`
);
}

return {
resultType: "crash",
Expand Down

0 comments on commit 884c1c0

Please sign in to comment.