Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Seed] Initial dynamic seeding #9

Merged
merged 1 commit into from
Nov 17, 2023
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
146 changes: 79 additions & 67 deletions src/functions/v2/seed.ts
Original file line number Diff line number Diff line change
@@ -1,108 +1,120 @@
import { Response } from "@cloudflare/workers-types";

Check warning on line 1 in src/functions/v2/seed.ts

View workflow job for this annotation

GitHub Actions / ESLint

'Response' is defined but never used
import type { EventContext, PagesFunction } from "@cloudflare/workers-types";

Check warning on line 2 in src/functions/v2/seed.ts

View workflow job for this annotation

GitHub Actions / ESLint

'EventContext' is defined but never used

Check warning on line 2 in src/functions/v2/seed.ts

View workflow job for this annotation

GitHub Actions / ESLint

'PagesFunction' is defined but never used

import type { Env } from "@types/bindings";

let authHeader: string;

async function getAuth() {

Check failure on line 8 in src/functions/v2/seed.ts

View workflow job for this annotation

GitHub Actions / ESLint

Missing return type on function
const resp = await fetch(
"https://auth.docker.io/token?scope=repository%3Alibrary%2Fhello-world%3Apull&service=registry.docker.io"
);
return (
"Bearer " + ((await resp.json()) as Record<string, string>).access_token
);
return "Bearer " + ((await resp.json()) as Record<string, string>).token;

Check failure on line 12 in src/functions/v2/seed.ts

View workflow job for this annotation

GitHub Actions / ESLint

Operands of '+' operation must either be both strings or both numbers. Consider using a template literal
}

