underpost 2.8.811 → 2.8.814

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/README.md CHANGED
@@ -68,7 +68,7 @@ Run dev client server
68
68
  npm run dev
69
69
  ```
70
70
  <!-- -->
71
- ## underpost ci/cd cli v2.8.811
71
+ ## underpost ci/cd cli v2.8.814
72
72
 
73
73
  ### Usage: `underpost [options] [command]`
74
74
  ```
package/bin/deploy.js CHANGED
@@ -51,23 +51,21 @@ logger.info('argv', process.argv);
51
51
 
52
52
  const [exe, dir, operator] = process.argv;
53
53
 
54
- const updateVirtualRoot = async ({ IP_ADDRESS, architecture, host, nfsHostPath, ipaddr, update }) => {
54
+ const updateVirtualRoot = async ({ IP_ADDRESS, architecture, host, nfsHostPath, ipaddr, update, gatewayip }) => {
55
55
  // <consumer_key>:<consumer_token>:<secret>
56
56
  const MAAS_API_TOKEN = shellExec(`maas apikey --username ${process.env.MAAS_ADMIN_USERNAME}`, {
57
57
  stdout: true,
58
58
  }).trim();
59
- const [consumer_key, consumer_token, secret] = MAAS_API_TOKEN.split(`\n`)[1].split(':');
59
+ const [consumer_key, consumer_token, secret] = MAAS_API_TOKEN.split(`\n`)[0].split(':');
60
60
  const chronyConfPath = `/etc/chrony/chrony.conf`;
61
61
  const timezone = 'America/New_York';
62
- const timeZoneSteps = [
63
- `apt-get update`,
64
62
 
63
+ const timeZoneSteps = [
65
64
  `export DEBIAN_FRONTEND=noninteractive`,
66
65
 
67
66
  `ln -fs /usr/share/zoneinfo/${timezone} /etc/localtime`,
68
67
 
69
- `DEBIAN_FRONTEND=noninteractive apt-get install -y tzdata`,
70
- `dpkg-reconfigure --frontend noninteractive tzdata`,
68
+ `sudo dpkg-reconfigure --frontend noninteractive tzdata`,
71
69
  ];
72
70
  const keyboardSteps = [
73
71
  `sudo locale-gen en_US.UTF-8`,
@@ -76,49 +74,27 @@ const updateVirtualRoot = async ({ IP_ADDRESS, architecture, host, nfsHostPath,
76
74
  `sudo dpkg-reconfigure --frontend noninteractive keyboard-configuration`,
77
75
  `sudo systemctl restart keyboard-setup.service`,
78
76
  ];
77
+ // # - ${JSON.stringify([...timeZoneSteps, ...chronySetUp(chronyConfPath)])}
79
78
  const installSteps = [
80
- `apt update`,
81
- `apt install -y cloud-init systemd-sysv openssh-server sudo locales udev util-linux systemd-sysv iproute2 netplan.io ca-certificates curl wget chrony keyboard-configuration`,
82
- `ln -sf /lib/systemd/systemd /sbin/init`,
83
-
84
- `echo 'deb http://ports.ubuntu.com/ubuntu-ports noble main restricted universe multiverse
79
+ `cat <<EOF | tee /etc/apt/sources.list
80
+ deb http://ports.ubuntu.com/ubuntu-ports noble main restricted universe multiverse
85
81
  deb http://ports.ubuntu.com/ubuntu-ports noble-updates main restricted universe multiverse
86
82
  deb http://ports.ubuntu.com/ubuntu-ports noble-security main restricted universe multiverse
83
+ EOF`,
87
84
 
88
- # Uncomment the following lines if you also need source packages (for building from source)
89
- # deb-src http://ports.ubuntu.com/ubuntu-ports noble main restricted universe multiverse
90
- # deb-src http://ports.ubuntu.com/ubuntu-ports noble-updates main restricted universe multiverse
91
- # deb-src http://ports.ubuntu.com/ubuntu-ports noble-security main restricted universe multiverse
92
- ' > /etc/apt/sources.list`,
93
- `apt update`,
85
+ `apt update -qq`,
94
86
  `apt -y full-upgrade`,
87
+ `apt install -y xinput x11-xkb-utils usbutils`,
95
88
  // `apt install -y cloud-init=25.1.2-0ubuntu0~24.04.1`,
89
+ `apt install -y cloud-init systemd-sysv openssh-server sudo locales udev util-linux systemd-sysv iproute2 netplan.io ca-certificates curl wget chrony`,
90
+ `ln -sf /lib/systemd/systemd /sbin/init`,
96
91
 
97
- `systemctl enable ssh`,
98
-
99
- `apt update -qq`,
100
- `apt install -y xinput x11-xkb-utils usbutils`,
92
+ `apt-get update`,
93
+ `DEBIAN_FRONTEND=noninteractive apt-get install -y apt-utils`,
94
+ `DEBIAN_FRONTEND=noninteractive apt-get install -y tzdata kmod keyboard-configuration console-setup`,
101
95
  ];
102
96
 
103
97
  let steps = [
104
- // `date -s "${shellExec(`date '+%Y-%m-%d %H:%M:%S'`, { stdout: true }).trim()}"`,
105
- // `date`,
106
-
107
- ...timeZoneSteps,
108
- ...chronySetUp(chronyConfPath),
109
-
110
- // Create root user
111
- `useradd -m -s /bin/bash -G sudo root`,
112
- `echo 'root:root' | chpasswd`,
113
- `mkdir -p /home/root/.ssh`,
114
- `echo '${fs.readFileSync(
115
- `/home/dd/engine/engine-private/deploy/id_rsa.pub`,
116
- 'utf8',
117
- )}' > /home/root/.ssh/authorized_keys`,
118
- `chown -R root /home/root/.ssh`,
119
- `chmod 700 /home/root/.ssh`,
120
- `chmod 600 /home/root/.ssh/authorized_keys`,
121
-
122
98
  // Configure cloud-init for MAAS
123
99
  `cat <<EOF_MAAS_CFG > /etc/cloud/cloud.cfg.d/90_maas.cfg
124
100
  #cloud-config
@@ -192,6 +168,9 @@ network:
192
168
  dhcp4: true
193
169
  addresses:
194
170
  - ${ipaddr}/24
171
+ # routes:
172
+ # - to: default
173
+ # via: ${gatewayip}
195
174
 
196
175
  # chpasswd:
197
176
  # expire: false
@@ -209,40 +188,48 @@ bootcmd:
209
188
  - echo "- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -"
210
189
  - echo "Init bootcmd"
211
190
  - echo "- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -"
212
- # - ${JSON.stringify([...timeZoneSteps, ...chronySetUp(chronyConfPath)])}
213
191
  runcmd:
214
192
  - echo "- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -"
215
193
  - echo "Init runcmd"
216
194
  - echo "- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -"
217
195
  EOF_MAAS_CFG`,
218
- ...keyboardSteps,
219
196
  ];
220
197
 
221
- if (!update) {
222
- steps = installSteps.concat(steps);
223
- }
198
+ const runSteps = (steps = []) => {
199
+ const script = steps
200
+ .map(
201
+ (s, i) => `echo "step ${i + 1}/${steps.length}: ${s.split('\n')[0]}"
202
+ ${s}`,
203
+ )
204
+ .join('\n');
224
205
 
225
- shellExec(`sudo chroot ${nfsHostPath} /usr/bin/qemu-aarch64-static /bin/bash <<'EOF'
226
- ${steps
227
- .map(
228
- (s, i) => `echo "step ${i + 1}/${steps.length}: ${s.split('\n')[0]}"
229
- ${s}
230
- `,
231
- )
232
- .join(``)}
233
- EOF`);
206
+ const cmd = `sudo chroot ${nfsHostPath} /usr/bin/qemu-aarch64-static /bin/bash <<'EOF_OUTER'
207
+ ${script}
208
+ EOF_OUTER`;
234
209
 
235
- shellExec(`sudo chroot ${nfsHostPath} /usr/bin/qemu-aarch64-static /bin/bash <<'EOF'
236
- echo "nameserver ${process.env.MAAS_DNS}" | tee /etc/resolv.conf > /dev/null
237
- apt update
238
- EOF`);
210
+ shellExec(cmd);
211
+ };
239
212
 
240
213
  if (update) {
214
+ // --reboot
241
215
  shellExec(`sudo chroot ${nfsHostPath} /usr/bin/qemu-aarch64-static /bin/bash <<'EOF'
242
- sudo cloud-init clean --logs --reboot
216
+ sudo cloud-init clean --logs --seed --configs all --machine-id
217
+ sudo rm -rf /var/lib/cloud/*
243
218
  EOF`);
244
- fs.writeFileSync(`${nfsHostPath}/var/log/cloud-init.log`, '', 'utf8');
245
219
 
220
+ if (fs.existsSync(`${nfsHostPath}/var/log/`)) {
221
+ fs.writeFileSync(`${nfsHostPath}/var/log/cloud-init.log`, '', 'utf8');
222
+ fs.writeFileSync(`${nfsHostPath}/var/log/cloud-init-output.log`, '', 'utf8');
223
+ }
224
+
225
+ runSteps(steps);
226
+ } else {
227
+ runSteps(installSteps.concat(steps));
228
+
229
+ shellExec(`sudo chroot ${nfsHostPath} /usr/bin/qemu-aarch64-static /bin/bash <<'EOF'
230
+ echo "nameserver ${process.env.MAAS_DNS}" | tee /etc/resolv.conf > /dev/null
231
+ apt update
232
+ EOF`);
246
233
  fs.writeFileSync(
247
234
  `${nfsHostPath}/dns.sh`,
248
235
  `rm /etc/resolv.conf
@@ -250,6 +237,41 @@ echo 'nameserver 8.8.8.8' > /run/systemd/resolve/stub-resolv.conf
250
237
  ln -sf /run/systemd/resolve/stub-resolv.conf /etc/resolv.conf`,
251
238
  'utf8',
252
239
  );
240
+
241
+ runSteps([
242
+ // `date -s "${shellExec(`date '+%Y-%m-%d %H:%M:%S'`, { stdout: true }).trim()}"`,
243
+ // `date`,
244
+ ...timeZoneSteps,
245
+ ...chronySetUp(chronyConfPath),
246
+ ...keyboardSteps,
247
+ ]);
248
+
249
+ runSteps([
250
+ `useradd -m -s /bin/bash -G sudo root`,
251
+ `echo 'root:root' | chpasswd`,
252
+ `mkdir -p /home/root/.ssh`,
253
+ `echo '${fs.readFileSync(
254
+ `/home/dd/engine/engine-private/deploy/id_rsa.pub`,
255
+ 'utf8',
256
+ )}' > /home/root/.ssh/authorized_keys`,
257
+ `chown -R root /home/root/.ssh`,
258
+ `chmod 700 /home/root/.ssh`,
259
+ `chmod 600 /home/root/.ssh/authorized_keys`,
260
+ ]);
261
+ }
262
+
263
+ logger.info('Check virtual root user config');
264
+ {
265
+ const cmd = `sudo chroot ${nfsHostPath} /usr/bin/qemu-aarch64-static /bin/bash <<'EOF_OUTER'
266
+ echo -e "\n=== Current date/time ==="
267
+ date '+%Y-%m-%d %H:%M:%S'
268
+ echo -e "\n=== Keyboard layout ==="
269
+ cat /etc/default/keyboard
270
+ echo -e "\n=== Registered users ==="
271
+ cut -d: -f1 /etc/passwd
272
+ EOF_OUTER`;
273
+
274
+ shellExec(cmd);
253
275
  }
254
276
  };
255
277
 
@@ -259,7 +281,7 @@ const chronySetUp = (path) => {
259
281
  # Use public servers from the pool.ntp.org project.
260
282
  # Please consider joining the pool (http://www.pool.ntp.org/join.html).
261
283
  # pool 2.pool.ntp.org iburst
262
- server ntp.ubuntu.com iburst
284
+ server ${process.env.MAAS_NTP_SERVER} iburst
263
285
 
264
286
  # Record the rate at which the system clock gains/losses time.
265
287
  driftfile /var/lib/chrony/drift
@@ -1751,7 +1773,6 @@ EOF`);
1751
1773
 
1752
1774
  switch (process.argv[3]) {
1753
1775
  case 'rpi4mb':
1754
- const resourceId = process.argv[4] ?? '12';
1755
1776
  tftpSubDir = '/rpi4mb';
1756
1777
  zipFirmwareFileName = `RPi4_UEFI_Firmware_v1.41.zip`;
1757
1778
  zipFirmwareName = zipFirmwareFileName.split('.zip')[0];
@@ -1763,7 +1784,7 @@ EOF`);
1763
1784
  await Downloader(zipFirmwareUrl, `../${zipFirmwareFileName}`);
1764
1785
  shellExec(`cd .. && mkdir ${zipFirmwareName} && cd ${zipFirmwareName} && unzip ../${zipFirmwareFileName}`);
1765
1786
  }
1766
- resource = resources.find((o) => o.id == resourceId);
1787
+ resource = resources.find((o) => o.architecture === 'arm64/ga-24.04' && o.name === 'ubuntu/noble');
1767
1788
  name = resource.name;
1768
1789
  architecture = resource.architecture;
1769
1790
  resource = resources.find((o) => o.name === name && o.architecture === architecture);
@@ -2078,8 +2099,9 @@ BOOT_ORDER=0x21`;
2078
2099
  newMachine = machineFactory(JSON.parse(newMachine));
2079
2100
  machines.push(newMachine);
2080
2101
  console.log(newMachine);
2102
+ // commissioning_scripts=90-verify-user.sh
2081
2103
  shellExec(
2082
- `maas ${process.env.MAAS_ADMIN_USERNAME} machine commission ${newMachine.system_id} enable_ssh=1 commissioning_scripts=90-verify-user.sh skip_bmc_config=1 skip_networking=1 skip_storage=1`,
2104
+ `maas ${process.env.MAAS_ADMIN_USERNAME} machine commission ${newMachine.system_id} enable_ssh=1 skip_bmc_config=1 skip_networking=1 skip_storage=1`,
2083
2105
  {
2084
2106
  silent: true,
2085
2107
  },
@@ -2185,6 +2207,7 @@ udp-port = 32766
2185
2207
  const host = process.argv[4];
2186
2208
  const nfsHostPath = `${process.env.NFS_EXPORT_PATH}/${host}`;
2187
2209
  const ipaddr = process.env.RPI4_IP;
2210
+ const gatewayip = process.env.GATEWAY_IP;
2188
2211
  await updateVirtualRoot({
2189
2212
  IP_ADDRESS,
2190
2213
  architecture,
@@ -2192,6 +2215,7 @@ udp-port = 32766
2192
2215
  nfsHostPath,
2193
2216
  ipaddr,
2194
2217
  update: true,
2218
+ gatewayip,
2195
2219
  });
2196
2220
  break;
2197
2221
  }
@@ -2201,6 +2225,7 @@ udp-port = 32766
2201
2225
  const architecture = process.argv[3];
2202
2226
  const host = process.argv[4];
2203
2227
  const nfsHostPath = `${process.env.NFS_EXPORT_PATH}/${host}`;
2228
+ const gatewayip = process.env.GATEWAY_IP;
2204
2229
  shellExec(`sudo dnf install -y iptables-legacy`);
2205
2230
  shellExec(`sudo dnf install -y debootstrap`);
2206
2231
  shellExec(`sudo dnf install kernel-modules-extra-$(uname -r)`);
@@ -2279,6 +2304,7 @@ EOF`);
2279
2304
  host,
2280
2305
  nfsHostPath,
2281
2306
  ipaddr,
2307
+ gatewayip,
2282
2308
  });
