@constellation-network/node-pilot 0.0.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 +213 -0
- package/bin/dev.cmd +3 -0
- package/bin/dev.js +19 -0
- package/bin/run.cmd +3 -0
- package/bin/run.js +15 -0
- package/dist/checks/check-hardware.d.ts +3 -0
- package/dist/checks/check-hardware.js +50 -0
- package/dist/checks/check-initial-setup.d.ts +3 -0
- package/dist/checks/check-initial-setup.js +15 -0
- package/dist/checks/check-layers.d.ts +7 -0
- package/dist/checks/check-layers.js +87 -0
- package/dist/checks/check-network.d.ts +6 -0
- package/dist/checks/check-network.js +72 -0
- package/dist/checks/check-project.d.ts +6 -0
- package/dist/checks/check-project.js +108 -0
- package/dist/clm.d.ts +9 -0
- package/dist/clm.js +30 -0
- package/dist/commands/config/get.d.ts +9 -0
- package/dist/commands/config/get.js +37 -0
- package/dist/commands/config/set.d.ts +11 -0
- package/dist/commands/config/set.js +41 -0
- package/dist/commands/config.d.ts +6 -0
- package/dist/commands/config.js +65 -0
- package/dist/commands/info.d.ts +6 -0
- package/dist/commands/info.js +32 -0
- package/dist/commands/logs.d.ts +12 -0
- package/dist/commands/logs.js +28 -0
- package/dist/commands/restart.d.ts +6 -0
- package/dist/commands/restart.js +25 -0
- package/dist/commands/shutdown.d.ts +6 -0
- package/dist/commands/shutdown.js +18 -0
- package/dist/commands/status.d.ts +6 -0
- package/dist/commands/status.js +22 -0
- package/dist/commands/test.d.ts +6 -0
- package/dist/commands/test.js +13 -0
- package/dist/config-store.d.ts +109 -0
- package/dist/config-store.js +151 -0
- package/dist/helpers/config-helper.d.ts +14 -0
- package/dist/helpers/config-helper.js +39 -0
- package/dist/helpers/docker-helper.d.ts +7 -0
- package/dist/helpers/docker-helper.js +37 -0
- package/dist/helpers/env-templates.d.ts +4 -0
- package/dist/helpers/env-templates.js +33 -0
- package/dist/helpers/github-helper.d.ts +3 -0
- package/dist/helpers/github-helper.js +13 -0
- package/dist/helpers/key-file-helper.d.ts +9 -0
- package/dist/helpers/key-file-helper.js +136 -0
- package/dist/helpers/project-helper.d.ts +9 -0
- package/dist/helpers/project-helper.js +85 -0
- package/dist/helpers/prompt-helper.d.ts +8 -0
- package/dist/helpers/prompt-helper.js +135 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.js +1 -0
- package/dist/info/cluster-info.d.ts +1 -0
- package/dist/info/cluster-info.js +16 -0
- package/dist/services/cluster-service.d.ts +9 -0
- package/dist/services/cluster-service.js +67 -0
- package/dist/services/fastforward-service.d.ts +14 -0
- package/dist/services/fastforward-service.js +84 -0
- package/dist/services/node-service.d.ts +10 -0
- package/dist/services/node-service.js +117 -0
- package/dist/services/shell-service.d.ts +9 -0
- package/dist/services/shell-service.js +53 -0
- package/dist/styles.d.ts +4 -0
- package/dist/styles.js +5 -0
- package/dist/types.d.ts +22 -0
- package/dist/types.js +1 -0
- package/oclif.manifest.json +241 -0
- package/package.json +98 -0
- package/projects/hypergraph/Dockerfile +41 -0
- package/projects/hypergraph/docker-compose.yml +54 -0
- package/projects/hypergraph/entrypoint.sh +35 -0
- package/projects/hypergraph/layers/gl1.env +3 -0
- package/projects/hypergraph/networks/integrationnet.env +9 -0
- package/projects/hypergraph/networks/mainnet.env +8 -0
- package/projects/hypergraph/networks/testnet.env +9 -0
- package/projects/hypergraph/pilot.env +2 -0
- package/projects/hypergraph/scripts/docker-build.sh +7 -0
- package/projects/hypergraph/scripts/install-dependencies.sh +318 -0
- package/projects/hypergraph/scripts/install.sh +149 -0
- package/projects/scripts/docker-cleanup.sh +64 -0
package/README.md
ADDED
@@ -0,0 +1,213 @@
|
|
1
|
+
@constellation-network/node-pilot
|
2
|
+
=================
|
3
|
+
|
4
|
+
A new CLI generated with oclif
|
5
|
+
|
6
|
+
|
7
|
+
[](https://oclif.io)
|
8
|
+
[](https://npmjs.org/package/@constellation-network/node-pilot)
|
9
|
+
[](https://npmjs.org/package/@constellation-network/node-pilot)
|
10
|
+
|
11
|
+
|
12
|
+
<!-- toc -->
|
13
|
+
* [Usage](#usage)
|
14
|
+
* [Commands](#commands)
|
15
|
+
<!-- tocstop -->
|
16
|
+
# Usage
|
17
|
+
<!-- usage -->
|
18
|
+
```sh-session
|
19
|
+
$ npm install -g @constellation-network/node-pilot
|
20
|
+
$ cpilot COMMAND
|
21
|
+
running command...
|
22
|
+
$ cpilot (--version|-v)
|
23
|
+
@constellation-network/node-pilot/0.0.1 darwin-arm64 node-v22.15.0
|
24
|
+
$ cpilot --help [COMMAND]
|
25
|
+
USAGE
|
26
|
+
$ cpilot COMMAND
|
27
|
+
...
|
28
|
+
```
|
29
|
+
<!-- usagestop -->
|
30
|
+
# Commands
|
31
|
+
<!-- commands -->
|
32
|
+
* [`cpilot config`](#cpilot-config)
|
33
|
+
* [`cpilot config get [NAME]`](#cpilot-config-get-name)
|
34
|
+
* [`cpilot config set NAME VALUE`](#cpilot-config-set-name-value)
|
35
|
+
* [`cpilot help [COMMAND]`](#cpilot-help-command)
|
36
|
+
* [`cpilot info`](#cpilot-info)
|
37
|
+
* [`cpilot logs [LAYER]`](#cpilot-logs-layer)
|
38
|
+
* [`cpilot restart`](#cpilot-restart)
|
39
|
+
* [`cpilot shutdown`](#cpilot-shutdown)
|
40
|
+
* [`cpilot status`](#cpilot-status)
|
41
|
+
|
42
|
+
## `cpilot config`
|
43
|
+
|
44
|
+
Update configuration settings
|
45
|
+
|
46
|
+
```
|
47
|
+
USAGE
|
48
|
+
$ cpilot config
|
49
|
+
|
50
|
+
DESCRIPTION
|
51
|
+
Update configuration settings
|
52
|
+
|
53
|
+
EXAMPLES
|
54
|
+
$ cpilot config
|
55
|
+
```
|
56
|
+
|
57
|
+
_See code: [src/commands/config.ts](https://github.com/Constellation-Labs/node-pilot/blob/v0.0.1/src/commands/config.ts)_
|
58
|
+
|
59
|
+
## `cpilot config get [NAME]`
|
60
|
+
|
61
|
+
Show all configuration settings or a specific one
|
62
|
+
|
63
|
+
```
|
64
|
+
USAGE
|
65
|
+
$ cpilot config get [NAME]
|
66
|
+
|
67
|
+
ARGUMENTS
|
68
|
+
NAME configuration to get
|
69
|
+
|
70
|
+
DESCRIPTION
|
71
|
+
Show all configuration settings or a specific one
|
72
|
+
|
73
|
+
EXAMPLES
|
74
|
+
$ cpilot config get
|
75
|
+
|
76
|
+
$ cpilot config get CL_EXTERNAL_IP
|
77
|
+
|
78
|
+
$ cpilot config get gl0:CL_PUBLIC_HTTP_PORT
|
79
|
+
```
|
80
|
+
|
81
|
+
_See code: [src/commands/config/get.ts](https://github.com/Constellation-Labs/node-pilot/blob/v0.0.1/src/commands/config/get.ts)_
|
82
|
+
|
83
|
+
## `cpilot config set NAME VALUE`
|
84
|
+
|
85
|
+
Set a configuration setting
|
86
|
+
|
87
|
+
```
|
88
|
+
USAGE
|
89
|
+
$ cpilot config set NAME VALUE
|
90
|
+
|
91
|
+
ARGUMENTS
|
92
|
+
NAME configuration name
|
93
|
+
VALUE the value to set to the configuration
|
94
|
+
|
95
|
+
DESCRIPTION
|
96
|
+
Set a configuration setting
|
97
|
+
|
98
|
+
EXAMPLES
|
99
|
+
$ cpilot config set CL_EXTERNAL_IP 127.0.0.1
|
100
|
+
|
101
|
+
$ cpilot config set gl0:CL_PUBLIC_HTTP_PORT 9000
|
102
|
+
```
|
103
|
+
|
104
|
+
_See code: [src/commands/config/set.ts](https://github.com/Constellation-Labs/node-pilot/blob/v0.0.1/src/commands/config/set.ts)_
|
105
|
+
|
106
|
+
## `cpilot help [COMMAND]`
|
107
|
+
|
108
|
+
Display help for cpilot.
|
109
|
+
|
110
|
+
```
|
111
|
+
USAGE
|
112
|
+
$ cpilot help [COMMAND...] [-n]
|
113
|
+
|
114
|
+
ARGUMENTS
|
115
|
+
COMMAND... Command to show help for.
|
116
|
+
|
117
|
+
FLAGS
|
118
|
+
-n, --nested-commands Include all nested commands in the output.
|
119
|
+
|
120
|
+
DESCRIPTION
|
121
|
+
Display help for cpilot.
|
122
|
+
```
|
123
|
+
|
124
|
+
_See code: [@oclif/plugin-help](https://github.com/oclif/plugin-help/blob/v6.2.32/src/commands/help.ts)_
|
125
|
+
|
126
|
+
## `cpilot info`
|
127
|
+
|
128
|
+
Display general info about the validator node
|
129
|
+
|
130
|
+
```
|
131
|
+
USAGE
|
132
|
+
$ cpilot info
|
133
|
+
|
134
|
+
DESCRIPTION
|
135
|
+
Display general info about the validator node
|
136
|
+
|
137
|
+
EXAMPLES
|
138
|
+
$ cpilot info
|
139
|
+
```
|
140
|
+
|
141
|
+
_See code: [src/commands/info.ts](https://github.com/Constellation-Labs/node-pilot/blob/v0.0.1/src/commands/info.ts)_
|
142
|
+
|
143
|
+
## `cpilot logs [LAYER]`
|
144
|
+
|
145
|
+
view validator node runtime logs
|
146
|
+
|
147
|
+
```
|
148
|
+
USAGE
|
149
|
+
$ cpilot logs [LAYER] [-f]
|
150
|
+
|
151
|
+
ARGUMENTS
|
152
|
+
LAYER network layer to view. e.g. gl0
|
153
|
+
|
154
|
+
FLAGS
|
155
|
+
-f, --follow continuously wait for additional data to be appended
|
156
|
+
|
157
|
+
DESCRIPTION
|
158
|
+
view validator node runtime logs
|
159
|
+
|
160
|
+
EXAMPLES
|
161
|
+
$ cpilot logs
|
162
|
+
```
|
163
|
+
|
164
|
+
_See code: [src/commands/logs.ts](https://github.com/Constellation-Labs/node-pilot/blob/v0.0.1/src/commands/logs.ts)_
|
165
|
+
|
166
|
+
## `cpilot restart`
|
167
|
+
|
168
|
+
A full shutdown of the validator node, then restart
|
169
|
+
|
170
|
+
```
|
171
|
+
USAGE
|
172
|
+
$ cpilot restart
|
173
|
+
|
174
|
+
DESCRIPTION
|
175
|
+
A full shutdown of the validator node, then restart
|
176
|
+
|
177
|
+
EXAMPLES
|
178
|
+
$ cpilot restart
|
179
|
+
```
|
180
|
+
|
181
|
+
_See code: [src/commands/restart.ts](https://github.com/Constellation-Labs/node-pilot/blob/v0.0.1/src/commands/restart.ts)_
|
182
|
+
|
183
|
+
## `cpilot shutdown`
|
184
|
+
|
185
|
+
A full shutdown of the validator node
|
186
|
+
|
187
|
+
```
|
188
|
+
USAGE
|
189
|
+
$ cpilot shutdown
|
190
|
+
|
191
|
+
DESCRIPTION
|
192
|
+
A full shutdown of the validator node
|
193
|
+
|
194
|
+
EXAMPLES
|
195
|
+
$ cpilot shutdown
|
196
|
+
```
|
197
|
+
|
198
|
+
_See code: [src/commands/shutdown.ts](https://github.com/Constellation-Labs/node-pilot/blob/v0.0.1/src/commands/shutdown.ts)_
|
199
|
+
|
200
|
+
## `cpilot status`
|
201
|
+
|
202
|
+
Display node status and configuration settings
|
203
|
+
|
204
|
+
```
|
205
|
+
USAGE
|
206
|
+
$ cpilot status
|
207
|
+
|
208
|
+
DESCRIPTION
|
209
|
+
Display node status and configuration settings
|
210
|
+
```
|
211
|
+
|
212
|
+
_See code: [src/commands/status.ts](https://github.com/Constellation-Labs/node-pilot/blob/v0.0.1/src/commands/status.ts)_
|
213
|
+
<!-- commandsstop -->
|
package/bin/dev.cmd
ADDED
package/bin/dev.js
ADDED
@@ -0,0 +1,19 @@
|
|
1
|
+
#!/usr/bin/env -S node --loader ts-node/esm --disable-warning=ExperimentalWarning --disable-warning=DeprecationWarning
|
2
|
+
const skipDefaultCommand = {
|
3
|
+
'--help': true, '--version': true, '-h': true, '-v': true,
|
4
|
+
}
|
5
|
+
if (process.argv.length === 2) {
|
6
|
+
process.argv[2] = 'status';
|
7
|
+
}
|
8
|
+
else if (process.argv.length > 2 && process.argv[2].startsWith('-') && !skipDefaultCommand[process.argv[2]]) {
|
9
|
+
process.argv.splice(2, 0 , 'status');
|
10
|
+
}
|
11
|
+
|
12
|
+
import {execute} from '@oclif/core'
|
13
|
+
|
14
|
+
await execute({development: true, dir: import.meta.url})
|
15
|
+
|
16
|
+
// eslint-disable-next-line no-warning-comments
|
17
|
+
// TODO
|
18
|
+
// cpilot config set project pacaswap-metagraph
|
19
|
+
// cpilot config --project pacaswap-metagraph
|
package/bin/run.cmd
ADDED
package/bin/run.js
ADDED
@@ -0,0 +1,15 @@
|
|
1
|
+
#!/usr/bin/env node
|
2
|
+
|
3
|
+
const skipDefaultCommand = {
|
4
|
+
'--help': true, '--version': true, '-h': true, '-v': true,
|
5
|
+
}
|
6
|
+
if (process.argv.length === 2) {
|
7
|
+
process.argv[2] = 'status';
|
8
|
+
}
|
9
|
+
else if (process.argv.length > 2 && process.argv[2].startsWith('-') && !skipDefaultCommand[process.argv[2]]) {
|
10
|
+
process.argv.splice(2, 0 , 'status');
|
11
|
+
}
|
12
|
+
|
13
|
+
import {execute} from '@oclif/core'
|
14
|
+
|
15
|
+
await execute({dir: import.meta.url})
|
@@ -0,0 +1,50 @@
|
|
1
|
+
import chalk from "chalk";
|
2
|
+
import fs from "node:fs";
|
3
|
+
import os from "node:os";
|
4
|
+
import ttyTable from "tty-table";
|
5
|
+
import { clm } from "../clm.js";
|
6
|
+
import { configStore } from "../config-store.js";
|
7
|
+
import { promptHelper } from "../helpers/prompt-helper.js";
|
8
|
+
export const checkHardware = {
|
9
|
+
async systemRequirements() {
|
10
|
+
clm.preStep('Checking hardware requirements...');
|
11
|
+
// Retrieve disk space
|
12
|
+
const r = fs.statfsSync('/');
|
13
|
+
const totalSpaceGB = (r.bsize * r.blocks / (1024 * 1024 * 1024)).toFixed(2);
|
14
|
+
// const usage = diskusage.checkSync(os.homedir());
|
15
|
+
// const usableSpaceGB = (usage.total / (1024 * 1024 * 1024)).toFixed(2);
|
16
|
+
// Retrieve sys memory
|
17
|
+
const totalMemoryBytes = os.totalmem();
|
18
|
+
const totalMemoryGB = (totalMemoryBytes / (1024 * 1024 * 1024)).toFixed(2);
|
19
|
+
// Retrieve number of CPU cores
|
20
|
+
const numOfCores = os.availableParallelism();
|
21
|
+
let allPassed = true;
|
22
|
+
const formatActual = (value, recommended, units = '') => {
|
23
|
+
const passed = Number(value) >= recommended;
|
24
|
+
allPassed = allPassed && passed;
|
25
|
+
return passed ? chalk.greenBright(value + units) : chalk.redBright(value + units);
|
26
|
+
};
|
27
|
+
// eslint-disable-next-line unicorn/consistent-function-scoping
|
28
|
+
const fc = (value) => chalk.white(value);
|
29
|
+
const header = [
|
30
|
+
{ headerColor: 'white', value: 'HARDWARE' },
|
31
|
+
{ headerColor: 'white', value: 'RECOMMENDED' },
|
32
|
+
{ headerColor: 'white', value: 'ACTUAL' },
|
33
|
+
];
|
34
|
+
const rows = [
|
35
|
+
[fc("Disk size"), fc("320 GB"), formatActual(totalSpaceGB, 320, " GB")],
|
36
|
+
[fc("System memory"), fc("8 GB"), formatActual(totalMemoryGB, 8, " GB")],
|
37
|
+
[fc("CPU cores"), fc("8 cores"), formatActual(numOfCores, 8, " cores")],
|
38
|
+
];
|
39
|
+
clm.echo(ttyTable(header, rows).render() + "\n");
|
40
|
+
if (allPassed) {
|
41
|
+
clm.postStep(" ✅ System requirements check passed ✅\n");
|
42
|
+
await promptHelper.doYouWishToContinue();
|
43
|
+
}
|
44
|
+
else {
|
45
|
+
clm.warn("System recommendations not met. The validator node may not function properly.\n");
|
46
|
+
await promptHelper.doYouWishToContinue('n');
|
47
|
+
}
|
48
|
+
configStore.setSystemInfo({ cores: numOfCores, disk: totalSpaceGB, memory: totalMemoryGB, platform: os.platform() });
|
49
|
+
}
|
50
|
+
};
|
@@ -0,0 +1,15 @@
|
|
1
|
+
import chalk from "chalk";
|
2
|
+
import { configStore } from "../config-store.js";
|
3
|
+
import { checkHardware } from "./check-hardware.js";
|
4
|
+
export const checkInitialSetup = {
|
5
|
+
async firstTimeRun() {
|
6
|
+
if (configStore.getSystemInfo() !== null) {
|
7
|
+
return;
|
8
|
+
}
|
9
|
+
console.log(chalk.white("\n ****************************************"));
|
10
|
+
console.log(" " + chalk.white("CONSTELLATION NETWORK") + " ");
|
11
|
+
console.log(" " + chalk.white("NODE PILOT") + " ");
|
12
|
+
console.log(chalk.white(" ****************************************"));
|
13
|
+
await checkHardware.systemRequirements();
|
14
|
+
},
|
15
|
+
};
|
@@ -0,0 +1,87 @@
|
|
1
|
+
import { input } from "@inquirer/prompts";
|
2
|
+
import chalk from "chalk";
|
3
|
+
import { clm } from "../clm.js";
|
4
|
+
import { configStore } from "../config-store.js";
|
5
|
+
import { dockerHelper } from "../helpers/docker-helper.js";
|
6
|
+
import { nodeService } from "../services/node-service.js";
|
7
|
+
export const checkLayers = {
|
8
|
+
async layersReadyToJoin() {
|
9
|
+
const { layersToRun } = configStore.getProjectInfo();
|
10
|
+
for (const layer of layersToRun) {
|
11
|
+
// eslint-disable-next-line no-await-in-loop
|
12
|
+
await this.nodeReadyToJoin(layer);
|
13
|
+
}
|
14
|
+
},
|
15
|
+
async layersRunning() {
|
16
|
+
const { layersToRun } = configStore.getProjectInfo();
|
17
|
+
const promises = layersToRun.map(l => nodeService.getNodeInfo(l));
|
18
|
+
const results = await Promise.all(promises);
|
19
|
+
const notRunningLayers = results.filter(r => r.state === "Unavailable");
|
20
|
+
if (notRunningLayers.length === layersToRun.length) {
|
21
|
+
const single = layersToRun.length === 1;
|
22
|
+
if (single) {
|
23
|
+
clm.preStep(`The Validator Node is not running.`);
|
24
|
+
}
|
25
|
+
else {
|
26
|
+
clm.preStep(`All the Validator Node layers [${layersToRun}] are not running.`);
|
27
|
+
}
|
28
|
+
await input({ default: 'y', message: 'Would you like to start the validator(s)? (y/n): ' }).then(async (answer) => {
|
29
|
+
if (answer.toLowerCase() === 'y') {
|
30
|
+
await dockerHelper.dockerBuild();
|
31
|
+
clm.preStep('Starting the node...');
|
32
|
+
await dockerHelper.dockerUp();
|
33
|
+
await nodeService.pollForLayersState(layersToRun);
|
34
|
+
}
|
35
|
+
else {
|
36
|
+
clm.postStep('Node not started.');
|
37
|
+
}
|
38
|
+
});
|
39
|
+
}
|
40
|
+
else if (notRunningLayers.length > 0) {
|
41
|
+
const layersNotRunning = notRunningLayers.map(r => r.layer);
|
42
|
+
clm.preStep('The following Validator Node layers are not running: ' + chalk.cyan(layersNotRunning.join(', ')));
|
43
|
+
await input({ default: 'y', message: 'Would you like to restart the docker containers? (y/n): ' }).then(async (answer) => {
|
44
|
+
if (answer.toLowerCase() === 'y') {
|
45
|
+
clm.preStep('Restarting docker containers...');
|
46
|
+
await dockerHelper.dockerUp();
|
47
|
+
await nodeService.pollForLayersState(layersToRun);
|
48
|
+
}
|
49
|
+
else {
|
50
|
+
clm.echo('Node not started.');
|
51
|
+
}
|
52
|
+
});
|
53
|
+
}
|
54
|
+
else {
|
55
|
+
const single = layersToRun.length === 1;
|
56
|
+
if (single) {
|
57
|
+
clm.postStep(`The Validator Node is running.`);
|
58
|
+
}
|
59
|
+
else {
|
60
|
+
clm.postStep(`All Validator Node layers are running: ${layersToRun.join(', ')}.`);
|
61
|
+
}
|
62
|
+
}
|
63
|
+
},
|
64
|
+
async layersStatus() {
|
65
|
+
const { layersToRun } = configStore.getProjectInfo();
|
66
|
+
const promises = layersToRun.map(l => nodeService.getNodeInfo(l));
|
67
|
+
const results = await Promise.all(promises);
|
68
|
+
const states = results.map(r => r.state);
|
69
|
+
clm.preStep("-----------------------");
|
70
|
+
clm.preStep(" VALIDATOR NODE STATUS ");
|
71
|
+
clm.preStep("-----------------------");
|
72
|
+
for (const [i, layer] of layersToRun.entries()) {
|
73
|
+
const state = states[i];
|
74
|
+
clm.step(` "${layer.toUpperCase()}" is "${state}"`);
|
75
|
+
}
|
76
|
+
},
|
77
|
+
async nodeReadyToJoin(layer) {
|
78
|
+
const status = await nodeService.getNodeInfo(layer);
|
79
|
+
if (status.state === "ReadyToJoin") {
|
80
|
+
await input({ default: 'y', message: `The validator node layer "${layer.toUpperCase()}" is ready to join the cluster. Would you like to join now? (y/n): ` }).then(async (answer) => {
|
81
|
+
if (answer.toLowerCase() === 'y') {
|
82
|
+
await nodeService.joinCluster(layer);
|
83
|
+
}
|
84
|
+
});
|
85
|
+
}
|
86
|
+
},
|
87
|
+
};
|
@@ -0,0 +1,72 @@
|
|
1
|
+
import { input, select } from "@inquirer/prompts";
|
2
|
+
import chalk from "chalk";
|
3
|
+
import { clm } from "../clm.js";
|
4
|
+
import { configStore } from "../config-store.js";
|
5
|
+
export const checkNetwork = {
|
6
|
+
async configureIpAddress() {
|
7
|
+
const { CL_EXTERNAL_IP: currentIpAddress } = configStore.getEnvCommonInfo();
|
8
|
+
const detectedIpAddress = await checkNetwork.fetchIPAddress().catch(() => '');
|
9
|
+
if (!currentIpAddress && !detectedIpAddress) {
|
10
|
+
const newIpAddress = await checkNetwork.enterIpAddressManually();
|
11
|
+
configStore.setEnvCommonInfo({ CL_EXTERNAL_IP: newIpAddress });
|
12
|
+
return;
|
13
|
+
}
|
14
|
+
if (currentIpAddress) {
|
15
|
+
clm.postStep("\nIP address is currently set to: " + chalk.cyan(currentIpAddress));
|
16
|
+
}
|
17
|
+
if (detectedIpAddress) {
|
18
|
+
clm.postStep("\nDetected IP address: " + chalk.cyan(detectedIpAddress) + "\n");
|
19
|
+
}
|
20
|
+
const choices = [{
|
21
|
+
disabled: !currentIpAddress,
|
22
|
+
name: 'Keep current IP address',
|
23
|
+
value: 'current'
|
24
|
+
}, {
|
25
|
+
disabled: !detectedIpAddress,
|
26
|
+
name: 'Use detected IP address',
|
27
|
+
value: 'detected'
|
28
|
+
}, {
|
29
|
+
name: 'Enter IP address manually:',
|
30
|
+
value: 'manual'
|
31
|
+
}];
|
32
|
+
const answer = await select({ choices, message: '' });
|
33
|
+
let selectedIpAddress = currentIpAddress;
|
34
|
+
if (answer === 'detected') {
|
35
|
+
selectedIpAddress = detectedIpAddress;
|
36
|
+
}
|
37
|
+
else if (answer === 'manual') {
|
38
|
+
selectedIpAddress = await checkNetwork.enterIpAddressManually();
|
39
|
+
}
|
40
|
+
configStore.setEnvCommonInfo({ CL_EXTERNAL_IP: selectedIpAddress });
|
41
|
+
},
|
42
|
+
async detectExternalIpAddress() {
|
43
|
+
const externalIp = await this.fetchIPAddress()
|
44
|
+
.catch(error => {
|
45
|
+
clm.warn(`Error while detecting your IP address: ${error.message}`);
|
46
|
+
return this.enterIpAddressManually();
|
47
|
+
});
|
48
|
+
clm.postStep("\nExternal IP address: " + chalk.cyan(externalIp) + "\n");
|
49
|
+
configStore.setEnvCommonInfo({ CL_EXTERNAL_IP: externalIp });
|
50
|
+
},
|
51
|
+
async enterIpAddressManually() {
|
52
|
+
return input({
|
53
|
+
message: 'Please enter the IP address manually:',
|
54
|
+
validate(value) {
|
55
|
+
// Basic validation for IP address format
|
56
|
+
const ipRegex = /^(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$/;
|
57
|
+
if (ipRegex.test(value.trim())) {
|
58
|
+
return true;
|
59
|
+
}
|
60
|
+
return 'Please enter a valid IP address (e.g., 192.168.1.1)';
|
61
|
+
}
|
62
|
+
});
|
63
|
+
},
|
64
|
+
async fetchIPAddress() {
|
65
|
+
return fetch('https://ifconfig.me/ip')
|
66
|
+
.then(res => {
|
67
|
+
if (res.ok)
|
68
|
+
return res.text();
|
69
|
+
throw new Error('Failed to fetch IP address');
|
70
|
+
});
|
71
|
+
}
|
72
|
+
};
|
@@ -0,0 +1,108 @@
|
|
1
|
+
import { input, select } from "@inquirer/prompts";
|
2
|
+
import { clm } from "../clm.js";
|
3
|
+
import { configStore } from "../config-store.js";
|
4
|
+
import { configHelper } from "../helpers/config-helper.js";
|
5
|
+
import { dockerHelper } from "../helpers/docker-helper.js";
|
6
|
+
import { promptHelper } from "../helpers/prompt-helper.js";
|
7
|
+
import { clusterService } from "../services/cluster-service.js";
|
8
|
+
import { nodeService } from "../services/node-service.js";
|
9
|
+
import { shellService } from "../services/shell-service.js";
|
10
|
+
import { checkNetwork } from "./check-network.js";
|
11
|
+
export const checkProject = {
|
12
|
+
async projectInstallation() {
|
13
|
+
let updateNetworkType = false;
|
14
|
+
let updateLayers = false;
|
15
|
+
if (!configStore.hasProjects() || process.env.PILOT_ENV === 'test') {
|
16
|
+
await promptHelper.selectProject();
|
17
|
+
await checkNetwork.configureIpAddress();
|
18
|
+
updateNetworkType = true;
|
19
|
+
updateLayers = true;
|
20
|
+
}
|
21
|
+
const { layersToRun } = configStore.getProjectInfo();
|
22
|
+
const { type } = configStore.getNetworkInfo();
|
23
|
+
if (!type || updateNetworkType) {
|
24
|
+
await promptHelper.selectNetwork();
|
25
|
+
updateLayers = true;
|
26
|
+
}
|
27
|
+
if (!layersToRun || updateLayers) {
|
28
|
+
await promptHelper.selectLayers();
|
29
|
+
await promptHelper.configureJavaMemoryArguments();
|
30
|
+
}
|
31
|
+
},
|
32
|
+
async releaseVersion() {
|
33
|
+
const nInfo = configStore.getNetworkInfo();
|
34
|
+
if (!nInfo.type) {
|
35
|
+
await this.projectInstallation();
|
36
|
+
}
|
37
|
+
let requiresInstall = false;
|
38
|
+
const rInfo = await configHelper.getReleaseInfo();
|
39
|
+
if (!rInfo) {
|
40
|
+
requiresInstall = true;
|
41
|
+
}
|
42
|
+
else if (rInfo.network !== nInfo.type) {
|
43
|
+
clm.preStep(`Network type has changed between user configuration and the node installation`);
|
44
|
+
const selectedNetwork = await select({
|
45
|
+
choices: [
|
46
|
+
{ name: `Keep current (${rInfo.network})`, value: rInfo.network },
|
47
|
+
{ name: `Switch to ${nInfo.type}`, value: nInfo.type }
|
48
|
+
],
|
49
|
+
message: 'Select network type:'
|
50
|
+
});
|
51
|
+
configStore.setNetworkInfo({
|
52
|
+
type: selectedNetwork,
|
53
|
+
version: selectedNetwork === rInfo.network ? rInfo.version : nInfo.version
|
54
|
+
});
|
55
|
+
if (selectedNetwork !== rInfo.network) {
|
56
|
+
requiresInstall = true;
|
57
|
+
}
|
58
|
+
}
|
59
|
+
else if (rInfo.version !== nInfo.version) {
|
60
|
+
configStore.setNetworkInfo({ type: rInfo.network, version: rInfo.version });
|
61
|
+
}
|
62
|
+
const clusterVersionInfo = await clusterService.getReleaseVersion();
|
63
|
+
if (!requiresInstall) {
|
64
|
+
const nInfo = configStore.getNetworkInfo();
|
65
|
+
if (nInfo.version !== clusterVersionInfo) {
|
66
|
+
const answer = await input({
|
67
|
+
default: 'y',
|
68
|
+
message: `A new required network version has been detected. Do you want to upgrade now? (y/n): `
|
69
|
+
});
|
70
|
+
if (answer !== 'y') {
|
71
|
+
process.exit(0);
|
72
|
+
}
|
73
|
+
requiresInstall = true;
|
74
|
+
}
|
75
|
+
}
|
76
|
+
if (requiresInstall) {
|
77
|
+
await this.runInstall();
|
78
|
+
}
|
79
|
+
},
|
80
|
+
async runInstall() {
|
81
|
+
const nInfo = configStore.getNetworkInfo();
|
82
|
+
let rInfo = await configHelper.getReleaseInfo();
|
83
|
+
if (rInfo && rInfo.network === nInfo.type) {
|
84
|
+
clm.postStep(`Network files are already installed for ${nInfo.type}`);
|
85
|
+
return false;
|
86
|
+
}
|
87
|
+
const nodeInfo = await nodeService.getNodeInfo('first');
|
88
|
+
const isRunning = nodeInfo.state !== 'Unavailable';
|
89
|
+
if (isRunning) {
|
90
|
+
await dockerHelper.dockerDown();
|
91
|
+
}
|
92
|
+
clm.preStep('Running install script...');
|
93
|
+
const silent = false; // !process.env.DEBUG;
|
94
|
+
await shellService.runCommand(`scripts/install.sh ${nInfo.type}`, undefined, silent); // different for metagraphs
|
95
|
+
rInfo = await configHelper.getReleaseInfo();
|
96
|
+
configStore.setNetworkInfo({
|
97
|
+
type: rInfo.network,
|
98
|
+
version: rInfo.version
|
99
|
+
});
|
100
|
+
return true;
|
101
|
+
},
|
102
|
+
async runUpgrade() {
|
103
|
+
const changed = await this.runInstall();
|
104
|
+
if (changed) {
|
105
|
+
await dockerHelper.dockerBuild();
|
106
|
+
}
|
107
|
+
}
|
108
|
+
};
|
package/dist/clm.d.ts
ADDED
package/dist/clm.js
ADDED
@@ -0,0 +1,30 @@
|
|
1
|
+
import chalk from "chalk";
|
2
|
+
/*
|
3
|
+
Command Line Messaging with color styling
|
4
|
+
*/
|
5
|
+
export const clm = {
|
6
|
+
debug(msg) {
|
7
|
+
if (process.env.DEBUG === 'true') {
|
8
|
+
console.log('[debug]', msg);
|
9
|
+
}
|
10
|
+
},
|
11
|
+
echo(msg) {
|
12
|
+
console.log(msg);
|
13
|
+
},
|
14
|
+
error(msg, silent = true) {
|
15
|
+
console.error(chalk.red(msg));
|
16
|
+
process.exit(silent ? 0 : 1);
|
17
|
+
},
|
18
|
+
postStep(s) {
|
19
|
+
console.log(chalk.green(s));
|
20
|
+
},
|
21
|
+
preStep(s) {
|
22
|
+
console.log('\n', chalk.italic(chalk.green(s)));
|
23
|
+
},
|
24
|
+
step(msg) {
|
25
|
+
console.warn(chalk.whiteBright(msg));
|
26
|
+
},
|
27
|
+
warn(msg) {
|
28
|
+
console.warn(chalk.red(msg));
|
29
|
+
}
|
30
|
+
};
|
@@ -0,0 +1,9 @@
|
|
1
|
+
import { Command } from '@oclif/core';
|
2
|
+
export default class ConfigGet extends Command {
|
3
|
+
static args: {
|
4
|
+
name: import("@oclif/core/interfaces").Arg<string | undefined, Record<string, unknown>>;
|
5
|
+
};
|
6
|
+
static description: string;
|
7
|
+
static examples: string[];
|
8
|
+
run(): Promise<void>;
|
9
|
+
}
|