@constellation-network/node-pilot 0.0.8 → 0.0.9
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 +22 -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-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.js +13 -8
- 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 +5 -2
- package/dist/commands/restart.js +25 -5
- package/dist/commands/shutdown.js +3 -3
- package/dist/commands/status.js +4 -0
- package/dist/commands/test.js +11 -3
- package/dist/config-store.d.ts +43 -30
- package/dist/config-store.js +71 -33
- 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} +8 -5
- 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/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 +23 -4
- package/package.json +9 -8
- package/projects/hypergraph/Dockerfile +27 -18
- package/projects/hypergraph/docker-compose.yml +14 -12
- 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/docker-build.sh +12 -1
- package/projects/hypergraph/scripts/install.sh +30 -25
- package/projects/hypergraph/seedlist +268 -0
- package/scripts/autoheal.sh +8 -0
- package/scripts/services/io.constellationnetwork.nodepilot.Updater.plist +16 -0
- package/scripts/services/node-pilot-autoheal.service +14 -0
- package/scripts/services/node-pilot-updater-hypergraph.service +15 -0
- package/scripts/updater.sh +13 -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.9 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.9/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.9/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.9/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.9/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,22 @@ 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.9/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 hypergraph]
|
182
|
+
|
183
|
+
ARGUMENTS
|
184
|
+
LAYER network layer to view. e.g. gl0
|
185
|
+
|
186
|
+
GLOBAL FLAGS
|
187
|
+
-p, --project=<option> Specify the project name to use
|
188
|
+
<options: hypergraph>
|
182
189
|
|
183
190
|
DESCRIPTION
|
184
191
|
A full shutdown of the validator node, then restart
|
@@ -187,7 +194,7 @@ EXAMPLES
|
|
187
194
|
$ cpilot restart
|
188
195
|
```
|
189
196
|
|
190
|
-
_See code: [src/commands/restart.ts](https://github.com/Constellation-Labs/node-pilot/blob/v0.0.
|
197
|
+
_See code: [src/commands/restart.ts](https://github.com/Constellation-Labs/node-pilot/blob/v0.0.9/src/commands/restart.ts)_
|
191
198
|
|
192
199
|
## `cpilot shutdown`
|
193
200
|
|
@@ -204,7 +211,7 @@ EXAMPLES
|
|
204
211
|
$ cpilot shutdown
|
205
212
|
```
|
206
213
|
|
207
|
-
_See code: [src/commands/shutdown.ts](https://github.com/Constellation-Labs/node-pilot/blob/v0.0.
|
214
|
+
_See code: [src/commands/shutdown.ts](https://github.com/Constellation-Labs/node-pilot/blob/v0.0.9/src/commands/shutdown.ts)_
|
208
215
|
|
209
216
|
## `cpilot status`
|
210
217
|
|
@@ -218,5 +225,5 @@ DESCRIPTION
|
|
218
225
|
Display node status and configuration settings
|
219
226
|
```
|
220
227
|
|
221
|
-
_See code: [src/commands/status.ts](https://github.com/Constellation-Labs/node-pilot/blob/v0.0.
|
228
|
+
_See code: [src/commands/status.ts](https://github.com/Constellation-Labs/node-pilot/blob/v0.0.9/src/commands/status.ts)_
|
222
229
|
<!-- 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.changeProjectStore(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");
|
@@ -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,12 +1,13 @@
|
|
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 = {
|
@@ -80,15 +81,16 @@ export const checkProject = {
|
|
80
81
|
},
|
81
82
|
async runInstall() {
|
82
83
|
const nInfo = configStore.getNetworkInfo();
|
83
|
-
const
|
84
|
+
const node = await clusterService.getClusterNodeInfo();
|
85
|
+
const NODE_URL = `http://${node.host}:${node.publicPort}`;
|
84
86
|
let rInfo = await configHelper.getReleaseInfo();
|
85
|
-
if (rInfo && rInfo.network === nInfo.type && rInfo.version ===
|
86
|
-
clm.postStep(`Network files are already installed for ${nInfo.type} version ${
|
87
|
+
if (rInfo && rInfo.network === nInfo.type && rInfo.version === node.version) {
|
88
|
+
clm.postStep(`Network files are already installed for ${nInfo.type} version ${node.version}`);
|
87
89
|
return false;
|
88
90
|
}
|
89
|
-
const isRunning = await
|
91
|
+
const isRunning = await dockerService.isRunning();
|
90
92
|
if (isRunning) {
|
91
|
-
await
|
93
|
+
await dockerService.dockerDown();
|
92
94
|
}
|
93
95
|
const silent = !process.env.DEBUG;
|
94
96
|
const spinner = ora('Running install script...');
|
@@ -100,9 +102,12 @@ export const checkProject = {
|
|
100
102
|
clm.preStep('Running install script...');
|
101
103
|
}
|
102
104
|
// NOTE: may be different for metagraphs
|
103
|
-
await shellService.runProjectCommand(`scripts/install.sh ${nInfo.type}`,
|
105
|
+
await shellService.runProjectCommand(`scripts/install.sh ${nInfo.type}`, { NODE_URL }, silent)
|
104
106
|
.catch(() => {
|
105
107
|
spinner.stop();
|
108
|
+
if (silent) {
|
109
|
+
clm.error(`Install script failed. run: ${chalk.cyan("DEBUG=true cpilot")} for more details`);
|
110
|
+
}
|
106
111
|
clm.error('Install script failed. Please run cpilot again after correcting the error');
|
107
112
|
});
|
108
113
|
if (silent) {
|
@@ -118,7 +123,7 @@ export const checkProject = {
|
|
118
123
|
async runUpgrade() {
|
119
124
|
const changed = await this.runInstall();
|
120
125
|
if (changed) {
|
121
|
-
await
|
126
|
+
await dockerService.dockerBuild();
|
122
127
|
}
|
123
128
|
}
|
124
129
|
};
|
@@ -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
|
}
|