@underpostnet/underpost 3.0.1 → 3.0.3

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/CLI-HELP.md CHANGED
@@ -1,4 +1,4 @@
1
- ## underpost ci/cd cli v3.0.1
1
+ ## underpost ci/cd cli v3.0.3
2
2
 
3
3
  ### Usage: `underpost [options] [command]`
4
4
  ```
@@ -379,8 +379,6 @@ Options:
379
379
  --dedicated-gpu Initializes the cluster with dedicated
380
380
  GPU base resources and environment
381
381
  settings.
382
- --full Initializes the cluster with all
383
- available statefulsets and services.
384
382
  --ns-use <ns-name> Switches the current Kubernetes context
385
383
  to the specified namespace (creates if
386
384
  it doesn't exist).
@@ -835,7 +833,7 @@ Options:
835
833
  Runs specified scripts using various runners.
836
834
 
837
835
  Arguments:
838
- runner-id The runner ID to run. Options: dev-cluster,metadata,svc-ls,svc-rm,ssh-deploy-info,dev-hosts-expose,dev-hosts-restore,cluster-build,template-deploy,template-deploy-image,clean,pull,release-deploy,ssh-deploy,ide,crypto-policy,sync,stop,ssh-deploy-stop,ssh-deploy-db-rollback,ssh-deploy-db,ssh-deploy-db-status,tz,get-proxy,instance-promote,instance,ls-deployments,host-update,dd-container,ip-info,db-client,git-conf,promote,metrics,cluster,deploy,disk-clean,disk-devices,disk-usage,dev,service,etc-hosts,sh,log,ps,ptls,release-cmt,deploy-test,sync-replica,tf-vae-test,spark-template,rmi,kill,secret,underpost-config,gpu-env,tf-gpu-test,deploy-job.
836
+ runner-id The runner ID to run. Options: dev-cluster,ipfs-expose,metadata,svc-ls,svc-rm,ssh-deploy-info,dev-hosts-expose,dev-hosts-restore,cluster-build,template-deploy,template-deploy-image,clean,pull,release-deploy,ssh-deploy,ide,crypto-policy,sync,stop,ssh-deploy-stop,ssh-deploy-db-rollback,ssh-deploy-db,ssh-deploy-db-status,tz,get-proxy,instance-promote,instance,ls-deployments,host-update,dd-container,ip-info,db-client,git-conf,promote,metrics,cluster,deploy,disk-clean,disk-devices,disk-usage,dev,service,etc-hosts,sh,log,ps,ptls,release-cmt,deploy-test,sync-replica,tf-vae-test,spark-template,rmi,kill,secret,underpost-config,gpu-env,tf-gpu-test,deploy-job.
839
837
  path The input value, identifier, or path for the operation.
840
838
 
841
839
  Options:
@@ -901,6 +899,7 @@ Options:
901
899
  --monitor-status-max-attempts <attempts> Sets the maximum number of status check attempts (default: 600).
902
900
  --dry-run Preview operations without executing them.
903
901
  --create-job-now After applying cron manifests, immediately create a Job from each CronJob (forwarded to cron runner).
902
+ --host-aliases <host-aliases> Adds entries to the Pod /etc/hosts via hostAliases. Format: semicolon-separated entries of "ip=hostname1,hostname2" (e.g., "127.0.0.1=foo.local,bar.local;10.1.2.3=foo.remote,bar.remote").
904
903
  -h, --help display help for command
905
904
 
906
905
  ```
package/README.md CHANGED
@@ -16,7 +16,7 @@
16
16
 
17
17
  <div align="center">
18
18
 
