feat: add garage tooling

This commit is contained in:
2026-08-30 18:51:19 +07:00 Unverified
parent 716246659c
commit 7f1d445981
7 changed files with 139 additions and 5 deletions
+3 -1
View File
@@ -7,6 +7,7 @@ import { exportCommand } from "./export";
import { logs } from "./logs";
import { ps } from "./ps";
import { restart } from "./restart";
import { s3 } from "./s3";
import { start } from "./start";
import { stop } from "./stop";
import { up } from "./up";
@@ -14,7 +15,7 @@ import { up } from "./up";
export const main = defineCommand({
meta: {
name: "kuber",
version: "1.1.0",
version: "1.2.0",
description: "Docker Compose -> K8s translation layer",
},
args: {
@@ -31,6 +32,7 @@ export const main = defineCommand({
logs,
ps,
restart,
s3,
start,
stop,
up,
+89
View File
@@ -0,0 +1,89 @@
import { defineCommand } from "citty";
import { ctx } from "../lib/context";
import { toTable } from "../lib/format";
import {
getComposeS3Claims,
getS3Credentials,
type S3Claim,
} from "../lib/storage";
const GARAGE_UI_URL = "http://garage-ui.garage-system.svc.cluster.local";
export function getS3UiUrl(bucket: string): string {
return `${GARAGE_UI_URL}/buckets/${encodeURIComponent(bucket)}/objects`;
}
async function getServiceClaim(service: string): Promise<S3Claim> {
const claim = getComposeS3Claims(await ctx().compose()).find(
(entry) => entry.service === service,
);
if (!claim) {
throw new Error(`Service ${service} does not declare a managed S3 volume.`);
}
return claim;
}
const list = defineCommand({
meta: {
name: "ls",
description: "List managed S3 claims",
},
async run() {
const claims = getComposeS3Claims(await ctx().compose());
if (claims.length === 0) {
console.log("No managed S3 volumes declared");
return;
}
console.log(
toTable(
claims.map((claim) => ({
service: claim.service,
key: claim.key,
bucket: claim.bucket,
})),
),
);
},
});
const creds = defineCommand({
meta: {
name: "creds",
description: "Print S3 environment variables for a service",
},
async run({ args }) {
const service = args._[0];
if (!service) throw new Error("Service name is required");
const credentials = await getS3Credentials(await getServiceClaim(service));
for (const [name, value] of Object.entries(credentials)) {
console.log(`${name}=${value}`);
}
},
});
const ui = defineCommand({
meta: {
name: "ui",
description: "Print the Garage UI URL for a service bucket",
},
async run({ args }) {
const service = args._[0];
if (!service) throw new Error("Service name is required");
console.log(getS3UiUrl((await getServiceClaim(service)).bucket));
},
});
export const s3 = defineCommand({
meta: {
name: "s3",
description: "Inspect managed S3 storage",
},
subCommands: {
creds,
ls: list,
ui,
},
});