@git.zone/cli 2.22.0 → 2.24.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/dist_ts/00_commitinfo_data.js +1 -1
- package/dist_ts/mod_services/classes.dockercontainer.d.ts +92 -0
- package/dist_ts/mod_services/classes.dockercontainer.js +225 -6
- package/dist_ts/mod_services/classes.globalregistry.d.ts +10 -0
- package/dist_ts/mod_services/classes.globalregistry.js +23 -1
- package/dist_ts/mod_services/classes.serviceconfiguration.d.ts +39 -1
- package/dist_ts/mod_services/classes.serviceconfiguration.js +89 -22
- package/dist_ts/mod_services/classes.servicedatamarker.d.ts +93 -0
- package/dist_ts/mod_services/classes.servicedatamarker.js +166 -0
- package/dist_ts/mod_services/classes.servicemanager.d.ts +103 -3
- package/dist_ts/mod_services/classes.servicemanager.js +352 -100
- package/dist_ts/mod_services/classes.servicepruner.d.ts +102 -0
- package/dist_ts/mod_services/classes.servicepruner.js +410 -0
- package/dist_ts/mod_services/helpers.d.ts +15 -0
- package/dist_ts/mod_services/helpers.js +57 -1
- package/dist_ts/mod_services/index.js +307 -53
- package/package.json +4 -3
- package/readme.hints.md +88 -0
- package/readme.md +71 -5
- package/ts/00_commitinfo_data.ts +1 -1
- package/ts/mod_services/classes.dockercontainer.ts +269 -9
- package/ts/mod_services/classes.globalregistry.ts +27 -0
- package/ts/mod_services/classes.serviceconfiguration.ts +105 -24
- package/ts/mod_services/classes.servicedatamarker.ts +228 -0
- package/ts/mod_services/classes.servicemanager.ts +480 -117
- package/ts/mod_services/classes.servicepruner.ts +532 -0
- package/ts/mod_services/helpers.ts +60 -0
- package/ts/mod_services/index.ts +437 -58
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
*/
|
|
4
4
|
export const commitinfo = {
|
|
5
5
|
name: '@git.zone/cli',
|
|
6
|
-
version: '2.
|
|
6
|
+
version: '2.24.0',
|
|
7
7
|
description: 'A comprehensive CLI tool for enhancing and managing local development workflows with gitzone utilities, focusing on project setup, version control, code formatting, and template management.'
|
|
8
8
|
};
|
|
9
9
|
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiMDBfY29tbWl0aW5mb19kYXRhLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vdHMvMDBfY29tbWl0aW5mb19kYXRhLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBOztHQUVHO0FBQ0gsTUFBTSxDQUFDLE1BQU0sVUFBVSxHQUFHO0lBQ3hCLElBQUksRUFBRSxlQUFlO0lBQ3JCLE9BQU8sRUFBRSxRQUFRO0lBQ2pCLFdBQVcsRUFBRSwrTEFBK0w7Q0FDN00sQ0FBQSJ9
|
|
@@ -11,12 +11,42 @@ export interface IDockerRunOptions {
|
|
|
11
11
|
environment?: {
|
|
12
12
|
[key: string]: string;
|
|
13
13
|
};
|
|
14
|
+
labels?: {
|
|
15
|
+
[key: string]: string;
|
|
16
|
+
};
|
|
14
17
|
restart?: string;
|
|
15
18
|
command?: string;
|
|
16
19
|
}
|
|
20
|
+
/** Container facts needed to decide, safely, whether a container may be removed. */
|
|
21
|
+
export interface IContainerInspectInfo {
|
|
22
|
+
id: string;
|
|
23
|
+
name: string;
|
|
24
|
+
state: string;
|
|
25
|
+
running: boolean;
|
|
26
|
+
labels: {
|
|
27
|
+
[key: string]: string;
|
|
28
|
+
};
|
|
29
|
+
/** Resolved host-side sources of every bind mount. */
|
|
30
|
+
mountSources: string[];
|
|
31
|
+
}
|
|
32
|
+
/** Single-quote a value for safe interpolation into a bash command. */
|
|
33
|
+
export declare const shellQuote: (valueArg: string) => string;
|
|
17
34
|
export declare class DockerContainer {
|
|
18
35
|
private smartshell;
|
|
36
|
+
/**
|
|
37
|
+
* Wall-clock bound for docker queries and in-container commands.
|
|
38
|
+
*
|
|
39
|
+
* smartshell only arms a timeout when one is passed, so without this a wedged
|
|
40
|
+
* `docker exec` never settles and retry loops that look bounded ("30
|
|
41
|
+
* attempts") hang forever. Mirrors the `timeout Ns docker …` approach used by
|
|
42
|
+
* @git.zone/tsdocker.
|
|
43
|
+
*/
|
|
44
|
+
private queryTimeoutSeconds;
|
|
45
|
+
/** Longer bound for privileged cleanup, which may delete a large tree. */
|
|
46
|
+
private cleanupTimeoutSeconds;
|
|
19
47
|
constructor();
|
|
48
|
+
/** `docker` prefixed with a hard wall-clock bound. */
|
|
49
|
+
private bounded;
|
|
20
50
|
/**
|
|
21
51
|
* Check if Docker is installed and available
|
|
22
52
|
*/
|
|
@@ -41,10 +71,52 @@ export declare class DockerContainer {
|
|
|
41
71
|
* Run a new container
|
|
42
72
|
*/
|
|
43
73
|
run(options: IDockerRunOptions): Promise<boolean>;
|
|
74
|
+
/**
|
|
75
|
+
* Run a one-off command in a temporary container (docker run --rm)
|
|
76
|
+
*/
|
|
77
|
+
runOneOff(options: {
|
|
78
|
+
image: string;
|
|
79
|
+
command: string;
|
|
80
|
+
volumes?: {
|
|
81
|
+
[key: string]: string;
|
|
82
|
+
};
|
|
83
|
+
user?: string;
|
|
84
|
+
/** Shell used inside the container. `sh` is available in every service image. */
|
|
85
|
+
shell?: string;
|
|
86
|
+
}): Promise<boolean>;
|
|
87
|
+
/**
|
|
88
|
+
* True when an image is already present locally.
|
|
89
|
+
*/
|
|
90
|
+
imageExists(imageArg: string): Promise<boolean>;
|
|
91
|
+
/**
|
|
92
|
+
* Remove a service data directory, escalating to a root one-off container
|
|
93
|
+
* when the invoking user cannot delete the contents.
|
|
94
|
+
*
|
|
95
|
+
* Service containers write as their own uid (mongod as 999, MinIO as root)
|
|
96
|
+
* with restrictive modes, so a plain recursive delete only removes part of the
|
|
97
|
+
* tree. For MongoDB that left a half-deleted, corrupt WiredTiger dataset that
|
|
98
|
+
* crash-looped on the next start — so a partial delete is worse than none.
|
|
99
|
+
* This either fully removes the directory or throws.
|
|
100
|
+
*
|
|
101
|
+
* The one-off container mounts only the target directory, so `rm -rf` inside
|
|
102
|
+
* it cannot reach anything else on the host.
|
|
103
|
+
*/
|
|
104
|
+
removeDataDirectory(hostPathArg: string, imageArg: string): Promise<void>;
|
|
44
105
|
/**
|
|
45
106
|
* Execute a command in a running container
|
|
46
107
|
*/
|
|
47
108
|
exec(containerName: string, command: string): Promise<string>;
|
|
109
|
+
/**
|
|
110
|
+
* Execute a command in a running container, returning stdout and stderr
|
|
111
|
+
* together along with the exit code.
|
|
112
|
+
*
|
|
113
|
+
* `exec` discards output on a non-zero exit and drops stderr entirely, which
|
|
114
|
+
* hides diagnostics that a caller may need to branch on.
|
|
115
|
+
*/
|
|
116
|
+
execCombined(containerName: string, command: string): Promise<{
|
|
117
|
+
exitCode: number;
|
|
118
|
+
output: string;
|
|
119
|
+
}>;
|
|
48
120
|
/**
|
|
49
121
|
* Get container logs
|
|
50
122
|
*/
|
|
@@ -71,4 +143,24 @@ export declare class DockerContainer {
|
|
|
71
143
|
getPortMappings(containerName: string): Promise<{
|
|
72
144
|
[key: string]: string;
|
|
73
145
|
} | null>;
|
|
146
|
+
/**
|
|
147
|
+
* Run a `docker ps` query and return matching container ids.
|
|
148
|
+
*
|
|
149
|
+
* Throws when Docker itself fails, so callers can fail closed instead of
|
|
150
|
+
* mistaking an unreachable daemon for "no containers exist".
|
|
151
|
+
*/
|
|
152
|
+
listIds(filterArgs: string[], includeStopped?: boolean): Promise<string[]>;
|
|
153
|
+
/**
|
|
154
|
+
* Inspect many containers at once and normalise the parts prune relies on.
|
|
155
|
+
* Throws on Docker failure so ambiguity never reads as absence.
|
|
156
|
+
*/
|
|
157
|
+
inspectMany(idsArg: string[]): Promise<IContainerInspectInfo[]>;
|
|
158
|
+
/**
|
|
159
|
+
* Resolved host paths bind-mounted by every *currently running* container on
|
|
160
|
+
* the daemon, regardless of which tool created it.
|
|
161
|
+
*
|
|
162
|
+
* This is the primitive that makes data reclamation safe: a directory that is
|
|
163
|
+
* mounted by anything running is never a deletion candidate.
|
|
164
|
+
*/
|
|
165
|
+
listRunningMountSources(): Promise<string[]>;
|
|
74
166
|
}
|
|
@@ -1,19 +1,37 @@
|
|
|
1
1
|
import * as plugins from './mod.plugins.js';
|
|
2
2
|
import * as helpers from './helpers.js';
|
|
3
3
|
import { logger } from '../gitzone.logging.js';
|
|
4
|
+
/** Single-quote a value for safe interpolation into a bash command. */
|
|
5
|
+
export const shellQuote = (valueArg) => `'${valueArg.replace(/'/g, `'"'"'`)}'`;
|
|
4
6
|
export class DockerContainer {
|
|
5
7
|
smartshell;
|
|
8
|
+
/**
|
|
9
|
+
* Wall-clock bound for docker queries and in-container commands.
|
|
10
|
+
*
|
|
11
|
+
* smartshell only arms a timeout when one is passed, so without this a wedged
|
|
12
|
+
* `docker exec` never settles and retry loops that look bounded ("30
|
|
13
|
+
* attempts") hang forever. Mirrors the `timeout Ns docker …` approach used by
|
|
14
|
+
* @git.zone/tsdocker.
|
|
15
|
+
*/
|
|
16
|
+
queryTimeoutSeconds = 60;
|
|
17
|
+
/** Longer bound for privileged cleanup, which may delete a large tree. */
|
|
18
|
+
cleanupTimeoutSeconds = 600;
|
|
6
19
|
constructor() {
|
|
7
20
|
this.smartshell = new plugins.smartshell.Smartshell({
|
|
8
21
|
executor: 'bash',
|
|
9
22
|
});
|
|
10
23
|
}
|
|
24
|
+
/** `docker` prefixed with a hard wall-clock bound. */
|
|
25
|
+
bounded(seconds) {
|
|
26
|
+
return `timeout ${seconds}s docker`;
|
|
27
|
+
}
|
|
11
28
|
/**
|
|
12
29
|
* Check if Docker is installed and available
|
|
13
30
|
*/
|
|
14
31
|
async checkDocker() {
|
|
15
32
|
try {
|
|
16
|
-
|
|
33
|
+
// Silent: this must not print to stdout, which would corrupt --json output.
|
|
34
|
+
const result = await this.smartshell.execSilent('docker --version');
|
|
17
35
|
return result.exitCode === 0;
|
|
18
36
|
}
|
|
19
37
|
catch (error) {
|
|
@@ -94,13 +112,20 @@ export class DockerContainer {
|
|
|
94
112
|
// Add volumes
|
|
95
113
|
if (options.volumes) {
|
|
96
114
|
for (const [hostPath, containerPath] of Object.entries(options.volumes)) {
|
|
97
|
-
command += ` -v
|
|
115
|
+
command += ` -v ${shellQuote(`${hostPath}:${containerPath}`)}`;
|
|
98
116
|
}
|
|
99
117
|
}
|
|
100
|
-
// Add environment variables
|
|
118
|
+
// Add environment variables. Values come from .nogit/env.json, which is
|
|
119
|
+
// user-editable, so they must not be interpolated unquoted.
|
|
101
120
|
if (options.environment) {
|
|
102
121
|
for (const [key, value] of Object.entries(options.environment)) {
|
|
103
|
-
command += ` -e ${key}
|
|
122
|
+
command += ` -e ${shellQuote(`${key}=${value}`)}`;
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
// Add labels (used to identify tool-owned containers during prune)
|
|
126
|
+
if (options.labels) {
|
|
127
|
+
for (const [key, value] of Object.entries(options.labels)) {
|
|
128
|
+
command += ` --label ${shellQuote(`${key}=${value}`)}`;
|
|
104
129
|
}
|
|
105
130
|
}
|
|
106
131
|
// Add restart policy
|
|
@@ -123,12 +148,109 @@ export class DockerContainer {
|
|
|
123
148
|
return false;
|
|
124
149
|
}
|
|
125
150
|
}
|
|
151
|
+
/**
|
|
152
|
+
* Run a one-off command in a temporary container (docker run --rm)
|
|
153
|
+
*/
|
|
154
|
+
async runOneOff(options) {
|
|
155
|
+
let command = `${this.bounded(this.cleanupTimeoutSeconds)} run --rm`;
|
|
156
|
+
if (options.user) {
|
|
157
|
+
command += ` --user ${shellQuote(options.user)}`;
|
|
158
|
+
}
|
|
159
|
+
if (options.volumes) {
|
|
160
|
+
for (const [hostPath, containerPath] of Object.entries(options.volumes)) {
|
|
161
|
+
// Quoted: this path reaches a root `rm -rf`, so a project directory
|
|
162
|
+
// containing `$(...)`, a backtick or a quote must not reach the shell
|
|
163
|
+
// unescaped. The path allowlist constrains shape, not metacharacters.
|
|
164
|
+
command += ` -v ${shellQuote(`${hostPath}:${containerPath}`)}`;
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
// The image entrypoint must be bypassed: service images start their daemon.
|
|
168
|
+
command += ` --entrypoint ${shellQuote(options.shell || 'bash')} ${shellQuote(options.image)}`;
|
|
169
|
+
command += ` -c ${shellQuote(options.command)}`;
|
|
170
|
+
try {
|
|
171
|
+
const result = await this.smartshell.exec(command);
|
|
172
|
+
return result.exitCode === 0;
|
|
173
|
+
}
|
|
174
|
+
catch (error) {
|
|
175
|
+
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
176
|
+
logger.log('error', `Failed to run one-off container: ${errorMessage}`);
|
|
177
|
+
return false;
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
/**
|
|
181
|
+
* True when an image is already present locally.
|
|
182
|
+
*/
|
|
183
|
+
async imageExists(imageArg) {
|
|
184
|
+
try {
|
|
185
|
+
const result = await this.smartshell.execSilent(`${this.bounded(this.queryTimeoutSeconds)} image inspect ${shellQuote(imageArg)}`);
|
|
186
|
+
return result.exitCode === 0;
|
|
187
|
+
}
|
|
188
|
+
catch (error) {
|
|
189
|
+
return false;
|
|
190
|
+
}
|
|
191
|
+
}
|
|
192
|
+
/**
|
|
193
|
+
* Remove a service data directory, escalating to a root one-off container
|
|
194
|
+
* when the invoking user cannot delete the contents.
|
|
195
|
+
*
|
|
196
|
+
* Service containers write as their own uid (mongod as 999, MinIO as root)
|
|
197
|
+
* with restrictive modes, so a plain recursive delete only removes part of the
|
|
198
|
+
* tree. For MongoDB that left a half-deleted, corrupt WiredTiger dataset that
|
|
199
|
+
* crash-looped on the next start — so a partial delete is worse than none.
|
|
200
|
+
* This either fully removes the directory or throws.
|
|
201
|
+
*
|
|
202
|
+
* The one-off container mounts only the target directory, so `rm -rf` inside
|
|
203
|
+
* it cannot reach anything else on the host.
|
|
204
|
+
*/
|
|
205
|
+
async removeDataDirectory(hostPathArg, imageArg) {
|
|
206
|
+
const hostPath = plugins.path.resolve(hostPathArg);
|
|
207
|
+
if (!(await plugins.smartfs.directory(hostPath).exists())) {
|
|
208
|
+
return;
|
|
209
|
+
}
|
|
210
|
+
// Fast path: the current user may already own everything.
|
|
211
|
+
try {
|
|
212
|
+
await plugins.smartfs.directory(hostPath).recursive().delete();
|
|
213
|
+
}
|
|
214
|
+
catch (error) {
|
|
215
|
+
// fall through to privileged removal
|
|
216
|
+
}
|
|
217
|
+
if (!(await plugins.smartfs.directory(hostPath).exists())) {
|
|
218
|
+
return;
|
|
219
|
+
}
|
|
220
|
+
if (!(await this.imageExists(imageArg))) {
|
|
221
|
+
throw new Error(`Cannot remove ${hostPath}: its contents belong to the container user and image ` +
|
|
222
|
+
`${imageArg} is not available locally to perform a privileged cleanup. ` +
|
|
223
|
+
`Pull ${imageArg} and retry, or remove the directory manually as root.`);
|
|
224
|
+
}
|
|
225
|
+
// Empty the mounted directory from inside a root container, then remove the
|
|
226
|
+
// now-empty directory from the host.
|
|
227
|
+
const emptied = await this.runOneOff({
|
|
228
|
+
image: imageArg,
|
|
229
|
+
shell: 'sh',
|
|
230
|
+
command: 'rm -rf /gitzone-target/..?* /gitzone-target/.[!.]* /gitzone-target/*',
|
|
231
|
+
volumes: { [hostPath]: '/gitzone-target' },
|
|
232
|
+
user: '0',
|
|
233
|
+
});
|
|
234
|
+
if (!emptied) {
|
|
235
|
+
throw new Error(`Privileged cleanup of ${hostPath} failed`);
|
|
236
|
+
}
|
|
237
|
+
try {
|
|
238
|
+
await plugins.smartfs.directory(hostPath).recursive().delete();
|
|
239
|
+
}
|
|
240
|
+
catch (error) {
|
|
241
|
+
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
242
|
+
throw new Error(`Could not remove ${hostPath} after privileged cleanup: ${errorMessage}`);
|
|
243
|
+
}
|
|
244
|
+
if (await plugins.smartfs.directory(hostPath).exists()) {
|
|
245
|
+
throw new Error(`Refusing to report success: ${hostPath} still exists`);
|
|
246
|
+
}
|
|
247
|
+
}
|
|
126
248
|
/**
|
|
127
249
|
* Execute a command in a running container
|
|
128
250
|
*/
|
|
129
251
|
async exec(containerName, command) {
|
|
130
252
|
try {
|
|
131
|
-
const result = await this.smartshell.exec(
|
|
253
|
+
const result = await this.smartshell.exec(`${this.bounded(this.queryTimeoutSeconds)} exec ${containerName} ${command}`);
|
|
132
254
|
if (result.exitCode === 0) {
|
|
133
255
|
return result.stdout;
|
|
134
256
|
}
|
|
@@ -138,6 +260,23 @@ export class DockerContainer {
|
|
|
138
260
|
return '';
|
|
139
261
|
}
|
|
140
262
|
}
|
|
263
|
+
/**
|
|
264
|
+
* Execute a command in a running container, returning stdout and stderr
|
|
265
|
+
* together along with the exit code.
|
|
266
|
+
*
|
|
267
|
+
* `exec` discards output on a non-zero exit and drops stderr entirely, which
|
|
268
|
+
* hides diagnostics that a caller may need to branch on.
|
|
269
|
+
*/
|
|
270
|
+
async execCombined(containerName, command) {
|
|
271
|
+
try {
|
|
272
|
+
const result = await this.smartshell.execSilent(`${this.bounded(this.queryTimeoutSeconds)} exec ${containerName} ${command} 2>&1`);
|
|
273
|
+
return { exitCode: result.exitCode, output: result.stdout || '' };
|
|
274
|
+
}
|
|
275
|
+
catch (error) {
|
|
276
|
+
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
277
|
+
return { exitCode: -1, output: errorMessage };
|
|
278
|
+
}
|
|
279
|
+
}
|
|
141
280
|
/**
|
|
142
281
|
* Get container logs
|
|
143
282
|
*/
|
|
@@ -224,5 +363,85 @@ export class DockerContainer {
|
|
|
224
363
|
return null;
|
|
225
364
|
}
|
|
226
365
|
}
|
|
366
|
+
/**
|
|
367
|
+
* Run a `docker ps` query and return matching container ids.
|
|
368
|
+
*
|
|
369
|
+
* Throws when Docker itself fails, so callers can fail closed instead of
|
|
370
|
+
* mistaking an unreachable daemon for "no containers exist".
|
|
371
|
+
*/
|
|
372
|
+
async listIds(filterArgs, includeStopped = true) {
|
|
373
|
+
const filters = filterArgs.map((filter) => `--filter ${shellQuote(filter)}`).join(' ');
|
|
374
|
+
const allFlag = includeStopped ? '-a' : '';
|
|
375
|
+
const result = await this.smartshell.execSilent(`${this.bounded(this.queryTimeoutSeconds)} ps ${allFlag} ${filters} --format '{{.ID}}'`);
|
|
376
|
+
if (result.exitCode !== 0) {
|
|
377
|
+
throw new Error(result.stderr || result.stdout || 'docker ps failed');
|
|
378
|
+
}
|
|
379
|
+
if (!result.stdout.trim()) {
|
|
380
|
+
return [];
|
|
381
|
+
}
|
|
382
|
+
return result.stdout
|
|
383
|
+
.trim()
|
|
384
|
+
.split(/\r?\n/)
|
|
385
|
+
.map((line) => line.trim())
|
|
386
|
+
.filter(Boolean);
|
|
387
|
+
}
|
|
388
|
+
/**
|
|
389
|
+
* Inspect many containers at once and normalise the parts prune relies on.
|
|
390
|
+
* Throws on Docker failure so ambiguity never reads as absence.
|
|
391
|
+
*/
|
|
392
|
+
async inspectMany(idsArg) {
|
|
393
|
+
if (idsArg.length === 0) {
|
|
394
|
+
return [];
|
|
395
|
+
}
|
|
396
|
+
const result = await this.smartshell.execSilent(`${this.bounded(this.queryTimeoutSeconds)} inspect ${idsArg.map((id) => shellQuote(id)).join(' ')}`);
|
|
397
|
+
if (result.exitCode !== 0) {
|
|
398
|
+
throw new Error(result.stderr || result.stdout || 'docker inspect failed');
|
|
399
|
+
}
|
|
400
|
+
let parsed;
|
|
401
|
+
try {
|
|
402
|
+
parsed = JSON.parse(result.stdout);
|
|
403
|
+
}
|
|
404
|
+
catch (error) {
|
|
405
|
+
throw new Error('docker inspect returned unparseable output');
|
|
406
|
+
}
|
|
407
|
+
if (!Array.isArray(parsed)) {
|
|
408
|
+
throw new Error('docker inspect returned unexpected output');
|
|
409
|
+
}
|
|
410
|
+
return parsed.map((container) => {
|
|
411
|
+
const labels = (container?.Config?.Labels || {});
|
|
412
|
+
const mountSources = [];
|
|
413
|
+
for (const mount of container?.Mounts || []) {
|
|
414
|
+
if (mount?.Source) {
|
|
415
|
+
mountSources.push(plugins.path.resolve(mount.Source));
|
|
416
|
+
}
|
|
417
|
+
}
|
|
418
|
+
return {
|
|
419
|
+
id: String(container?.Id || ''),
|
|
420
|
+
name: String(container?.Name || '').replace(/^\//, ''),
|
|
421
|
+
state: String(container?.State?.Status || 'unknown'),
|
|
422
|
+
running: container?.State?.Running === true,
|
|
423
|
+
labels,
|
|
424
|
+
mountSources,
|
|
425
|
+
};
|
|
426
|
+
});
|
|
427
|
+
}
|
|
428
|
+
/**
|
|
429
|
+
* Resolved host paths bind-mounted by every *currently running* container on
|
|
430
|
+
* the daemon, regardless of which tool created it.
|
|
431
|
+
*
|
|
432
|
+
* This is the primitive that makes data reclamation safe: a directory that is
|
|
433
|
+
* mounted by anything running is never a deletion candidate.
|
|
434
|
+
*/
|
|
435
|
+
async listRunningMountSources() {
|
|
436
|
+
const ids = await this.listIds([], false);
|
|
437
|
+
const containers = await this.inspectMany(ids);
|
|
438
|
+
const sources = new Set();
|
|
439
|
+
for (const container of containers) {
|
|
440
|
+
for (const source of container.mountSources) {
|
|
441
|
+
sources.add(source);
|
|
442
|
+
}
|
|
443
|
+
}
|
|
444
|
+
return [...sources];
|
|
445
|
+
}
|
|
227
446
|
}
|
|
228
|
-
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY2xhc3Nlcy5kb2NrZXJjb250YWluZXIuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi90cy9tb2Rfc2VydmljZXMvY2xhc3Nlcy5kb2NrZXJjb250YWluZXIudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxLQUFLLE9BQU8sTUFBTSxrQkFBa0IsQ0FBQztBQUM1QyxPQUFPLEtBQUssT0FBTyxNQUFNLGNBQWMsQ0FBQztBQUN4QyxPQUFPLEVBQUUsTUFBTSxFQUFFLE1BQU0sdUJBQXVCLENBQUM7QUFjL0MsTUFBTSxPQUFPLGVBQWU7SUFDbEIsVUFBVSxDQUFnQztJQUVsRDtRQUNFLElBQUksQ0FBQyxVQUFVLEdBQUcsSUFBSSxPQUFPLENBQUMsVUFBVSxDQUFDLFVBQVUsQ0FBQztZQUNsRCxRQUFRLEVBQUUsTUFBTTtTQUNqQixDQUFDLENBQUM7SUFDTCxDQUFDO0lBRUQ7O09BRUc7SUFDSSxLQUFLLENBQUMsV0FBVztRQUN0QixJQUFJLENBQUM7WUFDSCxNQUFNLE1BQU0sR0FBRyxNQUFNLElBQUksQ0FBQyxVQUFVLENBQUMsSUFBSSxDQUFDLGtCQUFrQixDQUFDLENBQUM7WUFDOUQsT0FBTyxNQUFNLENBQUMsUUFBUSxLQUFLLENBQUMsQ0FBQztRQUMvQixDQUFDO1FBQUMsT0FBTyxLQUFLLEVBQUUsQ0FBQztZQUNmLE9BQU8sS0FBSyxDQUFDO1FBQ2YsQ0FBQztJQUNILENBQUM7SUFFRDs7T0FFRztJQUNJLEtBQUssQ0FBQyxTQUFTLENBQUMsYUFBcUI7UUFDMUMsSUFBSSxDQUFDO1lBQ0gsbUJBQW1CO1lBQ25CLE1BQU0sYUFBYSxHQUFHLE1BQU0sSUFBSSxDQUFDLFVBQVUsQ0FBQyxJQUFJLENBQzlDLCtDQUErQyxhQUFhLElBQUksQ0FDakUsQ0FBQztZQUVGLElBQUksYUFBYSxDQUFDLFFBQVEsS0FBSyxDQUFDLEVBQUUsQ0FBQztnQkFDakMsT0FBTyxTQUFTLENBQUM7WUFDbkIsQ0FBQztZQUVELDhCQUE4QjtZ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
|
|
447
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY2xhc3Nlcy5kb2NrZXJjb250YWluZXIuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi90cy9tb2Rfc2VydmljZXMvY2xhc3Nlcy5kb2NrZXJjb250YWluZXIudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxLQUFLLE9BQU8sTUFBTSxrQkFBa0IsQ0FBQztBQUM1QyxPQUFPLEtBQUssT0FBTyxNQUFNLGNBQWMsQ0FBQztBQUN4QyxPQUFPLEVBQUUsTUFBTSxFQUFFLE1BQU0sdUJBQXVCLENBQUM7QUEwQi9DLHVFQUF1RTtBQUN2RSxNQUFNLENBQUMsTUFBTSxVQUFVLEdBQUcsQ0FBQyxRQUFnQixFQUFVLEVBQUUsQ0FBQyxJQUFJLFFBQVEsQ0FBQyxPQUFPLENBQUMsSUFBSSxFQUFFLE9BQU8sQ0FBQyxHQUFHLENBQUM7QUFFL0YsTUFBTSxPQUFPLGVBQWU7SUFDbEIsVUFBVSxDQUFnQztJQUNsRDs7Ozs7OztPQU9HO0lBQ0ssbUJBQW1CLEdBQUcsRUFBRSxDQUFDO0lBQ2pDLDBFQUEwRTtJQUNsRSxxQkFBcUIsR0FBRyxHQUFHLENBQUM7SUFFcEM7UUFDRSxJQUFJLENBQUMsVUFBVSxHQUFHLElBQUksT0FBTyxDQUFDLFVBQVUsQ0FBQyxVQUFVLENBQUM7WUFDbEQsUUFBUSxFQUFFLE1BQU07U0FDakIsQ0FBQyxDQUFDO0lBQ0wsQ0FBQztJQUVELHNEQUFzRDtJQUM5QyxPQUFPLENBQUMsT0FBZTtRQUM3QixPQUFPLFdBQVcsT0FBTyxVQUFVLENBQUM7SUFDdEMsQ0FBQztJQUVEOztPQUVHO0lBQ0ksS0FBSyxDQUFDLFdBQVc7UUFDdEIsSUFBSSxDQUFDO1lBQ0gsNEVBQTRFO1lBQzVFLE1BQU0sTUFBTSxHQUFHLE1BQU0sSUFBSSxDQUFDLFVBQVUsQ0FBQyxVQUFVLENBQUMsa0JBQWtCLENBQUMsQ0FBQztZQUNwRSxPQUFPLE1BQU0sQ0FBQyxRQUFRLEtBQUssQ0FBQyxDQUFDO1FBQy9CLENBQUM7UUFBQyxPQUFPLEtB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
|
|
@@ -70,6 +70,16 @@ export declare class GlobalRegistry {
|
|
|
70
70
|
stopped: string[];
|
|
71
71
|
failed: string[];
|
|
72
72
|
}>;
|
|
73
|
+
/**
|
|
74
|
+
* Cheap staleness summary for a non-blocking hint after ordinary commands.
|
|
75
|
+
*
|
|
76
|
+
* Deliberately filesystem-only: no Docker calls and no directory sizing, so
|
|
77
|
+
* it stays fast enough to run after every `start` or `status`.
|
|
78
|
+
*/
|
|
79
|
+
getStaleSummary(staleDaysArg: number): Promise<{
|
|
80
|
+
orphaned: number;
|
|
81
|
+
stale: number;
|
|
82
|
+
}>;
|
|
73
83
|
/**
|
|
74
84
|
* Remove stale registry entries (projects that no longer exist on disk)
|
|
75
85
|
*/
|
|
@@ -116,6 +116,28 @@ export class GlobalRegistry {
|
|
|
116
116
|
}
|
|
117
117
|
return { stopped, failed };
|
|
118
118
|
}
|
|
119
|
+
/**
|
|
120
|
+
* Cheap staleness summary for a non-blocking hint after ordinary commands.
|
|
121
|
+
*
|
|
122
|
+
* Deliberately filesystem-only: no Docker calls and no directory sizing, so
|
|
123
|
+
* it stays fast enough to run after every `start` or `status`.
|
|
124
|
+
*/
|
|
125
|
+
async getStaleSummary(staleDaysArg) {
|
|
126
|
+
const projects = await this.getAllProjects();
|
|
127
|
+
const thresholdMs = staleDaysArg * 24 * 60 * 60 * 1000;
|
|
128
|
+
let orphaned = 0;
|
|
129
|
+
let stale = 0;
|
|
130
|
+
for (const [projectPath, project] of Object.entries(projects)) {
|
|
131
|
+
if (!(await plugins.smartfs.directory(projectPath).exists())) {
|
|
132
|
+
orphaned++;
|
|
133
|
+
continue;
|
|
134
|
+
}
|
|
135
|
+
if (Date.now() - project.lastActive > thresholdMs) {
|
|
136
|
+
stale++;
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
return { orphaned, stale };
|
|
140
|
+
}
|
|
119
141
|
/**
|
|
120
142
|
* Remove stale registry entries (projects that no longer exist on disk)
|
|
121
143
|
*/
|
|
@@ -132,4 +154,4 @@ export class GlobalRegistry {
|
|
|
132
154
|
return removed;
|
|
133
155
|
}
|
|
134
156
|
}
|
|
135
|
-
//# sourceMappingURL=data:application/json;base64,
|
|
157
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY2xhc3Nlcy5nbG9iYWxyZWdpc3RyeS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3RzL21vZF9zZXJ2aWNlcy9jbGFzc2VzLmdsb2JhbHJlZ2lzdHJ5LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sS0FBSyxPQUFPLE1BQU0sZUFBZSxDQUFDO0FBQ3pDLE9BQU8sRUFBRSxlQUFlLEVBQUUsTUFBTSw4QkFBOEIsQ0FBQztBQUMvRCxPQUFPLEVBQUUsTUFBTSxFQUFFLE1BQU0sdUJBQXVCLENBQUM7QUF3Qi9DLE1BQU0sT0FBTyxjQUFjO0lBQ2pCLE1BQU0sQ0FBQyxRQUFRLEdBQTBCLElBQUksQ0FBQztJQUM5QyxPQUFPLENBQXlEO0lBQ2hFLE1BQU0sQ0FBa0I7SUFFaEM7UUFDRSxJQUFJLENBQUMsT0FBTyxHQUFHLElBQUksT0FBTyxDQUFDLFdBQVcsQ0FBQyxhQUFhLENBQUM7WUFDbkQsT0FBTyxFQUFFLGFBQWE7WUFDdEIsV0FBVyxFQUFFLGtCQUFrQjtTQUNoQyxDQUFDLENBQUM7UUFDSCxJQUFJLENBQUMsTUFBTSxHQUFHLElBQUksZUFBZSxFQUFFLENBQUM7SUFDdEMsQ0FBQztJQUVEOztPQUVHO0lBQ0ksTUFBTSxDQUFDLFdBQVc7UUFDdkIsSUFBSSxDQUFDLGNBQWMsQ0FBQyxRQUFRLEVBQUUsQ0FBQztZQUM3QixjQUFjLENBQUMsUUFBUSxHQUFHLElBQUksY0FBYyxFQUFFLENBQUM7UUFDakQsQ0FBQztRQUNELE9BQU8sY0FBYyxDQUFDLFFBQVEsQ0FBQztJQUNqQyxDQUFDO0lBRUQ7O09BRUc7SUFDSSxLQUFLLENBQUMsZUFBZSxDQUFDLElBQTRDO1FBQ3ZFLE1BQU0sT0FBTyxHQUFHLE1BQU0sSUFBSSxDQUFDLE9BQU8sQ0FBQyxPQUFPLEVBQUUsQ0FBQztRQUM3QyxNQUFNLFFBQVEsR0FBRyxPQUFPLENBQUMsUUFBUSxJQUFJLEVBQUUsQ0FBQztRQUV4QyxRQUFRLENBQUMsSUFBSSxDQUFDLFdBQVcs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
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
export declare const isLocalMongoHost: (hostArg: string) => boolean;
|
|
1
2
|
export interface IServiceConfig {
|
|
2
3
|
PROJECT_NAME: string;
|
|
3
4
|
MONGODB_HOST: string;
|
|
@@ -6,6 +7,12 @@ export interface IServiceConfig {
|
|
|
6
7
|
MONGODB_USER: string;
|
|
7
8
|
MONGODB_PASS: string;
|
|
8
9
|
MONGODB_URL: string;
|
|
10
|
+
/**
|
|
11
|
+
* When false, mongod runs without authentication and is published on
|
|
12
|
+
* loopback only. Opt-in, for runtimes whose `node:crypto` cannot complete a
|
|
13
|
+
* SCRAM handshake (notably Deno). Defaults to true.
|
|
14
|
+
*/
|
|
15
|
+
MONGODB_AUTH_ENABLED: boolean;
|
|
9
16
|
S3_HOST: string;
|
|
10
17
|
S3_PORT: string;
|
|
11
18
|
S3_CONSOLE_PORT: string;
|
|
@@ -33,6 +40,34 @@ export declare class ServiceConfiguration {
|
|
|
33
40
|
* Get the current configuration
|
|
34
41
|
*/
|
|
35
42
|
getConfig(): IServiceConfig;
|
|
43
|
+
/**
|
|
44
|
+
* Whether mongod should enforce authentication. Defaults to true; only an
|
|
45
|
+
* explicit `false` in `.nogit/env.json` disables it.
|
|
46
|
+
*/
|
|
47
|
+
isMongoAuthEnabled(): boolean;
|
|
48
|
+
/**
|
|
49
|
+
* Build MONGODB_URL from the current fields.
|
|
50
|
+
*
|
|
51
|
+
* Credentials are omitted entirely when auth is disabled, so the stored URL
|
|
52
|
+
* never advertises a username that mongod would not accept.
|
|
53
|
+
*/
|
|
54
|
+
private buildMongoUrl;
|
|
55
|
+
/**
|
|
56
|
+
* Recompute every derived field from the primitive ones.
|
|
57
|
+
*/
|
|
58
|
+
private updateDerivedFields;
|
|
59
|
+
/**
|
|
60
|
+
* Refuse an unauthenticated mongod that would be reachable off-host.
|
|
61
|
+
*
|
|
62
|
+
* Disabling auth is only defensible while the database is bound to loopback.
|
|
63
|
+
* Rather than trusting the operator to keep MONGODB_HOST local, this fails
|
|
64
|
+
* closed on the combination.
|
|
65
|
+
*/
|
|
66
|
+
assertMongoExposureIsSafe(): void;
|
|
67
|
+
/**
|
|
68
|
+
* Persist the MongoDB auth mode and recompute derived fields.
|
|
69
|
+
*/
|
|
70
|
+
setMongoAuthEnabled(enabledArg: boolean): Promise<void>;
|
|
36
71
|
/**
|
|
37
72
|
* Save the configuration to file
|
|
38
73
|
*/
|
|
@@ -70,7 +105,10 @@ export declare class ServiceConfiguration {
|
|
|
70
105
|
elasticsearch: string;
|
|
71
106
|
};
|
|
72
107
|
/**
|
|
73
|
-
* Get data directories
|
|
108
|
+
* Get data directories.
|
|
109
|
+
*
|
|
110
|
+
* Derived through `getServiceDataDirectory` so that creation here and
|
|
111
|
+
* reclamation in `ServicePruner` can never disagree about the shape.
|
|
74
112
|
*/
|
|
75
113
|
getDataDirectories(): {
|
|
76
114
|
mongo: string;
|