19
- [![Node.js CI](https://github.com/underpostnet/engine/actions/workflows/docker-image.ci.yml/badge.svg?branch=master)](https://github.com/underpostnet/engine/actions/workflows/docker-image.yml) [![Test](https://github.com/underpostnet/engine/actions/workflows/coverall.ci.yml/badge.svg?branch=master)](https://github.com/underpostnet/engine/actions/workflows/coverall.ci.yml) [![Downloads](https://img.shields.io/npm/dm/underpost.svg)](https://www.npmjs.com/package/underpost) [![Socket Badge](https://socket.dev/api/badge/npm/package/underpost/3.0.1)](https://socket.dev/npm/package/underpost/overview/3.0.1) [![Coverage Status](https://coveralls.io/repos/github/underpostnet/engine/badge.svg?branch=master)](https://coveralls.io/github/underpostnet/engine?branch=master) [![Version](https://img.shields.io/npm/v/underpost.svg)](https://www.npmjs.org/package/underpost) [![License](https://img.shields.io/npm/l/underpost.svg)](https://www.npmjs.com/package/underpost)
19
+ [![Node.js CI](https://github.com/underpostnet/engine/actions/workflows/docker-image.ci.yml/badge.svg?branch=master)](https://github.com/underpostnet/engine/actions/workflows/docker-image.yml) [![Test](https://github.com/underpostnet/engine/actions/workflows/coverall.ci.yml/badge.svg?branch=master)](https://github.com/underpostnet/engine/actions/workflows/coverall.ci.yml) [![Downloads](https://img.shields.io/npm/dm/underpost.svg)](https://www.npmjs.com/package/underpost) [![Socket Badge](https://socket.dev/api/badge/npm/package/underpost/3.0.3)](https://socket.dev/npm/package/underpost/overview/3.0.3) [![Coverage Status](https://coveralls.io/repos/github/underpostnet/engine/badge.svg?branch=master)](https://coveralls.io/github/underpostnet/engine?branch=master) [![Version](https://img.shields.io/npm/v/underpost.svg)](https://www.npmjs.org/package/underpost) [![License](https://img.shields.io/npm/l/underpost.svg)](https://www.npmjs.com/package/underpost)
20
20
 
21
21
  </div>
22
22
 
@@ -60,7 +60,7 @@ npm run dev
60
60
 
61
61
  <a target="_top" href="https://www.nexodev.org/docs?cid=src">See Docs here.</a>
62
62
 
63
- ## underpost ci/cd cli v3.0.1
63
+ ## underpost ci/cd cli v3.0.3
64
64
 
65
65
  ### Usage: `underpost [options] [command]`
66
66
  ```
package/bin/build.js CHANGED
@@ -172,6 +172,7 @@ const { DefaultConf } = await import(`../conf.${confName}.js`);
172
172
  ...packageJson.dependencies,
173
173
  ...CyberiaDependencies,
174
174
  };
175
+ packageJson.overrides = originPackageJson.overrides;
175
176
  fs.writeFileSync(`${basePath}/bin/index.js`, fs.readFileSync(`./bin/cyberia.js`, 'utf8'), 'utf8');
176
177
  fs.copyFileSync(`./src/api/object-layer/README.md`, `${basePath}/README.md`);
177
178
  fs.copySync(`./hardhat`, `${basePath}/hardhat`);
@@ -180,6 +181,9 @@ const { DefaultConf } = await import(`../conf.${confName}.js`);
180
181
  '/src/client/ssr/pages/CyberiaServerMetrics.js',
181
182
  '/src/server/object-layer.js',
182
183
  '/src/server/atlas-sprite-sheet-generator.js',
184
+ '/src/server/shape-generator.js',
185
+ '/src/server/semantic-layer-generator.js',
186
+ '/test/shape-generator.test.js',
183
187
  ])
184
188
  fs.copySync(`.${path}`, `${basePath}${path}`);
185
189
 
@@ -216,4 +220,5 @@ const { DefaultConf } = await import(`../conf.${confName}.js`);
216
220
  if (fs.existsSync(`./src/ws/${confName.split('-')[1]}`)) {
217
221
  fs.copySync(`./src/ws/${confName.split('-')[1]}`, `${basePath}/src/ws/${confName.split('-')[1]}`);
218
222
  }
223
+ shellExec(`cd ${basePath} && npm install --ignore-scripts`);
219
224
  }
package/bin/deploy.js CHANGED
@@ -374,7 +374,9 @@ try {
374
374
  shellExec(`node bin run kill 4002`);
375
375
  shellExec(`node bin run kill 4003`);
376
376
  shellExec(`npm run update-template`);
377
- shellExec(`cd ../pwa-microservices-template && npm install`);
377
+ shellExec(
378
+ `cd ../pwa-microservices-template && npm install && echo "\nENABLE_FILE_LOGS=true" >> .env.development`,
379
+ );
378
380
  shellExec(`cd ../pwa-microservices-template && npm run build && timeout 5s npm run dev`, {
379
381
  async: true,
380
382
  });
@@ -509,33 +511,23 @@ ${shellExec(`git log | grep Author: | sort -u`, { stdout: true }).split(`\n`).jo
509
511
  // https://besu.hyperledger.org/
510
512
  // https://github.com/hyperledger/besu/archive/refs/tags/24.9.1.tar.gz
511
513
 
512
- switch (process.platform) {
513
- case 'linux':
514
- {
515
- shellCd(`..`);
516
-
517
- // Download the Linux binary
518
- shellExec(`wget https://github.com/hyperledger/besu/releases/download/24.9.1/besu-24.9.1.tar.gz`);
514
+ shellCd(`..`);
519
515
 
520
- // Unzip the file:
521
- shellExec(`tar -xvzf besu-24.9.1.tar.gz`);
516
+ // Download the Linux binary
517
+ shellExec(`wget https://github.com/hyperledger/besu/releases/download/24.9.1/besu-24.9.1.tar.gz`);
522
518
 
523
- shellCd(`besu-24.9.1`);
519
+ // Unzip the file:
520
+ shellExec(`tar -xvzf besu-24.9.1.tar.gz`);
524
521
 
525
- shellExec(`bin/besu --help`);
522
+ shellCd(`besu-24.9.1`);
526
523
 
527
- // Set env path
528
- // export PATH=$PATH:/home/dd/besu-24.9.1/bin
524
+ shellExec(`bin/besu --help`);
529
525
 
530
- // Open src
531
- // shellExec(`sudo code /home/dd/besu-24.9.1 --user-data-dir="/root/.vscode-root" --no-sandbox`);
532
- }
533
-
534
- break;
526
+ // Set env path
527
+ // export PATH=$PATH:/home/dd/besu-24.9.1/bin
535
528
 
536
- default:
537
- break;
538
- }
529
+ // Open src
530
+ // shellExec(`sudo code /home/dd/besu-24.9.1 --user-data-dir="/root/.vscode-root" --no-sandbox`);
539
531
 
540
532
  break;
541
533
  }
@@ -977,10 +969,10 @@ nvidia/gpu-operator \
977
969
  `${key}`.toUpperCase().match('MAC')
978
970
  ? 'changethis'
979
971
  : isNaN(parseFloat(privateEnv[key]))
980
- ? `${privateEnv[key]}`.match(`@`)
981
- ? 'admin@default.net'
982
- : 'changethis'
983
- : privateEnv[key];
972
+ ? `${privateEnv[key]}`.match(`@`)
973
+ ? 'admin@default.net'
974
+ : 'changethis'
975
+ : privateEnv[key];
984
976
  }
