@fnndsc/stratus 0.1.0 → 0.2.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/README.md +6 -1
- package/dist/args.d.ts +20 -6
- package/dist/args.js +45 -2
- package/dist/args.js.map +1 -1
- package/dist/backend.d.ts +35 -4
- package/dist/backend.js +77 -12
- package/dist/backend.js.map +1 -1
- package/dist/cloud/builder.d.ts +172 -0
- package/dist/cloud/builder.js +41 -0
- package/dist/cloud/builder.js.map +1 -0
- package/dist/cloud/driver.d.ts +149 -0
- package/dist/cloud/fake/builder.d.ts +147 -0
- package/dist/cloud/fake/builder.js +213 -0
- package/dist/cloud/fake/builder.js.map +1 -0
- package/dist/cloud/fake/driver.d.ts +73 -1
- package/dist/cloud/fake/driver.js +122 -0
- package/dist/cloud/fake/driver.js.map +1 -1
- package/dist/cloud/oci/api.d.ts +3 -2
- package/dist/cloud/oci/api.js +2 -0
- package/dist/cloud/oci/api.js.map +1 -1
- package/dist/cloud/oci/buildApi.d.ts +61 -0
- package/dist/cloud/oci/buildApi.js +132 -0
- package/dist/cloud/oci/buildApi.js.map +1 -0
- package/dist/cloud/oci/builder.d.ts +172 -0
- package/dist/cloud/oci/builder.js +370 -0
- package/dist/cloud/oci/builder.js.map +1 -0
- package/dist/cloud/oci/driver.d.ts +23 -2
- package/dist/cloud/oci/driver.js +107 -1
- package/dist/cloud/oci/driver.js.map +1 -1
- package/dist/cloud/oci/planRead.d.ts +38 -0
- package/dist/cloud/oci/planRead.js +67 -0
- package/dist/cloud/oci/planRead.js.map +1 -0
- package/dist/cloud/oci/prices.d.ts +22 -1
- package/dist/cloud/oci/prices.js +35 -0
- package/dist/cloud/oci/prices.js.map +1 -1
- package/dist/cloud/oci/resourceApi.d.ts +114 -0
- package/dist/cloud/oci/resourceApi.js +261 -0
- package/dist/cloud/oci/resourceApi.js.map +1 -0
- package/dist/cloud/oci/resourceMap.d.ts +44 -0
- package/dist/cloud/oci/resourceMap.js +70 -0
- package/dist/cloud/oci/resourceMap.js.map +1 -0
- package/dist/cloud/oci/rmApi.d.ts +74 -0
- package/dist/cloud/oci/rmApi.js +141 -0
- package/dist/cloud/oci/rmApi.js.map +1 -0
- package/dist/cloud/oci/stackVars.d.ts +49 -0
- package/dist/cloud/oci/stackVars.js +70 -0
- package/dist/cloud/oci/stackVars.js.map +1 -0
- package/dist/cluster/fakeKube.d.ts +43 -0
- package/dist/cluster/fakeKube.js +86 -0
- package/dist/cluster/fakeKube.js.map +1 -0
- package/dist/cluster/kube.d.ts +40 -0
- package/dist/cluster/kube.js +46 -0
- package/dist/cluster/kube.js.map +1 -0
- package/dist/cluster/kubeHttp.d.ts +16 -0
- package/dist/cluster/kubeHttp.js +86 -0
- package/dist/cluster/kubeHttp.js.map +1 -0
- package/dist/commands/build.d.ts +90 -0
- package/dist/commands/build.js +358 -0
- package/dist/commands/build.js.map +1 -0
- package/dist/commands/capacity.d.ts +37 -0
- package/dist/commands/capacity.js +93 -0
- package/dist/commands/capacity.js.map +1 -0
- package/dist/commands/domain.d.ts +45 -0
- package/dist/commands/domain.js +150 -0
- package/dist/commands/domain.js.map +1 -0
- package/dist/commands/spend.d.ts +22 -0
- package/dist/commands/spend.js +65 -0
- package/dist/commands/spend.js.map +1 -0
- package/dist/commands/teardown.d.ts +10 -0
- package/dist/commands/teardown.js +72 -0
- package/dist/commands/teardown.js.map +1 -0
- package/dist/commands/verify.d.ts +28 -0
- package/dist/commands/verify.js +98 -0
- package/dist/commands/verify.js.map +1 -0
- package/dist/domain/adopt.d.ts +60 -0
- package/dist/domain/adopt.js +143 -0
- package/dist/domain/adopt.js.map +1 -0
- package/dist/domain/sizing.d.ts +55 -0
- package/dist/domain/sizing.js +66 -0
- package/dist/domain/sizing.js.map +1 -0
- package/dist/domain/spec.d.ts +101 -0
- package/dist/domain/spec.js +191 -0
- package/dist/domain/spec.js.map +1 -0
- package/dist/domain/spend.d.ts +84 -0
- package/dist/domain/spend.js +109 -0
- package/dist/domain/spend.js.map +1 -0
- package/dist/domain/state.d.ts +149 -0
- package/dist/domain/state.js +182 -0
- package/dist/domain/state.js.map +1 -0
- package/dist/domain/steps.d.ts +82 -0
- package/dist/domain/steps.js +311 -0
- package/dist/domain/steps.js.map +1 -0
- package/dist/domain/teardown.d.ts +38 -0
- package/dist/domain/teardown.js +48 -0
- package/dist/domain/teardown.js.map +1 -0
- package/dist/domain/verify.d.ts +68 -0
- package/dist/domain/verify.js +216 -0
- package/dist/domain/verify.js.map +1 -0
- package/dist/domain/view.d.ts +24 -0
- package/dist/domain/view.js +38 -0
- package/dist/domain/view.js.map +1 -0
- package/dist/domains/harborOci.d.ts +75 -0
- package/dist/domains/harborOci.js +165 -0
- package/dist/domains/harborOci.js.map +1 -0
- package/dist/index.d.ts +7 -0
- package/dist/index.js +6 -0
- package/dist/index.js.map +1 -1
- package/dist/installer/assisted.d.ts +97 -0
- package/dist/installer/assisted.js +171 -0
- package/dist/installer/assisted.js.map +1 -0
- package/dist/installer/installer.d.ts +86 -0
- package/dist/installer/installer.js +15 -0
- package/dist/installer/installer.js.map +1 -0
- package/dist/prompt.d.ts +33 -0
- package/dist/prompt.js +46 -0
- package/dist/prompt.js.map +1 -0
- package/dist/session.d.ts +2 -0
- package/dist/session.js +4 -0
- package/dist/session.js.map +1 -1
- package/dist/stratus.js +75 -3
- package/dist/stratus.js.map +1 -1
- package/dist/vfs/domains.d.ts +39 -0
- package/dist/vfs/domains.js +128 -0
- package/dist/vfs/domains.js.map +1 -0
- package/dist/vfs/look.d.ts +10 -0
- package/dist/vfs/look.js +43 -8
- package/dist/vfs/look.js.map +1 -1
- package/dist/vfs/resources.d.ts +136 -0
- package/dist/vfs/resources.js +325 -0
- package/dist/vfs/resources.js.map +1 -0
- package/dist/vfs/tenancy.d.ts +15 -2
- package/dist/vfs/tenancy.js +53 -17
- package/dist/vfs/tenancy.js.map +1 -1
- package/package.json +13 -6
package/dist/prompt.js
ADDED
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
/** The segment keys a stratus prompt uses, in the order they are drawn. */
|
|
2
|
+
export const STRATUS_SEGMENT_KEYS = ['cloud', 'tenancy', 'region', 'user', 'domain', 'cwd'];
|
|
3
|
+
/**
|
|
4
|
+
* Names the domain a path is inside, when it is one.
|
|
5
|
+
*
|
|
6
|
+
* @param cwd - The working directory.
|
|
7
|
+
* @param tenancyPath - The tenancy's folder, `/net/oci/<tenancy>`.
|
|
8
|
+
* @returns The domain's name, or null when the path is not under `domains/<name>`.
|
|
9
|
+
*/
|
|
10
|
+
export function domain_ofPath(cwd, tenancyPath) {
|
|
11
|
+
const prefix = `${tenancyPath}/domains/`;
|
|
12
|
+
if (!cwd.startsWith(prefix))
|
|
13
|
+
return null;
|
|
14
|
+
const name = cwd.slice(prefix.length).split('/')[0] ?? '';
|
|
15
|
+
return name.length > 0 ? name : null;
|
|
16
|
+
}
|
|
17
|
+
/**
|
|
18
|
+
* Builds the prompt's segments from the session as it stands.
|
|
19
|
+
*
|
|
20
|
+
* @param session - The stratus session.
|
|
21
|
+
* @param cwd - The working directory the prompt shows.
|
|
22
|
+
* @returns The segments, leader first.
|
|
23
|
+
*/
|
|
24
|
+
export function stratusSegments_build(session, cwd) {
|
|
25
|
+
const cloud = session.cloudLabel;
|
|
26
|
+
if (session.identity === null) {
|
|
27
|
+
return [
|
|
28
|
+
{ key: 'cloud', label: 'cloud', value: `${cloud} ✗`, tone: 'alert' },
|
|
29
|
+
{ key: 'cwd', label: 'working directory', value: cwd, tone: 'path' },
|
|
30
|
+
];
|
|
31
|
+
}
|
|
32
|
+
const segments = [
|
|
33
|
+
{ key: 'cloud', label: 'cloud', value: cloud, tone: 'leader' },
|
|
34
|
+
{ key: 'tenancy', label: 'tenancy', value: session.identity.tenancy, tone: 'place' },
|
|
35
|
+
];
|
|
36
|
+
const region = session.region;
|
|
37
|
+
if (region !== null)
|
|
38
|
+
segments.push({ key: 'region', label: 'region', value: region, tone: 'place' });
|
|
39
|
+
segments.push({ key: 'user', label: 'user', value: session.identity.user, tone: 'identity' });
|
|
40
|
+
const domain = domain_ofPath(cwd, session.tenancyPath);
|
|
41
|
+
if (domain !== null)
|
|
42
|
+
segments.push({ key: 'domain', label: 'domain', value: domain, tone: 'work' });
|
|
43
|
+
segments.push({ key: 'cwd', label: 'working directory', value: cwd, tone: 'path' });
|
|
44
|
+
return segments;
|
|
45
|
+
}
|
|
46
|
+
//# sourceMappingURL=prompt.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"prompt.js","sourceRoot":"","sources":["../src/prompt.ts"],"names":[],"mappings":"AAgBA,2EAA2E;AAC3E,MAAM,CAAC,MAAM,oBAAoB,GAAG,CAAC,OAAO,EAAE,SAAS,EAAE,QAAQ,EAAE,MAAM,EAAE,QAAQ,EAAE,KAAK,CAAU,CAAC;AAErG;;;;;;GAMG;AACH,MAAM,UAAU,aAAa,CAAC,GAAW,EAAE,WAAmB;IAC5D,MAAM,MAAM,GAAW,GAAG,WAAW,WAAW,CAAC;IACjD,IAAI,CAAC,GAAG,CAAC,UAAU,CAAC,MAAM,CAAC;QAAE,OAAO,IAAI,CAAC;IACzC,MAAM,IAAI,GAAW,GAAG,CAAC,KAAK,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;IAClE,OAAO,IAAI,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC;AACvC,CAAC;AAED;;;;;;GAMG;AACH,MAAM,UAAU,qBAAqB,CAAC,OAAuB,EAAE,GAAW;IACxE,MAAM,KAAK,GAAW,OAAO,CAAC,UAAU,CAAC;IACzC,IAAI,OAAO,CAAC,QAAQ,KAAK,IAAI,EAAE,CAAC;QAC9B,OAAO;YACL,EAAE,GAAG,EAAE,OAAO,EAAE,KAAK,EAAE,OAAO,EAAE,KAAK,EAAE,GAAG,KAAK,IAAI,EAAE,IAAI,EAAE,OAAO,EAAE;YACpE,EAAE,GAAG,EAAE,KAAK,EAAE,KAAK,EAAE,mBAAmB,EAAE,KAAK,EAAE,GAAG,EAAE,IAAI,EAAE,MAAM,EAAE;SACrE,CAAC;IACJ,CAAC;IACD,MAAM,QAAQ,GAAoB;QAChC,EAAE,GAAG,EAAE,OAAO,EAAE,KAAK,EAAE,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,IAAI,EAAE,QAAQ,EAAE;QAC9D,EAAE,GAAG,EAAE,SAAS,EAAE,KAAK,EAAE,SAAS,EAAE,KAAK,EAAE,OAAO,CAAC,QAAQ,CAAC,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE;KACrF,CAAC;IACF,MAAM,MAAM,GAAkB,OAAO,CAAC,MAAM,CAAC;IAC7C,IAAI,MAAM,KAAK,IAAI;QAAE,QAAQ,CAAC,IAAI,CAAC,EAAE,GAAG,EAAE,QAAQ,EAAE,KAAK,EAAE,QAAQ,EAAE,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,OAAO,EAAE,CAAC,CAAC;IACrG,QAAQ,CAAC,IAAI,CAAC,EAAE,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,OAAO,CAAC,QAAQ,CAAC,IAAI,EAAE,IAAI,EAAE,UAAU,EAAE,CAAC,CAAC;IAC9F,MAAM,MAAM,GAAkB,aAAa,CAAC,GAAG,EAAE,OAAO,CAAC,WAAW,CAAC,CAAC;IACtE,IAAI,MAAM,KAAK,IAAI;QAAE,QAAQ,CAAC,IAAI,CAAC,EAAE,GAAG,EAAE,QAAQ,EAAE,KAAK,EAAE,QAAQ,EAAE,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC,CAAC;IACpG,QAAQ,CAAC,IAAI,CAAC,EAAE,GAAG,EAAE,KAAK,EAAE,KAAK,EAAE,mBAAmB,EAAE,KAAK,EAAE,GAAG,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC,CAAC;IACpF,OAAO,QAAQ,CAAC;AAClB,CAAC"}
|
package/dist/session.d.ts
CHANGED
|
@@ -30,6 +30,8 @@ export declare class StratusSession implements BackendSession {
|
|
|
30
30
|
get region(): string | null;
|
|
31
31
|
/** Changes the session's region. */
|
|
32
32
|
region_set(region: string): void;
|
|
33
|
+
/** The cloud's name as the prompt leads with it: the driver's id in capitals (`OCI`). */
|
|
34
|
+
get cloudLabel(): string;
|
|
33
35
|
/** The mount the tenancy lives under. */
|
|
34
36
|
get mount(): string;
|
|
35
37
|
/** The tenancy's folder, or the mount when not connected. */
|
package/dist/session.js
CHANGED
|
@@ -52,6 +52,10 @@ export class StratusSession {
|
|
|
52
52
|
region_set(region) {
|
|
53
53
|
this.regionCurrent = region;
|
|
54
54
|
}
|
|
55
|
+
/** The cloud's name as the prompt leads with it: the driver's id in capitals (`OCI`). */
|
|
56
|
+
get cloudLabel() {
|
|
57
|
+
return this.driver.cloud.toUpperCase();
|
|
58
|
+
}
|
|
55
59
|
/** The mount the tenancy lives under. */
|
|
56
60
|
get mount() {
|
|
57
61
|
return `/net/${this.driver.cloud}`;
|
package/dist/session.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"session.js","sourceRoot":"","sources":["../src/session.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"session.js","sourceRoot":"","sources":["../src/session.ts"],"names":[],"mappings":"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"}
|
package/dist/stratus.js
CHANGED
|
@@ -14,7 +14,7 @@
|
|
|
14
14
|
*
|
|
15
15
|
* @module
|
|
16
16
|
*/
|
|
17
|
-
import { realpathSync } from 'node:fs';
|
|
17
|
+
import { existsSync, readFileSync, realpathSync } from 'node:fs';
|
|
18
18
|
import { fileURLToPath } from 'node:url';
|
|
19
19
|
import { engine_create } from '@fnndsc/brasa/core';
|
|
20
20
|
import { daemon_launch, daemonConsole_run, hostControl_parseArgv, packageWebRoot_find } from '@fnndsc/calypso';
|
|
@@ -23,18 +23,75 @@ import { FakeDriver, fakeCloud_sample } from './cloud/fake/driver.js';
|
|
|
23
23
|
import { OciDriver } from './cloud/oci/driver.js';
|
|
24
24
|
import { ociApi_make } from './cloud/oci/api.js';
|
|
25
25
|
import { stratusArgs_parse } from './args.js';
|
|
26
|
+
import { FakeBuildWorld, FakeCloudBuilder, FakeInstaller } from './cloud/fake/builder.js';
|
|
27
|
+
import { OciBuilder } from './cloud/oci/builder.js';
|
|
28
|
+
import { ociBuildApi_make } from './cloud/oci/buildApi.js';
|
|
29
|
+
import { AssistedInstaller, serviceAccount_read } from './installer/assisted.js';
|
|
30
|
+
import { promises as dnsPromises } from 'node:dns';
|
|
31
|
+
import { homedir } from 'node:os';
|
|
32
|
+
import { join } from 'node:path';
|
|
33
|
+
import { fakeVerifyReach } from './cluster/fakeKube.js';
|
|
34
|
+
import { rmApi_make } from './cloud/oci/rmApi.js';
|
|
26
35
|
const USAGE = [
|
|
27
36
|
'stratus: a mise session over the cloud substrate a Trusted Domain runs on.',
|
|
28
37
|
'',
|
|
29
38
|
'Usage: stratus [--profile NAME] [--config FILE] [--region REGION]',
|
|
30
|
-
' [--
|
|
39
|
+
' [--domain NAME=CHECKOUT]… [--redhat-account FILE] [--ssh-key FILE]',
|
|
40
|
+
' [--host-control[=shell,files,pipes,tasks]] [--expose-host-control]',
|
|
31
41
|
' stratus --fake',
|
|
32
42
|
'',
|
|
33
43
|
' --profile NAME the ~/.oci/config profile (DEFAULT)',
|
|
34
44
|
' --config FILE the OCI configuration file (~/.oci/config)',
|
|
35
45
|
' --region REGION the region the session works in (the profile\'s)',
|
|
46
|
+
' --domain NAME=CHECKOUT',
|
|
47
|
+
' a Trusted Domain built by the harbor-oci checkout at CHECKOUT,',
|
|
48
|
+
' shown under ~ (domains/NAME); repeat for each',
|
|
49
|
+
' --host-control=tasks',
|
|
50
|
+
' let the session start jobs that change the cloud and bill;',
|
|
51
|
+
' never granted by a bare --host-control',
|
|
52
|
+
' --redhat-account FILE',
|
|
53
|
+
' the Red Hat service account the builds use (~/.config/ocm/service-account.env)',
|
|
54
|
+
' --ssh-key FILE the public key the nodes take (~/.ssh/id_ed25519.pub)',
|
|
36
55
|
' --fake host a session over the fake cloud, for tests',
|
|
37
56
|
].join('\n');
|
|
57
|
+
/**
|
|
58
|
+
* A path with a leading `~` made absolute.
|
|
59
|
+
*
|
|
60
|
+
* @param file - The path.
|
|
61
|
+
* @returns It, from the home folder.
|
|
62
|
+
*/
|
|
63
|
+
function home_expand(file) {
|
|
64
|
+
return file.startsWith('~/') ? join(homedir(), file.slice(2)) : file;
|
|
65
|
+
}
|
|
66
|
+
/**
|
|
67
|
+
* OCI's build parts: Resource Manager, the build's other calls, the
|
|
68
|
+
* installer, and the files they read on this host, as `harbor-oci` kept them.
|
|
69
|
+
*
|
|
70
|
+
* @param driver - The read driver.
|
|
71
|
+
* @param args - The launch's arguments.
|
|
72
|
+
* @returns The builder and installer.
|
|
73
|
+
*/
|
|
74
|
+
function oci_buildParts(driver, args) {
|
|
75
|
+
const sshKeyFile = home_expand(args.sshKey ?? '~/.ssh/id_ed25519.pub');
|
|
76
|
+
const accountFile = home_expand(args.redhatAccount ?? '~/.config/ocm/service-account.env');
|
|
77
|
+
const sshPublicKey = () => (existsSync(sshKeyFile) ? readFileSync(sshKeyFile, 'utf-8') : null);
|
|
78
|
+
const resolver = new dnsPromises.Resolver();
|
|
79
|
+
resolver.setServers(['8.8.8.8']);
|
|
80
|
+
return {
|
|
81
|
+
builder: new OciBuilder({
|
|
82
|
+
rm: (region) => rmApi_make({ configFile: args.configFile, profile: args.profile, region }),
|
|
83
|
+
api: (region) => ociBuildApi_make({ configFile: args.configFile, profile: args.profile, region }),
|
|
84
|
+
driver,
|
|
85
|
+
sshPublicKey,
|
|
86
|
+
nameservers_resolve: (zone) => resolver.resolveNs(zone),
|
|
87
|
+
}),
|
|
88
|
+
installer: new AssistedInstaller({
|
|
89
|
+
account: () => serviceAccount_read(readFileSync(accountFile, 'utf-8')),
|
|
90
|
+
sshPublicKey: () => { const key = sshPublicKey(); if (key === null)
|
|
91
|
+
throw new Error(`${sshKeyFile}: no SSH public key`); return key; },
|
|
92
|
+
}),
|
|
93
|
+
};
|
|
94
|
+
}
|
|
38
95
|
/**
|
|
39
96
|
* Hosts the daemon.
|
|
40
97
|
*/
|
|
@@ -51,7 +108,22 @@ async function stratus_start() {
|
|
|
51
108
|
const driver = parsed.args.fake
|
|
52
109
|
? new FakeDriver(fakeCloud_sample())
|
|
53
110
|
: new OciDriver({ api: ociApi_make({ configFile: parsed.args.configFile, profile: parsed.args.profile }) });
|
|
54
|
-
|
|
111
|
+
// The fake cloud builds over a fake installer on a clock, so a build is seen moving; a real cloud's build half is not written yet.
|
|
112
|
+
const tickMs = Number(process.env['STRATUS_FAKE_TICK_MS'] ?? 700);
|
|
113
|
+
const world = new FakeBuildWorld(tickMs);
|
|
114
|
+
const made = stratusBackend_make({
|
|
115
|
+
driver,
|
|
116
|
+
region: parsed.args.region,
|
|
117
|
+
domains: parsed.args.domains,
|
|
118
|
+
...(parsed.args.fake
|
|
119
|
+
? {
|
|
120
|
+
builder: new FakeCloudBuilder(world), installer: new FakeInstaller(world), baseDomain: 'fake.example', waits: { pollMs: tickMs, hostsWaitMs: tickMs * 60, installWaitMs: tickMs * 120 },
|
|
121
|
+
// The fake cluster a fake build made answers verify: its hosts, healthy.
|
|
122
|
+
verifyReach: fakeVerifyReach((kubeconfig) => world.hosts_now(/cluster-([a-z0-9-]+)/.exec(kubeconfig)?.[1] ?? '').map((host) => ({ name: host.name, zone: host.zone, shape: 'VM.Standard.E5.Flex' }))),
|
|
123
|
+
}
|
|
124
|
+
// OCI builds through Resource Manager and Red Hat's Assisted Installer; the credentials stay files on this host.
|
|
125
|
+
: oci_buildParts(driver, parsed.args)),
|
|
126
|
+
});
|
|
55
127
|
const engine = await engine_create(made.backend);
|
|
56
128
|
if (made.session.identity === null) {
|
|
57
129
|
console.error(`[!] Not connected to ${driver.cloud}: ${made.session.disconnectedReason ?? 'no credential'}; hosting offline.`);
|
package/dist/stratus.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"stratus.js","sourceRoot":"","sources":["../src/stratus.ts"],"names":[],"mappings":";AACA;;;;;;;;;;;;;;GAcG;AACH,OAAO,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;
|
|
1
|
+
{"version":3,"file":"stratus.js","sourceRoot":"","sources":["../src/stratus.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import { type DomainSource, type HarborDomain } from '../domains/harborOci.js';
|
|
2
|
+
import type { ResourceNode } from './resources.js';
|
|
3
|
+
import type { DomainStore } from '../domain/state.js';
|
|
4
|
+
/** What a domain folder holds, in listing order. */
|
|
5
|
+
export declare const DOMAIN_ENTRIES: ReadonlyArray<string>;
|
|
6
|
+
/** How the domains tree is made. */
|
|
7
|
+
export interface DomainTreeOptions {
|
|
8
|
+
/** The domains the daemon was given. */
|
|
9
|
+
readonly sources: ReadonlyArray<DomainSource>;
|
|
10
|
+
/** Who rows are shown as owned by. */
|
|
11
|
+
readonly owner: () => string;
|
|
12
|
+
/** The clock. */
|
|
13
|
+
readonly now: () => Date;
|
|
14
|
+
/** The domains this daemon builds, kept on its host. */
|
|
15
|
+
readonly store?: DomainStore;
|
|
16
|
+
}
|
|
17
|
+
/** The domains a tenancy holds, as folders. */
|
|
18
|
+
export declare class DomainTree {
|
|
19
|
+
private readonly options;
|
|
20
|
+
constructor(options: DomainTreeOptions);
|
|
21
|
+
/** Every domain, read now: those read from checkouts, then those kept here; one kept here (adopted) stands in for its checkout. */
|
|
22
|
+
domains_read(): HarborDomain[];
|
|
23
|
+
/** One domain by name, read now: the one kept here, else the checkout's; null when there is none. */
|
|
24
|
+
domain_read(name: string): HarborDomain | null;
|
|
25
|
+
/**
|
|
26
|
+
* The node a path below `domains/` names.
|
|
27
|
+
*
|
|
28
|
+
* @param segments - The segments after `domains`.
|
|
29
|
+
* @returns The node.
|
|
30
|
+
*/
|
|
31
|
+
node_resolve(segments: ReadonlyArray<string>): ResourceNode;
|
|
32
|
+
private stepNode_resolve;
|
|
33
|
+
private authNode_resolve;
|
|
34
|
+
private domain_item;
|
|
35
|
+
private domainEntries_items;
|
|
36
|
+
private step_item;
|
|
37
|
+
private folder_item;
|
|
38
|
+
private file_item;
|
|
39
|
+
}
|
|
@@ -0,0 +1,128 @@
|
|
|
1
|
+
import { harborDomain_read, lastDone_of } from '../domains/harborOci.js';
|
|
2
|
+
import { builtDomain_read } from '../domain/view.js';
|
|
3
|
+
/** What a domain folder holds, in listing order. */
|
|
4
|
+
export const DOMAIN_ENTRIES = ['spec.yaml', 'settings', 'state.json', 'steps', 'auth'];
|
|
5
|
+
/** The domains a tenancy holds, as folders. */
|
|
6
|
+
export class DomainTree {
|
|
7
|
+
options;
|
|
8
|
+
constructor(options) {
|
|
9
|
+
this.options = options;
|
|
10
|
+
}
|
|
11
|
+
/** Every domain, read now: those read from checkouts, then those kept here; one kept here (adopted) stands in for its checkout. */
|
|
12
|
+
domains_read() {
|
|
13
|
+
const store = this.options.store;
|
|
14
|
+
const kept = store?.names_list() ?? [];
|
|
15
|
+
const read = this.options.sources
|
|
16
|
+
.filter((source) => !kept.includes(source.name))
|
|
17
|
+
.map((source) => harborDomain_read(source, this.options.now()));
|
|
18
|
+
if (store === undefined)
|
|
19
|
+
return read;
|
|
20
|
+
const built = kept
|
|
21
|
+
.map((name) => builtDomain_read(store, name))
|
|
22
|
+
.filter((domain) => domain !== null);
|
|
23
|
+
return [...read, ...built];
|
|
24
|
+
}
|
|
25
|
+
/** One domain by name, read now: the one kept here, else the checkout's; null when there is none. */
|
|
26
|
+
domain_read(name) {
|
|
27
|
+
const kept = this.options.store === undefined ? null : builtDomain_read(this.options.store, name);
|
|
28
|
+
if (kept !== null)
|
|
29
|
+
return kept;
|
|
30
|
+
const source = this.options.sources.find((entry) => entry.name === name);
|
|
31
|
+
return source === undefined ? null : harborDomain_read(source, this.options.now());
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* The node a path below `domains/` names.
|
|
35
|
+
*
|
|
36
|
+
* @param segments - The segments after `domains`.
|
|
37
|
+
* @returns The node.
|
|
38
|
+
*/
|
|
39
|
+
node_resolve(segments) {
|
|
40
|
+
if (segments.length === 0)
|
|
41
|
+
return { kind: 'listing', list: async () => this.domains_read().map((domain) => this.domain_item(domain)) };
|
|
42
|
+
const [name, entry, ...rest] = segments;
|
|
43
|
+
const domain = this.domain_read(name);
|
|
44
|
+
if (domain === null)
|
|
45
|
+
return { kind: 'missing' };
|
|
46
|
+
if (entry === undefined)
|
|
47
|
+
return { kind: 'listing', list: async () => this.domainEntries_items(domain) };
|
|
48
|
+
if (entry === 'steps')
|
|
49
|
+
return this.stepNode_resolve(domain, rest);
|
|
50
|
+
if (entry === 'auth')
|
|
51
|
+
return this.authNode_resolve(domain, rest);
|
|
52
|
+
if (rest.length > 0)
|
|
53
|
+
return { kind: 'missing' };
|
|
54
|
+
const text = domainFile_text(domain, entry);
|
|
55
|
+
return text === null ? { kind: 'missing' } : { kind: 'file', text };
|
|
56
|
+
}
|
|
57
|
+
stepNode_resolve(domain, segments) {
|
|
58
|
+
if (segments.length === 0)
|
|
59
|
+
return { kind: 'listing', list: async () => domain.steps.map((step) => this.step_item(step)) };
|
|
60
|
+
const step = domain.steps.find((entry) => entry.folder === segments[0]);
|
|
61
|
+
if (step === undefined)
|
|
62
|
+
return { kind: 'missing' };
|
|
63
|
+
const fields = [['state', `${step.state}\n`], ['evidence', `${step.evidence}\n`]];
|
|
64
|
+
if (segments.length === 1)
|
|
65
|
+
return { kind: 'listing', list: async () => fields.map(([name, text]) => this.file_item(name, text)) };
|
|
66
|
+
if (segments.length > 2)
|
|
67
|
+
return { kind: 'missing' };
|
|
68
|
+
const field = fields.find(([name]) => name === segments[1]);
|
|
69
|
+
return field === undefined ? { kind: 'missing' } : { kind: 'file', text: field[1] };
|
|
70
|
+
}
|
|
71
|
+
authNode_resolve(domain, segments) {
|
|
72
|
+
if (segments.length === 0) {
|
|
73
|
+
return { kind: 'listing', list: async () => domain.secrets.map((secret) => ({ name: secret.name, type: 'secret', size: 0, owner: this.options.owner(), date: this.options.now().toISOString() })) };
|
|
74
|
+
}
|
|
75
|
+
const secret = domain.secrets.find((entry) => entry.name === segments[0]);
|
|
76
|
+
if (secret === undefined || segments.length > 1)
|
|
77
|
+
return { kind: 'missing' };
|
|
78
|
+
return { kind: 'refused', errno: 'EACCES', reason: `a secret stays on the daemon's host: ${secret.hostPath}` };
|
|
79
|
+
}
|
|
80
|
+
// ---- rows ----
|
|
81
|
+
domain_item(domain) {
|
|
82
|
+
const last = lastDone_of(domain);
|
|
83
|
+
return {
|
|
84
|
+
name: domain.name,
|
|
85
|
+
type: 'domain',
|
|
86
|
+
size: 0,
|
|
87
|
+
owner: this.options.owner(),
|
|
88
|
+
date: this.options.now().toISOString(),
|
|
89
|
+
status: last !== null ? last.folder : 'empty',
|
|
90
|
+
...(domain.cluster !== null ? { title: domain.cluster } : {}),
|
|
91
|
+
};
|
|
92
|
+
}
|
|
93
|
+
domainEntries_items(domain) {
|
|
94
|
+
const items = [];
|
|
95
|
+
for (const entry of DOMAIN_ENTRIES) {
|
|
96
|
+
if (entry === 'steps')
|
|
97
|
+
items.push(this.folder_item('steps', domain.steps.length));
|
|
98
|
+
else if (entry === 'auth')
|
|
99
|
+
items.push(this.folder_item('auth', domain.secrets.length));
|
|
100
|
+
else {
|
|
101
|
+
const text = domainFile_text(domain, entry);
|
|
102
|
+
if (text !== null)
|
|
103
|
+
items.push(this.file_item(entry, text));
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
return items;
|
|
107
|
+
}
|
|
108
|
+
step_item(step) {
|
|
109
|
+
return { name: step.folder, type: 'step', size: 0, owner: this.options.owner(), date: this.options.now().toISOString(), status: step.state, title: step.evidence };
|
|
110
|
+
}
|
|
111
|
+
folder_item(name, count) {
|
|
112
|
+
return { name, type: 'kind', size: count, owner: 'cloud', date: this.options.now().toISOString() };
|
|
113
|
+
}
|
|
114
|
+
file_item(name, text) {
|
|
115
|
+
return { name, type: 'file', size: Buffer.byteLength(text), owner: this.options.owner(), date: this.options.now().toISOString() };
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
/** The text of a domain's own files; null when the domain has none of that name. */
|
|
119
|
+
function domainFile_text(domain, entry) {
|
|
120
|
+
if (entry === 'spec.yaml')
|
|
121
|
+
return domain.spec;
|
|
122
|
+
if (entry === 'state.json')
|
|
123
|
+
return domain.state === null ? null : `${JSON.stringify(domain.state, null, 2)}\n`;
|
|
124
|
+
if (entry === 'settings')
|
|
125
|
+
return Object.entries(domain.settings).map(([key, value]) => `${key}=${value}\n`).join('');
|
|
126
|
+
return null;
|
|
127
|
+
}
|
|
128
|
+
//# sourceMappingURL=domains.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"domains.js","sourceRoot":"","sources":["../../src/vfs/domains.ts"],"names":[],"mappings":"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"}
|
package/dist/vfs/look.d.ts
CHANGED
|
@@ -3,6 +3,16 @@ import { type ItemKindLook, type ListingLook } from '@fnndsc/fond';
|
|
|
3
3
|
export declare const CONTAINER_TYPES: ReadonlyArray<string>;
|
|
4
4
|
/** The kinds stratus lists beside the core's. */
|
|
5
5
|
export declare const STRATUS_ITEM_KINDS: ReadonlyArray<ItemKindLook>;
|
|
6
|
+
/** The status a kind folder wears when its count could not be asked. */
|
|
7
|
+
export declare const UNCOUNTED: string;
|
|
8
|
+
/**
|
|
9
|
+
* Paints text in the tone of a lifecycle state; text in a state with no tone is left plain.
|
|
10
|
+
*
|
|
11
|
+
* @param state - The state.
|
|
12
|
+
* @param text - What to paint.
|
|
13
|
+
* @returns The painted text.
|
|
14
|
+
*/
|
|
15
|
+
export declare function stateTone_paint(state: string, text: string): string;
|
|
6
16
|
/** Colours a name by the item's kind and state. */
|
|
7
17
|
export declare function stratusName_colorize(name: string, type: string, status?: string): string;
|
|
8
18
|
/** The look of a stratus listing. */
|
package/dist/vfs/look.js
CHANGED
|
@@ -3,9 +3,10 @@
|
|
|
3
3
|
*
|
|
4
4
|
* Every row is a folder or a file to the shell (docs/stratus.adoc, D5); the
|
|
5
5
|
* kind is how `ls -l` draws it: the container nouns, the resource kinds, the
|
|
6
|
-
* facts under `regions/`. A name is coloured by its kind
|
|
7
|
-
*
|
|
8
|
-
*
|
|
6
|
+
* facts under `regions/`. A name is coloured by its kind; a row with a
|
|
7
|
+
* lifecycle state shows it in the size column, coloured as jobs are by
|
|
8
|
+
* status: running green, stopped dim, provisioning amber, failed red. A kind
|
|
9
|
+
* folder (`instances/`) shows how many live resources it holds.
|
|
9
10
|
*
|
|
10
11
|
* @module
|
|
11
12
|
*/
|
|
@@ -23,17 +24,51 @@ export const STRATUS_ITEM_KINDS = [
|
|
|
23
24
|
{ type: 'shape', mark: 's', container: true },
|
|
24
25
|
{ type: 'price', mark: '$', container: true },
|
|
25
26
|
{ type: 'domain', mark: 'D', container: true, sizeColumn: state_column },
|
|
27
|
+
{ type: 'kind', mark: 'k', container: true, sizeColumn: count_column },
|
|
28
|
+
{ type: 'instance', mark: 'i', container: true, sizeColumn: state_column },
|
|
29
|
+
{ type: 'network', mark: 'n', container: true, sizeColumn: state_column },
|
|
30
|
+
{ type: 'subnet', mark: 'u', container: true, sizeColumn: state_column },
|
|
31
|
+
{ type: 'securitygroup', mark: 'g', container: true, sizeColumn: state_column },
|
|
32
|
+
{ type: 'loadbalancer', mark: 'b', container: true, sizeColumn: state_column },
|
|
33
|
+
{ type: 'volume', mark: 'V', container: true, sizeColumn: state_column },
|
|
34
|
+
{ type: 'bucket', mark: 'B', container: true, sizeColumn: state_column },
|
|
35
|
+
{ type: 'dnszone', mark: 'Z', container: true, sizeColumn: state_column },
|
|
36
|
+
{ type: 'step', mark: 'S', container: true, sizeColumn: state_column },
|
|
37
|
+
{ type: 'secret', mark: '!' },
|
|
38
|
+
{ type: 'object', mark: 'o' },
|
|
39
|
+
{ type: 'record', mark: 'R' },
|
|
26
40
|
];
|
|
27
|
-
/** The
|
|
41
|
+
/** The width a state takes in the size column, the longest state padded. */
|
|
42
|
+
const STATE_WIDTH = 12;
|
|
43
|
+
/** The long view's size column for an item with a state: the state, coloured by it. */
|
|
28
44
|
function state_column(item) {
|
|
29
|
-
|
|
45
|
+
if (item.status === undefined || item.status === '')
|
|
46
|
+
return null;
|
|
47
|
+
return stateTone_paint(item.status, item.status.padEnd(STATE_WIDTH));
|
|
48
|
+
}
|
|
49
|
+
/** The size column of a kind folder: how many it holds, or `-` when the count could not be asked. */
|
|
50
|
+
function count_column(item) {
|
|
51
|
+
return item.status === UNCOUNTED ? '-'.padEnd(8) : null;
|
|
52
|
+
}
|
|
53
|
+
/** The status a kind folder wears when its count could not be asked. */
|
|
54
|
+
export const UNCOUNTED = 'uncounted';
|
|
55
|
+
/**
|
|
56
|
+
* Paints text in the tone of a lifecycle state; text in a state with no tone is left plain.
|
|
57
|
+
*
|
|
58
|
+
* @param state - The state.
|
|
59
|
+
* @param text - What to paint.
|
|
60
|
+
* @returns The painted text.
|
|
61
|
+
*/
|
|
62
|
+
export function stateTone_paint(state, text) {
|
|
63
|
+
const tone = STATE_TONES.find((entry) => entry.matches.test(state.toLowerCase()));
|
|
64
|
+
return tone !== undefined ? tone.paint(text) : text;
|
|
30
65
|
}
|
|
31
66
|
/** States and the tone each is drawn in. */
|
|
32
67
|
const STATE_TONES = [
|
|
33
68
|
{ matches: /^(running|active|available|attached|ready|done)$/, paint: chalk.green },
|
|
34
|
-
{ matches: /^(stopped|inactive|terminated|deleted|detached)$/, paint: chalk.dim },
|
|
69
|
+
{ matches: /^(stopped|inactive|terminated|deleted|detached|unknown|empty)$/, paint: chalk.dim },
|
|
35
70
|
{ matches: /^(provisioning|creating|starting|stopping|updating|deleting|terminating|moving|queued|pending)$/, paint: chalk.yellow },
|
|
36
|
-
{ matches: /^(failed|faulted|error|unknown_value)$/, paint: chalk.red },
|
|
71
|
+
{ matches: /^(failed|faulted|error|unknown_value|expired)$/, paint: chalk.red },
|
|
37
72
|
];
|
|
38
73
|
/** Colours a name by the item's kind and state. */
|
|
39
74
|
export function stratusName_colorize(name, type, status) {
|
|
@@ -42,7 +77,7 @@ export function stratusName_colorize(name, type, status) {
|
|
|
42
77
|
if (tone !== undefined)
|
|
43
78
|
return tone.paint(name);
|
|
44
79
|
}
|
|
45
|
-
if (CONTAINER_TYPES.includes(type) || type === 'dir')
|
|
80
|
+
if (CONTAINER_TYPES.includes(type) || type === 'dir' || type === 'kind')
|
|
46
81
|
return chalk.blue(name);
|
|
47
82
|
if (type === 'region' || type === 'zone')
|
|
48
83
|
return chalk.cyan(name);
|
package/dist/vfs/look.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"look.js","sourceRoot":"","sources":["../../src/vfs/look.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"look.js","sourceRoot":"","sources":["../../src/vfs/look.ts"],"names":[],"mappings":"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"}
|