underpost 2.92.0 → 2.95.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/.github/workflows/pwa-microservices-template-page.cd.yml +5 -4
- package/README.md +4 -5
- package/bin/build.js +6 -1
- package/bin/deploy.js +2 -69
- package/cli.md +100 -92
- package/manifests/deployment/dd-default-development/deployment.yaml +4 -4
- package/manifests/deployment/dd-test-development/deployment.yaml +2 -2
- package/package.json +1 -1
- package/scripts/disk-clean.sh +216 -0
- package/scripts/ssh-cluster-info.sh +4 -3
- package/src/cli/cluster.js +1 -1
- package/src/cli/db.js +80 -89
- package/src/cli/deploy.js +77 -13
- package/src/cli/image.js +198 -133
- package/src/cli/index.js +60 -81
- package/src/cli/lxd.js +73 -74
- package/src/cli/monitor.js +20 -9
- package/src/cli/repository.js +86 -3
- package/src/cli/run.js +167 -63
- package/src/cli/ssh.js +351 -134
- package/src/index.js +1 -1
- package/src/monitor.js +11 -1
- package/src/server/backup.js +1 -1
- package/src/server/conf.js +1 -1
- package/src/server/dns.js +88 -1
- package/src/server/process.js +6 -1
- package/scripts/snap-clean.sh +0 -26
- package/src/client/public/default/plantuml/client-conf.svg +0 -1
- package/src/client/public/default/plantuml/client-schema.svg +0 -1
- package/src/client/public/default/plantuml/cron-conf.svg +0 -1
- package/src/client/public/default/plantuml/cron-schema.svg +0 -1
- package/src/client/public/default/plantuml/server-conf.svg +0 -1
- package/src/client/public/default/plantuml/server-schema.svg +0 -1
- package/src/client/public/default/plantuml/ssr-conf.svg +0 -1
- package/src/client/public/default/plantuml/ssr-schema.svg +0 -1
package/src/cli/image.js
CHANGED
|
@@ -24,143 +24,208 @@ const logger = loggerFactory(import.meta);
|
|
|
24
24
|
*/
|
|
25
25
|
class UnderpostImage {
|
|
26
26
|
static API = {
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
27
|
+
/**
|
|
28
|
+
* @method pullBaseImages
|
|
29
|
+
* @description Pulls base images and builds a 'rockylinux9-underpost' image,
|
|
30
|
+
* then loads it into the specified Kubernetes cluster type (Kind, Kubeadm, or K3s).
|
|
31
|
+
* @param {object} options - Options for pulling and loading images.
|
|
32
|
+
* @param {boolean} [options.kind=false] - If true, load image into Kind cluster.
|
|
33
|
+
* @param {boolean} [options.kubeadm=false] - If true, load image into Kubeadm cluster.
|
|
34
|
+
* @param {boolean} [options.k3s=false] - If true, load image into K3s cluster.
|
|
35
|
+
* @param {string} [options.path=false] - Path to the Dockerfile context.
|
|
36
|
+
* @param {boolean} [options.dev=false] - If true, use development mode.
|
|
37
|
+
* @param {string} [options.version=''] - Version tag for the image.
|
|
38
|
+
* @param {string} [options.imageName=''] - Custom name for the image.
|
|
39
|
+
* @memberof UnderpostImage
|
|
40
|
+
*/
|
|
41
|
+
pullBaseImages(
|
|
42
|
+
options = {
|
|
43
|
+
kind: false,
|
|
44
|
+
kubeadm: false,
|
|
45
|
+
k3s: false,
|
|
46
|
+
path: false,
|
|
47
|
+
dev: false,
|
|
48
|
+
version: '',
|
|
49
|
+
imageName: '',
|
|
50
|
+
},
|
|
51
|
+
) {
|
|
52
|
+
shellExec(`sudo podman pull docker.io/library/rockylinux:9`);
|
|
53
|
+
const baseCommand = options.dev ? 'node bin' : 'underpost';
|
|
54
|
+
const baseCommandOption = options.dev ? ' --dev' : '';
|
|
55
|
+
const IMAGE_NAME = options.imageName
|
|
56
|
+
? `options.imageName${options.version ? `:${options.version}` : ''}`
|
|
57
|
+
: `rockylinux9-underpost:${options.version ? options.version : Underpost.version}`;
|
|
58
|
+
let LOAD_TYPE = '';
|
|
59
|
+
if (options.kind === true) LOAD_TYPE = `--kind`;
|
|
60
|
+
else if (options.kubeadm === true) LOAD_TYPE = `--kubeadm`;
|
|
61
|
+
else if (options.k3s === true) LOAD_TYPE = `--k3s`;
|
|
62
|
+
shellExec(
|
|
63
|
+
`${baseCommand} image${baseCommandOption} --build --podman-save --reset --image-path=. --path ${
|
|
64
|
+
options.path ? options.path : getUnderpostRootPath()
|
|
65
|
+
} --image-name=${IMAGE_NAME} ${LOAD_TYPE}`,
|
|
66
|
+
);
|
|
67
|
+
},
|
|
68
|
+
/**
|
|
69
|
+
* @method build
|
|
70
|
+
* @description Builds a Docker image using Podman, optionally saves it as a tar archive,
|
|
71
|
+
* and loads it into a specified Kubernetes cluster (Kind, Kubeadm, or K3s).
|
|
72
|
+
* @param {object} options - Options for building and loading images.
|
|
73
|
+
* @param {string} [options.path=''] - The path to the directory containing the Dockerfile.
|
|
74
|
+
* @param {string} [options.imageName=''] - The name and tag for the image (e.g., 'my-app:latest').
|
|
75
|
+
* @param {string} [options.version=''] - Version tag for the image.
|
|
76
|
+
* @param {string} [options.imagePath=''] - Directory to save the image tar file.
|
|
77
|
+
* @param {string} [options.dockerfileName=''] - Name of the Dockerfile (defaults to 'Dockerfile').
|
|
78
|
+
* @param {boolean} [options.podmanSave=false] - If true, save the image as a tar archive using Podman.
|
|
79
|
+
* @param {boolean} [options.kind=false] - If true, load the image archive into a Kind cluster.
|
|
80
|
+
* @param {boolean} [options.kubeadm=false] - If true, load the image archive into a Kubeadm cluster (uses 'ctr').
|
|
81
|
+
* @param {boolean} [options.k3s=false] - If true, load the image archive into a K3s cluster (uses 'k3s ctr').
|
|
82
|
+
* @param {boolean} [options.secrets=false] - If true, load secrets from the .env file for the build.
|
|
83
|
+
* @param {string} [options.secretsPath=''] - Custom path to the .env file for secrets.
|
|
84
|
+
* @param {boolean} [options.reset=false] - If true, perform a no-cache build.
|
|
85
|
+
* @param {boolean} [options.dev=false] - If true, use development mode.
|
|
86
|
+
* @memberof UnderpostImage
|
|
87
|
+
*/
|
|
88
|
+
build(
|
|
89
|
+
options = {
|
|
90
|
+
path: '',
|
|
91
|
+
imageName: '',
|
|
92
|
+
version: '',
|
|
93
|
+
imagePath: '',
|
|
94
|
+
dockerfileName: '',
|
|
95
|
+
podmanSave: false,
|
|
96
|
+
kind: false,
|
|
97
|
+
kubeadm: false,
|
|
98
|
+
k3s: false,
|
|
99
|
+
secrets: false,
|
|
100
|
+
secretsPath: '',
|
|
101
|
+
reset: false,
|
|
102
|
+
dev: false,
|
|
103
|
+
},
|
|
104
|
+
) {
|
|
105
|
+
let {
|
|
106
|
+
path,
|
|
107
|
+
imageName,
|
|
108
|
+
version,
|
|
109
|
+
imagePath,
|
|
110
|
+
dockerfileName,
|
|
111
|
+
podmanSave,
|
|
112
|
+
secrets,
|
|
113
|
+
secretsPath,
|
|
114
|
+
kind,
|
|
115
|
+
kubeadm,
|
|
116
|
+
k3s,
|
|
117
|
+
reset,
|
|
118
|
+
dev,
|
|
119
|
+
} = options;
|
|
120
|
+
if (!path) path = '.';
|
|
121
|
+
if (!imageName) imageName = `rockylinux9-underpost:${Underpost.version}`;
|
|
122
|
+
if (!version) version = 'latest';
|
|
123
|
+
version = imageName && imageName.match(':') ? '' : `:${version}`;
|
|
124
|
+
const podManImg = `localhost/${imageName}${version}`;
|
|
125
|
+
if (imagePath && typeof imagePath === 'string' && !fs.existsSync(imagePath))
|
|
126
|
+
fs.mkdirSync(imagePath, { recursive: true });
|
|
127
|
+
const tarFile = `${imagePath}/${imageName.replace(':', '_')}.tar`;
|
|
128
|
+
let secretsInput = ' ';
|
|
129
|
+
let secretDockerInput = '';
|
|
130
|
+
let cache = '';
|
|
131
|
+
if (secrets === true) {
|
|
132
|
+
const envObj = dotenv.parse(
|
|
133
|
+
fs.readFileSync(
|
|
134
|
+
secretsPath && typeof secretsPath === 'string' ? secretsPath : `${getNpmRootPath()}/underpost/.env`,
|
|
135
|
+
'utf8',
|
|
136
|
+
),
|
|
137
|
+
);
|
|
138
|
+
for (const key of Object.keys(envObj)) {
|
|
139
|
+
secretsInput += ` && export ${key}="${envObj[key]}" `; // Example: $(cat gitlab-token.txt)
|
|
140
|
+
secretDockerInput += ` --secret id=${key},env=${key} \ `;
|
|
65
141
|
}
|
|
66
|
-
|
|
142
|
+
}
|
|
143
|
+
if (reset === true) cache += ' --rm --no-cache';
|
|
144
|
+
if (path && typeof path === 'string')
|
|
67
145
|
shellExec(
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
}
|
|
146
|
+
`cd ${path}${secretsInput}&& sudo podman build -f ./${
|
|
147
|
+
dockerfileName && typeof dockerfileName === 'string' ? dockerfileName : 'Dockerfile'
|
|
148
|
+
} -t ${imageName} --pull=never --cap-add=CAP_AUDIT_WRITE${cache}${secretDockerInput} --network host`,
|
|
71
149
|
);
|
|
72
|
-
},
|
|
73
|
-
/**
|
|
74
|
-
* @method build
|
|
75
|
-
* @description Builds a Docker image using Podman, optionally saves it as a tar archive,
|
|
76
|
-
* and loads it into a specified Kubernetes cluster (Kind, Kubeadm, or K3s).
|
|
77
|
-
* @param {object} options - Options for building and loading images.
|
|
78
|
-
* @param {string} [options.path=''] - The path to the directory containing the Dockerfile.
|
|
79
|
-
* @param {string} [options.imageName=''] - The name and tag for the image (e.g., 'my-app:latest').
|
|
80
|
-
* @param {string} [options.imagePath=''] - Directory to save the image tar file.
|
|
81
|
-
* @param {string} [options.dockerfileName=''] - Name of the Dockerfile (defaults to 'Dockerfile').
|
|
82
|
-
* @param {boolean} [options.podmanSave=false] - If true, save the image as a tar archive using Podman.
|
|
83
|
-
* @param {boolean} [options.kindLoad=false] - If true, load the image archive into a Kind cluster.
|
|
84
|
-
* @param {boolean} [options.kubeadmLoad=false] - If true, load the image archive into a Kubeadm cluster (uses 'ctr').
|
|
85
|
-
* @param {boolean} [options.k3sLoad=false] - If true, load the image archive into a K3s cluster (uses 'k3s ctr').
|
|
86
|
-
* @param {boolean} [options.secrets=false] - If true, load secrets from the .env file for the build.
|
|
87
|
-
* @param {string} [options.secretsPath=''] - Custom path to the .env file for secrets.
|
|
88
|
-
* @param {boolean} [options.reset=false] - If true, perform a no-cache build.
|
|
89
|
-
* @param {boolean} [options.dev=false] - If true, use development mode.
|
|
90
|
-
* @memberof UnderpostImage
|
|
91
|
-
*/
|
|
92
|
-
build(
|
|
93
|
-
options = {
|
|
94
|
-
path: '',
|
|
95
|
-
imageName: '',
|
|
96
|
-
imagePath: '',
|
|
97
|
-
dockerfileName: '',
|
|
98
|
-
podmanSave: false,
|
|
99
|
-
kindLoad: false,
|
|
100
|
-
kubeadmLoad: false,
|
|
101
|
-
k3sLoad: false,
|
|
102
|
-
secrets: false,
|
|
103
|
-
secretsPath: '',
|
|
104
|
-
reset: false,
|
|
105
|
-
dev: false,
|
|
106
|
-
},
|
|
107
|
-
) {
|
|
108
|
-
let {
|
|
109
|
-
path,
|
|
110
|
-
imageName,
|
|
111
|
-
imagePath,
|
|
112
|
-
dockerfileName,
|
|
113
|
-
podmanSave,
|
|
114
|
-
secrets,
|
|
115
|
-
secretsPath,
|
|
116
|
-
kindLoad,
|
|
117
|
-
kubeadmLoad,
|
|
118
|
-
k3sLoad,
|
|
119
|
-
reset,
|
|
120
|
-
dev,
|
|
121
|
-
} = options;
|
|
122
|
-
if (!path) path = '.';
|
|
123
|
-
const podManImg = `localhost/${imageName}`;
|
|
124
|
-
if (imagePath && typeof imagePath === 'string' && !fs.existsSync(imagePath))
|
|
125
|
-
fs.mkdirSync(imagePath, { recursive: true });
|
|
126
|
-
const tarFile = `${imagePath}/${imageName.replace(':', '_')}.tar`;
|
|
127
|
-
let secretsInput = ' ';
|
|
128
|
-
let secretDockerInput = '';
|
|
129
|
-
let cache = '';
|
|
130
|
-
if (secrets === true) {
|
|
131
|
-
const envObj = dotenv.parse(
|
|
132
|
-
fs.readFileSync(
|
|
133
|
-
secretsPath && typeof secretsPath === 'string' ? secretsPath : `${getNpmRootPath()}/underpost/.env`,
|
|
134
|
-
'utf8',
|
|
135
|
-
),
|
|
136
|
-
);
|
|
137
|
-
for (const key of Object.keys(envObj)) {
|
|
138
|
-
secretsInput += ` && export ${key}="${envObj[key]}" `; // Example: $(cat gitlab-token.txt)
|
|
139
|
-
secretDockerInput += ` --secret id=${key},env=${key} \ `;
|
|
140
|
-
}
|
|
141
|
-
}
|
|
142
|
-
if (reset === true) cache += ' --rm --no-cache';
|
|
143
|
-
if (path && typeof path === 'string')
|
|
144
|
-
shellExec(
|
|
145
|
-
`cd ${path}${secretsInput}&& sudo podman build -f ./${
|
|
146
|
-
dockerfileName && typeof dockerfileName === 'string' ? dockerfileName : 'Dockerfile'
|
|
147
|
-
} -t ${imageName} --pull=never --cap-add=CAP_AUDIT_WRITE${cache}${secretDockerInput} --network host`,
|
|
148
|
-
);
|
|
149
150
|
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
151
|
+
if (podmanSave === true) {
|
|
152
|
+
if (fs.existsSync(tarFile)) fs.removeSync(tarFile);
|
|
153
|
+
shellExec(`podman save -o ${tarFile} ${podManImg}`);
|
|
154
|
+
}
|
|
155
|
+
if (kind === true) shellExec(`sudo kind load image-archive ${tarFile}`);
|
|
156
|
+
else if (kubeadm === true) shellExec(`sudo ctr -n k8s.io images import ${tarFile}`);
|
|
157
|
+
else if (k3s === true) shellExec(`sudo k3s ctr images import ${tarFile}`);
|
|
158
|
+
},
|
|
159
|
+
/**
|
|
160
|
+
* @method list
|
|
161
|
+
* @description Lists currently loaded Docker images in the specified Kubernetes cluster node.
|
|
162
|
+
* @param {object} options - Options for listing loaded images.
|
|
163
|
+
* @param {string} [options.nodeName='kind-worker'] - The name of the node to query.
|
|
164
|
+
* @param {string} [options.namespace=''] - The namespace to filter images (if applicable).
|
|
165
|
+
* @param {boolean} [options.spec=false] - If true, include detailed specifications of each image.
|
|
166
|
+
* @param {boolean} [options.log=false] - If true, log the list of images to the console.
|
|
167
|
+
* @param {boolean} [options.k3s=false] - If true, list images from a K3s cluster.
|
|
168
|
+
* @param {boolean} [options.kubeadm=false] - If true, list images from a Kubeadm cluster.
|
|
169
|
+
* @param {boolean} [options.kind=false] - If true, list images from a Kind cluster.
|
|
170
|
+
* @returns {Array} - An array of loaded images information.
|
|
171
|
+
* @memberof UnderpostImage
|
|
172
|
+
*/
|
|
173
|
+
list(options = { nodeName: '', namespace: '', spec: false, log: false, k3s: false, kubeadm: false, kind: false }) {
|
|
174
|
+
if ((options.kubeadm === true || options.k3s === true) && !options.nodeName)
|
|
175
|
+
options.nodeName = shellExec('echo $HOSTNAME', { stdout: true, silent: true }).trim();
|
|
176
|
+
const list = Underpost.deploy.getCurrentLoadedImages(
|
|
177
|
+
options.nodeName ? options.nodeName : 'kind-worker',
|
|
178
|
+
options,
|
|
179
|
+
);
|
|
180
|
+
if (options.log) console.table(list);
|
|
181
|
+
return list;
|
|
182
|
+
},
|
|
183
|
+
/**
|
|
184
|
+
* @method rm
|
|
185
|
+
* @description Removes a specified Docker image from the specified Kubernetes cluster type (Kind, Kubeadm, or K3s).
|
|
186
|
+
* @param {object} options - Options for removing the image.
|
|
187
|
+
* @param {string} [options.imageName=''] - The name and tag of the image to be removed.
|
|
188
|
+
* @param {boolean} [options.k3s=false] - If true, remove the image from a K3s cluster.
|
|
189
|
+
* @param {boolean} [options.kubeadm=false] - If true, remove the image from a Kubeadm cluster.
|
|
190
|
+
* @param {boolean} [options.kind=false] - If true, remove the image from a Kind cluster.
|
|
191
|
+
* @memberof UnderpostImage
|
|
192
|
+
*/
|
|
193
|
+
rm(options = { imageName: '', k3s: false, kubeadm: false, kind: false }) {
|
|
194
|
+
let { imageName, k3s, kubeadm, kind } = options;
|
|
195
|
+
if (kind === true) {
|
|
196
|
+
shellExec(`docker exec -i kind-control-plane crictl rmi ${imageName}`);
|
|
197
|
+
shellExec(`docker exec -i kind-worker crictl rmi ${imageName}`);
|
|
198
|
+
} else if (kubeadm === true) {
|
|
199
|
+
shellExec(`crictl rmi ${imageName}`);
|
|
200
|
+
} else if (k3s === true) {
|
|
201
|
+
shellExec(`sudo k3s ctr images rm ${imageName}`);
|
|
202
|
+
}
|
|
203
|
+
},
|
|
204
|
+
/**
|
|
205
|
+
* @method pullDockerHubImage
|
|
206
|
+
* @description Pulls a Docker image from Docker Hub and loads it into the specified Kubernetes cluster type (Kind, Kubeadm, or K3s).
|
|
207
|
+
* @param {object} options - Options for pulling and loading the image.
|
|
208
|
+
* @param {boolean} [options.k3s=false] - If true, load the image into a K3s cluster.
|
|
209
|
+
* @param {boolean} [options.kubeadm=false] - If true, load the image into a Kubeadm cluster.
|
|
210
|
+
* @param {boolean} [options.kind=false] - If true, load the image into a Kind cluster.
|
|
211
|
+
* @param {string} [options.dockerhubImage=''] - The name of the Docker Hub image to be pulled.
|
|
212
|
+
* @param {string} [options.version=''] - The version tag of the image to be pulled.
|
|
213
|
+
* @memberof UnderpostImage
|
|
214
|
+
*/
|
|
215
|
+
pullDockerHubImage(options = { k3s: false, kubeadm: false, kind: false, dockerhubImage: '', version: '' }) {
|
|
216
|
+
if (options.dockerhubImage === 'underpost') {
|
|
217
|
+
options.dockerhubImage = 'underpost/underpost-engine';
|
|
218
|
+
if (!options.version) options.version = Underpost.version;
|
|
219
|
+
}
|
|
220
|
+
if (!options.version) options.version = 'latest';
|
|
221
|
+
const version = options.dockerhubImage && options.dockerhubImage.match(':') ? '' : `:${options.version}`;
|
|
222
|
+
const image = `${options.dockerhubImage}${version}`;
|
|
223
|
+
if (options.kind === true) {
|
|
224
|
+
shellExec(`docker pull ${image}`);
|
|
225
|
+
shellExec(`sudo kind load docker-image ${image}`);
|
|
226
|
+
} else {
|
|
227
|
+
shellExec(`sudo crictl pull ${image}`);
|
|
228
|
+
}
|
|
164
229
|
},
|
|
165
230
|
};
|
|
166
231
|
}
|
package/src/cli/index.js
CHANGED
|
@@ -8,7 +8,6 @@ import UnderpostLxd from './lxd.js';
|
|
|
8
8
|
import UnderpostBaremetal from './baremetal.js';
|
|
9
9
|
import UnderpostRun from './run.js';
|
|
10
10
|
import Dns from '../server/dns.js';
|
|
11
|
-
import { pbcopy } from '../server/process.js';
|
|
12
11
|
import UnderpostStatic from './static.js';
|
|
13
12
|
|
|
14
13
|
// Load environment variables from .env file
|
|
@@ -35,6 +34,8 @@ program
|
|
|
35
34
|
.option('--sync-conf', 'Sync configuration to private repositories (requires --deploy-id)')
|
|
36
35
|
.option('--purge', 'Remove deploy ID conf and all related repositories (requires --deploy-id)')
|
|
37
36
|
.option('--dev', 'Sets the development cli context')
|
|
37
|
+
.option('--default-conf', 'Create default deploy ID conf env files')
|
|
38
|
+
.option('--conf-workflow-id <workflow-id>', 'Set custom configuration workflow ID for conf generation')
|
|
38
39
|
.description('Initializes a new Underpost project, service, or configuration.')
|
|
39
40
|
.action(Underpost.repo.new);
|
|
40
41
|
|
|
@@ -256,57 +257,7 @@ program
|
|
|
256
257
|
.option('--ban-both-add', 'Adds IP addresses to both banned ingress and egress lists.')
|
|
257
258
|
.option('--ban-both-remove', 'Removes IP addresses from both banned ingress and egress lists.')
|
|
258
259
|
.description('Displays the current public machine IP addresses.')
|
|
259
|
-
.action(
|
|
260
|
-
const ipList = ips
|
|
261
|
-
? ips
|
|
262
|
-
.split(',')
|
|
263
|
-
.map((i) => i.trim())
|
|
264
|
-
.filter(Boolean)
|
|
265
|
-
: [];
|
|
266
|
-
|
|
267
|
-
if (options.banIngressAdd) {
|
|
268
|
-
return ipList.forEach((ip) => Dns.banIngress(ip));
|
|
269
|
-
}
|
|
270
|
-
if (options.banIngressRemove) {
|
|
271
|
-
return ipList.forEach((ip) => Dns.unbanIngress(ip));
|
|
272
|
-
}
|
|
273
|
-
if (options.banIngressList) {
|
|
274
|
-
return Dns.listBannedIngress();
|
|
275
|
-
}
|
|
276
|
-
if (options.banIngressClear) {
|
|
277
|
-
return Dns.clearBannedIngress();
|
|
278
|
-
}
|
|
279
|
-
|
|
280
|
-
if (options.banEgressAdd) {
|
|
281
|
-
return ipList.forEach((ip) => Dns.banEgress(ip));
|
|
282
|
-
}
|
|
283
|
-
if (options.banEgressRemove) {
|
|
284
|
-
return ipList.forEach((ip) => Dns.unbanEgress(ip));
|
|
285
|
-
}
|
|
286
|
-
if (options.banEgressList) {
|
|
287
|
-
return Dns.listBannedEgress();
|
|
288
|
-
}
|
|
289
|
-
if (options.banEgressClear) {
|
|
290
|
-
return Dns.clearBannedEgress();
|
|
291
|
-
}
|
|
292
|
-
|
|
293
|
-
if (options.banBothAdd) {
|
|
294
|
-
return ipList.forEach((ip) => {
|
|
295
|
-
Dns.banIngress(ip);
|
|
296
|
-
Dns.banEgress(ip);
|
|
297
|
-
});
|
|
298
|
-
}
|
|
299
|
-
if (options.banBothRemove) {
|
|
300
|
-
return ipList.forEach((ip) => {
|
|
301
|
-
Dns.unbanIngress(ip);
|
|
302
|
-
Dns.unbanEgress(ip);
|
|
303
|
-
});
|
|
304
|
-
}
|
|
305
|
-
|
|
306
|
-
const ip = await Dns.getPublicIp();
|
|
307
|
-
if (options.copy) return pbcopy(ip);
|
|
308
|
-
return console.log(ip);
|
|
309
|
-
});
|
|
260
|
+
.action(Dns.ipDispatcher);
|
|
310
261
|
|
|
311
262
|
// 'cluster' command: Manage Kubernetes clusters
|
|
312
263
|
program
|
|
@@ -412,37 +363,41 @@ program
|
|
|
412
363
|
if (args[1].init) return Underpost.secret[args[0]].init();
|
|
413
364
|
});
|
|
414
365
|
|
|
415
|
-
// '
|
|
366
|
+
// 'image'
|
|
416
367
|
program
|
|
417
|
-
.command('
|
|
368
|
+
.command('image')
|
|
369
|
+
.option(
|
|
370
|
+
'--build',
|
|
371
|
+
'Builds a Docker image using Podman, optionally saves it as a tar archive, and loads it into a specified Kubernetes cluster (Kind, Kubeadm, or K3s).',
|
|
372
|
+
)
|
|
373
|
+
.option('--ls', 'Lists all available Underpost Dockerfile images.')
|
|
374
|
+
.option('--rm <image-id>', 'Removes specified Underpost Dockerfile images.')
|
|
418
375
|
.option('--path [path]', 'The path to the Dockerfile directory.')
|
|
419
376
|
.option('--image-name [image-name]', 'Sets a custom name for the Docker image.')
|
|
420
377
|
.option('--image-path [image-path]', 'Sets the output path for the tar image archive.')
|
|
421
378
|
.option('--dockerfile-name [dockerfile-name]', 'Sets a custom name for the Dockerfile.')
|
|
422
379
|
.option('--podman-save', 'Exports the built image as a tar file using Podman.')
|
|
423
|
-
.option('--
|
|
424
|
-
.option('--
|
|
380
|
+
.option('--pull-base', 'Pulls base images and builds a "rockylinux9-underpost" image.')
|
|
381
|
+
.option('--spec', 'Get current cached list of container images used by all pods')
|
|
382
|
+
.option('--namespace <namespace>', 'Kubernetes namespace for image operations (defaults to "default").')
|
|
383
|
+
.option('--kind', 'Set kind cluster env image context management.')
|
|
384
|
+
.option('--kubeadm', 'Set kubeadm cluster env image context management.')
|
|
385
|
+
.option('--k3s', 'Set k3s cluster env image context management.')
|
|
386
|
+
.option('--node-name', 'Set node name for kubeadm or k3s cluster env image context management.')
|
|
425
387
|
.option('--secrets', 'Includes Dockerfile environment secrets during the build.')
|
|
426
388
|
.option('--secrets-path [secrets-path]', 'Specifies a custom path for Dockerfile environment secrets.')
|
|
427
389
|
.option('--reset', 'Performs a build without using the cache.')
|
|
428
390
|
.option('--dev', 'Use development mode.')
|
|
429
|
-
.option('--
|
|
430
|
-
.description(
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
.option('--kind-load', 'Imports the pulled image into a Kind cluster.')
|
|
440
|
-
.option('--kubeadm-load', 'Imports the pulled image into a Kubeadm cluster.')
|
|
441
|
-
.option('--version', 'Sets a custom version for the base images.')
|
|
442
|
-
.option('--k3s-load', 'Loads the image into a K3s cluster.')
|
|
443
|
-
.option('--dev', 'Use development mode.')
|
|
444
|
-
.description('Pulls required Underpost Dockerfile base images and optionally loads them into clusters.')
|
|
445
|
-
.action(Underpost.image.dockerfile.pullBaseImages);
|
|
391
|
+
.option('--pull-dockerhub <dockerhub-image>', 'Sets a custom Docker Hub image for base image pulls.')
|
|
392
|
+
.description('Manages Docker images, including building, saving, and loading into Kubernetes clusters.')
|
|
393
|
+
.action(async (options) => {
|
|
394
|
+
if (options.rm) Underpost.image.rm({ ...options, imageName: options.rm });
|
|
395
|
+
if (options.ls) Underpost.image.list({ ...options, log: true });
|
|
396
|
+
if (options.pullBase) Underpost.image.pullBaseImages(options);
|
|
397
|
+
if (options.build) Underpost.image.build(options);
|
|
398
|
+
if (options.pullDockerhub)
|
|
399
|
+
Underpost.image.pullDockerHubImage({ ...options, dockerhubImage: options.pullDockerhub });
|
|
400
|
+
});
|
|
446
401
|
|
|
447
402
|
// 'install' command: Fast import npm dependencies
|
|
448
403
|
program
|
|
@@ -472,10 +427,14 @@ program
|
|
|
472
427
|
.option('--drop', 'Drops the specified databases or collections before importing.')
|
|
473
428
|
.option('--preserveUUID', 'Preserves UUIDs during database import operations.')
|
|
474
429
|
.option('--git', 'Enables Git integration for backup version control (clone, pull, commit, push to GitHub).')
|
|
430
|
+
.option('--force-clone', 'Forces cloning of the Git repository, overwriting local changes.')
|
|
475
431
|
.option('--hosts <hosts>', 'Comma-separated list of database hosts to filter operations.')
|
|
476
432
|
.option('--paths <paths>', 'Comma-separated list of paths to filter database operations.')
|
|
477
433
|
.option('--ns <ns-name>', 'Kubernetes namespace context for database operations (defaults to "default").')
|
|
478
|
-
.option(
|
|
434
|
+
.option(
|
|
435
|
+
'--macro-rollback-export <n-commits-reset>',
|
|
436
|
+
'Exports a macro rollback script that reverts the last n commits (Git integration required).',
|
|
437
|
+
)
|
|
479
438
|
.description(
|
|
480
439
|
'Manages database operations with support for MariaDB and MongoDB, including import/export, multi-pod targeting, and Git integration.',
|
|
481
440
|
)
|
|
@@ -564,9 +523,10 @@ program
|
|
|
564
523
|
.option('--ms-interval <ms-interval>', 'Sets a custom millisecond interval for monitoring checks.')
|
|
565
524
|
.option('--now', 'Executes the monitor script immediately.')
|
|
566
525
|
.option('--single', 'Disables recurrence, running the monitor script only once.')
|
|
567
|
-
.option('--replicas <replicas>', 'Sets a custom number of replicas for monitoring.')
|
|
526
|
+
.option('--replicas <replicas>', 'Sets a custom number of replicas for monitoring. Defaults to 1.')
|
|
568
527
|
.option('--type <type>', 'Sets a custom monitor type.')
|
|
569
528
|
.option('--sync', 'Synchronizes with current proxy deployments and traffic configurations.')
|
|
529
|
+
.option('--namespace <namespace>', 'Sets the Kubernetes namespace for the deployment. Defaults to "default".')
|
|
570
530
|
.description('Manages health server monitoring for specified deployments.')
|
|
571
531
|
.action(Underpost.monitor.callback);
|
|
572
532
|
|
|
@@ -589,13 +549,18 @@ program
|
|
|
589
549
|
.option('--keys-list', 'Lists all ssh keys from current private keys file storage.')
|
|
590
550
|
.option('--hosts-list', 'Lists all ssh hosts from current private keys file storage.')
|
|
591
551
|
.option('--disable-password', 'Disables password authentication for the SSH session.')
|
|
552
|
+
.option('--key-test', 'Tests the SSH key using ssh-keygen.')
|
|
553
|
+
.option('--stop', 'Stops the SSH service.')
|
|
554
|
+
.option('--status', 'Checks the status of the SSH service.')
|
|
555
|
+
.option('--connect-uri', 'Displays the connection URI.')
|
|
556
|
+
.option('--copy', 'Copies the connection URI to clipboard.')
|
|
592
557
|
.action(Underpost.ssh.callback);
|
|
593
558
|
|
|
594
559
|
// 'run' command: Run a script
|
|
595
560
|
program
|
|
596
561
|
.command('run')
|
|
597
562
|
.argument('<runner-id>', `The runner ID to run. Options: ${Object.keys(UnderpostRun.RUNNERS).join(', ')}.`)
|
|
598
|
-
.argument('[path]', 'The
|
|
563
|
+
.argument('[path]', 'The input value, identifier, or path for the operation.')
|
|
599
564
|
.option('--command <command-array>', 'Array of commands to run.')
|
|
600
565
|
.option('--args <args-array>', 'Array of arguments to pass to the command.')
|
|
601
566
|
.option('--dev', 'Sets the development context environment for the script.')
|
|
@@ -622,9 +587,10 @@ program
|
|
|
622
587
|
'Optional: Specifies a comma-separated list of key-value pairs for labels (e.g., "app=my-app,env=prod").',
|
|
623
588
|
)
|
|
624
589
|
.option('--claim-name <name>', 'Optional: Specifies the claim name for volume mounting in deploy-job.')
|
|
625
|
-
.option(
|
|
626
|
-
|
|
627
|
-
|
|
590
|
+
.option(
|
|
591
|
+
'--kind-type <kind-type>',
|
|
592
|
+
'Specifies the kind of Kubernetes resource (e.g., Job, Deployment) for deploy-job.',
|
|
593
|
+
)
|
|
628
594
|
.option('--force', 'Forces operation, overriding any warnings or conflicts.')
|
|
629
595
|
.option('--tls', 'Enables TLS for the runner execution.')
|
|
630
596
|
.option('--reset', 'Resets the runner state before execution.')
|
|
@@ -642,7 +608,17 @@ program
|
|
|
642
608
|
.option('--expose', 'Enables service exposure for the runner execution.')
|
|
643
609
|
.option('--conf-server-path <conf-server-path>', 'Sets a custom configuration server path.')
|
|
644
610
|
.option('--underpost-root <underpost-root>', 'Sets a custom Underpost root path.')
|
|
645
|
-
.
|
|
611
|
+
.option('--cron-jobs <jobs>', 'Comma-separated list of cron jobs to run before executing the script.')
|
|
612
|
+
.option('--timezone <timezone>', 'Sets the timezone for the runner execution.')
|
|
613
|
+
.option('--kubeadm', 'Sets the kubeadm cluster context for the runner execution.')
|
|
614
|
+
.option('--k3s', 'Sets the k3s cluster context for the runner execution.')
|
|
615
|
+
.option('--kind', 'Sets the kind cluster context for the runner execution.')
|
|
616
|
+
.option('--log-type <log-type>', 'Sets the log type for the runner execution.')
|
|
617
|
+
.option('--deploy-id <deploy-id>', 'Sets deploy id context for the runner execution.')
|
|
618
|
+
.option('--user <user>', 'Sets user context for the runner execution.')
|
|
619
|
+
.option('--hosts <hosts>', 'Comma-separated list of hosts for the runner execution.')
|
|
620
|
+
.option('--instance-id <instance-id>', 'Sets instance id context for the runner execution.')
|
|
621
|
+
.description('Runs specified scripts using various runners.')
|
|
646
622
|
.action(UnderpostRun.API.callback);
|
|
647
623
|
|
|
648
624
|
// 'lxd' command: LXD management
|
|
@@ -674,7 +650,10 @@ program
|
|
|
674
650
|
'--delete-expose <vm-name-ports>',
|
|
675
651
|
'Removes exposed ports on a VM (e.g., "k8s-control:80,443"). Multiple VM-port pairs can be comma-separated.',
|
|
676
652
|
)
|
|
677
|
-
.option('--
|
|
653
|
+
.option('--workflow-id <workflow-id>', 'Sets the workflow ID context for LXD operations.')
|
|
654
|
+
.option('--vm-id <vm-id>', 'Sets the VM ID context for LXD operations.')
|
|
655
|
+
.option('--deploy-id <deploy-id>', 'Sets the deployment ID context for LXD operations.')
|
|
656
|
+
.option('--namespace <namespace>', 'Kubernetes namespace for LXD operations (defaults to "default").')
|
|
678
657
|
.description('Manages LXD containers and virtual machines.')
|
|
679
658
|
.action(UnderpostLxd.API.callback);
|
|
680
659
|
|