feat: add PK01 host postgres platform-db CLI
This commit is contained in:
@@ -0,0 +1,214 @@
|
||||
version: 1
|
||||
kind: postgres-host-cluster
|
||||
|
||||
metadata:
|
||||
id: pk01-platform-postgres
|
||||
description: PK01 host-native PostgreSQL 16 for UniDesk platform external state
|
||||
owner: unidesk
|
||||
relatedIssues:
|
||||
- 280
|
||||
- 281
|
||||
|
||||
cluster:
|
||||
role: primary
|
||||
environment: platform
|
||||
exposure: private-only
|
||||
haPhase: standalone-with-backup
|
||||
futureHaModes:
|
||||
- primary-standby
|
||||
- managed-rds
|
||||
|
||||
node:
|
||||
id: PK01
|
||||
route: PK01
|
||||
mode: host-systemd
|
||||
osFamily: ubuntu
|
||||
requiredHostFacts:
|
||||
minCpu: 2
|
||||
minMemoryGiB: 3.5
|
||||
minDiskFreeGiB: 20
|
||||
requireSwap: true
|
||||
swap:
|
||||
ensure: true
|
||||
size: 4G
|
||||
path: /swapfile
|
||||
|
||||
postgres:
|
||||
package:
|
||||
manager: apt
|
||||
version: "16"
|
||||
repo: pgdg-archive
|
||||
repoUrl: https://apt-archive.postgresql.org/pub/repos/apt
|
||||
suite: focal-pgdg
|
||||
component: main
|
||||
signingKeyUrl: https://www.postgresql.org/media/keys/ACCC4CF8.asc
|
||||
signedBy: /usr/share/keyrings/postgresql-pgdg.gpg
|
||||
sourceList: /etc/apt/sources.list.d/pgdg.list
|
||||
service:
|
||||
name: postgresql
|
||||
enabled: true
|
||||
state: running
|
||||
paths:
|
||||
dataDir: /var/lib/postgresql/16/main
|
||||
configDir: /etc/postgresql/16/main
|
||||
logDir: /var/log/postgresql
|
||||
network:
|
||||
port: 5432
|
||||
listenAddresses:
|
||||
- 127.0.0.1
|
||||
- 10.0.8.3
|
||||
- 0.0.0.0
|
||||
connectionHost: db.pikapython.com
|
||||
publicDns: db.pikapython.com
|
||||
transport: postgres-native-tls
|
||||
sslmode: require
|
||||
tls:
|
||||
enabled: true
|
||||
mode: self-signed-server-cert
|
||||
commonName: db.pikapython.com
|
||||
certFile: /etc/postgresql/16/main/server.crt
|
||||
keyFile: /etc/postgresql/16/main/server.key
|
||||
futureClientSslmode: verify-full
|
||||
firewall:
|
||||
mode: pg-hba-declared-sources
|
||||
defaultDeny: true
|
||||
allowSources:
|
||||
- id: pk01-local
|
||||
cidr: 127.0.0.1/32
|
||||
purpose: local-admin
|
||||
- id: pk01-vpc
|
||||
cidr: 10.0.8.0/22
|
||||
purpose: private-vpc-clients
|
||||
- id: master-server-public
|
||||
cidr: 74.48.78.17/32
|
||||
purpose: admin-and-secret-sync
|
||||
- id: D601-public
|
||||
cidr: 36.49.29.73/32
|
||||
purpose: platform-infra-standby-app
|
||||
tuning:
|
||||
maxConnections: 50
|
||||
sharedBuffers: 512MB
|
||||
effectiveCacheSize: 2GB
|
||||
workMem: 8MB
|
||||
maintenanceWorkMem: 128MB
|
||||
walCompression: true
|
||||
checkpointCompletionTarget: 0.9
|
||||
auth:
|
||||
passwordEncryption: scram-sha-256
|
||||
pgHba:
|
||||
- type: local
|
||||
database: all
|
||||
user: postgres
|
||||
method: peer
|
||||
- type: host
|
||||
database: all
|
||||
user: all
|
||||
address: 127.0.0.1/32
|
||||
method: scram-sha-256
|
||||
- type: hostssl
|
||||
database: sub2api
|
||||
user: sub2api
|
||||
address: 10.0.8.0/22
|
||||
method: scram-sha-256
|
||||
- type: hostssl
|
||||
database: sub2api
|
||||
user: sub2api
|
||||
address: 74.48.78.17/32
|
||||
method: scram-sha-256
|
||||
- type: hostssl
|
||||
database: sub2api
|
||||
user: sub2api
|
||||
address: 36.49.29.73/32
|
||||
method: scram-sha-256
|
||||
|
||||
secrets:
|
||||
source: master-local
|
||||
root: .state/secrets
|
||||
entries:
|
||||
- name: sub2api-db-credentials
|
||||
sourceRef: platform-db/sub2api-db.env
|
||||
type: env
|
||||
requiredKeys:
|
||||
- SUB2API_DB_USER
|
||||
- SUB2API_DB_PASSWORD
|
||||
- SUB2API_DB_NAME
|
||||
createIfMissing:
|
||||
enabled: true
|
||||
values:
|
||||
SUB2API_DB_USER: sub2api
|
||||
SUB2API_DB_NAME: sub2api
|
||||
randomHex:
|
||||
SUB2API_DB_PASSWORD: 32
|
||||
|
||||
objects:
|
||||
roles:
|
||||
- name: sub2api
|
||||
passwordRef:
|
||||
sourceRef: platform-db/sub2api-db.env
|
||||
key: SUB2API_DB_PASSWORD
|
||||
login: true
|
||||
attributes:
|
||||
createdb: false
|
||||
createrole: false
|
||||
superuser: false
|
||||
databases:
|
||||
- name: sub2api
|
||||
owner: sub2api
|
||||
encoding: UTF8
|
||||
locale: C.UTF-8
|
||||
extensions: []
|
||||
|
||||
exports:
|
||||
connectionStrings:
|
||||
- name: sub2api-database-url
|
||||
sourceSecretRef: platform-db/sub2api-db.env
|
||||
render:
|
||||
envKey: DATABASE_URL
|
||||
format: postgresql://$(SUB2API_DB_USER):$(SUB2API_DB_PASSWORD)@$(PGHOST):5432/$(SUB2API_DB_NAME)?sslmode=require
|
||||
variables:
|
||||
PGHOST: db.pikapython.com
|
||||
writeToSecretSource:
|
||||
sourceRef: platform-infra/sub2api.env
|
||||
key: DATABASE_URL
|
||||
mode: update-or-insert
|
||||
consumers:
|
||||
- scope: platform-infra
|
||||
secret: sub2api-secrets
|
||||
key: DATABASE_URL
|
||||
|
||||
backup:
|
||||
phase: minimum-restoreable
|
||||
logicalDump:
|
||||
enabled: true
|
||||
schedule: "17 3 * * *"
|
||||
database: sub2api
|
||||
retentionDays: 14
|
||||
destination:
|
||||
type: pk01-local
|
||||
path: /var/backups/unidesk/platform-db/pk01/sub2api
|
||||
encryption:
|
||||
enabled: false
|
||||
futureKeyRef: platform-db/backup-age-recipient.txt
|
||||
physicalWalArchive:
|
||||
enabled: false
|
||||
futureTool: pgbackrest
|
||||
|
||||
observability:
|
||||
statusChecks:
|
||||
- kind: systemd-active
|
||||
service: postgresql
|
||||
- kind: port-listen
|
||||
host: 127.0.0.1
|
||||
port: 5432
|
||||
- kind: psql-local
|
||||
database: postgres
|
||||
- kind: psql-app-role
|
||||
database: sub2api
|
||||
user: sub2api
|
||||
- kind: disk-free
|
||||
path: /var/lib/postgresql/16/main
|
||||
minFreeGiB: 10
|
||||
redaction:
|
||||
neverPrintValues: true
|
||||
showFingerprint: true
|
||||
showKeyNames: true
|
||||
@@ -24,6 +24,7 @@ import { runCommanderCommand } from "./src/commander";
|
||||
import { isHelpToken, rootHelp, serverHelp, sshHelp, staticNamespaceHelp } from "./src/help";
|
||||
import { runServerCleanupCommand } from "./src/server-cleanup";
|
||||
import { runGcCommand } from "./src/gc";
|
||||
import { runPlatformDbCommand } from "./src/platform-db";
|
||||
|
||||
const remoteOptions = extractRemoteCliOptions(process.argv.slice(2));
|
||||
const args = remoteOptions.args;
|
||||
@@ -339,6 +340,14 @@ async function main(): Promise<void> {
|
||||
return;
|
||||
}
|
||||
|
||||
if (top === "platform-db") {
|
||||
const result = await runPlatformDbCommand(readConfig(), args.slice(1));
|
||||
const ok = (result as { ok?: unknown }).ok !== false;
|
||||
emitJson(commandName, result, ok);
|
||||
if (!ok) process.exitCode = 1;
|
||||
return;
|
||||
}
|
||||
|
||||
const config = readConfig();
|
||||
const autoRemoteCiPublishPlan = autoRemoteCiPublishUserServiceDryRunPlan(config, args);
|
||||
if (autoRemoteCiPublishPlan.enabled && autoRemoteCiPublishPlan.host !== null) {
|
||||
|
||||
@@ -30,6 +30,7 @@ const syntaxFiles = [
|
||||
"scripts/src/e2e.ts",
|
||||
"scripts/src/help.ts",
|
||||
"scripts/src/commander.ts",
|
||||
"scripts/src/platform-db.ts",
|
||||
"scripts/src/recovery-guardrails.ts",
|
||||
"scripts/src/server-cleanup.ts",
|
||||
"scripts/src/remote.ts",
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import { ghHelp } from "./gh";
|
||||
import { authBrokerHelp } from "./auth-broker";
|
||||
import { platformDbHelp } from "./platform-db";
|
||||
|
||||
export function rootHelp(): unknown {
|
||||
return {
|
||||
@@ -59,6 +60,7 @@ export function rootHelp(): unknown {
|
||||
{ command: "hwlab g14 monitor-prs | hwlab g14 control-plane status|apply|trigger-current|runtime-migration|cleanup-runs|cleanup-released-pvs | hwlab g14 git-mirror status|apply|sync|flush | hwlab g14 tools-image status|build", description: "Start the legacy G14 PR monitor, run bounded v0.2 Tekton/Argo control-plane, manual PipelineRun trigger, runtime migration, CI workspace retention, manual devops-infra git mirror/relay maintenance, or fixed HWLAB CI tools image actions; long confirmed trigger/sync/flush actions return async jobs by default." },
|
||||
{ command: "agentrun get|describe|events|logs|result|ack|cancel|dispatch|create|apply|send|control-plane|git-mirror", description: "Use AgentRun v0.1 resource primitives with low-noise human output by default; session follow-up uses send only and the server decides internal steer vs turn." },
|
||||
{ command: "platform-infra sub2api plan|apply|status|validate|codex-pool", description: "Deploy Sub2API in G14 platform-infra, manage the YAML-controlled Codex upstream pool, expose the unified API, and inspect marker sentinel state with low-noise reports without printing API keys." },
|
||||
{ command: "platform-db postgres plan|status|apply", description: "Manage YAML-declared host-native PostgreSQL 16 on PK01 for Sub2API/platform state, with PostgreSQL native TLS and redacted secret exports." },
|
||||
{ command: "hwlab cd audit --env dev | hwlab cd status --env dev | hwlab cd apply --env dev --dry-run", description: "Legacy D601 HWLAB DEV CD wrapper kept for explicit old-path diagnostics; current HWLAB rollout uses G14 GitOps." },
|
||||
{ command: "code-agent-sandbox", description: "Independent Code Agent Sandbox service skeleton for adapter, mode, and credential-boundary diagnostics." },
|
||||
{ command: "schedule list|get|runs|run|retry-run|delete", description: "Manage backend-core scheduled tasks and run history; schedule run <id> supports --wait-ms N and retry-run reuses the failed run's schedule." },
|
||||
@@ -693,6 +695,7 @@ export async function staticNamespaceHelp(args: string[]): Promise<unknown | nul
|
||||
if (top === "gh") return ghHelp();
|
||||
if (top === "agentrun") return loadHelp(async () => (await import("./agentrun")).agentRunHelp(), agentRunHelpSummary());
|
||||
if (top === "platform-infra") return loadHelp(async () => (await import("./platform-infra")).platformInfraHelp(), platformInfraHelpSummary());
|
||||
if (top === "platform-db") return platformDbHelp();
|
||||
if (top === "hwlab" && (sub === "node" || sub === "nodes")) return loadHelp(async () => (await import("./hwlab-node")).hwlabNodeHelp(), hwlabNodeHelpSummary());
|
||||
if (top === "hwlab" && sub === "g14") return loadHelp(async () => (await import("./hwlab-g14")).hwlabG14Help(), hwlabG14HelpSummary());
|
||||
if (top === "hwlab") return loadHelp(async () => (await import("./hwlab-cd")).hwlabHelp(), hwlabHelpSummary());
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user