985
977
  return env;
986
978
  };
package/bin/file.js CHANGED
@@ -97,6 +97,9 @@ try {
97
97
  './manifests/deployment/dd-template-development',
98
98
  './src/server/object-layer.js',
99
99
  './src/server/atlas-sprite-sheet-generator.js',
100
+ './src/server/shape-generator.js',
101
+ './src/server/semantic-layer-generator.js',
102
+ './test/shape-generator.test.js',
100
103
  'bin/cyberia.js',
101
104
  ]) {
102
105
  if (fs.existsSync(deletePath)) fs.removeSync('../pwa-microservices-template/' + deletePath);
@@ -23,7 +23,7 @@ spec:
23
23
  spec:
24
24
  containers:
25
25
  - name: dd-cron-backup
26
- image: underpost/underpost-engine:v3.0.1
26
+ image: underpost/underpost-engine:v3.0.3
27
27
  command:
28
28
  - /bin/sh
29
29
  - -c
@@ -23,7 +23,7 @@ spec:
23
23
  spec:
24
24
  containers:
25
25
  - name: dd-cron-dns
26
- image: underpost/underpost-engine:v3.0.1
26
+ image: underpost/underpost-engine:v3.0.3
27
27
  command:
28
28
  - /bin/sh
29
29
  - -c
@@ -17,7 +17,7 @@ spec:
17
17
  spec:
18
18
  containers:
19
19
  - name: dd-default-development-blue
20
- image: localhost/rockylinux9-underpost:v3.0.1
20
+ image: localhost/rockylinux9-underpost:v3.0.3
21
21
  # resources:
22
22
  # requests:
23
23
  # memory: "124Ki"
@@ -100,7 +100,7 @@ spec:
100
100
  spec:
101
101
  containers:
102
102
  - name: dd-default-development-green
103
- image: localhost/rockylinux9-underpost:v3.0.1
103
+ image: localhost/rockylinux9-underpost:v3.0.3
104
104
  # resources:
105
105
  # requests:
106
106
  # memory: "124Ki"
@@ -18,7 +18,7 @@ spec:
18
18
  spec:
19
19
  containers:
20
20
  - name: dd-test-development-blue
21
- image: localhost/rockylinux9-underpost:v3.0.1
21
+ image: localhost/rockylinux9-underpost:v3.0.3
22
22
 
23
23
  command:
24
24
  - /bin/sh
@@ -103,7 +103,7 @@ spec:
103
103
  spec:
104
104
  containers:
105
105
  - name: dd-test-development-green
106
- image: localhost/rockylinux9-underpost:v3.0.1
106
+ image: localhost/rockylinux9-underpost:v3.0.3
107
107
 
108
108
  command:
109
109
  - /bin/sh
@@ -16,6 +16,13 @@ data:
16
16
  ipfs-cluster-service init
17
17
  fi
18
18
 
19
+ # Bind cluster APIs to 0.0.0.0 so they are reachable from other pods.
20
+ # By default ipfs-cluster listens on 127.0.0.1 for REST (9094),
21
+ # Proxy (9095) and Pinning Service (9097).
22
+ sed -i 's|/ip4/127\.0\.0\.1/tcp/9094|/ip4/0.0.0.0/tcp/9094|g' /data/ipfs-cluster/service.json
23
+ sed -i 's|/ip4/127\.0\.0\.1/tcp/9095|/ip4/0.0.0.0/tcp/9095|g' /data/ipfs-cluster/service.json
24
+ sed -i 's|/ip4/127\.0\.0\.1/tcp/9097|/ip4/0.0.0.0/tcp/9097|g' /data/ipfs-cluster/service.json
25
+
19
26
  PEER_HOSTNAME=$(cat /proc/sys/kernel/hostname)
20
27
 
21
28
  if echo "${PEER_HOSTNAME}" | grep -q "^ipfs-cluster-0"; then
package/package.json CHANGED
@@ -2,7 +2,7 @@
2
2
  "type": "module",
3
3
  "main": "src/index.js",
4
4
  "name": "@underpostnet/underpost",
5
- "version": "3.0.1",
5
+ "version": "3.0.3",
6
6
  "description": "pwa api rest template",
7
7
  "scripts": {
8
8
  "start": "env-cmd -f .env.production node --max-old-space-size=8192 src/server",
@@ -111,6 +111,10 @@
111
111
  },
112
112
  "overrides": {
113
113
  "minimatch": "^10.2.2",
114
- "glob": "^11.0.0"
114
+ "glob": "^11.0.0",
115
+ "diff": ">=8.0.3",
116
+ "js-yaml": ">=3.14.2",
117
+ "debug": ">=4.3.6",
118
+ "serialize-javascript": ">=7.0.3"
115
119
  }
116
120
  }
