@cicore/cli 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/bin/ci.js +13 -0
- package/dist/commands/addon/api-actions.d.ts +45 -0
- package/dist/commands/addon/api-actions.d.ts.map +1 -0
- package/dist/commands/addon/api-actions.js +281 -0
- package/dist/commands/addon/api-actions.js.map +1 -0
- package/dist/commands/addon/build.d.ts +11 -0
- package/dist/commands/addon/build.d.ts.map +1 -0
- package/dist/commands/addon/build.js +182 -0
- package/dist/commands/addon/build.js.map +1 -0
- package/dist/commands/addon/create.d.ts +11 -0
- package/dist/commands/addon/create.d.ts.map +1 -0
- package/dist/commands/addon/create.js +1186 -0
- package/dist/commands/addon/create.js.map +1 -0
- package/dist/commands/addon/delete.d.ts +13 -0
- package/dist/commands/addon/delete.d.ts.map +1 -0
- package/dist/commands/addon/delete.js +83 -0
- package/dist/commands/addon/delete.js.map +1 -0
- package/dist/commands/addon/deploy.d.ts +27 -0
- package/dist/commands/addon/deploy.d.ts.map +1 -0
- package/dist/commands/addon/deploy.js +459 -0
- package/dist/commands/addon/deploy.js.map +1 -0
- package/dist/commands/addon/dev-deploy.d.ts +31 -0
- package/dist/commands/addon/dev-deploy.d.ts.map +1 -0
- package/dist/commands/addon/dev-deploy.js +128 -0
- package/dist/commands/addon/dev-deploy.js.map +1 -0
- package/dist/commands/addon/dev.d.ts +36 -0
- package/dist/commands/addon/dev.d.ts.map +1 -0
- package/dist/commands/addon/dev.js +323 -0
- package/dist/commands/addon/dev.js.map +1 -0
- package/dist/commands/addon/extract-classes.d.ts +23 -0
- package/dist/commands/addon/extract-classes.d.ts.map +1 -0
- package/dist/commands/addon/extract-classes.js +281 -0
- package/dist/commands/addon/extract-classes.js.map +1 -0
- package/dist/commands/addon/generate-safelist.d.ts +24 -0
- package/dist/commands/addon/generate-safelist.d.ts.map +1 -0
- package/dist/commands/addon/generate-safelist.js +276 -0
- package/dist/commands/addon/generate-safelist.js.map +1 -0
- package/dist/commands/addon/index.d.ts +19 -0
- package/dist/commands/addon/index.d.ts.map +1 -0
- package/dist/commands/addon/index.js +296 -0
- package/dist/commands/addon/index.js.map +1 -0
- package/dist/commands/addon/init-repo.d.ts +25 -0
- package/dist/commands/addon/init-repo.d.ts.map +1 -0
- package/dist/commands/addon/init-repo.js +171 -0
- package/dist/commands/addon/init-repo.js.map +1 -0
- package/dist/commands/addon/install.d.ts +23 -0
- package/dist/commands/addon/install.d.ts.map +1 -0
- package/dist/commands/addon/install.js +84 -0
- package/dist/commands/addon/install.js.map +1 -0
- package/dist/commands/addon/list.d.ts +10 -0
- package/dist/commands/addon/list.d.ts.map +1 -0
- package/dist/commands/addon/list.js +102 -0
- package/dist/commands/addon/list.js.map +1 -0
- package/dist/commands/addon/manifest-refresh.d.ts +17 -0
- package/dist/commands/addon/manifest-refresh.d.ts.map +1 -0
- package/dist/commands/addon/manifest-refresh.js +48 -0
- package/dist/commands/addon/manifest-refresh.js.map +1 -0
- package/dist/commands/addon/migrate.d.ts +40 -0
- package/dist/commands/addon/migrate.d.ts.map +1 -0
- package/dist/commands/addon/migrate.js +236 -0
- package/dist/commands/addon/migrate.js.map +1 -0
- package/dist/commands/addon/publish.d.ts +33 -0
- package/dist/commands/addon/publish.d.ts.map +1 -0
- package/dist/commands/addon/publish.js +236 -0
- package/dist/commands/addon/publish.js.map +1 -0
- package/dist/commands/addon/scaffold-quality.d.ts +21 -0
- package/dist/commands/addon/scaffold-quality.d.ts.map +1 -0
- package/dist/commands/addon/scaffold-quality.js +90 -0
- package/dist/commands/addon/scaffold-quality.js.map +1 -0
- package/dist/commands/addon/sign.d.ts +9 -0
- package/dist/commands/addon/sign.d.ts.map +1 -0
- package/dist/commands/addon/sign.js +83 -0
- package/dist/commands/addon/sign.js.map +1 -0
- package/dist/commands/addon/toggle.d.ts +6 -0
- package/dist/commands/addon/toggle.d.ts.map +1 -0
- package/dist/commands/addon/toggle.js +46 -0
- package/dist/commands/addon/toggle.js.map +1 -0
- package/dist/commands/agent/index.d.ts +34 -0
- package/dist/commands/agent/index.d.ts.map +1 -0
- package/dist/commands/agent/index.js +564 -0
- package/dist/commands/agent/index.js.map +1 -0
- package/dist/commands/brand/index.d.ts +54 -0
- package/dist/commands/brand/index.d.ts.map +1 -0
- package/dist/commands/brand/index.js +367 -0
- package/dist/commands/brand/index.js.map +1 -0
- package/dist/commands/build/index.d.ts +53 -0
- package/dist/commands/build/index.d.ts.map +1 -0
- package/dist/commands/build/index.js +726 -0
- package/dist/commands/build/index.js.map +1 -0
- package/dist/commands/cache/flush-local.d.ts +31 -0
- package/dist/commands/cache/flush-local.d.ts.map +1 -0
- package/dist/commands/cache/flush-local.js +161 -0
- package/dist/commands/cache/flush-local.js.map +1 -0
- package/dist/commands/cache/index.d.ts +14 -0
- package/dist/commands/cache/index.d.ts.map +1 -0
- package/dist/commands/cache/index.js +453 -0
- package/dist/commands/cache/index.js.map +1 -0
- package/dist/commands/check/index.d.ts +8 -0
- package/dist/commands/check/index.d.ts.map +1 -0
- package/dist/commands/check/index.js +1316 -0
- package/dist/commands/check/index.js.map +1 -0
- package/dist/commands/cloudflare/index.d.ts +8 -0
- package/dist/commands/cloudflare/index.d.ts.map +1 -0
- package/dist/commands/cloudflare/index.js +453 -0
- package/dist/commands/cloudflare/index.js.map +1 -0
- package/dist/commands/core/create.d.ts +12 -0
- package/dist/commands/core/create.d.ts.map +1 -0
- package/dist/commands/core/create.js +206 -0
- package/dist/commands/core/create.js.map +1 -0
- package/dist/commands/core/delete.d.ts +11 -0
- package/dist/commands/core/delete.d.ts.map +1 -0
- package/dist/commands/core/delete.js +64 -0
- package/dist/commands/core/delete.js.map +1 -0
- package/dist/commands/core/env.d.ts +12 -0
- package/dist/commands/core/env.d.ts.map +1 -0
- package/dist/commands/core/env.js +95 -0
- package/dist/commands/core/env.js.map +1 -0
- package/dist/commands/core/health.d.ts +6 -0
- package/dist/commands/core/health.d.ts.map +1 -0
- package/dist/commands/core/health.js +215 -0
- package/dist/commands/core/health.js.map +1 -0
- package/dist/commands/core/index.d.ts +15 -0
- package/dist/commands/core/index.d.ts.map +1 -0
- package/dist/commands/core/index.js +86 -0
- package/dist/commands/core/index.js.map +1 -0
- package/dist/commands/core/list.d.ts +11 -0
- package/dist/commands/core/list.d.ts.map +1 -0
- package/dist/commands/core/list.js +58 -0
- package/dist/commands/core/list.js.map +1 -0
- package/dist/commands/core/rebuild.d.ts +13 -0
- package/dist/commands/core/rebuild.d.ts.map +1 -0
- package/dist/commands/core/rebuild.js +119 -0
- package/dist/commands/core/rebuild.js.map +1 -0
- package/dist/commands/db/index.d.ts +23 -0
- package/dist/commands/db/index.d.ts.map +1 -0
- package/dist/commands/db/index.js +355 -0
- package/dist/commands/db/index.js.map +1 -0
- package/dist/commands/db/promote-silo.d.ts +320 -0
- package/dist/commands/db/promote-silo.d.ts.map +1 -0
- package/dist/commands/db/promote-silo.js +930 -0
- package/dist/commands/db/promote-silo.js.map +1 -0
- package/dist/commands/db/relocate.d.ts +41 -0
- package/dist/commands/db/relocate.d.ts.map +1 -0
- package/dist/commands/db/relocate.js +482 -0
- package/dist/commands/db/relocate.js.map +1 -0
- package/dist/commands/db/rollback-silo.d.ts +44 -0
- package/dist/commands/db/rollback-silo.d.ts.map +1 -0
- package/dist/commands/db/rollback-silo.js +402 -0
- package/dist/commands/db/rollback-silo.js.map +1 -0
- package/dist/commands/deploy/index.d.ts +26 -0
- package/dist/commands/deploy/index.d.ts.map +1 -0
- package/dist/commands/deploy/index.js +107 -0
- package/dist/commands/deploy/index.js.map +1 -0
- package/dist/commands/devops/index.d.ts +6 -0
- package/dist/commands/devops/index.d.ts.map +1 -0
- package/dist/commands/devops/index.js +220 -0
- package/dist/commands/devops/index.js.map +1 -0
- package/dist/commands/domain/index.d.ts +8 -0
- package/dist/commands/domain/index.d.ts.map +1 -0
- package/dist/commands/domain/index.js +386 -0
- package/dist/commands/domain/index.js.map +1 -0
- package/dist/commands/image/index.d.ts +8 -0
- package/dist/commands/image/index.d.ts.map +1 -0
- package/dist/commands/image/index.js +308 -0
- package/dist/commands/image/index.js.map +1 -0
- package/dist/commands/install/factory-reset.d.ts +21 -0
- package/dist/commands/install/factory-reset.d.ts.map +1 -0
- package/dist/commands/install/factory-reset.js +83 -0
- package/dist/commands/install/factory-reset.js.map +1 -0
- package/dist/commands/install/index.d.ts +17 -0
- package/dist/commands/install/index.d.ts.map +1 -0
- package/dist/commands/install/index.js +44 -0
- package/dist/commands/install/index.js.map +1 -0
- package/dist/commands/install/install.d.ts +35 -0
- package/dist/commands/install/install.d.ts.map +1 -0
- package/dist/commands/install/install.js +171 -0
- package/dist/commands/install/install.js.map +1 -0
- package/dist/commands/login/index.d.ts +15 -0
- package/dist/commands/login/index.d.ts.map +1 -0
- package/dist/commands/login/index.js +58 -0
- package/dist/commands/login/index.js.map +1 -0
- package/dist/commands/nginx/index.d.ts +11 -0
- package/dist/commands/nginx/index.d.ts.map +1 -0
- package/dist/commands/nginx/index.js +580 -0
- package/dist/commands/nginx/index.js.map +1 -0
- package/dist/commands/server/bootstrap.d.ts +25 -0
- package/dist/commands/server/bootstrap.d.ts.map +1 -0
- package/dist/commands/server/bootstrap.js +260 -0
- package/dist/commands/server/bootstrap.js.map +1 -0
- package/dist/commands/server/index.d.ts +8 -0
- package/dist/commands/server/index.d.ts.map +1 -0
- package/dist/commands/server/index.js +2524 -0
- package/dist/commands/server/index.js.map +1 -0
- package/dist/commands/setup/index.d.ts +34 -0
- package/dist/commands/setup/index.d.ts.map +1 -0
- package/dist/commands/setup/index.js +423 -0
- package/dist/commands/setup/index.js.map +1 -0
- package/dist/commands/ssl/index.d.ts +8 -0
- package/dist/commands/ssl/index.d.ts.map +1 -0
- package/dist/commands/ssl/index.js +275 -0
- package/dist/commands/ssl/index.js.map +1 -0
- package/dist/commands/superadmin/index.d.ts +16 -0
- package/dist/commands/superadmin/index.d.ts.map +1 -0
- package/dist/commands/superadmin/index.js +81 -0
- package/dist/commands/superadmin/index.js.map +1 -0
- package/dist/commands/tenant/index.d.ts +6 -0
- package/dist/commands/tenant/index.d.ts.map +1 -0
- package/dist/commands/tenant/index.js +192 -0
- package/dist/commands/tenant/index.js.map +1 -0
- package/dist/index.d.ts +11 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +107 -0
- package/dist/index.js.map +1 -0
- package/dist/lib/addon-sign.d.ts +23 -0
- package/dist/lib/addon-sign.d.ts.map +1 -0
- package/dist/lib/addon-sign.js +39 -0
- package/dist/lib/addon-sign.js.map +1 -0
- package/dist/lib/addon-sign.test.d.ts +2 -0
- package/dist/lib/addon-sign.test.d.ts.map +1 -0
- package/dist/lib/addon-sign.test.js +27 -0
- package/dist/lib/addon-sign.test.js.map +1 -0
- package/dist/lib/cdn.d.ts +25 -0
- package/dist/lib/cdn.d.ts.map +1 -0
- package/dist/lib/cdn.js +131 -0
- package/dist/lib/cdn.js.map +1 -0
- package/dist/lib/cloudflare.d.ts +133 -0
- package/dist/lib/cloudflare.d.ts.map +1 -0
- package/dist/lib/cloudflare.js +435 -0
- package/dist/lib/cloudflare.js.map +1 -0
- package/dist/lib/config.d.ts +96 -0
- package/dist/lib/config.d.ts.map +1 -0
- package/dist/lib/config.js +132 -0
- package/dist/lib/config.js.map +1 -0
- package/dist/lib/env.d.ts +8 -0
- package/dist/lib/env.d.ts.map +1 -0
- package/dist/lib/env.js +64 -0
- package/dist/lib/env.js.map +1 -0
- package/dist/lib/hosts.d.ts +194 -0
- package/dist/lib/hosts.d.ts.map +1 -0
- package/dist/lib/hosts.js +183 -0
- package/dist/lib/hosts.js.map +1 -0
- package/dist/lib/logger.d.ts +68 -0
- package/dist/lib/logger.d.ts.map +1 -0
- package/dist/lib/logger.js +130 -0
- package/dist/lib/logger.js.map +1 -0
- package/dist/lib/nginx-config.d.ts +78 -0
- package/dist/lib/nginx-config.d.ts.map +1 -0
- package/dist/lib/nginx-config.js +736 -0
- package/dist/lib/nginx-config.js.map +1 -0
- package/dist/lib/ops/addon-dev.d.ts +93 -0
- package/dist/lib/ops/addon-dev.d.ts.map +1 -0
- package/dist/lib/ops/addon-dev.js +237 -0
- package/dist/lib/ops/addon-dev.js.map +1 -0
- package/dist/lib/ops/addon-quality.d.ts +38 -0
- package/dist/lib/ops/addon-quality.d.ts.map +1 -0
- package/dist/lib/ops/addon-quality.js +338 -0
- package/dist/lib/ops/addon-quality.js.map +1 -0
- package/dist/lib/ops/addon-routes.d.ts +49 -0
- package/dist/lib/ops/addon-routes.d.ts.map +1 -0
- package/dist/lib/ops/addon-routes.js +189 -0
- package/dist/lib/ops/addon-routes.js.map +1 -0
- package/dist/lib/ops/addon.d.ts +120 -0
- package/dist/lib/ops/addon.d.ts.map +1 -0
- package/dist/lib/ops/addon.js +260 -0
- package/dist/lib/ops/addon.js.map +1 -0
- package/dist/lib/ops/cdn.d.ts +87 -0
- package/dist/lib/ops/cdn.d.ts.map +1 -0
- package/dist/lib/ops/cdn.js +170 -0
- package/dist/lib/ops/cdn.js.map +1 -0
- package/dist/lib/ops/cf.d.ts +36 -0
- package/dist/lib/ops/cf.d.ts.map +1 -0
- package/dist/lib/ops/cf.js +114 -0
- package/dist/lib/ops/cf.js.map +1 -0
- package/dist/lib/ops/compose.d.ts +95 -0
- package/dist/lib/ops/compose.d.ts.map +1 -0
- package/dist/lib/ops/compose.js +165 -0
- package/dist/lib/ops/compose.js.map +1 -0
- package/dist/lib/ops/core.d.ts +117 -0
- package/dist/lib/ops/core.d.ts.map +1 -0
- package/dist/lib/ops/core.js +322 -0
- package/dist/lib/ops/core.js.map +1 -0
- package/dist/lib/ops/db.d.ts +116 -0
- package/dist/lib/ops/db.d.ts.map +1 -0
- package/dist/lib/ops/db.js +351 -0
- package/dist/lib/ops/db.js.map +1 -0
- package/dist/lib/ops/dns.d.ts +111 -0
- package/dist/lib/ops/dns.d.ts.map +1 -0
- package/dist/lib/ops/dns.js +306 -0
- package/dist/lib/ops/dns.js.map +1 -0
- package/dist/lib/ops/image.d.ts +94 -0
- package/dist/lib/ops/image.d.ts.map +1 -0
- package/dist/lib/ops/image.js +159 -0
- package/dist/lib/ops/image.js.map +1 -0
- package/dist/lib/ops/nginx.d.ts +114 -0
- package/dist/lib/ops/nginx.d.ts.map +1 -0
- package/dist/lib/ops/nginx.js +388 -0
- package/dist/lib/ops/nginx.js.map +1 -0
- package/dist/lib/ops/redis.d.ts +7 -0
- package/dist/lib/ops/redis.d.ts.map +1 -0
- package/dist/lib/ops/redis.js +35 -0
- package/dist/lib/ops/redis.js.map +1 -0
- package/dist/lib/ops/ssh.d.ts +127 -0
- package/dist/lib/ops/ssh.d.ts.map +1 -0
- package/dist/lib/ops/ssh.js +269 -0
- package/dist/lib/ops/ssh.js.map +1 -0
- package/dist/lib/prompts.d.ts +46 -0
- package/dist/lib/prompts.d.ts.map +1 -0
- package/dist/lib/prompts.js +113 -0
- package/dist/lib/prompts.js.map +1 -0
- package/dist/lib/sast.d.ts +43 -0
- package/dist/lib/sast.d.ts.map +1 -0
- package/dist/lib/sast.js +79 -0
- package/dist/lib/sast.js.map +1 -0
- package/dist/lib/sast.test.d.ts +2 -0
- package/dist/lib/sast.test.d.ts.map +1 -0
- package/dist/lib/sast.test.js +33 -0
- package/dist/lib/sast.test.js.map +1 -0
- package/dist/lib/shell.d.ts +61 -0
- package/dist/lib/shell.d.ts.map +1 -0
- package/dist/lib/shell.js +183 -0
- package/dist/lib/shell.js.map +1 -0
- package/dist/lib/ssh-config.d.ts +37 -0
- package/dist/lib/ssh-config.d.ts.map +1 -0
- package/dist/lib/ssh-config.js +122 -0
- package/dist/lib/ssh-config.js.map +1 -0
- package/dist/lib/tenant-scope.d.ts +38 -0
- package/dist/lib/tenant-scope.d.ts.map +1 -0
- package/dist/lib/tenant-scope.js +129 -0
- package/dist/lib/tenant-scope.js.map +1 -0
- package/dist/lib/tenant-scope.test.d.ts +2 -0
- package/dist/lib/tenant-scope.test.d.ts.map +1 -0
- package/dist/lib/tenant-scope.test.js +223 -0
- package/dist/lib/tenant-scope.test.js.map +1 -0
- package/package.json +58 -0
- package/templates/bootstrap/.env.template +54 -0
- package/templates/bootstrap/docker-compose.yml +145 -0
- package/templates/vhost.conf.tmpl +446 -0
|
@@ -0,0 +1,564 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* CiCore CLI — `ci agent` (provisioning agent / execution bridge, K4)
|
|
3
|
+
*
|
|
4
|
+
* The control-plane never SSHes ad hoc. The panel (PHP) writes a *job* to
|
|
5
|
+
* `cp_provisioning_jobs`; a privileged agent claims it and runs the work,
|
|
6
|
+
* recording step logs, status, errors and an audit trail. This is that agent.
|
|
7
|
+
*
|
|
8
|
+
* - `ci agent enqueue` — write a (signed) job. The panel mirrors this INSERT
|
|
9
|
+
* in PHP; the CLI form is for testing + ops.
|
|
10
|
+
* - `ci agent run` — claim queued jobs and execute them. Run it as a cron /
|
|
11
|
+
* systemd timer on the host (or any box with SSH + control-plane access).
|
|
12
|
+
*
|
|
13
|
+
* Execution reuses the existing CLI commands by spawning them as child
|
|
14
|
+
* processes (e.g. `brand_reconcile` → `ci brand reconcile`), so the agent adds
|
|
15
|
+
* no second copy of the provisioning logic and a job failure can't take the
|
|
16
|
+
* agent down. Jobs are HMAC-signed (env `CICORE_JOB_SIGNING_SECRET`) so a
|
|
17
|
+
* compromised panel can't inject arbitrary work; if the secret is unset the
|
|
18
|
+
* agent runs in dev mode (verification skipped, with a warning).
|
|
19
|
+
*
|
|
20
|
+
* v1 job type: `brand_reconcile`. Reconcile is idempotent, so a failed job is
|
|
21
|
+
* safe to re-run (recovery = re-queue); true compensating rollback for
|
|
22
|
+
* create-type jobs (create_brand, …) is a follow-up.
|
|
23
|
+
*/
|
|
24
|
+
import { execFile } from 'node:child_process';
|
|
25
|
+
import { createHmac } from 'node:crypto';
|
|
26
|
+
import { fileURLToPath } from 'node:url';
|
|
27
|
+
import { log } from '../../lib/logger.js';
|
|
28
|
+
import { getHostConfig } from '../../lib/hosts.js';
|
|
29
|
+
import { dbSelectJson, dbExec } from '../../lib/ops/db.js';
|
|
30
|
+
import { cdnUploadManifest, cdnCleanAddon } from '../../lib/ops/cdn.js';
|
|
31
|
+
const CONTROL_DB = 'vucore_control';
|
|
32
|
+
const SLUG_RE = /^[a-z][a-z0-9_-]{1,62}$/;
|
|
33
|
+
/** Job types the agent knows how to execute. */
|
|
34
|
+
const KNOWN_TYPES = [
|
|
35
|
+
'brand_reconcile',
|
|
36
|
+
'db_promote_silo', // Faz 6 (dormant; pool tier aktifleşince)
|
|
37
|
+
'db_promote_silo_rollback', // Faz 6.2 (dormant)
|
|
38
|
+
'db_relocate', // M2 relocation (aktif yön; K-REL onaylı)
|
|
39
|
+
'publish_addon', // M3.4 marketplace publish (option-b; single authority)
|
|
40
|
+
'manifest_refresh', // E7-1 quarantine/revoke runtime-propagasyon (manifest regen → R2)
|
|
41
|
+
];
|
|
42
|
+
export function registerAgentCommands(program) {
|
|
43
|
+
const agent = program.command('agent').description('Provisioning agent — control-plane job execution bridge (K4)');
|
|
44
|
+
agent
|
|
45
|
+
.command('enqueue')
|
|
46
|
+
.description('Write a (signed) provisioning job to the control-plane')
|
|
47
|
+
.requiredOption('--type <type>', `Job type (${KNOWN_TYPES.join(' | ')})`)
|
|
48
|
+
.option('-h, --host <host>', 'Host alias (cicore | mkt)')
|
|
49
|
+
.option('--brand <slug>', 'Brand slug (for brand_reconcile)')
|
|
50
|
+
.option('--dns', 'Pass --dns to the reconcile (provision DNS too)')
|
|
51
|
+
.option('--requested-by <who>', 'Audit actor', 'cli')
|
|
52
|
+
.action(async (opts) => {
|
|
53
|
+
const cfg = resolveHost(opts.host);
|
|
54
|
+
assertType(opts.type);
|
|
55
|
+
if (opts.brand !== undefined && !SLUG_RE.test(opts.brand)) {
|
|
56
|
+
log.error(`Invalid --brand slug '${opts.brand}'.`);
|
|
57
|
+
process.exit(1);
|
|
58
|
+
}
|
|
59
|
+
const targetType = 'brand';
|
|
60
|
+
const payload = { brand: opts.brand ?? null, dns: opts.dns === true };
|
|
61
|
+
const sig = signJob(opts.type, targetType, payload);
|
|
62
|
+
const sigSql = sig ? `'${sig}'` : 'NULL';
|
|
63
|
+
const res = await dbExec(cfg, CONTROL_DB, `INSERT INTO cp_provisioning_jobs (target_type, type, payload, status, requested_by, signature)
|
|
64
|
+
VALUES ('${targetType}', '${opts.type}', '${sqlLit(JSON.stringify(payload))}'::jsonb, 'queued',
|
|
65
|
+
'${sqlLit(opts.requestedBy ?? 'cli')}', ${sigSql});`);
|
|
66
|
+
if (!res.success) {
|
|
67
|
+
log.error(`enqueue failed: ${res.stderr.trim()}`);
|
|
68
|
+
process.exit(1);
|
|
69
|
+
}
|
|
70
|
+
log.success(`Job queued: ${opts.type} (brand=${opts.brand ?? '-'}, dns=${opts.dns === true})${sig ? ' [signed]' : ' [UNSIGNED — dev]'}`);
|
|
71
|
+
});
|
|
72
|
+
agent
|
|
73
|
+
.command('run')
|
|
74
|
+
.description('Claim and execute queued provisioning jobs')
|
|
75
|
+
.option('-h, --host <host>', 'Host alias (cicore | mkt)')
|
|
76
|
+
.option('--once', 'Process the queue once and exit (cron mode)', false)
|
|
77
|
+
.option('--max <n>', 'Max jobs to process this run', '10')
|
|
78
|
+
.action(async (opts) => {
|
|
79
|
+
const cfg = resolveHost(opts.host);
|
|
80
|
+
const max = Number.parseInt(opts.max ?? '10', 10);
|
|
81
|
+
let processed = 0;
|
|
82
|
+
for (let i = 0; i < max; i++) {
|
|
83
|
+
const job = await claimNext(cfg);
|
|
84
|
+
if (!job)
|
|
85
|
+
break;
|
|
86
|
+
await runJob(cfg, job);
|
|
87
|
+
processed++;
|
|
88
|
+
}
|
|
89
|
+
log.info(processed === 0 ? 'No queued jobs.' : `Processed ${processed} job(s).`);
|
|
90
|
+
});
|
|
91
|
+
agent
|
|
92
|
+
.command('reconcile')
|
|
93
|
+
.description('Stuck-job recovery — re-evaluate jobs claimed (running) ama hiç tamamlanmamış (agent yarıda öldü). Idempotent + fail-closed.')
|
|
94
|
+
.option('-h, --host <host>', 'Host alias (cicore | mkt)')
|
|
95
|
+
.option('--stale-min <n>', 'Bu süreden (dk) eski running job = stuck adayı', '10')
|
|
96
|
+
.option('--max-age-min <n>', 'Bu süreden (dk) eski → fail-closed (vazgeç, manuel)', '60')
|
|
97
|
+
.option('--once', 'Tek geçiş (cron/timer modu)', false)
|
|
98
|
+
.option('--dry-run', 'Yalnız rapor; durum değiştirme', false)
|
|
99
|
+
.action(async (opts) => {
|
|
100
|
+
const cfg = resolveHost(opts.host);
|
|
101
|
+
const staleMin = Number.parseInt(opts.staleMin ?? '10', 10);
|
|
102
|
+
const maxAgeMin = Number.parseInt(opts.maxAgeMin ?? '60', 10);
|
|
103
|
+
const dryRun = Boolean(opts.dryRun ?? opts['dry-run']);
|
|
104
|
+
const { requeued, failed } = await reconcileStaleJobs(cfg, staleMin, maxAgeMin, dryRun);
|
|
105
|
+
// Exit 1 when stuck jobs were found so systemd OnFailure / monitoring catches it.
|
|
106
|
+
if (requeued + failed > 0)
|
|
107
|
+
process.exit(1);
|
|
108
|
+
});
|
|
109
|
+
}
|
|
110
|
+
// ─────────────────────────────────────────────────────────────────────────
|
|
111
|
+
// Job lifecycle
|
|
112
|
+
// ─────────────────────────────────────────────────────────────────────────
|
|
113
|
+
/** Claim the oldest queued job (set running). Single-agent v1: select then guarded update. */
|
|
114
|
+
async function claimNext(cfg) {
|
|
115
|
+
const queued = await dbSelectJson(cfg, CONTROL_DB, `SELECT id, target_type, target_id, type, payload, signature, requested_by
|
|
116
|
+
FROM cp_provisioning_jobs WHERE status = 'queued' ORDER BY created_at LIMIT 1`);
|
|
117
|
+
if (queued.length === 0)
|
|
118
|
+
return undefined;
|
|
119
|
+
const job = queued[0];
|
|
120
|
+
// Guarded claim: only succeeds if still queued (AND status guard = race-safe).
|
|
121
|
+
const res = await dbExec(cfg, CONTROL_DB, `UPDATE cp_provisioning_jobs SET status='running', steps='[]'::jsonb
|
|
122
|
+
WHERE id='${job.id}' AND status='queued';`);
|
|
123
|
+
if (!res.success || !/UPDATE 1/.test(res.stdout)) {
|
|
124
|
+
log.debug(`[agent] job ${job.id} already claimed by another runner — skip`);
|
|
125
|
+
return undefined;
|
|
126
|
+
}
|
|
127
|
+
await audit(cfg, job.requested_by, 'job_claimed', `job:${job.id}`, { type: job.type, payload: job.payload });
|
|
128
|
+
return job;
|
|
129
|
+
}
|
|
130
|
+
async function runJob(cfg, job) {
|
|
131
|
+
log.info(`[agent] running job ${job.id} (${job.type})`);
|
|
132
|
+
const steps = [];
|
|
133
|
+
try {
|
|
134
|
+
// 1. Verify signature (or skip in dev with a warning).
|
|
135
|
+
verifySignature(job);
|
|
136
|
+
// 2. Dispatch by type.
|
|
137
|
+
if (job.type === 'brand_reconcile') {
|
|
138
|
+
const brand = typeof job.payload.brand === 'string' ? job.payload.brand : undefined;
|
|
139
|
+
const dns = job.payload.dns === true;
|
|
140
|
+
const out = await spawnReconcile(cfg.alias, brand, dns);
|
|
141
|
+
steps.push(...out.steps);
|
|
142
|
+
if (!out.ok)
|
|
143
|
+
throw new Error(out.error || 'reconcile failed');
|
|
144
|
+
}
|
|
145
|
+
else if (job.type === 'db_promote_silo') {
|
|
146
|
+
// F5 / Faz 6 — pool→silo terfi orchestrator (9-step).
|
|
147
|
+
// Mevcut provision-agent çatısı reuse (K4 lock); orchestrator
|
|
148
|
+
// cp_provisioning_jobs.steps'i kendisi günceller (per-step
|
|
149
|
+
// idempotent resume). Buradaki steps[] yalnız agent yüzeyindeki
|
|
150
|
+
// özet log; resmi steps jsonb job.id ile orchestrator yönetir.
|
|
151
|
+
const brand = typeof job.payload.brand === 'string' ? job.payload.brand : undefined;
|
|
152
|
+
if (!brand)
|
|
153
|
+
throw new Error('db_promote_silo payload missing brand');
|
|
154
|
+
const out = await spawnPromoteSilo(cfg.alias, brand, job.id);
|
|
155
|
+
steps.push(...out.steps);
|
|
156
|
+
if (!out.ok)
|
|
157
|
+
throw new Error(out.error || 'promote-silo failed');
|
|
158
|
+
}
|
|
159
|
+
else if (job.type === 'db_promote_silo_rollback') {
|
|
160
|
+
// Faz 6.2 — silo→pool geri dönüş orchestrator (9-step).
|
|
161
|
+
// INV-5 (anti-leak ters yön) + UUID-only v1 + INV-3 'rolling_back'
|
|
162
|
+
// freeze BrandWriteGuardMiddleware allow-list ile. Spawn aynı
|
|
163
|
+
// pattern (--confirm-manifest agent mode + --job-id).
|
|
164
|
+
const brand = typeof job.payload.brand === 'string' ? job.payload.brand : undefined;
|
|
165
|
+
if (!brand)
|
|
166
|
+
throw new Error('db_promote_silo_rollback payload missing brand');
|
|
167
|
+
const out = await spawnRollbackSilo(cfg.alias, brand, job.id);
|
|
168
|
+
steps.push(...out.steps);
|
|
169
|
+
if (!out.ok)
|
|
170
|
+
throw new Error(out.error || 'rollback-silo failed');
|
|
171
|
+
}
|
|
172
|
+
else if (job.type === 'db_relocate') {
|
|
173
|
+
// M2 — db_relocate orchestrator (9-step; K-REL-* onaylı).
|
|
174
|
+
// brand'in dedicated DB'sini farklı host/cluster'a taşır. Write-freeze
|
|
175
|
+
// status='relocating' (BrandWriteGuardMiddleware allow-list, migration
|
|
176
|
+
// 006). pg_dump|pg_restore (K-REL-1 v1); kaynak DB retain 14g (K-REL-3
|
|
177
|
+
// INV-2 reuse). Payload: { brand, target_host, target_port?, target_
|
|
178
|
+
// cluster?, target_region? }.
|
|
179
|
+
const brand = typeof job.payload.brand === 'string' ? job.payload.brand : undefined;
|
|
180
|
+
const targetHost = typeof job.payload.target_host === 'string' ? job.payload.target_host : undefined;
|
|
181
|
+
const targetPort = typeof job.payload.target_port === 'number'
|
|
182
|
+
? String(job.payload.target_port)
|
|
183
|
+
: (typeof job.payload.target_port === 'string' ? job.payload.target_port : undefined);
|
|
184
|
+
const targetCluster = typeof job.payload.target_cluster === 'string' ? job.payload.target_cluster : undefined;
|
|
185
|
+
const targetRegion = typeof job.payload.target_region === 'string' ? job.payload.target_region : undefined;
|
|
186
|
+
if (!brand)
|
|
187
|
+
throw new Error('db_relocate payload missing brand');
|
|
188
|
+
if (!targetHost)
|
|
189
|
+
throw new Error('db_relocate payload missing target_host');
|
|
190
|
+
const out = await spawnRelocate(cfg.alias, brand, targetHost, targetPort, targetCluster, targetRegion, job.id);
|
|
191
|
+
steps.push(...out.steps);
|
|
192
|
+
if (!out.ok)
|
|
193
|
+
throw new Error(out.error || 'db_relocate failed');
|
|
194
|
+
}
|
|
195
|
+
else if (job.type === 'publish_addon') {
|
|
196
|
+
// M3.4 — control-plane registration via AddonRegistryService (single
|
|
197
|
+
// authority, K-M3.4-1) inside the app container, then manifest → R2.
|
|
198
|
+
const out = await spawnPublishAddon(cfg, job.payload, job.id);
|
|
199
|
+
steps.push(...out.steps);
|
|
200
|
+
if (!out.ok)
|
|
201
|
+
throw new Error(out.error || 'publish_addon failed');
|
|
202
|
+
}
|
|
203
|
+
else if (job.type === 'manifest_refresh') {
|
|
204
|
+
// E7-1 — quarantine/revoke runtime-propagasyon: GÜNCEL DB'den imzalı manifest
|
|
205
|
+
// regen + R2'ye yükle → Worker addon-gate.js taze entry.scan_status okur →
|
|
206
|
+
// quarantine ALWAYS 451. publish'siz (cp_addons'a yazmaz).
|
|
207
|
+
const out = await spawnManifestRefresh(cfg, job.id);
|
|
208
|
+
steps.push(...out.steps);
|
|
209
|
+
if (!out.ok)
|
|
210
|
+
throw new Error(out.error || 'manifest_refresh failed');
|
|
211
|
+
}
|
|
212
|
+
else {
|
|
213
|
+
throw new Error(`unknown job type '${job.type}'`);
|
|
214
|
+
}
|
|
215
|
+
await completeJob(cfg, job.id, 'success', steps, null);
|
|
216
|
+
await audit(cfg, job.requested_by, 'job_success', `job:${job.id}`, { steps });
|
|
217
|
+
log.success(`[agent] job ${job.id} success (${steps.length} steps)`);
|
|
218
|
+
}
|
|
219
|
+
catch (err) {
|
|
220
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
221
|
+
// Forward-recovery saga: each step is idempotent (R2 hash-path no-op, cp ON CONFLICT,
|
|
222
|
+
// am refreshCdnManifest+pointer-set). Mark 'failed' → reconcileStaleJobs exp-backoff
|
|
223
|
+
// requeue → publish-job re-runs → forward-completes. No backward compensation needed.
|
|
224
|
+
await completeJob(cfg, job.id, 'failed', steps, message);
|
|
225
|
+
await audit(cfg, job.requested_by, 'job_failed', `job:${job.id}`, { error: message, steps });
|
|
226
|
+
log.error(`[agent] job ${job.id} failed: ${message}`);
|
|
227
|
+
}
|
|
228
|
+
}
|
|
229
|
+
async function completeJob(cfg, id, status, steps, error) {
|
|
230
|
+
const errSql = error === null ? 'NULL' : `'${sqlLit(error)}'`;
|
|
231
|
+
await dbExec(cfg, CONTROL_DB, `UPDATE cp_provisioning_jobs
|
|
232
|
+
SET status='${status}', steps='${sqlLit(JSON.stringify(steps))}'::jsonb,
|
|
233
|
+
error=${errSql}, finished_at=now()
|
|
234
|
+
WHERE id='${id}';`);
|
|
235
|
+
}
|
|
236
|
+
/**
|
|
237
|
+
* Stuck-job reconcile (RECONCILE-JOB, provision-agent tamamlayıcısı). claimNext yalnız
|
|
238
|
+
* 'queued' alır → bir agent 'running'a aldıktan SONRA ölürse (completeJob'a varmadan) job
|
|
239
|
+
* sonsuza dek 'running' kalır + ASLA re-claim edilmez (sessiz stuck). Bu mekanizma onları
|
|
240
|
+
* kurtarır — getStatus-re-pull yerine yaş-tabanlı re-evaluate (idempotent + fail-closed):
|
|
241
|
+
*
|
|
242
|
+
* yaş ≤ staleMin → ATLA (aktif agent olabilir; çift-run yok)
|
|
243
|
+
* staleMin < yaş ≤ maxAge → REQUEUE ('running'→'queued'); agent normal yolla idempotent
|
|
244
|
+
* re-run eder (job ops per-step resume + brand-reconcile idempotent)
|
|
245
|
+
* yaş > maxAge → FAILED (fail-closed: vazgeç, manuel müdahale; sonsuz-requeue YOK)
|
|
246
|
+
*
|
|
247
|
+
* Yaş-tabanlı bound = attempt-sayaç kolonu GEREKMEZ (migration-prod-apply yok). Tüm UPDATE'ler
|
|
248
|
+
* `status='running' AND finished_at IS NULL` guard'lı → race-safe (bu arada biten job'a dokunmaz).
|
|
249
|
+
*/
|
|
250
|
+
async function reconcileStaleJobs(cfg, staleMin, maxAgeMin, dryRun) {
|
|
251
|
+
const stale = await dbSelectJson(cfg, CONTROL_DB, `SELECT id, type, requested_by, EXTRACT(EPOCH FROM (now() - created_at))/60 AS age_min
|
|
252
|
+
FROM cp_provisioning_jobs
|
|
253
|
+
WHERE status='running' AND finished_at IS NULL
|
|
254
|
+
AND created_at < now() - (interval '1 minute' * ${staleMin})
|
|
255
|
+
ORDER BY created_at`);
|
|
256
|
+
if (stale.length === 0) {
|
|
257
|
+
log.info('[reconcile] stuck-running job yok (temiz).');
|
|
258
|
+
return { requeued: 0, failed: 0, skipped: 0 };
|
|
259
|
+
}
|
|
260
|
+
log.warn(`[reconcile] ${stale.length} stuck-running job (>${staleMin}dk, hiç tamamlanmamış).`);
|
|
261
|
+
let requeued = 0, failed = 0, skipped = 0;
|
|
262
|
+
for (const j of stale) {
|
|
263
|
+
const age = Math.round(Number(j.age_min));
|
|
264
|
+
if (Number(j.age_min) > maxAgeMin) {
|
|
265
|
+
// fail-closed: çok-eski → vazgeç (manuel). Sonsuz-requeue engeli.
|
|
266
|
+
if (dryRun) {
|
|
267
|
+
log.info(`[reconcile] (dry) ${j.id} (${j.type}, ${age}dk) → FAILED (max-age)`);
|
|
268
|
+
failed++;
|
|
269
|
+
continue;
|
|
270
|
+
}
|
|
271
|
+
const err = `reconcile: stuck >${maxAgeMin}dk (running, hiç tamamlanmadı) → fail-closed, manuel müdahale gerekli`;
|
|
272
|
+
const res = await dbExec(cfg, CONTROL_DB, `UPDATE cp_provisioning_jobs SET status='failed', error='${sqlLit(err)}', finished_at=now()
|
|
273
|
+
WHERE id='${j.id}' AND status='running' AND finished_at IS NULL;`);
|
|
274
|
+
if (res.success && /UPDATE 1/.test(res.stdout)) {
|
|
275
|
+
await audit(cfg, j.requested_by, 'job_reconcile_failed', `job:${j.id}`, { age_min: age, reason: 'max-age' });
|
|
276
|
+
log.error(`[ALERT:reconcile-stuck][cid:${j.id}] STUCK-JOB-FAILED: type=${j.type} age=${age}dk req_by=${j.requested_by ?? 'system'} — fail-closed, manuel müdahale gerekli (DURABILITY-RISK)`);
|
|
277
|
+
failed++;
|
|
278
|
+
}
|
|
279
|
+
else {
|
|
280
|
+
skipped++;
|
|
281
|
+
log.debug(`[reconcile] ${j.id} state değişti (race) — skip`);
|
|
282
|
+
}
|
|
283
|
+
}
|
|
284
|
+
else {
|
|
285
|
+
// idempotent recovery: requeue → agent re-run eder (per-step resume).
|
|
286
|
+
if (dryRun) {
|
|
287
|
+
log.info(`[reconcile] (dry) ${j.id} (${j.type}, ${age}dk) → REQUEUE`);
|
|
288
|
+
requeued++;
|
|
289
|
+
continue;
|
|
290
|
+
}
|
|
291
|
+
const res = await dbExec(cfg, CONTROL_DB, `UPDATE cp_provisioning_jobs SET status='queued'
|
|
292
|
+
WHERE id='${j.id}' AND status='running' AND finished_at IS NULL;`);
|
|
293
|
+
if (res.success && /UPDATE 1/.test(res.stdout)) {
|
|
294
|
+
await audit(cfg, j.requested_by, 'job_reconcile_requeued', `job:${j.id}`, { age_min: age });
|
|
295
|
+
log.warn(`[ALERT:reconcile-requeued][cid:${j.id}] STUCK-JOB-REQUEUED: type=${j.type} age=${age}dk req_by=${j.requested_by ?? 'system'} — idempotent-rerun tetiklendi`);
|
|
296
|
+
requeued++;
|
|
297
|
+
}
|
|
298
|
+
else {
|
|
299
|
+
skipped++;
|
|
300
|
+
log.debug(`[reconcile] ${j.id} state değişti (race) — skip`);
|
|
301
|
+
}
|
|
302
|
+
}
|
|
303
|
+
}
|
|
304
|
+
log.info(`[reconcile] ${requeued} requeued · ${failed} failed (fail-closed) · ${skipped} skip${dryRun ? ' [DRY-RUN]' : ''}.`);
|
|
305
|
+
return { requeued, failed, skipped };
|
|
306
|
+
}
|
|
307
|
+
async function audit(cfg, actor, action, target, after) {
|
|
308
|
+
await dbExec(cfg, CONTROL_DB, `INSERT INTO cp_audit_log (actor, action, target, after)
|
|
309
|
+
VALUES (${actor ? `'${sqlLit(actor)}'` : 'NULL'}, '${sqlLit(action)}', '${sqlLit(target)}',
|
|
310
|
+
'${sqlLit(JSON.stringify(after))}'::jsonb);`);
|
|
311
|
+
}
|
|
312
|
+
/** Spawn `ci brand reconcile` as a child process; map output → steps + ok. */
|
|
313
|
+
function spawnReconcile(host, brand, dns) {
|
|
314
|
+
const cliEntry = fileURLToPath(new URL('../../index.js', import.meta.url));
|
|
315
|
+
const args = [cliEntry, 'brand', 'reconcile', '--host', host];
|
|
316
|
+
if (brand)
|
|
317
|
+
args.push('--brand', brand);
|
|
318
|
+
if (dns)
|
|
319
|
+
args.push('--dns');
|
|
320
|
+
return new Promise((resolve) => {
|
|
321
|
+
execFile(process.execPath, args, { timeout: 300_000 }, (error, stdout, stderr) => {
|
|
322
|
+
const text = `${stdout}\n${stderr}`;
|
|
323
|
+
// Step lines: the reconcile summary marks each with ✓ / ⚠.
|
|
324
|
+
const steps = text.split('\n').map(l => l.trim()).filter(l => /^[ℹ]?\s*[✓⚠]/.test(l) || /[✓⚠]/.test(l)).map(l => l.replace(/^ℹ\s*/, ''));
|
|
325
|
+
resolve({ ok: !error, steps, error: error ? (stderr.trim() || stdout.trim() || error.message).slice(0, 500) : '' });
|
|
326
|
+
});
|
|
327
|
+
});
|
|
328
|
+
}
|
|
329
|
+
/**
|
|
330
|
+
* M3.4 publish_addon executor (option-b / single authority). Runs the host-side
|
|
331
|
+
* runner INSIDE the app container so the control-plane write goes through
|
|
332
|
+
* AddonRegistryService (the only cp_addons writer), then uploads the rebuilt
|
|
333
|
+
* catalog manifest to R2 (the CDN gate reads it). Idempotent: the runner's
|
|
334
|
+
* upsert/publishVersion are upserts, so a re-queued job is safe.
|
|
335
|
+
*
|
|
336
|
+
* Host config (deploy/Mustafa-gate): CICORE_PHP_CONTAINER (default 'cicore-php')
|
|
337
|
+
* + PUBLISH_ADDON_RUNNER (default the in-container script path).
|
|
338
|
+
*/
|
|
339
|
+
async function spawnPublishAddon(cfg, payload, jobId) {
|
|
340
|
+
const steps = [];
|
|
341
|
+
const container = process.env.CICORE_PHP_CONTAINER ?? 'cicore-php';
|
|
342
|
+
const runner = process.env.PUBLISH_ADDON_RUNNER ?? '/var/www/app/Backend/Console/publish-addon-job.php';
|
|
343
|
+
// inject job ID so publish-addon-job.php can log saga steps with traceability
|
|
344
|
+
const payloadJson = JSON.stringify({ ...payload, _job_id: jobId });
|
|
345
|
+
// Saga compensation C1: R2 hash-path clean (orphan prevention on fail).
|
|
346
|
+
// PHP handles C2 (cp_addon_versions.content_hash=null) + C3 (am-pointer restore) server-side.
|
|
347
|
+
const sagaCompensateR2 = async () => {
|
|
348
|
+
const ver = payload.version;
|
|
349
|
+
const hash = typeof ver?.content_hash === 'string' ? ver.content_hash : undefined;
|
|
350
|
+
const addonMeta = payload.addon;
|
|
351
|
+
const slug = typeof addonMeta?.slug === 'string' ? addonMeta.slug
|
|
352
|
+
: typeof payload.slug === 'string' ? payload.slug : undefined;
|
|
353
|
+
if (hash && slug) {
|
|
354
|
+
await cdnCleanAddon(cfg, slug, { version: hash }).catch(() => { });
|
|
355
|
+
steps.push(`saga compensation C1: R2 hash-path ${slug}/${hash} cleaned`);
|
|
356
|
+
}
|
|
357
|
+
};
|
|
358
|
+
// 1. Register in control-plane via AddonRegistryService (single authority).
|
|
359
|
+
const run = await new Promise((resolve) => {
|
|
360
|
+
execFile('docker', ['exec', container, 'php', runner, payloadJson], { timeout: 300_000 }, (error, stdout, stderr) => {
|
|
361
|
+
resolve({ ok: !error, stdout: stdout ?? '', error: error ? (stderr.trim() || error.message).slice(0, 500) : '' });
|
|
362
|
+
});
|
|
363
|
+
});
|
|
364
|
+
if (!run.ok) {
|
|
365
|
+
await sagaCompensateR2();
|
|
366
|
+
return { ok: false, steps, error: `publish-job: ${run.error}` };
|
|
367
|
+
}
|
|
368
|
+
// collect any SAGA_STEP_DONE lines emitted by publish-addon-job.php
|
|
369
|
+
for (const l of run.stdout.split('\n')) {
|
|
370
|
+
if (l.startsWith('SAGA_STEP_DONE='))
|
|
371
|
+
steps.push(`saga: ${l.slice('SAGA_STEP_DONE='.length).trim()}`);
|
|
372
|
+
}
|
|
373
|
+
steps.push('publish-job: control-plane registered (AddonRegistryService)');
|
|
374
|
+
// 2. Extract the rebuilt manifest → upload to R2 (addons/_manifest.json).
|
|
375
|
+
const line = run.stdout.split('\n').find(l => l.startsWith('MANIFEST_JSON='));
|
|
376
|
+
if (!line) {
|
|
377
|
+
await sagaCompensateR2();
|
|
378
|
+
return { ok: false, steps, error: 'publish-job: MANIFEST_JSON üretilmedi' };
|
|
379
|
+
}
|
|
380
|
+
const up = await cdnUploadManifest(cfg, line.slice('MANIFEST_JSON='.length));
|
|
381
|
+
if (!up.success) {
|
|
382
|
+
await sagaCompensateR2();
|
|
383
|
+
steps.push('manifest upload FAILED');
|
|
384
|
+
return { ok: false, steps, error: 'manifest upload failed' };
|
|
385
|
+
}
|
|
386
|
+
steps.push('manifest uploaded to R2 (addons/_manifest.json)');
|
|
387
|
+
return { ok: true, steps, error: '' };
|
|
388
|
+
}
|
|
389
|
+
/**
|
|
390
|
+
* E7-1 manifest_refresh executor — quarantine/revoke runtime-propagasyon. GÜNCEL DB'den
|
|
391
|
+
* imzalı manifest regen (refresh-manifest-job.php, READ-ONLY) → R2'ye yükle. publish
|
|
392
|
+
* YOK (cp_addons'a yazmaz). Worker taze manifest'i okuyunca quarantine entry → 451.
|
|
393
|
+
*/
|
|
394
|
+
async function spawnManifestRefresh(cfg, _jobId) {
|
|
395
|
+
const steps = [];
|
|
396
|
+
const container = process.env.CICORE_PHP_CONTAINER ?? 'cicore-php';
|
|
397
|
+
const runner = process.env.REFRESH_MANIFEST_RUNNER ?? '/var/www/app/Backend/Console/refresh-manifest-job.php';
|
|
398
|
+
const run = await new Promise((resolve) => {
|
|
399
|
+
execFile('docker', ['exec', container, 'php', runner], { timeout: 120_000 }, (error, stdout, stderr) => {
|
|
400
|
+
resolve({ ok: !error, stdout: stdout ?? '', error: error ? (stderr.trim() || error.message).slice(0, 500) : '' });
|
|
401
|
+
});
|
|
402
|
+
});
|
|
403
|
+
if (!run.ok)
|
|
404
|
+
return { ok: false, steps, error: `refresh-manifest-job: ${run.error}` };
|
|
405
|
+
const line = run.stdout.split('\n').find(l => l.startsWith('MANIFEST_JSON='));
|
|
406
|
+
if (!line)
|
|
407
|
+
return { ok: false, steps, error: 'refresh-manifest-job: MANIFEST_JSON üretilmedi' };
|
|
408
|
+
const up = await cdnUploadManifest(cfg, line.slice('MANIFEST_JSON='.length));
|
|
409
|
+
if (!up.success) {
|
|
410
|
+
steps.push('manifest upload FAILED');
|
|
411
|
+
return { ok: false, steps, error: 'manifest upload failed' };
|
|
412
|
+
}
|
|
413
|
+
steps.push('manifest refreshed → R2 (quarantine/revoke runtime-propagasyon)');
|
|
414
|
+
return { ok: true, steps, error: '' };
|
|
415
|
+
}
|
|
416
|
+
/**
|
|
417
|
+
* Spawn `ci db promote-silo` as a child process. Agent always passes
|
|
418
|
+
* --confirm-manifest (job already approved via panel super-admin gate +
|
|
419
|
+
* HMAC signature; no human-in-the-loop on the agent side). --job-id ties
|
|
420
|
+
* orchestrator's per-step jsonb to the row claimed by claimNext().
|
|
421
|
+
*/
|
|
422
|
+
function spawnPromoteSilo(host, brand, jobId) {
|
|
423
|
+
const cliEntry = fileURLToPath(new URL('../../index.js', import.meta.url));
|
|
424
|
+
const args = [cliEntry, 'db', 'promote-silo',
|
|
425
|
+
'--brand', brand, '--host', host,
|
|
426
|
+
'--job-id', jobId, '--confirm-manifest'];
|
|
427
|
+
return new Promise((resolve) => {
|
|
428
|
+
// 30 dk timeout — data migration uzun sürebilir; per-step idempotent
|
|
429
|
+
// guard sayesinde timeout sonrası resume güvenli.
|
|
430
|
+
execFile(process.execPath, args, { timeout: 1_800_000 }, (error, stdout, stderr) => {
|
|
431
|
+
const text = `${stdout}\n${stderr}`;
|
|
432
|
+
const steps = text.split('\n').map(l => l.trim())
|
|
433
|
+
.filter(l => /\[step \d+\/\d+\]/.test(l) || /^[ℹ]?\s*[✓⚠]/.test(l))
|
|
434
|
+
.map(l => l.replace(/^ℹ\s*/, ''));
|
|
435
|
+
resolve({ ok: !error, steps, error: error ? (stderr.trim() || stdout.trim() || error.message).slice(0, 500) : '' });
|
|
436
|
+
});
|
|
437
|
+
});
|
|
438
|
+
}
|
|
439
|
+
/**
|
|
440
|
+
* Spawn `ci db rollback-silo` — Faz 6.2 ters yön orchestrator. Aynı
|
|
441
|
+
* --confirm-manifest + --job-id pattern. 30 dk timeout (delete+copy
|
|
442
|
+
* uzun sürebilir; per-step idempotent guard resume güvenli).
|
|
443
|
+
*/
|
|
444
|
+
function spawnRollbackSilo(host, brand, jobId) {
|
|
445
|
+
const cliEntry = fileURLToPath(new URL('../../index.js', import.meta.url));
|
|
446
|
+
const args = [cliEntry, 'db', 'rollback-silo',
|
|
447
|
+
'--brand', brand, '--host', host,
|
|
448
|
+
'--job-id', jobId, '--confirm-manifest'];
|
|
449
|
+
return new Promise((resolve) => {
|
|
450
|
+
execFile(process.execPath, args, { timeout: 1_800_000 }, (error, stdout, stderr) => {
|
|
451
|
+
const text = `${stdout}\n${stderr}`;
|
|
452
|
+
const steps = text.split('\n').map(l => l.trim())
|
|
453
|
+
.filter(l => /\[step \d+\/\d+\]/.test(l) || /^[ℹ]?\s*[✓⚠]/.test(l))
|
|
454
|
+
.map(l => l.replace(/^ℹ\s*/, ''));
|
|
455
|
+
resolve({ ok: !error, steps, error: error ? (stderr.trim() || stdout.trim() || error.message).slice(0, 500) : '' });
|
|
456
|
+
});
|
|
457
|
+
});
|
|
458
|
+
}
|
|
459
|
+
/**
|
|
460
|
+
* Spawn `ci db relocate` — M2 db_relocate (aktif yön; K-REL onaylı).
|
|
461
|
+
* Agent --confirm-relocation her zaman geçirir (panel super-admin gate +
|
|
462
|
+
* HMAC zaten onay sağlar). 30 dk timeout (büyük DB pg_dump/restore uzun
|
|
463
|
+
* sürebilir; idempotent guard sayesinde resume güvenli).
|
|
464
|
+
*/
|
|
465
|
+
function spawnRelocate(host, brand, targetHost, targetPort, targetCluster, targetRegion, jobId) {
|
|
466
|
+
const cliEntry = fileURLToPath(new URL('../../index.js', import.meta.url));
|
|
467
|
+
const args = [cliEntry, 'db', 'relocate',
|
|
468
|
+
'--brand', brand, '--host', host,
|
|
469
|
+
'--target-host', targetHost,
|
|
470
|
+
'--job-id', jobId, '--confirm-relocation'];
|
|
471
|
+
if (targetPort)
|
|
472
|
+
args.push('--target-port', targetPort);
|
|
473
|
+
if (targetCluster)
|
|
474
|
+
args.push('--target-cluster', targetCluster);
|
|
475
|
+
if (targetRegion)
|
|
476
|
+
args.push('--target-region', targetRegion);
|
|
477
|
+
return new Promise((resolve) => {
|
|
478
|
+
execFile(process.execPath, args, { timeout: 1_800_000 }, (error, stdout, stderr) => {
|
|
479
|
+
const text = `${stdout}\n${stderr}`;
|
|
480
|
+
const steps = text.split('\n').map(l => l.trim())
|
|
481
|
+
.filter(l => /\[step \d+\/\d+\]/.test(l) || /^[ℹ]?\s*[✓⚠]/.test(l))
|
|
482
|
+
.map(l => l.replace(/^ℹ\s*/, ''));
|
|
483
|
+
resolve({ ok: !error, steps, error: error ? (stderr.trim() || stdout.trim() || error.message).slice(0, 500) : '' });
|
|
484
|
+
});
|
|
485
|
+
});
|
|
486
|
+
}
|
|
487
|
+
// ─────────────────────────────────────────────────────────────────────────
|
|
488
|
+
// Signing (HMAC — panel can't inject arbitrary jobs)
|
|
489
|
+
// ─────────────────────────────────────────────────────────────────────────
|
|
490
|
+
/**
|
|
491
|
+
* Order-stable canonical string for signing. Keys are sorted recursively so the
|
|
492
|
+
* signature survives jsonb's key re-normalisation (Postgres returns jsonb keys
|
|
493
|
+
* in a different order than they were inserted — without this, every legit job
|
|
494
|
+
* would fail verification).
|
|
495
|
+
*/
|
|
496
|
+
function canonical(type, targetType, payload) {
|
|
497
|
+
return stableStringify({ type, target_type: targetType, payload });
|
|
498
|
+
}
|
|
499
|
+
function stableStringify(value) {
|
|
500
|
+
if (value === null || typeof value !== 'object')
|
|
501
|
+
return JSON.stringify(value);
|
|
502
|
+
if (Array.isArray(value))
|
|
503
|
+
return `[${value.map(stableStringify).join(',')}]`;
|
|
504
|
+
const obj = value;
|
|
505
|
+
return `{${Object.keys(obj).sort().map(k => `${JSON.stringify(k)}:${stableStringify(obj[k])}`).join(',')}}`;
|
|
506
|
+
}
|
|
507
|
+
/** Sign a job, or return '' (unsigned) when no secret is configured (dev). */
|
|
508
|
+
/**
|
|
509
|
+
* Enqueue a signed provisioning job (reusable by other commands, e.g.
|
|
510
|
+
* `ci addon publish` → publish_addon). Mirrors the `agent enqueue` INSERT;
|
|
511
|
+
* caller ensures `type` is a KNOWN_TYPES value. Returns whether the row landed.
|
|
512
|
+
*/
|
|
513
|
+
export async function enqueueJob(cfg, type, targetType, payload, requestedBy = 'cli') {
|
|
514
|
+
const sig = signJob(type, targetType, payload);
|
|
515
|
+
const sigSql = sig ? `'${sig}'` : 'NULL';
|
|
516
|
+
const res = await dbExec(cfg, CONTROL_DB, `INSERT INTO cp_provisioning_jobs (target_type, type, payload, status, requested_by, signature)
|
|
517
|
+
VALUES ('${sqlLit(targetType)}', '${sqlLit(type)}', '${sqlLit(JSON.stringify(payload))}'::jsonb, 'queued',
|
|
518
|
+
'${sqlLit(requestedBy)}', ${sigSql});`);
|
|
519
|
+
return res.success;
|
|
520
|
+
}
|
|
521
|
+
function signJob(type, targetType, payload) {
|
|
522
|
+
const secret = process.env.CICORE_JOB_SIGNING_SECRET;
|
|
523
|
+
if (!secret) {
|
|
524
|
+
log.warn('CICORE_JOB_SIGNING_SECRET unset — enqueuing UNSIGNED job (dev only).');
|
|
525
|
+
return '';
|
|
526
|
+
}
|
|
527
|
+
return createHmac('sha256', secret).update(canonical(type, targetType, payload)).digest('hex');
|
|
528
|
+
}
|
|
529
|
+
/** Verify a job's signature; throw on mismatch. Dev mode (no secret) warns + passes. */
|
|
530
|
+
function verifySignature(job) {
|
|
531
|
+
const secret = process.env.CICORE_JOB_SIGNING_SECRET;
|
|
532
|
+
if (!secret) {
|
|
533
|
+
log.warn(`[agent] CICORE_JOB_SIGNING_SECRET unset — running job ${job.id} WITHOUT signature check (dev only).`);
|
|
534
|
+
return;
|
|
535
|
+
}
|
|
536
|
+
const expected = createHmac('sha256', secret).update(canonical(job.type, job.target_type, job.payload)).digest('hex');
|
|
537
|
+
if (job.signature !== expected) {
|
|
538
|
+
throw new Error('job signature invalid — refusing to execute (possible tampering)');
|
|
539
|
+
}
|
|
540
|
+
}
|
|
541
|
+
// ─────────────────────────────────────────────────────────────────────────
|
|
542
|
+
// Helpers
|
|
543
|
+
// ─────────────────────────────────────────────────────────────────────────
|
|
544
|
+
function assertType(type) {
|
|
545
|
+
if (!KNOWN_TYPES.includes(type)) {
|
|
546
|
+
log.error(`Unknown --type '${type}'. Known: ${KNOWN_TYPES.join(', ')}.`);
|
|
547
|
+
process.exit(1);
|
|
548
|
+
}
|
|
549
|
+
}
|
|
550
|
+
function resolveHost(alias) {
|
|
551
|
+
if (alias === undefined) {
|
|
552
|
+
log.error('--host is required (cicore | mkt).');
|
|
553
|
+
process.exit(1);
|
|
554
|
+
}
|
|
555
|
+
try {
|
|
556
|
+
return getHostConfig(alias);
|
|
557
|
+
}
|
|
558
|
+
catch (err) {
|
|
559
|
+
log.error(err instanceof Error ? err.message : String(err));
|
|
560
|
+
process.exit(1);
|
|
561
|
+
}
|
|
562
|
+
}
|
|
563
|
+
function sqlLit(s) { return s.replace(/'/g, "''"); }
|
|
564
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/commands/agent/index.ts"],"names":[],"mappings":"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"}
|