@constellation-network/node-pilot 0.6.0 → 0.7.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 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.6.0 darwin-arm64 node-v22.15.0
24
+ @constellation-network/node-pilot/0.7.0 darwin-arm64 node-v22.15.0
25
25
  $ cpilot --help [COMMAND]
26
26
  USAGE
27
27
  $ cpilot COMMAND
@@ -71,7 +71,7 @@ EXAMPLES
71
71
  $ cpilot clean
72
72
  ```
73
73
 
74
- _See code: [src/commands/clean.ts](https://github.com/Constellation-Labs/node-pilot/blob/v0.6.0/src/commands/clean.ts)_
74
+ _See code: [src/commands/clean.ts](https://github.com/Constellation-Labs/node-pilot/blob/v0.7.0/src/commands/clean.ts)_
75
75
 
76
76
  ## `cpilot config`
77
77
 
@@ -88,7 +88,7 @@ EXAMPLES
88
88
  $ cpilot config
89
89
  ```
90
90
 
91
- _See code: [src/commands/config.ts](https://github.com/Constellation-Labs/node-pilot/blob/v0.6.0/src/commands/config.ts)_
91
+ _See code: [src/commands/config.ts](https://github.com/Constellation-Labs/node-pilot/blob/v0.7.0/src/commands/config.ts)_
92
92
 
93
93
  ## `cpilot config get [NAME]`
94
94
 
@@ -112,7 +112,7 @@ EXAMPLES
112
112
  $ cpilot config get gl0:CL_PUBLIC_HTTP_PORT
113
113
  ```
114
114
 
115
- _See code: [src/commands/config/get.ts](https://github.com/Constellation-Labs/node-pilot/blob/v0.6.0/src/commands/config/get.ts)_
115
+ _See code: [src/commands/config/get.ts](https://github.com/Constellation-Labs/node-pilot/blob/v0.7.0/src/commands/config/get.ts)_
116
116
 
117
117
  ## `cpilot config set NAME VALUE`
118
118
 
@@ -135,7 +135,7 @@ EXAMPLES
135
135
  $ cpilot config set gl0:CL_PUBLIC_HTTP_PORT 9000
136
136
  ```
137
137
 
138
- _See code: [src/commands/config/set.ts](https://github.com/Constellation-Labs/node-pilot/blob/v0.6.0/src/commands/config/set.ts)_
138
+ _See code: [src/commands/config/set.ts](https://github.com/Constellation-Labs/node-pilot/blob/v0.7.0/src/commands/config/set.ts)_
139
139
 
140
140
  ## `cpilot help [COMMAND]`
141
141
 
@@ -172,7 +172,7 @@ EXAMPLES
172
172
  $ cpilot info
173
173
  ```
174
174
 
175
- _See code: [src/commands/info.ts](https://github.com/Constellation-Labs/node-pilot/blob/v0.6.0/src/commands/info.ts)_
175
+ _See code: [src/commands/info.ts](https://github.com/Constellation-Labs/node-pilot/blob/v0.7.0/src/commands/info.ts)_
176
176
 
177
177
  ## `cpilot logs LAYER`
178
178
 
@@ -198,7 +198,7 @@ EXAMPLES
198
198
  $ cpilot logs
199
199
  ```
200
200
 
201
- _See code: [src/commands/logs.ts](https://github.com/Constellation-Labs/node-pilot/blob/v0.6.0/src/commands/logs.ts)_
201
+ _See code: [src/commands/logs.ts](https://github.com/Constellation-Labs/node-pilot/blob/v0.7.0/src/commands/logs.ts)_
202
202
 
203
203
  ## `cpilot restart [LAYER]`
204
204
 
@@ -226,7 +226,7 @@ EXAMPLES
226
226
  $ cpilot restart
227
227
  ```
228
228
 
229
- _See code: [src/commands/restart.ts](https://github.com/Constellation-Labs/node-pilot/blob/v0.6.0/src/commands/restart.ts)_
229
+ _See code: [src/commands/restart.ts](https://github.com/Constellation-Labs/node-pilot/blob/v0.7.0/src/commands/restart.ts)_
230
230
 
231
231
  ## `cpilot shutdown`
232
232
 
@@ -234,10 +234,7 @@ A full shutdown of the validator node
234
234
 
235
235
  ```
236
236
  USAGE
237
- $ cpilot shutdown [-l <value>]
238
-
239
- FLAGS
240
- -l, --layer=<value> specify a layer to shutdown. e.g. gl0
237
+ $ cpilot shutdown
241
238
 
242
239
  DESCRIPTION
243
240
  A full shutdown of the validator node
@@ -246,7 +243,7 @@ EXAMPLES
246
243
  $ cpilot shutdown
247
244
  ```
248
245
 
249
- _See code: [src/commands/shutdown.ts](https://github.com/Constellation-Labs/node-pilot/blob/v0.6.0/src/commands/shutdown.ts)_
246
+ _See code: [src/commands/shutdown.ts](https://github.com/Constellation-Labs/node-pilot/blob/v0.7.0/src/commands/shutdown.ts)_
250
247
 
251
248
  ## `cpilot status`
252
249
 
@@ -260,5 +257,5 @@ DESCRIPTION
260
257
  Display node status and configuration settings
261
258
  ```
262
259
 
263
- _See code: [src/commands/status.ts](https://github.com/Constellation-Labs/node-pilot/blob/v0.6.0/src/commands/status.ts)_
260
+ _See code: [src/commands/status.ts](https://github.com/Constellation-Labs/node-pilot/blob/v0.7.0/src/commands/status.ts)_
264
261
  <!-- commandsstop -->
@@ -2,6 +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 { healthCheckConfig } from "../helpers/health-check-config.js";
5
6
  import { StatusTable } from "../helpers/status-table.js";
6
7
  import { dockerService } from "../services/docker-service.js";
7
8
  import { nodeService } from "../services/node-service.js";
@@ -29,6 +30,7 @@ export const checkLayers = {
29
30
  await input({ default: 'y', message: 'Would you like to start the validator(s)? (y/n): ' }).then(async (answer) => {
30
31
  if (answer.toLowerCase() === 'y') {
31
32
  await dockerService.dockerBuild();
33
+ healthCheckConfig.setNodeState({ lastError: '' });
32
34
  clm.preStep('Starting the node...');
33
35
  await dockerService.dockerUp();
34
36
  await nodeService.pollForLayersState(layersToRun);
@@ -1,6 +1,15 @@
1
+ import semver from "semver";
1
2
  export declare const checkNodePilot: {
2
3
  checkDiscordRegistration(): Promise<void>;
3
4
  checkVersion(): Promise<void>;
4
- isDiscordAlertsEnabled(): any;
5
+ compareVersions(): Promise<{
6
+ currentVer: undefined;
7
+ latestVer: undefined;
8
+ } | {
9
+ currentVer: semver.SemVer | null;
10
+ latestVer: semver.SemVer | null;
11
+ }>;
12
+ isDiscordAlertsEnabled(): boolean;
5
13
  promptDiscordRegistration(): Promise<void>;
14
+ runUpgrade(): Promise<void>;
6
15
  };
@@ -1,14 +1,13 @@
1
- import { JSONStorage } from "node-localstorage";
2
- import fs from "node:fs";
3
1
  import os from "node:os";
4
- import path from "node:path";
5
2
  import semver from "semver";
6
3
  import packageJson from '../../package.json' with { type: 'json' };
7
4
  import { clm } from "../clm.js";
8
5
  import { configStore } from "../config-store.js";
6
+ import { healthCheckConfig } from "../helpers/health-check-config.js";
9
7
  import { projectHelper } from "../helpers/project-helper.js";
10
8
  import { promptHelper } from "../helpers/prompt-helper.js";
11
9
  import { dockerService } from "../services/docker-service.js";
10
+ import { nodeService } from "../services/node-service.js";
12
11
  import { shellService } from "../services/shell-service.js";
13
12
  const REGISTRY_URL = 'https://registry.npmjs.org/';
14
13
  export const checkNodePilot = {
@@ -20,16 +19,7 @@ export const checkNodePilot = {
20
19
  configStore.setProjectFlag('discordChecked', true);
21
20
  },
22
21
  async checkVersion() {
23
- const packageUrl = new URL(encodeURIComponent(packageJson.name).replace(/^%40/, '@'), REGISTRY_URL);
24
- const headers = {
25
- accept: 'application/vnd.npm.install-v1+json; q=1.0, application/json; q=0.8, */*',
26
- };
27
- const result = await fetch(packageUrl.toString(), { headers }).then(res => res.json()).catch(() => null);
28
- if (!result) {
29
- return;
30
- }
31
- const latestVer = semver.parse(result['dist-tags'].latest);
32
- const currentVer = semver.parse(packageJson.version);
22
+ const { currentVer, latestVer } = await this.compareVersions();
33
23
  if (!latestVer || !currentVer || latestVer.compare(currentVer) === 0)
34
24
  return;
35
25
  clm.echo(`There is a new node-pilot version available. Current version: "${currentVer.version}", Latest version: "${latestVer.version}"`);
@@ -43,6 +33,9 @@ export const checkNodePilot = {
43
33
  }
44
34
  if (await promptHelper.confirmPrompt('Do you wish to update now?')) {
45
35
  if (dockerIsRunning) {
36
+ const { layersToRun } = configStore.getProjectInfo();
37
+ await nodeService.leaveClusterAllLayers();
38
+ await nodeService.pollForLayersState(layersToRun, 'Offline');
46
39
  await dockerService.dockerDown();
47
40
  }
48
41
  }
@@ -72,16 +65,27 @@ export const checkNodePilot = {
72
65
  clm.postStep('Update completed. Run cpilot again to use the latest version');
73
66
  process.exit(0);
74
67
  },
68
+ async compareVersions() {
69
+ const packageUrl = new URL(encodeURIComponent(packageJson.name).replace(/^%40/, '@'), REGISTRY_URL);
70
+ const headers = {
71
+ accept: 'application/vnd.npm.install-v1+json; q=1.0, application/json; q=0.8, */*',
72
+ };
73
+ const result = await fetch(packageUrl.toString(), { headers }).then(res => res.json()).catch(() => null);
74
+ if (!result) {
75
+ return { currentVer: undefined, latestVer: undefined };
76
+ }
77
+ const latestVer = semver.parse(result['dist-tags'].latest);
78
+ const currentVer = semver.parse(packageJson.version);
79
+ return { currentVer, latestVer };
80
+ },
75
81
  isDiscordAlertsEnabled() {
76
- const hcStorage = getHcStorage();
77
- const user = hcStorage.getItem('user');
78
- return user && user.webHookEnabled;
82
+ const { webHookEnabled = false } = healthCheckConfig.getUserState();
83
+ return webHookEnabled;
79
84
  },
80
85
  async promptDiscordRegistration() {
81
- const hcStorage = getHcStorage();
82
86
  const join = await promptHelper.confirmPrompt('Do you want to enable Discord notifications for your node?:');
83
87
  if (!join) {
84
- hcStorage.setItem('user', { webHookEnabled: false });
88
+ healthCheckConfig.setUserState({ webHookEnabled: false });
85
89
  clm.postStep('Discord notifications are disabled.');
86
90
  return;
87
91
  }
@@ -99,16 +103,19 @@ export const checkNodePilot = {
99
103
  // if (answer.charAt(0) === '@') answer = answer.slice(1);
100
104
  // hcStorage.setItem('user', {discordUser: answer.trim(), webHookEnabled: true});
101
105
  // }
102
- hcStorage.setItem('user', { webHookEnabled: true });
106
+ healthCheckConfig.setUserState({ webHookEnabled: true });
103
107
  clm.postStep('Discord notifications are enabled.');
108
+ },
109
+ async runUpgrade() {
110
+ const { currentVer, latestVer } = await this.compareVersions();
111
+ if (!latestVer || !currentVer || latestVer.compare(currentVer) === 0)
112
+ return;
113
+ clm.step('Updating Node Pilot to the latest version...');
114
+ await shellService.runCommand(`sudo npm install -g @constellation-network/node-pilot@${latestVer.version}`);
115
+ const hasMajorMinorChange = latestVer.major !== currentVer.major || latestVer.minor !== currentVer.minor;
116
+ if (hasMajorMinorChange) {
117
+ clm.step('Updating scripts and configuration files...');
118
+ await projectHelper.upgradeHypergraph();
119
+ }
104
120
  }
105
121
  };
106
- function getHcStorage() {
107
- const { layersToRun, projectDir } = configStore.getProjectInfo();
108
- const layer = layersToRun[0];
109
- const hcPath = path.join(projectDir, layer, 'data', 'health-check');
110
- if (fs.existsSync(hcPath)) {
111
- fs.mkdirSync(hcPath, { recursive: true });
112
- }
113
- return new JSONStorage(hcPath);
114
- }
@@ -34,6 +34,7 @@ export default class Clean extends Command {
34
34
  await promptHelper.doYouWishToContinue();
35
35
  await dockerService.dockerDown();
36
36
  }
37
+ clm.preStep('Requesting sudo permission to remove files...');
37
38
  for (const layer of layers) {
38
39
  if (deleteData) {
39
40
  // eslint-disable-next-line no-await-in-loop
@@ -1,7 +1,7 @@
1
1
  import { Command } from '@oclif/core';
2
+ import { checkNodePilot } from "../checks/check-pilot.js";
2
3
  import { configStore } from "../config-store.js";
3
4
  import { configHelper } from "../helpers/config-helper.js";
4
- import { checkNodePilot } from "../checks/check-pilot.js";
5
5
  export default class Info extends Command {
6
6
  static description = 'Display general info about the validator node';
7
7
  static examples = [
@@ -31,6 +31,6 @@ export default class Info extends Command {
31
31
  // Fast Forward
32
32
  // configHelper.showEnvInfo('Fast Forward Enabled', (projectInfo.fastForward === undefined || Boolean(projectInfo.fastForward)).toString());
33
33
  // Discord alerts
34
- configHelper.showEnvInfo('Discord Alerts Enabled', checkNodePilot.isDiscordAlertsEnabled());
34
+ configHelper.showEnvInfo('Discord Alerts Enabled', checkNodePilot.isDiscordAlertsEnabled().toString());
35
35
  }
36
36
  }
@@ -85,6 +85,7 @@ export default class Restart extends BaseCommand {
85
85
  await dockerService.dockerDown();
86
86
  }
87
87
  clm.preStep('Checking for a new version...');
88
+ // await checkNodePilot.runUpgrade();
88
89
  await checkProject.runUpgrade();
89
90
  clm.preStep('Starting the node...');
90
91
  await dockerService.dockerRestartAll();
@@ -2,8 +2,5 @@ import { Command } from '@oclif/core';
2
2
  export default class Shutdown extends Command {
3
3
  static description: string;
4
4
  static examples: string[];
5
- static flags: {
6
- layer: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
7
- };
8
5
  run(): Promise<void>;
9
6
  }
@@ -1,4 +1,4 @@
1
- import { Command, Flags } from '@oclif/core';
1
+ import { Command } from '@oclif/core';
2
2
  import { configStore } from "../config-store.js";
3
3
  import { configHelper } from "../helpers/config-helper.js";
4
4
  import { dockerService } from "../services/docker-service.js";
@@ -8,26 +8,16 @@ export default class Shutdown extends Command {
8
8
  static examples = [
9
9
  '<%= config.bin %> <%= command.id %>',
10
10
  ];
11
- static flags = {
12
- layer: Flags.string({ char: 'l', description: 'specify a layer to shutdown. e.g. gl0' })
13
- };
11
+ // NOTE: To only run specific layers, need to first shutdown project, config layers, and restart
12
+ // static override flags = {
13
+ // layer: Flags.string({char: 'l', description: 'specify a layer to shutdown. e.g. gl0'})
14
+ // }
14
15
  async run() {
15
16
  configHelper.assertProject('No project found. ');
16
- const { flags } = await this.parse(Shutdown);
17
17
  const { layersToRun } = configStore.getProjectInfo();
18
- const layer = flags.layer;
19
- if (layer) {
20
- if (!layersToRun.includes(layer)) {
21
- this.error(`Invalid layer: ${layer}. Available layers: ${layersToRun.join(',')}`);
22
- }
23
- await nodeService.leaveCluster(layer);
24
- await nodeService.pollForLayersState([], 'Offline');
25
- await dockerService.dockerDown([layer]);
26
- }
27
- else {
28
- await nodeService.leaveClusterAllLayers();
29
- await nodeService.pollForLayersState(layersToRun, 'Offline');
30
- await dockerService.dockerDown();
31
- }
18
+ configStore.setProjectStatusToRunning(false);
19
+ await nodeService.leaveClusterAllLayers();
20
+ await nodeService.pollForLayersState(layersToRun, 'Offline');
21
+ await dockerService.dockerDown();
32
22
  }
33
23
  }
@@ -0,0 +1,13 @@
1
+ export declare const healthCheckConfig: {
2
+ getUserState(): UserState;
3
+ setNodeState(state: Partial<NodeState>): void;
4
+ setUserState(state: Partial<UserState>): void;
5
+ };
6
+ type NodeState = {
7
+ lastError: string;
8
+ };
9
+ type UserState = {
10
+ discordUser?: string;
11
+ webHookEnabled?: boolean;
12
+ };
13
+ export {};
@@ -0,0 +1,30 @@
1
+ import { JSONStorage } from "node-localstorage";
2
+ import fs from "node:fs";
3
+ import path from "node:path";
4
+ import { configStore } from "../config-store.js";
5
+ export const healthCheckConfig = {
6
+ getUserState() {
7
+ const hcStorage = getHcStorage();
8
+ const info = hcStorage.getItem('user');
9
+ return info || {};
10
+ },
11
+ setNodeState(state) {
12
+ const hcStorage = getHcStorage();
13
+ const info = hcStorage.getItem('node');
14
+ hcStorage.setItem('node', { ...info, ...state });
15
+ },
16
+ setUserState(state) {
17
+ const hcStorage = getHcStorage();
18
+ const info = hcStorage.getItem('user');
19
+ hcStorage.setItem('user', { ...info, ...state });
20
+ }
21
+ };
22
+ function getHcStorage() {
23
+ const { layersToRun, projectDir } = configStore.getProjectInfo();
24
+ const layer = layersToRun[0];
25
+ const hcPath = path.join(projectDir, layer, 'data', 'health-check');
26
+ if (fs.existsSync(hcPath)) {
27
+ fs.mkdirSync(hcPath, { recursive: true });
28
+ }
29
+ return new JSONStorage(hcPath);
30
+ }
@@ -38,7 +38,7 @@ export class StatusTable {
38
38
  const activeProject = configStore.getActiveProject();
39
39
  const projects = configStore.getRunningProjects();
40
40
  if (!activeProject || projects.length === 0) {
41
- clm.error("No running projects found.");
41
+ clm.error("No projects are running.");
42
42
  }
43
43
  const info = [];
44
44
  for (const project of projects) {
@@ -23,7 +23,6 @@ export const dockerService = {
23
23
  }
24
24
  },
25
25
  async dockerDown(layers) {
26
- configStore.setProjectStatusToRunning(false);
27
26
  await run('down', layers);
28
27
  },
29
28
  async dockerRestart(layer) {
@@ -215,16 +215,7 @@
215
215
  "examples": [
216
216
  "<%= config.bin %> <%= command.id %>"
217
217
  ],
218
- "flags": {
219
- "layer": {
220
- "char": "l",
221
- "description": "specify a layer to shutdown. e.g. gl0",
222
- "name": "layer",
223
- "hasDynamicHelp": false,
224
- "multiple": false,
225
- "type": "option"
226
- }
227
- },
218
+ "flags": {},
228
219
  "hasDynamicHelp": false,
229
220
  "hiddenAliases": [],
230
221
  "id": "shutdown",
@@ -349,5 +340,5 @@
349
340
  ]
350
341
  }
351
342
  },
352
- "version": "0.6.0"
343
+ "version": "0.7.0"
353
344
  }
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@constellation-network/node-pilot",
3
3
  "description": "An easy deployment and monitoring tool for Constellation nodes.",
4
- "version": "0.6.0",
4
+ "version": "0.7.0",
5
5
  "author": "Frank Fox",
6
6
  "bin": {
7
7
  "cpilot": "bin/run.js"
@@ -39,7 +39,7 @@ COPY dist/gl0.jar /app/jars/gl0.jar
39
39
  #COPY ./health-check /health-check
40
40
  #RUN chmod +x /health-check/bin/run.sh
41
41
  #RUN chmod +x /health-check/bin/hydrate.sh
42
- RUN npm install -g "@constellation-network/node-pilot-health-check@0.0.20"
42
+ RUN npm install -g "@constellation-network/node-pilot-health-check@0.0.21"
43
43
 
44
44
  # Add entrypoint
45
45
  COPY ./entrypoint.sh /app/entrypoint.sh