async function seedKV(env: Env) {
await env.containerFlareKV.put(
"hello-world/latest",
`sha256:e18f0a777aefabe047a671ab3ec3eed05414477c951ab1a6f352a06974245fe7`
async function seedTag(env: Env, tag: string) {

Check failure on line 15 in src/functions/v2/seed.ts

View workflow job for this annotation

GitHub Actions / ESLint

Missing return type on function
// Get hello-world:latest
const label_req = await fetch(

Check failure on line 17 in src/functions/v2/seed.ts

View workflow job for this annotation

GitHub Actions / ESLint

Variable name `label_req` must match one of the following formats: camelCase, PascalCase, UPPER_CASE
"https://registry-1.docker.io/v2/library/hello-world/manifests/latest",
{
method: "HEAD",
headers: {
Authorization: authHeader,
Accept: "application/vnd.docker.distribution.manifest.list.v2+json",
},
}
);

await env.containerFlareKV.put(
"e18f0a777aefabe047a671ab3ec3eed05414477c951ab1a6f352a06974245fe7",
`{
"manifests": [
{
"digest": "sha256:f54a58bc1aac5ea1a25d796ae155dc228b3f0e11d046ae276b39c4bf2f13d8c4",
"mediaType": "application/vnd.docker.distribution.manifest.v2+json",
"platform": {
"architecture": "amd64",
"os": "linux"
},
"size": 525
}
],
"mediaType": "application/vnd.docker.distribution.manifest.list.v2+json",
"schemaVersion": 2
}`
);
if (label_req.status != 200) {

Check failure on line 28 in src/functions/v2/seed.ts

View workflow job for this annotation

GitHub Actions / ESLint

Expected '!==' and instead saw '!='
console.error("Tag does not exist", label_req.statusText);
return;
}

await env.containerFlareKV.put(
"f54a58bc1aac5ea1a25d796ae155dc228b3f0e11d046ae276b39c4bf2f13d8c4",
`{
"schemaVersion": 2,
"mediaType": "application/vnd.docker.distribution.manifest.v2+json",
"config": {
"mediaType": "application/vnd.docker.container.image.v1+json",
"size": 1469,
"digest": "sha256:feb5d9fea6a5e9606aa995e879d862b825965ba48de054caab5ef356dc6b3412"
},
"layers": [
{
"mediaType": "application/vnd.docker.image.rootfs.diff.tar.gzip",
"size": 2479,
"digest": "sha256:2db29710123e3e53a794f2694094b9b4338aa9ee5c40b930cb8063a1be392c54"
}
]
}`
);
console.log(await label_req.text());

const sha_hash = await label_req.headers.get("docker-content-digest")!;

Check warning on line 35 in src/functions/v2/seed.ts

View workflow job for this annotation

GitHub Actions / ESLint

Forbidden non-null assertion
await env.containerFlareKV.put(tag, sha_hash);
console.log(sha_hash);
seedOS(env, sha_hash);
}

async function seedR2(env: Env) {
const req = await fetch(
"https://registry-1.docker.io/v2/library/hello-world/blobs/sha256:2db29710123e3e53a794f2694094b9b4338aa9ee5c40b930cb8063a1be392c54",
async function seedOS(env: Env, hash: string) {
// Get sha256:
const label_req = await fetch(
`https://registry-1.docker.io/v2/library/hello-world/manifests/${hash}`,
{
method: "GET",
headers: {
Authorization: authHeader,
Accept: "application/vnd.docker.distribution.manifest.list.v2+json",
},
}
);

if (req.status != 200) {
console.error("Seed not 200", req.statusText);
if (label_req.status != 200) {
console.error("OS list does not exist", label_req.statusText);
return;
}

await env.containerFlareR2.put(
"sha256:2db29710123e3e53a794f2694094b9b4338aa9ee5c40b930cb8063a1be392c54",
await req.arrayBuffer()
);
const os_list = await label_req.text();
await env.containerFlareKV.put(hash, os_list);
const os_json = JSON.parse(os_list) as Record<any, any>;

Check warning on line 61 in src/functions/v2/seed.ts

View workflow job for this annotation

GitHub Actions / ESLint

Unexpected any. Specify a different type

Check warning on line 61 in src/functions/v2/seed.ts

View workflow job for this annotation

GitHub Actions / ESLint

Unexpected any. Specify a different type

const req2 = await fetch(
"https://registry-1.docker.io/v2/library/hello-world/blobs/sha256:feb5d9fea6a5e9606aa995e879d862b825965ba48de054caab5ef356dc6b3412",
for (var key in os_json.manifests) {
seedImage(env, os_json.manifests[key].digest);
}
}

async function seedImage(env: Env, hash: string) {
// Get sha256:
const label_req = await fetch(
`https://registry-1.docker.io/v2/library/hello-world/manifests/${hash}`,
{
method: "GET",
headers: {
Authorization: authHeader,
Accept: "application/vnd.docker.distribution.manifest.v2+json",
},
}
);

await env.containerFlareR2.put(
"sha256:feb5d9fea6a5e9606aa995e879d862b825965ba48de054caab5ef356dc6b3412",
await req2.arrayBuffer()
);
if (label_req.status != 200) {
console.error("OS list does not exist", label_req.statusText);
return;
}

const os_list = await label_req.text();
await env.containerFlareKV.put(hash, os_list);
const image_json = JSON.parse(os_list) as Record<any, any>;

Check warning on line 88 in src/functions/v2/seed.ts

View workflow job for this annotation

GitHub Actions / ESLint

Unexpected any. Specify a different type

Check warning on line 88 in src/functions/v2/seed.ts

View workflow job for this annotation

GitHub Actions / ESLint

Unexpected any. Specify a different type

seedBlob(env, image_json.config.digest);
for (var key in image_json.layers) {
seedBlob(env, image_json.layers[key].digest);
}
}

export const onRequestGet: PagesFunction<Env> = async (
context: EventContext<Env, "", Record<string, unknown>>
) => {
if (context.env.ENVIRONMENT !== "development") {
return new Response("", { status: 404 });
async function seedBlob(env: Env, hash: string) {
const req = await fetch(
`https://registry-1.docker.io/v2/library/hello-world/blobs/${hash}`,
{
headers: {
Authorization: authHeader,
},
}
);

if (req.status != 200) {
console.error("Seed not 200", req.statusText);
}

await env.containerFlareR2.put(hash, await req.arrayBuffer());
}

async function seed(env: Env, tag: string) {
console.log("Seeding...");
authHeader = await getAuth();
await Promise.all([seedKV(context.env), seedR2(context.env)]);
return new Response("Seeding done");
};
await seedTag(env, tag);
console.log("DONE Seeding");
}

export default seed;
Loading