@underpostnet/underpost 2.90.4 → 2.95.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/.github/workflows/pwa-microservices-template-page.cd.yml +5 -4
- package/.github/workflows/release.cd.yml +7 -7
- package/README.md +7 -8
- package/bin/build.js +6 -1
- package/bin/deploy.js +2 -196
- package/cli.md +154 -80
- 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/rocky-setup.sh +1 -0
- package/scripts/ssh-cluster-info.sh +4 -3
- package/src/cli/cluster.js +1 -1
- package/src/cli/db.js +1143 -201
- package/src/cli/deploy.js +93 -24
- package/src/cli/env.js +2 -2
- package/src/cli/image.js +198 -133
- package/src/cli/index.js +111 -44
- package/src/cli/lxd.js +73 -74
- package/src/cli/monitor.js +20 -9
- package/src/cli/repository.js +212 -5
- package/src/cli/run.js +207 -74
- package/src/cli/ssh.js +642 -14
- package/src/client/components/core/CommonJs.js +0 -1
- package/src/db/mongo/MongooseDB.js +5 -1
- 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 +242 -1
- package/src/server/process.js +6 -1
- package/src/server/start.js +2 -0
- 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/repository.js
CHANGED
|
@@ -10,8 +10,8 @@ import { pbcopy, shellCd, shellExec } from '../server/process.js';
|
|
|
10
10
|
import { actionInitLog, loggerFactory } from '../server/logger.js';
|
|
11
11
|
import fs from 'fs-extra';
|
|
12
12
|
import { getNpmRootPath } from '../server/conf.js';
|
|
13
|
-
import UnderpostStartUp from '../server/start.js';
|
|
14
13
|
import { Config } from '../server/conf.js';
|
|
14
|
+
import { DefaultConf } from '../../conf.js';
|
|
15
15
|
|
|
16
16
|
dotenv.config();
|
|
17
17
|
|
|
@@ -234,21 +234,154 @@ class UnderpostRepository {
|
|
|
234
234
|
/**
|
|
235
235
|
* Initializes a new Underpost repository, optionally setting up a deploy ID or sub-configuration.
|
|
236
236
|
* @param {string} [projectName=''] - The name of the project to create.
|
|
237
|
-
* @param {object} [options
|
|
237
|
+
* @param {object} [options] - Initialization options.
|
|
238
238
|
* @param {string} [options.deployId=''] - The deployment ID to set up.
|
|
239
239
|
* @param {string} [options.subConf=''] - The sub-configuration to create.
|
|
240
240
|
* @param {boolean} [options.cluster=false] - If true, sets up a clustered configuration.
|
|
241
241
|
* @param {boolean} [options.dev=false] - If true, uses development settings.
|
|
242
|
+
* @param {boolean} [options.buildRepos=false] - If true, creates the deployment repositories (engine-*, engine-*-private, engine-*-cron-backups).
|
|
243
|
+
* @param {boolean} [options.purge=false] - If true, removes the deploy ID conf and all related repositories (requires deployId).
|
|
244
|
+
* @param {boolean} [options.cleanTemplate=false] - If true, cleans the pwa-microservices-template build directory.
|
|
245
|
+
* @param {boolean} [options.build=false] - If true, builds the deployment to pwa-microservices-template (requires deployId).
|
|
246
|
+
* @param {boolean} [options.syncConf=false] - If true, syncs configuration to private repositories (requires deployId).
|
|
247
|
+
* @param {boolean} [options.defaultConf=false] - If true, updates the default configuration file (requires deployId).
|
|
248
|
+
* @param {string} [options.confWorkflowId=''] - If provided, uses this configuration workflow ID.
|
|
242
249
|
* @returns {Promise<boolean>} A promise that resolves when the initialization is complete.
|
|
243
250
|
* @memberof UnderpostRepository
|
|
244
251
|
*/
|
|
245
|
-
new(
|
|
252
|
+
new(
|
|
253
|
+
projectName,
|
|
254
|
+
options = {
|
|
255
|
+
deployId: '',
|
|
256
|
+
subConf: '',
|
|
257
|
+
cluster: false,
|
|
258
|
+
dev: false,
|
|
259
|
+
buildRepos: false,
|
|
260
|
+
purge: false,
|
|
261
|
+
cleanTemplate: false,
|
|
262
|
+
build: false,
|
|
263
|
+
syncConf: false,
|
|
264
|
+
defaultConf: false,
|
|
265
|
+
confWorkflowId: '',
|
|
266
|
+
},
|
|
267
|
+
) {
|
|
246
268
|
return new Promise(async (resolve, reject) => {
|
|
247
269
|
try {
|
|
248
270
|
await logger.setUpInfo();
|
|
249
271
|
actionInitLog();
|
|
272
|
+
|
|
273
|
+
// Handle cleanTemplate operation
|
|
274
|
+
if (options.cleanTemplate) {
|
|
275
|
+
logger.info('Cleaning build directory');
|
|
276
|
+
const basePath = '../pwa-microservices-template';
|
|
277
|
+
shellExec(`cd ${basePath} && git reset`);
|
|
278
|
+
shellExec(`cd ${basePath} && git checkout .`);
|
|
279
|
+
shellExec(`cd ${basePath} && git clean -f -d`);
|
|
280
|
+
logger.info('Build directory cleaned successfully');
|
|
281
|
+
return resolve(true);
|
|
282
|
+
}
|
|
283
|
+
|
|
284
|
+
// Handle defaultConf operation
|
|
285
|
+
if (options.defaultConf) {
|
|
286
|
+
UnderpostRepository.API.updateDefaultConf(options);
|
|
287
|
+
return resolve(true);
|
|
288
|
+
}
|
|
289
|
+
|
|
250
290
|
if (options.deployId) {
|
|
251
|
-
|
|
291
|
+
let deployId = options.deployId;
|
|
292
|
+
if (!deployId.startsWith('dd-')) deployId = `dd-${deployId}`;
|
|
293
|
+
// Handle purge operation
|
|
294
|
+
if (options.purge) {
|
|
295
|
+
logger.info(`Purging deploy ID: ${deployId}`);
|
|
296
|
+
|
|
297
|
+
const suffix = deployId.split('dd-')[1];
|
|
298
|
+
const repoName = `engine-${suffix}`;
|
|
299
|
+
const privateRepoName = `engine-${suffix}-private`;
|
|
300
|
+
const cronRepoName = `engine-${suffix}-cron-backups`;
|
|
301
|
+
const confFolder = `./engine-private/conf/${deployId}`;
|
|
302
|
+
|
|
303
|
+
// Remove conf folder
|
|
304
|
+
if (fs.existsSync(confFolder)) {
|
|
305
|
+
fs.removeSync(confFolder);
|
|
306
|
+
logger.info(`Removed conf folder: ${confFolder}`);
|
|
307
|
+
} else {
|
|
308
|
+
logger.warn(`Conf folder not found: ${confFolder}`);
|
|
309
|
+
}
|
|
310
|
+
|
|
311
|
+
// Remove repositories
|
|
312
|
+
const repos = [
|
|
313
|
+
{ path: `../${repoName}`, name: repoName },
|
|
314
|
+
{ path: `../${privateRepoName}`, name: privateRepoName },
|
|
315
|
+
{ path: `../${cronRepoName}`, name: cronRepoName },
|
|
316
|
+
];
|
|
317
|
+
|
|
318
|
+
for (const repo of repos) {
|
|
319
|
+
if (fs.existsSync(repo.path)) {
|
|
320
|
+
fs.removeSync(repo.path);
|
|
321
|
+
logger.info(`Removed repository: ${repo.path}`);
|
|
322
|
+
} else {
|
|
323
|
+
logger.warn(`Repository not found: ${repo.path}`);
|
|
324
|
+
}
|
|
325
|
+
}
|
|
326
|
+
|
|
327
|
+
logger.info(`Successfully purged deploy ID: ${deployId}`);
|
|
328
|
+
return resolve(true);
|
|
329
|
+
}
|
|
330
|
+
|
|
331
|
+
// Handle sync-conf operation
|
|
332
|
+
if (options.syncConf) {
|
|
333
|
+
logger.info(`Syncing configuration for deploy ID: ${deployId}`);
|
|
334
|
+
shellExec(`node bin/build ${deployId} conf`);
|
|
335
|
+
logger.info('Configuration synced successfully');
|
|
336
|
+
return resolve(true);
|
|
337
|
+
}
|
|
338
|
+
|
|
339
|
+
// Handle build operation
|
|
340
|
+
if (options.build) {
|
|
341
|
+
logger.info(`Building deployment for deploy ID: ${deployId}`);
|
|
342
|
+
shellExec(`node bin/build ${deployId}`);
|
|
343
|
+
logger.info('Build completed successfully');
|
|
344
|
+
return resolve(true);
|
|
345
|
+
}
|
|
346
|
+
|
|
347
|
+
// Normal deploy ID factory operation
|
|
348
|
+
const { deployId: normalizedDeployId } = Config.deployIdFactory(deployId, options);
|
|
349
|
+
|
|
350
|
+
if (options.buildRepos) {
|
|
351
|
+
const suffix = normalizedDeployId.split('dd-')[1];
|
|
352
|
+
const repoName = `engine-${suffix}`;
|
|
353
|
+
const privateRepoName = `engine-${suffix}-private`;
|
|
354
|
+
const cronRepoName = `engine-${suffix}-cron-backups`;
|
|
355
|
+
const repos = [
|
|
356
|
+
{ path: `../${repoName}`, name: repoName },
|
|
357
|
+
{ path: `../${privateRepoName}`, name: privateRepoName },
|
|
358
|
+
{ path: `../${cronRepoName}`, name: cronRepoName },
|
|
359
|
+
];
|
|
360
|
+
|
|
361
|
+
const username = process.env.GITHUB_USERNAME;
|
|
362
|
+
const token = process.env.GITHUB_TOKEN;
|
|
363
|
+
|
|
364
|
+
if (!username) {
|
|
365
|
+
logger.error('GITHUB_USERNAME environment variable not set');
|
|
366
|
+
return reject(false);
|
|
367
|
+
}
|
|
368
|
+
|
|
369
|
+
for (const repo of repos) {
|
|
370
|
+
if (!fs.existsSync(repo.path)) {
|
|
371
|
+
fs.mkdirSync(repo.path, { recursive: true });
|
|
372
|
+
logger.info(`Created repository directory: ${repo.path}`);
|
|
373
|
+
}
|
|
374
|
+
|
|
375
|
+
// Initialize git repository
|
|
376
|
+
shellExec(`cd ${repo.path} && git init`, { disableLog: false });
|
|
377
|
+
logger.info(`Initialized git repository in: ${repo.path}`);
|
|
378
|
+
|
|
379
|
+
// Add remote origin
|
|
380
|
+
const remoteUrl = `https://${token ? `${token}@` : ''}github.com/${username}/${repo.name}.git`;
|
|
381
|
+
shellExec(`cd ${repo.path} && git remote add origin ${remoteUrl}`, { disableLog: false });
|
|
382
|
+
logger.info(`Added remote origin for: ${repo.name}`);
|
|
383
|
+
}
|
|
384
|
+
}
|
|
252
385
|
return resolve(true);
|
|
253
386
|
}
|
|
254
387
|
if (projectName) {
|
|
@@ -326,7 +459,9 @@ class UnderpostRepository {
|
|
|
326
459
|
const privateRepoPath = `../${privateRepoName}`;
|
|
327
460
|
if (fs.existsSync(privateRepoPath)) fs.removeSync(privateRepoPath);
|
|
328
461
|
shellExec(`cd .. && underpost clone ${process.env.GITHUB_USERNAME}/${privateRepoName}`);
|
|
329
|
-
shellExec(`cd ${privateRepoPath} && underpost pull . ${process.env.GITHUB_USERNAME}/${privateRepoName}
|
|
462
|
+
shellExec(`cd ${privateRepoPath} && underpost pull . ${process.env.GITHUB_USERNAME}/${privateRepoName}`, {
|
|
463
|
+
silent: true,
|
|
464
|
+
});
|
|
330
465
|
shellExec(`underpost run secret`);
|
|
331
466
|
shellExec(`underpost run underpost-config`);
|
|
332
467
|
const packageJsonDeploy = JSON.parse(fs.readFileSync(`./engine-private/conf/${deployId}/package.json`, 'utf8'));
|
|
@@ -380,6 +515,78 @@ Prevent build private config repo.`,
|
|
|
380
515
|
return line;
|
|
381
516
|
});
|
|
382
517
|
},
|
|
518
|
+
/**
|
|
519
|
+
* Updates the default configuration file based on the provided options.
|
|
520
|
+
* @param {object} [options={ deployId: '' }] - The options for updating the configuration.
|
|
521
|
+
* @param {string} [options.deployId=''] - The deployment ID to use for configuration.
|
|
522
|
+
* @param {string} [options.confWorkflowId=''] - The configuration workflow ID to use.
|
|
523
|
+
* @memberof UnderpostRepository
|
|
524
|
+
*/
|
|
525
|
+
updateDefaultConf(options = { deployId: '', confWorkflowId: '' }) {
|
|
526
|
+
const defaultServer = DefaultConf.server['default.net']['/'];
|
|
527
|
+
let { deployId, confWorkflowId } = options;
|
|
528
|
+
let defaultConf = false;
|
|
529
|
+
|
|
530
|
+
// Custom workflow configurations
|
|
531
|
+
if (confWorkflowId)
|
|
532
|
+
switch (confWorkflowId) {
|
|
533
|
+
case 'dd-github-pages': {
|
|
534
|
+
const host = `${process.env.GITHUB_USERNAME ? process.env.GITHUB_USERNAME : 'underpostnet'}.github.io`;
|
|
535
|
+
const path = '/pwa-microservices-template-ghpkg';
|
|
536
|
+
DefaultConf.server = {
|
|
537
|
+
[host]: { [path]: defaultServer },
|
|
538
|
+
};
|
|
539
|
+
DefaultConf.server[host][path].apiBaseProxyPath = '/';
|
|
540
|
+
DefaultConf.server[host][path].apiBaseHost = 'www.nexodev.org';
|
|
541
|
+
defaultConf = true;
|
|
542
|
+
break;
|
|
543
|
+
}
|
|
544
|
+
case 'template': {
|
|
545
|
+
const host = 'default.net';
|
|
546
|
+
const path = '/';
|
|
547
|
+
DefaultConf.server[host][path].valkey = {
|
|
548
|
+
port: 6379,
|
|
549
|
+
host: 'valkey-service.default.svc.cluster.local',
|
|
550
|
+
};
|
|
551
|
+
// mongodb-0.mongodb-service
|
|
552
|
+
DefaultConf.server[host][path].db.host = 'mongodb://mongodb-service:27017';
|
|
553
|
+
defaultConf = true;
|
|
554
|
+
break;
|
|
555
|
+
}
|
|
556
|
+
default:
|
|
557
|
+
logger.error(`Unknown confWorkflowId: ${confWorkflowId}.`);
|
|
558
|
+
return;
|
|
559
|
+
}
|
|
560
|
+
else if (deployId && fs.existsSync(`./engine-private/conf/${deployId}`)) {
|
|
561
|
+
DefaultConf.client = JSON.parse(fs.readFileSync(`./engine-private/conf/${deployId}/conf.client.json`, 'utf8'));
|
|
562
|
+
DefaultConf.server = JSON.parse(fs.readFileSync(`./engine-private/conf/${deployId}/conf.server.json`, 'utf8'));
|
|
563
|
+
DefaultConf.ssr = JSON.parse(fs.readFileSync(`./engine-private/conf/${deployId}/conf.ssr.json`, 'utf8'));
|
|
564
|
+
// DefaultConf.cron = JSON.parse(fs.readFileSync(`./engine-private/conf/${deployId}/conf.cron.json`, 'utf8'));
|
|
565
|
+
|
|
566
|
+
for (const host of Object.keys(DefaultConf.server)) {
|
|
567
|
+
for (const path of Object.keys(DefaultConf.server[host])) {
|
|
568
|
+
DefaultConf.server[host][path].db = defaultServer.db;
|
|
569
|
+
DefaultConf.server[host][path].mailer = defaultServer.mailer;
|
|
570
|
+
|
|
571
|
+
delete DefaultConf.server[host][path]._wp_client;
|
|
572
|
+
delete DefaultConf.server[host][path]._wp_git;
|
|
573
|
+
delete DefaultConf.server[host][path]._wp_directory;
|
|
574
|
+
delete DefaultConf.server[host][path].wp;
|
|
575
|
+
delete DefaultConf.server[host][path].git;
|
|
576
|
+
delete DefaultConf.server[host][path].directory;
|
|
577
|
+
}
|
|
578
|
+
}
|
|
579
|
+
} else
|
|
580
|
+
logger.warn(
|
|
581
|
+
`Deploy ID configuration not found: ./engine-private/conf/${deployId}, using default configuration.`,
|
|
582
|
+
);
|
|
583
|
+
const sepRender = '/**/';
|
|
584
|
+
const confRawPaths = fs.readFileSync('./conf.js', 'utf8').split(sepRender);
|
|
585
|
+
confRawPaths[1] = `${JSON.stringify(DefaultConf)};`;
|
|
586
|
+
const targetConfPath = `./conf${defaultConf ? '' : `.${deployId}`}.js`;
|
|
587
|
+
fs.writeFileSync(targetConfPath, confRawPaths.join(sepRender), 'utf8');
|
|
588
|
+
shellExec(`prettier --write ${targetConfPath}`);
|
|
589
|
+
},
|
|
383
590
|
};
|
|
384
591
|
}
|
|
385
592
|
|