Deployment interface

This commit is contained in:
2026-01-03 20:15:58 +01:00
parent 61a9e1d8d9
commit 07a37f92df
6 changed files with 54 additions and 24 deletions
-20
View File
@@ -3,26 +3,6 @@ import testAuth from "../auth";
import { StatusCodes } from "http-status-codes";
import { deployApp, getDeployments } from "@/core/deployment";
export async function GET(req: NextRequest): Promise<NextResponse> {
const auth = await testAuth(req);
if (auth) {
return NextResponse.json(
{ message: auth },
{ status: StatusCodes.UNAUTHORIZED }
);
}
// const apps = await getApps();
const apps = await getDeployments([]);
return NextResponse.json({
message: "ok",
apps,
});
}
export async function POST(req: NextRequest): Promise<NextResponse> {
const auth = await testAuth(req);
const { name, appId }: { name: string; appId: string } = await req.json();
+29
View File
@@ -0,0 +1,29 @@
import { NextRequest, NextResponse } from "next/server";
import testAuth from "../auth";
import { StatusCodes } from "http-status-codes";
import { deployApp, getDeployments } from "@/core/deployment";
export async function POST(req: NextRequest): Promise<NextResponse> {
const auth = await testAuth(req);
const apps = await req.json();
if (auth) {
return NextResponse.json(
{ message: auth },
{ status: StatusCodes.UNAUTHORIZED }
);
}
if (!apps)
return NextResponse.json(
{ message: "Body should be Application[]" },
{ status: StatusCodes.UNAUTHORIZED }
);
const deployments = await getDeployments(apps);
return NextResponse.json({
message: "ok",
deployments,
});
}
+2 -1
View File
@@ -18,6 +18,7 @@ import { Combobox } from "../ui/combobox";
import { deployApp } from "@/lib/dockship/deploy";
import { useAsync } from "@/hooks/use-async";
import { Application } from "@/lib/types";
import { getApps } from "@/lib/dockship/application";
export default function DeployAppDialog({
defaultApp,
@@ -27,7 +28,7 @@ export default function DeployAppDialog({
children: ReactNode;
}) {
const { value: nodes } = useAsync([], getLiveNodes);
const { value: apps } = useAsync<Application[]>([], async () => []);
const { value: apps } = useAsync<Application[]>([], getApps);
const [name, setName] = useState("");
const [app, setApp] = useState(defaultApp || "");
const [node, setNode] = useState("");
-1
View File
@@ -20,7 +20,6 @@ function sanitizeString(str: string): string {
export async function getDeployments(
apps: Application[]
): Promise<Deployment[]> {
// Limit concurrent Docker calls (adjust if needed)
const limit = pLimit(5);
const deploymentIds = apps.flatMap((app) => app.deployments);
+10
View File
@@ -13,6 +13,16 @@ export async function getApps(): Promise<Application[]> {
return read(() => [], "data", "apps.json");
}
export async function getApp(appId: string): Promise<Application | undefined> {
if (await verifySession()) {
throw new Error("Unauthorized");
}
return (await read<Application[]>(() => [], "data", "apps.json")).find(
(app) => app.id === appId
);
}
export async function registerApp(name: string, repo: string) {
if (await verifySession()) {
throw new Error("Unauthorized");
+13 -2
View File
@@ -3,16 +3,18 @@
import { Deployment } from "@/lib/types";
import { getNodes } from "./node";
import axios from "axios";
import { editApp, getApp, getApps } from "./application";
export async function getDeployments(): Promise<(null | Deployment)[]> {
const nodes = await getNodes();
const apps = await getApps();
return (
await Promise.all(
nodes.map(
async (n) =>
await (
await axios.get(`http://${n.ip}:3000/api/deploy`, {
await axios.post(`http://${n.ip}:3000/api/get-deployments`, apps, {
headers: { Authorization: `ApiKey ${n.key}` },
})
).data.apps
@@ -32,7 +34,7 @@ export async function deployApp(
if (!node) throw new Error("Node not found");
return await (
const deployId = await (
await axios.post(
`http://${node.ip}:3000/api/deploy`,
{ name, appId },
@@ -41,4 +43,13 @@ export async function deployApp(
}
)
).data.deployId;
const app = await getApp(appId);
if (!app) throw new Error("(deployId) App not found");
app.deployments.push(deployId);
editApp(appId, app);
return deployId;
}