@git.zone/cli 2.23.0 → 2.25.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/gitzone.cli.js +11 -2
- package/dist_ts/mod_services/classes.dockercontainer.d.ts +81 -0
- package/dist_ts/mod_services/classes.dockercontainer.js +205 -10
- 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 +52 -1
- package/dist_ts/mod_services/classes.serviceconfiguration.js +116 -20
- 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 +91 -5
- package/dist_ts/mod_services/classes.servicemanager.js +274 -64
- package/dist_ts/mod_services/classes.serviceoptions.d.ts +58 -0
- package/dist_ts/mod_services/classes.serviceoptions.js +93 -0
- 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/dist_ts/mod_tools/classes.packagemanager.d.ts +13 -0
- package/dist_ts/mod_tools/classes.packagemanager.js +42 -1
- package/dist_ts/mod_tools/index.js +4 -1
- package/package.json +3 -2
- package/readme.hints.md +105 -0
- package/readme.md +123 -5
- package/ts/00_commitinfo_data.ts +1 -1
- package/ts/gitzone.cli.ts +10 -0
- package/ts/mod_services/classes.dockercontainer.ts +244 -13
- package/ts/mod_services/classes.globalregistry.ts +27 -0
- package/ts/mod_services/classes.serviceconfiguration.ts +148 -27
- package/ts/mod_services/classes.servicedatamarker.ts +228 -0
- package/ts/mod_services/classes.servicemanager.ts +394 -72
- package/ts/mod_services/classes.serviceoptions.ts +135 -0
- 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
- package/ts/mod_tools/classes.packagemanager.ts +54 -0
- package/ts/mod_tools/index.ts +5 -0
|
@@ -0,0 +1,166 @@
|
|
|
1
|
+
import * as plugins from './mod.plugins.js';
|
|
2
|
+
export const serviceNames = ['mongodb', 'minio', 'elasticsearch'];
|
|
3
|
+
/** Owner recorded in markers and container labels. */
|
|
4
|
+
export const serviceDataOwner = '@git.zone/cli';
|
|
5
|
+
/** Value of the `git.zone.tool` label on containers created by `gitzone services`. */
|
|
6
|
+
export const serviceToolLabel = 'gitzone-services';
|
|
7
|
+
/** Marker file name, stored in `<projectPath>/.nogit/`. */
|
|
8
|
+
export const serviceDataMarkerFile = '.gitzone-services.json';
|
|
9
|
+
/**
|
|
10
|
+
* Directory basename used below `.nogit/` for each service's bind-mounted data.
|
|
11
|
+
* This mapping is the only shape `gitzone services` ever creates, and prune
|
|
12
|
+
* refuses to touch anything that does not match it exactly.
|
|
13
|
+
*/
|
|
14
|
+
export const serviceDataDirectoryNames = {
|
|
15
|
+
mongodb: 'mongodata',
|
|
16
|
+
minio: 'miniodata',
|
|
17
|
+
elasticsearch: 'esdata',
|
|
18
|
+
};
|
|
19
|
+
/**
|
|
20
|
+
* Image used to run each service, and therefore the image available to perform
|
|
21
|
+
* a privileged cleanup of that service's data directory: if the data exists,
|
|
22
|
+
* the service ran, so its image is present locally.
|
|
23
|
+
*/
|
|
24
|
+
export const serviceImages = {
|
|
25
|
+
mongodb: 'mongo:7.0',
|
|
26
|
+
minio: 'minio/minio',
|
|
27
|
+
elasticsearch: 'elasticsearch:8.11.0',
|
|
28
|
+
};
|
|
29
|
+
const isPlainObject = (value) => {
|
|
30
|
+
return typeof value === 'object' && value !== null && !Array.isArray(value);
|
|
31
|
+
};
|
|
32
|
+
/** Absolute path of the marker file for a project. */
|
|
33
|
+
export const getServiceDataMarkerPath = (projectPathArg) => {
|
|
34
|
+
return plugins.path.join(plugins.path.resolve(projectPathArg), '.nogit', serviceDataMarkerFile);
|
|
35
|
+
};
|
|
36
|
+
/**
|
|
37
|
+
* Expected absolute data directory path for a service in a project.
|
|
38
|
+
* `mod_services` must always derive data paths through this helper so that
|
|
39
|
+
* creation and reclamation agree on a single shape.
|
|
40
|
+
*/
|
|
41
|
+
export const getServiceDataDirectory = (projectPathArg, serviceArg) => {
|
|
42
|
+
return plugins.path.join(plugins.path.resolve(projectPathArg), '.nogit', serviceDataDirectoryNames[serviceArg]);
|
|
43
|
+
};
|
|
44
|
+
/**
|
|
45
|
+
* True only when `candidatePathArg` is exactly one of the three data
|
|
46
|
+
* directories `gitzone services` creates for `projectPathArg`.
|
|
47
|
+
*
|
|
48
|
+
* This is an allowlist, not a denylist: any path that is not byte-for-byte one
|
|
49
|
+
* of the expected resolved paths is rejected. It is the last line of defence
|
|
50
|
+
* before a recursive delete.
|
|
51
|
+
*/
|
|
52
|
+
export const isSafeServiceDataPath = (projectPathArg, candidatePathArg) => {
|
|
53
|
+
const candidate = plugins.path.resolve(candidatePathArg);
|
|
54
|
+
for (const service of serviceNames) {
|
|
55
|
+
if (getServiceDataDirectory(projectPathArg, service) === candidate) {
|
|
56
|
+
return true;
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
return false;
|
|
60
|
+
};
|
|
61
|
+
/** Validate an unknown value as a usable marker. */
|
|
62
|
+
export const isValidServiceDataMarker = (markerArg) => {
|
|
63
|
+
if (!isPlainObject(markerArg)) {
|
|
64
|
+
return false;
|
|
65
|
+
}
|
|
66
|
+
if (markerArg.owner !== serviceDataOwner) {
|
|
67
|
+
return false;
|
|
68
|
+
}
|
|
69
|
+
if (markerArg.kind !== 'service-data') {
|
|
70
|
+
return false;
|
|
71
|
+
}
|
|
72
|
+
if (markerArg.schemaVersion !== 1) {
|
|
73
|
+
return false;
|
|
74
|
+
}
|
|
75
|
+
if (markerArg.safeToPrune !== true) {
|
|
76
|
+
return false;
|
|
77
|
+
}
|
|
78
|
+
if (typeof markerArg.projectPath !== 'string' || !markerArg.projectPath) {
|
|
79
|
+
return false;
|
|
80
|
+
}
|
|
81
|
+
if (!Array.isArray(markerArg.dataDirectories)) {
|
|
82
|
+
return false;
|
|
83
|
+
}
|
|
84
|
+
for (const entry of markerArg.dataDirectories) {
|
|
85
|
+
if (!isPlainObject(entry)) {
|
|
86
|
+
return false;
|
|
87
|
+
}
|
|
88
|
+
if (!serviceNames.includes(entry.service)) {
|
|
89
|
+
return false;
|
|
90
|
+
}
|
|
91
|
+
if (typeof entry.path !== 'string' || !entry.path) {
|
|
92
|
+
return false;
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
return true;
|
|
96
|
+
};
|
|
97
|
+
/** Read and validate the marker for a project, or undefined when absent/invalid. */
|
|
98
|
+
export const readServiceDataMarker = async (projectPathArg) => {
|
|
99
|
+
const markerPath = getServiceDataMarkerPath(projectPathArg);
|
|
100
|
+
try {
|
|
101
|
+
if (!(await plugins.smartfs.file(markerPath).exists())) {
|
|
102
|
+
return undefined;
|
|
103
|
+
}
|
|
104
|
+
const content = (await plugins.smartfs.file(markerPath).encoding('utf8').read());
|
|
105
|
+
const parsed = JSON.parse(content);
|
|
106
|
+
return isValidServiceDataMarker(parsed) ? parsed : undefined;
|
|
107
|
+
}
|
|
108
|
+
catch {
|
|
109
|
+
return undefined;
|
|
110
|
+
}
|
|
111
|
+
};
|
|
112
|
+
/**
|
|
113
|
+
* Record that `gitzone services` owns a data directory for this project.
|
|
114
|
+
*
|
|
115
|
+
* The marker lives in `.nogit/` rather than inside the bind-mounted data
|
|
116
|
+
* directory itself, so it can never confuse mongod, MinIO or Elasticsearch at
|
|
117
|
+
* runtime. Entries are merged so enabling a service later does not drop the
|
|
118
|
+
* claim on previously created directories.
|
|
119
|
+
*/
|
|
120
|
+
export const recordServiceDataDirectory = async (projectPathArg, serviceArg) => {
|
|
121
|
+
const projectPath = plugins.path.resolve(projectPathArg);
|
|
122
|
+
const dataPath = getServiceDataDirectory(projectPath, serviceArg);
|
|
123
|
+
const existingMarker = await readServiceDataMarker(projectPath);
|
|
124
|
+
const entries = existingMarker
|
|
125
|
+
? existingMarker.dataDirectories.filter((entry) => entry.service !== serviceArg)
|
|
126
|
+
: [];
|
|
127
|
+
entries.push({ service: serviceArg, path: dataPath });
|
|
128
|
+
entries.sort((entryA, entryB) => entryA.service.localeCompare(entryB.service));
|
|
129
|
+
const marker = {
|
|
130
|
+
owner: serviceDataOwner,
|
|
131
|
+
kind: 'service-data',
|
|
132
|
+
schemaVersion: 1,
|
|
133
|
+
projectPath,
|
|
134
|
+
safeToPrune: true,
|
|
135
|
+
createdAt: existingMarker?.createdAt || new Date().toISOString(),
|
|
136
|
+
dataDirectories: entries,
|
|
137
|
+
};
|
|
138
|
+
const markerPath = getServiceDataMarkerPath(projectPath);
|
|
139
|
+
await plugins.smartfs.directory(plugins.path.dirname(markerPath)).recursive().create();
|
|
140
|
+
await plugins.smartfs
|
|
141
|
+
.file(markerPath)
|
|
142
|
+
.encoding('utf8')
|
|
143
|
+
.write(`${JSON.stringify(marker, null, 2)}\n`);
|
|
144
|
+
};
|
|
145
|
+
/**
|
|
146
|
+
* Labels applied to every container `gitzone services` creates.
|
|
147
|
+
*
|
|
148
|
+
* Mirrors the `git.zone.*` namespace already established by
|
|
149
|
+
* `@git.zone/tsdocker` so prune logic can identify tool-owned resources
|
|
150
|
+
* without ever matching on image or bare name.
|
|
151
|
+
*/
|
|
152
|
+
export const getServiceContainerLabels = (optionsArg) => {
|
|
153
|
+
return {
|
|
154
|
+
'git.zone.tool': serviceToolLabel,
|
|
155
|
+
'git.zone.service': optionsArg.service,
|
|
156
|
+
'git.zone.project-path': plugins.path.resolve(optionsArg.projectPath),
|
|
157
|
+
'git.zone.data-path': plugins.path.resolve(optionsArg.dataPath),
|
|
158
|
+
'git.zone.safe-to-prune': 'true',
|
|
159
|
+
};
|
|
160
|
+
};
|
|
161
|
+
/** True when a container's labels prove `gitzone services` created it. */
|
|
162
|
+
export const isServiceOwnedByLabels = (labelsArg) => {
|
|
163
|
+
return (labelsArg['git.zone.tool'] === serviceToolLabel &&
|
|
164
|
+
labelsArg['git.zone.safe-to-prune'] === 'true');
|
|
165
|
+
};
|
|
166
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY2xhc3Nlcy5zZXJ2aWNlZGF0YW1hcmtlci5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3RzL21vZF9zZXJ2aWNlcy9jbGFzc2VzLnNlcnZpY2VkYXRhbWFya2VyLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sS0FBSyxPQUFPLE1BQU0sa0JBQWtCLENBQUM7QUFZNUMsTUFBTSxDQUFDLE1BQU0sWUFBWSxHQUFtQixDQUFDLFNBQVMsRUFBRSxPQUFPLEVBQUUsZUFBZSxDQUFDLENBQUM7QUFFbEYsc0RBQXNEO0FBQ3RELE1BQU0sQ0FBQyxNQUFNLGdCQUFnQixHQUFHLGVBQWUsQ0FBQztBQUVoRCxzRkFBc0Y7QUFDdEYsTUFBTSxDQUFDLE1BQU0sZ0JBQWdCLEdBQUcsa0JBQWtCLENBQUM7QUFFbkQsMkRBQTJEO0FBQzNELE1BQU0sQ0FBQyxNQUFNLHFCQUFxQixHQUFHLHdCQUF3QixDQUFDO0FBRTlEOzs7O0dBSUc7QUFDSCxNQUFNLENBQUMsTUFBTSx5QkFBeUIsR0FBc0M7SUFDMUUsT0FBTyxFQUFFLFdBQVc7SUFDcEIsS0FBSyxFQUFFLFdBQVc7SUFDbEIsYUFBYSxFQUFFLFFBQVE7Q0FDeEIsQ0FBQztBQUVGOzs7O0dBSUc7QUFDSCxNQUFNLENBQUMsTUFBTSxhQUFhLEdBQXNDO0lBQzlELE9BQU8sRUFBRSxXQUFXO0lBQ3BCLEtBQUssRUFBRSxhQUFhO0lBQ3BCLGFBQWEsRUFBRSxzQkFBc0I7Q0FDdEMsQ0FBQztBQWlCRixNQUFNLGFBQWEsR0FBRyxDQUFDLEtBQWMsRUFBZ0MsRUFBRTtJQUNyRSxPQUFPLE9BQU8sS0FBSyxLQUFLLFFBQVEsSUFBSSxLQUFLLEtBQUssSUFBSSxJQUFJLENBQUMsS0FBSyxDQUFDLE9BQU8sQ0FBQyxLQUFLLENBQUMsQ0FBQztBQUM5RSxDQUFDLENBQUM7QUFFRixzREFBc0Q7QUFDdEQsTUFBTSxDQUFDLE1BQU0sd0JBQXdCLEdBQUcsQ0FBQyxjQUFzQixFQUFVLEVBQUU7SUFD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
|
|
@@ -1,3 +1,36 @@
|
|
|
1
|
+
import { ServiceConfiguration } from './classes.serviceconfiguration.js';
|
|
2
|
+
import { type TServiceName } from './classes.servicedatamarker.js';
|
|
3
|
+
import type { ContainerStatus } from './classes.dockercontainer.js';
|
|
4
|
+
import type { TServiceOptionSource } from './classes.serviceoptions.js';
|
|
5
|
+
export interface IServiceStatus {
|
|
6
|
+
service: TServiceName;
|
|
7
|
+
enabled: boolean;
|
|
8
|
+
container: string;
|
|
9
|
+
status: ContainerStatus;
|
|
10
|
+
port: string;
|
|
11
|
+
connectionString: string;
|
|
12
|
+
dataDirectory: string;
|
|
13
|
+
dataSizeBytes: number;
|
|
14
|
+
/** Only meaningful when the container does not exist yet. */
|
|
15
|
+
portAvailable: boolean | null;
|
|
16
|
+
/** MongoDB only: whether the instance enforces authentication. */
|
|
17
|
+
authEnabled?: boolean;
|
|
18
|
+
/** MongoDB only: whether the auth mode is declared in committed config. */
|
|
19
|
+
authSource?: TServiceOptionSource;
|
|
20
|
+
}
|
|
21
|
+
export interface IServicesStatus {
|
|
22
|
+
project: {
|
|
23
|
+
name: string;
|
|
24
|
+
path: string;
|
|
25
|
+
enabledServices: string[];
|
|
26
|
+
};
|
|
27
|
+
services: {
|
|
28
|
+
mongodb: IServiceStatus;
|
|
29
|
+
minio: IServiceStatus;
|
|
30
|
+
elasticsearch: IServiceStatus;
|
|
31
|
+
};
|
|
32
|
+
totalDataBytes: number;
|
|
33
|
+
}
|
|
1
34
|
export declare class ServiceManager {
|
|
2
35
|
private config;
|
|
3
36
|
private docker;
|
|
@@ -8,6 +41,16 @@ export declare class ServiceManager {
|
|
|
8
41
|
* Initialize the service manager
|
|
9
42
|
*/
|
|
10
43
|
init(): Promise<void>;
|
|
44
|
+
/**
|
|
45
|
+
* Human phrasing for where the auth mode came from. A declared auth-off is
|
|
46
|
+
* committed to the repository and therefore affects everyone who clones it,
|
|
47
|
+
* so it must never read the same as a local-only choice.
|
|
48
|
+
*/
|
|
49
|
+
private describeMongoAuthSource;
|
|
50
|
+
/**
|
|
51
|
+
* Expose the resolved service configuration to the command layer.
|
|
52
|
+
*/
|
|
53
|
+
getConfiguration(): ServiceConfiguration;
|
|
11
54
|
/**
|
|
12
55
|
* Load service configuration from .smartconfig.json
|
|
13
56
|
*/
|
|
@@ -21,15 +64,31 @@ export declare class ServiceManager {
|
|
|
21
64
|
*/
|
|
22
65
|
private isServiceEnabled;
|
|
23
66
|
/**
|
|
24
|
-
*
|
|
67
|
+
* Prepare a service's data directory: create it and record tool ownership.
|
|
68
|
+
*
|
|
69
|
+
* The marker written here is what later allows `gitzone services prune` to
|
|
70
|
+
* prove the directory is reclaimable instead of guessing from its path.
|
|
71
|
+
*/
|
|
72
|
+
private prepareDataDirectory;
|
|
73
|
+
/**
|
|
74
|
+
* Register this project with the global registry.
|
|
75
|
+
*
|
|
76
|
+
* Public and called from the command layer after any start path: previously
|
|
77
|
+
* only `startAll` registered, so `gitzone services start mongo` created a
|
|
78
|
+
* container the registry never knew about and prune could never account for.
|
|
25
79
|
*/
|
|
26
|
-
|
|
80
|
+
registerWithGlobalRegistry(): Promise<void>;
|
|
27
81
|
/**
|
|
28
82
|
* Start all enabled services
|
|
29
83
|
*/
|
|
30
84
|
startAll(): Promise<void>;
|
|
31
85
|
/**
|
|
32
|
-
* Stop
|
|
86
|
+
* Stop every service container belonging to this project.
|
|
87
|
+
*
|
|
88
|
+
* Deliberately not filtered by the enabled-service list: disabling a service
|
|
89
|
+
* previously left its container running with no command able to stop it,
|
|
90
|
+
* which is how projects accumulated forgotten containers. Stopping a service
|
|
91
|
+
* that is not running is a no-op, so covering all three is always safe.
|
|
33
92
|
*/
|
|
34
93
|
stopAll(): Promise<void>;
|
|
35
94
|
/**
|
|
@@ -52,9 +111,21 @@ export declare class ServiceManager {
|
|
|
52
111
|
*/
|
|
53
112
|
private ensureMongoKeyfile;
|
|
54
113
|
/**
|
|
55
|
-
*
|
|
114
|
+
* The mongod argv the container was created with
|
|
56
115
|
*/
|
|
57
|
-
private
|
|
116
|
+
private getMongoContainerCmd;
|
|
117
|
+
/**
|
|
118
|
+
* Make sure the configured root user exists when auth is enabled.
|
|
119
|
+
*
|
|
120
|
+
* `MONGO_INITDB_ROOT_USERNAME` only takes effect on an empty dbpath, so data
|
|
121
|
+
* that was first created with auth disabled has no user at all. Enabling auth
|
|
122
|
+
* over it would leave an unusable database. MongoDB's localhost exception is
|
|
123
|
+
* the designed bootstrap path for exactly this: while zero users exist, a
|
|
124
|
+
* connection from localhost — which, inside the container, is what this is —
|
|
125
|
+
* may create the first one. If users already exist the exception does not
|
|
126
|
+
* apply and creation fails, so this can never overwrite or escalate anything.
|
|
127
|
+
*/
|
|
128
|
+
private ensureMongoRootUser;
|
|
58
129
|
/**
|
|
59
130
|
* Initiate the single-node replica set once mongod is reachable
|
|
60
131
|
*/
|
|
@@ -79,10 +150,25 @@ export declare class ServiceManager {
|
|
|
79
150
|
* Stop Elasticsearch service
|
|
80
151
|
*/
|
|
81
152
|
stopElasticsearch(): Promise<void>;
|
|
153
|
+
/**
|
|
154
|
+
* Collect service status as structured data.
|
|
155
|
+
*
|
|
156
|
+
* This is the machine-readable surface behind `gitzone services status
|
|
157
|
+
* --json`; consumers such as test suites can read a connection string from it
|
|
158
|
+
* without scraping human output or re-deriving it from `.nogit/env.json`.
|
|
159
|
+
*/
|
|
160
|
+
collectStatus(): Promise<IServicesStatus>;
|
|
82
161
|
/**
|
|
83
162
|
* Show service status
|
|
84
163
|
*/
|
|
85
164
|
showStatus(): Promise<void>;
|
|
165
|
+
/**
|
|
166
|
+
* Report on-disk size of this project's service data.
|
|
167
|
+
*
|
|
168
|
+
* Reporting comes before any deletion: knowing what a project holds is what
|
|
169
|
+
* makes reclaiming it a decision rather than a guess.
|
|
170
|
+
*/
|
|
171
|
+
showDiskUsage(): Promise<void>;
|
|
86
172
|
/**
|
|
87
173
|
* Show configuration
|
|
88
174
|
*/
|