@constellation-network/node-pilot 0.18.0-testnet → 0.18.1-intnet

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.
Files changed (44) hide show
  1. package/README.md +12 -16
  2. package/dist/base-command.d.ts +1 -1
  3. package/dist/base-command.js +13 -4
  4. package/dist/checks/check-hardware.js +2 -2
  5. package/dist/checks/check-initial-setup.js +2 -1
  6. package/dist/checks/check-network.js +0 -7
  7. package/dist/checks/check-project.js +6 -4
  8. package/dist/clm.js +2 -2
  9. package/dist/commands/config/get.js +8 -0
  10. package/dist/commands/config/set.js +5 -1
  11. package/dist/commands/config.js +8 -0
  12. package/dist/commands/info.js +6 -0
  13. package/dist/commands/project.d.ts +12 -0
  14. package/dist/commands/project.js +46 -0
  15. package/dist/commands/restart.d.ts +2 -2
  16. package/dist/commands/restart.js +15 -16
  17. package/dist/commands/shutdown.js +2 -1
  18. package/dist/commands/status.d.ts +1 -1
  19. package/dist/commands/status.js +1 -1
  20. package/dist/config-store.d.ts +12 -20
  21. package/dist/config-store.js +9 -116
  22. package/dist/helpers/config-helper.js +2 -1
  23. package/dist/helpers/pilot-manager.d.ts +23 -0
  24. package/dist/helpers/pilot-manager.js +170 -0
  25. package/dist/helpers/project-helper.d.ts +3 -2
  26. package/dist/helpers/project-helper.js +39 -17
  27. package/dist/helpers/prompt-helper.d.ts +1 -0
  28. package/dist/helpers/prompt-helper.js +15 -3
  29. package/dist/helpers/service-log.js +2 -2
  30. package/dist/helpers/status-table.js +5 -4
  31. package/dist/services/cluster-service.d.ts +2 -1
  32. package/dist/services/cluster-service.js +28 -7
  33. package/dist/services/docker-service.js +3 -2
  34. package/dist/services/node-service.js +3 -2
  35. package/oclif.manifest.json +42 -13
  36. package/package.json +2 -2
  37. package/projects/hypergraph/docker-compose.yml +8 -4
  38. package/projects/hypergraph/networks/integrationnet/gl0.env +2 -1
  39. package/projects/hypergraph/networks/integrationnet/gl1.env +4 -3
  40. package/projects/hypergraph/networks/mainnet/gl0.env +2 -1
  41. package/projects/hypergraph/networks/mainnet/gl1.env +2 -1
  42. package/projects/hypergraph/networks/testnet/gl0.env +1 -0
  43. package/projects/hypergraph/networks/testnet/gl1.env +1 -0
  44. package/projects/hypergraph/scripts/install-dependencies.sh +2 -2
@@ -1,10 +1,6 @@
1
- import { input } from "@inquirer/prompts";
2
1
  import { JSONStorage } from "node-localstorage";
3
2
  import fs from "node:fs";
4
- import os from "node:os";
5
- import path from "node:path";
6
3
  import packageJson from '../package.json' with { type: 'json' };
7
- import { clm } from "./clm.js";
8
4
  const pilotReleaseInfo = { name: packageJson.name, version: packageJson.version };
