121 lines · 4.7 KB
import { waitUntil } from "cloudflare:workers";
import { jobDb } from "../scope";
import { tarHeader, tarPadding, TAR_BLOCK } from "../../tar";
import { imageBlob, imageTag } from "./images";
import type { BlobDescriptor, ResolvedImage } from "./images";
import type { CompiledJob } from "../compile";

const OCI_INDEX = "application/vnd.oci.image.index.v1+json";
const FILE_MODE = 0o644;
const encoder = new TextEncoder();

function blobPath(digest: string): string {
  return `blobs/sha256/${digest.replace("sha256:", "")}`;
}

/**
 * The tar `docker load` takes: an OCI image layout (index.json + blobs) that also carries the classic
 * manifest.json, the same shape `docker save` writes, tagged so steps can run it by `imageTag(digest)`.
 */
function layoutFiles(image: ResolvedImage): Array<[string, Uint8Array]> {
  const tag = imageTag(image.digest);
  const index = {
    schemaVersion: 2,
    mediaType: OCI_INDEX,
    manifests: [
      {
        mediaType: image.mediaType,
        digest: image.digest,
        size: image.manifestSize,
        annotations: {
          "io.containerd.image.name": `docker.io/${tag}`,
          "org.opencontainers.image.ref.name": tag.split(":")[1],
        },
      },
    ],
  };
  const manifest = [
    {
      Config: blobPath(image.config.digest),
      RepoTags: [tag],