@constellation-network/node-pilot 0.0.8 → 0.0.10
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 +26 -15
- package/bin/dev.js +1 -6
- package/bin/run.js +1 -1
- package/dist/base-command.d.ts +9 -0
- package/dist/base-command.js +20 -0
- package/dist/checks/check-hardware.js +3 -3
- package/dist/checks/check-initial-setup.js +2 -0
- package/dist/checks/check-layers.js +7 -7
- package/dist/checks/check-network.d.ts +2 -0
- package/dist/checks/check-network.js +46 -11
- package/dist/checks/check-node-ctl.js +4 -4
- package/dist/checks/check-project.d.ts +1 -0
- package/dist/checks/check-project.js +15 -4
- package/dist/checks/check-wallet.d.ts +3 -0
- package/dist/checks/check-wallet.js +37 -0
- package/dist/clm.d.ts +1 -0
- package/dist/clm.js +3 -0
- package/dist/commands/config/get.d.ts +6 -0
- package/dist/commands/config/get.js +57 -11
- package/dist/commands/config/set.d.ts +0 -1
- package/dist/commands/config/set.js +13 -11
- package/dist/commands/config.js +17 -22
- package/dist/commands/info.js +3 -2
- package/dist/commands/logs.d.ts +1 -1
- package/dist/commands/logs.js +7 -3
- package/dist/commands/restart.d.ts +10 -2
- package/dist/commands/restart.js +65 -9
- package/dist/commands/shutdown.js +3 -3
- package/dist/commands/status.js +4 -0
- package/dist/commands/test.js +10 -3
- package/dist/config-store.d.ts +47 -31
- package/dist/config-store.js +98 -42
- package/dist/helpers/config-helper.js +2 -2
- package/dist/helpers/env-templates.d.ts +4 -3
- package/dist/helpers/env-templates.js +28 -20
- package/dist/helpers/key-file-helper.d.ts +2 -0
- package/dist/helpers/key-file-helper.js +51 -16
- package/dist/helpers/project-helper.d.ts +2 -2
- package/dist/helpers/project-helper.js +37 -38
- package/dist/helpers/prompt-helper.d.ts +0 -1
- package/dist/helpers/prompt-helper.js +15 -15
- package/dist/services/archiver-service.d.ts +17 -0
- package/dist/services/archiver-service.js +104 -0
- package/dist/services/cluster-service.d.ts +10 -6
- package/dist/services/cluster-service.js +45 -45
- package/dist/services/docker-service.d.ts +9 -0
- package/dist/{helpers/docker-helper.js → services/docker-service.js} +11 -9
- package/dist/services/fastforward-service.js +3 -3
- package/dist/services/get-random-node.js +1 -1
- package/dist/{helpers/github-helper.d.ts → services/github-service.d.ts} +1 -1
- package/dist/{helpers/github-helper.js → services/github-service.js} +1 -1
- package/dist/services/node-service.js +14 -14
- package/dist/services/notify-service.d.ts +1 -0
- package/dist/services/notify-service.js +1 -0
- package/dist/services/systemd-service.d.ts +3 -0
- package/dist/services/systemd-service.js +45 -0
- package/dist/test.d.ts +1 -0
- package/dist/test.js +50 -0
- package/dist/types.d.ts +6 -0
- package/install-dependencies.sh +0 -2
- package/oclif.manifest.json +33 -4
- package/package.json +9 -8
- package/projects/custom/pilot.json +9 -0
- package/projects/hypergraph/Dockerfile +24 -18
- package/projects/hypergraph/docker-compose.yml +14 -14
- package/projects/hypergraph/networks/integrationnet/gl0.env +4 -0
- package/projects/hypergraph/networks/integrationnet/gl1.env +4 -0
- package/projects/hypergraph/networks/integrationnet/network.env +8 -0
- package/projects/hypergraph/networks/{integrationnet.env → integrationnet/source-nodes.env} +1 -9
- package/projects/hypergraph/networks/mainnet/gl0.env +4 -0
- package/projects/hypergraph/networks/mainnet/gl1.env +4 -0
- package/projects/hypergraph/networks/mainnet/network.env +8 -0
- package/projects/hypergraph/networks/{mainnet.env → mainnet/source-nodes.env} +0 -8
- package/projects/hypergraph/networks/testnet/gl0.env +5 -0
- package/projects/hypergraph/networks/testnet/gl1.env +4 -0
- package/projects/hypergraph/networks/testnet/network.env +8 -0
- package/projects/hypergraph/networks/{testnet.env → testnet/source-nodes.env} +0 -8
- package/projects/hypergraph/scripts/check-version.sh +31 -0
- package/projects/hypergraph/scripts/install.sh +30 -25
- package/projects/hypergraph/seedlist +268 -0
- package/scripts/autoheal.sh +8 -0
- package/scripts/restart_logger.sh +3 -0
- package/scripts/services/io.constellationnetwork.nodepilot.Updater.plist +16 -0
- package/scripts/services/node-pilot-autoheal.service +12 -0
- package/scripts/services/node-pilot-restarter.service +11 -0
- package/scripts/services/node-pilot-updater.service +13 -0
- package/scripts/update_logger.sh +3 -0
- package/dist/helpers/docker-helper.d.ts +0 -7
- package/projects/hypergraph/layers/gl1.env +0 -3
- package/projects/scripts/docker-cleanup.sh +0 -64
package/README.md
CHANGED
@@ -21,7 +21,7 @@ $ npm install -g @constellation-network/node-pilot
|
|
21
21
|
$ cpilot COMMAND
|
22
22
|
running command...
|
23
23
|
$ cpilot (--version|-v)
|
24
|
-
@constellation-network/node-pilot/0.0.
|
24
|
+
@constellation-network/node-pilot/0.0.10 darwin-arm64 node-v22.15.0
|
25
25
|
$ cpilot --help [COMMAND]
|
26
26
|
USAGE
|
27
27
|
$ cpilot COMMAND
|
@@ -42,8 +42,8 @@ If no command is entered, node-pilot will automatically perform a series of chec
|
|
42
42
|
* [`cpilot config set NAME VALUE`](#cpilot-config-set-name-value)
|
43
43
|
* [`cpilot help [COMMAND]`](#cpilot-help-command)
|
44
44
|
* [`cpilot info`](#cpilot-info)
|
45
|
-
* [`cpilot logs
|
46
|
-
* [`cpilot restart`](#cpilot-restart)
|
45
|
+
* [`cpilot logs LAYER`](#cpilot-logs-layer)
|
46
|
+
* [`cpilot restart [LAYER]`](#cpilot-restart-layer)
|
47
47
|
* [`cpilot shutdown`](#cpilot-shutdown)
|
48
48
|
* [`cpilot status`](#cpilot-status)
|
49
49
|
|
@@ -62,7 +62,7 @@ EXAMPLES
|
|
62
62
|
$ cpilot config
|
63
63
|
```
|
64
64
|
|
65
|
-
_See code: [src/commands/config.ts](https://github.com/Constellation-Labs/node-pilot/blob/v0.0.
|
65
|
+
_See code: [src/commands/config.ts](https://github.com/Constellation-Labs/node-pilot/blob/v0.0.10/src/commands/config.ts)_
|
66
66
|
|
67
67
|
## `cpilot config get [NAME]`
|
68
68
|
|
@@ -86,7 +86,7 @@ EXAMPLES
|
|
86
86
|
$ cpilot config get gl0:CL_PUBLIC_HTTP_PORT
|
87
87
|
```
|
88
88
|
|
89
|
-
_See code: [src/commands/config/get.ts](https://github.com/Constellation-Labs/node-pilot/blob/v0.0.
|
89
|
+
_See code: [src/commands/config/get.ts](https://github.com/Constellation-Labs/node-pilot/blob/v0.0.10/src/commands/config/get.ts)_
|
90
90
|
|
91
91
|
## `cpilot config set NAME VALUE`
|
92
92
|
|
@@ -109,7 +109,7 @@ EXAMPLES
|
|
109
109
|
$ cpilot config set gl0:CL_PUBLIC_HTTP_PORT 9000
|
110
110
|
```
|
111
111
|
|
112
|
-
_See code: [src/commands/config/set.ts](https://github.com/Constellation-Labs/node-pilot/blob/v0.0.
|
112
|
+
_See code: [src/commands/config/set.ts](https://github.com/Constellation-Labs/node-pilot/blob/v0.0.10/src/commands/config/set.ts)_
|
113
113
|
|
114
114
|
## `cpilot help [COMMAND]`
|
115
115
|
|
@@ -146,15 +146,15 @@ EXAMPLES
|
|
146
146
|
$ cpilot info
|
147
147
|
```
|
148
148
|
|
149
|
-
_See code: [src/commands/info.ts](https://github.com/Constellation-Labs/node-pilot/blob/v0.0.
|
149
|
+
_See code: [src/commands/info.ts](https://github.com/Constellation-Labs/node-pilot/blob/v0.0.10/src/commands/info.ts)_
|
150
150
|
|
151
|
-
## `cpilot logs
|
151
|
+
## `cpilot logs LAYER`
|
152
152
|
|
153
153
|
view validator node runtime logs
|
154
154
|
|
155
155
|
```
|
156
156
|
USAGE
|
157
|
-
$ cpilot logs
|
157
|
+
$ cpilot logs LAYER [-f] [-n <value>]
|
158
158
|
|
159
159
|
ARGUMENTS
|
160
160
|
LAYER network layer to view. e.g. gl0
|
@@ -170,15 +170,26 @@ EXAMPLES
|
|
170
170
|
$ cpilot logs
|
171
171
|
```
|
172
172
|
|
173
|
-
_See code: [src/commands/logs.ts](https://github.com/Constellation-Labs/node-pilot/blob/v0.0.
|
173
|
+
_See code: [src/commands/logs.ts](https://github.com/Constellation-Labs/node-pilot/blob/v0.0.10/src/commands/logs.ts)_
|
174
174
|
|
175
|
-
## `cpilot restart`
|
175
|
+
## `cpilot restart [LAYER]`
|
176
176
|
|
177
177
|
A full shutdown of the validator node, then restart
|
178
178
|
|
179
179
|
```
|
180
180
|
USAGE
|
181
|
-
$ cpilot restart
|
181
|
+
$ cpilot restart [LAYER] [-p ] [--autostart] [--update]
|
182
|
+
|
183
|
+
ARGUMENTS
|
184
|
+
LAYER network layer to restart. e.g. gl0
|
185
|
+
|
186
|
+
FLAGS
|
187
|
+
--autostart restart each running project if it has been stopped
|
188
|
+
--update update each project if a new version is available
|
189
|
+
|
190
|
+
GLOBAL FLAGS
|
191
|
+
-p, --project=<option> Specify the project name to use
|
192
|
+
<options: >
|
182
193
|
|
183
194
|
DESCRIPTION
|
184
195
|
A full shutdown of the validator node, then restart
|
@@ -187,7 +198,7 @@ EXAMPLES
|
|
187
198
|
$ cpilot restart
|
188
199
|
```
|
189
200
|
|
190
|
-
_See code: [src/commands/restart.ts](https://github.com/Constellation-Labs/node-pilot/blob/v0.0.
|
201
|
+
_See code: [src/commands/restart.ts](https://github.com/Constellation-Labs/node-pilot/blob/v0.0.10/src/commands/restart.ts)_
|
191
202
|
|
192
203
|
## `cpilot shutdown`
|
193
204
|
|
@@ -204,7 +215,7 @@ EXAMPLES
|
|
204
215
|
$ cpilot shutdown
|
205
216
|
```
|
206
217
|
|
207
|
-
_See code: [src/commands/shutdown.ts](https://github.com/Constellation-Labs/node-pilot/blob/v0.0.
|
218
|
+
_See code: [src/commands/shutdown.ts](https://github.com/Constellation-Labs/node-pilot/blob/v0.0.10/src/commands/shutdown.ts)_
|
208
219
|
|
209
220
|
## `cpilot status`
|
210
221
|
|
@@ -218,5 +229,5 @@ DESCRIPTION
|
|
218
229
|
Display node status and configuration settings
|
219
230
|
```
|
220
231
|
|
221
|
-
_See code: [src/commands/status.ts](https://github.com/Constellation-Labs/node-pilot/blob/v0.0.
|
232
|
+
_See code: [src/commands/status.ts](https://github.com/Constellation-Labs/node-pilot/blob/v0.0.10/src/commands/status.ts)_
|
222
233
|
<!-- commandsstop -->
|
package/bin/dev.js
CHANGED
@@ -5,15 +5,10 @@ const skipDefaultCommand = {
|
|
5
5
|
if (process.argv.length === 2) {
|
6
6
|
process.argv[2] = 'status';
|
7
7
|
}
|
8
|
-
else if (process.argv.length > 2 && process.argv
|
8
|
+
else if (process.argv.length > 2 && process.argv.every(a => a.startsWith('-')) && !skipDefaultCommand[process.argv[2]]) {
|
9
9
|
process.argv.splice(2, 0 , 'status');
|
10
10
|
}
|
11
11
|
|
12
12
|
import {execute} from '@oclif/core'
|
13
13
|
|
14
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.js
CHANGED
@@ -6,7 +6,7 @@ const skipDefaultCommand = {
|
|
6
6
|
if (process.argv.length === 2) {
|
7
7
|
process.argv[2] = 'status';
|
8
8
|
}
|
9
|
-
else if (process.argv.length > 2 && process.argv
|
9
|
+
else if (process.argv.length > 2 && process.argv.every(a => a.startsWith('-')) && !skipDefaultCommand[process.argv[2]]) {
|
10
10
|
process.argv.splice(2, 0 , 'status');
|
11
11
|
}
|
12
12
|
|
@@ -0,0 +1,9 @@
|
|
1
|
+
import { Command } from '@oclif/core';
|
2
|
+
export declare abstract class BaseCommand extends Command {
|
3
|
+
static baseFlags: {
|
4
|
+
project: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
|
5
|
+
};
|
6
|
+
checkProject(flags: {
|
7
|
+
project?: string;
|
8
|
+
}): void;
|
9
|
+
}
|
@@ -0,0 +1,20 @@
|
|
1
|
+
// src/base.ts
|
2
|
+
import { Command, Flags } from '@oclif/core';
|
3
|
+
import { configStore } from "./config-store.js";
|
4
|
+
import { configHelper } from "./helpers/config-helper.js";
|
5
|
+
export class BaseCommand extends Command {
|
6
|
+
static baseFlags = {
|
7
|
+
project: Flags.string({
|
8
|
+
char: 'p',
|
9
|
+
description: 'Specify the project name to use',
|
10
|
+
helpGroup: 'GLOBAL', // Optional: Group this flag in the help output
|
11
|
+
options: configStore.getProjects()
|
12
|
+
})
|
13
|
+
};
|
14
|
+
checkProject(flags) {
|
15
|
+
configHelper.assertProject('No project found. ');
|
16
|
+
if (flags.project) {
|
17
|
+
configStore.setActiveProject(flags.project);
|
18
|
+
}
|
19
|
+
}
|
20
|
+
}
|
@@ -20,7 +20,7 @@ export const checkHardware = {
|
|
20
20
|
const numOfCores = os.availableParallelism();
|
21
21
|
let allPassed = true;
|
22
22
|
const formatActual = (value, recommended, units = '') => {
|
23
|
-
const passed = Number(value) >= recommended;
|
23
|
+
const passed = Math.ceil(Number(value)) >= recommended;
|
24
24
|
allPassed = allPassed && passed;
|
25
25
|
return passed ? chalk.greenBright(value + units) : chalk.redBright(value + units);
|
26
26
|
};
|
@@ -32,8 +32,8 @@ export const checkHardware = {
|
|
32
32
|
{ headerColor: 'white', value: 'ACTUAL' },
|
33
33
|
];
|
34
34
|
const rows = [
|
35
|
-
[fc("Disk size"), fc("
|
36
|
-
[fc("System memory"), fc("
|
35
|
+
[fc("Disk size"), fc("240 GB"), formatActual(totalSpaceGB, 240, " GB")],
|
36
|
+
[fc("System memory"), fc("16 GB"), formatActual(totalMemoryGB, 16, " GB")],
|
37
37
|
[fc("CPU cores"), fc("8 cores"), formatActual(numOfCores, 8, " cores")],
|
38
38
|
];
|
39
39
|
clm.echo(ttyTable(header, rows).render() + "\n");
|
@@ -1,5 +1,6 @@
|
|
1
1
|
import chalk from "chalk";
|
2
2
|
import { configStore } from "../config-store.js";
|
3
|
+
import { systemdService } from "../services/systemd-service.js";
|
3
4
|
import { checkDependencies } from "./check-dependencies.js";
|
4
5
|
import { checkHardware } from "./check-hardware.js";
|
5
6
|
export const checkInitialSetup = {
|
@@ -13,5 +14,6 @@ export const checkInitialSetup = {
|
|
13
14
|
console.log(" " + chalk.whiteBright("NODE PILOT") + " ");
|
14
15
|
console.log(chalk.whiteBright(" ****************************************"));
|
15
16
|
await checkHardware.systemRequirements();
|
17
|
+
await systemdService.install();
|
16
18
|
},
|
17
19
|
};
|
@@ -2,7 +2,7 @@ import { input } from "@inquirer/prompts";
|
|
2
2
|
import chalk from "chalk";
|
3
3
|
import { clm } from "../clm.js";
|
4
4
|
import { configStore } from "../config-store.js";
|
5
|
-
import {
|
5
|
+
import { dockerService } from "../services/docker-service.js";
|
6
6
|
import { nodeService } from "../services/node-service.js";
|
7
7
|
export const checkLayers = {
|
8
8
|
async layersReadyToJoin() {
|
@@ -27,9 +27,9 @@ export const checkLayers = {
|
|
27
27
|
}
|
28
28
|
await input({ default: 'y', message: 'Would you like to start the validator(s)? (y/n): ' }).then(async (answer) => {
|
29
29
|
if (answer.toLowerCase() === 'y') {
|
30
|
-
await
|
30
|
+
await dockerService.dockerBuild();
|
31
31
|
clm.preStep('Starting the node...');
|
32
|
-
await
|
32
|
+
await dockerService.dockerUp();
|
33
33
|
await nodeService.pollForLayersState(layersToRun);
|
34
34
|
}
|
35
35
|
else {
|
@@ -40,11 +40,11 @@ export const checkLayers = {
|
|
40
40
|
else if (notRunningLayers.length > 0) {
|
41
41
|
const layersNotRunning = notRunningLayers.map(r => r.layer);
|
42
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
|
43
|
+
await input({ default: 'y', message: 'Would you like to start the validator(s)? (y/n): ' }).then(async (answer) => {
|
44
44
|
if (answer.toLowerCase() === 'y') {
|
45
|
-
clm.preStep('
|
46
|
-
await
|
47
|
-
await nodeService.pollForLayersState(
|
45
|
+
clm.preStep('Starting docker containers...');
|
46
|
+
await dockerService.dockerStartLayers(layersNotRunning);
|
47
|
+
await nodeService.pollForLayersState(layersNotRunning);
|
48
48
|
}
|
49
49
|
else {
|
50
50
|
clm.echo('Node not started.');
|
@@ -1,7 +1,9 @@
|
|
1
1
|
export declare const checkNetwork: {
|
2
|
+
checkForExistingNodeIdInCluster(): Promise<void>;
|
2
3
|
checkSeedList(): Promise<void>;
|
3
4
|
configureIpAddress(): Promise<void>;
|
4
5
|
detectExternalIpAddress(): Promise<void>;
|
5
6
|
enterIpAddressManually(): Promise<string>;
|
6
7
|
fetchIPAddress(): Promise<string>;
|
8
|
+
isNetworkConnectable(): Promise<boolean>;
|
7
9
|
};
|
@@ -4,7 +4,27 @@ import fs from "node:fs";
|
|
4
4
|
import path from "node:path";
|
5
5
|
import { clm } from "../clm.js";
|
6
6
|
import { configStore } from "../config-store.js";
|
7
|
+
import { clusterService } from "../services/cluster-service.js";
|
8
|
+
import { dockerService } from "../services/docker-service.js";
|
9
|
+
import { shellService } from "../services/shell-service.js";
|
7
10
|
export const checkNetwork = {
|
11
|
+
async checkForExistingNodeIdInCluster() {
|
12
|
+
if (configStore.hasProjectFlag('duplicateNodeIdChecked')) {
|
13
|
+
return;
|
14
|
+
}
|
15
|
+
clm.preStep('Checking for existing Node ID in cluster...');
|
16
|
+
const { nodeId } = configStore.getProjectInfo();
|
17
|
+
const clusterInfo = await clusterService.getClusterInfo();
|
18
|
+
const found = clusterInfo.some(node => node.id === nodeId);
|
19
|
+
const isDockerRunning = await dockerService.isRunning();
|
20
|
+
if (!isDockerRunning && found) {
|
21
|
+
clm.warn('Node ID already exists in the cluster.');
|
22
|
+
clm.warn('You need to shutdown your node from a previous installation before continuing.');
|
23
|
+
clm.error(`Or to change the node ID, configure the Key File: use ${chalk.cyan('cpilot config')}, and select ${chalk.cyan('Key File')}`);
|
24
|
+
}
|
25
|
+
configStore.setProjectFlag('duplicateNodeIdChecked', true);
|
26
|
+
clm.postStep('No duplicate Node found.');
|
27
|
+
},
|
8
28
|
async checkSeedList() {
|
9
29
|
if (configStore.hasProjectFlag('seedListChecked')) {
|
10
30
|
return;
|
@@ -23,10 +43,11 @@ export const checkNetwork = {
|
|
23
43
|
}
|
24
44
|
const printNotFoundError = () => {
|
25
45
|
clm.warn(`Node ID not found in ${type.toUpperCase()} seed list. You may try again later.`);
|
26
|
-
clm.
|
46
|
+
clm.warn(`To change the Key File: use ${chalk.cyan('cpilot config')}, and select ${chalk.cyan('Key File')}`);
|
47
|
+
clm.error(`To change the Network: use ${chalk.cyan('cpilot config')}, and select ${chalk.cyan('Network')}`);
|
27
48
|
};
|
28
49
|
if (type === 'mainnet') {
|
29
|
-
// the mainnet seed list comed from a network release
|
50
|
+
// the mainnet seed list comed from a network release
|
30
51
|
printNotFoundError();
|
31
52
|
}
|
32
53
|
else {
|
@@ -52,11 +73,11 @@ export const checkNetwork = {
|
|
52
73
|
}
|
53
74
|
},
|
54
75
|
async configureIpAddress() {
|
55
|
-
const { CL_EXTERNAL_IP: currentIpAddress } = configStore.
|
76
|
+
const { CL_EXTERNAL_IP: currentIpAddress } = configStore.getEnvInfo();
|
56
77
|
const detectedIpAddress = await checkNetwork.fetchIPAddress().catch(() => '');
|
57
78
|
if (!currentIpAddress && !detectedIpAddress) {
|
58
79
|
const newIpAddress = await checkNetwork.enterIpAddressManually();
|
59
|
-
configStore.
|
80
|
+
configStore.setEnvInfo({ CL_EXTERNAL_IP: newIpAddress });
|
60
81
|
return;
|
61
82
|
}
|
62
83
|
if (currentIpAddress) {
|
@@ -85,7 +106,7 @@ export const checkNetwork = {
|
|
85
106
|
else if (answer === 'manual') {
|
86
107
|
selectedIpAddress = await checkNetwork.enterIpAddressManually();
|
87
108
|
}
|
88
|
-
configStore.
|
109
|
+
configStore.setEnvInfo({ CL_EXTERNAL_IP: selectedIpAddress });
|
89
110
|
},
|
90
111
|
async detectExternalIpAddress() {
|
91
112
|
const externalIp = await this.fetchIPAddress()
|
@@ -94,7 +115,7 @@ export const checkNetwork = {
|
|
94
115
|
return this.enterIpAddressManually();
|
95
116
|
});
|
96
117
|
clm.postStep("\nExternal IP address: " + chalk.cyan(externalIp) + "\n");
|
97
|
-
configStore.
|
118
|
+
configStore.setEnvInfo({ CL_EXTERNAL_IP: externalIp });
|
98
119
|
},
|
99
120
|
async enterIpAddressManually() {
|
100
121
|
return input({
|
@@ -110,11 +131,25 @@ export const checkNetwork = {
|
|
110
131
|
});
|
111
132
|
},
|
112
133
|
async fetchIPAddress() {
|
113
|
-
return
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
134
|
+
return shellService.runCommandWithOutput('curl -4 https://ifconfig.me/ip');
|
135
|
+
},
|
136
|
+
async isNetworkConnectable() {
|
137
|
+
return clusterService.getClusterInfo()
|
138
|
+
.then(async (nodes) => {
|
139
|
+
const someAreReady = nodes.some(node => node.state === 'Ready');
|
140
|
+
if (!someAreReady) {
|
141
|
+
if (nodes.length > 0) {
|
142
|
+
clm.warn(`Found ${nodes.length} nodes in the cluster, but none are READY.`);
|
143
|
+
}
|
144
|
+
throw new Error(`Network is not connectable.`);
|
145
|
+
}
|
146
|
+
clm.debug(`Network is live. Found ${nodes.length} nodes in the cluster.`);
|
147
|
+
configStore.setClusterStats({ total: nodes.length });
|
148
|
+
return true;
|
149
|
+
})
|
150
|
+
.catch(() => {
|
151
|
+
clm.error(`Network is not in service. Please try again later.`);
|
152
|
+
return false;
|
118
153
|
});
|
119
154
|
}
|
120
155
|
};
|
@@ -5,11 +5,11 @@ import path from "node:path";
|
|
5
5
|
import yaml from "yaml";
|
6
6
|
import { clm } from "../clm.js";
|
7
7
|
import { configStore } from "../config-store.js";
|
8
|
-
import { dockerHelper } from "../helpers/docker-helper.js";
|
9
8
|
import { keyFileHelper } from "../helpers/key-file-helper.js";
|
10
9
|
import { promptHelper } from "../helpers/prompt-helper.js";
|
11
|
-
import {
|
10
|
+
import { dockerService } from "../services/docker-service.js";
|
12
11
|
import { nodeService } from "../services/node-service.js";
|
12
|
+
import { shellService } from "../services/shell-service.js";
|
13
13
|
export const checkNodeCtl = {
|
14
14
|
async check4Migration() {
|
15
15
|
if (configStore.hasProjectFlag('nodeCtlChecked')) {
|
@@ -22,7 +22,7 @@ export const checkNodeCtl = {
|
|
22
22
|
}
|
23
23
|
const hasNodeAdminUser = fs.existsSync('/home/nodeadmin');
|
24
24
|
if (hasNodeAdminUser) {
|
25
|
-
const isDockerRunning = await
|
25
|
+
const isDockerRunning = await dockerService.isRunning();
|
26
26
|
const isPortOpen = await nodeService.isPortInUse(9000);
|
27
27
|
clm.step(chalk.bold('NODECTL has been detected.'));
|
28
28
|
if (!isDockerRunning && isPortOpen) {
|
@@ -71,7 +71,7 @@ export const checkNodeCtl = {
|
|
71
71
|
// prompt for password
|
72
72
|
const keyPassword = await password({ message: 'Enter the key file password:' });
|
73
73
|
const keyAlias = await input({ message: 'Enter the key file alias:' });
|
74
|
-
configStore.
|
74
|
+
configStore.setEnvInfo({ CL_KEYALIAS: keyAlias, CL_KEYSTORE: pilotKeyPath, CL_PASSWORD: keyPassword });
|
75
75
|
try {
|
76
76
|
const dagAddress = await keyFileHelper.getAddress();
|
77
77
|
const nodeId = await keyFileHelper.getId();
|
@@ -1,15 +1,21 @@
|
|
1
1
|
import { input, select } from "@inquirer/prompts";
|
2
|
+
import chalk from "chalk";
|
2
3
|
import ora from 'ora';
|
3
4
|
import { clm } from "../clm.js";
|
4
5
|
import { configStore } from "../config-store.js";
|
5
6
|
import { configHelper } from "../helpers/config-helper.js";
|
6
|
-
import { dockerHelper } from "../helpers/docker-helper.js";
|
7
7
|
import { projectHelper } from "../helpers/project-helper.js";
|
8
8
|
import { promptHelper } from "../helpers/prompt-helper.js";
|
9
9
|
import { clusterService } from "../services/cluster-service.js";
|
10
|
+
import { dockerService } from "../services/docker-service.js";
|
10
11
|
import { shellService } from "../services/shell-service.js";
|
11
12
|
import { checkNetwork } from "./check-network.js";
|
12
13
|
export const checkProject = {
|
14
|
+
async hasVersionChanged() {
|
15
|
+
const clusterVersion = await clusterService.getReleaseVersion();
|
16
|
+
const rInfo = await configHelper.getReleaseInfo();
|
17
|
+
return !rInfo || (rInfo.version !== clusterVersion);
|
18
|
+
},
|
13
19
|
async projectInstallation() {
|
14
20
|
let updateNetworkType = false;
|
15
21
|
let updateLayers = false;
|
@@ -86,9 +92,9 @@ export const checkProject = {
|
|
86
92
|
clm.postStep(`Network files are already installed for ${nInfo.type} version ${clusterVersion}`);
|
87
93
|
return false;
|
88
94
|
}
|
89
|
-
const isRunning = await
|
95
|
+
const isRunning = await dockerService.isRunning();
|
90
96
|
if (isRunning) {
|
91
|
-
await
|
97
|
+
await dockerService.dockerDown();
|
92
98
|
}
|
93
99
|
const silent = !process.env.DEBUG;
|
94
100
|
const spinner = ora('Running install script...');
|
@@ -99,10 +105,15 @@ export const checkProject = {
|
|
99
105
|
else {
|
100
106
|
clm.preStep('Running install script...');
|
101
107
|
}
|
108
|
+
// const node = await clusterService.getClusterNodeInfo();
|
109
|
+
// const NODE_URL = `http://${node.host}:${node.publicPort}`;
|
102
110
|
// NOTE: may be different for metagraphs
|
103
111
|
await shellService.runProjectCommand(`scripts/install.sh ${nInfo.type}`, undefined, silent)
|
104
112
|
.catch(() => {
|
105
113
|
spinner.stop();
|
114
|
+
if (silent) {
|
115
|
+
clm.error(`Install script failed. run: ${chalk.cyan("DEBUG=true cpilot")} for more details`);
|
116
|
+
}
|
106
117
|
clm.error('Install script failed. Please run cpilot again after correcting the error');
|
107
118
|
});
|
108
119
|
if (silent) {
|
@@ -118,7 +129,7 @@ export const checkProject = {
|
|
118
129
|
async runUpgrade() {
|
119
130
|
const changed = await this.runInstall();
|
120
131
|
if (changed) {
|
121
|
-
await
|
132
|
+
await dockerService.dockerBuild();
|
122
133
|
}
|
123
134
|
}
|
124
135
|
};
|
@@ -0,0 +1,37 @@
|
|
1
|
+
import chalk from "chalk";
|
2
|
+
import { clm } from "../clm.js";
|
3
|
+
import { configStore } from "../config-store.js";
|
4
|
+
import { promptHelper } from "../helpers/prompt-helper.js";
|
5
|
+
export const checkWallet = {
|
6
|
+
async checkCollateral() {
|
7
|
+
const { type } = configStore.getNetworkInfo();
|
8
|
+
if (type !== 'mainnet')
|
9
|
+
return;
|
10
|
+
const skipCollateralCheck = configStore.hasProjectFlag('skipCollateralCheck');
|
11
|
+
if (skipCollateralCheck)
|
12
|
+
return;
|
13
|
+
clm.preStep('Checking for required collateral...');
|
14
|
+
const { dagAddress } = configStore.getProjectInfo();
|
15
|
+
const url = `https://be-mainnet.constellationnetwork.io/addresses/${dagAddress}/balance`;
|
16
|
+
let hasError = false;
|
17
|
+
const balance = await fetch(url)
|
18
|
+
.then(res => res.json())
|
19
|
+
.then(i => i.data.balance)
|
20
|
+
.catch(() => {
|
21
|
+
clm.warn(`Failed to fetch balance from ${url}`);
|
22
|
+
hasError = true;
|
23
|
+
});
|
24
|
+
if (!hasError && balance < 25_000_000_000_000) {
|
25
|
+
clm.warn(`You need at least 250k DAG to run a validator node. Your account ${chalk.cyan(dagAddress)} has a balance of ${chalk.cyan(balance)} DAG.`);
|
26
|
+
hasError = true;
|
27
|
+
}
|
28
|
+
if (hasError) {
|
29
|
+
clm.echo('You may continue and skip this check in the future');
|
30
|
+
await promptHelper.doYouWishToContinue();
|
31
|
+
}
|
32
|
+
else {
|
33
|
+
clm.postStep('Collateral check PASSED');
|
34
|
+
}
|
35
|
+
configStore.setProjectFlag('skipCollateralCheck', true);
|
36
|
+
}
|
37
|
+
};
|
package/dist/clm.d.ts
CHANGED
package/dist/clm.js
CHANGED
@@ -1,5 +1,6 @@
|
|
1
1
|
import { Args, Command } from '@oclif/core';
|
2
|
-
import {
|
2
|
+
import { clm } from "../../clm.js";
|
3
|
+
import { configStore, layerEnvNames, networkEnvNames } from "../../config-store.js";
|
3
4
|
import { configHelper } from "../../helpers/config-helper.js";
|
4
5
|
export default class ConfigGet extends Command {
|
5
6
|
static args = {
|
@@ -11,27 +12,72 @@ export default class ConfigGet extends Command {
|
|
11
12
|
'<%= config.bin %> <%= command.id %> CL_EXTERNAL_IP',
|
12
13
|
'<%= config.bin %> <%= command.id %> gl0:CL_PUBLIC_HTTP_PORT',
|
13
14
|
];
|
15
|
+
getKeyInfo() {
|
16
|
+
const { dagAddress, nodeId } = configStore.getProjectInfo();
|
17
|
+
const { CL_KEYALIAS, CL_KEYSTORE } = configStore.getEnvInfo();
|
18
|
+
return {
|
19
|
+
KEY_ALIAS: CL_KEYALIAS,
|
20
|
+
KEY_FILE: CL_KEYSTORE,
|
21
|
+
NODE_ADDRESS: dagAddress,
|
22
|
+
NODE_ID: nodeId,
|
23
|
+
};
|
24
|
+
}
|
14
25
|
async run() {
|
15
26
|
configHelper.assertProject('No configuration found. ');
|
16
27
|
const { args } = await this.parse(ConfigGet);
|
17
|
-
const info = configStore.getEnvInfo();
|
28
|
+
// const info = configStore.getEnvInfo();
|
18
29
|
const { layersToRun } = configStore.getProjectInfo();
|
19
|
-
const
|
20
|
-
const
|
30
|
+
const { type: network } = configStore.getNetworkInfo();
|
31
|
+
const networkEnv = configStore.getEnvNetworkInfo(network);
|
32
|
+
// const networkProp = info.network as Record<string, string>;
|
33
|
+
// const layers = info.layers as Record<string, Record<string, string>>;
|
34
|
+
const gl = (l) => configStore.getEnvLayerInfo(network, l);
|
21
35
|
if (Object.keys(args).length === 0 || args.name === undefined) {
|
22
|
-
const
|
23
|
-
const layersList = layersToRun.map(l => (Object.keys(layerEnvNames).map(k => ({ name: `${l}:${k}`, value:
|
24
|
-
|
25
|
-
|
36
|
+
const networkList = Object.keys(networkEnvNames).sort().map(k => ({ name: k, value: networkEnv[k] }));
|
37
|
+
const layersList = layersToRun.map(l => (Object.keys(layerEnvNames).map(k => ({ name: `${l}:${k}`, value: gl(l)[k] }))));
|
38
|
+
const keyInfo = this.getKeyInfo();
|
39
|
+
const keyInfoList = Object.keys(keyInfo).map(k => ({ name: 'key:' + k, value: keyInfo[k] }));
|
40
|
+
configHelper.showEnvInfoList(networkList);
|
41
|
+
configHelper.showEnvInfoList(keyInfoList);
|
26
42
|
configHelper.showEnvInfoList(layersList.flat());
|
27
43
|
}
|
28
44
|
else if (args.name.includes(':')) {
|
29
45
|
const [layer, name] = args.name.split(':');
|
30
|
-
|
46
|
+
if (layer === 'key') {
|
47
|
+
const keyInfo = this.getKeyInfo();
|
48
|
+
if (Object.hasOwn(keyInfo, name)) {
|
49
|
+
configHelper.showEnvInfo(args.name, keyInfo[name]);
|
50
|
+
}
|
51
|
+
else {
|
52
|
+
clm.warn('Invalid key property. Valid properties are: ' + Object.keys(keyInfo).join(', '));
|
53
|
+
}
|
54
|
+
}
|
55
|
+
else if (!layersToRun.includes(layer)) {
|
56
|
+
clm.warn(`Layer ${layer} is not running. Valid layers are: ` + layersToRun.join(', '));
|
57
|
+
}
|
58
|
+
else if (Object.hasOwn(layerEnvNames, name)) {
|
59
|
+
configHelper.showEnvInfo(args.name, gl(layer)[name]);
|
60
|
+
}
|
61
|
+
else {
|
62
|
+
clm.warn('Invalid layer property. Valid properties are: ' + Object.keys(layerEnvNames).join(', '));
|
63
|
+
}
|
64
|
+
}
|
65
|
+
else if (args.name === 'key') {
|
66
|
+
const keyInfo = this.getKeyInfo();
|
67
|
+
const keyInfoList = Object.keys(keyInfo).map(k => ({ name: 'key:' + k, value: keyInfo[k] }));
|
68
|
+
configHelper.showEnvInfoList(keyInfoList);
|
69
|
+
}
|
70
|
+
else if (layersToRun.includes(args.name)) {
|
71
|
+
const layer = args.name;
|
72
|
+
const list = Object.keys(layerEnvNames).map(k => ({ name: `${layer}:${k}`, value: gl(layer)[k] }));
|
73
|
+
configHelper.showEnvInfoList(list);
|
31
74
|
}
|
32
75
|
else {
|
33
|
-
|
34
|
-
|
76
|
+
if (!Object.hasOwn(networkEnvNames, args.name)) {
|
77
|
+
clm.warn('Invalid network-wide property. Valid properties are: ' + Object.keys(networkEnvNames).join(', '));
|
78
|
+
return;
|
79
|
+
}
|
80
|
+
configHelper.showEnvInfo(args.name, networkEnv[args.name]);
|
35
81
|
}
|
36
82
|
}
|
37
83
|
}
|