fix: pin chart to exact latest version at provision time, fix health check URL
Some checks failed
Build & Release / build (push) Has been cancelled
Some checks failed
Build & Release / build (push) Has been cancelled
This commit is contained in:
@@ -140,7 +140,7 @@ export async function customerRoutes(app: FastifyInstance) {
|
|||||||
await createCustomerDnsRecord(slug);
|
await createCustomerDnsRecord(slug);
|
||||||
await setStep("dns", "done");
|
await setStep("dns", "done");
|
||||||
|
|
||||||
addCustomerChart(slug, body.appVersion);
|
await addCustomerChart(slug, body.appVersion);
|
||||||
await setStep("chart", "done");
|
await setStep("chart", "done");
|
||||||
|
|
||||||
await db`UPDATE customers SET status = 'provisioned', updated_at = NOW() WHERE slug = ${slug}`;
|
await db`UPDATE customers SET status = 'provisioned', updated_at = NOW() WHERE slug = ${slug}`;
|
||||||
@@ -299,7 +299,7 @@ export async function customerRoutes(app: FastifyInstance) {
|
|||||||
const dbUrl = new URL(secrets["database-url"]);
|
const dbUrl = new URL(secrets["database-url"]);
|
||||||
await addCustomerToPool(slug, dbUrl.password);
|
await addCustomerToPool(slug, dbUrl.password);
|
||||||
|
|
||||||
addCustomerChart(slug, "*");
|
await addCustomerChart(slug, "*");
|
||||||
await db`UPDATE customers SET status = 'provisioned', updated_at = NOW() WHERE slug = ${slug}`;
|
await db`UPDATE customers SET status = 'provisioned', updated_at = NOW() WHERE slug = ${slug}`;
|
||||||
app.log.info({ slug }, "customer reactivated");
|
app.log.info({ slug }, "customer reactivated");
|
||||||
return reply.code(200).send({ slug, status: "provisioned" });
|
return reply.code(200).send({ slug, status: "provisioned" });
|
||||||
|
|||||||
@@ -44,7 +44,7 @@ export async function getCustomerDnsRecord(slug: string): Promise<{ exists: bool
|
|||||||
|
|
||||||
export async function checkCustomerHealth(slug: string): Promise<{ reachable: boolean; status: number | null }> {
|
export async function checkCustomerHealth(slug: string): Promise<{ reachable: boolean; status: number | null }> {
|
||||||
try {
|
try {
|
||||||
const res = await fetch(`https://${slug}.lunarfront.tech/health`, {
|
const res = await fetch(`https://${slug}.lunarfront.tech/api/health`, {
|
||||||
signal: AbortSignal.timeout(5000),
|
signal: AbortSignal.timeout(5000),
|
||||||
});
|
});
|
||||||
return { reachable: res.ok, status: res.status };
|
return { reachable: res.ok, status: res.status };
|
||||||
|
|||||||
@@ -4,6 +4,23 @@ import { tmpdir } from "os";
|
|||||||
import { join } from "path";
|
import { join } from "path";
|
||||||
import { config } from "../lib/config";
|
import { config } from "../lib/config";
|
||||||
|
|
||||||
|
async function getLatestChartVersion(): Promise<string> {
|
||||||
|
const res = await fetch("https://api.digitalocean.com/v2/registry/lunarfront/repositories/lunarfront/tags?page=1&per_page=100", {
|
||||||
|
headers: { Authorization: `Bearer ${config.doToken}` },
|
||||||
|
});
|
||||||
|
const data = await res.json() as { tags: { tag: string }[] };
|
||||||
|
const versions = (data.tags ?? [])
|
||||||
|
.map(t => t.tag)
|
||||||
|
.filter(t => /^\d+\.\d+\.\d+$/.test(t))
|
||||||
|
.sort((a, b) => {
|
||||||
|
const [aMaj, aMin, aPat] = a.split(".").map(Number);
|
||||||
|
const [bMaj, bMin, bPat] = b.split(".").map(Number);
|
||||||
|
return bMaj - aMaj || bMin - aMin || bPat - aPat;
|
||||||
|
});
|
||||||
|
if (!versions.length) throw new Error("No chart versions found in DOCR");
|
||||||
|
return versions[0];
|
||||||
|
}
|
||||||
|
|
||||||
function withRepo<T>(fn: (dir: string, env: NodeJS.ProcessEnv) => T): T {
|
function withRepo<T>(fn: (dir: string, env: NodeJS.ProcessEnv) => T): T {
|
||||||
const keyPath = join(tmpdir(), `manager-ssh-key-${Date.now()}`);
|
const keyPath = join(tmpdir(), `manager-ssh-key-${Date.now()}`);
|
||||||
const dir = join(tmpdir(), `lunarfront-charts-${Date.now()}`);
|
const dir = join(tmpdir(), `lunarfront-charts-${Date.now()}`);
|
||||||
@@ -30,9 +47,10 @@ function withRepo<T>(fn: (dir: string, env: NodeJS.ProcessEnv) => T): T {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export function addCustomerChart(slug: string, appVersion: string) {
|
export async function addCustomerChart(slug: string, appVersion: string) {
|
||||||
|
const version = (appVersion === "*" || appVersion === "latest") ? await getLatestChartVersion() : appVersion;
|
||||||
withRepo((dir, env) => {
|
withRepo((dir, env) => {
|
||||||
const manifest = buildArgoCDApp(slug, appVersion);
|
const manifest = buildArgoCDApp(slug, version);
|
||||||
writeFileSync(join(dir, "customers", `${slug}.yaml`), manifest);
|
writeFileSync(join(dir, "customers", `${slug}.yaml`), manifest);
|
||||||
execSync(`git -C ${dir} add customers/${slug}.yaml`, { env });
|
execSync(`git -C ${dir} add customers/${slug}.yaml`, { env });
|
||||||
execSync(`git -C ${dir} commit -m "feat: provision customer ${slug}"`, { env });
|
execSync(`git -C ${dir} commit -m "feat: provision customer ${slug}"`, { env });
|
||||||
@@ -50,8 +68,8 @@ export function removeCustomerChart(slug: string) {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
function buildArgoCDApp(slug: string, appVersion: string): string {
|
function buildArgoCDApp(slug: string, version: string): string {
|
||||||
const revision = appVersion === "*" || appVersion === "latest" ? ">=0.0.1" : appVersion;
|
const revision = version;
|
||||||
return `apiVersion: argoproj.io/v1alpha1
|
return `apiVersion: argoproj.io/v1alpha1
|
||||||
kind: Application
|
kind: Application
|
||||||
metadata:
|
metadata:
|
||||||
|
|||||||
Reference in New Issue
Block a user