This commit is contained in:
2025-12-31 16:01:15 +01:00
parent b7d86e3b98
commit b3eea5a2fd
4 changed files with 37 additions and 16 deletions
+7 -5
View File
@@ -8,11 +8,11 @@ import { Play, Square, RotateCcw, MoreVertical, Plus } from "lucide-react";
import { Progress } from "@/components/ui/progress"; import { Progress } from "@/components/ui/progress";
import DeployApplication from "@/components/dialogs/DeployApplication"; import DeployApplication from "@/components/dialogs/DeployApplication";
import { useEffect, useState } from "react"; import { useEffect, useState } from "react";
import { Application } from "@/lib/types"; import { ImageApp } from "@/lib/types";
import { getApplications } from "@/core/application"; import { getApplications } from "@/core/application";
export default function ApplicationsPage() { export default function ApplicationsPage() {
const [applications, setApplications] = useState<Application[]>([]); const [applications, setApplications] = useState<ImageApp[]>([]);
useEffect(() => { useEffect(() => {
const fetch = async () => { const fetch = async () => {
@@ -22,6 +22,8 @@ export default function ApplicationsPage() {
fetch(); fetch();
}, []); }, []);
console.log(applications);
return ( return (
<DashboardLayout <DashboardLayout
title="Applications" title="Applications"
@@ -54,7 +56,7 @@ export default function ApplicationsPage() {
{/* {app.status} */} {/* {app.status} */}
<div className="min-w-0"> <div className="min-w-0">
<div className="font-mono text-sm font-medium"> <div className="font-mono text-sm font-medium">
{app.name} {app.app?.name || app.name}
</div> </div>
<div className="text-xs text-muted-foreground font-mono truncate"> <div className="text-xs text-muted-foreground font-mono truncate">
{app.image} {app.image}
@@ -62,10 +64,10 @@ export default function ApplicationsPage() {
</div> </div>
</div> </div>
{/* Replicas */} {/* Containers */}
<div className="flex justify-between md:block md:col-span-1"> <div className="flex justify-between md:block md:col-span-1">
<span className="text-xs text-muted-foreground md:hidden"> <span className="text-xs text-muted-foreground md:hidden">
Replicas Containers
</span> </span>
<div className="font-mono text-sm">{app.replicas}</div> <div className="font-mono text-sm">{app.replicas}</div>
</div> </div>
+2 -2
View File
@@ -3,7 +3,7 @@
import { verifySession } from "./auth/session"; import { verifySession } from "./auth/session";
import { getNodes } from "./node"; import { getNodes } from "./node";
import axios from "axios"; import axios from "axios";
import { Application } from "@/lib/types"; import { ImageApp } from "@/lib/types";
export async function deployNewApp(name: string, repo: string, nodeId: string) { export async function deployNewApp(name: string, repo: string, nodeId: string) {
if (await verifySession()) { if (await verifySession()) {
@@ -25,7 +25,7 @@ export async function deployNewApp(name: string, repo: string, nodeId: string) {
).data.applications; ).data.applications;
} }
export async function getApplications(): Promise<Application[]> { export async function getApplications(): Promise<ImageApp[]> {
const nodes = await getNodes(); const nodes = await getNodes();
return ( return (
+19 -9
View File
@@ -2,22 +2,21 @@
import Docker from "dockerode"; import Docker from "dockerode";
import { randomUUID } from "crypto"; import { randomUUID } from "crypto";
import fs from "fs/promises"; import fs from "fs";
import path from "path"; import path from "path";
import { exec } from "child_process"; import { exec } from "child_process";
import util from "util"; import util from "util";
import axios from "axios"; import { ImageApp } from "@/lib/types";
import { Application } from "@/lib/types";
const docker = new Docker(); const docker = new Docker();
const execAsync = util.promisify(exec); const execAsync = util.promisify(exec);
const DATA_DIR = path.join(process.cwd(), "data", "apps"); const DATA_DIR = path.join(process.cwd(), "data", "apps");
export async function getApplications(): Promise<Application[]> { export async function getApplications(): Promise<ImageApp[]> {
const images = await docker.listImages(); const images = await docker.listImages();
const containers = await docker.listContainers({ all: true }); const containers = await docker.listContainers({ all: true });
const apps: Application[] = []; const apps: ImageApp[] = [];
for (const image of images) { for (const image of images) {
const imageName = image.RepoTags?.[0]; const imageName = image.RepoTags?.[0];
@@ -46,9 +45,20 @@ export async function getApplications(): Promise<Application[]> {
} }
} }
const name = imageName.split("/").pop()?.split(":")[0] ?? imageName;
var app;
try {
app = JSON.parse(
fs.readFileSync(path.join(DATA_DIR, name, "app.json")).toString()
);
} catch {}
apps.push({ apps.push({
app,
name,
id: image.Id.slice(7, 15), id: image.Id.slice(7, 15),
name: imageName.split("/").pop()?.split(":")[0] ?? imageName,
image: imageName, image: imageName,
containers: relatedContainers.length, containers: relatedContainers.length,
replicas: `${running}/${relatedContainers.length}`, replicas: `${running}/${relatedContainers.length}`,
@@ -70,7 +80,7 @@ export async function deployNewApp(name: string, repo: string, nodeId: string) {
const repoDir = path.join(appDir, "repo"); const repoDir = path.join(appDir, "repo");
// Create directories // Create directories
await fs.mkdir(repoDir, { recursive: true }); fs.mkdirSync(repoDir, { recursive: true });
// Write app.json // Write app.json
const appConfig = { const appConfig = {
@@ -81,7 +91,7 @@ export async function deployNewApp(name: string, repo: string, nodeId: string) {
createdAt: new Date().toISOString(), createdAt: new Date().toISOString(),
}; };
await fs.writeFile( fs.writeFileSync(
path.join(appDir, "app.json"), path.join(appDir, "app.json"),
JSON.stringify(appConfig, null, 2) JSON.stringify(appConfig, null, 2)
); );
@@ -97,7 +107,7 @@ export async function deployNewApp(name: string, repo: string, nodeId: string) {
const dockerfilePath = path.join(repoDir, "Dockerfile"); const dockerfilePath = path.join(repoDir, "Dockerfile");
try { try {
await fs.access(dockerfilePath); fs.accessSync(dockerfilePath);
} catch { } catch {
throw new Error("Dockerfile not found in repository root"); throw new Error("Dockerfile not found in repository root");
} }
+9
View File
@@ -49,6 +49,15 @@ export interface Docker {
} }
export interface Application { export interface Application {
id: string;
name: string;
repo: string;
nodeId: string;
createdAt: string;
}
export interface ImageApp {
app?: Application;
id: string; id: string;
name: string; name: string;
image: string; image: string;