2283
2309
 
2284
2310
  break;
@@ -2302,6 +2328,7 @@ EOF`);
2302
2328
  shellExec(`sudo umount ${nfsHostPath}/sys`);
2303
2329
  shellExec(`sudo umount ${nfsHostPath}/dev/pts`);
2304
2330
  shellExec(`sudo umount ${nfsHostPath}/dev`);
2331
+ shellExec(`sudo umount ${nfsHostPath}/run`);
2305
2332
  // shellExec(`sudo umount ${nfsHostPath}/lib/modules`);
2306
2333
  break;
2307
2334
  }
package/cli.md CHANGED
@@ -1,4 +1,4 @@
1
- ## underpost ci/cd cli v2.8.811
1
+ ## underpost ci/cd cli v2.8.814
2
2
 
3
3
  ### Usage: `underpost [options] [command]`
4
4
  ```
@@ -58,7 +58,7 @@ services:
58
58
  cpus: '0.25'
59
59
  memory: 20M
60
60
  labels: # labels in Compose file instead of Dockerfile
61
- engine.version: '2.8.811'
61
+ engine.version: '2.8.814'
62
62
  networks:
63
63
  - load-balancer
64
64
 
@@ -17,7 +17,7 @@ spec:
17
17
  spec:
18
18
  containers:
