@hsuite/smart-engines-cli 1.2.1 → 1.4.2
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/README.md +272 -58
- package/dist/_lib/attestation.d.ts +45 -0
- package/dist/_lib/attestation.d.ts.map +1 -0
- package/dist/_lib/attestation.js +76 -0
- package/dist/_lib/attestation.js.map +1 -0
- package/dist/_lib/baas.d.ts +147 -0
- package/dist/_lib/baas.d.ts.map +1 -0
- package/dist/_lib/baas.js +260 -0
- package/dist/_lib/baas.js.map +1 -0
- package/dist/_lib/cluster.d.ts +6 -6
- package/dist/_lib/cluster.js +6 -6
- package/dist/_lib/deploy-manifest.d.ts +69 -0
- package/dist/_lib/deploy-manifest.d.ts.map +1 -0
- package/dist/_lib/deploy-manifest.js +87 -0
- package/dist/_lib/deploy-manifest.js.map +1 -0
- package/dist/_lib/docker.d.ts +82 -0
- package/dist/_lib/docker.d.ts.map +1 -0
- package/dist/_lib/docker.js +164 -0
- package/dist/_lib/docker.js.map +1 -0
- package/dist/_lib/faucet-client.d.ts +64 -0
- package/dist/_lib/faucet-client.d.ts.map +1 -0
- package/dist/_lib/faucet-client.js +92 -0
- package/dist/_lib/faucet-client.js.map +1 -0
- package/dist/_lib/framework.d.ts +59 -0
- package/dist/_lib/framework.d.ts.map +1 -0
- package/dist/_lib/framework.js +149 -0
- package/dist/_lib/framework.js.map +1 -0
- package/dist/_lib/frontend-guard.d.ts +13 -0
- package/dist/_lib/frontend-guard.d.ts.map +1 -0
- package/dist/_lib/frontend-guard.js +41 -0
- package/dist/_lib/frontend-guard.js.map +1 -0
- package/dist/_lib/registry-fanout.d.ts +178 -0
- package/dist/_lib/registry-fanout.d.ts.map +1 -0
- package/dist/_lib/registry-fanout.js +545 -0
- package/dist/_lib/registry-fanout.js.map +1 -0
- package/dist/_lib/runtime-env.d.ts +126 -0
- package/dist/_lib/runtime-env.d.ts.map +1 -0
- package/dist/_lib/runtime-env.js +172 -0
- package/dist/_lib/runtime-env.js.map +1 -0
- package/dist/_lib/subscription-client.d.ts +129 -18
- package/dist/_lib/subscription-client.d.ts.map +1 -1
- package/dist/_lib/subscription-client.js +268 -40
- package/dist/_lib/subscription-client.js.map +1 -1
- package/dist/_lib/subscription-env.d.ts +35 -0
- package/dist/_lib/subscription-env.d.ts.map +1 -1
- package/dist/_lib/subscription-env.js +46 -2
- package/dist/_lib/subscription-env.js.map +1 -1
- package/dist/commands/app-lifecycle.d.ts +36 -0
- package/dist/commands/app-lifecycle.d.ts.map +1 -0
- package/dist/commands/app-lifecycle.js +145 -0
- package/dist/commands/app-lifecycle.js.map +1 -0
- package/dist/commands/ci.d.ts +45 -0
- package/dist/commands/ci.d.ts.map +1 -0
- package/dist/commands/ci.js +174 -0
- package/dist/commands/ci.js.map +1 -0
- package/dist/commands/deploy-manifest.d.ts +11 -0
- package/dist/commands/deploy-manifest.d.ts.map +1 -0
- package/dist/commands/deploy-manifest.js +17 -0
- package/dist/commands/deploy-manifest.js.map +1 -0
- package/dist/commands/deploy.d.ts +70 -11
- package/dist/commands/deploy.d.ts.map +1 -1
- package/dist/commands/deploy.js +273 -150
- package/dist/commands/deploy.js.map +1 -1
- package/dist/commands/downgrade.js +1 -1
- package/dist/commands/downgrade.js.map +1 -1
- package/dist/commands/faucet.d.ts +78 -0
- package/dist/commands/faucet.d.ts.map +1 -0
- package/dist/commands/faucet.js +184 -0
- package/dist/commands/faucet.js.map +1 -0
- package/dist/commands/governance.js +1 -1
- package/dist/commands/governance.js.map +1 -1
- package/dist/commands/hist-balance.d.ts +1 -1
- package/dist/commands/hist-balance.js +1 -1
- package/dist/commands/init.js +1 -1
- package/dist/commands/list.d.ts +22 -0
- package/dist/commands/list.d.ts.map +1 -0
- package/dist/commands/list.js +81 -0
- package/dist/commands/list.js.map +1 -0
- package/dist/commands/personhood.js +2 -2
- package/dist/commands/personhood.js.map +1 -1
- package/dist/commands/redeploy.d.ts +62 -0
- package/dist/commands/redeploy.d.ts.map +1 -0
- package/dist/commands/redeploy.js +322 -0
- package/dist/commands/redeploy.js.map +1 -0
- package/dist/commands/status.d.ts +51 -0
- package/dist/commands/status.d.ts.map +1 -0
- package/dist/commands/status.js +138 -0
- package/dist/commands/status.js.map +1 -0
- package/dist/commands/subscribe.d.ts +94 -17
- package/dist/commands/subscribe.d.ts.map +1 -1
- package/dist/commands/subscribe.js +487 -81
- package/dist/commands/subscribe.js.map +1 -1
- package/dist/commands/transactions.d.ts +60 -0
- package/dist/commands/transactions.d.ts.map +1 -0
- package/dist/commands/transactions.js +101 -0
- package/dist/commands/transactions.js.map +1 -0
- package/dist/commands/update.d.ts +40 -0
- package/dist/commands/update.d.ts.map +1 -0
- package/dist/commands/update.js +114 -0
- package/dist/commands/update.js.map +1 -0
- package/dist/commands/verify.d.ts +10 -19
- package/dist/commands/verify.d.ts.map +1 -1
- package/dist/commands/verify.js +14 -23
- package/dist/commands/verify.js.map +1 -1
- package/dist/index.d.ts +12 -3
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +32 -3
- package/dist/index.js.map +1 -1
- package/package.json +11 -4
|
@@ -0,0 +1,322 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
+
var ownKeys = function(o) {
|
|
20
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
+
var ar = [];
|
|
22
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
+
return ar;
|
|
24
|
+
};
|
|
25
|
+
return ownKeys(o);
|
|
26
|
+
};
|
|
27
|
+
return function (mod) {
|
|
28
|
+
if (mod && mod.__esModule) return mod;
|
|
29
|
+
var result = {};
|
|
30
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
+
__setModuleDefault(result, mod);
|
|
32
|
+
return result;
|
|
33
|
+
};
|
|
34
|
+
})();
|
|
35
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
36
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
37
|
+
};
|
|
38
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
39
|
+
exports.redeployCommand = void 0;
|
|
40
|
+
exports.runRedeploy = runRedeploy;
|
|
41
|
+
/**
|
|
42
|
+
* `hsuite redeploy` — redeploy an EXISTING smart-app (same appId, fresh push
|
|
43
|
+
* creds, a new image tag and/or a new frontend bundle).
|
|
44
|
+
*
|
|
45
|
+
* Mirrors `deploy` but re-binds to an EXISTING app instead of forking a new one:
|
|
46
|
+
* - resolves the target appId (flag → DEPLOYED_APP_ID) and authenticates as
|
|
47
|
+
* the subscription identity (SUBSCRIPTION_APP_ID → target). Auth is by XRPL
|
|
48
|
+
* wallet; the bound appId is only client context (the host authorizes by
|
|
49
|
+
* wallet → developerWallet ownership of the target appId).
|
|
50
|
+
* - calls `reissuePushCredentials(appId)` for fresh single-use push creds —
|
|
51
|
+
* NOT `init`, which would mint a brand-new app + DKG entity + paid
|
|
52
|
+
* subscription on every run (~20 XRP/run + a new appId each time).
|
|
53
|
+
* - `--tag` overrides the manifest's `backend.tag`.
|
|
54
|
+
*
|
|
55
|
+
* The manifest is the ONE canonical shape (backend required, frontend optional):
|
|
56
|
+
* redeploy always rebuilds + pushes the backend image and re-uploads the SPA
|
|
57
|
+
* bundle when a `frontend` block is present, then `deploy()`s.
|
|
58
|
+
*
|
|
59
|
+
* Same trusted-deploy attestation as `deploy` (the host's deploy policy is
|
|
60
|
+
* hardened-by-default).
|
|
61
|
+
*/
|
|
62
|
+
const commander_1 = require("commander");
|
|
63
|
+
const chalk_1 = __importDefault(require("chalk"));
|
|
64
|
+
const fs_1 = require("fs");
|
|
65
|
+
const path_1 = require("path");
|
|
66
|
+
const os_1 = require("os");
|
|
67
|
+
const env_1 = require("../_lib/env");
|
|
68
|
+
const subscription_env_1 = require("../_lib/subscription-env");
|
|
69
|
+
const runtime_env_1 = require("../_lib/runtime-env");
|
|
70
|
+
const cluster_1 = require("../_lib/cluster");
|
|
71
|
+
const framework_1 = require("../_lib/framework");
|
|
72
|
+
const baas_1 = require("../_lib/baas");
|
|
73
|
+
const registry_fanout_1 = require("../_lib/registry-fanout");
|
|
74
|
+
const attestation_1 = require("../_lib/attestation");
|
|
75
|
+
const deploy_manifest_1 = require("../_lib/deploy-manifest");
|
|
76
|
+
const frontend_guard_1 = require("../_lib/frontend-guard");
|
|
77
|
+
const status_1 = require("./status");
|
|
78
|
+
/** Pure orchestration body — exported for unit tests. */
|
|
79
|
+
async function runRedeploy(opts) {
|
|
80
|
+
const manifest = (0, deploy_manifest_1.parseManifest)(opts.manifestPath);
|
|
81
|
+
const env = (0, env_1.readEnv)(opts.envPath);
|
|
82
|
+
const b = manifest.backend;
|
|
83
|
+
const tag = opts.tag ?? b.tag;
|
|
84
|
+
const detection = (0, framework_1.detectFramework)(opts.projectDir);
|
|
85
|
+
const sdkVersion = (0, framework_1.resolveSdkVersion)(opts.projectDir, detection);
|
|
86
|
+
// Auth IDENTITY (subscription) ≠ management TARGET (deployed app). The
|
|
87
|
+
// deployed app holds no subscription, so authenticate as the developer's
|
|
88
|
+
// subscription identity; the reissue below operates on the deployed appId.
|
|
89
|
+
// Auth is by XRPL wallet — the bound appId is only client context; the host
|
|
90
|
+
// authorizes by wallet → developerWallet ownership of the target appId.
|
|
91
|
+
// (Under mint-first/deploy-last `SUBSCRIPTION_APP_ID == DEPLOYED_APP_ID`, so
|
|
92
|
+
// these usually resolve to the same id; the split is retained because a
|
|
93
|
+
// developer MAY pass a distinct deployed --app-id.)
|
|
94
|
+
const subscriptionAppId = (0, subscription_env_1.requireSubscriptionAppId)(env, {
|
|
95
|
+
subscriptionAppId: opts.subscriptionAppId,
|
|
96
|
+
});
|
|
97
|
+
// Resolve the EXISTING app to redeploy: explicit flag → DEPLOYED_APP_ID.
|
|
98
|
+
// No subscription fallback — the subscription is the auth identity above, not
|
|
99
|
+
// a deploy target; a subscribe-but-never-deployed state has nothing to redeploy.
|
|
100
|
+
const appId = opts.appId ?? env.get('DEPLOYED_APP_ID');
|
|
101
|
+
if (!appId) {
|
|
102
|
+
throw new Error('No app to redeploy. Pass --app-id <id> or run `hsuite deploy` first (sets DEPLOYED_APP_ID).');
|
|
103
|
+
}
|
|
104
|
+
const client = await (0, baas_1.connectAndAuth)({
|
|
105
|
+
gateway: opts.gateway,
|
|
106
|
+
env,
|
|
107
|
+
appId: subscriptionAppId,
|
|
108
|
+
clientFactory: opts.clientFactory,
|
|
109
|
+
});
|
|
110
|
+
// Reissue ephemeral push creds for the EXISTING app — no fork, no new entity,
|
|
111
|
+
// no new subscription. Hits `POST /apps/:appId/credentials/reissue` (the
|
|
112
|
+
// dedicated redeploy route, distinct from deploy's `credentials/push`): the
|
|
113
|
+
// host asserts ownership + an ACTIVE subscription, refuses SUSPENDED apps, and
|
|
114
|
+
// (idempotently) rotates the per-app Harbor push robot.
|
|
115
|
+
const creds = await client.deployment.reissuePushCredentials(appId);
|
|
116
|
+
console.log(chalk_1.default.gray(` push creds reissued: appId=${creds.appId} registry=${creds.registry.repository}`));
|
|
117
|
+
if (!tag)
|
|
118
|
+
throw new Error('a backend redeploy needs a tag (manifest.backend.tag or --tag)');
|
|
119
|
+
// The `docker push` summary digest — the digest the LOCAL client holds. With a
|
|
120
|
+
// containerd image store (Colima / buildkit) this can differ from the digest
|
|
121
|
+
// Harbor serves for the tag; see resolveAttestationDigest below (#1589).
|
|
122
|
+
const pushDigest = (0, baas_1.buildAndPush)({
|
|
123
|
+
registry: creds.registry,
|
|
124
|
+
tag,
|
|
125
|
+
context: (0, path_1.resolve)(b.context ?? '.'),
|
|
126
|
+
dockerfile: b.dockerfile ?? 'Dockerfile',
|
|
127
|
+
platform: b.platform,
|
|
128
|
+
build: b.build,
|
|
129
|
+
skipBuild: opts.skipBuild,
|
|
130
|
+
skipPush: opts.skipPush,
|
|
131
|
+
dockerHost: opts.dockerHost,
|
|
132
|
+
name: manifest.name,
|
|
133
|
+
runFn: opts.runFn,
|
|
134
|
+
});
|
|
135
|
+
// #1589: attest the digest the registry SERVES for the tag (the same
|
|
136
|
+
// `Docker-Content-Digest` the deployer resolves + pins and the fan-out
|
|
137
|
+
// re-verifies), NOT the local `docker push` summary. Otherwise a containerd
|
|
138
|
+
// image-store push attests a manifest digest Harbor re-serialized under a
|
|
139
|
+
// different sha256 → the #1445 gate rejects a legitimate developer deploy.
|
|
140
|
+
const imageDigest = await (0, registry_fanout_1.resolveAttestationDigest)({
|
|
141
|
+
registry: creds.registry,
|
|
142
|
+
tag,
|
|
143
|
+
pushDigest,
|
|
144
|
+
log: (m) => console.log(chalk_1.default.gray(m)),
|
|
145
|
+
});
|
|
146
|
+
console.log(chalk_1.default.gray(` pushed: ${creds.registry.repository}:${tag} (${imageDigest})`));
|
|
147
|
+
// Fan the pushed image out to EVERY cluster Harbor before reconciling — the
|
|
148
|
+
// federated registry host round-robins, so the single push landed on one
|
|
149
|
+
// cluster. Blocks (throws → exit 1) unless every cluster serves the digest.
|
|
150
|
+
// Fed the SAME registry-served digest we attest, so present/verify agree.
|
|
151
|
+
if (!opts.skipDistribute) {
|
|
152
|
+
await (0, registry_fanout_1.fanOutPushedImage)({
|
|
153
|
+
registry: creds.registry,
|
|
154
|
+
tag,
|
|
155
|
+
digest: imageDigest,
|
|
156
|
+
log: (m) => console.log(chalk_1.default.gray(m)),
|
|
157
|
+
});
|
|
158
|
+
}
|
|
159
|
+
// Relative `frontend.dir`/`bundlePath` (and the frontend build hook) resolve
|
|
160
|
+
// against the smart-app root — `backend.context` when present, else
|
|
161
|
+
// `--project` — NOT the CLI's process.cwd(). (Same cwd class as the backend
|
|
162
|
+
// build: a bare `public` must mean `<smart-app>/public`.)
|
|
163
|
+
const baseDir = (0, path_1.resolve)(b.context ?? opts.projectDir);
|
|
164
|
+
let bundleSha256 = '';
|
|
165
|
+
if (manifest.frontend) {
|
|
166
|
+
const bundlePath = await resolveFrontendBundle(manifest, baseDir, opts.runFn);
|
|
167
|
+
const bundle = await fs_1.promises.readFile(bundlePath);
|
|
168
|
+
const upload = await client.deployment.uploadFrontend(appId, bundle);
|
|
169
|
+
bundleSha256 = upload.bundleSha256;
|
|
170
|
+
console.log(chalk_1.default.gray(` frontend: sha256=${bundleSha256.slice(0, 12)}…`));
|
|
171
|
+
}
|
|
172
|
+
// Forward the developer's `.env.local` runtime creds into the deployed
|
|
173
|
+
// customer-env (issue #1564) — same as `deploy`. `manifest.backend.env` wins
|
|
174
|
+
// for explicit non-secret overrides; secrets ride from `.env.local`. Resolved
|
|
175
|
+
// BEFORE the attestation-seed check so a credential-less redeploy fails with
|
|
176
|
+
// the specific #1564 remedy. FAILS LOUD unless `--allow-open-mode` (which then
|
|
177
|
+
// withholds the seed from the container while still signing locally).
|
|
178
|
+
const runtimeEnv = (0, runtime_env_1.resolveRuntimeEnv)({
|
|
179
|
+
env,
|
|
180
|
+
manifestEnv: b.env,
|
|
181
|
+
allowOpenMode: opts.allowOpenMode,
|
|
182
|
+
warn: (m) => console.warn(chalk_1.default.yellow(` ⚠ ${m}`)),
|
|
183
|
+
});
|
|
184
|
+
console.log(chalk_1.default.gray(` runtime env: ${Object.keys(runtimeEnv).length} vars forwarded from ${opts.envPath} + manifest` +
|
|
185
|
+
(runtimeEnv.XRPL_SEED ? ' (cluster mode)' : ' (open mode)')));
|
|
186
|
+
// The host's hardened deploy policy requires a signed attestation, so the seed
|
|
187
|
+
// is needed to SIGN regardless of open/cluster mode.
|
|
188
|
+
const seed = env.get('XRPL_SEED');
|
|
189
|
+
if (!seed)
|
|
190
|
+
throw new Error('XRPL_SEED required to sign the build attestation');
|
|
191
|
+
const signed = (0, attestation_1.assembleAndSign)({
|
|
192
|
+
appId,
|
|
193
|
+
developerWallet: env.get('XRPL_ADDRESS') ?? '',
|
|
194
|
+
developerChain: 'xrpl',
|
|
195
|
+
framework: detection.framework,
|
|
196
|
+
sdkVersion,
|
|
197
|
+
// The pushed image's `sha256:<64hex>` registry manifest digest (captured
|
|
198
|
+
// by buildAndPush) — bound with strict equality by the host, so it MUST
|
|
199
|
+
// be the digest, not the tag-form ref the gate would reject.
|
|
200
|
+
imageDigest,
|
|
201
|
+
bundleSha256,
|
|
202
|
+
cliVersion: (0, attestation_1.readCliVersion)(),
|
|
203
|
+
}, seed);
|
|
204
|
+
const url = await deployBackend(client, appId, manifest, tag, signed, runtimeEnv, opts.strategy);
|
|
205
|
+
// Block until the runtime settles (default on) — see deploy.ts for rationale.
|
|
206
|
+
if (opts.wait !== false) {
|
|
207
|
+
const status = await (0, status_1.waitForRunning)(client, appId, {
|
|
208
|
+
intervalMs: opts.waitIntervalMs,
|
|
209
|
+
maxPolls: opts.waitMaxPolls,
|
|
210
|
+
sleep: opts.sleep,
|
|
211
|
+
});
|
|
212
|
+
console.log(chalk_1.default.gray(` runtime: ${status.runtime?.runtimeState ?? status.state}`));
|
|
213
|
+
if (status.runtime?.runtimeState === 'FAILED') {
|
|
214
|
+
throw new Error(`redeploy reached FAILED runtime for ${appId}` +
|
|
215
|
+
(status.runtime?.lastError ? `: ${status.runtime.lastError}` : ''));
|
|
216
|
+
}
|
|
217
|
+
}
|
|
218
|
+
return { appId, url };
|
|
219
|
+
}
|
|
220
|
+
/**
|
|
221
|
+
* Resolve the frontend bundle to a tarball path: `bundlePath` wins; otherwise
|
|
222
|
+
* tar `dir` (running its optional `build` first) into a temp `.tar`.
|
|
223
|
+
*
|
|
224
|
+
* `baseDir` is the smart-app root (`backend.context` / `--project`); relative
|
|
225
|
+
* `dir`/`bundlePath` resolve against it, NOT the CLI's process.cwd(), and the
|
|
226
|
+
* optional pre-build hook runs with `cwd` set to the resolved `dir`.
|
|
227
|
+
*/
|
|
228
|
+
async function resolveFrontendBundle(manifest, baseDir, runFn) {
|
|
229
|
+
const f = manifest.frontend;
|
|
230
|
+
if (f.bundlePath) {
|
|
231
|
+
const p = (0, path_1.resolve)(baseDir, f.bundlePath);
|
|
232
|
+
if (!(0, fs_1.existsSync)(p))
|
|
233
|
+
throw new Error(`frontend bundle not found: ${p}`);
|
|
234
|
+
return p;
|
|
235
|
+
}
|
|
236
|
+
const dir = (0, path_1.resolve)(baseDir, f.dir);
|
|
237
|
+
if (!(0, fs_1.existsSync)(dir))
|
|
238
|
+
throw new Error(`frontend dir not found: ${dir}`);
|
|
239
|
+
// Optional pre-build (e.g. `ng build`) — run via the injected seam IN `dir`
|
|
240
|
+
// (a real chdir; `PWD` alone does not move the child's working directory).
|
|
241
|
+
if (f.build) {
|
|
242
|
+
const run = runFn ?? (await Promise.resolve().then(() => __importStar(require('child_process')))).execFileSync;
|
|
243
|
+
run('sh', ['-c', f.build], {
|
|
244
|
+
stdio: 'inherit',
|
|
245
|
+
cwd: dir,
|
|
246
|
+
env: { ...process.env, PWD: dir },
|
|
247
|
+
});
|
|
248
|
+
}
|
|
249
|
+
// Fail-closed: never re-ship a bundle that still carries unfilled
|
|
250
|
+
// REPLACE_BEFORE_DEPLOY placeholders (shared with `deploy`). See frontend-guard.
|
|
251
|
+
await (0, frontend_guard_1.assertNoDeploySentinels)(dir);
|
|
252
|
+
const out = (0, path_1.join)((0, os_1.tmpdir)(), `hsuite-frontend-${Date.now()}.tar`);
|
|
253
|
+
return (0, baas_1.tarFrontend)({ dir, out, runFn });
|
|
254
|
+
}
|
|
255
|
+
async function deployBackend(client, appId, manifest, tag, attestation, runtimeEnv, strategy) {
|
|
256
|
+
const b = manifest.backend;
|
|
257
|
+
const body = {
|
|
258
|
+
tag,
|
|
259
|
+
port: b.port,
|
|
260
|
+
replicas: b.replicas ?? 1,
|
|
261
|
+
degree: manifest.degree,
|
|
262
|
+
// Resolved runtime env — `.env.local` runtime creds merged with
|
|
263
|
+
// `manifest.backend.env` (manifest wins) — NOT `manifest.backend.env` alone
|
|
264
|
+
// (issue #1564). Mirrored into the PQC-encrypted customer-env Secret.
|
|
265
|
+
env: runtimeEnv,
|
|
266
|
+
resources: b.limits,
|
|
267
|
+
...(strategy ? { strategy } : {}),
|
|
268
|
+
attestation,
|
|
269
|
+
};
|
|
270
|
+
const res = await client.deployment.deploy(appId, body);
|
|
271
|
+
return res.url;
|
|
272
|
+
}
|
|
273
|
+
exports.redeployCommand = new commander_1.Command('redeploy')
|
|
274
|
+
.description('Redeploy an existing smart-app (same appId, new tag and/or frontend bundle)')
|
|
275
|
+
.requiredOption('--manifest <file>', 'JSON manifest path')
|
|
276
|
+
.option('--env <file>', 'Env file with auth creds', '.env.local')
|
|
277
|
+
.option('--project <dir>', 'Smart-app project root (for SDK/framework detection)', '.')
|
|
278
|
+
.option('--gateway <url>', 'Smart-engines gateway URL', cluster_1.DEFAULT_GATEWAY)
|
|
279
|
+
.option('--app-id <id>', 'Existing deployed appId to redeploy (else DEPLOYED_APP_ID)')
|
|
280
|
+
.option('--subscription-app-id <id>', 'Subscription appId to authenticate as (else SUBSCRIPTION_APP_ID)')
|
|
281
|
+
.option('--tag <tag>', 'Override the backend image tag (else manifest.backend.tag)')
|
|
282
|
+
.option('--strategy <strategy>', 'Update strategy: rolling | recreate')
|
|
283
|
+
.option('--docker-host <host>', 'DOCKER_HOST for the build/push (defaults to $DOCKER_HOST)')
|
|
284
|
+
.option('--skip-build', 'Skip `docker build`', false)
|
|
285
|
+
.option('--skip-push', 'Skip `docker push`', false)
|
|
286
|
+
.option('--skip-distribute', 'Skip the multi-cluster image fan-out (single-cluster / dev registry)', false)
|
|
287
|
+
.option('--allow-open-mode', 'Allow an intentional zero-cred / open-mode redeploy (no XRPL_SEED forwarded). Default: a credential-less redeploy FAILS LOUD (#1564).', false)
|
|
288
|
+
.option('--no-wait', 'Do not block until the runtime settles — exit as soon as deploy() is accepted (default: wait for RUNNING/FAILED)')
|
|
289
|
+
.action(async (opts) => {
|
|
290
|
+
console.log(chalk_1.default.bold.cyan('\n hsuite redeploy\n'));
|
|
291
|
+
let result;
|
|
292
|
+
try {
|
|
293
|
+
result = await runRedeploy({
|
|
294
|
+
manifestPath: opts.manifest,
|
|
295
|
+
envPath: opts.env,
|
|
296
|
+
gateway: opts.gateway,
|
|
297
|
+
projectDir: opts.project,
|
|
298
|
+
appId: opts.appId,
|
|
299
|
+
subscriptionAppId: opts.subscriptionAppId,
|
|
300
|
+
tag: opts.tag,
|
|
301
|
+
strategy: opts.strategy,
|
|
302
|
+
dockerHost: opts.dockerHost ?? process.env.DOCKER_HOST,
|
|
303
|
+
skipBuild: opts.skipBuild,
|
|
304
|
+
skipPush: opts.skipPush,
|
|
305
|
+
skipDistribute: opts.skipDistribute,
|
|
306
|
+
allowOpenMode: opts.allowOpenMode,
|
|
307
|
+
wait: opts.wait,
|
|
308
|
+
});
|
|
309
|
+
}
|
|
310
|
+
catch (err) {
|
|
311
|
+
if (err instanceof framework_1.NoSdkError) {
|
|
312
|
+
console.error(chalk_1.default.red(`\n ✗ ${err.message}\n`));
|
|
313
|
+
}
|
|
314
|
+
else {
|
|
315
|
+
console.error(chalk_1.default.red(`\n ✗ ${err.message}\n`));
|
|
316
|
+
}
|
|
317
|
+
process.exit(1);
|
|
318
|
+
}
|
|
319
|
+
(0, env_1.upsertEnv)(opts.env, { DEPLOYED_APP_ID: result.appId });
|
|
320
|
+
console.log(chalk_1.default.bold.green(`\n ✓ redeployed: ${result.url}\n`));
|
|
321
|
+
});
|
|
322
|
+
//# sourceMappingURL=redeploy.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"redeploy.js","sourceRoot":"","sources":["../../src/commands/redeploy.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAgFA,kCAqKC;AArPD;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,yCAAoC;AACpC,kDAA0B;AAC1B,2BAAgD;AAChD,+BAAqC;AACrC,2BAA4B;AAI5B,qCAAiD;AACjD,+DAAoE;AACpE,qDAAwD;AACxD,6CAAkD;AAClD,iDAAmF;AACnF,uCAAqF;AACrF,6DAAsF;AACtF,qDAA8F;AAC9F,6DAAuE;AACvE,2DAAiE;AACjE,qCAA0C;AAwC1C,yDAAyD;AAClD,KAAK,UAAU,WAAW,CAAC,IAAkB;IAClD,MAAM,QAAQ,GAAG,IAAA,+BAAa,EAAC,IAAI,CAAC,YAAY,CAAC,CAAC;IAClD,MAAM,GAAG,GAAG,IAAA,aAAO,EAAC,IAAI,CAAC,OAAO,CAAC,CAAC;IAElC,MAAM,CAAC,GAAG,QAAQ,CAAC,OAAO,CAAC;IAC3B,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,IAAI,CAAC,CAAC,GAAG,CAAC;IAE9B,MAAM,SAAS,GAAG,IAAA,2BAAe,EAAC,IAAI,CAAC,UAAU,CAAC,CAAC;IACnD,MAAM,UAAU,GAAG,IAAA,6BAAiB,EAAC,IAAI,CAAC,UAAU,EAAE,SAAS,CAAC,CAAC;IAEjE,uEAAuE;IACvE,yEAAyE;IACzE,2EAA2E;IAC3E,4EAA4E;IAC5E,wEAAwE;IACxE,6EAA6E;IAC7E,wEAAwE;IACxE,oDAAoD;IACpD,MAAM,iBAAiB,GAAG,IAAA,2CAAwB,EAAC,GAAG,EAAE;QACtD,iBAAiB,EAAE,IAAI,CAAC,iBAAiB;KAC1C,CAAC,CAAC;IAEH,yEAAyE;IACzE,8EAA8E;IAC9E,iFAAiF;IACjF,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,IAAI,GAAG,CAAC,GAAG,CAAC,iBAAiB,CAAC,CAAC;IACvD,IAAI,CAAC,KAAK,EAAE,CAAC;QACX,MAAM,IAAI,KAAK,CACb,6FAA6F,CAC9F,CAAC;IACJ,CAAC;IAED,MAAM,MAAM,GAAG,MAAM,IAAA,qBAAc,EAAC;QAClC,OAAO,EAAE,IAAI,CAAC,OAAO;QACrB,GAAG;QACH,KAAK,EAAE,iBAAiB;QACxB,aAAa,EAAE,IAAI,CAAC,aAAa;KAClC,CAAC,CAAC;IAEH,8EAA8E;IAC9E,yEAAyE;IACzE,4EAA4E;IAC5E,+EAA+E;IAC/E,wDAAwD;IACxD,MAAM,KAAK,GAAG,MAAM,MAAM,CAAC,UAAU,CAAC,sBAAsB,CAAC,KAAK,CAAC,CAAC;IACpE,OAAO,CAAC,GAAG,CACT,eAAK,CAAC,IAAI,CAAC,gCAAgC,KAAK,CAAC,KAAK,aAAa,KAAK,CAAC,QAAQ,CAAC,UAAU,EAAE,CAAC,CAChG,CAAC;IAEF,IAAI,CAAC,GAAG;QAAE,MAAM,IAAI,KAAK,CAAC,gEAAgE,CAAC,CAAC;IAC5F,+EAA+E;IAC/E,6EAA6E;IAC7E,yEAAyE;IACzE,MAAM,UAAU,GAAG,IAAA,mBAAY,EAAC;QAC9B,QAAQ,EAAE,KAAK,CAAC,QAAQ;QACxB,GAAG;QACH,OAAO,EAAE,IAAA,cAAO,EAAC,CAAC,CAAC,OAAO,IAAI,GAAG,CAAC;QAClC,UAAU,EAAE,CAAC,CAAC,UAAU,IAAI,YAAY;QACxC,QAAQ,EAAE,CAAC,CAAC,QAAQ;QACpB,KAAK,EAAE,CAAC,CAAC,KAAK;QACd,SAAS,EAAE,IAAI,CAAC,SAAS;QACzB,QAAQ,EAAE,IAAI,CAAC,QAAQ;QACvB,UAAU,EAAE,IAAI,CAAC,UAAU;QAC3B,IAAI,EAAE,QAAQ,CAAC,IAAI;QACnB,KAAK,EAAE,IAAI,CAAC,KAAK;KAClB,CAAC,CAAC;IAEH,qEAAqE;IACrE,uEAAuE;IACvE,4EAA4E;IAC5E,0EAA0E;IAC1E,2EAA2E;IAC3E,MAAM,WAAW,GAAG,MAAM,IAAA,0CAAwB,EAAC;QACjD,QAAQ,EAAE,KAAK,CAAC,QAAQ;QACxB,GAAG;QACH,UAAU;QACV,GAAG,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,OAAO,CAAC,GAAG,CAAC,eAAK,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;KACvC,CAAC,CAAC;IACH,OAAO,CAAC,GAAG,CAAC,eAAK,CAAC,IAAI,CAAC,aAAa,KAAK,CAAC,QAAQ,CAAC,UAAU,IAAI,GAAG,KAAK,WAAW,GAAG,CAAC,CAAC,CAAC;IAE1F,4EAA4E;IAC5E,yEAAyE;IACzE,4EAA4E;IAC5E,0EAA0E;IAC1E,IAAI,CAAC,IAAI,CAAC,cAAc,EAAE,CAAC;QACzB,MAAM,IAAA,mCAAiB,EAAC;YACtB,QAAQ,EAAE,KAAK,CAAC,QAAQ;YACxB,GAAG;YACH,MAAM,EAAE,WAAW;YACnB,GAAG,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,OAAO,CAAC,GAAG,CAAC,eAAK,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;SACvC,CAAC,CAAC;IACL,CAAC;IAED,6EAA6E;IAC7E,oEAAoE;IACpE,4EAA4E;IAC5E,0DAA0D;IAC1D,MAAM,OAAO,GAAG,IAAA,cAAO,EAAC,CAAC,CAAC,OAAO,IAAI,IAAI,CAAC,UAAU,CAAC,CAAC;IACtD,IAAI,YAAY,GAAG,EAAE,CAAC;IACtB,IAAI,QAAQ,CAAC,QAAQ,EAAE,CAAC;QACtB,MAAM,UAAU,GAAG,MAAM,qBAAqB,CAAC,QAAQ,EAAE,OAAO,EAAE,IAAI,CAAC,KAAK,CAAC,CAAC;QAC9E,MAAM,MAAM,GAAG,MAAM,aAAE,CAAC,QAAQ,CAAC,UAAU,CAAC,CAAC;QAC7C,MAAM,MAAM,GAAG,MAAM,MAAM,CAAC,UAAU,CAAC,cAAc,CAAC,KAAK,EAAE,MAAM,CAAC,CAAC;QACrE,YAAY,GAAG,MAAM,CAAC,YAAY,CAAC;QACnC,OAAO,CAAC,GAAG,CAAC,eAAK,CAAC,IAAI,CAAC,sBAAsB,YAAY,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC;IAC9E,CAAC;IAED,uEAAuE;IACvE,6EAA6E;IAC7E,8EAA8E;IAC9E,6EAA6E;IAC7E,+EAA+E;IAC/E,sEAAsE;IACtE,MAAM,UAAU,GAAG,IAAA,+BAAiB,EAAC;QACnC,GAAG;QACH,WAAW,EAAE,CAAC,CAAC,GAAG;QAClB,aAAa,EAAE,IAAI,CAAC,aAAa;QACjC,IAAI,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,OAAO,CAAC,IAAI,CAAC,eAAK,CAAC,MAAM,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC;KACpD,CAAC,CAAC;IACH,OAAO,CAAC,GAAG,CACT,eAAK,CAAC,IAAI,CACR,kBAAkB,MAAM,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC,MAAM,wBAAwB,IAAI,CAAC,OAAO,aAAa;QAC/F,CAAC,UAAU,CAAC,SAAS,CAAC,CAAC,CAAC,iBAAiB,CAAC,CAAC,CAAC,cAAc,CAAC,CAC9D,CACF,CAAC;IAEF,+EAA+E;IAC/E,qDAAqD;IACrD,MAAM,IAAI,GAAG,GAAG,CAAC,GAAG,CAAC,WAAW,CAAC,CAAC;IAClC,IAAI,CAAC,IAAI;QAAE,MAAM,IAAI,KAAK,CAAC,kDAAkD,CAAC,CAAC;IAC/E,MAAM,MAAM,GAAG,IAAA,6BAAe,EAC5B;QACE,KAAK;QACL,eAAe,EAAE,GAAG,CAAC,GAAG,CAAC,cAAc,CAAC,IAAI,EAAE;QAC9C,cAAc,EAAE,MAAM;QACtB,SAAS,EAAE,SAAS,CAAC,SAAS;QAC9B,UAAU;QACV,yEAAyE;QACzE,wEAAwE;QACxE,6DAA6D;QAC7D,WAAW;QACX,YAAY;QACZ,UAAU,EAAE,IAAA,4BAAc,GAAE;KAC7B,EACD,IAAI,CACL,CAAC;IAEF,MAAM,GAAG,GAAG,MAAM,aAAa,CAAC,MAAM,EAAE,KAAK,EAAE,QAAQ,EAAE,GAAG,EAAE,MAAM,EAAE,UAAU,EAAE,IAAI,CAAC,QAAQ,CAAC,CAAC;IAEjG,8EAA8E;IAC9E,IAAI,IAAI,CAAC,IAAI,KAAK,KAAK,EAAE,CAAC;QACxB,MAAM,MAAM,GAAG,MAAM,IAAA,uBAAc,EAAC,MAAM,EAAE,KAAK,EAAE;YACjD,UAAU,EAAE,IAAI,CAAC,cAAc;YAC/B,QAAQ,EAAE,IAAI,CAAC,YAAY;YAC3B,KAAK,EAAE,IAAI,CAAC,KAAK;SAClB,CAAC,CAAC;QACH,OAAO,CAAC,GAAG,CAAC,eAAK,CAAC,IAAI,CAAC,cAAc,MAAM,CAAC,OAAO,EAAE,YAAY,IAAI,MAAM,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC;QACtF,IAAI,MAAM,CAAC,OAAO,EAAE,YAAY,KAAK,QAAQ,EAAE,CAAC;YAC9C,MAAM,IAAI,KAAK,CACb,uCAAuC,KAAK,EAAE;gBAC5C,CAAC,MAAM,CAAC,OAAO,EAAE,SAAS,CAAC,CAAC,CAAC,KAAK,MAAM,CAAC,OAAO,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CACrE,CAAC;QACJ,CAAC;IACH,CAAC;IACD,OAAO,EAAE,KAAK,EAAE,GAAG,EAAE,CAAC;AACxB,CAAC;AAED;;;;;;;GAOG;AACH,KAAK,UAAU,qBAAqB,CAClC,QAAkB,EAClB,OAAe,EACf,KAAa;IAEb,MAAM,CAAC,GAAG,QAAQ,CAAC,QAAS,CAAC;IAC7B,IAAI,CAAC,CAAC,UAAU,EAAE,CAAC;QACjB,MAAM,CAAC,GAAG,IAAA,cAAO,EAAC,OAAO,EAAE,CAAC,CAAC,UAAU,CAAC,CAAC;QACzC,IAAI,CAAC,IAAA,eAAU,EAAC,CAAC,CAAC;YAAE,MAAM,IAAI,KAAK,CAAC,8BAA8B,CAAC,EAAE,CAAC,CAAC;QACvE,OAAO,CAAC,CAAC;IACX,CAAC;IACD,MAAM,GAAG,GAAG,IAAA,cAAO,EAAC,OAAO,EAAE,CAAC,CAAC,GAAI,CAAC,CAAC;IACrC,IAAI,CAAC,IAAA,eAAU,EAAC,GAAG,CAAC;QAAE,MAAM,IAAI,KAAK,CAAC,2BAA2B,GAAG,EAAE,CAAC,CAAC;IACxE,4EAA4E;IAC5E,2EAA2E;IAC3E,IAAI,CAAC,CAAC,KAAK,EAAE,CAAC;QACZ,MAAM,GAAG,GAAG,KAAK,IAAK,CAAC,wDAAa,eAAe,GAAC,CAAC,CAAC,YAAiC,CAAC;QACxF,GAAG,CAAC,IAAI,EAAE,CAAC,IAAI,EAAE,CAAC,CAAC,KAAK,CAAC,EAAE;YACzB,KAAK,EAAE,SAAS;YAChB,GAAG,EAAE,GAAG;YACR,GAAG,EAAE,EAAE,GAAG,OAAO,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,EAAuB;SACvD,CAAC,CAAC;IACL,CAAC;IACD,kEAAkE;IAClE,iFAAiF;IACjF,MAAM,IAAA,wCAAuB,EAAC,GAAG,CAAC,CAAC;IACnC,MAAM,GAAG,GAAG,IAAA,WAAI,EAAC,IAAA,WAAM,GAAE,EAAE,mBAAmB,IAAI,CAAC,GAAG,EAAE,MAAM,CAAC,CAAC;IAChE,OAAO,IAAA,kBAAW,EAAC,EAAE,GAAG,EAAE,GAAG,EAAE,KAAK,EAAE,CAAC,CAAC;AAC1C,CAAC;AAED,KAAK,UAAU,aAAa,CAC1B,MAAkB,EAClB,KAAa,EACb,QAAkB,EAClB,GAAW,EACX,WAA8B,EAC9B,UAAkC,EAClC,QAAiC;IAEjC,MAAM,CAAC,GAAG,QAAQ,CAAC,OAAO,CAAC;IAC3B,MAAM,IAAI,GAA2D;QACnE,GAAG;QACH,IAAI,EAAE,CAAC,CAAC,IAAI;QACZ,QAAQ,EAAE,CAAC,CAAC,QAAQ,IAAI,CAAC;QACzB,MAAM,EAAE,QAAQ,CAAC,MAAM;QACvB,gEAAgE;QAChE,4EAA4E;QAC5E,sEAAsE;QACtE,GAAG,EAAE,UAAU;QACf,SAAS,EAAE,CAAC,CAAC,MAAM;QACnB,GAAG,CAAC,QAAQ,CAAC,CAAC,CAAC,EAAE,QAAQ,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QACjC,WAAW;KACZ,CAAC;IACF,MAAM,GAAG,GAAG,MAAM,MAAM,CAAC,UAAU,CAAC,MAAM,CAAC,KAAK,EAAE,IAAI,CAAC,CAAC;IACxD,OAAO,GAAG,CAAC,GAAG,CAAC;AACjB,CAAC;AAEY,QAAA,eAAe,GAAG,IAAI,mBAAO,CAAC,UAAU,CAAC;KACnD,WAAW,CAAC,6EAA6E,CAAC;KAC1F,cAAc,CAAC,mBAAmB,EAAE,oBAAoB,CAAC;KACzD,MAAM,CAAC,cAAc,EAAE,0BAA0B,EAAE,YAAY,CAAC;KAChE,MAAM,CAAC,iBAAiB,EAAE,sDAAsD,EAAE,GAAG,CAAC;KACtF,MAAM,CAAC,iBAAiB,EAAE,2BAA2B,EAAE,yBAAe,CAAC;KACvE,MAAM,CAAC,eAAe,EAAE,4DAA4D,CAAC;KACrF,MAAM,CACL,4BAA4B,EAC5B,kEAAkE,CACnE;KACA,MAAM,CAAC,aAAa,EAAE,4DAA4D,CAAC;KACnF,MAAM,CAAC,uBAAuB,EAAE,qCAAqC,CAAC;KACtE,MAAM,CAAC,sBAAsB,EAAE,2DAA2D,CAAC;KAC3F,MAAM,CAAC,cAAc,EAAE,qBAAqB,EAAE,KAAK,CAAC;KACpD,MAAM,CAAC,aAAa,EAAE,oBAAoB,EAAE,KAAK,CAAC;KAClD,MAAM,CAAC,mBAAmB,EAAE,sEAAsE,EAAE,KAAK,CAAC;KAC1G,MAAM,CAAC,mBAAmB,EAAE,uIAAuI,EAAE,KAAK,CAAC;KAC3K,MAAM,CAAC,WAAW,EAAE,kHAAkH,CAAC;KACvI,MAAM,CAAC,KAAK,EAAE,IAAI,EAAE,EAAE;IACrB,OAAO,CAAC,GAAG,CAAC,eAAK,CAAC,IAAI,CAAC,IAAI,CAAC,uBAAuB,CAAC,CAAC,CAAC;IACtD,IAAI,MAAsB,CAAC;IAC3B,IAAI,CAAC;QACH,MAAM,GAAG,MAAM,WAAW,CAAC;YACzB,YAAY,EAAE,IAAI,CAAC,QAAQ;YAC3B,OAAO,EAAE,IAAI,CAAC,GAAG;YACjB,OAAO,EAAE,IAAI,CAAC,OAAO;YACrB,UAAU,EAAE,IAAI,CAAC,OAAO;YACxB,KAAK,EAAE,IAAI,CAAC,KAAK;YACjB,iBAAiB,EAAE,IAAI,CAAC,iBAAiB;YACzC,GAAG,EAAE,IAAI,CAAC,GAAG;YACb,QAAQ,EAAE,IAAI,CAAC,QAAQ;YACvB,UAAU,EAAE,IAAI,CAAC,UAAU,IAAI,OAAO,CAAC,GAAG,CAAC,WAAW;YACtD,SAAS,EAAE,IAAI,CAAC,SAAS;YACzB,QAAQ,EAAE,IAAI,CAAC,QAAQ;YACvB,cAAc,EAAE,IAAI,CAAC,cAAc;YACnC,aAAa,EAAE,IAAI,CAAC,aAAa;YACjC,IAAI,EAAE,IAAI,CAAC,IAAI;SAChB,CAAC,CAAC;IACL,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,IAAI,GAAG,YAAY,sBAAU,EAAE,CAAC;YAC9B,OAAO,CAAC,KAAK,CAAC,eAAK,CAAC,GAAG,CAAC,SAAS,GAAG,CAAC,OAAO,IAAI,CAAC,CAAC,CAAC;QACrD,CAAC;aAAM,CAAC;YACN,OAAO,CAAC,KAAK,CAAC,eAAK,CAAC,GAAG,CAAC,SAAU,GAAa,CAAC,OAAO,IAAI,CAAC,CAAC,CAAC;QAChE,CAAC;QACD,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;IAED,IAAA,eAAS,EAAC,IAAI,CAAC,GAAG,EAAE,EAAE,eAAe,EAAE,MAAM,CAAC,KAAK,EAAE,CAAC,CAAC;IACvD,OAAO,CAAC,GAAG,CAAC,eAAK,CAAC,IAAI,CAAC,KAAK,CAAC,qBAAqB,MAAM,CAAC,GAAG,IAAI,CAAC,CAAC,CAAC;AACrE,CAAC,CAAC,CAAC"}
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `hsuite status` — live lifecycle + runtime status of a deployed app.
|
|
3
|
+
*
|
|
4
|
+
* Renders `state` (PENDING_SUBSCRIPTION | ACTIVE | SUSPENDED | RETIRED) plus the
|
|
5
|
+
* runtime sub-view (runtimeState / replicas / lastError) when present. `--json`
|
|
6
|
+
* prints the raw `BaasRuntimeStatus`; `--watch` polls until the runtime reaches
|
|
7
|
+
* a terminal state (RUNNING / FAILED) or the app is no longer ACTIVE.
|
|
8
|
+
*/
|
|
9
|
+
import { Command } from 'commander';
|
|
10
|
+
import type { BaasClient, BaasRuntimeStatus } from '@hsuite/smart-engines-sdk';
|
|
11
|
+
import { connectAndAuth } from '../_lib/baas';
|
|
12
|
+
export type StatusOpts = {
|
|
13
|
+
envPath: string;
|
|
14
|
+
gateway: string;
|
|
15
|
+
/** Management TARGET — the deployed app to inspect. */
|
|
16
|
+
appId?: string;
|
|
17
|
+
/** Auth IDENTITY — the developer's subscription appId. */
|
|
18
|
+
subscriptionAppId?: string;
|
|
19
|
+
watch?: boolean;
|
|
20
|
+
/** Poll interval (ms) for --watch. Default 5000. */
|
|
21
|
+
watchIntervalMs?: number;
|
|
22
|
+
/** Max --watch polls before giving up. Default 60 (~5 min at 5s). */
|
|
23
|
+
watchMaxPolls?: number;
|
|
24
|
+
clientFactory?: Parameters<typeof connectAndAuth>[0]['clientFactory'];
|
|
25
|
+
/** Injectable sleep for tests. Defaults to setTimeout. */
|
|
26
|
+
sleep?: (ms: number) => Promise<void>;
|
|
27
|
+
};
|
|
28
|
+
/** A runtime is "settled" once it can no longer transition on its own. */
|
|
29
|
+
export declare function isTerminal(s: BaasRuntimeStatus): boolean;
|
|
30
|
+
/**
|
|
31
|
+
* Poll a deployed app's runtime until it settles (RUNNING / FAILED /
|
|
32
|
+
* NOT_DEPLOYED, or the app is no longer ACTIVE) or the poll budget is exhausted.
|
|
33
|
+
* Shared by `hsuite deploy --wait` / `redeploy --wait` so a deploy blocks until
|
|
34
|
+
* the runtime actually converges instead of printing a URL that isn't live yet.
|
|
35
|
+
* Never throws on a FAILED runtime — returns the final status so the caller
|
|
36
|
+
* decides the exit code.
|
|
37
|
+
*/
|
|
38
|
+
export declare function waitForRunning(client: BaasClient, appId: string, opts?: {
|
|
39
|
+
intervalMs?: number;
|
|
40
|
+
maxPolls?: number;
|
|
41
|
+
sleep?: (ms: number) => Promise<void>;
|
|
42
|
+
}): Promise<BaasRuntimeStatus>;
|
|
43
|
+
/**
|
|
44
|
+
* Pure orchestration body — exported for unit tests. Returns the final
|
|
45
|
+
* `BaasRuntimeStatus` (after watching, when `--watch`).
|
|
46
|
+
*/
|
|
47
|
+
export declare function runStatus(opts: StatusOpts): Promise<BaasRuntimeStatus>;
|
|
48
|
+
/** Human-readable one-block render of a status. */
|
|
49
|
+
export declare function renderStatus(status: BaasRuntimeStatus): string;
|
|
50
|
+
export declare const statusCommand: Command;
|
|
51
|
+
//# sourceMappingURL=status.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"status.d.ts","sourceRoot":"","sources":["../../src/commands/status.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AACH,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAEpC,OAAO,KAAK,EAAE,UAAU,EAAE,iBAAiB,EAAE,MAAM,2BAA2B,CAAC;AAK/E,OAAO,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;AAE9C,MAAM,MAAM,UAAU,GAAG;IACvB,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,MAAM,CAAC;IAChB,uDAAuD;IACvD,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,0DAA0D;IAC1D,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,oDAAoD;IACpD,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,qEAAqE;IACrE,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,aAAa,CAAC,EAAE,UAAU,CAAC,OAAO,cAAc,CAAC,CAAC,CAAC,CAAC,CAAC,eAAe,CAAC,CAAC;IACtE,0DAA0D;IAC1D,KAAK,CAAC,EAAE,CAAC,EAAE,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;CACvC,CAAC;AAEF,0EAA0E;AAC1E,wBAAgB,UAAU,CAAC,CAAC,EAAE,iBAAiB,GAAG,OAAO,CAGxD;AAED;;;;;;;GAOG;AACH,wBAAsB,cAAc,CAClC,MAAM,EAAE,UAAU,EAClB,KAAK,EAAE,MAAM,EACb,IAAI,GAAE;IAAE,UAAU,CAAC,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAAC,KAAK,CAAC,EAAE,CAAC,EAAE,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAA;CAAO,GAC3F,OAAO,CAAC,iBAAiB,CAAC,CAY5B;AAED;;;GAGG;AACH,wBAAsB,SAAS,CAAC,IAAI,EAAE,UAAU,GAAG,OAAO,CAAC,iBAAiB,CAAC,CA+B5E;AAED,mDAAmD;AACnD,wBAAgB,YAAY,CAAC,MAAM,EAAE,iBAAiB,GAAG,MAAM,CAgB9D;AAED,eAAO,MAAM,aAAa,SAgCtB,CAAC"}
|
|
@@ -0,0 +1,138 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.statusCommand = void 0;
|
|
7
|
+
exports.isTerminal = isTerminal;
|
|
8
|
+
exports.waitForRunning = waitForRunning;
|
|
9
|
+
exports.runStatus = runStatus;
|
|
10
|
+
exports.renderStatus = renderStatus;
|
|
11
|
+
/**
|
|
12
|
+
* `hsuite status` — live lifecycle + runtime status of a deployed app.
|
|
13
|
+
*
|
|
14
|
+
* Renders `state` (PENDING_SUBSCRIPTION | ACTIVE | SUSPENDED | RETIRED) plus the
|
|
15
|
+
* runtime sub-view (runtimeState / replicas / lastError) when present. `--json`
|
|
16
|
+
* prints the raw `BaasRuntimeStatus`; `--watch` polls until the runtime reaches
|
|
17
|
+
* a terminal state (RUNNING / FAILED) or the app is no longer ACTIVE.
|
|
18
|
+
*/
|
|
19
|
+
const commander_1 = require("commander");
|
|
20
|
+
const chalk_1 = __importDefault(require("chalk"));
|
|
21
|
+
const env_1 = require("../_lib/env");
|
|
22
|
+
const subscription_env_1 = require("../_lib/subscription-env");
|
|
23
|
+
const cluster_1 = require("../_lib/cluster");
|
|
24
|
+
const baas_1 = require("../_lib/baas");
|
|
25
|
+
/** A runtime is "settled" once it can no longer transition on its own. */
|
|
26
|
+
function isTerminal(s) {
|
|
27
|
+
const rs = s.runtime?.runtimeState;
|
|
28
|
+
return s.state !== 'ACTIVE' || rs === 'RUNNING' || rs === 'FAILED' || rs === 'NOT_DEPLOYED';
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* Poll a deployed app's runtime until it settles (RUNNING / FAILED /
|
|
32
|
+
* NOT_DEPLOYED, or the app is no longer ACTIVE) or the poll budget is exhausted.
|
|
33
|
+
* Shared by `hsuite deploy --wait` / `redeploy --wait` so a deploy blocks until
|
|
34
|
+
* the runtime actually converges instead of printing a URL that isn't live yet.
|
|
35
|
+
* Never throws on a FAILED runtime — returns the final status so the caller
|
|
36
|
+
* decides the exit code.
|
|
37
|
+
*/
|
|
38
|
+
async function waitForRunning(client, appId, opts = {}) {
|
|
39
|
+
const sleep = opts.sleep ?? ((ms) => new Promise((r) => setTimeout(r, ms)));
|
|
40
|
+
const interval = opts.intervalMs ?? 5000;
|
|
41
|
+
const maxPolls = opts.maxPolls ?? 60;
|
|
42
|
+
let status = await client.deployment.status(appId);
|
|
43
|
+
let polls = 0;
|
|
44
|
+
while (!isTerminal(status) && polls < maxPolls) {
|
|
45
|
+
await sleep(interval);
|
|
46
|
+
status = await client.deployment.status(appId);
|
|
47
|
+
polls++;
|
|
48
|
+
}
|
|
49
|
+
return status;
|
|
50
|
+
}
|
|
51
|
+
/**
|
|
52
|
+
* Pure orchestration body — exported for unit tests. Returns the final
|
|
53
|
+
* `BaasRuntimeStatus` (after watching, when `--watch`).
|
|
54
|
+
*/
|
|
55
|
+
async function runStatus(opts) {
|
|
56
|
+
const env = (0, env_1.readEnv)(opts.envPath);
|
|
57
|
+
// Auth IDENTITY (subscription) ≠ management TARGET (deployed app). The host
|
|
58
|
+
// gates /api/v3/baas/auth/* on the authenticated appId's subscription; the deployed
|
|
59
|
+
// app holds none, so we authenticate as the developer's subscription and
|
|
60
|
+
// pass the deployed app as the call target.
|
|
61
|
+
const appId = (0, subscription_env_1.requireAppId)(env, { appId: opts.appId });
|
|
62
|
+
const subscriptionAppId = (0, subscription_env_1.requireSubscriptionAppId)(env, {
|
|
63
|
+
subscriptionAppId: opts.subscriptionAppId,
|
|
64
|
+
});
|
|
65
|
+
const client = await (0, baas_1.connectAndAuth)({
|
|
66
|
+
gateway: opts.gateway,
|
|
67
|
+
env,
|
|
68
|
+
appId: subscriptionAppId,
|
|
69
|
+
clientFactory: opts.clientFactory,
|
|
70
|
+
});
|
|
71
|
+
let status = await client.deployment.status(appId);
|
|
72
|
+
if (opts.watch) {
|
|
73
|
+
const sleep = opts.sleep ?? ((ms) => new Promise((r) => setTimeout(r, ms)));
|
|
74
|
+
const interval = opts.watchIntervalMs ?? 5000;
|
|
75
|
+
const maxPolls = opts.watchMaxPolls ?? 60;
|
|
76
|
+
let polls = 0;
|
|
77
|
+
while (!isTerminal(status) && polls < maxPolls) {
|
|
78
|
+
await sleep(interval);
|
|
79
|
+
status = await client.deployment.status(appId);
|
|
80
|
+
polls++;
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
return status;
|
|
84
|
+
}
|
|
85
|
+
/** Human-readable one-block render of a status. */
|
|
86
|
+
function renderStatus(status) {
|
|
87
|
+
const lines = [
|
|
88
|
+
` appId: ${status.appId}`,
|
|
89
|
+
` state: ${status.state}`,
|
|
90
|
+
];
|
|
91
|
+
if (status.runtime) {
|
|
92
|
+
lines.push(` runtimeState: ${status.runtime.runtimeState}`);
|
|
93
|
+
lines.push(` replicas: ${status.runtime.replicas}`);
|
|
94
|
+
if (status.runtime.image)
|
|
95
|
+
lines.push(` image: ${status.runtime.image}`);
|
|
96
|
+
if (status.runtime.lastReconciledAt)
|
|
97
|
+
lines.push(` reconciled: ${status.runtime.lastReconciledAt}`);
|
|
98
|
+
if (status.runtime.lastError)
|
|
99
|
+
lines.push(` lastError: ${status.runtime.lastError}`);
|
|
100
|
+
}
|
|
101
|
+
else {
|
|
102
|
+
lines.push(' runtime: (not deployed)');
|
|
103
|
+
}
|
|
104
|
+
return lines.join('\n');
|
|
105
|
+
}
|
|
106
|
+
exports.statusCommand = new commander_1.Command('status')
|
|
107
|
+
.description('Show a deployed app’s lifecycle + runtime status')
|
|
108
|
+
.option('--env <file>', 'Env file with auth creds', '.env.local')
|
|
109
|
+
.option('--gateway <url>', 'Smart-engines gateway URL', cluster_1.DEFAULT_GATEWAY)
|
|
110
|
+
.option('--app-id <id>', 'App to inspect (else DEPLOYED_APP_ID / SUBSCRIPTION_APP_ID)')
|
|
111
|
+
.option('--subscription-app-id <id>', 'Subscription appId to authenticate as (else SUBSCRIPTION_APP_ID)')
|
|
112
|
+
.option('--watch', 'Poll until the runtime settles (RUNNING / FAILED)', false)
|
|
113
|
+
.option('--json', 'Print the raw status JSON', false)
|
|
114
|
+
.action(async (opts) => {
|
|
115
|
+
if (!opts.json)
|
|
116
|
+
console.log(chalk_1.default.bold.cyan('\n hsuite status\n'));
|
|
117
|
+
let status;
|
|
118
|
+
try {
|
|
119
|
+
status = await runStatus({
|
|
120
|
+
envPath: opts.env,
|
|
121
|
+
gateway: opts.gateway,
|
|
122
|
+
appId: opts.appId,
|
|
123
|
+
subscriptionAppId: opts.subscriptionAppId,
|
|
124
|
+
watch: opts.watch,
|
|
125
|
+
});
|
|
126
|
+
}
|
|
127
|
+
catch (err) {
|
|
128
|
+
console.error(chalk_1.default.red(`\n ✗ ${err.message}\n`));
|
|
129
|
+
process.exit(1);
|
|
130
|
+
}
|
|
131
|
+
if (opts.json) {
|
|
132
|
+
process.stdout.write(JSON.stringify(status, null, 2) + '\n');
|
|
133
|
+
return;
|
|
134
|
+
}
|
|
135
|
+
console.log(renderStatus(status));
|
|
136
|
+
console.log('');
|
|
137
|
+
});
|
|
138
|
+
//# sourceMappingURL=status.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"status.js","sourceRoot":"","sources":["../../src/commands/status.ts"],"names":[],"mappings":"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"}
|