@@ -19,22 +19,12 @@ const FileController = {
19
19
  },
20
20
  get: async (req, res, options) => {
21
21
  try {
22
+ res.setHeader('Access-Control-Allow-Origin', '*');
23
+ res.setHeader('Cross-Origin-Resource-Policy', 'cross-origin');
22
24
  const result = await FileService.get(req, res, options);
23
25
  if (result instanceof Buffer) {
24
- if (
25
- process.env.NODE_ENV === 'development' ||
26
- req.hostname === options.host ||
27
- (options.origins && options.origins.find((o) => o.match(req.hostname)))
28
- ) {
29
- res.set('Cross-Origin-Resource-Policy', 'cross-origin');
30
- return res.status(200).end(result);
31
- }
32
- return res.status(403).json({
33
- status: 'error',
34
- message: 'Forbidden',
35
- });
26
+ return res.status(200).end(result);
36
27
  }
37
-
38
28
  return res.status(200).json({
39
29
  status: 'success',
40
30
  data: result,
@@ -5,27 +5,6 @@
5
5
  "logo": true
6
6
  }
7
7
  },
8
- {
9
- "api": "cyberia-biome",
10
- "model": {
11
- "fileId": true,
12
- "topLevelColorFileId": true
13
- }
14
- },
15
- {
16
- "api": "cyberia-tile",
17
- "model": {
18
- "fileId": true
19
- }
20
- },
21
- {
22
- "api": "cyberia-world",
23
- "model": {
24
- "adjacentFace": {
25
- "fileId": true
26
- }
27
- }
28
- },
29
8
  {
30
9
  "api": "document",
31
10
  "model": {
@@ -37,7 +37,6 @@ class UnderpostCluster {
37
37
  * @param {boolean} [options.postgresql=false] - Deploy PostgreSQL.
38
38
  * @param {boolean} [options.valkey=false] - Deploy Valkey.
39
39
  * @param {boolean} [options.ipfs=false] - Deploy ipfs-cluster statefulset.
40
- * @param {boolean} [options.full=false] - Deploy a full set of common components.
41
40
  * @param {boolean} [options.info=false] - Display extensive Kubernetes cluster information.
42
41
  * @param {boolean} [options.certManager=false] - Deploy Cert-Manager for certificate management.
43
42
  * @param {boolean} [options.listPods=false] - List Kubernetes pods.
@@ -75,7 +74,6 @@ class UnderpostCluster {
75
74
  postgresql: false,
76
75
  valkey: false,
77
76
  ipfs: false,
78
- full: false,
79
77
  info: false,
80
78
  certManager: false,
81
79
  listPods: false,
@@ -102,26 +100,22 @@ class UnderpostCluster {
102
100
  replicas: '',
103
101
  },
104
102
  ) {
105
- // Handles initial host setup (installing docker, podman, kind, kubeadm, helm)
106
- if (options.initHost === true) return Underpost.cluster.initHost();
103
+ if (options.initHost) return Underpost.cluster.initHost();
107
104
 
108
- // Handles initial host setup (installing docker, podman, kind, kubeadm, helm)
109
- if (options.uninstallHost === true) return Underpost.cluster.uninstallHost();
105
+ if (options.uninstallHost) return Underpost.cluster.uninstallHost();
110
106
 
111
- // Applies general host configuration (SELinux, containerd, sysctl)
112
- if (options.config === true) return Underpost.cluster.config();
107
+ if (options.config) return Underpost.cluster.config();
113
108
 
114
- // Sets up kubectl configuration for the current user
115
- if (options.chown === true) return Underpost.cluster.chown();
109
+ if (options.chown) return Underpost.cluster.chown();
116
110
 
117
111
  const npmRoot = getNpmRootPath();
118
- const underpostRoot = options?.dev === true ? '.' : `${npmRoot}/underpost`;
112
+ const underpostRoot = options.dev ? '.' : `${npmRoot}/underpost`;
119
113
 
120
- if (options.listPods === true) return console.table(Underpost.deploy.get(podName ?? undefined));
114
+ if (options.listPods) return console.table(Underpost.deploy.get(podName ?? undefined));
121
115
  // Set default namespace if not specified
122
116
  if (!options.namespace) options.namespace = 'default';
123
117
 
124
- if (options.nsUse && typeof options.nsUse === 'string') {
118
+ if (options.nsUse) {
125
119
  // Verify if namespace exists, create if not
126
120
  const namespaceExists = shellExec(`kubectl get namespace ${options.nsUse} --ignore-not-found -o name`, {
127
121
  stdout: true,
@@ -142,8 +136,8 @@ class UnderpostCluster {
142
136
  }
143
137
 
144
138
  // Reset Kubernetes cluster components (Kind/Kubeadm/K3s) and container runtimes
145
- if (options.reset === true) {
146
- const clusterType = options.k3s === true ? 'k3s' : options.kubeadm === true ? 'kubeadm' : 'kind';
139
+ if (options.reset) {
140
+ const clusterType = options.k3s ? 'k3s' : options.kubeadm ? 'kubeadm' : 'kind';
147
141
  return await Underpost.cluster.safeReset({
148
142
  underpostRoot,
149
143
  removeVolumeHostPaths: options.removeVolumeHostPaths,
@@ -160,7 +154,7 @@ class UnderpostCluster {
160
154
  // --- Kubeadm/Kind/K3s Cluster Initialization ---
161
155
  if (!alreadyKubeadmCluster && !alreadyKindCluster && !alreadyK3sCluster) {
162
156
  Underpost.cluster.config();
163
- if (options.k3s === true) {
157
+ if (options.k3s) {
164
158
  logger.info('Initializing K3s control plane...');
165
159
  // Install K3s
166
160
  logger.info('Installing K3s...');
@@ -172,7 +166,7 @@ class UnderpostCluster {
172
166
  logger.info('Waiting for K3s to be ready...');
173
167
  shellExec(`sudo systemctl is-active --wait k3s || sudo systemctl wait --for=active k3s.service`);
174
168
  logger.info('K3s service is active.');
175
- } else if (options.kubeadm === true) {
169
+ } else if (options.kubeadm) {
176
170
  logger.info('Initializing Kubeadm control plane...');
177
171
  // Set default values if not provided
178
172
  const podNetworkCidr = options.podNetworkCidr || '192.168.0.0/16';
@@ -208,7 +202,7 @@ class UnderpostCluster {
208
202
  logger.info('Initializing Kind cluster...');
209
203
  shellExec(
210
204
  `cd ${underpostRoot}/manifests && kind create cluster --config kind-config${
211
- options?.dev === true ? '-dev' : ''
205
+ options.dev ? '-dev' : ''
212
206
  }.yaml`,
213
207
  );
214
208
  Underpost.cluster.chown('kind'); // Pass 'kind' to chown
@@ -218,14 +212,12 @@ class UnderpostCluster {
218
212
  // --- Optional Component Deployments (Databases, Ingress, Cert-Manager) ---
219
213
  // These deployments happen after the base cluster is up.
220
214
 
221
- if (options.full === true || options.dedicatedGpu === true) {
215
+ if (options.dedicatedGpu) {
222
216
  shellExec(`node ${underpostRoot}/bin/deploy nvidia-gpu-operator`);
223
- shellExec(
224
- `node ${underpostRoot}/bin/deploy kubeflow-spark-operator${options.kubeadm === true ? ' kubeadm' : ''}`,
225
- );
217
+ shellExec(`node ${underpostRoot}/bin/deploy kubeflow-spark-operator${options.kubeadm ? ' kubeadm' : ''}`);
226
218
  }
227
219
 
228
- if (options.grafana === true) {
220
+ if (options.grafana) {
229
221
  shellExec(`kubectl delete deployment grafana -n ${options.namespace} --ignore-not-found`);
230
222
  shellExec(`kubectl apply -k ${underpostRoot}/manifests/grafana -n ${options.namespace}`);
231
223
  const yaml = `${fs
@@ -238,7 +230,7 @@ EOF
238
230
  `);
239
231
  }
240
232
 
241
- if (options.prom && typeof options.prom === 'string') {
233
+ if (options.prom) {
242
234
  shellExec(`kubectl delete deployment prometheus --ignore-not-found`);
243
235
  shellExec(`kubectl delete configmap prometheus-config --ignore-not-found`);
244
236
  shellExec(`kubectl delete service prometheus --ignore-not-found`);
@@ -257,8 +249,8 @@ EOF
257
249
  `);
258
250
  }
259
251
 
260
- if (options.full === true || options.valkey === true) {
261
- if (options.pullImage === true) Underpost.cluster.pullImage('valkey/valkey:latest', options);
252
+ if (options.valkey) {
253
+ if (options.pullImage) Underpost.cluster.pullImage('valkey/valkey:latest', options);
262
254
  shellExec(`kubectl delete statefulset valkey-service -n ${options.namespace} --ignore-not-found`);
263
255
  shellExec(`kubectl apply -k ${underpostRoot}/manifests/valkey -n ${options.namespace}`);
264
256
  await Underpost.test.statusMonitor('valkey-service', 'Running', 'pods', 1000, 60 * 10);
@@ -266,17 +258,17 @@ EOF
266
258
  if (options.ipfs) {
267
259
  await Underpost.ipfs.deploy(options, underpostRoot);
268
260
  }
269
- if (options.full === true || options.mariadb === true) {
261
+ if (options.mariadb) {
270
262
  shellExec(
271
263
  `sudo kubectl create secret generic mariadb-secret --from-file=username=/home/dd/engine/engine-private/mariadb-username --from-file=password=/home/dd/engine/engine-private/mariadb-password --dry-run=client -o yaml | kubectl apply -f - -n ${options.namespace}`,
272
264
  );
273
265
  shellExec(`kubectl delete statefulset mariadb-statefulset -n ${options.namespace} --ignore-not-found`);
274
266
 
275
- if (options.pullImage === true) Underpost.cluster.pullImage('mariadb:latest', options);
267
+ if (options.pullImage) Underpost.cluster.pullImage('mariadb:latest', options);
276
268
  shellExec(`kubectl apply -f ${underpostRoot}/manifests/mariadb/storage-class.yaml -n ${options.namespace}`);
277
269
  shellExec(`kubectl apply -k ${underpostRoot}/manifests/mariadb -n ${options.namespace}`);
278
270
  }
279
- if (options.full === true || options.mysql === true) {
271
+ if (options.mysql) {
280
272
  shellExec(
281
273
  `sudo kubectl create secret generic mysql-secret --from-file=username=/home/dd/engine/engine-private/mysql-username --from-file=password=/home/dd/engine/engine-private/mysql-password --dry-run=client -o yaml | kubectl apply -f - -n ${options.namespace}`,
282
274
  );
@@ -285,15 +277,15 @@ EOF
285
277
  shellExec(`sudo chown -R $(whoami):$(whoami) /mnt/data`);
286
278
  shellExec(`kubectl apply -k ${underpostRoot}/manifests/mysql -n ${options.namespace}`);
287
279
  }
288
- if (options.full === true || options.postgresql === true) {
289
- if (options.pullImage === true) Underpost.cluster.pullImage('postgres:latest', options);
280
+ if (options.postgresql) {
281
+ if (options.pullImage) Underpost.cluster.pullImage('postgres:latest', options);
290
282
  shellExec(
291
283
  `sudo kubectl create secret generic postgres-secret --from-file=password=/home/dd/engine/engine-private/postgresql-password --dry-run=client -o yaml | kubectl apply -f - -n ${options.namespace}`,
292
284
  );
293
285
  shellExec(`kubectl apply -k ${underpostRoot}/manifests/postgresql -n ${options.namespace}`);
294
286
  }
295
- if (options.mongodb4 === true) {
296
- if (options.pullImage === true) Underpost.cluster.pullImage('mongo:4.4', options);
287
+ if (options.mongodb4) {
288
+ if (options.pullImage) Underpost.cluster.pullImage('mongo:4.4', options);
297
289
  shellExec(`kubectl apply -k ${underpostRoot}/manifests/mongodb-4.4 -n ${options.namespace}`);
298
290
 
299
291
  const deploymentName = 'mongodb-deployment';
@@ -314,8 +306,8 @@ EOF
314
306
  --eval 'rs.initiate(${JSON.stringify(mongoConfig)})'`,
315
307
  );
316
308
  }
317
- } else if (options.full === true || options.mongodb === true) {
318
- if (options.pullImage === true) Underpost.cluster.pullImage('mongo:latest', options);
309
+ } else if (options.mongodb) {
310
+ if (options.pullImage) Underpost.cluster.pullImage('mongo:latest', options);
319
311
  shellExec(
320
312
  `sudo kubectl create secret generic mongodb-keyfile --from-file=/home/dd/engine/engine-private/mongodb-keyfile --dry-run=client -o yaml | kubectl apply -f - -n ${options.namespace}`,
321
313
  );
@@ -344,11 +336,11 @@ EOF
344
336
  }
345
337
  }
346
338
 
347
- if (options.full === true || options.contour === true) {
339
+ if (options.contour) {
348
340
  shellExec(
349
341
  `kubectl apply -f https://cdn.jsdelivr.net/gh/projectcontour/contour@release-1.33/examples/render/contour.yaml`,
350
342
  );
351
- if (options.kubeadm === true) {
343
+ if (options.kubeadm) {
352
344
  // Envoy service might need NodePort for kubeadm
353
345
  shellExec(
354
346
  `sudo kubectl apply -f ${underpostRoot}/manifests/envoy-service-nodeport.yaml -n ${options.namespace}`,
@@ -358,7 +350,7 @@ EOF
358
350
  // so a specific NodePort service might not be needed or can be configured differently.
359
351
  }
360
352
 
361
- if (options.full === true || options.certManager === true) {
353
+ if (options.certManager) {
362
354
  if (!Underpost.deploy.get('cert-manager').find((p) => p.STATUS === 'Running')) {
363
355
  shellExec(`helm repo add jetstack https://charts.jetstack.io --force-update`);
364
356
  shellExec(
package/src/cli/index.js CHANGED
@@ -218,7 +218,6 @@ program
218
218
  .option('--contour', 'Initializes the cluster with Project Contour base HTTPProxy and Envoy.')
219
219
  .option('--cert-manager', "Initializes the cluster with a Let's Encrypt production ClusterIssuer.")
220
220
  .option('--dedicated-gpu', 'Initializes the cluster with dedicated GPU base resources and environment settings.')
221
- .option('--full', 'Initializes the cluster with all available statefulsets and services.')
222
221
  .option(
223
222
  '--ns-use <ns-name>',
224
223
  "Switches the current Kubernetes context to the specified namespace (creates if it doesn't exist).",
@@ -613,6 +612,12 @@ program
613
612
  '--create-job-now',
614
613
  'After applying cron manifests, immediately create a Job from each CronJob (forwarded to cron runner).',
615
614
  )
615
+ .option(
616
+ '--host-aliases <host-aliases>',
617
+ 'Adds entries to the Pod /etc/hosts via hostAliases. ' +
618
+ 'Format: semicolon-separated entries of "ip=hostname1,hostname2" ' +
619
+ '(e.g., "127.0.0.1=foo.local,bar.local;10.1.2.3=foo.remote,bar.remote").',
620
+ )
616
621
  .description('Runs specified scripts using various runners.')
617
622
  .action(Underpost.run.callback);
618
623
 
package/src/cli/run.js CHANGED
@@ -32,7 +32,6 @@ const logger = loggerFactory(import.meta);
32
32
  * @property {string} podName - The name of the pod to run.
33
33
  * @property {string} nodeName - The name of the node to run.
34
34
  * @property {number} port - Custom port to use.
35
- * @property {boolean} etcHosts - Whether to modify /etc/hosts.
36
35
  * @property {string} volumeHostPath - The host path for the volume.
37
36
  * @property {string} volumeMountPath - The mount path for the volume.
38
37
  * @property {string} imageName - The name of the image to run.
@@ -85,9 +84,12 @@ const logger = loggerFactory(import.meta);
85
84
  * @property {string} monitorStatusKindType - The monitor status kind type option.
86
85
  * @property {string} monitorStatusDeltaMs - The monitor status delta in milliseconds.
87
86
  * @property {string} monitorStatusMaxAttempts - The maximum number of attempts for monitor status.
87
+ * @property {boolean} logs - Whether to enable logs.
88
88
  * @property {boolean} dryRun - Whether to perform a dry run.
89
89
  * @property {boolean} createJobNow - Whether to create the job immediately.
90
- * @property {boolean} logs - Whether to enable logs.
90
+ * @property {string|Array<{ip: string, hostnames: string[]}>} hostAliases - Adds entries to the Pod /etc/hosts via Kubernetes hostAliases.
91
+ * As a string (CLI): semicolon-separated entries of "ip=hostname1,hostname2" (e.g., "127.0.0.1=foo.local,bar.local;10.1.2.3=foo.remote").
92
+ * As an array (programmatic): objects with `ip` and `hostnames` fields (e.g., [{ ip: "127.0.0.1", hostnames: ["foo.local"] }]).
91
93
  * @memberof UnderpostRun
92
94
  */
93
95
  const DEFAULT_OPTION = {
@@ -150,6 +152,7 @@ const DEFAULT_OPTION = {
150
152
  logs: false,
151
153
  dryRun: false,
152
154
  createJobNow: false,
155
+ hostAliases: '',
153
156
  };
154
157
 
155
158
  /**
@@ -217,6 +220,20 @@ class UnderpostRun {
217
220
  }
218
221
  },
219
222
 
223
+ /**
224
+ * @method ipfs-expose
225
+ * @description Exposes IPFS Cluster services on specified ports for local access.
226
+ * @type {Function}
227
+ * @memberof UnderpostRun
228
+ */
229
+ 'ipfs-expose': (path, options = DEFAULT_OPTION) => {
230
+ const ports = [5001, 9094, 8080];
231
+ for (const port of ports)
232
+ shellExec(`node bin deploy --expose ipfs-cluster --expose-port ${port} --disable-update-underpost-config`, {
233
+ async: true,
234
+ });
235
+ },
236
+
220
237
  /**
221
238
  * @method metadata
222
239
  * @description Generates metadata for the specified path after exposing the development cluster.
@@ -1826,6 +1843,30 @@ EOF
1826
1843
  const imagePullPolicy = options.imagePullPolicy || 'IfNotPresent';
1827
1844
  const hostNetwork = options.hostNetwork ? options.hostNetwork : '';
1828
1845
  const apiVersion = options.apiVersion || 'v1';
1846
+ // Parse hostAliases option:
1847
+ // - string from CLI: "ip1=host1,host2;ip2=host3,host4"
1848
+ // - array from programmatic callers: [{ ip: "127.0.0.1", hostnames: ["foo.local"] }]
1849
+ const hostAliases = options.hostAliases
1850
+ ? Array.isArray(options.hostAliases)
1851
+ ? options.hostAliases
1852
+ : options.hostAliases
1853
+ .split(';')
1854
+ .filter((entry) => entry.trim())
1855
+ .map((entry) => {
1856
+ const [ip, hostnamesStr] = entry.split('=');
1857
+ const hostnames = hostnamesStr ? hostnamesStr.split(',').map((h) => h.trim()) : [];
1858
+ return { ip: ip.trim(), hostnames };
1859
+ })
1860
+ : [];
1861
+ const hostAliasesYaml =
1862
+ hostAliases.length > 0
1863
+ ? ` hostAliases:\n${hostAliases
1864
+ .map(
1865
+ (alias) =>
1866
+ ` - ip: "${alias.ip}"\n hostnames:\n${alias.hostnames.map((h) => ` - "${h}"`).join('\n')}`,
1867
+ )
1868
+ .join('\n')}`
1869
+ : '';
1829
1870
  const labels = options.labels
1830
1871
  ? options.labels
1831
1872
  .split(',')
@@ -1856,6 +1897,7 @@ spec:
1856
1897
  restartPolicy: ${restartPolicy}
1857
1898
  ${runtimeClassName ? ` runtimeClassName: ${runtimeClassName}` : ''}
1858
1899
  ${hostNetwork ? ` hostNetwork: ${hostNetwork}` : ''}
1900
+ ${hostAliasesYaml}
1859
1901
  containers:
1860
1902
  - name: ${containerName}
1861
1903
  image: ${imageName}
@@ -27,8 +27,8 @@ const LoadingAnimation = {
27
27
  ? subThemeManager.darkColor
28
28
  : `#66e400`
29
29
  : subThemeManager.lightColor
30
- ? subThemeManager.lightColor
31
- : `#157e00`};"
30
+ ? subThemeManager.lightColor
31
+ : `#157e00`};"
32
32
  ></div>
33
33
  `,
34
34
  );
@@ -131,7 +131,6 @@ const LoadingAnimation = {
131
131
  if (!backgroundContainer) backgroundContainer = '.ssr-background';
132
132
  if (s(backgroundContainer)) {
133
133
  s(backgroundContainer).style.display = 'none';
134
- if (s(`.main-body-btn-container`)) s(`.main-body-btn-container`).classList.remove('hide');
135
134
  if (callBack) callBack();
136
135
  }
137
136
  },