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/CHANGELOG.md +352 -264
- package/CLI-HELP.md +3 -4
- package/README.md +2 -2
- package/bin/build.js +5 -0
- package/bin/deploy.js +18 -26
- package/bin/file.js +3 -0
- package/manifests/cronjobs/dd-cron/dd-cron-backup.yaml +1 -1
- package/manifests/cronjobs/dd-cron/dd-cron-dns.yaml +1 -1
- package/manifests/deployment/dd-default-development/deployment.yaml +2 -2
- package/manifests/deployment/dd-test-development/deployment.yaml +2 -2
- package/manifests/ipfs/configmap.yaml +7 -0
- package/package.json +6 -2
- package/src/api/file/file.controller.js +3 -13
- package/src/api/file/file.ref.json +0 -21
- package/src/cli/cluster.js +30 -38
- package/src/cli/index.js +6 -1
- package/src/cli/run.js +44 -2
- package/src/client/components/core/LoadingAnimation.js +2 -3
- package/src/client/components/core/Modal.js +3 -1
- package/src/client/components/core/PublicProfile.js +3 -3
- package/src/client/components/core/Router.js +34 -1
- package/src/client/components/core/Worker.js +1 -1
- package/src/index.js +1 -1
- package/src/runtime/express/Express.js +1 -1
- package/src/server/auth.js +18 -18
- package/src/server/ipfs-client.js +433 -0
- package/bin/ssl.js +0 -63
package/CLI-HELP.md
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
## underpost ci/cd cli v3.0.
|
|
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
|
-
[](https://github.com/underpostnet/engine/actions/workflows/docker-image.yml) [](https://github.com/underpostnet/engine/actions/workflows/coverall.ci.yml) [](https://www.npmjs.com/package/underpost) [](https://github.com/underpostnet/engine/actions/workflows/docker-image.yml) [](https://github.com/underpostnet/engine/actions/workflows/coverall.ci.yml) [](https://www.npmjs.com/package/underpost) [](https://socket.dev/npm/package/underpost/overview/3.0.3) [](https://coveralls.io/github/underpostnet/engine?branch=master) [](https://www.npmjs.org/package/underpost) [](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.
|
|
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(
|
|
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
|
-
|
|
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
|
-
|
|
521
|
-
|
|
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
|
-
|
|
519
|
+
// Unzip the file:
|
|
520
|
+
shellExec(`tar -xvzf besu-24.9.1.tar.gz`);
|
|
524
521
|
|
|
525
|
-
|
|
522
|
+
shellCd(`besu-24.9.1`);
|
|
526
523
|
|
|
527
|
-
|
|
528
|
-
// export PATH=$PATH:/home/dd/besu-24.9.1/bin
|
|
524
|
+
shellExec(`bin/besu --help`);
|
|
529
525
|
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
}
|
|
533
|
-
|
|
534
|
-
break;
|
|
526
|
+
// Set env path
|
|
527
|
+
// export PATH=$PATH:/home/dd/besu-24.9.1/bin
|
|
535
528
|
|
|
536
|
-
|
|
537
|
-
|
|
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
|
-
|
|
981
|
-
|
|
982
|
-
|
|
983
|
-
|
|
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);
|
|
@@ -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.
|
|
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.
|
|
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.
|
|
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.
|
|
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": "underpost",
|
|
5
|
-
"version": "3.0.
|
|
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
|
-
|
|
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": {
|
package/src/cli/cluster.js
CHANGED
|
@@ -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
|
-
|
|
106
|
-
if (options.initHost === true) return Underpost.cluster.initHost();
|
|
103
|
+
if (options.initHost) return Underpost.cluster.initHost();
|
|
107
104
|
|
|
108
|
-
|
|
109
|
-
if (options.uninstallHost === true) return Underpost.cluster.uninstallHost();
|
|
105
|
+
if (options.uninstallHost) return Underpost.cluster.uninstallHost();
|
|
110
106
|
|
|
111
|
-
|
|
112
|
-
if (options.config === true) return Underpost.cluster.config();
|
|
107
|
+
if (options.config) return Underpost.cluster.config();
|
|
113
108
|
|
|
114
|
-
|
|
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
|
|
112
|
+
const underpostRoot = options.dev ? '.' : `${npmRoot}/underpost`;
|
|
119
113
|
|
|
120
|
-
if (options.listPods
|
|
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
|
|
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
|
|
146
|
-
const clusterType = options.k3s
|
|
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
|
|
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
|
|
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
|
|
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.
|
|
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
|
|
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
|
|
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.
|
|
261
|
-
if (options.pullImage
|
|
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.
|
|
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
|
|
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.
|
|
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.
|
|
289
|
-
if (options.pullImage
|
|
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
|
|
296
|
-
if (options.pullImage
|
|
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.
|
|
318
|
-
if (options.pullImage
|
|
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.
|
|
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
|
|
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.
|
|
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 {
|
|
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
|
-
|
|
31
|
-
|
|
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
|
},
|