underpost 2.89.1 → 2.89.21
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/.env.development +2 -0
- package/.env.production +2 -0
- package/.env.test +2 -0
- package/.github/workflows/release.cd.yml +2 -0
- package/README.md +2 -3
- package/cli.md +123 -94
- package/manifests/deployment/dd-default-development/deployment.yaml +2 -2
- package/manifests/deployment/dd-test-development/deployment.yaml +10 -2
- package/manifests/deployment/dd-test-development/proxy.yaml +4 -0
- package/manifests/grafana/deployment.yaml +7 -0
- package/manifests/grafana/kustomization.yaml +1 -1
- package/manifests/grafana/pvc.yaml +1 -1
- package/manifests/grafana/storage-class.yaml +9 -0
- package/manifests/pv-pvc-dd.yaml +34 -0
- package/package.json +1 -1
- package/src/cli/cluster.js +40 -18
- package/src/cli/deploy.js +193 -77
- package/src/cli/index.js +20 -1
- package/src/cli/repository.js +12 -0
- package/src/cli/run.js +185 -68
- package/src/client/components/core/ObjectLayerEngineModal.js +4 -3
- package/src/client/components/core/ObjectLayerEngineViewer.js +83 -31
- package/src/index.js +1 -1
- package/src/server/start.js +2 -1
package/src/cli/deploy.js
CHANGED
|
@@ -91,12 +91,25 @@ class UnderpostDeploy {
|
|
|
91
91
|
* @param {Array<string>} deploymentVersions - List of deployment versions.
|
|
92
92
|
* @returns {string} - YAML service configuration for the specified deployment.
|
|
93
93
|
* @param {string} [serviceId] - Custom service name (optional).
|
|
94
|
+
* @param {Array} [pathRewritePolicy] - Path rewrite policy (optional).
|
|
94
95
|
* @memberof UnderpostDeploy
|
|
95
96
|
*/
|
|
96
|
-
deploymentYamlServiceFactory({ deployId, path, env, port, deploymentVersions, serviceId }) {
|
|
97
|
+
deploymentYamlServiceFactory({ deployId, path, env, port, deploymentVersions, serviceId, pathRewritePolicy }) {
|
|
97
98
|
return `
|
|
98
99
|
- conditions:
|
|
99
100
|
- prefix: ${path}
|
|
101
|
+
${
|
|
102
|
+
pathRewritePolicy
|
|
103
|
+
? `pathRewritePolicy:
|
|
104
|
+
replacePrefix:
|
|
105
|
+
${pathRewritePolicy.map(
|
|
106
|
+
(rd) => `- prefix: ${rd.prefix}
|
|
107
|
+
replacement: ${rd.replacement}
|
|
108
|
+
`,
|
|
109
|
+
).join(`
|
|
110
|
+
`)}`
|
|
111
|
+
: ''
|
|
112
|
+
}
|
|
100
113
|
enableWebsockets: true
|
|
101
114
|
services:
|
|
102
115
|
${deploymentVersions
|
|
@@ -121,6 +134,17 @@ class UnderpostDeploy {
|
|
|
121
134
|
*/
|
|
122
135
|
deploymentYamlPartsFactory({ deployId, env, suffix, resources, replicas, image }) {
|
|
123
136
|
const packageJson = JSON.parse(fs.readFileSync('./package.json', 'utf8'));
|
|
137
|
+
let volumes = [
|
|
138
|
+
{
|
|
139
|
+
volumeMountPath: '/etc/config',
|
|
140
|
+
volumeName: 'config-volume',
|
|
141
|
+
configMap: 'underpost-config',
|
|
142
|
+
},
|
|
143
|
+
];
|
|
144
|
+
const confVolume = fs.existsSync(`./engine-private/conf/${deployId}/conf.volume.json`)
|
|
145
|
+
? JSON.parse(fs.readFileSync(`./engine-private/conf/${deployId}/conf.volume.json`, 'utf8'))
|
|
146
|
+
: [];
|
|
147
|
+
volumes = volumes.concat(confVolume);
|
|
124
148
|
return `apiVersion: apps/v1
|
|
125
149
|
kind: Deployment
|
|
126
150
|
metadata:
|
|
@@ -155,13 +179,10 @@ spec:
|
|
|
155
179
|
npm install -g underpost &&
|
|
156
180
|
underpost secret underpost --create-from-file /etc/config/.env.${env} &&
|
|
157
181
|
underpost start --build --run ${deployId} ${env}
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
- name: config-volume
|
|
163
|
-
configMap:
|
|
164
|
-
name: underpost-config
|
|
182
|
+
${UnderpostDeploy.API.volumeFactory(volumes)
|
|
183
|
+
.render.split(`\n`)
|
|
184
|
+
.map((l) => ' ' + l)
|
|
185
|
+
.join(`\n`)}
|
|
165
186
|
---
|
|
166
187
|
apiVersion: v1
|
|
167
188
|
kind: Service
|
|
@@ -230,7 +251,7 @@ ${UnderpostDeploy.API.deploymentYamlPartsFactory({
|
|
|
230
251
|
|
|
231
252
|
const pathPortAssignment = pathPortAssignmentData[host];
|
|
232
253
|
// logger.info('', { host, pathPortAssignment });
|
|
233
|
-
|
|
254
|
+
let _proxyYaml = `
|
|
234
255
|
---
|
|
235
256
|
apiVersion: projectcontour.io/v1
|
|
236
257
|
kind: HTTPProxy
|
|
@@ -248,32 +269,31 @@ spec:
|
|
|
248
269
|
routes:`;
|
|
249
270
|
const deploymentVersions =
|
|
250
271
|
options.traffic && typeof options.traffic === 'string' ? options.traffic.split(',') : ['blue'];
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
path,
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
272
|
+
let proxyRoutes = '';
|
|
273
|
+
if (!options.disableDeploymentProxy)
|
|
274
|
+
for (const conditionObj of pathPortAssignment) {
|
|
275
|
+
const { path, port } = conditionObj;
|
|
276
|
+
proxyRoutes += UnderpostDeploy.API.deploymentYamlServiceFactory({
|
|
277
|
+
path,
|
|
278
|
+
deployId,
|
|
279
|
+
env,
|
|
280
|
+
port,
|
|
281
|
+
deploymentVersions,
|
|
282
|
+
});
|
|
283
|
+
}
|
|
261
284
|
for (const customService of customServices) {
|
|
262
|
-
const { path: _path, port, serviceId, host: _host } = customService;
|
|
285
|
+
const { path: _path, port, serviceId, host: _host, pathRewritePolicy } = customService;
|
|
263
286
|
if (host === _host) {
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
});
|
|
272
|
-
break;
|
|
273
|
-
}
|
|
274
|
-
}
|
|
287
|
+
proxyRoutes += UnderpostDeploy.API.deploymentYamlServiceFactory({
|
|
288
|
+
path: _path,
|
|
289
|
+
port,
|
|
290
|
+
serviceId,
|
|
291
|
+
deploymentVersions,
|
|
292
|
+
pathRewritePolicy,
|
|
293
|
+
});
|
|
275
294
|
}
|
|
276
295
|
}
|
|
296
|
+
if (proxyRoutes) proxyYaml += _proxyYaml + proxyRoutes;
|
|
277
297
|
}
|
|
278
298
|
const yamlPath = `./engine-private/conf/${deployId}/build/${env}/proxy.yaml`;
|
|
279
299
|
fs.writeFileSync(yamlPath, proxyYaml, 'utf8');
|
|
@@ -332,28 +352,31 @@ spec:
|
|
|
332
352
|
|
|
333
353
|
/**
|
|
334
354
|
* Callback function for handling deployment options.
|
|
335
|
-
* @param {string} deployList - List of deployment IDs to
|
|
336
|
-
* @param {string} env - Environment for which the
|
|
337
|
-
* @param {object} options - Options for the
|
|
338
|
-
* @param {
|
|
339
|
-
* @param {
|
|
340
|
-
* @param {
|
|
341
|
-
* @param {
|
|
342
|
-
* @param {
|
|
343
|
-
* @param {
|
|
344
|
-
* @param {
|
|
345
|
-
* @param {string} options.certHosts -
|
|
355
|
+
* @param {string} deployList - List of deployment IDs to process.
|
|
356
|
+
* @param {string} env - Environment for which the deployment is being processed.
|
|
357
|
+
* @param {object} options - Options for the deployment process.
|
|
358
|
+
* @param {boolean} options.remove - Whether to remove the deployment.
|
|
359
|
+
* @param {boolean} options.infoRouter - Whether to display router information.
|
|
360
|
+
* @param {boolean} options.sync - Whether to synchronize deployment configurations.
|
|
361
|
+
* @param {boolean} options.buildManifest - Whether to build the deployment manifest.
|
|
362
|
+
* @param {boolean} options.infoUtil - Whether to display utility information.
|
|
363
|
+
* @param {boolean} options.expose - Whether to expose the deployment.
|
|
364
|
+
* @param {boolean} options.cert - Whether to create certificates for the deployment.
|
|
365
|
+
* @param {string} options.certHosts - Comma-separated list of hosts for which to create certificates.
|
|
346
366
|
* @param {string} options.versions - Comma-separated list of versions to deploy.
|
|
347
367
|
* @param {string} options.image - Docker image for the deployment.
|
|
348
|
-
* @param {string} options.traffic -
|
|
368
|
+
* @param {string} options.traffic - Traffic status for the deployment.
|
|
349
369
|
* @param {string} options.replicas - Number of replicas for the deployment.
|
|
350
370
|
* @param {string} options.node - Node name for resource allocation.
|
|
351
|
-
* @param {
|
|
352
|
-
* @param {
|
|
353
|
-
* @param {
|
|
354
|
-
* @param {
|
|
355
|
-
* @param {
|
|
356
|
-
* @
|
|
371
|
+
* @param {boolean} options.restoreHosts - Whether to restore the hosts file.
|
|
372
|
+
* @param {boolean} options.disableUpdateDeployment - Whether to disable deployment updates.
|
|
373
|
+
* @param {boolean} options.disableUpdateProxy - Whether to disable proxy updates.
|
|
374
|
+
* @param {boolean} options.disableDeploymentProxy - Whether to disable deployment proxy.
|
|
375
|
+
* @param {boolean} options.disableUpdateVolume - Whether to disable volume updates.
|
|
376
|
+
* @param {boolean} options.status - Whether to display deployment status.
|
|
377
|
+
* @param {boolean} options.etcHosts - Whether to display the /etc/hosts file.
|
|
378
|
+
* @param {boolean} options.disableUpdateUnderpostConfig - Whether to disable Underpost config updates.
|
|
379
|
+
* @returns {Promise<void>} - Promise that resolves when the deployment process is complete.
|
|
357
380
|
* @memberof UnderpostDeploy
|
|
358
381
|
*/
|
|
359
382
|
async callback(
|
|
@@ -376,8 +399,11 @@ spec:
|
|
|
376
399
|
restoreHosts: false,
|
|
377
400
|
disableUpdateDeployment: false,
|
|
378
401
|
disableUpdateProxy: false,
|
|
402
|
+
disableDeploymentProxy: false,
|
|
403
|
+
disableUpdateVolume: false,
|
|
379
404
|
status: false,
|
|
380
405
|
etcHosts: false,
|
|
406
|
+
disableUpdateUnderpostConfig: false,
|
|
381
407
|
},
|
|
382
408
|
) {
|
|
383
409
|
if (options.infoUtil === true)
|
|
@@ -473,7 +499,7 @@ EOF`);
|
|
|
473
499
|
logger.info('router', await UnderpostDeploy.API.routerFactory(deployList, env));
|
|
474
500
|
return;
|
|
475
501
|
}
|
|
476
|
-
UnderpostDeploy.API.configMap(env);
|
|
502
|
+
if (!options.disableUpdateUnderpostConfig) UnderpostDeploy.API.configMap(env);
|
|
477
503
|
let renderHosts = '';
|
|
478
504
|
let etcHosts = [];
|
|
479
505
|
if (options.restoreHosts === true) {
|
|
@@ -504,6 +530,26 @@ EOF`);
|
|
|
504
530
|
}
|
|
505
531
|
|
|
506
532
|
const confServer = JSON.parse(fs.readFileSync(`./engine-private/conf/${deployId}/conf.server.json`, 'utf8'));
|
|
533
|
+
const confVolume = fs.existsSync(`./engine-private/conf/${deployId}/conf.volume.json`)
|
|
534
|
+
? JSON.parse(fs.readFileSync(`./engine-private/conf/${deployId}/conf.volume.json`, 'utf8'))
|
|
535
|
+
: [];
|
|
536
|
+
|
|
537
|
+
if (!options.disableUpdateVolume) {
|
|
538
|
+
for (const volume of confVolume) {
|
|
539
|
+
if (options.remove) {
|
|
540
|
+
shellExec(`kubectl delete pvc ${volume.claimName}`);
|
|
541
|
+
shellExec(`kubectl delete pv ${volume.claimName.replace('pvc-', 'pv-')}`);
|
|
542
|
+
continue;
|
|
543
|
+
}
|
|
544
|
+
shellExec(`kubectl apply -f - <<EOF
|
|
545
|
+
${UnderpostDeploy.API.persistentVolumeFactory({
|
|
546
|
+
hostPath: volume.volumeMountPath,
|
|
547
|
+
pvcId: volume.claimName,
|
|
548
|
+
})}
|
|
549
|
+
EOF
|
|
550
|
+
`);
|
|
551
|
+
}
|
|
552
|
+
}
|
|
507
553
|
|
|
508
554
|
for (const host of Object.keys(confServer)) {
|
|
509
555
|
if (!options.disableUpdateProxy) {
|
|
@@ -686,6 +732,78 @@ EOF`);
|
|
|
686
732
|
);
|
|
687
733
|
shellExec(`sudo kubectl apply -f ./engine-private/conf/${deployId}/build/${env}/proxy.yaml`);
|
|
688
734
|
},
|
|
735
|
+
|
|
736
|
+
/**
|
|
737
|
+
* Creates volume mounts and volumes for a deployment.
|
|
738
|
+
* @param {Array<volume>} volumes - List of volume configurations.
|
|
739
|
+
* @param {string} volume.volumeName - Name of the volume.
|
|
740
|
+
* @param {string} volume.volumeMountPath - Mount path of the volume in the container.
|
|
741
|
+
* @param {string} volume.volumeHostPath - Host path of the volume.
|
|
742
|
+
* @param {string} volume.volumeType - Type of the volume (e.g. 'Directory').
|
|
743
|
+
* @param {string|null} volume.claimName - Name of the persistent volume claim (if applicable).
|
|
744
|
+
* @param {string|null} volume.configMap - Name of the config map (if applicable).
|
|
745
|
+
* @returns {object} - Object containing the rendered volume mounts and volumes.
|
|
746
|
+
* @memberof UnderpostDeploy
|
|
747
|
+
*/
|
|
748
|
+
volumeFactory(
|
|
749
|
+
volumes = [
|
|
750
|
+
{
|
|
751
|
+
volumeName: 'volume-name',
|
|
752
|
+
volumeMountPath: '/path/in/container',
|
|
753
|
+
volumeHostPath: '/path/on/host',
|
|
754
|
+
volumeType: 'Directory',
|
|
755
|
+
claimName: null,
|
|
756
|
+
configMap: null,
|
|
757
|
+
},
|
|
758
|
+
],
|
|
759
|
+
) {
|
|
760
|
+
let _volumeMounts = `
|
|
761
|
+
volumeMounts:`;
|
|
762
|
+
let _volumes = `
|
|
763
|
+
volumes:`;
|
|
764
|
+
volumes.map((volumeData) => {
|
|
765
|
+
const { volumeName, volumeMountPath, volumeHostPath, volumeType, claimName, configMap } = volumeData;
|
|
766
|
+
_volumeMounts += `
|
|
767
|
+
- name: ${volumeName}
|
|
768
|
+
mountPath: ${volumeMountPath}
|
|
769
|
+
`;
|
|
770
|
+
|
|
771
|
+
_volumes += `
|
|
772
|
+
- name: ${volumeName}
|
|
773
|
+
${
|
|
774
|
+
configMap
|
|
775
|
+
? ` configMap:
|
|
776
|
+
name: ${configMap}`
|
|
777
|
+
: claimName
|
|
778
|
+
? ` persistentVolumeClaim:
|
|
779
|
+
claimName: ${claimName}`
|
|
780
|
+
: ` hostPath:
|
|
781
|
+
path: ${volumeHostPath}
|
|
782
|
+
type: ${volumeType}
|
|
783
|
+
`
|
|
784
|
+
}
|
|
785
|
+
|
|
786
|
+
`;
|
|
787
|
+
});
|
|
788
|
+
return { render: _volumeMounts + _volumes };
|
|
789
|
+
},
|
|
790
|
+
|
|
791
|
+
/**
|
|
792
|
+
* Creates a persistent volume and persistent volume claim for a deployment.
|
|
793
|
+
* @param {object} options - Options for the persistent volume and claim creation.
|
|
794
|
+
* @param {string} options.hostPath - Host path for the persistent volume.
|
|
795
|
+
* @param {string} options.pvcId - Persistent volume claim ID.
|
|
796
|
+
* @returns {string} - YAML configuration for the persistent volume and claim.
|
|
797
|
+
* @memberof UnderpostDeploy
|
|
798
|
+
*/
|
|
799
|
+
persistentVolumeFactory({ hostPath, pvcId }) {
|
|
800
|
+
return fs
|
|
801
|
+
.readFileSync(`./manifests/pv-pvc-dd.yaml`, 'utf8')
|
|
802
|
+
.replace('/home/dd', hostPath)
|
|
803
|
+
.replace('pv-dd', pvcId.replace('pvc-', 'pv-'))
|
|
804
|
+
.replace('pvc-dd', pvcId);
|
|
805
|
+
},
|
|
806
|
+
|
|
689
807
|
/**
|
|
690
808
|
* Creates a hosts file for a deployment.
|
|
691
809
|
* @param {Array<string>} hosts - List of hosts to be added to the hosts file.
|
|
@@ -789,37 +907,35 @@ ${renderHosts}`,
|
|
|
789
907
|
}))
|
|
790
908
|
.filter((o) => o.image);
|
|
791
909
|
}
|
|
792
|
-
|
|
793
|
-
|
|
794
|
-
|
|
795
|
-
|
|
796
|
-
});
|
|
910
|
+
const raw = shellExec(node === 'kind-worker' ? `docker exec -i ${node} crictl images` : `crictl images`, {
|
|
911
|
+
stdout: true,
|
|
912
|
+
silent: true,
|
|
913
|
+
});
|
|
797
914
|
|
|
798
|
-
|
|
799
|
-
|
|
800
|
-
|
|
801
|
-
|
|
915
|
+
const heads = raw
|
|
916
|
+
.split(`\n`)[0]
|
|
917
|
+
.split(' ')
|
|
918
|
+
.filter((_r) => _r.trim());
|
|
802
919
|
|
|
803
|
-
|
|
804
|
-
|
|
805
|
-
|
|
806
|
-
|
|
807
|
-
|
|
808
|
-
|
|
809
|
-
|
|
810
|
-
|
|
811
|
-
|
|
812
|
-
|
|
813
|
-
|
|
814
|
-
|
|
815
|
-
|
|
816
|
-
|
|
817
|
-
|
|
818
|
-
}
|
|
819
|
-
result.push(pod);
|
|
920
|
+
const pods = raw
|
|
921
|
+
.split(`\n`)
|
|
922
|
+
.filter((r) => !r.match('IMAGE'))
|
|
923
|
+
.map((r) => r.split(' ').filter((_r) => _r.trim()));
|
|
924
|
+
|
|
925
|
+
const result = [];
|
|
926
|
+
|
|
927
|
+
for (const row of pods) {
|
|
928
|
+
if (row.length === 0) continue;
|
|
929
|
+
const pod = {};
|
|
930
|
+
let index = -1;
|
|
931
|
+
for (const head of heads) {
|
|
932
|
+
if (head in pod) continue;
|
|
933
|
+
index++;
|
|
934
|
+
pod[head] = row[index];
|
|
820
935
|
}
|
|
821
|
-
|
|
936
|
+
result.push(pod);
|
|
822
937
|
}
|
|
938
|
+
return result;
|
|
823
939
|
},
|
|
824
940
|
};
|
|
825
941
|
}
|
package/src/cli/index.js
CHANGED
|
@@ -78,6 +78,8 @@ program
|
|
|
78
78
|
.option('--msg <msg>', 'Sets a custom commit message.')
|
|
79
79
|
.option('--deploy-id <deploy-id>', 'Sets the deployment configuration ID for the commit context.')
|
|
80
80
|
.option('--cached', 'Commit staged changes only or context.')
|
|
81
|
+
.option('--hashes <hashes>', 'Comma-separated list of specific file hashes of commits.')
|
|
82
|
+
.option('--extension <extension>', 'specific file extensions of commits.')
|
|
81
83
|
.description('Manages commits to a GitHub repository, supporting various commit types and options.')
|
|
82
84
|
.action(Underpost.repo.commit);
|
|
83
85
|
|
|
@@ -162,6 +164,8 @@ program
|
|
|
162
164
|
.option('--worker', 'Sets the context for a worker node.')
|
|
163
165
|
.option('--chown', 'Sets the appropriate ownership for Kubernetes kubeconfig files.')
|
|
164
166
|
.option('--k3s', 'Initializes the cluster using K3s (Lightweight Kubernetes).')
|
|
167
|
+
.option('--hosts <hosts>', 'A comma-separated list of cluster hostnames or IP addresses.')
|
|
168
|
+
.option('--remove-volume-host-paths', 'Removes specified volume host paths after execution.')
|
|
165
169
|
.action(Underpost.cluster.init)
|
|
166
170
|
.description('Manages Kubernetes clusters, defaulting to Kind cluster initialization.');
|
|
167
171
|
|
|
@@ -191,6 +195,8 @@ program
|
|
|
191
195
|
.option('--traffic <traffic-versions>', 'A comma-separated list of custom deployment traffic weights.')
|
|
192
196
|
.option('--disable-update-deployment', 'Disables updates to deployments.')
|
|
193
197
|
.option('--disable-update-proxy', 'Disables updates to proxies.')
|
|
198
|
+
.option('--disable-deployment-proxy', 'Disables proxies of deployments.')
|
|
199
|
+
.option('--disable-update-volume', 'Disables updates to volume mounts during deployment.')
|
|
194
200
|
.option(
|
|
195
201
|
'--status',
|
|
196
202
|
'Retrieves current network traffic data from resource deployments and the host machine network configuration.',
|
|
@@ -198,6 +204,7 @@ program
|
|
|
198
204
|
.option('--kubeadm', 'Enables the kubeadm context for deployment operations.')
|
|
199
205
|
.option('--etc-hosts', 'Enables the etc-hosts context for deployment operations.')
|
|
200
206
|
.option('--restore-hosts', 'Restores default `/etc/hosts` entries.')
|
|
207
|
+
.option('--disable-update-underpost-config', 'Disables updates to Underpost configuration during deployment.')
|
|
201
208
|
.description('Manages application deployments, defaulting to deploying development pods.')
|
|
202
209
|
.action(Underpost.deploy.callback);
|
|
203
210
|
|
|
@@ -379,13 +386,24 @@ program
|
|
|
379
386
|
.option('--dev', 'Sets the development context environment for the script.')
|
|
380
387
|
.option('--build', 'Set builder context runner')
|
|
381
388
|
.option('--replicas <replicas>', 'Sets a custom number of replicas for deployment.')
|
|
382
|
-
.option('--pod-name <pod-name>', 'Optional: Specifies the pod name for
|
|
389
|
+
.option('--pod-name <pod-name>', 'Optional: Specifies the pod name for execution.')
|
|
390
|
+
.option('--node-name <node-name>', 'Optional: Specifies the node name for execution.')
|
|
391
|
+
.option('--port <port>', 'Optional: Specifies the port for execution.')
|
|
392
|
+
.option('--etc-hosts', 'Enables etc-hosts context for the runner execution.')
|
|
383
393
|
.option('--volume-host-path <volume-host-path>', 'Optional: Specifies the volume host path for test execution.')
|
|
384
394
|
.option('--volume-mount-path <volume-mount-path>', 'Optional: Specifies the volume mount path for test execution.')
|
|
385
395
|
.option('--volume-type <volume-type>', 'Optional: Specifies the volume type for test execution.')
|
|
386
396
|
.option('--image-name <image-name>', 'Optional: Specifies the image name for test execution.')
|
|
387
397
|
.option('--container-name <container-name>', 'Optional: Specifies the container name for test execution.')
|
|
388
398
|
.option('--namespace <namespace>', 'Optional: Specifies the namespace for test execution.')
|
|
399
|
+
.option('--tty', 'Enables TTY for the container in deploy-job.')
|
|
400
|
+
.option('--stdin', 'Keeps STDIN open for the container in deploy-job.')
|
|
401
|
+
.option('--restart-policy <policy>', 'Sets the restart policy for the job in deploy-job.')
|
|
402
|
+
.option('--runtime-class-name <name>', 'Sets the runtime class name for the job in deploy-job.')
|
|
403
|
+
.option('--image-pull-policy <policy>', 'Sets the image pull policy for the job in deploy-job.')
|
|
404
|
+
.option('--api-version <version>', 'Sets the API version for the job manifest in deploy-job.')
|
|
405
|
+
.option('--claim-name <name>', 'Optional: Specifies the claim name for volume mounting in deploy-job.')
|
|
406
|
+
.option('--kind <kind-type>', 'Specifies the kind of Kubernetes resource (e.g., Job, Deployment) for deploy-job.')
|
|
389
407
|
.option('--kubeadm', 'Flag to indicate Kubeadm cluster type context')
|
|
390
408
|
.option('--k3s', 'Flag to indicate K3s cluster type context')
|
|
391
409
|
.option('--force', 'Forces operation, overriding any warnings or conflicts.')
|
|
@@ -394,6 +412,7 @@ program
|
|
|
394
412
|
.option('--terminal', 'Enables terminal mode for interactive script execution.')
|
|
395
413
|
.option('--dev-proxy-port-offset <port-offset>', 'Sets a custom port offset for development proxy.')
|
|
396
414
|
.option('--conf-server-path <conf-server-path>', 'Sets a custom configuration server path.')
|
|
415
|
+
.option('--underpost-root <underpost-root>', 'Sets a custom Underpost root path.')
|
|
397
416
|
.description('Runs a script from the specified path.')
|
|
398
417
|
.action(UnderpostRun.API.callback);
|
|
399
418
|
|
package/src/cli/repository.js
CHANGED
|
@@ -89,6 +89,8 @@ class UnderpostRepository {
|
|
|
89
89
|
* @param {boolean} [options.lastMsg=0] - If greater than 0, copies or show the last last single n commit message to clipboard.
|
|
90
90
|
* @param {string} [options.msg=''] - If provided, outputs this message instead of committing.
|
|
91
91
|
* @param {string} [options.deployId=''] - An optional deploy ID to include in the commit message.
|
|
92
|
+
* @param {string} [options.hashes=''] - If provided with diff option, shows the diff between two hashes.
|
|
93
|
+
* @param {string} [options.extension=''] - If provided with diff option, filters the diff by this file extension.
|
|
92
94
|
* @memberof UnderpostRepository
|
|
93
95
|
*/
|
|
94
96
|
commit(
|
|
@@ -107,9 +109,19 @@ class UnderpostRepository {
|
|
|
107
109
|
log: 0,
|
|
108
110
|
msg: '',
|
|
109
111
|
deployId: '',
|
|
112
|
+
hashes: '',
|
|
113
|
+
extension: '',
|
|
110
114
|
},
|
|
111
115
|
) {
|
|
112
116
|
if (!repoPath) repoPath = '.';
|
|
117
|
+
if (options.diff && options.hashes) {
|
|
118
|
+
const hashes = options.hashes.split(',');
|
|
119
|
+
const cmd = `git --no-pager diff ${hashes[0]} ${hashes[1] ? hashes[1] : 'HEAD'}${options.extension ? ` -- '*.${options.extension}'` : ''}`;
|
|
120
|
+
if (options.copy) {
|
|
121
|
+
pbcopy(cmd);
|
|
122
|
+
} else console.log(cmd);
|
|
123
|
+
return;
|
|
124
|
+
}
|
|
113
125
|
if (options.msg) {
|
|
114
126
|
options.msg = options.msg.replaceAll('"', '').replaceAll(`'`, '').replaceAll('`', '');
|
|
115
127
|
let key = Object.keys(commitData).find((k) => k && options.msg.toLocaleLowerCase().slice(0, 16).match(k));
|