19
19
  - name: dd-template-development-blue
20
- image: localhost/rockylinux9-underpost:v2.8.811
20
+ image: localhost/rockylinux9-underpost:v2.8.814
21
21
  # resources:
22
22
  # requests:
23
23
  # memory: "124Ki"
@@ -100,7 +100,7 @@ spec:
100
100
  spec:
101
101
  containers:
102
102
  - name: dd-template-development-green
103
- image: localhost/rockylinux9-underpost:v2.8.811
103
+ image: localhost/rockylinux9-underpost:v2.8.814
104
104
  # resources:
105
105
  # requests:
106
106
  # memory: "124Ki"
package/package.json CHANGED
@@ -2,7 +2,7 @@
2
2
  "type": "module",
3
3
  "main": "src/index.js",
4
4
  "name": "underpost",
5
- "version": "2.8.811",
5
+ "version": "2.8.814",
6
6
  "description": "pwa api rest template",
7
7
  "scripts": {
8
8
  "start": "env-cmd -f .env.production node --max-old-space-size=8192 src/server",
@@ -508,20 +508,24 @@ net.ipv4.ip_forward = 1' | sudo tee ${iptableConfPath}`);
508
508
  logger.info('Phase 1/6: Cleaning up Kubernetes resources (PVCs, PVs) while API server is accessible...');
509
509
 
510
510
  // Get all Persistent Volumes and identify their host paths for data deletion.
511
- const pvListJson = shellExec(`kubectl get pv -o json || echo '{"items":[]}'`, { stdout: true, silent: true });
512
- const pvList = JSON.parse(pvListJson);
513
-
514
- if (pvList.items && pvList.items.length > 0) {
515
- for (const pv of pvList.items) {
516
- // Check if the PV uses hostPath and delete its contents
517
- if (pv.spec.hostPath && pv.spec.hostPath.path) {
518
- const hostPath = pv.spec.hostPath.path;
519
- logger.info(`Removing data from host path for PV '${pv.metadata.name}': ${hostPath}`);
520
- shellExec(`sudo rm -rf ${hostPath}/* || true`);
511
+ try {
512
+ const pvListJson = shellExec(`kubectl get pv -o json || echo '{"items":[]}'`, { stdout: true, silent: true });
513
+ const pvList = JSON.parse(pvListJson);
514
+
515
+ if (pvList.items && pvList.items.length > 0) {
516
+ for (const pv of pvList.items) {
517
+ // Check if the PV uses hostPath and delete its contents
518
+ if (pv.spec.hostPath && pv.spec.hostPath.path) {
519
+ const hostPath = pv.spec.hostPath.path;
520
+ logger.info(`Removing data from host path for PV '${pv.metadata.name}': ${hostPath}`);
521
+ shellExec(`sudo rm -rf ${hostPath}/* || true`);
522
+ }
521
523
  }
524
+ } else {
525
+ logger.info('No Persistent Volumes found with hostPath to clean up.');
522
526
  }
523
- } else {
524
- logger.info('No Persistent Volumes found with hostPath to clean up.');
527
+ } catch (error) {
528
+ logger.error('Failed to clean up Persistent Volumes:', error);
525
529
  }
526
530
 
527
531
  // Phase 2: Stop Kubelet/K3s agent and remove CNI configuration
package/src/index.js CHANGED
@@ -32,7 +32,7 @@ class Underpost {
32
32
  * @type {String}
33
33
  * @memberof Underpost
34
34
  */
35
- static version = 'v2.8.811';
35
+ static version = 'v2.8.814';
36
36
  /**
37
37
  * Repository cli API
38
38
  * @static
@@ -1,21 +1,13 @@
1
- # Use Rocky Linux 9 as the base image
2
1
  FROM rockylinux:9
3
2
 
4
- # Set environment variable for non-interactive mode (though less critical for DNF than APT)
5
- ENV DNF_ASSUMEYES=1
3
+ RUN dnf install -y --allowerasing bzip2
6
4
 
7
- # Set root password to root
8
- RUN echo 'root:root' | chpasswd
9
-
10
- # Update system packages and install EPEL, then essential tools
11
- # DNF is the package manager for Rocky Linux (RHEL-based)
12
5
  RUN dnf update -y
13
6
  RUN dnf install -y epel-release
14
7
  RUN dnf install -y --allowerasing sudo
15
8
  RUN dnf install -y --allowerasing curl
16
9
  RUN dnf install -y --allowerasing net-tools
17
10
  RUN dnf install -y --allowerasing openssh-server
18
- RUN dnf install -y --allowerasing supervisor
19
11
  RUN dnf install -y --allowerasing nano
20
12
  RUN dnf install -y --allowerasing vim-enhanced
21
13
  RUN dnf install -y --allowerasing less
@@ -25,11 +17,6 @@ RUN dnf install -y --allowerasing git
25
17
  RUN dnf install -y --allowerasing gnupg2
26
18
  RUN dnf clean all
27
19
 
28
- # Configure SSH
29
- RUN mkdir -p /var/run/sshd
30
- # Allow root login via password
31
- RUN sed -ri 's/#PermitRootLogin prohibit-password/PermitRootLogin yes/g' /etc/ssh/sshd_config
32
-
33
20
  # Install LAMPP (XAMPP)
34
21
  # Download the XAMPP installer for Linux
35
22
  RUN curl -Lo xampp-linux-installer.run https://sourceforge.net/projects/xampp/files/XAMPP%20Linux/7.4.33/xampp-linux-x64-7.4.33-0-installer.run?from_af=true
@@ -53,7 +40,6 @@ RUN mkdir /www
53
40
  RUN ln -s /www /opt/lampp/htdocs
54
41
 
55
42
  # Install Node.js
56
- # Add NodeSource repository for Node.js 23.x (for RHEL-based systems)
57
43
  RUN curl -fsSL https://rpm.nodesource.com/setup_23.x | bash -
58
44
  RUN dnf install nodejs -y
59
45
  RUN dnf clean all
@@ -71,25 +57,3 @@ EXPOSE 80
71
57
  EXPOSE 443
72
58
  EXPOSE 3000-3100
73
59
  EXPOSE 4000-4100
74
-
75
- # Default command to start SSH and XAMPP (Apache and MySQL)
76
- # Using supervisord to manage multiple processes
77
- CMD ["/usr/bin/supervisord", "-n"]
78
-
79
- # To run XAMPP services under supervisord, you'll need to add a supervisord configuration file.
80
- # For example, create a file named /etc/supervisord.d/xampp.ini inside the container:
81
- #
82
- # [program:sshd]
83
- # command=/usr/sbin/sshd -D
84
- # autostart=true
85
- # autorestart=true
86
- #
87
- # [program:apache]
88
- # command=/opt/lampp/bin/apachectl start
89
- # autostart=true
90
- # autorestart=true
91
- #
92
- # [program:mysql]
93
- # command=/opt/lampp/bin/mysql.server start
94
- # autostart=true
95
- # autorestart=true