9
5
  class EmptyStorage extends JSONStorage {
10
6
  constructor() { super("/tmp"); }
@@ -12,52 +8,7 @@ class EmptyStorage extends JSONStorage {
12
8
  setItem(_key, _value) { }
13
9
  }
14
10
  class ConfigStore {
15
- pilotStore;
16
- projectStore;
17
- constructor() {
18
- const appDir = path.join(os.homedir(), '.node-pilot');
19
- if (!fs.existsSync(appDir)) {
20
- fs.mkdirSync(path.join(appDir, 'logs'), { recursive: true });
21
- }
22
- this.pilotStore = new JSONStorage(path.join(appDir, 'config'));
23
- const appInfo = this.pilotStore.getItem('pilot');
24
- if (!appInfo) {
25
- this.pilotStore.setItem('pilot', { appDir, project: 'undefined', projects: [], restarting: 0, running: [] });
26
- }
27
- const { project } = this.pilotStore.getItem('pilot');
28
- this.projectStore = project === 'undefined' ? new EmptyStorage() : new JSONStorage(path.join(appDir, project, 'config'));
29
- }
30
- async applyNewProjectStore(name) {
31
- const { appDir, projects } = this.pilotStore.getItem('pilot');
32
- const projectDir = path.join(appDir, name);
33
- if (projects.includes(name)) {
34
- const answer = await input({ default: 'n', message: `Project ${name} already exists. Do you want to reinstall? (y/n):` });
35
- if (answer === 'y') {
36
- this.projectStore = new JSONStorage(path.join(projectDir, 'config'));
37
- this.projectStore.clear();
38
- fs.rmSync(projectDir, { force: true, recursive: true });
39
- this.pilotStore.setItem('pilot', { appDir, project: name, projects });
40
- }
41
- else {
42
- clm.error(`Project ${name} already exists.`);
43
- }
44
- }
45
- else {
46
- this.setPilotInfo({ project: name, projects: [...projects, name] });
47
- }
48
- fs.mkdirSync(path.join(projectDir, 'config'), { recursive: true });
49
- this.projectStore = new JSONStorage(path.join(projectDir, 'config'));
50
- this.setDockerEnvInfo({ DOCKER_IMAGE_VERSION: 'test' });
51
- this.setProjectInfo({ name, projectDir });
52
- }
53
- getActiveProject() {
54
- const { project } = this.pilotStore.getItem('pilot');
55
- return project;
56
- }
57
- getAppDir() {
58
- const { appDir } = this.pilotStore.getItem('pilot');
59
- return appDir;
60
- }
11
+ projectStore = new EmptyStorage();
61
12
  getDockerEnvInfo() {
62
13
  return this.projectStore.getItem('docker');
63
14
  }
@@ -82,7 +33,7 @@ class ConfigStore {
82
33
  return { CLI: layerInfo.CL_CLI_HTTP_PORT, P2P: layerInfo.CL_P2P_HTTP_PORT, PUBLIC: layerInfo.CL_PUBLIC_HTTP_PORT };
83
34
  }
84
35
  getNetworkInfo() {
85
- return this.projectStore.getItem('network');
36
+ return this.projectStore.getItem('network') || {};
86
37
  }
87
38
  getPilotReleaseInfo() {
88
39
  return pilotReleaseInfo;
@@ -90,45 +41,10 @@ class ConfigStore {
90
41
  getProjectInfo() {
91
42
  return this.projectStore.getItem('project') || {};
92
43
  }
93
- getProjects() {
94
- const { projects } = this.pilotStore.getItem('pilot');
95
- return projects;
96
- }
97
- getRunningProjects() {
98
- const { running } = this.pilotStore.getItem('pilot');
99
- return running;
100
- }
101
- getSystemInfo() {
102
- return this.pilotStore.getItem('system');
103
- }
104
44
  hasProjectFlag(name) {
105
45
  const flags = this.projectStore.getItem('flags') || {};
106
46
  return flags[name] || false;
107
47
  }
108
- hasProjects() {
109
- const { projects } = this.pilotStore.getItem('pilot');
110
- return projects.length > 0;
111
- }
112
- isRestarting() {
113
- const { restarting } = this.pilotStore.getItem('pilot');
114
- if (restarting && restarting + 1000 * 60 * 5 < Date.now()) {
115
- this.setIsRestarting(0);
116
- return false;
117
- }
118
- return restarting > 0;
119
- }
120
- setActiveProject(name) {
121
- const { appDir, project, projects } = this.pilotStore.getItem('pilot');
122
- if (projects && projects.includes(name)) {
123
- if (project === name)
124
- return;
125
- this.projectStore = new JSONStorage(path.join(appDir, name, 'config'));
126
- this.setPilotInfo({ project: name });
127
- }
128
- else {
129
- throw new Error(`Project ${name} doesn't exist.`);
130
- }
131
- }
132
48
  setClusterStats(info) {
133
49
  const oldInfo = this.projectStore.getItem('cluster-stats');
134
50
  this.projectStore.setItem('cluster-stats', { ...oldInfo, ...info });
@@ -155,13 +71,14 @@ class ConfigStore {
155
71
  networks = {};
156
72
  this.projectStore.setItem('network-env', { ...networks, [network]: { ...networks[network], ...info } });
157
73
  }
158
- setIsRestarting(val) {
159
- this.setPilotInfo({ restarting: val });
160
- }
161
74
  setNetworkInfo(info) {
162
75
  const oldInfo = this.projectStore.getItem('network');
163
76
  this.projectStore.setItem('network', { ...oldInfo, ...info });
164
77
  }
78
+ setProjectConfig(config) {
79
+ const projectExists = fs.existsSync(config);
80
+ this.projectStore = projectExists ? new JSONStorage(config) : new EmptyStorage();
81
+ }
165
82
  setProjectFlag(name, value) {
166
83
  const flags = this.projectStore.getItem('flags') || {};
167
84
  flags[name] = value;
@@ -172,31 +89,6 @@ class ConfigStore {
172
89
  const oldInfo = this.projectStore.getItem('project');
173
90
  this.projectStore.setItem('project', { ...oldInfo, ...info });
174
91
  }
175
- setProjectStatusToRunning(isRunning) {
176
- const { project, running } = this.pilotStore.getItem('pilot');
177
- if (isRunning) {
178
- if (running.includes(project))
179
- return;
180
- this.setPilotInfo({ running: [...running, project] });
181
- }
182
- else {
183
- if (!running.includes(project))
184
- return;
185
- running.splice(running.indexOf(project), 1);
186
- this.setPilotInfo({ running });
187
- }
188
- }
189
- setSystemInfo(info) {
190
- const oldInfo = this.projectStore.getItem('system');
191
- this.pilotStore.setItem('system', { ...oldInfo, ...info });
192
- }
193
- getPilotInfo() {
194
- return this.pilotStore.getItem('pilot');
195
- }
196
- setPilotInfo(info) {
197
- const oldInfo = this.pilotStore.getItem('pilot');
198
- this.pilotStore.setItem('pilot', { ...oldInfo, ...info });
199
- }
200
92
  }
201
93
  export const configStore = new ConfigStore();
202
94
  export const envNames = {
@@ -214,7 +106,7 @@ export const networkEnvNames = {
214
106
  CL_L0_PEER_HTTP_PORT: 1,
215
107
  CL_L0_PEER_ID: 1,
216
108
  CL_L0_PEER_P2P_PORT: 1,
217
- CL_L0_TOKEN_IDENTIFIER: 1,
109
+ CL_L0_TOKEN_IDENTIFIER: 1
218
110
  };
219
111
  // NETWORK LAYER
220
112
  export const layerEnvNames = {
@@ -229,5 +121,6 @@ export const layerEnvNames = {
229
121
  CL_L0_PEER_P2P_PORT: 1,
230
122
  CL_LB: 1,
231
123
  CL_P2P_HTTP_PORT: 1,
232
- CL_PUBLIC_HTTP_PORT: 1
124
+ CL_PUBLIC_HTTP_PORT: 1,
125
+ CL_SOURCE_HTTP_PORT: 1
233
126
  };
@@ -4,9 +4,10 @@ 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 { pilotManager } from "./pilot-manager.js";
7
8
  export const configHelper = {
8
9
  assertProject(prefix = '') {
9
- if (configStore.hasProjects())
10
+ if (pilotManager.hasProjects())
10
11
  return;
11
12
  clm.error(prefix + 'Please create a new project first.');
12
13
  },
@@ -0,0 +1,23 @@
1
+ import { SystemInfo } from "../config-store.js";
2
+ export declare class PilotManager {
3
+ private pilotStore;
4
+ constructor();
5
+ applyNewProjectStore(name: string, type: 'hypergraph' | 'metagraph'): Promise<void>;
6
+ getActiveProject(): string;
7
+ getAppDir(): string;
8
+ getProjectDir(project: string): string;
9
+ getProjects(): string[];
10
+ getRunningProjects(): string[];
11
+ getSystemInfo(): SystemInfo;
12
+ hasProjects(): boolean;
13
+ isProjectInstalled(): boolean;
14
+ isRestarting(): boolean;
15
+ removeProject(name: string): Promise<void>;
16
+ setActiveProject(name: string, isNewProject?: boolean): void;
17
+ setIsRestarting(val: number): void;
18
+ setProjectStatusToRunning(isRunning: boolean): void;
19
+ setSystemInfo(info: Partial<SystemInfo>): void;
20
+ private getPilotInfo;
21
+ private setPilotInfo;
22
+ }
23
+ export declare const pilotManager: PilotManager;
@@ -0,0 +1,170 @@
1
+ import { input } from "@inquirer/prompts";
2
+ import chalk from "chalk";
3
+ import { JSONStorage } from "node-localstorage";
4
+ import fs from "node:fs";
5
+ import os from "node:os";
6
+ import path from "node:path";
7
+ import { clm } from "../clm.js";
8
+ import { configStore } from "../config-store.js";
9
+ import { shellService } from "../services/shell-service.js";
10
+ import { promptHelper } from "./prompt-helper.js";
11
+ export class PilotManager {
12
+ pilotStore;
13
+ constructor() {
14
+ const appDir = path.join(os.homedir(), '.node-pilot');
15
+ if (!fs.existsSync(appDir)) {
16
+ fs.mkdirSync(path.join(appDir, 'logs'), { recursive: true });
17
+ }
18
+ this.pilotStore = new JSONStorage(path.join(appDir, 'config'));
19
+ const appInfo = this.pilotStore.getItem('pilot');
20
+ if (!appInfo) {
21
+ this.pilotStore.setItem('pilot', { appDir, project: 'undefined', projects: [], restarting: 0, running: [] });
22
+ }
23
+ const { project } = this.pilotStore.getItem('pilot');
24
+ const projectPath = path.join(appDir, project, 'config');
25
+ configStore.setProjectConfig(projectPath);
26
+ }
27
+ async applyNewProjectStore(name, type) {
28
+ const { appDir, projects } = this.pilotStore.getItem('pilot');
29
+ const projectDir = path.join(appDir, name);
30
+ if (projects.includes(name)) {
31
+ if (fs.existsSync(projectDir)) {
32
+ const answer = await input({
33
+ default: 'n',
34
+ message: `Project ${name} already exists. Do you want to reinstall? (y/n):`
35
+ });
36
+ if (answer === 'y') {
37
+ // this.projectStore = new JSONStorage(path.join(projectDir,'config'));
38
+ // this.projectStore.clear();
39
+ fs.rmSync(projectDir, { force: true, recursive: true });
40
+ this.setPilotInfo({ project: name });
41
+ }
42
+ else {
43
+ clm.error(`Project ${name} already exists.`);
44
+ }
45
+ }
46
+ else {
47
+ this.setPilotInfo({ project: name });
48
+ }
49
+ }
50
+ else {
51
+ this.setPilotInfo({ project: name, projects: [...projects, name] });
52
+ }
53
+ fs.mkdirSync(path.join(projectDir, 'config'), { recursive: true });
54
+ // this.projectStore = new JSONStorage(path.join(projectDir,'config'));
55
+ configStore.setProjectConfig(path.join(projectDir, 'config'));
56
+ configStore.setDockerEnvInfo({ DOCKER_IMAGE_VERSION: 'test' });
57
+ configStore.setProjectInfo({ name, projectDir, type });
58
+ }
59
+ getActiveProject() {
60
+ const { project } = this.pilotStore.getItem('pilot');
61
+ return project;
62
+ }
63
+ getAppDir() {
64
+ const { appDir } = this.pilotStore.getItem('pilot');
65
+ return appDir;
66
+ }
67
+ getProjectDir(project) {
68
+ const { appDir } = this.pilotStore.getItem('pilot');
69
+ const dir = path.join(appDir, project);
70
+ if (fs.existsSync(dir))
71
+ return dir;
72
+ throw new Error(`Project ${project} doesn't exist.`);
73
+ }
74
+ getProjects() {
75
+ const { projects } = this.pilotStore.getItem('pilot');
76
+ return projects;
77
+ }
78
+ getRunningProjects() {
79
+ const { running } = this.pilotStore.getItem('pilot');
80
+ return running;
81
+ }
82
+ getSystemInfo() {
83
+ return this.pilotStore.getItem('system');
84
+ }
85
+ hasProjects() {
86
+ const { projects } = this.pilotStore.getItem('pilot');
87
+ return projects.length > 0;
88
+ }
89
+ isProjectInstalled() {
90
+ const { appDir, projects } = this.pilotStore.getItem('pilot');
91
+ const activeProject = this.getActiveProject();
92
+ return projects.includes(activeProject) && fs.existsSync(path.join(appDir, activeProject));
93
+ }
94
+ isRestarting() {
95
+ const { restarting } = this.pilotStore.getItem('pilot');
96
+ if (restarting && restarting + 1000 * 60 * 5 < Date.now()) {
97
+ this.setIsRestarting(0);
98
+ return false;
99
+ }
100
+ return restarting > 0;
101
+ }
102
+ async removeProject(name) {
103
+ let { project, projects } = this.pilotStore.getItem('pilot');
104
+ projects.splice(projects.indexOf(name), 1);
105
+ if (projects.length === 0) {
106
+ clm.error(`Project ${name} cannot be removed as it is the only active project.`);
107
+ }
108
+ if (project === name) {
109
+ project = projects[0];
110
+ if (project) {
111
+ clm.postStep(`Active project has been changed to ${project}`);
112
+ }
113
+ }
114
+ try {
115
+ const projectDir = this.getProjectDir(name);
116
+ clm.warn(`WARNING: This will remove all data and logs associated with the project ${chalk.cyan(name)}. Use with caution.`);
117
+ await promptHelper.doYouWishToContinue();
118
+ clm.warn('Running with "sudo" which may request your password...');
119
+ await shellService.runCommand(`sudo rm -rf ${projectDir}`);
120
+ }
121
+ catch {
122
+ clm.warn(`Project ${name} not found.`);
123
+ }
124
+ this.setPilotInfo({ project, projects });
125
+ }
126
+ setActiveProject(name, isNewProject = false) {
127
+ const { appDir, project, projects } = this.pilotStore.getItem('pilot');
128
+ if (projects && projects.includes(name)) {
129
+ if (project === name)
130
+ return;
131
+ configStore.setProjectConfig(path.join(appDir, name, 'config'));
132
+ this.setPilotInfo({ project: name });
133
+ }
134
+ else if (isNewProject) {
135
+ this.setPilotInfo({ project: name });
136
+ }
137
+ else {
138
+ throw new Error(`Project ${name} doesn't exist.`);
139
+ }
140
+ }
141
+ setIsRestarting(val) {
142
+ this.setPilotInfo({ restarting: val });
143
+ }
144
+ setProjectStatusToRunning(isRunning) {
145
+ const { project, running } = this.pilotStore.getItem('pilot');
146
+ if (isRunning) {
147
+ if (running.includes(project))
148
+ return;
149
+ this.setPilotInfo({ running: [...running, project] });
150
+ }
151
+ else {
152
+ if (!running.includes(project))
153
+ return;
154
+ running.splice(running.indexOf(project), 1);
155
+ this.setPilotInfo({ running });
156
+ }
157
+ }
158
+ setSystemInfo(info) {
159
+ const oldInfo = this.pilotStore.getItem('system');
160
+ this.pilotStore.setItem('system', { ...oldInfo, ...info });
161
+ }
162
+ getPilotInfo() {
163
+ return this.pilotStore.getItem('pilot');
164
+ }
165
+ setPilotInfo(info) {
166
+ const oldInfo = this.pilotStore.getItem('pilot');
167
+ this.pilotStore.setItem('pilot', { ...oldInfo, ...info });
168
+ }
169
+ }
170
+ export const pilotManager = new PilotManager();
@@ -3,12 +3,13 @@ export declare const projectHelper: {
3
3
  cleanup(layers: TessellationLayer[], deleteData: boolean, deleteLogs: boolean, deleteJars: boolean): Promise<void>;
4
4
  generateLayerEnvFiles(layers?: TessellationLayer[]): Promise<void>;
5
5
  importEnvFiles(): void;
6
- installEmbedded(name: string): Promise<void>;
6
+ installEmbedded(embeddedName: string, projectName: string, projectType: "hypergraph" | "metagraph"): Promise<void>;
7
7
  installFromGithub(_repo: string): Promise<never>;
8
8
  installHypergraph(): Promise<void>;
9
- installProject(name: string, projectFolder: string): Promise<void>;
9
+ installProject(name: string, type: "hypergraph" | "metagraph", projectFolder: string): Promise<void>;
10
10
  prepareDataFolder(): void;
11
11
  selectProject(): Promise<void>;
12
+ updateDockerEnv(): void;
12
13
  upgradeEmbedded(name: string): void;
13
14
  upgradeHypergraph(): void;
14
15
  upgradeProject(name: string, projectFolder: string): void;
@@ -9,6 +9,7 @@ import { githubService } from "../services/github-service.js";
9
9
  import { shellService } from "../services/shell-service.js";
10
10
  import { configHelper } from "./config-helper.js";
11
11
  import { getLayerEnvFileContent } from "./env-templates.js";
12
+ import { pilotManager } from "./pilot-manager.js";
12
13
  import { promptHelper } from "./prompt-helper.js";
13
14
  export const projectHelper = {
14
15
  async cleanup(layers, deleteData, deleteLogs, deleteJars) {
@@ -73,12 +74,12 @@ export const projectHelper = {
73
74
  // eslint-disable-next-line no-warning-comments
74
75
  // TODO: verify all required env variables are present
75
76
  },
76
- async installEmbedded(name) {
77
- const projectFolder = path.resolve(path.dirname(fileURLToPath(import.meta.url)), `../../projects/${name}`);
77
+ async installEmbedded(embeddedName, projectName, projectType) {
78
+ const projectFolder = path.resolve(path.dirname(fileURLToPath(import.meta.url)), `../../projects/${embeddedName}`);
78
79
  if (!fs.existsSync(projectFolder)) {
79
80
  clm.error(`Project folder not found: ${projectFolder}`);
80
81
  }
81
- await this.installProject(name, projectFolder);
82
+ await this.installProject(projectName, projectType, projectFolder);
82
83
  // Set the project version to match the latest Pilot version. This prevents previous migration scripts from running.
83
84
  configStore.setProjectInfo({ version: configStore.getPilotReleaseInfo().version });
84
85
  },
@@ -88,28 +89,21 @@ export const projectHelper = {
88
89
  throw new Error('installFromGithub - Not implemented');
89
90
  },
90
91
  async installHypergraph() {
91
- await this.installEmbedded('hypergraph');
92
+ const name = pilotManager.getActiveProject() || 'hypergraph';
93
+ await this.installEmbedded('hypergraph', name, 'hypergraph');
92
94
  this.prepareDataFolder();
93
- // const {projectDir} = configStore.getProjectInfo();
94
- // const {platform} = configStore.getSystemInfo();
95
- //
96
- // if (platform === 'linux') {
97
- // const layerDir = path.join(projectDir,'gl0');
98
- // // set permission for group "docker" on the layer folder and any subfolders created later
99
- // await shellService.runCommand(`sudo setfacl -Rm g:docker:rwX -dm g:docker:rwX ${layerDir}`)
100
- // }
101
95
  this.importEnvFiles();
102
96
  },
103
- async installProject(name, projectFolder) {
104
- if (!configStore.hasProjects()) {
97
+ async installProject(name, type, projectFolder) {
98
+ if (!pilotManager.hasProjects()) {
105
99
  // On first install, copy scripts
106
100
  const scriptsFolder = path.resolve(path.dirname(fileURLToPath(import.meta.url)), `../../scripts`);
107
- const projectDir = path.join(configStore.getAppDir(), 'scripts');
101
+ const projectDir = path.join(pilotManager.getAppDir(), 'scripts');
108
102
  clm.debug(`Installing node pilot scripts from ${scriptsFolder} to ${projectDir}`);
109
103
  fs.mkdirSync(projectDir, { recursive: true });
110
104
  fs.cpSync(scriptsFolder, projectDir, { recursive: true });
111
105
  }
112
- await configStore.applyNewProjectStore(name);
106
+ await pilotManager.applyNewProjectStore(name, type);
113
107
  const { projectDir } = configStore.getProjectInfo();
114
108
  clm.debug(`Installing project from ${projectFolder} to ${projectDir}`);
115
109
  fs.cpSync(projectFolder, projectDir, { recursive: true });
@@ -146,7 +140,7 @@ export const projectHelper = {
146
140
  });
147
141
  const ghRepoRegex = /^https?:\/\/(?:www\.)?github\.com\/([A-Za-z0-9](?:-?[A-Za-z0-9]){0,38})\/([A-Za-z0-9._-]+)(?:\.git)?\/?$/;
148
142
  if (project === 'dor') {
149
- await this.installEmbedded('dor');
143
+ await this.installEmbedded('dor', 'dor', 'metagraph');
150
144
  }
151
145
  else if (project === 'custom') {
152
146
  let repo = await input({
@@ -173,6 +167,33 @@ export const projectHelper = {
173
167
  }
174
168
  }
175
169
  },
170
+ updateDockerEnv() {
171
+ const { type: network } = configStore.getNetworkInfo();
172
+ let CL_GL0_PUBLIC_PORT = '';
173
+ let CL_GL0_P2P_PORT = '';
174
+ let CL_GL1_PUBLIC_PORT = '';
175
+ let CL_GL1_P2P_PORT = '';
176
+ const { layersToRun } = configStore.getProjectInfo();
177
+ for (const layer of layersToRun) {
178
+ const info = configStore.getEnvLayerInfo(network, layer);
179
+ switch (layer) {
180
+ case 'gl0': {
181
+ CL_GL0_P2P_PORT = info.CL_P2P_HTTP_PORT;
182
+ CL_GL0_PUBLIC_PORT = info.CL_PUBLIC_HTTP_PORT;
183
+ break;
184
+ }
185
+ case 'gl1': {
186
+ CL_GL1_P2P_PORT = info.CL_P2P_HTTP_PORT;
187
+ CL_GL1_PUBLIC_PORT = info.CL_PUBLIC_HTTP_PORT;
188
+ break;
189
+ }
190
+ }
191
+ }
192
+ configStore.setDockerEnvInfo({
193
+ CL_GL0_P2P_PORT, CL_GL0_PUBLIC_PORT,
194
+ CL_GL1_P2P_PORT, CL_GL1_PUBLIC_PORT
195
+ });
196
+ },
176
197
  upgradeEmbedded(name) {
177
198
  const projectFolder = path.resolve(path.dirname(fileURLToPath(import.meta.url)), `../../projects/${name}`);
178
199
  if (!fs.existsSync(projectFolder)) {
@@ -183,6 +204,7 @@ export const projectHelper = {
183
204
  upgradeHypergraph() {
184
205
  this.upgradeEmbedded('hypergraph');
185
206
  this.importEnvFiles();
207
+ this.updateDockerEnv();
186
208
  },
187
209
  upgradeProject(name, projectFolder) {
188
210
  const { projectDir } = configStore.getProjectInfo();
@@ -1,4 +1,5 @@
1
1
  export declare const promptHelper: {
2
+ configurePorts(): Promise<void>;
2
3
  confirmPrompt(msg: string): Promise<boolean>;
3
4
  doYouWishToContinue(defaultAnswer?: "n" | "y"): Promise<void>;
4
5
  selectLayers(): Promise<void>;
@@ -1,10 +1,22 @@
1
- import { checkbox, input, select } from "@inquirer/prompts";
1
+ import { checkbox, input, number, select } 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
5
  import { dockerService } from "../services/docker-service.js";
6
6
  import { nodeService } from "../services/node-service.js";
7
7
  export const promptHelper = {
8
+ async configurePorts() {
9
+ const defaults = { cl1: [9300, 9301], dl1: [9400, 9401], gl0: [9000, 9001], gl1: [9100, 9101], ml0: [9200, 9201] };
10
+ const { layersToRun } = configStore.getProjectInfo();
11
+ const { type: network } = configStore.getNetworkInfo();
12
+ for (const layer of layersToRun) {
13
+ // eslint-disable-next-line no-await-in-loop
14
+ const port1 = await number({ default: defaults[layer][0], message: `${layer} Public Port:`, required: true, validate: v => v !== undefined && v > 0 && v <= 65_535 });
15
+ // eslint-disable-next-line no-await-in-loop
16
+ const port2 = await number({ default: defaults[layer][1], message: `${layer} P2P Port:`, required: true, validate: v => v !== undefined && v > 0 && v <= 65_535 });
17
+ configStore.setEnvLayerInfo(network, layer, { CL_P2P_HTTP_PORT: port2.toString(), CL_PUBLIC_HTTP_PORT: port1.toString() });
18
+ }
19
+ },
8
20
  async confirmPrompt(msg) {
9
21
  const result = await input({
10
22
  default: 'y',
@@ -34,8 +46,8 @@ export const promptHelper = {
34
46
  }
35
47
  },
36
48
  async selectLayers() {
37
- const { name } = configStore.getProjectInfo();
38
- const choices = name === 'hypergraph' ? ['gl0', 'gl1'] : ['ml0', 'cl1', 'dl1'];
49
+ const { name, type } = configStore.getProjectInfo();
50
+ const choices = type === 'hypergraph' ? ['gl0', 'gl1'] : ['ml0', 'cl1', 'dl1'];
39
51
  const result = await checkbox({ choices, message: `Select network layers to run for ${chalk.cyan(name)}:`, validate: v => v.length > 0 });
40
52
  configStore.setProjectInfo({ layersToRun: result });
41
53
  },
@@ -1,12 +1,12 @@
1
1
  import fs from "node:fs";
2
2
  import path from "node:path";
3
- import { configStore } from "../config-store.js";
3
+ import { pilotManager } from "./pilot-manager.js";
4
4
  export const serviceLog = {
5
5
  error(s) {
6
6
  this.log(s);
7
7
  },
8
8
  log(s) {
9
- const appDir = configStore.getAppDir();
9
+ const appDir = pilotManager.getAppDir();
10
10
  const logFile = path.join(appDir, 'logs', 'service.log');
11
11
  fs.appendFileSync(logFile, s + '\n');
12
12
  },
@@ -5,6 +5,7 @@ import os from "node:os";
5
5
  import ttyTable from "tty-table";
6
6
  import { clm } from "../clm.js";
7
7
  import { configStore } from "../config-store.js";
8
+ import { pilotManager } from "./pilot-manager.js";
8
9
  import { formatTimeAgo, glHeader1, glHeader2, statusTableHeader } from "./status-table-helper.js";
9
10
  export class StatusTable {
10
11
  alreadyRendered = false;
@@ -35,21 +36,21 @@ export class StatusTable {
35
36
  }
36
37
  getProjectInfo() {
37
38
  const appPath = os.homedir() + '/.node-pilot';
38
- const activeProject = configStore.getActiveProject();
39
- const projects = configStore.getRunningProjects();
39
+ const activeProject = pilotManager.getActiveProject();
40
+ const projects = pilotManager.getRunningProjects();
40
41
  if (!activeProject || projects.length === 0) {
41
42
  clm.error("No projects are running.");
42
43
  }
43
44
  const info = [];
44
45
  for (const project of projects) {
45
- configStore.setActiveProject(project);
46
+ pilotManager.setActiveProject(project);
46
47
  const { layersToRun } = configStore.getProjectInfo();
47
48
  const { type: network } = configStore.getNetworkInfo();
48
49
  for (const layer of layersToRun) {
49
50
  info.push({ layer, network, path: `${appPath}/${project}/${layer}/data/health-check/node`, project });
50
51
  }
51
52
  }
52
- configStore.setActiveProject(activeProject);
53
+ pilotManager.setActiveProject(activeProject);
53
54
  return info;
54
55
  }
55
56
  async monitorNarrow() {
@@ -10,8 +10,9 @@ export declare const clusterService: {
10
10
  getSourceNodeInfo(layer: TessellationLayer): Promise<NodeInfo>;
11
11
  getSourceNodeLatestOrdinal(layer: TessellationLayer): Promise<number>;
12
12
  getSourceNodeOrdinalHash(layer: TessellationLayer, ordinal: number): Promise<string>;
13
- makeClusterRequestGet(path: string, layer?: TessellationLayer): Promise<any>;
13
+ makeClusterRequestGet(path: string, layer?: TessellationLayer, params?: string): Promise<any>;
14
14
  makeClusterRequestPost(path: string, body: string, layer?: TessellationLayer): Promise<any>;
15
+ makeRandomSourceNodeRequest(path: string, layer: TessellationLayer): Promise<any>;
15
16
  makeSourceNodeRequest(path: string, layer: TessellationLayer): Promise<any>;
16
17
  postNodeParams(body: string, layer?: TessellationLayer): Promise<string>;
17
18
  };