@fnndsc/stratus 0.1.0 → 0.2.1
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/README.md
CHANGED
|
@@ -12,16 +12,21 @@ The `stratus` command hosts the session as a calypso daemon on the bastion, the
|
|
|
12
12
|
stratus # the DEFAULT profile of ~/.oci/config, its home region
|
|
13
13
|
stratus --profile BCH --region us-phoenix-1
|
|
14
14
|
stratus --fake # a session over the fake cloud, for tests
|
|
15
|
+
stratus --fake --host-control tasks
|
|
16
|
+
# one that may build domains over the fake cloud
|
|
15
17
|
```
|
|
16
18
|
|
|
19
|
+
A domain is made, priced and built with `domain new`, `domain plan` and `domain build`. The build runs as a task (`/proc/steps/<name>-build`) that outlives every surface and a daemon restart; `wait` follows it, `kill` asks it to stop. Starting it needs the `tasks` tier, and before the first step that bills it asks, with the cost. Over the fake cloud the build moves on a clock (`STRATUS_FAKE_TICK_MS`, 700 by default). `domain adopt <name> --from <harbor-oci checkout>` keeps a domain built elsewhere and, with the tier, takes its stack and Terraform state into OCI Resource Manager, where `domain plan` plans against it; an adopted domain is never built on. `domain verify` runs `harbor-oci`'s ten checks against a domain's cluster through its kubeconfig (`src/cluster/`, `src/domain/verify.ts`); the block-volume probe, which writes, needs the tier. `spend` prices each domain's machines, volumes and load balancers at list price (`src/domain/spend.ts`). Over OCI, `domain build` runs through Resource Manager and Red Hat's Assisted Installer (`src/installer/assisted.ts`, a service account from `--redhat-account`, the nodes' key from `--ssh-key`), and `domain teardown` removes what a domain built, asking for its name.
|
|
20
|
+
|
|
17
21
|
Attach with `chell --remote`, or open the ARGUS address the daemon prints. A credential that does not work still starts the daemon, disconnected, with `/net/oci` empty.
|
|
18
22
|
|
|
19
23
|
## Shape
|
|
20
24
|
|
|
21
25
|
- `src/cloud/driver.ts` is the `CloudDriver` interface: identity, containers, regions, zones, limits, shapes, prices, each answered for the region given.
|
|
22
|
-
- `src/cloud/oci/` is the OCI driver over Oracle's TypeScript SDK (`api.ts` wraps the few calls made, `prices.ts` reads Oracle's public price list). Only this folder may import an `oci-*` package: `npm run lint:stratus-deps` at the repository root keeps it so.
|
|
26
|
+
- `src/cloud/oci/` is the OCI driver over Oracle's TypeScript SDK (`api.ts` wraps the few calls made, `prices.ts` reads Oracle's public price list), and its build half over Resource Manager (`builder.ts`, `rmApi.ts`; `planRead.ts` reads a plan's JSON, drift apart). Only this folder may import an `oci-*` package: `npm run lint:stratus-deps` at the repository root keeps it so.
|
|
23
27
|
- `src/cloud/fake/` is an in-memory cloud. It runs the same driver contract (`tests/support/driverContract.ts`) the OCI driver runs over recorded answers, and it is what the boot proof hosts.
|
|
24
28
|
- `src/vfs/tenancy.ts` is the tree, a fond provider over the driver; `src/vfs/look.ts` is how its rows show.
|
|
29
|
+
- `src/domain/` is a domain built here: its spec (`spec.ts`, `harbor-oci`'s `spec.yaml` shape), its state on the host (`state.ts`, `$XDG_STATE_HOME/stratus/domains/<name>/`), its fit and cost (`sizing.ts`), and its steps (`steps.ts`), written once over the cloud's build half (`src/cloud/builder.ts`) and the installer (`src/installer/`). `src/cloud/fake/builder.ts` is the fake of both.
|
|
25
30
|
- `src/session.ts` is who the session is (`user@tenancy`), where it starts (`domains/`) and where it left off; `src/backend.ts` is the descriptor `engine_create` takes.
|
|
26
31
|
|
|
27
32
|
## Proving it
|
package/dist/args.d.ts
CHANGED
|
@@ -1,17 +1,31 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* @file The `stratus` command line: what it takes, and the refusal of
|
|
3
|
-
* anything else by name.
|
|
4
|
-
*
|
|
5
|
-
* @module
|
|
6
|
-
*/
|
|
7
1
|
/** What the command line asked for. */
|
|
8
2
|
export interface StratusArgs {
|
|
9
3
|
readonly profile?: string;
|
|
10
4
|
readonly configFile?: string;
|
|
11
5
|
readonly region?: string;
|
|
6
|
+
/** The Red Hat service account file: `RH_CLIENT_ID=`, `RH_CLIENT_SECRET=`. */
|
|
7
|
+
readonly redhatAccount?: string;
|
|
8
|
+
/** The nodes' SSH public key file. */
|
|
9
|
+
readonly sshKey?: string;
|
|
12
10
|
readonly fake: boolean;
|
|
13
11
|
readonly help: boolean;
|
|
12
|
+
/** `--domain <name>=<checkout>`, as many as given. */
|
|
13
|
+
readonly domains: ReadonlyArray<{
|
|
14
|
+
readonly name: string;
|
|
15
|
+
readonly root: string;
|
|
16
|
+
}>;
|
|
14
17
|
}
|
|
18
|
+
/**
|
|
19
|
+
* Reads `<name>=<checkout>`: a name that is a path segment, and a checkout,
|
|
20
|
+
* `~` meaning the home directory.
|
|
21
|
+
*
|
|
22
|
+
* @param given - The word.
|
|
23
|
+
* @returns The domain, or null when the word is not one.
|
|
24
|
+
*/
|
|
25
|
+
export declare function domainArg_parse(given: string): {
|
|
26
|
+
name: string;
|
|
27
|
+
root: string;
|
|
28
|
+
} | null;
|
|
15
29
|
/**
|
|
16
30
|
* Parses the command line; unknown words are refused by name, as the house
|
|
17
31
|
* rule says.
|
package/dist/args.js
CHANGED
|
@@ -4,6 +4,8 @@
|
|
|
4
4
|
*
|
|
5
5
|
* @module
|
|
6
6
|
*/
|
|
7
|
+
import { homedir } from 'node:os';
|
|
8
|
+
import { join, resolve } from 'node:path';
|
|
7
9
|
/** The value after a `--flag VALUE` or `--flag=VALUE`, or undefined. */
|
|
8
10
|
function flagValue_get(argv, flag) {
|
|
9
11
|
const at = argv.indexOf(flag);
|
|
@@ -12,6 +14,24 @@ function flagValue_get(argv, flag) {
|
|
|
12
14
|
const joined = argv.find((arg) => arg.startsWith(`${flag}=`));
|
|
13
15
|
return joined?.slice(flag.length + 1);
|
|
14
16
|
}
|
|
17
|
+
/**
|
|
18
|
+
* Reads `<name>=<checkout>`: a name that is a path segment, and a checkout,
|
|
19
|
+
* `~` meaning the home directory.
|
|
20
|
+
*
|
|
21
|
+
* @param given - The word.
|
|
22
|
+
* @returns The domain, or null when the word is not one.
|
|
23
|
+
*/
|
|
24
|
+
export function domainArg_parse(given) {
|
|
25
|
+
const equals = given.indexOf('=');
|
|
26
|
+
if (equals <= 0 || equals === given.length - 1)
|
|
27
|
+
return null;
|
|
28
|
+
const name = given.slice(0, equals);
|
|
29
|
+
if (!/^[A-Za-z0-9][A-Za-z0-9._-]*$/.test(name))
|
|
30
|
+
return null;
|
|
31
|
+
const path = given.slice(equals + 1);
|
|
32
|
+
const root = path === '~' ? homedir() : path.startsWith('~/') ? join(homedir(), path.slice(2)) : resolve(path);
|
|
33
|
+
return { name, root };
|
|
34
|
+
}
|
|
15
35
|
/**
|
|
16
36
|
* Parses the command line; unknown words are refused by name, as the house
|
|
17
37
|
* rule says.
|
|
@@ -20,23 +40,46 @@ function flagValue_get(argv, flag) {
|
|
|
20
40
|
* @returns The arguments, or the refusal.
|
|
21
41
|
*/
|
|
22
42
|
export function stratusArgs_parse(argv) {
|
|
23
|
-
const known = ['--profile', '--config', '--region', '--fake', '--help', '-h', '--host-control', '--expose-host-control'];
|
|
24
|
-
const valued = ['--profile', '--config', '--region', '--host-control'];
|
|
43
|
+
const known = ['--profile', '--config', '--region', '--fake', '--help', '-h', '--host-control', '--expose-host-control', '--domain', '--redhat-account', '--ssh-key'];
|
|
44
|
+
const valued = ['--profile', '--config', '--region', '--host-control', '--redhat-account', '--ssh-key'];
|
|
45
|
+
const domains = [];
|
|
25
46
|
for (let i = 0; i < argv.length; i++) {
|
|
26
47
|
const word = argv[i];
|
|
48
|
+
if (word === '--domain') {
|
|
49
|
+
const given = argv[i + 1];
|
|
50
|
+
const domain = given === undefined ? null : domainArg_parse(given);
|
|
51
|
+
if (domain === null)
|
|
52
|
+
return { error: `--domain takes <name>=<harbor-oci checkout>, not '${given ?? ''}'` };
|
|
53
|
+
domains.push(domain);
|
|
54
|
+
i++;
|
|
55
|
+
continue;
|
|
56
|
+
}
|
|
27
57
|
const name = word.includes('=') ? word.slice(0, word.indexOf('=')) : word;
|
|
28
58
|
if (!known.includes(name))
|
|
29
59
|
return { error: `unknown option '${word}' (stratus --help)` };
|
|
60
|
+
if (name === '--domain') {
|
|
61
|
+
const domain = domainArg_parse(word.slice('--domain='.length));
|
|
62
|
+
if (domain === null)
|
|
63
|
+
return { error: `--domain takes <name>=<harbor-oci checkout>, not '${word.slice('--domain='.length)}'` };
|
|
64
|
+
domains.push(domain);
|
|
65
|
+
continue;
|
|
66
|
+
}
|
|
30
67
|
if (valued.includes(name) && !word.includes('=') && name !== '--host-control')
|
|
31
68
|
i++;
|
|
69
|
+
// `--host-control tasks` takes its tiers as the next word, as calypso reads it; bare, it takes none.
|
|
70
|
+
if (name === '--host-control' && !word.includes('=') && argv[i + 1] !== undefined && !argv[i + 1].startsWith('-'))
|
|
71
|
+
i++;
|
|
32
72
|
}
|
|
33
73
|
return {
|
|
34
74
|
args: {
|
|
35
75
|
profile: flagValue_get(argv, '--profile'),
|
|
36
76
|
configFile: flagValue_get(argv, '--config'),
|
|
37
77
|
region: flagValue_get(argv, '--region'),
|
|
78
|
+
redhatAccount: flagValue_get(argv, '--redhat-account'),
|
|
79
|
+
sshKey: flagValue_get(argv, '--ssh-key'),
|
|
38
80
|
fake: argv.includes('--fake'),
|
|
39
81
|
help: argv.includes('--help') || argv.includes('-h'),
|
|
82
|
+
domains,
|
|
40
83
|
},
|
|
41
84
|
};
|
|
42
85
|
}
|
package/dist/args.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"args.js","sourceRoot":"","sources":["../src/args.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;
|
|
1
|
+
{"version":3,"file":"args.js","sourceRoot":"","sources":["../src/args.ts"],"names":[],"mappings":"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"}
|
package/dist/backend.d.ts
CHANGED
|
@@ -4,16 +4,23 @@
|
|
|
4
4
|
* One backend for every cloud (docs/stratus.adoc, D1): its id is `stratus`,
|
|
5
5
|
* its filesystem is the tenancy tree over whichever driver it was given, its
|
|
6
6
|
* identity the cloud user at the tenancy. It registers no commands yet and
|
|
7
|
-
* no answer kinds (every row is a folder or a file, D5)
|
|
8
|
-
* wire's ChRIS-shaped context filled with what a substrate session has,
|
|
9
|
-
*
|
|
7
|
+
* no answer kinds (every row is a folder or a file, D5). Its prompt is the
|
|
8
|
+
* wire's ChRIS-shaped context filled with what a substrate session has, plus
|
|
9
|
+
* the backend-neutral segments of D9 (`prompt.ts`) a surface draws in order.
|
|
10
10
|
*
|
|
11
11
|
* @module
|
|
12
12
|
*/
|
|
13
|
-
import type
|
|
13
|
+
import { type Backend } from '@fnndsc/brasa/core';
|
|
14
14
|
import type { CloudDriver } from './cloud/driver.js';
|
|
15
15
|
import { StratusSession } from './session.js';
|
|
16
16
|
import { TenancyProvider } from './vfs/tenancy.js';
|
|
17
|
+
import { DomainTree } from './vfs/domains.js';
|
|
18
|
+
import type { DomainSource } from './domains/harborOci.js';
|
|
19
|
+
import type { CloudBuilder } from './cloud/builder.js';
|
|
20
|
+
import type { Installer } from './installer/installer.js';
|
|
21
|
+
import type { VerifyReach } from './commands/verify.js';
|
|
22
|
+
import { DomainStore } from './domain/state.js';
|
|
23
|
+
import { type BuildDeps } from './domain/steps.js';
|
|
17
24
|
/** How the backend is made. */
|
|
18
25
|
export interface StratusBackendOptions {
|
|
19
26
|
/** The cloud. */
|
|
@@ -24,13 +31,37 @@ export interface StratusBackendOptions {
|
|
|
24
31
|
readonly configDir?: string;
|
|
25
32
|
/** How long the tree keeps a cloud answer, in milliseconds. */
|
|
26
33
|
readonly cacheLifeMs?: number;
|
|
34
|
+
/** The Trusted Domains this daemon knows, each a `harbor-oci` checkout. */
|
|
35
|
+
readonly domains?: ReadonlyArray<DomainSource>;
|
|
36
|
+
/** Where the domains this daemon builds are kept; `$XDG_STATE_HOME/stratus/domains` when absent. */
|
|
37
|
+
readonly store?: DomainStore;
|
|
38
|
+
/** The cloud's build half; absent, this cloud cannot build, adopt or plan, and the verbs say so. With no installer beside it, it adopts and plans but does not build. */
|
|
39
|
+
readonly builder?: CloudBuilder;
|
|
40
|
+
/** The installer the build's steps call. */
|
|
41
|
+
readonly installer?: Installer;
|
|
42
|
+
/** The DNS zone a new domain's names live under when `domain new` is not told. */
|
|
43
|
+
readonly baseDomain?: string;
|
|
44
|
+
/** How `domain verify` reaches a cluster; the network when absent. */
|
|
45
|
+
readonly verifyReach?: VerifyReach;
|
|
46
|
+
/** The build's waits, `harbor-oci`'s when absent. */
|
|
47
|
+
readonly waits?: Pick<BuildDeps, 'pollMs' | 'hostsWaitMs' | 'installWaitMs'>;
|
|
27
48
|
}
|
|
28
49
|
/** The backend and the pieces a host may reach into. */
|
|
29
50
|
export interface StratusBackend {
|
|
30
51
|
readonly backend: Backend;
|
|
31
52
|
readonly session: StratusSession;
|
|
32
53
|
readonly tenancy: TenancyProvider;
|
|
54
|
+
readonly domains: DomainTree;
|
|
55
|
+
readonly store: DomainStore;
|
|
33
56
|
}
|
|
57
|
+
/**
|
|
58
|
+
* The paths a session enters without a lookup: the mount, and once the
|
|
59
|
+
* tenancy is known, the tenancy, `regions`, `domains` and its kind folders.
|
|
60
|
+
*
|
|
61
|
+
* @param session - The session.
|
|
62
|
+
* @returns The structural paths.
|
|
63
|
+
*/
|
|
64
|
+
export declare function structuralPaths_of(session: StratusSession): string[];
|
|
34
65
|
/**
|
|
35
66
|
* Makes the stratus backend over a driver.
|
|
36
67
|
*
|
package/dist/backend.js
CHANGED
|
@@ -1,8 +1,41 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @file The stratus backend: the descriptor a session over a cloud runs with.
|
|
3
|
+
*
|
|
4
|
+
* One backend for every cloud (docs/stratus.adoc, D1): its id is `stratus`,
|
|
5
|
+
* its filesystem is the tenancy tree over whichever driver it was given, its
|
|
6
|
+
* identity the cloud user at the tenancy. It registers no commands yet and
|
|
7
|
+
* no answer kinds (every row is a folder or a file, D5). Its prompt is the
|
|
8
|
+
* wire's ChRIS-shaped context filled with what a substrate session has, plus
|
|
9
|
+
* the backend-neutral segments of D9 (`prompt.ts`) a surface draws in order.
|
|
10
|
+
*
|
|
11
|
+
* @module
|
|
12
|
+
*/
|
|
13
|
+
import { commands_register } from '@fnndsc/brasa/core';
|
|
1
14
|
import { VFSDispatcher } from '@fnndsc/fond';
|
|
2
15
|
import { AnswerCache } from './cache.js';
|
|
3
16
|
import { StratusSession } from './session.js';
|
|
4
17
|
import { TenancyProvider } from './vfs/tenancy.js';
|
|
18
|
+
import { KIND_FOLDERS } from './vfs/resources.js';
|
|
19
|
+
import { DomainTree } from './vfs/domains.js';
|
|
20
|
+
import { stratusCommands_make } from './commands/domain.js';
|
|
5
21
|
import { stratusListingLook } from './vfs/look.js';
|
|
22
|
+
import { stratusSegments_build } from './prompt.js';
|
|
23
|
+
import { DomainStore, domainsRoot_of } from './domain/state.js';
|
|
24
|
+
import { BUILD_WAITS, buildRun_make, STEPS_SOURCE } from './domain/steps.js';
|
|
25
|
+
/**
|
|
26
|
+
* The paths a session enters without a lookup: the mount, and once the
|
|
27
|
+
* tenancy is known, the tenancy, `regions`, `domains` and its kind folders.
|
|
28
|
+
*
|
|
29
|
+
* @param session - The session.
|
|
30
|
+
* @returns The structural paths.
|
|
31
|
+
*/
|
|
32
|
+
export function structuralPaths_of(session) {
|
|
33
|
+
const paths = ['/', '/net', session.mount];
|
|
34
|
+
if (session.identity === null)
|
|
35
|
+
return paths;
|
|
36
|
+
const tenancy = session.tenancyPath;
|
|
37
|
+
return [...paths, tenancy, `${tenancy}/regions`, `${tenancy}/domains`, ...KIND_FOLDERS.map((kind) => `${tenancy}/${kind}`)];
|
|
38
|
+
}
|
|
6
39
|
/**
|
|
7
40
|
* Makes the stratus backend over a driver.
|
|
8
41
|
*
|
|
@@ -11,7 +44,23 @@ import { stratusListingLook } from './vfs/look.js';
|
|
|
11
44
|
*/
|
|
12
45
|
export function stratusBackend_make(options) {
|
|
13
46
|
const session = new StratusSession({ driver: options.driver, region: options.region, configDir: options.configDir });
|
|
14
|
-
const
|
|
47
|
+
const store = options.store ?? new DomainStore(domainsRoot_of());
|
|
48
|
+
// The steps run over the cloud's build half and the installer; a cloud with neither cannot build yet.
|
|
49
|
+
const deps = options.builder !== undefined && options.installer !== undefined
|
|
50
|
+
? { store, builder: options.builder, installer: options.installer, zones: 3, version: '4.22', ...(options.waits ?? BUILD_WAITS) }
|
|
51
|
+
: null;
|
|
52
|
+
const domains = new DomainTree({
|
|
53
|
+
store,
|
|
54
|
+
sources: options.domains ?? [],
|
|
55
|
+
owner: () => session.identity?.user ?? 'disconnected',
|
|
56
|
+
now: () => new Date(),
|
|
57
|
+
});
|
|
58
|
+
const tenancy = new TenancyProvider({ driver: options.driver, cache: new AnswerCache(options.cacheLifeMs), region: () => session.region, domains });
|
|
59
|
+
const region = () => session.region;
|
|
60
|
+
commands_register(stratusCommands_make({
|
|
61
|
+
domains, driver: options.driver, region, domainsPath: () => `${session.tenancyPath}/domains`,
|
|
62
|
+
build: { domains, store, driver: options.driver, region, deps, builder: options.builder ?? null, baseDomain: options.baseDomain ?? null, ...(options.verifyReach !== undefined ? { verifyReach: options.verifyReach } : {}) },
|
|
63
|
+
}), 'backend');
|
|
15
64
|
const dispatcher = new VFSDispatcher();
|
|
16
65
|
dispatcher.provider_register(tenancy);
|
|
17
66
|
const backend = {
|
|
@@ -19,20 +68,36 @@ export function stratusBackend_make(options) {
|
|
|
19
68
|
session,
|
|
20
69
|
vfs: {
|
|
21
70
|
dispatcher,
|
|
22
|
-
|
|
71
|
+
// The tenancy and its fixed folders are entered without asking once
|
|
72
|
+
// the session knows its tenancy (docs/stratus.adoc, D4).
|
|
73
|
+
get structural() {
|
|
74
|
+
return structuralPaths_of(session);
|
|
75
|
+
},
|
|
23
76
|
},
|
|
24
77
|
completion: { rootWords: ['net'] },
|
|
78
|
+
// A domain's build runs as a task; one left running when the daemon stopped goes on from its first step not done.
|
|
79
|
+
jobs: [{
|
|
80
|
+
id: STEPS_SOURCE,
|
|
81
|
+
label: 'build steps',
|
|
82
|
+
resume: (record) => deps === null || typeof record.data['domain'] !== 'string'
|
|
83
|
+
? null
|
|
84
|
+
: buildRun_make(record.data['domain'], typeof record.data['through'] === 'string' ? record.data['through'] : undefined, deps),
|
|
85
|
+
}],
|
|
25
86
|
listingLook: stratusListingLook,
|
|
26
|
-
prompt: async (last) =>
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
87
|
+
prompt: async (last) => {
|
|
88
|
+
const cwd = session.cwd_get() ?? (await session.home_get());
|
|
89
|
+
return {
|
|
90
|
+
user: (await session.user_get()) ?? 'disconnected',
|
|
91
|
+
uri: session.identity?.tenancy ?? '',
|
|
92
|
+
cwd,
|
|
93
|
+
pacsserver: null,
|
|
94
|
+
physicalMode: false,
|
|
95
|
+
lastExitCode: last?.lastExitCode ?? 0,
|
|
96
|
+
lastCommandDurationMs: last?.lastCommandDurationMs ?? 0,
|
|
97
|
+
segments: stratusSegments_build(session, cwd),
|
|
98
|
+
};
|
|
99
|
+
},
|
|
35
100
|
};
|
|
36
|
-
return { backend, session, tenancy };
|
|
101
|
+
return { backend, session, tenancy, domains, store };
|
|
37
102
|
}
|
|
38
103
|
//# sourceMappingURL=backend.js.map
|
package/dist/backend.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"backend.js","sourceRoot":"","sources":["../src/backend.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"backend.js","sourceRoot":"","sources":["../src/backend.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,172 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @file The cloud driver's build half: what a domain's steps ask of a cloud
|
|
3
|
+
* (docs/stratus.adoc, D3). The read half is `driver.ts`; a cloud that cannot
|
|
4
|
+
* build yet has a driver and no builder, and the build verbs say so.
|
|
5
|
+
*
|
|
6
|
+
* OCI's builder runs Terraform in Resource Manager: a plan is a plan job
|
|
7
|
+
* read as JSON, an apply is an apply job. Its plan says which changes are
|
|
8
|
+
* `Oracle-Tags` drift, so a re-plan can be read for real change (D6).
|
|
9
|
+
*
|
|
10
|
+
* @module
|
|
11
|
+
*/
|
|
12
|
+
import type { DomainSpec } from '../domain/spec.js';
|
|
13
|
+
import type { PlatformManifest } from '../installer/installer.js';
|
|
14
|
+
/** One check the build makes before it starts. */
|
|
15
|
+
export interface PreflightCheck {
|
|
16
|
+
name: string;
|
|
17
|
+
ok: boolean;
|
|
18
|
+
note: string;
|
|
19
|
+
}
|
|
20
|
+
/** One change a plan would make. */
|
|
21
|
+
export interface PlanRow {
|
|
22
|
+
action: 'create' | 'change' | 'destroy';
|
|
23
|
+
/** The neutral kind (`instances`, `loadbalancers`, …) or the cloud's own. */
|
|
24
|
+
kind: string;
|
|
25
|
+
name: string;
|
|
26
|
+
/** A change the cloud makes to its own tags after an apply, not a real one. */
|
|
27
|
+
drift?: boolean;
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* An infrastructure plan, as the operator is asked about it.
|
|
31
|
+
*
|
|
32
|
+
* @property ref - The cloud's handle on it, for the apply (OCI: the plan job's id).
|
|
33
|
+
* @property rows - Each change.
|
|
34
|
+
*/
|
|
35
|
+
export interface InfraPlan {
|
|
36
|
+
ref: string;
|
|
37
|
+
rows: ReadonlyArray<PlanRow>;
|
|
38
|
+
/** The stack the plan was made in, when the plan made one. */
|
|
39
|
+
stackRef?: string;
|
|
40
|
+
}
|
|
41
|
+
/** A plan's counts: a resource both destroyed and created is replaced, drift is apart from real change. */
|
|
42
|
+
export interface PlanCounts {
|
|
43
|
+
create: number;
|
|
44
|
+
replace: number;
|
|
45
|
+
change: number;
|
|
46
|
+
drift: number;
|
|
47
|
+
destroy: number;
|
|
48
|
+
/** The kinds replaced, for the line. */
|
|
49
|
+
replacedKinds: string[];
|
|
50
|
+
}
|
|
51
|
+
/**
|
|
52
|
+
* A plan's counts (D6).
|
|
53
|
+
*
|
|
54
|
+
* @param plan - The plan.
|
|
55
|
+
* @returns Creations, replacements, real changes, drift, destructions.
|
|
56
|
+
*/
|
|
57
|
+
export declare function planCounts_of(plan: InfraPlan): PlanCounts;
|
|
58
|
+
/**
|
|
59
|
+
* Whether a plan touches anything that exists, drift aside: what an apply refuses unless asked by name.
|
|
60
|
+
*
|
|
61
|
+
* @param counts - The plan's counts.
|
|
62
|
+
* @returns True when it replaces, changes or destroys.
|
|
63
|
+
*/
|
|
64
|
+
export declare function planCounts_alter(counts: PlanCounts): boolean;
|
|
65
|
+
/**
|
|
66
|
+
* A plan's counts in a line.
|
|
67
|
+
*
|
|
68
|
+
* @param counts - The counts.
|
|
69
|
+
* @returns `3 to create, 21 to replace (loadbalancers), 0 to change and 24 Oracle-Tags drift, 0 to destroy`.
|
|
70
|
+
*/
|
|
71
|
+
export declare function planCounts_words(counts: PlanCounts): string;
|
|
72
|
+
/** What every builder call is given to report with and to stop on. */
|
|
73
|
+
export interface BuildCall {
|
|
74
|
+
/** Writes a line to the step's log. */
|
|
75
|
+
readonly log: (line: string) => void;
|
|
76
|
+
/** Aborted when the operator asks the step to stop. */
|
|
77
|
+
readonly signal: AbortSignal;
|
|
78
|
+
}
|
|
79
|
+
/** The addresses an apply leaves for the DNS records. */
|
|
80
|
+
export interface InfraOutputs {
|
|
81
|
+
/** The API's load balancer address. */
|
|
82
|
+
apiIp: string;
|
|
83
|
+
/** The internal API's address. */
|
|
84
|
+
apiIntIp: string;
|
|
85
|
+
/** The applications' (`*.apps`) address. */
|
|
86
|
+
appsIp: string;
|
|
87
|
+
/** The stack's handle, for a later plan and the teardown. */
|
|
88
|
+
stackRef: string;
|
|
89
|
+
/** The platform manifests the stack made for the installer (OCI: its cloud controller and CSI driver). */
|
|
90
|
+
manifests: PlatformManifest[];
|
|
91
|
+
}
|
|
92
|
+
/** What a domain's teardown removes, beside its stack. */
|
|
93
|
+
export interface TeardownRequest {
|
|
94
|
+
readonly domain: string;
|
|
95
|
+
readonly region: string;
|
|
96
|
+
readonly compartmentId: string;
|
|
97
|
+
readonly baseDomain: string;
|
|
98
|
+
/** The stack whose resources a destroy job removes, when one was made. */
|
|
99
|
+
readonly stackRef?: string;
|
|
100
|
+
/** The discovery image and its link, when the iso step ran. */
|
|
101
|
+
readonly isoObject?: string;
|
|
102
|
+
readonly isoLinkId?: string;
|
|
103
|
+
/** Block volumes the cluster made that the stack never knew (its CSI claims). */
|
|
104
|
+
readonly volumeIds: ReadonlyArray<string>;
|
|
105
|
+
}
|
|
106
|
+
/** A cloud's build half. */
|
|
107
|
+
export interface CloudBuilder {
|
|
108
|
+
/** Its id (`oci`, `fake`). */
|
|
109
|
+
readonly id: string;
|
|
110
|
+
/** Checks the tenancy can take the domain: keys, limits, the tag namespace, the zone. */
|
|
111
|
+
preflight(request: {
|
|
112
|
+
domain: string;
|
|
113
|
+
spec: DomainSpec;
|
|
114
|
+
region: string;
|
|
115
|
+
baseDomain: string;
|
|
116
|
+
compartmentId: string;
|
|
117
|
+
}, call: BuildCall): Promise<PreflightCheck[]>;
|
|
118
|
+
/** Puts the discovery image where the machines boot from: its object, a link to it (a secret) and the link's end. */
|
|
119
|
+
iso_store(request: {
|
|
120
|
+
domain: string;
|
|
121
|
+
url: string;
|
|
122
|
+
region: string;
|
|
123
|
+
compartmentId: string;
|
|
124
|
+
}, call: BuildCall): Promise<{
|
|
125
|
+
object: string;
|
|
126
|
+
expires: string;
|
|
127
|
+
link: string;
|
|
128
|
+
linkId: string;
|
|
129
|
+
}>;
|
|
130
|
+
/** Plans the infrastructure: against the domain's stack when it has one (adopted, or a re-plan), else in a new one. */
|
|
131
|
+
infra_plan(request: {
|
|
132
|
+
domain: string;
|
|
133
|
+
spec: DomainSpec;
|
|
134
|
+
region: string;
|
|
135
|
+
isoObject: string;
|
|
136
|
+
stackRef?: string;
|
|
137
|
+
compartmentId?: string;
|
|
138
|
+
baseDomain?: string;
|
|
139
|
+
isoLink?: string;
|
|
140
|
+
}, call: BuildCall): Promise<InfraPlan>;
|
|
141
|
+
/** Applies a plan. Billing starts here. */
|
|
142
|
+
infra_apply(request: {
|
|
143
|
+
domain: string;
|
|
144
|
+
plan: InfraPlan;
|
|
145
|
+
region: string;
|
|
146
|
+
stackRef?: string;
|
|
147
|
+
}, call: BuildCall): Promise<InfraOutputs>;
|
|
148
|
+
/** Writes the cluster's records in its zone. */
|
|
149
|
+
dns_upsert(request: {
|
|
150
|
+
domain: string;
|
|
151
|
+
baseDomain: string;
|
|
152
|
+
outputs: InfraOutputs;
|
|
153
|
+
compartmentId: string;
|
|
154
|
+
region: string;
|
|
155
|
+
}, call: BuildCall): Promise<string[]>;
|
|
156
|
+
/** Takes in infrastructure built elsewhere: a stack with its variables and its Terraform state; returns the stack's handle. */
|
|
157
|
+
/** How many resources a stack's state holds: what a destroy job removes. */
|
|
158
|
+
stackResources_count?(request: {
|
|
159
|
+
region: string;
|
|
160
|
+
stackRef: string;
|
|
161
|
+
}): Promise<number>;
|
|
162
|
+
/** Removes what a domain built: the stack's resources (a destroy job), then its records, image, link and volumes. Returns what went, a line each. */
|
|
163
|
+
teardown_run?(request: TeardownRequest, call: BuildCall): Promise<string[]>;
|
|
164
|
+
stack_adopt?(request: {
|
|
165
|
+
domain: string;
|
|
166
|
+
region: string;
|
|
167
|
+
compartmentId: string;
|
|
168
|
+
variables: Record<string, string>;
|
|
169
|
+
state: Buffer;
|
|
170
|
+
stackVersion: string;
|
|
171
|
+
}, call: BuildCall): Promise<string>;
|
|
172
|
+
}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* A plan's counts (D6).
|
|
3
|
+
*
|
|
4
|
+
* @param plan - The plan.
|
|
5
|
+
* @returns Creations, replacements, real changes, drift, destructions.
|
|
6
|
+
*/
|
|
7
|
+
export function planCounts_of(plan) {
|
|
8
|
+
const rows = plan.rows;
|
|
9
|
+
const created = new Set(rows.filter((row) => row.action === 'create').map((row) => row.name));
|
|
10
|
+
const replaced = rows.filter((row) => row.action === 'destroy' && created.has(row.name));
|
|
11
|
+
const replacedNames = new Set(replaced.map((row) => row.name));
|
|
12
|
+
return {
|
|
13
|
+
create: rows.filter((row) => row.action === 'create' && !replacedNames.has(row.name)).length,
|
|
14
|
+
replace: replaced.length,
|
|
15
|
+
change: rows.filter((row) => row.action === 'change' && row.drift !== true).length,
|
|
16
|
+
drift: rows.filter((row) => row.action === 'change' && row.drift === true).length,
|
|
17
|
+
destroy: rows.filter((row) => row.action === 'destroy' && !replacedNames.has(row.name)).length,
|
|
18
|
+
replacedKinds: [...new Set(replaced.map((row) => row.kind))].sort(),
|
|
19
|
+
};
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* Whether a plan touches anything that exists, drift aside: what an apply refuses unless asked by name.
|
|
23
|
+
*
|
|
24
|
+
* @param counts - The plan's counts.
|
|
25
|
+
* @returns True when it replaces, changes or destroys.
|
|
26
|
+
*/
|
|
27
|
+
export function planCounts_alter(counts) {
|
|
28
|
+
return counts.replace > 0 || counts.change > 0 || counts.destroy > 0;
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* A plan's counts in a line.
|
|
32
|
+
*
|
|
33
|
+
* @param counts - The counts.
|
|
34
|
+
* @returns `3 to create, 21 to replace (loadbalancers), 0 to change and 24 Oracle-Tags drift, 0 to destroy`.
|
|
35
|
+
*/
|
|
36
|
+
export function planCounts_words(counts) {
|
|
37
|
+
const replace = counts.replace > 0 ? `, ${counts.replace} to replace (${counts.replacedKinds.join(', ')})` : '';
|
|
38
|
+
const drift = counts.drift > 0 ? ` and ${counts.drift} Oracle-Tags drift` : '';
|
|
39
|
+
return `${counts.create} to create${replace}, ${counts.change} to change${drift}, ${counts.destroy} to destroy`;
|
|
40
|
+
}
|
|
41
|
+
//# sourceMappingURL=builder.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"builder.js","sourceRoot":"","sources":["../../src/cloud/builder.ts"],"names":[],"mappings":"AAuDA;;;;;GAKG;AACH,MAAM,UAAU,aAAa,CAAC,IAAe;IAC3C,MAAM,IAAI,GAA2B,IAAI,CAAC,IAAI,CAAC;IAC/C,MAAM,OAAO,GAAgB,IAAI,GAAG,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,GAAY,EAAW,EAAE,CAAC,GAAG,CAAC,MAAM,KAAK,QAAQ,CAAC,CAAC,GAAG,CAAC,CAAC,GAAY,EAAU,EAAE,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC;IAC9I,MAAM,QAAQ,GAAc,IAAI,CAAC,MAAM,CAAC,CAAC,GAAY,EAAW,EAAE,CAAC,GAAG,CAAC,MAAM,KAAK,SAAS,IAAI,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC;IACtH,MAAM,aAAa,GAAgB,IAAI,GAAG,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,GAAY,EAAU,EAAE,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC;IAC7F,OAAO;QACL,MAAM,EAAE,IAAI,CAAC,MAAM,CAAC,CAAC,GAAY,EAAW,EAAE,CAAC,GAAG,CAAC,MAAM,KAAK,QAAQ,IAAI,CAAC,aAAa,CAAC,GAAG,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,MAAM;QAC9G,OAAO,EAAE,QAAQ,CAAC,MAAM;QACxB,MAAM,EAAE,IAAI,CAAC,MAAM,CAAC,CAAC,GAAY,EAAW,EAAE,CAAC,GAAG,CAAC,MAAM,KAAK,QAAQ,IAAI,GAAG,CAAC,KAAK,KAAK,IAAI,CAAC,CAAC,MAAM;QACpG,KAAK,EAAE,IAAI,CAAC,MAAM,CAAC,CAAC,GAAY,EAAW,EAAE,CAAC,GAAG,CAAC,MAAM,KAAK,QAAQ,IAAI,GAAG,CAAC,KAAK,KAAK,IAAI,CAAC,CAAC,MAAM;QACnG,OAAO,EAAE,IAAI,CAAC,MAAM,CAAC,CAAC,GAAY,EAAW,EAAE,CAAC,GAAG,CAAC,MAAM,KAAK,SAAS,IAAI,CAAC,aAAa,CAAC,GAAG,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,MAAM;QAChH,aAAa,EAAE,CAAC,GAAG,IAAI,GAAG,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,GAAY,EAAU,EAAE,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE;KACrF,CAAC;AACJ,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,gBAAgB,CAAC,MAAkB;IACjD,OAAO,MAAM,CAAC,OAAO,GAAG,CAAC,IAAI,MAAM,CAAC,MAAM,GAAG,CAAC,IAAI,MAAM,CAAC,OAAO,GAAG,CAAC,CAAC;AACvE,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,gBAAgB,CAAC,MAAkB;IACjD,MAAM,OAAO,GAAW,MAAM,CAAC,OAAO,GAAG,CAAC,CAAC,CAAC,CAAC,KAAK,MAAM,CAAC,OAAO,gBAAgB,MAAM,CAAC,aAAa,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC;IACxH,MAAM,KAAK,GAAW,MAAM,CAAC,KAAK,GAAG,CAAC,CAAC,CAAC,CAAC,QAAQ,MAAM,CAAC,KAAK,oBAAoB,CAAC,CAAC,CAAC,EAAE,CAAC;IACvF,OAAO,GAAG,MAAM,CAAC,MAAM,aAAa,OAAO,KAAK,MAAM,CAAC,MAAM,aAAa,KAAK,KAAK,MAAM,CAAC,OAAO,aAAa,CAAC;AAClH,CAAC"}
|