@underpostnet/underpost 2.96.0 → 2.97.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/.dockerignore +1 -2
- package/.env.development +0 -3
- package/.env.production +0 -3
- package/.env.test +0 -3
- package/.prettierignore +1 -2
- package/README.md +31 -31
- package/baremetal/commission-workflows.json +64 -17
- package/baremetal/packer-workflows.json +11 -0
- package/cli.md +72 -40
- package/manifests/deployment/dd-default-development/deployment.yaml +2 -2
- package/manifests/deployment/dd-test-development/deployment.yaml +4 -4
- package/package.json +3 -2
- package/packer/images/Rocky9Amd64/rocky9.pkr.hcl +6 -2
- package/packer/images/Rocky9Arm64/Makefile +69 -0
- package/packer/images/Rocky9Arm64/README.md +122 -0
- package/packer/images/Rocky9Arm64/http/rocky9.ks.pkrtpl.hcl +114 -0
- package/packer/images/Rocky9Arm64/rocky9.pkr.hcl +171 -0
- package/scripts/disk-clean.sh +128 -187
- package/scripts/ipxe-setup.sh +197 -0
- package/scripts/packer-init-vars-file.sh +16 -6
- package/scripts/packer-setup.sh +270 -33
- package/scripts/ports-ls.sh +31 -0
- package/scripts/quick-tftp.sh +19 -0
- package/src/api/document/document.controller.js +15 -0
- package/src/api/document/document.model.js +14 -0
- package/src/api/document/document.router.js +1 -0
- package/src/api/document/document.service.js +61 -3
- package/src/cli/baremetal.js +1716 -439
- package/src/cli/cloud-init.js +354 -231
- package/src/cli/cluster.js +1 -1
- package/src/cli/db.js +22 -0
- package/src/cli/deploy.js +6 -2
- package/src/cli/image.js +1 -0
- package/src/cli/index.js +40 -36
- package/src/cli/run.js +77 -11
- package/src/cli/ssh.js +1 -1
- package/src/client/components/core/Input.js +3 -1
- package/src/client/components/core/Panel.js +161 -15
- package/src/client/components/core/PanelForm.js +198 -35
- package/src/client/components/core/Translate.js +11 -0
- package/src/client/services/document/document.service.js +19 -0
- package/src/index.js +2 -1
- package/src/server/dns.js +8 -2
- package/src/server/start.js +14 -6
- package/manifests/mariadb/config.yaml +0 -10
- package/manifests/mariadb/secret.yaml +0 -8
package/src/cli/db.js
CHANGED
|
@@ -725,8 +725,14 @@ class UnderpostDB {
|
|
|
725
725
|
* @param {string} [options.paths=''] - Comma-separated list of paths to filter databases
|
|
726
726
|
* @param {boolean} [options.allPods=false] - Whether to target all pods in deployment
|
|
727
727
|
* @param {boolean} [options.primaryPod=false] - Whether to target MongoDB primary pod only
|
|
728
|
+
* @param {string} [options.primaryPodEnsure=''] - Pod name to ensure MongoDB primary pod is running
|
|
728
729
|
* @param {boolean} [options.stats=false] - Whether to display database statistics
|
|
729
730
|
* @param {number} [options.macroRollbackExport=1] - Number of commits to rollback in macro export
|
|
731
|
+
* @param {boolean} [options.forceClone=false] - Whether to force re-clone Git repository
|
|
732
|
+
* @param {boolean} [options.dev=false] - Development mode flag
|
|
733
|
+
* @param {boolean} [options.k3s=false] - k3s cluster flag
|
|
734
|
+
* @param {boolean} [options.kubeadm=false] - kubeadm cluster flag
|
|
735
|
+
* @param {boolean} [options.kind=false] - kind cluster flag
|
|
730
736
|
* @returns {Promise<void>} Resolves when operation is complete
|
|
731
737
|
* @memberof UnderpostDB
|
|
732
738
|
*/
|
|
@@ -746,9 +752,14 @@ class UnderpostDB {
|
|
|
746
752
|
paths: '',
|
|
747
753
|
allPods: false,
|
|
748
754
|
primaryPod: false,
|
|
755
|
+
primaryPodEnsure: '',
|
|
749
756
|
stats: false,
|
|
750
757
|
macroRollbackExport: 1,
|
|
751
758
|
forceClone: false,
|
|
759
|
+
dev: false,
|
|
760
|
+
k3s: false,
|
|
761
|
+
kubeadm: false,
|
|
762
|
+
kind: false,
|
|
752
763
|
},
|
|
753
764
|
) {
|
|
754
765
|
const newBackupTimestamp = new Date().getTime();
|
|
@@ -763,6 +774,17 @@ class UnderpostDB {
|
|
|
763
774
|
export: options.export,
|
|
764
775
|
});
|
|
765
776
|
|
|
777
|
+
if (options.primaryPodEnsure) {
|
|
778
|
+
const primaryPodName = UnderpostDB.API.getMongoPrimaryPodName({ namespace, podName: options.primaryPodEnsure });
|
|
779
|
+
if (!primaryPodName) {
|
|
780
|
+
const baseCommand = options.dev ? 'node bin' : 'underpost';
|
|
781
|
+
const baseClusterCommand = options.dev ? ' --dev' : '';
|
|
782
|
+
let clusterFlag = options.k3s ? ' --k3s' : options.kubeadm ? ' --kubeadm' : '';
|
|
783
|
+
shellExec(`${baseCommand} cluster${baseClusterCommand}${clusterFlag} --mongodb`);
|
|
784
|
+
}
|
|
785
|
+
return;
|
|
786
|
+
}
|
|
787
|
+
|
|
766
788
|
// Track processed repositories to avoid duplicate Git operations
|
|
767
789
|
const processedRepos = new Set();
|
|
768
790
|
// Track processed host+path combinations to avoid duplicates
|
package/src/cli/deploy.js
CHANGED
|
@@ -106,12 +106,13 @@ class UnderpostDeploy {
|
|
|
106
106
|
* @memberof UnderpostDeploy
|
|
107
107
|
*/
|
|
108
108
|
deploymentYamlPartsFactory({ deployId, env, suffix, resources, replicas, image, namespace, volumes, cmd }) {
|
|
109
|
+
const baseCommand = env === 'development' ? 'node bin' : 'underpost';
|
|
109
110
|
if (!cmd)
|
|
110
111
|
cmd = [
|
|
111
112
|
`npm install -g npm@11.2.0`,
|
|
112
113
|
`npm install -g underpost`,
|
|
113
|
-
|
|
114
|
-
|
|
114
|
+
`${baseCommand} secret underpost --create-from-file /etc/config/.env.${env}`,
|
|
115
|
+
`${baseCommand} start --build --run ${deployId} ${env}`,
|
|
115
116
|
];
|
|
116
117
|
const packageJson = JSON.parse(fs.readFileSync('./package.json', 'utf8'));
|
|
117
118
|
if (!volumes)
|
|
@@ -221,6 +222,7 @@ ${UnderpostDeploy.API.deploymentYamlPartsFactory({
|
|
|
221
222
|
replicas,
|
|
222
223
|
image,
|
|
223
224
|
namespace: options.namespace,
|
|
225
|
+
cmd: options.cmd ? options.cmd.split(',').map((c) => c.trim()) : undefined,
|
|
224
226
|
}).replace('{{ports}}', buildKindPorts(fromPort, toPort))}
|
|
225
227
|
`;
|
|
226
228
|
}
|
|
@@ -389,6 +391,7 @@ spec:
|
|
|
389
391
|
* @param {string} [options.namespace] - Kubernetes namespace for the deployment.
|
|
390
392
|
* @param {string} [options.kindType] - Type of Kubernetes resource to retrieve information for.
|
|
391
393
|
* @param {number} [options.port] - Port number for exposing the deployment.
|
|
394
|
+
* @param {string} [options.cmd] - Custom initialization command for deploymentYamlPartsFactory (comma-separated commands).
|
|
392
395
|
* @returns {Promise<void>} - Promise that resolves when the deployment process is complete.
|
|
393
396
|
* @memberof UnderpostDeploy
|
|
394
397
|
*/
|
|
@@ -420,6 +423,7 @@ spec:
|
|
|
420
423
|
namespace: '',
|
|
421
424
|
kindType: '',
|
|
422
425
|
port: 0,
|
|
426
|
+
cmd: '',
|
|
423
427
|
},
|
|
424
428
|
) {
|
|
425
429
|
const namespace = options.namespace ? options.namespace : 'default';
|
package/src/cli/image.js
CHANGED
|
@@ -119,6 +119,7 @@ class UnderpostImage {
|
|
|
119
119
|
} = options;
|
|
120
120
|
if (!path) path = '.';
|
|
121
121
|
if (!imageName) imageName = `rockylinux9-underpost:${Underpost.version}`;
|
|
122
|
+
if (!imagePath) imagePath = '.';
|
|
122
123
|
if (!version) version = 'latest';
|
|
123
124
|
version = imageName && imageName.match(':') ? '' : `:${version}`;
|
|
124
125
|
const podManImg = `localhost/${imageName}${version}`;
|
package/src/cli/index.js
CHANGED
|
@@ -10,7 +10,6 @@ import UnderpostRun from './run.js';
|
|
|
10
10
|
import Dns from '../server/dns.js';
|
|
11
11
|
import UnderpostStatic from './static.js';
|
|
12
12
|
|
|
13
|
-
// Load environment variables from .env file
|
|
14
13
|
const underpostRootPath = getUnderpostRootPath();
|
|
15
14
|
fs.existsSync(`${underpostRootPath}/.env`)
|
|
16
15
|
? dotenv.config({ path: `${underpostRootPath}/.env`, override: true })
|
|
@@ -18,10 +17,8 @@ fs.existsSync(`${underpostRootPath}/.env`)
|
|
|
18
17
|
|
|
19
18
|
const program = new Command();
|
|
20
19
|
|
|
21
|
-
// Set up the main program information
|
|
22
20
|
program.name('underpost').description(`underpost ci/cd cli ${Underpost.version}`).version(Underpost.version);
|
|
23
21
|
|
|
24
|
-
// 'new' command: Create a new project
|
|
25
22
|
program
|
|
26
23
|
.command('new')
|
|
27
24
|
.argument('[app-name]', 'The name of the new project.')
|
|
@@ -39,7 +36,6 @@ program
|
|
|
39
36
|
.description('Initializes a new Underpost project, service, or configuration.')
|
|
40
37
|
.action(Underpost.repo.new);
|
|
41
38
|
|
|
42
|
-
// 'start' command: Start application servers, build pipelines, or services
|
|
43
39
|
program
|
|
44
40
|
.command('start')
|
|
45
41
|
.argument('<deploy-id>', 'The unique identifier for the deployment configuration.')
|
|
@@ -49,10 +45,10 @@ program
|
|
|
49
45
|
)
|
|
50
46
|
.option('--run', 'Starts application servers and monitors their health.')
|
|
51
47
|
.option('--build', 'Triggers the client-side application build process.')
|
|
48
|
+
.option('--underpost-quickly-install', 'Uses Underpost Quickly Install for dependency installation.')
|
|
52
49
|
.action(Underpost.start.callback)
|
|
53
50
|
.description('Initiates application servers, build pipelines, or other defined services based on the deployment ID.');
|
|
54
51
|
|
|
55
|
-
// 'clone' command: Clone a GitHub repository
|
|
56
52
|
program
|
|
57
53
|
.command('clone')
|
|
58
54
|
.argument(`<uri>`, 'The URI of the GitHub repository (e.g., "username/repository").')
|
|
@@ -61,7 +57,6 @@ program
|
|
|
61
57
|
.description('Clones a specified GitHub repository into the current directory.')
|
|
62
58
|
.action(Underpost.repo.clone);
|
|
63
59
|
|
|
64
|
-
// 'pull' command: Pull updates from a GitHub repository
|
|
65
60
|
program
|
|
66
61
|
.command('pull')
|
|
67
62
|
.argument('<path>', 'The absolute or relative directory path where the repository is located.')
|
|
@@ -70,7 +65,6 @@ program
|
|
|
70
65
|
.option('-g8', 'Uses the g8 repository extension for pulling.')
|
|
71
66
|
.action(Underpost.repo.pull);
|
|
72
67
|
|
|
73
|
-
// 'cmt' command: Commit changes to a GitHub repository
|
|
74
68
|
program
|
|
75
69
|
.command('cmt')
|
|
76
70
|
.argument('[path]', 'The absolute or relative directory path of the repository.')
|
|
@@ -92,7 +86,6 @@ program
|
|
|
92
86
|
.description('Manages commits to a GitHub repository, supporting various commit types and options.')
|
|
93
87
|
.action(Underpost.repo.commit);
|
|
94
88
|
|
|
95
|
-
// 'push' command: Push changes to a GitHub repository
|
|
96
89
|
program
|
|
97
90
|
.command('push')
|
|
98
91
|
.argument('<path>', 'The absolute or relative directory path of the repository.')
|
|
@@ -102,7 +95,6 @@ program
|
|
|
102
95
|
.description('Pushes committed changes from a local repository to a remote GitHub repository.')
|
|
103
96
|
.action(Underpost.repo.push);
|
|
104
97
|
|
|
105
|
-
// 'env' command: Manage environment variables
|
|
106
98
|
program
|
|
107
99
|
.command('env')
|
|
108
100
|
.argument(
|
|
@@ -122,7 +114,6 @@ program
|
|
|
122
114
|
loadConf(deployId, subConf);
|
|
123
115
|
});
|
|
124
116
|
|
|
125
|
-
// 'static' command: Manage static configurations
|
|
126
117
|
program
|
|
127
118
|
.command('static')
|
|
128
119
|
.option('--page <ssr-component-path>', 'Build custom static pages.')
|
|
@@ -139,21 +130,17 @@ program
|
|
|
139
130
|
.option('--locale <locale>', 'Page locale (default: en-US).')
|
|
140
131
|
.option('--site-name <name>', 'Site name for Open Graph.')
|
|
141
132
|
|
|
142
|
-
// Script and style options
|
|
143
133
|
.option('--head-scripts <paths>', 'Comma-separated paths to scripts for head section.')
|
|
144
134
|
.option('--body-scripts <paths>', 'Comma-separated paths to scripts for body section.')
|
|
145
135
|
.option('--styles <paths>', 'Comma-separated paths to stylesheets.')
|
|
146
136
|
|
|
147
|
-
// Icon options
|
|
148
137
|
.option('--favicon <path>', 'Favicon path.')
|
|
149
138
|
.option('--apple-touch-icon <path>', 'Apple touch icon path.')
|
|
150
139
|
.option('--manifest <path>', 'Web manifest path.')
|
|
151
140
|
|
|
152
|
-
// Component options
|
|
153
141
|
.option('--head-components <paths>', 'Comma-separated SSR head component paths.')
|
|
154
142
|
.option('--body-components <paths>', 'Comma-separated SSR body component paths.')
|
|
155
143
|
|
|
156
|
-
// Build options
|
|
157
144
|
.option('--deploy-id <deploy-id>', 'Build static assets for a specific deployment ID.')
|
|
158
145
|
.option('--build', 'Triggers the static build process for the specified deployment ID.')
|
|
159
146
|
.option('--build-host <build-host>', 'Sets a custom build host for static documents or assets.')
|
|
@@ -162,11 +149,9 @@ program
|
|
|
162
149
|
.option('--minify', 'Minify HTML output (default: true for production).')
|
|
163
150
|
.option('--no-minify', 'Disable HTML minification.')
|
|
164
151
|
|
|
165
|
-
// Config file options
|
|
166
152
|
.option('--config-file <path>', 'Path to JSON configuration file.')
|
|
167
153
|
.option('--generate-config [path]', 'Generate a template configuration file.')
|
|
168
154
|
|
|
169
|
-
// Other options
|
|
170
155
|
.option('--lang <lang>', 'HTML lang attribute (default: en).')
|
|
171
156
|
.option('--dir <dir>', 'HTML dir attribute (default: ltr).')
|
|
172
157
|
.option('--dev', 'Sets the development cli context')
|
|
@@ -174,7 +159,6 @@ program
|
|
|
174
159
|
.description(`Manages static build of page, bundles, and documentation with comprehensive customization options.`)
|
|
175
160
|
.action(UnderpostStatic.API.callback);
|
|
176
161
|
|
|
177
|
-
// 'config' command: Manage Underpost configurations
|
|
178
162
|
program
|
|
179
163
|
.command('config')
|
|
180
164
|
.argument('operator', `The configuration operation to perform. Options: ${Object.keys(Underpost.env).join(', ')}.`)
|
|
@@ -185,7 +169,6 @@ program
|
|
|
185
169
|
.description(`Manages Underpost configurations using various operators.`)
|
|
186
170
|
.action((...args) => Underpost.env[args[0]](args[1], args[2], args[3]));
|
|
187
171
|
|
|
188
|
-
// 'root' command: Get npm root path
|
|
189
172
|
program
|
|
190
173
|
.command('root')
|
|
191
174
|
.description('Displays the root path of the npm installation.')
|
|
@@ -194,6 +177,7 @@ program
|
|
|
194
177
|
program
|
|
195
178
|
.command('ip')
|
|
196
179
|
.argument('[ips]', 'Optional args comma-separated list of IP to process.')
|
|
180
|
+
.option('--dhcp', 'Fetches and displays the current Dynamic Host Configuration Protocol server IP address.')
|
|
197
181
|
.option('--copy', 'Copies the IP addresses to the clipboard.')
|
|
198
182
|
.option('--ban-ingress-add', 'Adds IP addresses to banned ingress list.')
|
|
199
183
|
.option('--ban-ingress-remove', 'Removes IP addresses from banned ingress list.')
|
|
@@ -208,7 +192,6 @@ program
|
|
|
208
192
|
.description('Displays the current public machine IP addresses.')
|
|
209
193
|
.action(Dns.ipDispatcher);
|
|
210
194
|
|
|
211
|
-
// 'cluster' command: Manage Kubernetes clusters
|
|
212
195
|
program
|
|
213
196
|
.command('cluster')
|
|
214
197
|
.argument('[pod-name]', 'Optional: Filters information by a specific pod name.')
|
|
@@ -257,7 +240,6 @@ program
|
|
|
257
240
|
.action(Underpost.cluster.init)
|
|
258
241
|
.description('Manages Kubernetes clusters, defaulting to Kind cluster initialization.');
|
|
259
242
|
|
|
260
|
-
// 'deploy' command: Manage deployments
|
|
261
243
|
program
|
|
262
244
|
.command('deploy')
|
|
263
245
|
.argument('[deploy-list]', 'A comma-separated list of deployment IDs (e.g., "default-a,default-b").')
|
|
@@ -295,10 +277,10 @@ program
|
|
|
295
277
|
.option('--namespace <namespace>', 'Kubernetes namespace for deployment operations (defaults to "default").')
|
|
296
278
|
.option('--kind-type <kind-type>', 'Specifies the Kind cluster type for deployment operations.')
|
|
297
279
|
.option('--port <port>', 'Sets up port forwarding from local to remote ports.')
|
|
280
|
+
.option('--cmd <cmd>', 'Custom initialization command for deployment (comma-separated commands).')
|
|
298
281
|
.description('Manages application deployments, defaulting to deploying development pods.')
|
|
299
282
|
.action(Underpost.deploy.callback);
|
|
300
283
|
|
|
301
|
-
// 'secret' command: Manage secrets
|
|
302
284
|
program
|
|
303
285
|
.command('secret')
|
|
304
286
|
.argument('<platform>', `The secret management platform. Options: ${Object.keys(Underpost.secret).join(', ')}.`)
|
|
@@ -312,7 +294,6 @@ program
|
|
|
312
294
|
if (args[1].init) return Underpost.secret[args[0]].init();
|
|
313
295
|
});
|
|
314
296
|
|
|
315
|
-
// 'image'
|
|
316
297
|
program
|
|
317
298
|
.command('image')
|
|
318
299
|
.option(
|
|
@@ -348,7 +329,6 @@ program
|
|
|
348
329
|
Underpost.image.pullDockerHubImage({ ...options, dockerhubImage: options.pullDockerhub });
|
|
349
330
|
});
|
|
350
331
|
|
|
351
|
-
// 'install' command: Fast import npm dependencies
|
|
352
332
|
program
|
|
353
333
|
.command('install')
|
|
354
334
|
.description('Quickly imports Underpost npm dependencies by copying them.')
|
|
@@ -356,10 +336,9 @@ program
|
|
|
356
336
|
fs.copySync(`${underpostRootPath}/node_modules`, './node_modules');
|
|
357
337
|
});
|
|
358
338
|
|
|
359
|
-
// 'db' command: Manage databases
|
|
360
339
|
program
|
|
361
340
|
.command('db')
|
|
362
|
-
.argument('
|
|
341
|
+
.argument('[deploy-list]', 'A comma-separated list of deployment IDs (e.g., "default-a,default-b").')
|
|
363
342
|
.option('--import', 'Imports container backups from specified repositories.')
|
|
364
343
|
.option('--export', 'Exports container backups to specified repositories.')
|
|
365
344
|
.option(
|
|
@@ -368,6 +347,7 @@ program
|
|
|
368
347
|
)
|
|
369
348
|
.option('--all-pods', 'Target all matching pods instead of just the first one.')
|
|
370
349
|
.option('--primary-pod', 'Automatically detect and use MongoDB primary pod (MongoDB only).')
|
|
350
|
+
.option('--primary-pod-ensure <pod-name>', 'Ensure setup of MongoDB replica set primary pod before operations.')
|
|
371
351
|
.option('--stats', 'Display database statistics (collection/table names with document/row counts).')
|
|
372
352
|
.option('--collections <collections>', 'Comma-separated list of database collections to operate on.')
|
|
373
353
|
.option('--out-path <out-path>', 'Specifies a custom output path for backups.')
|
|
@@ -382,6 +362,10 @@ program
|
|
|
382
362
|
'--macro-rollback-export <n-commits-reset>',
|
|
383
363
|
'Exports a macro rollback script that reverts the last n commits (Git integration required).',
|
|
384
364
|
)
|
|
365
|
+
.option('--dev', 'Sets the development cli context')
|
|
366
|
+
.option('--kubeadm', 'Enables the kubeadm context for database operations.')
|
|
367
|
+
.option('--kind', 'Enables the kind context for database operations.')
|
|
368
|
+
.option('--k3s', 'Enables the k3s context for database operations.')
|
|
385
369
|
.description(
|
|
386
370
|
'Manages database operations with support for MariaDB and MongoDB, including import/export, multi-pod targeting, and Git integration.',
|
|
387
371
|
)
|
|
@@ -401,7 +385,6 @@ program
|
|
|
401
385
|
.description('Manages cluster metadata operations, including import and export.')
|
|
402
386
|
.action(Underpost.db.clusterMetadataBackupCallback);
|
|
403
387
|
|
|
404
|
-
// 'script' command: Execute scripts
|
|
405
388
|
program
|
|
406
389
|
.command('script')
|
|
407
390
|
.argument('operator', `The script operation to perform. Options: ${Object.keys(Underpost.script).join(', ')}.`)
|
|
@@ -416,7 +399,6 @@ program
|
|
|
416
399
|
)
|
|
417
400
|
.action((...args) => Underpost.script[args[0]](args[1], args[2], args[3]));
|
|
418
401
|
|
|
419
|
-
// 'cron' command: Manage cron jobs
|
|
420
402
|
program
|
|
421
403
|
.command('cron')
|
|
422
404
|
.argument('[deploy-list]', 'A comma-separated list of deployment IDs (e.g., "default-a,default-b").')
|
|
@@ -432,7 +414,6 @@ program
|
|
|
432
414
|
.description('Manages cron jobs, including initialization, execution, and configuration updates.')
|
|
433
415
|
.action(Underpost.cron.callback);
|
|
434
416
|
|
|
435
|
-
// 'fs' command: File storage management
|
|
436
417
|
program
|
|
437
418
|
.command('fs')
|
|
438
419
|
.argument('[path]', 'The absolute or relative directory path for file operations.')
|
|
@@ -446,7 +427,6 @@ program
|
|
|
446
427
|
.description('Manages file storage, defaulting to file upload operations.')
|
|
447
428
|
.action(Underpost.fs.callback);
|
|
448
429
|
|
|
449
|
-
// 'test' command: Manage tests
|
|
450
430
|
program
|
|
451
431
|
.command('test')
|
|
452
432
|
.argument('[deploy-list]', 'A comma-separated list of deployment IDs (e.g., "default-a,default-b").')
|
|
@@ -459,7 +439,6 @@ program
|
|
|
459
439
|
.option('--kind-type <kind-type>', 'Optional: Specifies the Kind cluster type for tests.')
|
|
460
440
|
.action(Underpost.test.callback);
|
|
461
441
|
|
|
462
|
-
// 'monitor' command: Monitor health server
|
|
463
442
|
program
|
|
464
443
|
.command('monitor')
|
|
465
444
|
.argument('<deploy-id>', 'The deployment configuration ID to monitor.')
|
|
@@ -477,7 +456,6 @@ program
|
|
|
477
456
|
.description('Manages health server monitoring for specified deployments.')
|
|
478
457
|
.action(Underpost.monitor.callback);
|
|
479
458
|
|
|
480
|
-
// 'ssh' command: SSH management
|
|
481
459
|
program
|
|
482
460
|
.command('ssh')
|
|
483
461
|
.option('--deploy-id <deploy-id>', 'Sets deploy id context for ssh operations.')
|
|
@@ -503,12 +481,11 @@ program
|
|
|
503
481
|
.option('--copy', 'Copies the connection URI to clipboard.')
|
|
504
482
|
.action(Underpost.ssh.callback);
|
|
505
483
|
|
|
506
|
-
// 'run' command: Run a script
|
|
507
484
|
program
|
|
508
485
|
.command('run')
|
|
509
486
|
.argument('<runner-id>', `The runner ID to run. Options: ${Object.keys(UnderpostRun.RUNNERS).join(', ')}.`)
|
|
510
487
|
.argument('[path]', 'The input value, identifier, or path for the operation.')
|
|
511
|
-
.option('--
|
|
488
|
+
.option('--cmd <command-list>', 'Comma-separated list of commands to execute.')
|
|
512
489
|
.option('--args <args-array>', 'Array of arguments to pass to the command.')
|
|
513
490
|
.option('--dev', 'Sets the development context environment for the script.')
|
|
514
491
|
.option('--build', 'Set builder context runner')
|
|
@@ -565,10 +542,10 @@ program
|
|
|
565
542
|
.option('--user <user>', 'Sets user context for the runner execution.')
|
|
566
543
|
.option('--hosts <hosts>', 'Comma-separated list of hosts for the runner execution.')
|
|
567
544
|
.option('--instance-id <instance-id>', 'Sets instance id context for the runner execution.')
|
|
545
|
+
.option('--pid <process-id>', 'Sets process id context for the runner execution.')
|
|
568
546
|
.description('Runs specified scripts using various runners.')
|
|
569
547
|
.action(UnderpostRun.API.callback);
|
|
570
548
|
|
|
571
|
-
// 'lxd' command: LXD management
|
|
572
549
|
program
|
|
573
550
|
.command('lxd')
|
|
574
551
|
.option('--init', 'Initializes LXD on the current machine.')
|
|
@@ -604,13 +581,20 @@ program
|
|
|
604
581
|
.description('Manages LXD containers and virtual machines.')
|
|
605
582
|
.action(UnderpostLxd.API.callback);
|
|
606
583
|
|
|
607
|
-
// 'baremetal' command: Baremetal server management
|
|
608
584
|
program
|
|
609
|
-
.command('baremetal [workflow-id] [hostname] [ip-
|
|
585
|
+
.command('baremetal [workflow-id] [ip-address] [hostname] [ip-file-server] [ip-config] [netmask] [dns-server]')
|
|
610
586
|
.option('--control-server-install', 'Installs the baremetal control server.')
|
|
611
587
|
.option('--control-server-uninstall', 'Uninstalls the baremetal control server.')
|
|
588
|
+
.option('--control-server-restart', 'Restarts the baremetal control server.')
|
|
612
589
|
.option('--control-server-db-install', 'Installs up the database for the baremetal control server.')
|
|
613
590
|
.option('--control-server-db-uninstall', 'Uninstalls the database for the baremetal control server.')
|
|
591
|
+
.option('--create-machine', 'Creates a new baremetal machine entry in the database.')
|
|
592
|
+
.option(
|
|
593
|
+
'--mac <mac>',
|
|
594
|
+
'Specifies the MAC address for baremetal machine operations. Use "random" for random MAC, "hardware" to use device\'s actual MAC (no spoofing), or specify a MAC address.',
|
|
595
|
+
)
|
|
596
|
+
.option('--ipxe', 'Chainloads iPXE to normalize identity before commissioning.')
|
|
597
|
+
.option('--ipxe-rebuild', 'Forces rebuild of iPXE binary with embedded boot script.')
|
|
614
598
|
.option('--install-packer', 'Installs Packer CLI.')
|
|
615
599
|
.option(
|
|
616
600
|
'--packer-maas-image-template <template-path>',
|
|
@@ -625,12 +609,32 @@ program
|
|
|
625
609
|
'--packer-maas-image-upload',
|
|
626
610
|
'Uploads an existing MAAS image artifact without rebuilding for the workflow specified by --packer-workflow-id.',
|
|
627
611
|
)
|
|
612
|
+
.option(
|
|
613
|
+
'--packer-maas-image-cached',
|
|
614
|
+
'Continue last build without removing artifacts (used with --packer-maas-image-build).',
|
|
615
|
+
)
|
|
616
|
+
.option('--remove-machines <system-ids>', 'Removes baremetal machines by comma-separated system IDs, or use "all"')
|
|
617
|
+
.option('--clear-discovered', 'Clears all discovered baremetal machines from the database.')
|
|
628
618
|
.option('--commission', 'Init workflow for commissioning a physical machine.')
|
|
619
|
+
.option(
|
|
620
|
+
'--bootstrap-http-server-path <path>',
|
|
621
|
+
'Sets a custom bootstrap HTTP server path for baremetal commissioning.',
|
|
622
|
+
)
|
|
623
|
+
.option(
|
|
624
|
+
'--bootstrap-http-server-port <port>',
|
|
625
|
+
'Sets a custom bootstrap HTTP server port for baremetal commissioning.',
|
|
626
|
+
)
|
|
627
|
+
.option('--iso-url <url>', 'Uses a custom ISO URL for baremetal machine commissioning.')
|
|
629
628
|
.option('--nfs-build', 'Builds an NFS root filesystem for a workflow id config architecture using QEMU emulation.')
|
|
630
629
|
.option('--nfs-mount', 'Mounts the NFS root filesystem for a workflow id config architecture.')
|
|
631
630
|
.option('--nfs-unmount', 'Unmounts the NFS root filesystem for a workflow id config architecture.')
|
|
632
631
|
.option('--nfs-sh', 'Copies QEMU emulation root entrypoint shell command to the clipboard.')
|
|
632
|
+
.option('--cloud-init', 'Sets the kernel parameters and sets the necessary seed users on the HTTP server.')
|
|
633
633
|
.option('--cloud-init-update', 'Updates cloud init for a workflow id config architecture.')
|
|
634
|
+
.option('--ubuntu-tools-build', 'Builds ubuntu tools for chroot environment.')
|
|
635
|
+
.option('--ubuntu-tools-test', 'Tests ubuntu tools in chroot environment.')
|
|
636
|
+
.option('--bootcmd <bootcmd-list>', 'Comma-separated list of boot commands to execute.')
|
|
637
|
+
.option('--runcmd <runcmd-list>', 'Comma-separated list of run commands to execute.')
|
|
634
638
|
.option('--logs <log-id>', 'Displays logs for log id: dhcp, cloud, machine, cloud-config.')
|
|
635
639
|
.option('--dev', 'Sets the development context environment for baremetal operations.')
|
|
636
640
|
.option('--ls', 'Lists available boot resources and machines.')
|
package/src/cli/run.js
CHANGED
|
@@ -57,6 +57,7 @@ class UnderpostRun {
|
|
|
57
57
|
* @property {boolean} force - Whether to force the operation.
|
|
58
58
|
* @property {boolean} reset - Whether to reset the operation.
|
|
59
59
|
* @property {boolean} tls - Whether to use TLS.
|
|
60
|
+
* @property {string} cmd - The command to run in the container.
|
|
60
61
|
* @property {string} tty - The TTY option for the container.
|
|
61
62
|
* @property {string} stdin - The stdin option for the container.
|
|
62
63
|
* @property {string} restartPolicy - The restart policy for the container.
|
|
@@ -87,6 +88,7 @@ class UnderpostRun {
|
|
|
87
88
|
* @property {string} deployId - The deployment ID.
|
|
88
89
|
* @property {string} instanceId - The instance ID.
|
|
89
90
|
* @property {string} user - The user to run as.
|
|
91
|
+
* @property {string} pid - The process ID.
|
|
90
92
|
* @memberof UnderpostRun
|
|
91
93
|
*/
|
|
92
94
|
static DEFAULT_OPTION = {
|
|
@@ -104,6 +106,7 @@ class UnderpostRun {
|
|
|
104
106
|
force: false,
|
|
105
107
|
reset: false,
|
|
106
108
|
tls: false,
|
|
109
|
+
cmd: '',
|
|
107
110
|
tty: '',
|
|
108
111
|
stdin: '',
|
|
109
112
|
restartPolicy: '',
|
|
@@ -134,6 +137,7 @@ class UnderpostRun {
|
|
|
134
137
|
deployId: '',
|
|
135
138
|
instanceId: '',
|
|
136
139
|
user: '',
|
|
140
|
+
pid: '',
|
|
137
141
|
};
|
|
138
142
|
/**
|
|
139
143
|
* @static
|
|
@@ -187,6 +191,7 @@ class UnderpostRun {
|
|
|
187
191
|
* @memberof UnderpostRun
|
|
188
192
|
*/
|
|
189
193
|
kill: (path = '', options = UnderpostRun.DEFAULT_OPTION) => {
|
|
194
|
+
if (options.pid) return shellExec(`sudo kill -9 ${options.pid}`);
|
|
190
195
|
for (const _path of path.split(',')) {
|
|
191
196
|
if (_path.split('+')[1]) {
|
|
192
197
|
let [port, sumPortOffSet] = _path.split('+');
|
|
@@ -564,7 +569,7 @@ class UnderpostRun {
|
|
|
564
569
|
const currentTraffic = isDeployRunnerContext(path, options)
|
|
565
570
|
? UnderpostDeploy.API.getCurrentTraffic(deployId, { namespace: options.namespace })
|
|
566
571
|
: '';
|
|
567
|
-
let targetTraffic = currentTraffic ? (currentTraffic === 'blue' ? 'green' : 'blue') : '';
|
|
572
|
+
let targetTraffic = currentTraffic ? (currentTraffic === 'blue' ? 'green' : 'blue') : 'green';
|
|
568
573
|
if (targetTraffic) versions = targetTraffic;
|
|
569
574
|
|
|
570
575
|
shellExec(
|
|
@@ -574,8 +579,13 @@ class UnderpostRun {
|
|
|
574
579
|
);
|
|
575
580
|
|
|
576
581
|
if (isDeployRunnerContext(path, options)) {
|
|
582
|
+
const cmdString = options.cmd
|
|
583
|
+
? ` --cmd ${options.cmd.find((c) => c.match('"')) ? `"${options.cmd}"` : `'${options.cmd}'`}`
|
|
584
|
+
: '';
|
|
577
585
|
shellExec(
|
|
578
|
-
`${baseCommand} deploy --kubeadm
|
|
586
|
+
`${baseCommand} deploy --kubeadm${cmdString} --replicas ${
|
|
587
|
+
replicas
|
|
588
|
+
} --disable-update-proxy ${deployId} ${env} --versions ${versions}${options.namespace ? ` --namespace ${options.namespace}` : ''}`,
|
|
579
589
|
);
|
|
580
590
|
if (!targetTraffic)
|
|
581
591
|
targetTraffic = UnderpostDeploy.API.getCurrentTraffic(deployId, { namespace: options.namespace });
|
|
@@ -1157,6 +1167,7 @@ EOF
|
|
|
1157
1167
|
* @memberof UnderpostRun
|
|
1158
1168
|
*/
|
|
1159
1169
|
cluster: async (path = '', options = UnderpostRun.DEFAULT_OPTION) => {
|
|
1170
|
+
const { underpostRoot } = options;
|
|
1160
1171
|
const env = options.dev ? 'development' : 'production';
|
|
1161
1172
|
const baseCommand = options.dev ? 'node bin' : 'underpost';
|
|
1162
1173
|
const baseClusterCommand = options.dev ? ' --dev' : '';
|
|
@@ -1166,12 +1177,16 @@ EOF
|
|
|
1166
1177
|
await timer(5000);
|
|
1167
1178
|
shellExec(`${baseCommand} cluster${baseClusterCommand} --${clusterType}`);
|
|
1168
1179
|
await timer(5000);
|
|
1169
|
-
let [runtimeImage, deployList] =
|
|
1170
|
-
|
|
1171
|
-
|
|
1180
|
+
let [runtimeImage, deployList] =
|
|
1181
|
+
path && path.trim() && path.split(',')
|
|
1182
|
+
? path.split(',')
|
|
1183
|
+
: [
|
|
1184
|
+
'express',
|
|
1185
|
+
fs.readFileSync(`${underpostRoot}/engine-private/deploy/dd.router`, 'utf8').replaceAll(',', '+'),
|
|
1186
|
+
];
|
|
1172
1187
|
shellExec(
|
|
1173
|
-
`${baseCommand} image${baseClusterCommand}${
|
|
1174
|
-
runtimeImage ? ` --pull-base --path /
|
|
1188
|
+
`${baseCommand} image${baseClusterCommand} --build ${
|
|
1189
|
+
runtimeImage ? ` --pull-base --path ${underpostRoot}/src/runtime/${runtimeImage}` : ''
|
|
1175
1190
|
} --${clusterType}`,
|
|
1176
1191
|
);
|
|
1177
1192
|
if (!deployList) {
|
|
@@ -1246,7 +1261,7 @@ EOF
|
|
|
1246
1261
|
'disk-clean': async (path, options = UnderpostRun.DEFAULT_OPTION) => {
|
|
1247
1262
|
const { underpostRoot } = options;
|
|
1248
1263
|
shellExec(`chmod +x ${underpostRoot}/scripts/disk-clean.sh`);
|
|
1249
|
-
shellExec(`./scripts/disk-clean.sh
|
|
1264
|
+
shellExec(`./scripts/disk-clean.sh`);
|
|
1250
1265
|
},
|
|
1251
1266
|
|
|
1252
1267
|
/**
|
|
@@ -1405,7 +1420,7 @@ EOF
|
|
|
1405
1420
|
shellExec(
|
|
1406
1421
|
`${baseCommand} deploy${options.dev ? '' : ' --kubeadm'}${options.devProxyPortOffset ? ' --disable-deployment-proxy' : ''} --disable-update-deployment ${deployId} ${env} --versions ${versions}`,
|
|
1407
1422
|
);
|
|
1408
|
-
} else logger.error(
|
|
1423
|
+
} else logger.error(`Service pod ${podToMonitor} failed to start in time.`);
|
|
1409
1424
|
if (options.etcHosts === true) {
|
|
1410
1425
|
const hostListenResult = UnderpostDeploy.API.etcHostFactory([host]);
|
|
1411
1426
|
logger.info(hostListenResult.renderHosts);
|
|
@@ -1447,6 +1462,32 @@ EOF
|
|
|
1447
1462
|
console.log(result);
|
|
1448
1463
|
},
|
|
1449
1464
|
|
|
1465
|
+
/**
|
|
1466
|
+
* @method ps
|
|
1467
|
+
* @description Displays running processes that match a specified path or keyword.
|
|
1468
|
+
* @param {string} path - The input value, identifier, or path for the operation (used as a keyword to filter processes).
|
|
1469
|
+
* @param {Object} options - The default underpost runner options for customizing workflow
|
|
1470
|
+
* @memberof UnderpostRun
|
|
1471
|
+
*/
|
|
1472
|
+
ps: async (path = '', options = UnderpostRun.DEFAULT_OPTION) => {
|
|
1473
|
+
const out = shellExec(`ps aux${path ? `| grep '${path}' | grep -v grep` : ''}`, {
|
|
1474
|
+
stdout: true,
|
|
1475
|
+
silent: true,
|
|
1476
|
+
});
|
|
1477
|
+
console.log(path ? out.replaceAll(path, path.bgYellow.black.bold) : out);
|
|
1478
|
+
},
|
|
1479
|
+
|
|
1480
|
+
/**
|
|
1481
|
+
* @method ptls
|
|
1482
|
+
* @description Set on ~/.bashrc alias: ports <port> Command to list listening ports that match the given keyword.
|
|
1483
|
+
* @param {string} path - The input value, identifier, or path for the operation (used as a keyword to filter listening ports).
|
|
1484
|
+
* @param {Object} options - The default underpost runner options for customizing workflow
|
|
1485
|
+
* @memberof UnderpostRun
|
|
1486
|
+
*/
|
|
1487
|
+
ptls: async (path = '', options = UnderpostRun.DEFAULT_OPTION) => {
|
|
1488
|
+
shellExec(`chmod +x ${options.underpostRoot}/scripts/ports-ls.sh`);
|
|
1489
|
+
shellExec(`${options.underpostRoot}/scripts/ports-ls.sh`);
|
|
1490
|
+
},
|
|
1450
1491
|
/**
|
|
1451
1492
|
* @method release-cmt
|
|
1452
1493
|
* @description Commits and pushes a new release for the `engine` repository with a message indicating the new version.
|
|
@@ -1462,6 +1503,31 @@ EOF
|
|
|
1462
1503
|
shellExec(`underpost push . ${process.env.GITHUB_USERNAME}/engine`, { silent: true });
|
|
1463
1504
|
},
|
|
1464
1505
|
|
|
1506
|
+
/**
|
|
1507
|
+
* @method deploy-test
|
|
1508
|
+
* @description Deploys a test deployment (`dd-test`) in either development or production mode, setting up necessary secrets and starting the deployment.
|
|
1509
|
+
* @param {string} path - The input value, identifier, or path for the operation (used as the deployment ID).
|
|
1510
|
+
* @param {Object} options - The default underpost runner options for customizing workflow
|
|
1511
|
+
* @memberof UnderpostRun
|
|
1512
|
+
*/
|
|
1513
|
+
'deploy-test': async (path, options = UnderpostRun.DEFAULT_OPTION) => {
|
|
1514
|
+
// Note: use recomendation empty deploy cluster: node bin --dev cluster
|
|
1515
|
+
const env = options.dev ? 'development' : 'production';
|
|
1516
|
+
const baseCommand = options.dev ? 'node bin' : 'underpost';
|
|
1517
|
+
const baseClusterCommand = options.dev ? ' --dev' : '';
|
|
1518
|
+
const inputs = path ? path.split(',') : [];
|
|
1519
|
+
const deployId = inputs[0] ? inputs[0] : 'dd-test';
|
|
1520
|
+
const cmd = options.cmd
|
|
1521
|
+
? options.cmd
|
|
1522
|
+
: [
|
|
1523
|
+
`npm install -g npm@11.2.0`,
|
|
1524
|
+
`npm install -g underpost`,
|
|
1525
|
+
`${baseCommand} secret underpost --create-from-file /etc/config/.env.${env}`,
|
|
1526
|
+
`${baseCommand} start --build --run ${deployId} ${env} --underpost-quickly-install`,
|
|
1527
|
+
];
|
|
1528
|
+
shellExec(`node bin run sync${baseClusterCommand} --cron-jobs none dd-test --cmd "${cmd}"`);
|
|
1529
|
+
},
|
|
1530
|
+
|
|
1465
1531
|
/**
|
|
1466
1532
|
* @method sync-replica
|
|
1467
1533
|
* @description Syncs a replica for the dd.router
|
|
@@ -1597,7 +1663,7 @@ ${hostNetwork ? ` hostNetwork: ${hostNetwork}` : ''}
|
|
|
1597
1663
|
imagePullPolicy: ${imagePullPolicy}
|
|
1598
1664
|
tty: ${tty}
|
|
1599
1665
|
stdin: ${stdin}
|
|
1600
|
-
command: ${JSON.stringify(options.
|
|
1666
|
+
command: ${JSON.stringify(options.cmd ? options.cmd : ['/bin/bash', '-c'])}
|
|
1601
1667
|
${
|
|
1602
1668
|
args.length > 0
|
|
1603
1669
|
? ` args:
|
|
@@ -1649,7 +1715,7 @@ EOF`;
|
|
|
1649
1715
|
try {
|
|
1650
1716
|
const npmRoot = getNpmRootPath();
|
|
1651
1717
|
const underpostRoot = options?.dev === true ? '.' : `${npmRoot}/underpost`;
|
|
1652
|
-
if (options.
|
|
1718
|
+
if (options.cmd) options.cmd = options.cmd.split(',');
|
|
1653
1719
|
if (options.args) options.args = options.args.split(',');
|
|
1654
1720
|
if (!options.underpostRoot) options.underpostRoot = underpostRoot;
|
|
1655
1721
|
if (!options.namespace) options.namespace = 'default';
|
package/src/cli/ssh.js
CHANGED
|
@@ -280,7 +280,7 @@ EOF`);
|
|
|
280
280
|
options.password = confNode.users[options.user].password;
|
|
281
281
|
logger.info(`Using saved password for user ${options.user}`);
|
|
282
282
|
}
|
|
283
|
-
options.port = confNode.users[options.user].port ||
|
|
283
|
+
options.port = options.port || confNode.users[options.user].port || 22;
|
|
284
284
|
}
|
|
285
285
|
}
|
|
286
286
|
|