@bizone-ai/cli 0.1.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 +289 -0
- package/bin/bizone.js +9 -0
- package/package.json +22 -0
- package/src/cli.js +103 -0
- package/src/colors.js +46 -0
- package/src/commands/configuration.js +69 -0
- package/src/commands/database.js +68 -0
- package/src/commands/environment.js +104 -0
- package/src/commands/images.js +66 -0
- package/src/commands/resources.js +60 -0
- package/src/commands/start.js +201 -0
- package/src/commands/stop.js +53 -0
- package/src/config.js +78 -0
- package/src/containers/_commons.js +16 -0
- package/src/containers/cloud-tools.js +28 -0
- package/src/containers/mysql.js +18 -0
- package/src/containers/orchestrator.js +36 -0
- package/src/containers/resource-manager.js +25 -0
- package/src/containers/resources-job.js +8 -0
- package/src/containers/state-store.js +28 -0
- package/src/containers/ui.js +15 -0
- package/src/defaults.js +64 -0
- package/src/docker.js +190 -0
- package/src/http.js +60 -0
- package/src/resources-loader.js +50 -0
package/README.md
ADDED
|
@@ -0,0 +1,289 @@
|
|
|
1
|
+
# Bizone CLI
|
|
2
|
+
|
|
3
|
+
An assistant CLI for running the **Bizone orchestrator platform** locally using Docker.
|
|
4
|
+
|
|
5
|
+
The CLI starts, configures, and stops the platform containers — a bundled
|
|
6
|
+
`mysql` database, `resource-manager`, `orchestrator`, `state-store`, and `ui` —
|
|
7
|
+
plus the one-shot resources initialization job (`bizone-resources`).
|
|
8
|
+
Optionally runs `cloud-tools` as well if required.
|
|
9
|
+
Works on **macOS** and **Windows**.
|
|
10
|
+
|
|
11
|
+
---
|
|
12
|
+
|
|
13
|
+
## Installation
|
|
14
|
+
|
|
15
|
+
Requires **Node.js >= 18** and a running **Docker** engine.
|
|
16
|
+
|
|
17
|
+
```bash
|
|
18
|
+
cd cli
|
|
19
|
+
npm install # no runtime dependencies, but sets up the bin link
|
|
20
|
+
npm link # makes `bizone` available globally (optional)
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
Or run directly without linking:
|
|
24
|
+
|
|
25
|
+
```bash
|
|
26
|
+
node cli/bin/bizone.js <category> <command> [args]
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
All examples below assume the `bizone` command is on your PATH.
|
|
30
|
+
|
|
31
|
+
---
|
|
32
|
+
|
|
33
|
+
## Command structure
|
|
34
|
+
|
|
35
|
+
```
|
|
36
|
+
bizone <category> <command> [args] [--no-colors]
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
| Category | Aliases | Purpose |
|
|
40
|
+
|-----------------|-------------|-------------------------------------------------|
|
|
41
|
+
| `start` | — | Start the platform |
|
|
42
|
+
| `stop` | — | Stop the platform |
|
|
43
|
+
| `configuration` | `config`,`c`| General CLI configuration |
|
|
44
|
+
| `images` | `img` | Override container image URLs |
|
|
45
|
+
| `environment` | `env` | Set environment variables per container |
|
|
46
|
+
| `resources` | `res`, `r` | Resources imported into the resource-manager |
|
|
47
|
+
| `database` | `db` | Manage the bundled MySQL database |
|
|
48
|
+
|
|
49
|
+
Global flags:
|
|
50
|
+
|
|
51
|
+
- `--no-colors` — disable ANSI colors (also disabled when `NO_COLOR` is set or output is not a TTY)
|
|
52
|
+
- `--help`, `-h` — show usage
|
|
53
|
+
- `--version`, `-v` — show version
|
|
54
|
+
|
|
55
|
+
---
|
|
56
|
+
|
|
57
|
+
## Configuration file
|
|
58
|
+
|
|
59
|
+
All settings are stored in a single JSON file in your home directory:
|
|
60
|
+
|
|
61
|
+
- **macOS / Linux:** `~/.bizone/config.json`
|
|
62
|
+
- **Windows:** `%USERPROFILE%\.bizone\config.json`
|
|
63
|
+
|
|
64
|
+
Running container ids are tracked alongside it in `containers.json`.
|
|
65
|
+
|
|
66
|
+
File shape:
|
|
67
|
+
|
|
68
|
+
```json
|
|
69
|
+
{
|
|
70
|
+
"config": { "key": "value" },
|
|
71
|
+
"images": { "type": "image-url" },
|
|
72
|
+
"env": { "type": { "NAME": "value" } },
|
|
73
|
+
"resources": { "namespace": "path" }
|
|
74
|
+
}
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
---
|
|
78
|
+
|
|
79
|
+
## `configuration` — general settings
|
|
80
|
+
|
|
81
|
+
```bash
|
|
82
|
+
bizone config get # show current configuration (with defaults)
|
|
83
|
+
bizone config set {key} {value} # set a config key
|
|
84
|
+
bizone config remove {key} # reset a key back to its default
|
|
85
|
+
```
|
|
86
|
+
|
|
87
|
+
Stored at `$.config.{key}`.
|
|
88
|
+
|
|
89
|
+
### Available keys
|
|
90
|
+
|
|
91
|
+
| Key | Default | Description |
|
|
92
|
+
|-------------------------|----------------|----------------------------------------------------------------------------------------------------|
|
|
93
|
+
| `forward_aws_env` | `true` | Forward `AWS_REGION`, `AWS_ACCESS_KEY_ID`, `AWS_SECRET_ACCESS_KEY` into the orchestrator container |
|
|
94
|
+
| `network_name` | `bizone-local` | Shared docker network all containers join |
|
|
95
|
+
| `mysql_port` | `33306` | Host port for the bundled MySQL database |
|
|
96
|
+
| `orchestrator_port` | `8001` | Host port for the orchestrator |
|
|
97
|
+
| `resource_manager_port` | `7070` | Host port for the resource-manager |
|
|
98
|
+
| `state_store_port` | `8088` | Host port for the state-store |
|
|
99
|
+
| `state_store_enable` | `true` | Run `state-store` as part of the sequence |
|
|
100
|
+
| `cloud_tools_port` | `8086` | Host port for cloud-tools |
|
|
101
|
+
| `cloud_tools_enable` | `false` | Run `cloud-tools` as part of the sequence |
|
|
102
|
+
| `ui_port` | `7006` | Host port for the UI |
|
|
103
|
+
| `timeout_sec` | `300` | Readiness wait timeout per service (seconds) |
|
|
104
|
+
|
|
105
|
+
Example:
|
|
106
|
+
|
|
107
|
+
```bash
|
|
108
|
+
bizone config set ui_port 9006
|
|
109
|
+
bizone config set cloud_tools_enable true
|
|
110
|
+
```
|
|
111
|
+
|
|
112
|
+
---
|
|
113
|
+
|
|
114
|
+
## `images` — override container images
|
|
115
|
+
|
|
116
|
+
```bash
|
|
117
|
+
bizone images get # list image URLs (override or default)
|
|
118
|
+
bizone images set {type} {url} # override an image
|
|
119
|
+
bizone images remove {type} # reset to default
|
|
120
|
+
```
|
|
121
|
+
|
|
122
|
+
Stored at `$.images.{type}`. Valid types:
|
|
123
|
+
|
|
124
|
+
`mysql`, `orchestrator`, `state-store`, `resource-manager`, `cloud-tools`, `ui`, `resources`
|
|
125
|
+
|
|
126
|
+
Example:
|
|
127
|
+
|
|
128
|
+
```bash
|
|
129
|
+
bizone images set state-store bizone-local/state-store:1.0.0
|
|
130
|
+
```
|
|
131
|
+
|
|
132
|
+
---
|
|
133
|
+
|
|
134
|
+
## `environment` — per-container environment variables
|
|
135
|
+
|
|
136
|
+
```bash
|
|
137
|
+
bizone env get {type} # show env vars (secrets masked)
|
|
138
|
+
bizone env set {type} {name} {value} # set an env var
|
|
139
|
+
bizone env remove {type} {name} # remove an env var
|
|
140
|
+
```
|
|
141
|
+
|
|
142
|
+
Stored at `$.env.{type}.{name}`. `{type}` is one of the image types above.
|
|
143
|
+
|
|
144
|
+
Each container type also has built-in **default** environment variables that
|
|
145
|
+
are applied at run time unless you override the same key with `env set` (your
|
|
146
|
+
value wins). `env get` shows the effective set, tagging each entry as
|
|
147
|
+
`(default)` or `(override)`. For example, the MySQL client defaults
|
|
148
|
+
(`storage.type=mysql`, `mysql.storage`, `mysql.storage.user`,
|
|
149
|
+
`mysql.storage.password.secret`, `secret.mysql.password`) are applied to every
|
|
150
|
+
container except `ui`, and the `mysql` container gets `MYSQL_ROOT_PASSWORD=root`.
|
|
151
|
+
|
|
152
|
+
Secret values are masked on `get` (showing only the first 4 and last 4
|
|
153
|
+
characters). Keys are treated as secrets when they match a predefined list
|
|
154
|
+
(e.g. `AWS_SECRET_ACCESS_KEY`, `mysql.storage.password.secret`) or contain
|
|
155
|
+
`password` / `secret` / `token` / `apikey`.
|
|
156
|
+
|
|
157
|
+
Example:
|
|
158
|
+
|
|
159
|
+
```bash
|
|
160
|
+
bizone env set state-store db_url "mysql://user:pass@host:3306/db"
|
|
161
|
+
bizone env get state-store
|
|
162
|
+
# db_url = mysq*******...****/db
|
|
163
|
+
```
|
|
164
|
+
|
|
165
|
+
These env vars are passed to the container at run time via `-e NAME=value`.
|
|
166
|
+
|
|
167
|
+
---
|
|
168
|
+
|
|
169
|
+
## `resources` — startup resource import
|
|
170
|
+
|
|
171
|
+
Define resources to import into the resource-manager on startup, grouped by
|
|
172
|
+
namespace.
|
|
173
|
+
|
|
174
|
+
```bash
|
|
175
|
+
bizone resources get # list configured sources
|
|
176
|
+
bizone resources set {namespace} {path} # set a file or folder source
|
|
177
|
+
bizone resources remove {namespace} # remove a namespace source
|
|
178
|
+
```
|
|
179
|
+
|
|
180
|
+
Stored at `$.resources.{namespace}`. `{path}` may be:
|
|
181
|
+
|
|
182
|
+
- a **folder** — every `.json` file found recursively becomes one item
|
|
183
|
+
- a **single file with an `items` array** — that array is used as the items
|
|
184
|
+
- a **single file otherwise** — the whole file becomes the only item
|
|
185
|
+
|
|
186
|
+
Relative paths resolve against the `.bizone` config directory.
|
|
187
|
+
|
|
188
|
+
Example:
|
|
189
|
+
|
|
190
|
+
```bash
|
|
191
|
+
bizone resources set my_namespace ./my_namespace.json
|
|
192
|
+
```
|
|
193
|
+
|
|
194
|
+
### Import procedure
|
|
195
|
+
|
|
196
|
+
On startup, for each namespace, the CLI sends:
|
|
197
|
+
|
|
198
|
+
```
|
|
199
|
+
POST http://localhost:{resource_manager_port}/admin/{namespace}/status
|
|
200
|
+
|
|
201
|
+
{ "user": "bizone-cli", "message": "resource initialization", "items": [ ... ] }
|
|
202
|
+
```
|
|
203
|
+
|
|
204
|
+
---
|
|
205
|
+
|
|
206
|
+
## `start` — start the platform
|
|
207
|
+
|
|
208
|
+
```bash
|
|
209
|
+
bizone start
|
|
210
|
+
```
|
|
211
|
+
|
|
212
|
+
Non-blocking: once everything is ready it prints **"Platform is running"** and
|
|
213
|
+
returns control to the shell. Container ids are saved to
|
|
214
|
+
`~/.bizone/containers.json` keyed by container name.
|
|
215
|
+
|
|
216
|
+
### Startup sequence
|
|
217
|
+
|
|
218
|
+
1. Create the shared docker network `bizone-local` (skipped if it exists).
|
|
219
|
+
2. Start `mysql` **only if it is not already running** (an existing DB container
|
|
220
|
+
is reused), then wait until it accepts connections (`mysqladmin ping`).
|
|
221
|
+
The resource-manager is configured to store into this database, whose data
|
|
222
|
+
lives in the persistent docker volume `bizone-mysql-data`.
|
|
223
|
+
3. Start `resource-manager`; wait until `GET /.system/status` returns `{ "status": "OK" }`.
|
|
224
|
+
4. Run the `bizone-resources` initialization job (blocking).
|
|
225
|
+
5. Import any configured `resources` namespaces (see above).
|
|
226
|
+
6. Start `orchestrator`, `ui`, and any enabled optional services in parallel
|
|
227
|
+
(state-store / cloud-tools run only when `*_enable=true`).
|
|
228
|
+
- The orchestrator receives the AWS env vars when `forward_aws_env=true`.
|
|
229
|
+
7. Wait for all of them to become ready:
|
|
230
|
+
- `ui` — `GET /actuator/health/readiness` returns `{"status":{"code":"UP"}}`
|
|
231
|
+
- all others — `GET /.system/status` returns `{ "status": "OK" }`
|
|
232
|
+
- each wait times out after `timeout_sec` seconds.
|
|
233
|
+
|
|
234
|
+
Each container is started with:
|
|
235
|
+
|
|
236
|
+
```
|
|
237
|
+
docker run -d \
|
|
238
|
+
--name bizone-{type} -h bizone-{type} \
|
|
239
|
+
--network bizone-local --network-alias bizone-{type} \
|
|
240
|
+
-p {host_port}:{container_port} \
|
|
241
|
+
[-e NAME=value ...] \
|
|
242
|
+
{image}
|
|
243
|
+
```
|
|
244
|
+
|
|
245
|
+
---
|
|
246
|
+
|
|
247
|
+
## `stop` — stop the platform
|
|
248
|
+
|
|
249
|
+
```bash
|
|
250
|
+
bizone stop
|
|
251
|
+
```
|
|
252
|
+
|
|
253
|
+
Reads `containers.json`, validates each id against `docker ps`, stops &
|
|
254
|
+
removes the running containers, and updates the local file.
|
|
255
|
+
|
|
256
|
+
The **database is intentionally left running** so its data persists and the
|
|
257
|
+
next `bizone start` reuses it. To remove the database, use `bizone db destroy`.
|
|
258
|
+
|
|
259
|
+
---
|
|
260
|
+
|
|
261
|
+
## `database` — manage the MySQL database
|
|
262
|
+
|
|
263
|
+
```bash
|
|
264
|
+
bizone database destroy # remove the DB container and its data volume
|
|
265
|
+
```
|
|
266
|
+
|
|
267
|
+
The bundled `mysql` container stores its data in the persistent docker volume
|
|
268
|
+
`bizone-mysql-data`, so it survives `bizone stop` and container restarts.
|
|
269
|
+
|
|
270
|
+
`destroy` permanently removes both the `bizone-mysql` container and the
|
|
271
|
+
`bizone-mysql-data` volume (all data is lost). It refuses to run while any other
|
|
272
|
+
platform container (`bizone-*`) is still running — run `bizone stop` first.
|
|
273
|
+
|
|
274
|
+
---
|
|
275
|
+
|
|
276
|
+
## Troubleshooting
|
|
277
|
+
|
|
278
|
+
- **"Docker does not appear to be running"** — start Docker Desktop / the Docker daemon.
|
|
279
|
+
- **Startup timed out** — increase `timeout_sec`, or check the container logs with `docker logs bizone-{type}`.
|
|
280
|
+
- **Port already in use** — change the relevant `*_port` config value.
|
|
281
|
+
- **Stale containers blocking a re-run** — `bizone start` force-removes existing
|
|
282
|
+
`bizone-*` containers by name before starting; you can also run `bizone stop`.
|
|
283
|
+
- **`pull access denied` from AWS ECR** — when an image lives in an
|
|
284
|
+
`{account}.dkr.ecr.{region}.amazonaws.com` registry and the pull is
|
|
285
|
+
unauthorized, `bizone start` automatically authenticates by running
|
|
286
|
+
`aws ecr get-login-password --region {region}` and piping it into
|
|
287
|
+
`docker login --username AWS --password-stdin {registry}`, then retries.
|
|
288
|
+
This requires the **AWS CLI** to be installed and configured with valid
|
|
289
|
+
credentials for that account.
|
package/bin/bizone.js
ADDED
package/package.json
ADDED
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@bizone-ai/cli",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "Assistant CLI for running the Bizone orchestrator platform locally with Docker",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"bin": {
|
|
7
|
+
"bizone": "bin/bizone.js"
|
|
8
|
+
},
|
|
9
|
+
"engines": {
|
|
10
|
+
"node": ">=18"
|
|
11
|
+
},
|
|
12
|
+
"files": [
|
|
13
|
+
"bin",
|
|
14
|
+
"src",
|
|
15
|
+
"README.md"
|
|
16
|
+
],
|
|
17
|
+
"scripts": {
|
|
18
|
+
"start": "node bin/bizone.js",
|
|
19
|
+
"test": "echo No tests"
|
|
20
|
+
},
|
|
21
|
+
"license": "UNLICENSED"
|
|
22
|
+
}
|
package/src/cli.js
ADDED
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
// Argument parsing and command dispatch.
|
|
2
|
+
|
|
3
|
+
import { initColors, color, log } from './colors.js';
|
|
4
|
+
import { configuration } from './commands/configuration.js';
|
|
5
|
+
import { images } from './commands/images.js';
|
|
6
|
+
import { environment } from './commands/environment.js';
|
|
7
|
+
import { resources } from './commands/resources.js';
|
|
8
|
+
import { database } from './commands/database.js';
|
|
9
|
+
import { start } from './commands/start.js';
|
|
10
|
+
import { stop } from './commands/stop.js';
|
|
11
|
+
import { CONFIG_PATH } from './config.js';
|
|
12
|
+
|
|
13
|
+
const VERSION = '1.0.0';
|
|
14
|
+
|
|
15
|
+
// category -> { aliases, handler }
|
|
16
|
+
const CATEGORIES = {
|
|
17
|
+
configuration: { aliases: ['config', 'c'], handler: configuration },
|
|
18
|
+
images: { aliases: ['img'], handler: images },
|
|
19
|
+
environment: { aliases: ['env'], handler: environment },
|
|
20
|
+
resources: { aliases: ['res', 'r'], handler: resources },
|
|
21
|
+
database: { aliases: ['db'], handler: database },
|
|
22
|
+
};
|
|
23
|
+
|
|
24
|
+
function resolveCategory(name) {
|
|
25
|
+
if (CATEGORIES[name]) return CATEGORIES[name];
|
|
26
|
+
for (const cat of Object.values(CATEGORIES)) {
|
|
27
|
+
if (cat.aliases.includes(name)) return cat;
|
|
28
|
+
}
|
|
29
|
+
return null;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
function printHelp() {
|
|
33
|
+
const b = color.bold;
|
|
34
|
+
const c = color.cyan;
|
|
35
|
+
log.plain(b('bizone') + ' - run the Bizone orchestrator platform locally with Docker');
|
|
36
|
+
log.plain('');
|
|
37
|
+
log.plain(b('Usage:') + ' bizone <category> <command> [args] [--no-colors]');
|
|
38
|
+
log.plain('');
|
|
39
|
+
log.plain(b('Lifecycle:'));
|
|
40
|
+
log.plain(` ${c('bizone start')} Start the platform (startup sequence)`);
|
|
41
|
+
log.plain(` ${c('bizone stop')} Stop running platform containers`);
|
|
42
|
+
log.plain('');
|
|
43
|
+
log.plain(b('Configuration:') + color.dim(' (config, c)'));
|
|
44
|
+
log.plain(` ${c('bizone config get')} Show current configuration`);
|
|
45
|
+
log.plain(` ${c('bizone config set {key} {value}')} Set a config value`);
|
|
46
|
+
log.plain(` ${c('bizone config remove {key}')} Remove a config value`);
|
|
47
|
+
log.plain('');
|
|
48
|
+
log.plain(b('Images:') + color.dim(' (img)'));
|
|
49
|
+
log.plain(` ${c('bizone images get')} List image URLs (override or default)`);
|
|
50
|
+
log.plain(` ${c('bizone images set {type} {url}')} Override an image`);
|
|
51
|
+
log.plain(` ${c('bizone images remove {type}')} Reset image to default`);
|
|
52
|
+
log.plain('');
|
|
53
|
+
log.plain(b('Environment:') + color.dim(' (env)'));
|
|
54
|
+
log.plain(` ${c('bizone env get {type}')} Show env vars (secrets masked)`);
|
|
55
|
+
log.plain(` ${c('bizone env set {type} {name} {value}')} Set an env var`);
|
|
56
|
+
log.plain(` ${c('bizone env remove {type} {name}')} Remove an env var`);
|
|
57
|
+
log.plain('');
|
|
58
|
+
log.plain(b('Resources:') + color.dim(' (res, r)'));
|
|
59
|
+
log.plain(` ${c('bizone resources get')} List resource sources`);
|
|
60
|
+
log.plain(` ${c('bizone resources set {namespace} {path}')} Set a resource source`);
|
|
61
|
+
log.plain(` ${c('bizone resources remove {namespace}')} Remove a resource source`);
|
|
62
|
+
log.plain('');
|
|
63
|
+
log.plain(b('Database:') + color.dim(' (db)'));
|
|
64
|
+
log.plain(` ${c('bizone database destroy')} Remove the DB container and its data volume`);
|
|
65
|
+
log.plain('');
|
|
66
|
+
log.plain(b('Global flags:'));
|
|
67
|
+
log.plain(` ${c('--no-colors')} Disable ANSI colors`);
|
|
68
|
+
log.plain(` ${c('--help, -h')} Show this help`);
|
|
69
|
+
log.plain(` ${c('--version, -v')} Show version`);
|
|
70
|
+
log.plain('');
|
|
71
|
+
log.plain(color.dim(`Config file: ${CONFIG_PATH}`));
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
export async function main(argv) {
|
|
75
|
+
// Extract global flags anywhere in argv.
|
|
76
|
+
const noColors = argv.includes('--no-colors');
|
|
77
|
+
initColors({ noColors });
|
|
78
|
+
const args = argv.filter((a) => a !== '--no-colors');
|
|
79
|
+
|
|
80
|
+
if (args.length === 0 || args[0] === '--help' || args[0] === '-h' || args[0] === 'help') {
|
|
81
|
+
printHelp();
|
|
82
|
+
return 0;
|
|
83
|
+
}
|
|
84
|
+
if (args[0] === '--version' || args[0] === '-v' || args[0] === 'version') {
|
|
85
|
+
log.plain(VERSION);
|
|
86
|
+
return 0;
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
const [category, ...rest] = args;
|
|
90
|
+
|
|
91
|
+
// Lifecycle commands act as bare categories.
|
|
92
|
+
if (category === 'start') return await start();
|
|
93
|
+
if (category === 'stop') return stop();
|
|
94
|
+
|
|
95
|
+
const resolved = resolveCategory(category);
|
|
96
|
+
if (!resolved) {
|
|
97
|
+
log.err(`Unknown command: ${color.cyan(category)}`);
|
|
98
|
+
log.plain(`Run ${color.cyan('bizone --help')} for usage.`);
|
|
99
|
+
return 1;
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
return await resolved.handler(rest);
|
|
103
|
+
}
|
package/src/colors.js
ADDED
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
// Minimal ANSI color helpers. Colors are disabled when `--no-colors` is passed
|
|
2
|
+
// or when stdout is not a TTY / NO_COLOR env is set.
|
|
3
|
+
|
|
4
|
+
let enabled = true;
|
|
5
|
+
|
|
6
|
+
export function setColorsEnabled(value) {
|
|
7
|
+
enabled = value;
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
export function initColors({ noColors }) {
|
|
11
|
+
if (noColors) {
|
|
12
|
+
enabled = false;
|
|
13
|
+
return;
|
|
14
|
+
}
|
|
15
|
+
if (process.env.NO_COLOR) {
|
|
16
|
+
enabled = false;
|
|
17
|
+
return;
|
|
18
|
+
}
|
|
19
|
+
enabled = Boolean(process.stdout.isTTY);
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
function wrap(open, close) {
|
|
23
|
+
return (text) => (enabled ? `[${open}m${text}[${close}m` : String(text));
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
export const color = {
|
|
27
|
+
bold: wrap(1, 22),
|
|
28
|
+
dim: wrap(2, 22),
|
|
29
|
+
red: wrap(31, 39),
|
|
30
|
+
green: wrap(32, 39),
|
|
31
|
+
yellow: wrap(33, 39),
|
|
32
|
+
blue: wrap(34, 39),
|
|
33
|
+
magenta: wrap(35, 39),
|
|
34
|
+
cyan: wrap(36, 39),
|
|
35
|
+
gray: wrap(90, 39),
|
|
36
|
+
};
|
|
37
|
+
|
|
38
|
+
// Common log helpers.
|
|
39
|
+
export const log = {
|
|
40
|
+
info: (msg) => console.log(msg),
|
|
41
|
+
step: (msg) => console.log(`${color.cyan('•')} ${msg}`),
|
|
42
|
+
ok: (msg) => console.log(`${color.green('✓')} ${msg}`),
|
|
43
|
+
warn: (msg) => console.log(`${color.yellow('!')} ${msg}`),
|
|
44
|
+
err: (msg) => console.error(`${color.red('✗')} ${msg}`),
|
|
45
|
+
plain: (msg) => console.log(msg),
|
|
46
|
+
};
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
// `bizone configuration|config|c get|set|remove`
|
|
2
|
+
|
|
3
|
+
import { loadConfig, saveConfig, getConfigValue } from '../config.js';
|
|
4
|
+
import { CONFIG_KEYS, DEFAULT_CONFIG } from '../defaults.js';
|
|
5
|
+
import { color, log } from '../colors.js';
|
|
6
|
+
|
|
7
|
+
function printKnownKeys() {
|
|
8
|
+
log.plain(color.bold('Known configuration keys (with defaults):'));
|
|
9
|
+
for (const k of CONFIG_KEYS) {
|
|
10
|
+
log.plain(` ${color.cyan(k)} = ${color.dim(DEFAULT_CONFIG[k])}`);
|
|
11
|
+
}
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
export function configuration(args) {
|
|
15
|
+
const [sub, key, ...rest] = args;
|
|
16
|
+
const cfg = loadConfig();
|
|
17
|
+
|
|
18
|
+
switch (sub) {
|
|
19
|
+
case 'get': {
|
|
20
|
+
log.plain(color.bold('Configuration:'));
|
|
21
|
+
for (const k of CONFIG_KEYS) {
|
|
22
|
+
const isSet = Object.prototype.hasOwnProperty.call(cfg.config, k);
|
|
23
|
+
const val = getConfigValue(cfg, k);
|
|
24
|
+
const tag = isSet ? '' : color.dim(' (default)');
|
|
25
|
+
log.plain(` ${color.cyan(k)} = ${val}${tag}`);
|
|
26
|
+
}
|
|
27
|
+
// Any non-standard custom keys the user added.
|
|
28
|
+
for (const k of Object.keys(cfg.config)) {
|
|
29
|
+
if (!CONFIG_KEYS.includes(k)) {
|
|
30
|
+
log.plain(` ${color.cyan(k)} = ${cfg.config[k]}${color.yellow(' (custom)')}`);
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
return 0;
|
|
34
|
+
}
|
|
35
|
+
case 'set': {
|
|
36
|
+
if (!key || rest.length === 0) {
|
|
37
|
+
log.err('Usage: bizone config set {key} {value}');
|
|
38
|
+
printKnownKeys();
|
|
39
|
+
return 1;
|
|
40
|
+
}
|
|
41
|
+
const value = rest.join(' ');
|
|
42
|
+
if (!CONFIG_KEYS.includes(key)) {
|
|
43
|
+
log.warn(`"${key}" is not a known config key; storing it anyway.`);
|
|
44
|
+
}
|
|
45
|
+
cfg.config[key] = value;
|
|
46
|
+
saveConfig(cfg);
|
|
47
|
+
log.ok(`Set ${color.cyan(key)} = ${value}`);
|
|
48
|
+
return 0;
|
|
49
|
+
}
|
|
50
|
+
case 'remove': {
|
|
51
|
+
if (!key) {
|
|
52
|
+
log.err('Usage: bizone config remove {key}');
|
|
53
|
+
return 1;
|
|
54
|
+
}
|
|
55
|
+
if (Object.prototype.hasOwnProperty.call(cfg.config, key)) {
|
|
56
|
+
delete cfg.config[key];
|
|
57
|
+
saveConfig(cfg);
|
|
58
|
+
log.ok(`Removed ${color.cyan(key)}`);
|
|
59
|
+
} else {
|
|
60
|
+
log.warn(`Key ${color.cyan(key)} was not set.`);
|
|
61
|
+
}
|
|
62
|
+
return 0;
|
|
63
|
+
}
|
|
64
|
+
default:
|
|
65
|
+
log.err('Usage: bizone config <get|set|remove> ...');
|
|
66
|
+
printKnownKeys();
|
|
67
|
+
return 1;
|
|
68
|
+
}
|
|
69
|
+
}
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
// `bizone database|db destroy` — remove the database container and its volume.
|
|
2
|
+
// Only permitted when no other platform containers are running.
|
|
3
|
+
|
|
4
|
+
import { loadContainers, saveContainers } from '../config.js';
|
|
5
|
+
import { CONTAINERS } from '../defaults.js';
|
|
6
|
+
import {
|
|
7
|
+
dockerAvailable,
|
|
8
|
+
runningContainerNames,
|
|
9
|
+
stopContainer,
|
|
10
|
+
removeVolume,
|
|
11
|
+
} from '../docker.js';
|
|
12
|
+
import { color, log } from '../colors.js';
|
|
13
|
+
|
|
14
|
+
const mysql = CONTAINERS.mysql;
|
|
15
|
+
|
|
16
|
+
export function database(args) {
|
|
17
|
+
const [sub] = args;
|
|
18
|
+
switch (sub) {
|
|
19
|
+
case 'destroy':
|
|
20
|
+
return destroy();
|
|
21
|
+
default:
|
|
22
|
+
log.err('Usage: bizone database destroy');
|
|
23
|
+
return 1;
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
function destroy() {
|
|
28
|
+
if (!dockerAvailable()) {
|
|
29
|
+
log.err('Docker does not appear to be running or installed.');
|
|
30
|
+
return 1;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
// Refuse while any other platform container is still running.
|
|
34
|
+
const running = runningContainerNames();
|
|
35
|
+
const others = [...running].filter(
|
|
36
|
+
(n) => n.startsWith('bizone-') && n !== mysql.containerName,
|
|
37
|
+
);
|
|
38
|
+
if (others.length > 0) {
|
|
39
|
+
log.err(`Cannot destroy the database while platform containers are running: ${others.join(', ')}`);
|
|
40
|
+
log.plain(`Run ${color.cyan('bizone stop')} first, then ${color.cyan('bizone db destroy')}.`);
|
|
41
|
+
return 1;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
log.warn(`This will permanently delete the database container and ALL its data (volume ${mysql.volume.name}).`);
|
|
45
|
+
|
|
46
|
+
// Stop + remove the container (no-op if already gone).
|
|
47
|
+
log.step(`Removing container ${mysql.containerName}...`);
|
|
48
|
+
stopContainer(mysql.containerName);
|
|
49
|
+
|
|
50
|
+
// Remove the data volume.
|
|
51
|
+
log.step(`Removing volume ${mysql.volume.name}...`);
|
|
52
|
+
if (removeVolume(mysql.volume.name)) {
|
|
53
|
+
log.ok(`Removed volume ${mysql.volume.name}`);
|
|
54
|
+
} else {
|
|
55
|
+
log.warn(`Volume ${mysql.volume.name} not found or already removed`);
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
// Drop from the local record.
|
|
59
|
+
const containers = loadContainers();
|
|
60
|
+
if (containers[mysql.containerName]) {
|
|
61
|
+
delete containers[mysql.containerName];
|
|
62
|
+
saveContainers(containers);
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
log.plain('');
|
|
66
|
+
log.plain(color.green(color.bold('✓ Database destroyed')));
|
|
67
|
+
return 0;
|
|
68
|
+
}
|