underpost 2.99.6 → 2.99.7
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/ghpkg.ci.yml +10 -25
- package/.github/workflows/npmpkg.ci.yml +13 -2
- package/CHANGELOG.md +496 -0
- package/README.md +3 -3
- package/bin/deploy.js +13 -3
- package/cli.md +46 -28
- package/jsdoc.json +26 -5
- package/manifests/cronjobs/dd-cron/dd-cron-backup.yaml +9 -2
- package/manifests/cronjobs/dd-cron/dd-cron-dns.yaml +9 -2
- package/manifests/deployment/dd-default-development/deployment.yaml +2 -2
- package/manifests/deployment/dd-test-development/deployment.yaml +2 -2
- package/package.json +1 -2
- package/src/cli/baremetal.js +8 -322
- package/src/cli/cloud-init.js +2 -2
- package/src/cli/index.js +12 -1
- package/src/cli/repository.js +166 -13
- package/src/cli/run.js +16 -42
- package/src/cli/ssh.js +1 -1
- package/src/cli/system.js +332 -0
- package/src/db/DataBaseProvider.js +3 -3
- package/src/db/mariadb/MariaDB.js +3 -3
- package/src/db/mongo/MongooseDB.js +3 -3
- package/src/index.js +17 -5
- package/src/mailer/EmailRender.js +3 -3
- package/src/mailer/MailerProvider.js +4 -4
- package/src/server/backup.js +15 -4
- package/src/server/client-build-docs.js +28 -2
- package/src/server/conf.js +6 -5
- package/src/server/cron.js +48 -38
- package/src/server/dns.js +0 -8
package/src/cli/run.js
CHANGED
|
@@ -345,6 +345,7 @@ class UnderpostRun {
|
|
|
345
345
|
*/
|
|
346
346
|
'template-deploy': (path = '', options = DEFAULT_OPTION) => {
|
|
347
347
|
const baseCommand = options.dev ? 'node bin' : 'underpost';
|
|
348
|
+
const message = shellExec(`node bin cmt --changelog --changelog-no-hash`, { silent: true, stdout: true }).trim();
|
|
348
349
|
shellExec(`${baseCommand} run clean`);
|
|
349
350
|
shellExec(
|
|
350
351
|
`${baseCommand} push ./engine-private ${options.force ? '-f ' : ''}${
|
|
@@ -353,9 +354,23 @@ class UnderpostRun {
|
|
|
353
354
|
);
|
|
354
355
|
shellCd('/home/dd/engine');
|
|
355
356
|
shellExec(`git reset`);
|
|
357
|
+
function replaceNthNewline(str, n, replacement = ' ') {
|
|
358
|
+
let count = 0;
|
|
359
|
+
return str.replace(/\r\n?|\n/g, (match) => {
|
|
360
|
+
count++;
|
|
361
|
+
return count === n ? replacement : match;
|
|
362
|
+
});
|
|
363
|
+
}
|
|
356
364
|
shellExec(
|
|
357
365
|
`${baseCommand} cmt . --empty ci package-pwa-microservices-template${
|
|
358
366
|
path.startsWith('sync') ? `-${path}` : ''
|
|
367
|
+
}${
|
|
368
|
+
message
|
|
369
|
+
? ` "${replaceNthNewline(
|
|
370
|
+
message.replaceAll('"', '').replaceAll('`', '').replaceAll('#', '').replaceAll('- ', ''),
|
|
371
|
+
2,
|
|
372
|
+
)}"`
|
|
373
|
+
: ''
|
|
359
374
|
}`,
|
|
360
375
|
);
|
|
361
376
|
shellExec(`${baseCommand} push . ${options.force ? '-f ' : ''}${process.env.GITHUB_USERNAME}/engine`);
|
|
@@ -508,21 +523,7 @@ class UnderpostRun {
|
|
|
508
523
|
if (!validVersion) throw new Error('Version mismatch');
|
|
509
524
|
}
|
|
510
525
|
if (options.timezone !== 'none') shellExec(`${baseCommand} run${baseClusterCommand} tz`);
|
|
511
|
-
if (options.deployIdCronJobs !== 'none')
|
|
512
|
-
const cronClusterFlag = options.k3s
|
|
513
|
-
? ' --k3s'
|
|
514
|
-
: options.kind
|
|
515
|
-
? ' --kind'
|
|
516
|
-
: options.kubeadm
|
|
517
|
-
? ' --kubeadm'
|
|
518
|
-
: '';
|
|
519
|
-
const cronCmdFlag = options.cmdCronJobs ? ` --cmd-cron-jobs "${options.cmdCronJobs}"` : '';
|
|
520
|
-
const cronCreateJobNowFlag = options.createJobNow ? ' --create-job-now' : '';
|
|
521
|
-
const cronDryRunFlag = options.dryRun ? ' --dry-run' : '';
|
|
522
|
-
shellExec(
|
|
523
|
-
`${baseCommand} run${baseClusterCommand} cron${cronClusterFlag}${cronCmdFlag}${cronCreateJobNowFlag}${cronDryRunFlag}${options.deployIdCronJobs ? ` ${options.deployIdCronJobs}` : ''}`,
|
|
524
|
-
);
|
|
525
|
-
}
|
|
526
|
+
if (options.deployIdCronJobs !== 'none') shellExec(`node bin cron --dev --setup-start --apply`);
|
|
526
527
|
}
|
|
527
528
|
|
|
528
529
|
const currentTraffic = isDeployRunnerContext(path, options)
|
|
@@ -728,33 +729,6 @@ class UnderpostRun {
|
|
|
728
729
|
shellExec(`sudo timedatectl set-timezone ${tz}`);
|
|
729
730
|
},
|
|
730
731
|
|
|
731
|
-
/**
|
|
732
|
-
* @method cron
|
|
733
|
-
* @description Sets up cron jobs using `underpost cron --setup-start` command, which likely configures scheduled tasks for the application.
|
|
734
|
-
* @param {string} path - The input value, identifier, or path for the operation.
|
|
735
|
-
* @param {Object} options - The default underpost runner options for customizing workflow
|
|
736
|
-
* @memberof UnderpostRun
|
|
737
|
-
*/
|
|
738
|
-
cron: (path, options = DEFAULT_OPTION) => {
|
|
739
|
-
const baseCommand = options.dev ? 'node bin' : 'underpost';
|
|
740
|
-
const devFlag = options.dev ? ' --dev' : '';
|
|
741
|
-
const gitFlag = options.git ? ' --git' : '';
|
|
742
|
-
const namespaceFlag =
|
|
743
|
-
options.namespace && options.namespace !== 'default' ? ` --namespace ${options.namespace}` : '';
|
|
744
|
-
const imageFlag = options.image ? ` --image ${options.image}` : '';
|
|
745
|
-
const cmdFlag = options.cmdCronJobs ? ` --cmd "${options.cmdCronJobs}"` : '';
|
|
746
|
-
const ddCronPath = './engine-private/deploy/dd.cron';
|
|
747
|
-
const defaultDeployId = !path && fs.existsSync(ddCronPath) ? fs.readFileSync(ddCronPath, 'utf8').trim() : '';
|
|
748
|
-
const setupStartId = path || defaultDeployId;
|
|
749
|
-
const setupStart = setupStartId ? ` --setup-start ${setupStartId} --apply` : '';
|
|
750
|
-
const clusterFlag = options.k3s ? ' --k3s' : options.kind ? ' --kind' : options.kubeadm ? ' --kubeadm' : '';
|
|
751
|
-
const createJobNowFlag = options.createJobNow ? ' --create-job-now' : '';
|
|
752
|
-
const dryRunFlag = options.dryRun ? ' --dry-run' : '';
|
|
753
|
-
shellExec(
|
|
754
|
-
`${baseCommand} cron${devFlag}${gitFlag}${namespaceFlag}${imageFlag}${cmdFlag}${clusterFlag}${createJobNowFlag}${dryRunFlag}${setupStart}`,
|
|
755
|
-
);
|
|
756
|
-
},
|
|
757
|
-
|
|
758
732
|
/**
|
|
759
733
|
* @method get-proxy
|
|
760
734
|
* @description Retrieves and logs the HTTPProxy resources in the specified namespace using `kubectl get HTTPProxy`.
|
package/src/cli/ssh.js
CHANGED
|
@@ -536,7 +536,7 @@ SSH_KEY=$(node bin config get --plain DEFAULT_SSH_KEY_PATH)
|
|
|
536
536
|
|
|
537
537
|
chmod 600 "$SSH_KEY"
|
|
538
538
|
|
|
539
|
-
ssh -i "$SSH_KEY" -o BatchMode=yes "$REMOTE_USER@$REMOTE_HOST" -p $REMOTE_PORT sh <<EOF
|
|
539
|
+
ssh -i "$SSH_KEY" -o BatchMode=yes -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null "$REMOTE_USER@$REMOTE_HOST" -p $REMOTE_PORT sh <<EOF
|
|
540
540
|
${cd ? `cd ${cd}` : ''}
|
|
541
541
|
${useSudo ? `sudo -n -- /bin/bash -lc "${remoteCommand}"` : remoteCommand}
|
|
542
542
|
EOF
|
|
@@ -0,0 +1,332 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* System provisioning module for Underpost CLI.
|
|
3
|
+
* This module provides a factory for generating shell commands to provision systems based on their OS type.
|
|
4
|
+
* It includes methods for basic system setup, user creation, timezone configuration, and keyboard layout settings.
|
|
5
|
+
* The provisioning steps are tailored for both Ubuntu and Rocky Linux distributions, ensuring compatibility and ease of use.
|
|
6
|
+
* @module src/cli/system.js
|
|
7
|
+
* @namespace UnderpostSystemProvisionig
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
import fs from 'fs-extra';
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* @class UnderpostSystemProvisionig
|
|
14
|
+
* @description A class that encapsulates the system provisioning logic for Underpost CLI. It provides a structured way to generate shell commands for provisioning systems based on their OS type, including Ubuntu and Rocky Linux. The class contains a static API object with a factory for different provisioning steps, making it easy to extend and maintain.
|
|
15
|
+
* @memberof UnderpostSystemProvisionig
|
|
16
|
+
*/
|
|
17
|
+
class UnderpostSystemProvisionig {
|
|
18
|
+
static API = {
|
|
19
|
+
/**
|
|
20
|
+
* @property {object} factory
|
|
21
|
+
* @description A factory object containing functions for system provisioning based on OS type.
|
|
22
|
+
* Each OS type (e.g., 'ubuntu') provides methods for base system setup, user creation,
|
|
23
|
+
* timezone configuration, and keyboard layout settings.
|
|
24
|
+
* @memberof UnderpostSystemProvisionig
|
|
25
|
+
*/
|
|
26
|
+
factory: {
|
|
27
|
+
/**
|
|
28
|
+
* @property {object} ubuntu
|
|
29
|
+
* @description Provisioning steps for Ubuntu-based systems.
|
|
30
|
+
* @memberof UnderpostSystemProvisionig
|
|
31
|
+
*/
|
|
32
|
+
ubuntu: {
|
|
33
|
+
/**
|
|
34
|
+
* @method base
|
|
35
|
+
* @description Generates shell commands for basic Ubuntu system provisioning.
|
|
36
|
+
* This includes updating package lists, installing essential build tools,
|
|
37
|
+
* kernel modules, cloud-init, SSH server, and other core utilities.
|
|
38
|
+
* @param {object} params - The parameters for the function.
|
|
39
|
+
* @memberof UnderpostSystemProvisionig
|
|
40
|
+
* @returns {string[]} An array of shell commands.
|
|
41
|
+
*/
|
|
42
|
+
base: () => [
|
|
43
|
+
// Configure APT sources for Ubuntu ports
|
|
44
|
+
`cat <<SOURCES | tee /etc/apt/sources.list
|
|
45
|
+
deb http://ports.ubuntu.com/ubuntu-ports noble main restricted universe multiverse
|
|
46
|
+
deb http://ports.ubuntu.com/ubuntu-ports noble-updates main restricted universe multiverse
|
|
47
|
+
deb http://ports.ubuntu.com/ubuntu-ports noble-security main restricted universe multiverse
|
|
48
|
+
SOURCES`,
|
|
49
|
+
|
|
50
|
+
// Update package lists and perform a full system upgrade
|
|
51
|
+
`apt update -qq`,
|
|
52
|
+
`apt -y full-upgrade`,
|
|
53
|
+
|
|
54
|
+
// Install all essential packages in one consolidated step
|
|
55
|
+
`DEBIAN_FRONTEND=noninteractive apt install -y build-essential xinput x11-xkb-utils usbutils uuid-runtime linux-image-generic systemd-sysv openssh-server sudo locales udev util-linux iproute2 netplan.io ca-certificates curl wget chrony apt-utils tzdata kmod keyboard-configuration console-setup iputils-ping`,
|
|
56
|
+
|
|
57
|
+
// Ensure systemd is the init system
|
|
58
|
+
`ln -sf /lib/systemd/systemd /sbin/init`,
|
|
59
|
+
|
|
60
|
+
// Clean up
|
|
61
|
+
`apt-get clean`,
|
|
62
|
+
],
|
|
63
|
+
/**
|
|
64
|
+
* @method user
|
|
65
|
+
* @description Generates shell commands for creating a root user and configuring SSH access.
|
|
66
|
+
* This is a critical security step for initial access to the provisioned system.
|
|
67
|
+
* @memberof UnderpostSystemProvisionig
|
|
68
|
+
* @returns {string[]} An array of shell commands.
|
|
69
|
+
*/
|
|
70
|
+
user: () => [
|
|
71
|
+
`useradd -m -s /bin/bash -G sudo root`, // Create a root user with bash shell and sudo privileges.
|
|
72
|
+
`echo 'root:root' | chpasswd`, // Set a default password for the root user (consider more secure methods for production).
|
|
73
|
+
`mkdir -p /home/root/.ssh`, // Create .ssh directory for authorized keys.
|
|
74
|
+
// Add the public SSH key to authorized_keys for passwordless login.
|
|
75
|
+
`echo '${fs.readFileSync(
|
|
76
|
+
`/home/dd/engine/engine-private/deploy/id_rsa.pub`,
|
|
77
|
+
'utf8',
|
|
78
|
+
)}' > /home/root/.ssh/authorized_keys`,
|
|
79
|
+
`chown -R root /home/root/.ssh`, // Set ownership for security.
|
|
80
|
+
`chmod 700 /home/root/.ssh`, // Set permissions for the .ssh directory.
|
|
81
|
+
`chmod 600 /home/root/.ssh/authorized_keys`, // Set permissions for authorized_keys.
|
|
82
|
+
],
|
|
83
|
+
/**
|
|
84
|
+
* @method timezone
|
|
85
|
+
* @description Generates shell commands for configuring the system timezone and Chrony (NTP client).
|
|
86
|
+
* Accurate time synchronization is essential for logging, security, and distributed systems.
|
|
87
|
+
* @param {object} params - The parameters for the function.
|
|
88
|
+
* @param {string} params.timezone - The timezone string (e.g., 'America/New_York').
|
|
89
|
+
* @param {string} params.chronyConfPath - The path to the Chrony configuration file.
|
|
90
|
+
* @param {string} [alias='chrony'] - The alias for the chrony service.
|
|
91
|
+
* @memberof UnderpostSystemProvisionig
|
|
92
|
+
* @returns {string[]} An array of shell commands.
|
|
93
|
+
*/
|
|
94
|
+
timezone: ({ timezone, chronyConfPath }, alias = 'chrony') => [
|
|
95
|
+
`export DEBIAN_FRONTEND=noninteractive`, // Set non-interactive mode for Debian packages.
|
|
96
|
+
`ln -fs /usr/share/zoneinfo/${timezone} /etc/localtime`, // Symlink timezone.
|
|
97
|
+
`sudo dpkg-reconfigure --frontend noninteractive tzdata`, // Reconfigure timezone data.
|
|
98
|
+
`sudo timedatectl set-timezone ${timezone}`, // Set timezone using timedatectl.
|
|
99
|
+
`sudo timedatectl set-ntp true`, // Enable NTP synchronization.
|
|
100
|
+
|
|
101
|
+
// Write the Chrony configuration file.
|
|
102
|
+
`echo '
|
|
103
|
+
# Use public servers from the pool.ntp.org project.
|
|
104
|
+
# Please consider joining the pool (http://www.pool.ntp.org/join.html).
|
|
105
|
+
# pool 2.pool.ntp.org iburst
|
|
106
|
+
server ${process.env.MAAS_NTP_SERVER} iburst
|
|
107
|
+
|
|
108
|
+
# Record the rate at which the system clock gains/losses time.
|
|
109
|
+
driftfile /var/lib/chrony/drift
|
|
110
|
+
|
|
111
|
+
# Allow the system clock to be stepped in the first three updates
|
|
112
|
+
# if its offset is larger than 1 second.
|
|
113
|
+
makestep 1.0 3
|
|
114
|
+
|
|
115
|
+
# Enable kernel synchronization of the real-time clock (RTC).
|
|
116
|
+
rtcsync
|
|
117
|
+
|
|
118
|
+
# Enable hardware timestamping on all interfaces that support it.
|
|
119
|
+
#hwtimestamp *
|
|
120
|
+
|
|
121
|
+
# Increase the minimum number of selectable sources required to adjust
|
|
122
|
+
# the system clock.
|
|
123
|
+
#minsources 2
|
|
124
|
+
|
|
125
|
+
# Allow NTP client access from local network.
|
|
126
|
+
#allow 192.168.0.0/16
|
|
127
|
+
|
|
128
|
+
# Serve time even if not synchronized to a time source.
|
|
129
|
+
#local stratum 10
|
|
130
|
+
|
|
131
|
+
# Specify file containing keys for NTP authentication.
|
|
132
|
+
keyfile /etc/chrony.keys
|
|
133
|
+
|
|
134
|
+
# Get TAI-UTC offset and leap seconds from the system tz database.
|
|
135
|
+
leapsectz right/UTC
|
|
136
|
+
|
|
137
|
+
# Specify directory for log files.
|
|
138
|
+
logdir /var/log/chrony
|
|
139
|
+
|
|
140
|
+
# Select which information is logged.
|
|
141
|
+
#log measurements statistics tracking
|
|
142
|
+
' > ${chronyConfPath}`,
|
|
143
|
+
`systemctl stop ${alias}`, // Stop Chrony service before reconfiguring.
|
|
144
|
+
|
|
145
|
+
// Enable, restart, and check status of Chrony service.
|
|
146
|
+
`sudo systemctl enable --now ${alias}`,
|
|
147
|
+
`sudo systemctl restart ${alias}`,
|
|
148
|
+
|
|
149
|
+
// Wait for chrony to synchronize
|
|
150
|
+
`echo "Waiting for chrony to synchronize..."`,
|
|
151
|
+
`for i in {1..30}; do chronyc tracking | grep -q "Leap status : Normal" && break || sleep 2; done`,
|
|
152
|
+
|
|
153
|
+
`sudo systemctl status ${alias}`,
|
|
154
|
+
|
|
155
|
+
// Verify Chrony synchronization.
|
|
156
|
+
`chronyc sources`,
|
|
157
|
+
`chronyc tracking`,
|
|
158
|
+
|
|
159
|
+
`chronyc sourcestats -v`, // Display source statistics.
|
|
160
|
+
`timedatectl status`, // Display current time and date settings.
|
|
161
|
+
],
|
|
162
|
+
/**
|
|
163
|
+
* @method keyboard
|
|
164
|
+
* @description Generates shell commands for configuring the keyboard layout.
|
|
165
|
+
* This ensures correct input behavior on the provisioned system.
|
|
166
|
+
* @param {string} [keyCode='en'] - The keyboard layout code (e.g., 'en', 'es').
|
|
167
|
+
* @memberof UnderpostSystemProvisionig
|
|
168
|
+
* @returns {string[]} An array of shell commands.
|
|
169
|
+
*/
|
|
170
|
+
keyboard: (keyCode = 'en') => [
|
|
171
|
+
`sudo locale-gen en_US.UTF-8`,
|
|
172
|
+
`sudo update-locale LANG=en_US.UTF-8`,
|
|
173
|
+
`sudo sed -i 's/XKBLAYOUT="us"/XKBLAYOUT="${keyCode}"/' /etc/default/keyboard`,
|
|
174
|
+
`sudo dpkg-reconfigure --frontend noninteractive keyboard-configuration`,
|
|
175
|
+
`sudo systemctl restart keyboard-setup.service`,
|
|
176
|
+
],
|
|
177
|
+
},
|
|
178
|
+
/**
|
|
179
|
+
* @property {object} rocky
|
|
180
|
+
* @description Provisioning steps for Rocky Linux-based systems.
|
|
181
|
+
* @memberof UnderpostSystemProvisionig
|
|
182
|
+
*/
|
|
183
|
+
rocky: {
|
|
184
|
+
/**
|
|
185
|
+
* @method base
|
|
186
|
+
* @description Generates shell commands for basic Rocky Linux system provisioning.
|
|
187
|
+
* This includes installing Node.js, npm, and underpost CLI tools.
|
|
188
|
+
* @param {object} params - The parameters for the function.
|
|
189
|
+
* @memberof UnderpostSystemProvisionig
|
|
190
|
+
* @returns {string[]} An array of shell commands.
|
|
191
|
+
*/
|
|
192
|
+
base: () => [
|
|
193
|
+
// Update system and install EPEL repository
|
|
194
|
+
`dnf -y update`,
|
|
195
|
+
`dnf -y install epel-release`,
|
|
196
|
+
|
|
197
|
+
// Install essential system tools (avoiding duplicates from container packages)
|
|
198
|
+
`dnf -y install --allowerasing bzip2 openssh-server nano vim-enhanced less openssl-devel git gnupg2 libnsl perl`,
|
|
199
|
+
`dnf clean all`,
|
|
200
|
+
|
|
201
|
+
// Install Node.js
|
|
202
|
+
`curl -fsSL https://rpm.nodesource.com/setup_24.x | bash -`,
|
|
203
|
+
`dnf install -y nodejs`,
|
|
204
|
+
`dnf clean all`,
|
|
205
|
+
|
|
206
|
+
// Verify Node.js and npm versions
|
|
207
|
+
`node --version`,
|
|
208
|
+
`npm --version`,
|
|
209
|
+
|
|
210
|
+
// Install underpost ci/cd cli
|
|
211
|
+
`npm install -g underpost`,
|
|
212
|
+
`underpost --version`,
|
|
213
|
+
],
|
|
214
|
+
/**
|
|
215
|
+
* @method user
|
|
216
|
+
* @description Generates shell commands for creating a root user and configuring SSH access on Rocky Linux.
|
|
217
|
+
* This is a critical security step for initial access to the provisioned system.
|
|
218
|
+
* @memberof UnderpostSystemProvisionig
|
|
219
|
+
* @returns {string[]} An array of shell commands.
|
|
220
|
+
*/
|
|
221
|
+
user: () => [
|
|
222
|
+
`useradd -m -s /bin/bash -G wheel root`, // Create a root user with bash shell and wheel group (sudo on RHEL)
|
|
223
|
+
`echo 'root:root' | chpasswd`, // Set a default password for the root user
|
|
224
|
+
`mkdir -p /home/root/.ssh`, // Create .ssh directory for authorized keys
|
|
225
|
+
// Add the public SSH key to authorized_keys for passwordless login
|
|
226
|
+
`echo '${fs.readFileSync(
|
|
227
|
+
`/home/dd/engine/engine-private/deploy/id_rsa.pub`,
|
|
228
|
+
'utf8',
|
|
229
|
+
)}' > /home/root/.ssh/authorized_keys`,
|
|
230
|
+
`chown -R root:root /home/root/.ssh`, // Set ownership for security
|
|
231
|
+
`chmod 700 /home/root/.ssh`, // Set permissions for the .ssh directory
|
|
232
|
+
`chmod 600 /home/root/.ssh/authorized_keys`, // Set permissions for authorized_keys
|
|
233
|
+
],
|
|
234
|
+
/**
|
|
235
|
+
* @method timezone
|
|
236
|
+
* @description Generates shell commands for configuring the system timezone on Rocky Linux.
|
|
237
|
+
* @param {object} params - The parameters for the function.
|
|
238
|
+
* @param {string} params.timezone - The timezone string (e.g., 'America/Santiago').
|
|
239
|
+
* @param {string} params.chronyConfPath - The path to the Chrony configuration file (optional).
|
|
240
|
+
* @memberof UnderpostSystemProvisionig
|
|
241
|
+
* @returns {string[]} An array of shell commands.
|
|
242
|
+
*/
|
|
243
|
+
timezone: ({ timezone, chronyConfPath = '/etc/chrony.conf' }) => [
|
|
244
|
+
// Set system timezone using both methods (for chroot and running system)
|
|
245
|
+
`ln -sf /usr/share/zoneinfo/${timezone} /etc/localtime`,
|
|
246
|
+
`echo '${timezone}' > /etc/timezone`,
|
|
247
|
+
`timedatectl set-timezone ${timezone} 2>/dev/null`,
|
|
248
|
+
|
|
249
|
+
// Configure chrony with local NTP server and common NTP pools
|
|
250
|
+
`echo '# Local NTP server' > ${chronyConfPath}`,
|
|
251
|
+
`echo 'server 192.168.1.1 iburst prefer' >> ${chronyConfPath}`,
|
|
252
|
+
`echo '' >> ${chronyConfPath}`,
|
|
253
|
+
`echo '# Fallback public NTP servers' >> ${chronyConfPath}`,
|
|
254
|
+
`echo 'server 0.pool.ntp.org iburst' >> ${chronyConfPath}`,
|
|
255
|
+
`echo 'server 1.pool.ntp.org iburst' >> ${chronyConfPath}`,
|
|
256
|
+
`echo 'server 2.pool.ntp.org iburst' >> ${chronyConfPath}`,
|
|
257
|
+
`echo 'server 3.pool.ntp.org iburst' >> ${chronyConfPath}`,
|
|
258
|
+
`echo '' >> ${chronyConfPath}`,
|
|
259
|
+
`echo '# Configuration' >> ${chronyConfPath}`,
|
|
260
|
+
`echo 'driftfile /var/lib/chrony/drift' >> ${chronyConfPath}`,
|
|
261
|
+
`echo 'makestep 1.0 3' >> ${chronyConfPath}`,
|
|
262
|
+
`echo 'rtcsync' >> ${chronyConfPath}`,
|
|
263
|
+
`echo 'logdir /var/log/chrony' >> ${chronyConfPath}`,
|
|
264
|
+
|
|
265
|
+
// Enable chronyd to start on boot
|
|
266
|
+
`systemctl enable chronyd 2>/dev/null`,
|
|
267
|
+
|
|
268
|
+
// Create systemd link for boot (works in chroot)
|
|
269
|
+
`mkdir -p /etc/systemd/system/multi-user.target.wants`,
|
|
270
|
+
`ln -sf /usr/lib/systemd/system/chronyd.service /etc/systemd/system/multi-user.target.wants/chronyd.service 2>/dev/null`,
|
|
271
|
+
|
|
272
|
+
// Start chronyd if systemd is running
|
|
273
|
+
`systemctl start chronyd 2>/dev/null`,
|
|
274
|
+
|
|
275
|
+
// Restart chronyd to apply configuration
|
|
276
|
+
`systemctl restart chronyd 2>/dev/null`,
|
|
277
|
+
|
|
278
|
+
// Force immediate time synchronization (only if chronyd is running)
|
|
279
|
+
`chronyc makestep 2>/dev/null`,
|
|
280
|
+
|
|
281
|
+
// Verify timezone configuration
|
|
282
|
+
`ls -l /etc/localtime`,
|
|
283
|
+
`cat /etc/timezone || echo 'No /etc/timezone file'`,
|
|
284
|
+
`timedatectl status 2>/dev/null || echo 'Timezone set to ${timezone} (timedatectl not available in chroot)'`,
|
|
285
|
+
`chronyc tracking 2>/dev/null || echo 'Chrony configured but not running (will start on boot)'`,
|
|
286
|
+
],
|
|
287
|
+
/**
|
|
288
|
+
* @method keyboard
|
|
289
|
+
* @description Generates shell commands for configuring the keyboard layout on Rocky Linux.
|
|
290
|
+
* This uses localectl to set the keyboard layout for both console and X11.
|
|
291
|
+
* @param {string} [keyCode='us'] - The keyboard layout code (e.g., 'us', 'es').
|
|
292
|
+
* @memberof UnderpostSystemProvisionig
|
|
293
|
+
* @returns {string[]} An array of shell commands.
|
|
294
|
+
*/
|
|
295
|
+
keyboard: (keyCode = 'us') => [
|
|
296
|
+
// Configure vconsole.conf for console keyboard layout (persistent)
|
|
297
|
+
`echo 'KEYMAP=${keyCode}' > /etc/vconsole.conf`,
|
|
298
|
+
`echo 'FONT=latarcyrheb-sun16' >> /etc/vconsole.conf`,
|
|
299
|
+
|
|
300
|
+
// Configure locale.conf for system locale
|
|
301
|
+
`echo 'LANG=en_US.UTF-8' > /etc/locale.conf`,
|
|
302
|
+
`echo 'LC_ALL=en_US.UTF-8' >> /etc/locale.conf`,
|
|
303
|
+
|
|
304
|
+
// Set keyboard layout using localectl (works if systemd is running)
|
|
305
|
+
`localectl set-locale LANG=en_US.UTF-8 2>/dev/null`,
|
|
306
|
+
`localectl set-keymap ${keyCode} 2>/dev/null`,
|
|
307
|
+
`localectl set-x11-keymap ${keyCode} 2>/dev/null`,
|
|
308
|
+
|
|
309
|
+
// Configure X11 keyboard layout file directly
|
|
310
|
+
`mkdir -p /etc/X11/xorg.conf.d`,
|
|
311
|
+
`echo 'Section "InputClass"' > /etc/X11/xorg.conf.d/00-keyboard.conf`,
|
|
312
|
+
`echo ' Identifier "system-keyboard"' >> /etc/X11/xorg.conf.d/00-keyboard.conf`,
|
|
313
|
+
`echo ' MatchIsKeyboard "on"' >> /etc/X11/xorg.conf.d/00-keyboard.conf`,
|
|
314
|
+
`echo ' Option "XkbLayout" "${keyCode}"' >> /etc/X11/xorg.conf.d/00-keyboard.conf`,
|
|
315
|
+
`echo 'EndSection' >> /etc/X11/xorg.conf.d/00-keyboard.conf`,
|
|
316
|
+
|
|
317
|
+
// Load the keymap immediately (if not in chroot)
|
|
318
|
+
`loadkeys ${keyCode} 2>/dev/null || echo 'Keymap ${keyCode} configured (loadkeys not available in chroot)'`,
|
|
319
|
+
|
|
320
|
+
// Verify configuration
|
|
321
|
+
`echo 'Keyboard configuration files:'`,
|
|
322
|
+
`cat /etc/vconsole.conf`,
|
|
323
|
+
`cat /etc/locale.conf`,
|
|
324
|
+
`cat /etc/X11/xorg.conf.d/00-keyboard.conf 2>/dev/null || echo 'X11 config created'`,
|
|
325
|
+
`localectl status 2>/dev/null || echo 'Keyboard layout set to ${keyCode} (localectl not available in chroot)'`,
|
|
326
|
+
],
|
|
327
|
+
},
|
|
328
|
+
},
|
|
329
|
+
};
|
|
330
|
+
}
|
|
331
|
+
|
|
332
|
+
export default UnderpostSystemProvisionig;
|
|
@@ -4,7 +4,7 @@ import { loggerFactory } from '../server/logger.js';
|
|
|
4
4
|
/**
|
|
5
5
|
* Module for managing and loading various database connections (e.g., Mongoose, MariaDB).
|
|
6
6
|
* @module src/db/DataBaseProvider.js
|
|
7
|
-
* @namespace
|
|
7
|
+
* @namespace DataBaseProviderService
|
|
8
8
|
*/
|
|
9
9
|
|
|
10
10
|
const logger = loggerFactory(import.meta);
|
|
@@ -12,7 +12,7 @@ const logger = loggerFactory(import.meta);
|
|
|
12
12
|
/**
|
|
13
13
|
* @class
|
|
14
14
|
* @alias DataBaseProviderService
|
|
15
|
-
* @memberof
|
|
15
|
+
* @memberof DataBaseProviderService
|
|
16
16
|
* @classdesc Centralized service for loading, managing, and accessing multiple database connections
|
|
17
17
|
* based on application configuration (host, path, provider type).
|
|
18
18
|
*/
|
|
@@ -90,7 +90,7 @@ class DataBaseProviderService {
|
|
|
90
90
|
/**
|
|
91
91
|
* Singleton instance of the DataBaseProviderService class for backward compatibility.
|
|
92
92
|
* @alias DataBaseProvider
|
|
93
|
-
* @memberof
|
|
93
|
+
* @memberof DataBaseProviderService
|
|
94
94
|
* @type {DataBaseProviderService}
|
|
95
95
|
*/
|
|
96
96
|
const DataBaseProvider = new DataBaseProviderService();
|
|
@@ -5,7 +5,7 @@ import { loggerFactory } from '../../server/logger.js';
|
|
|
5
5
|
/**
|
|
6
6
|
* Module for interacting with MariaDB/MySQL databases using the mariadb connector.
|
|
7
7
|
* @module src/db/MariaDB.js
|
|
8
|
-
* @namespace
|
|
8
|
+
* @namespace MariaDBService
|
|
9
9
|
*/
|
|
10
10
|
|
|
11
11
|
const logger = loggerFactory(import.meta);
|
|
@@ -13,7 +13,7 @@ const logger = loggerFactory(import.meta);
|
|
|
13
13
|
/**
|
|
14
14
|
* @class
|
|
15
15
|
* @alias MariaDBService
|
|
16
|
-
* @memberof
|
|
16
|
+
* @memberof MariaDBService
|
|
17
17
|
* @classdesc Provides a simplified interface for executing queries against a MariaDB/MySQL database
|
|
18
18
|
* using a connection pool, ensuring connection management (acquisition and release).
|
|
19
19
|
*/
|
|
@@ -58,7 +58,7 @@ class MariaDBService {
|
|
|
58
58
|
/**
|
|
59
59
|
* Singleton instance of the MariaDBService class for backward compatibility.
|
|
60
60
|
* @alias MariaDB
|
|
61
|
-
* @memberof
|
|
61
|
+
* @memberof MariaDBService
|
|
62
62
|
* @type {MariaDBService}
|
|
63
63
|
*/
|
|
64
64
|
const MariaDB = new MariaDBService();
|
|
@@ -5,7 +5,7 @@ import { getCapVariableName } from '../../client/components/core/CommonJs.js';
|
|
|
5
5
|
/**
|
|
6
6
|
* Module for connecting to and loading models for a MongoDB database using Mongoose.
|
|
7
7
|
* @module src/db/MongooseDB.js
|
|
8
|
-
* @namespace
|
|
8
|
+
* @namespace MongooseDBService
|
|
9
9
|
*/
|
|
10
10
|
|
|
11
11
|
const logger = loggerFactory(import.meta);
|
|
@@ -13,7 +13,7 @@ const logger = loggerFactory(import.meta);
|
|
|
13
13
|
/**
|
|
14
14
|
* @class
|
|
15
15
|
* @alias MongooseDBService
|
|
16
|
-
* @memberof
|
|
16
|
+
* @memberof MongooseDBService
|
|
17
17
|
* @classdesc Manages the Mongoose connection lifecycle and dynamic loading of database models
|
|
18
18
|
* based on API configuration.
|
|
19
19
|
*/
|
|
@@ -66,7 +66,7 @@ class MongooseDBService {
|
|
|
66
66
|
/**
|
|
67
67
|
* Singleton instance of the MongooseDBService class for backward compatibility.
|
|
68
68
|
* @alias MongooseDB
|
|
69
|
-
* @memberof
|
|
69
|
+
* @memberof MongooseDBService
|
|
70
70
|
* @type {MongooseDBService}
|
|
71
71
|
*/
|
|
72
72
|
const MongooseDB = new MongooseDBService();
|
package/src/index.js
CHANGED
|
@@ -21,6 +21,7 @@ import UnderpostSecret from './cli/secrets.js';
|
|
|
21
21
|
import UnderpostSSH from './cli/ssh.js';
|
|
22
22
|
import UnderpostStatic from './cli/static.js';
|
|
23
23
|
import UnderpostTest from './cli/test.js';
|
|
24
|
+
import UnderpostSystemProvisionig from './cli/system.js';
|
|
24
25
|
|
|
25
26
|
import UnderpostDns from './server/dns.js';
|
|
26
27
|
import UnderpostBackup from './server/backup.js';
|
|
@@ -40,7 +41,7 @@ class Underpost {
|
|
|
40
41
|
* @type {String}
|
|
41
42
|
* @memberof Underpost
|
|
42
43
|
*/
|
|
43
|
-
static version = 'v2.99.
|
|
44
|
+
static version = 'v2.99.7';
|
|
44
45
|
|
|
45
46
|
/**
|
|
46
47
|
* Required Node.js major version
|
|
@@ -211,7 +212,17 @@ class Underpost {
|
|
|
211
212
|
}
|
|
212
213
|
|
|
213
214
|
/**
|
|
214
|
-
*
|
|
215
|
+
* System Provisioning cli API
|
|
216
|
+
* @static
|
|
217
|
+
* @type {UnderpostSystemProvisionig.API}
|
|
218
|
+
* @memberof Underpost
|
|
219
|
+
*/
|
|
220
|
+
static get system() {
|
|
221
|
+
return UnderpostSystemProvisionig.API;
|
|
222
|
+
}
|
|
223
|
+
|
|
224
|
+
/**
|
|
225
|
+
* Dns server API
|
|
215
226
|
* @static
|
|
216
227
|
* @type {UnderpostDns.API}
|
|
217
228
|
* @memberof Underpost
|
|
@@ -221,7 +232,7 @@ class Underpost {
|
|
|
221
232
|
}
|
|
222
233
|
|
|
223
234
|
/**
|
|
224
|
-
* BackUp
|
|
235
|
+
* BackUp server API
|
|
225
236
|
* @static
|
|
226
237
|
* @type {UnderpostBackup.API}
|
|
227
238
|
* @memberof Underpost
|
|
@@ -231,7 +242,7 @@ class Underpost {
|
|
|
231
242
|
}
|
|
232
243
|
|
|
233
244
|
/**
|
|
234
|
-
* Cron
|
|
245
|
+
* Cron server API
|
|
235
246
|
* @static
|
|
236
247
|
* @type {UnderpostCron.API}
|
|
237
248
|
* @memberof Underpost
|
|
@@ -241,7 +252,7 @@ class Underpost {
|
|
|
241
252
|
}
|
|
242
253
|
|
|
243
254
|
/**
|
|
244
|
-
* Start Up
|
|
255
|
+
* Start Up server API
|
|
245
256
|
* @static
|
|
246
257
|
* @type {UnderpostStartUp.API}
|
|
247
258
|
* @memberof Underpost
|
|
@@ -284,6 +295,7 @@ export {
|
|
|
284
295
|
UnderpostImage,
|
|
285
296
|
UnderpostStatic,
|
|
286
297
|
UnderpostLxd,
|
|
298
|
+
UnderpostKickStart,
|
|
287
299
|
UnderpostMonitor,
|
|
288
300
|
UnderpostRepository,
|
|
289
301
|
UnderpostRun,
|
|
@@ -3,13 +3,13 @@ import { ssrFactory } from '../server/ssr.js';
|
|
|
3
3
|
/**
|
|
4
4
|
* Module for handling the rendering and styling of HTML emails using SSR components.
|
|
5
5
|
* @module src/mailer/EmailRender.js
|
|
6
|
-
* @namespace
|
|
6
|
+
* @namespace EmailRenderService
|
|
7
7
|
*/
|
|
8
8
|
|
|
9
9
|
/**
|
|
10
10
|
* @class
|
|
11
11
|
* @alias EmailRenderService
|
|
12
|
-
* @memberof
|
|
12
|
+
* @memberof EmailRenderService
|
|
13
13
|
* @classdesc Utility class for managing CSS styles and rendering email templates using
|
|
14
14
|
* Server-Side Rendering (SSR) components.
|
|
15
15
|
*/
|
|
@@ -108,7 +108,7 @@ class EmailRenderService {
|
|
|
108
108
|
/**
|
|
109
109
|
* Singleton instance of the EmailRenderService class for backward compatibility.
|
|
110
110
|
* @alias EmailRender
|
|
111
|
-
* @memberof
|
|
111
|
+
* @memberof EmailRenderService
|
|
112
112
|
* @type {EmailRenderService}
|
|
113
113
|
*/
|
|
114
114
|
const EmailRender = new EmailRenderService();
|
|
@@ -5,7 +5,7 @@ import { EmailRender } from './EmailRender.js';
|
|
|
5
5
|
/**
|
|
6
6
|
* Module for configuring and sending emails using Nodemailer.
|
|
7
7
|
* @module src/mailer/MailerProvider.js
|
|
8
|
-
* @namespace
|
|
8
|
+
* @namespace MailerProviderService
|
|
9
9
|
*/
|
|
10
10
|
|
|
11
11
|
const logger = loggerFactory(import.meta);
|
|
@@ -27,13 +27,13 @@ const logger = loggerFactory(import.meta);
|
|
|
27
27
|
* @property {string} [host=''] - Application host for context.
|
|
28
28
|
* @property {string} [path=''] - Application path for context.
|
|
29
29
|
* @property {object.<string, string>} templates - Map of template keys to SSR component file names.
|
|
30
|
-
* @memberof
|
|
30
|
+
* @memberof MailerProviderService
|
|
31
31
|
*/
|
|
32
32
|
|
|
33
33
|
/**
|
|
34
34
|
* @class
|
|
35
35
|
* @alias MailerProviderService
|
|
36
|
-
* @memberof
|
|
36
|
+
* @memberof MailerProviderService
|
|
37
37
|
* @classdesc Manages multiple Nodemailer transporter instances and handles loading of
|
|
38
38
|
* email templates and sending emails.
|
|
39
39
|
*/
|
|
@@ -205,7 +205,7 @@ class MailerProviderService {
|
|
|
205
205
|
/**
|
|
206
206
|
* Singleton instance of the MailerProviderService class for backward compatibility.
|
|
207
207
|
* @alias MailerProvider
|
|
208
|
-
* @memberof
|
|
208
|
+
* @memberof MailerProviderService
|
|
209
209
|
* @type {MailerProviderService}
|
|
210
210
|
*/
|
|
211
211
|
const MailerProvider = new MailerProviderService();
|