Skip to content

Commit b6baa86

Browse files
committed
Merge branch 'feature/deploy-from-ghcr'
2 parents 1f0cf68 + 1b0a0de commit b6baa86

File tree

9 files changed

+524
-28
lines changed

9 files changed

+524
-28
lines changed

package-lock.json

Lines changed: 196 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,8 @@
1616
"@auth/prisma-adapter": "^2.5.2",
1717
"@deploy-cat/heroicons-solid": "^2.1.1",
1818
"@kubernetes/client-node": "^0.18.1",
19+
"@octokit/rest": "^21.0.2",
20+
"@octokit/webhooks": "^13.3.0",
1921
"@prisma/client": "^5.19.1",
2022
"@solid-mediakit/auth": "^2.1.3",
2123
"@solidjs/router": "^0.13.1",

src/components/cloud/CreateServiceForm.tsx

Lines changed: 91 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -4,15 +4,86 @@ import { knative } from "~/lib/k8s";
44
import { EnvVarsInput } from "../EnvVarsInput";
55
import { ScalingInput } from "../ScalingInput";
66
import { ResourcesInput } from "../ResourcesInput";
7-
import { getUser } from "~/lib/auth";
7+
import { getUser, getAccount } from "~/lib/auth";
88
import type { Service } from "~/lib/knative";
99
import { toNumber } from "~/lib/knative";
10+
import { SourceInput } from "./service/SourceInput";
11+
import { k8sCore } from "~/lib/k8s";
12+
import { Octokit } from "@octokit/rest";
13+
import * as crypto from "crypto";
14+
import { config } from "~/lib/config";
15+
16+
const ensureGithubPullSecret = async (namespace: string) => {
17+
"use server";
18+
const secretName = "pull-secret-ghcr";
19+
try {
20+
await k8sCore.readNamespacedSecret(secretName, namespace);
21+
} catch (e) {
22+
const user = await getUser();
23+
const accout = await getAccount();
24+
25+
const username = user.name;
26+
const token = accout.access_token;
27+
const email = user.email;
28+
29+
await k8sCore.createNamespacedSecret(namespace, {
30+
apiVersion: "v1",
31+
kind: "Secret",
32+
metadata: {
33+
name: secretName,
34+
labels: {
35+
"app.kubernetes.io/managed-by": "deploycat",
36+
},
37+
},
38+
type: "kubernetes.io/dockerconfigjson",
39+
data: {
40+
".dockerconfigjson": Buffer.from(
41+
JSON.stringify({
42+
auths: {
43+
"ghcr.io": {
44+
username: username,
45+
password: token,
46+
email: email,
47+
auth: Buffer.from(`${username}:${token}`).toString("base64"),
48+
},
49+
},
50+
})
51+
).toString("base64"),
52+
},
53+
});
54+
}
55+
};
56+
57+
const createGithubWebhook = async (namespace: string, service) => {
58+
"use server";
59+
const account = await getAccount();
60+
const ok = new Octokit({
61+
auth: account.access_token,
62+
});
63+
ok.repos.createWebhook({
64+
owner: service.ghPackageOwner,
65+
repo: service.ghPackageRepo,
66+
config: {
67+
url: `${config?.publicurl}/api/webhooks/github/apps/${namespace}/${service.name}/package`,
68+
content_type: "json",
69+
secret: service.webhookSecret,
70+
},
71+
events: ["package"],
72+
active: true,
73+
});
74+
};
1075

1176
const createServiceFromForm = async (form: FormData) => {
1277
"use server";
1378
const service = {
1479
name: form.get("name") as string,
80+
source: form.get("source") as string,
1581
image: form.get("image") as string,
82+
ghPackage: form.get("ghPackage") as string,
83+
ghPackageTag: form.get("ghPackageTag") as string,
84+
ghPackageName: form.get("ghPackageName") as string,
85+
ghPackageOwner: form.get("ghPackageOwner") as string,
86+
ghPackageRepo: form.get("ghPackageRepo") as string,
1687
port: Number(form.get("port")) as number,
1788
resources: {
1889
cpuLimit: toNumber(form.get("cpuLimit")),
@@ -24,8 +95,24 @@ const createServiceFromForm = async (form: FormData) => {
2495
},
2596
envVars: JSON.parse(form.get("env") as string) as { [key: string]: string },
2697
} as Service;
98+
2799
const user = await getUser();
28-
await knative.createService(service, user.name);
100+
if (service?.source === "ghcr") {
101+
try {
102+
service.webhookSecret = crypto.randomBytes(16).toString("hex");
103+
await ensureGithubPullSecret(user.name);
104+
await createGithubWebhook(user.name, service);
105+
} catch (e) {
106+
console.error(e);
107+
}
108+
service.image = `ghcr.io/${service.ghPackageOwner}/${service.ghPackageName}:${service.ghPackageTag}`;
109+
service.pullSecret = "pull-secret-ghcr";
110+
}
111+
try {
112+
await knative.createService(service, user.name, service.source);
113+
} catch (e) {
114+
console.error(e);
115+
}
29116
};
30117

31118
const createServiceAction = action(createServiceFromForm, "createService");
@@ -54,18 +141,8 @@ export const CreateServiceForm = () => {
54141
class="input input-bordered w-full"
55142
/>
56143
</label>
57-
<label class="form-control w-full">
58-
<div class="label">
59-
<span class="label-text">Image</span>
60-
</div>
61-
<input
62-
type="text"
63-
name="image"
64-
required
65-
placeholder="traefik/whoami"
66-
class="input input-bordered w-full"
67-
/>
68-
</label>
144+
<SourceInput />
145+
69146
<label class="form-control w-full">
70147
<div class="label">
71148
<span class="label-text">Port</span>

0 commit comments

Comments
 (0)