@underpostnet/underpost 2.99.8 → 3.0.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.
Files changed (45) hide show
  1. package/.env.development +2 -1
  2. package/.env.production +1 -0
  3. package/.env.test +2 -1
  4. package/.github/workflows/publish.ci.yml +18 -34
  5. package/.vscode/extensions.json +8 -50
  6. package/.vscode/settings.json +0 -77
  7. package/CHANGELOG.md +67 -1
  8. package/{cli.md → CLI-HELP.md} +48 -41
  9. package/README.md +3 -3
  10. package/bin/build.js +1 -15
  11. package/bin/deploy.js +4 -133
  12. package/bin/file.js +1 -5
  13. package/bin/zed.js +63 -2
  14. package/jsdoc.json +1 -2
  15. package/manifests/cronjobs/dd-cron/dd-cron-backup.yaml +1 -1
  16. package/manifests/cronjobs/dd-cron/dd-cron-dns.yaml +1 -1
  17. package/manifests/deployment/dd-default-development/deployment.yaml +2 -2
  18. package/manifests/deployment/dd-test-development/deployment.yaml +2 -2
  19. package/manifests/deployment/fastapi/initial_data.sh +4 -52
  20. package/manifests/ipfs/configmap.yaml +57 -0
  21. package/manifests/ipfs/headless-service.yaml +35 -0
  22. package/manifests/ipfs/kustomization.yaml +8 -0
  23. package/manifests/ipfs/statefulset.yaml +149 -0
  24. package/manifests/ipfs/storage-class.yaml +9 -0
  25. package/package.json +5 -5
  26. package/scripts/k3s-node-setup.sh +89 -0
  27. package/scripts/lxd-vm-setup.sh +23 -0
  28. package/scripts/rocky-setup.sh +1 -13
  29. package/src/cli/baremetal.js +7 -9
  30. package/src/cli/cluster.js +72 -121
  31. package/src/cli/deploy.js +8 -5
  32. package/src/cli/index.js +31 -30
  33. package/src/cli/ipfs.js +184 -0
  34. package/src/cli/lxd.js +191 -236
  35. package/src/cli/repository.js +4 -1
  36. package/src/client/components/core/VanillaJs.js +0 -25
  37. package/src/client/services/user/user.management.js +0 -5
  38. package/src/client/services/user/user.service.js +1 -1
  39. package/src/index.js +12 -1
  40. package/src/server/client-build-docs.js +26 -7
  41. package/src/server/conf.js +1 -1
  42. package/src/server/logger.js +22 -10
  43. package/.vscode/zed.keymap.json +0 -39
  44. package/.vscode/zed.settings.json +0 -20
  45. package/manifests/lxd/underpost-setup.sh +0 -163
package/src/index.js CHANGED
@@ -12,6 +12,7 @@ import UnderpostDB from './cli/db.js';
12
12
  import UnderpostDeploy from './cli/deploy.js';
13
13
  import UnderpostRootEnv from './cli/env.js';
14
14
  import UnderpostFileStorage from './cli/fs.js';
15
+ import UnderpostIPFS from './cli/ipfs.js';
15
16
  import UnderpostImage from './cli/image.js';
16
17
  import UnderpostLxd from './cli/lxd.js';
17
18
  import UnderpostMonitor from './cli/monitor.js';
@@ -41,7 +42,7 @@ class Underpost {
41
42
  * @type {String}
42
43
  * @memberof Underpost
43
44
  */
44
- static version = 'v2.99.8';
45
+ static version = 'v3.0.0';
45
46
 
46
47
  /**
47
48
  * Required Node.js major version
@@ -143,6 +144,15 @@ class Underpost {
143
144
  static get fs() {
144
145
  return UnderpostFileStorage.API;
145
146
  }
147
+ /**
148
+ * IPFS cli API
149
+ * @static
150
+ * @type {UnderpostIPFS.API}
151
+ * @memberof Underpost
152
+ */
153
+ static get ipfs() {
154
+ return UnderpostIPFS.API;
155
+ }
146
156
  /**
147
157
  * Monitor cli API
148
158
  * @static
@@ -296,6 +306,7 @@ export {
296
306
  UnderpostStatic,
297
307
  UnderpostLxd,
298
308
  UnderpostKickStart,
309
+ UnderpostIPFS,
299
310
  UnderpostMonitor,
300
311
  UnderpostRepository,
301
312
  UnderpostRun,
@@ -7,7 +7,6 @@
7
7
  */
8
8
 
9
9
  import fs from 'fs-extra';
10
- import swaggerAutoGen from 'swagger-autogen';
11
10
  import { shellExec } from './process.js';
12
11
  import { loggerFactory } from './logger.js';
13
12
  import { JSONweb } from './client-formatted.js';
@@ -123,13 +122,33 @@ const buildApiDocs = async ({
123
122
 
124
123
  logger.warn('build swagger api docs', doc.info);
125
124
 
126
- const outputFile = `./public/${host}${path === '/' ? path : `${path}/`}swagger-output.json`;
127
- const routes = [];
128
- for (const api of apis) {
129
- if (['user'].includes(api)) routes.push(`./src/api/${api}/${api}.router.js`);
130
- }
125
+ // swagger-autogen@2.9.2 bug: getProducesTag, getConsumesTag, getResponsesTag missing __¬¬¬__ decode before eval
126
+ fs.writeFileSync(
127
+ `node_modules/swagger-autogen/src/swagger-tags.js`,
128
+ fs
129
+ .readFileSync(`node_modules/swagger-autogen/src/swagger-tags.js`, 'utf8')
130
+ // getProducesTag and getConsumesTag: already decode " but not __¬¬¬__
131
+ .replaceAll(
132
+ `data.replaceAll('\\n', ' ').replaceAll('\u201c', '\u201d')`,
133
+ `data.replaceAll('\\n', ' ').replaceAll('\u201c', '\u201d').replaceAll('__\u00ac\u00ac\u00ac__', '"')`,
134
+ )
135
+ // getResponsesTag: decodes neither " nor __¬¬¬__
136
+ .replaceAll(
137
+ `data.replaceAll('\\n', ' ');`,
138
+ `data.replaceAll('\\n', ' ').replaceAll('__\u00ac\u00ac\u00ac__', '"');`,
139
+ ),
140
+ 'utf8',
141
+ );
142
+ setTimeout(async () => {
143
+ const { default: swaggerAutoGen } = await import('swagger-autogen');
144
+ const outputFile = `./public/${host}${path === '/' ? path : `${path}/`}swagger-output.json`;
145
+ const routes = [];
146
+ for (const api of apis) {
147
+ if (['user'].includes(api)) routes.push(`./src/api/${api}/${api}.router.js`);
148
+ }
131
149
 
132
- await swaggerAutoGen({ openapi: '3.0.0' })(outputFile, routes, doc);
150
+ await swaggerAutoGen({ openapi: '3.0.0' })(outputFile, routes, doc);
151
+ });
133
152
  };
134
153
 
135
154
  /**
@@ -1335,7 +1335,7 @@ const buildCliDoc = (program, oldVersion, newVersion) => {
1335
1335
  });
1336
1336
  md = md.replaceAll(oldVersion, newVersion);
1337
1337
  fs.writeFileSync(`./src/client/public/nexodev/docs/references/Command Line Interface.md`, md, 'utf8');
1338
- fs.writeFileSync(`./cli.md`, md, 'utf8');
1338
+ fs.writeFileSync(`./CLI-HELP.md`, md, 'utf8');
1339
1339
  const readme = fs.readFileSync(`./README.md`, 'utf8');
1340
1340
  fs.writeFileSync('./README.md', readme.replaceAll(oldVersion, newVersion), 'utf8');
1341
1341
  };
@@ -101,27 +101,37 @@ const setUpInfo = async (logger = new winston.Logger()) => {
101
101
  * @param meta - The `meta` parameter in the `loggerFactory` function is used to extract the last part
102
102
  * of a URL and use it to create log files in a specific directory.
103
103
  * @param logLevel - Specify the logging level for the logger instance. e.g., 'error', 'warn', 'info', 'debug'.
104
+ * @param enableFileLogs - Whether to write logs to files. Defaults to the value of the `ENABLE_FILE_LOGS` environment variable.
104
105
  * @returns {underpostLogger} The `loggerFactory` function returns a logger instance created using Winston logger
105
106
  * library. The logger instance is configured with various transports for printing out messages to
106
107
  * different destinations such as the terminal, error.log file, and all.log file. The logger instance
107
108
  * also has a method `setUpInfo` attached to it for setting up additional information.
108
109
  * @memberof Logger
109
110
  */
110
- const loggerFactory = (meta = { url: '' }, logLevel = '') => {
111
+ const loggerFactory = (
112
+ meta = { url: '' },
113
+ logLevel = '',
114
+ enableFileLogs = process.env.ENABLE_FILE_LOGS === 'true' || process.env.ENABLE_FILE_LOGS === true,
115
+ ) => {
111
116
  meta = meta.url.split('/').pop();
112
117
  // Define which transports the logger must use to print out messages.
113
118
  // In this example, we are using three different transports
114
119
  const transports = [
115
120
  // Allow the use the terminal to print the messages
116
121
  new winston.transports.Console(),
117
- // Allow to print all the error level messages inside the error.log file
118
- // new winston.transports.File({
119
- // filename: `logs/${meta}/error.log`,
120
- // level: 'error',
121
- // }),
122
- // Allow to print all the error message inside the all.log file
123
- // (also the error log that are also printed inside the error.log(
124
- new winston.transports.File({ filename: `logs/${meta}/all.log` }),
122
+ // Optionally write log files when enableFileLogs is true
123
+ ...(enableFileLogs
124
+ ? [
125
+ // Allow to print all the error level messages inside the error.log file
126
+ new winston.transports.File({
127
+ filename: `logs/${meta}/error.log`,
128
+ level: 'error',
129
+ }),
130
+ // Allow to print all the error messages inside the all.log file
131
+ // (also includes error logs that are also printed inside error.log)
132
+ new winston.transports.File({ filename: `logs/${meta}/all.log` }),
133
+ ]
134
+ : []),
125
135
  ];
126
136
 
127
137
  // Create the logger instance that has to be exported
@@ -154,6 +164,7 @@ const loggerFactory = (meta = { url: '' }, logLevel = '') => {
154
164
  * @param {Object} meta - An object containing metadata, such as the URL, to be used in the logger.
155
165
  * @param {string} logLevel - The logging level to be used for the logger (e.g., 'error', 'warn', 'info', 'debug').
156
166
  * @param {Function} skip - A function to determine whether to skip logging for a particular request.
167
+ * @param {boolean} enableFileLogs - Whether to write logs to files. Defaults to false.
157
168
  * @returns {Function} A middleware function that can be used in an Express application to log HTTP requests.
158
169
  * @memberof Logger
159
170
  */
@@ -161,10 +172,11 @@ const loggerMiddleware = (
161
172
  meta = { url: '' },
162
173
  logLevel = 'info',
163
174
  skip = (req, res) => process.env.NODE_ENV === 'production',
175
+ enableFileLogs = process.env.ENABLE_FILE_LOGS === 'true' || process.env.ENABLE_FILE_LOGS === true,
164
176
  ) => {
165
177
  const stream = {
166
178
  // Use the http severity
167
- write: (message) => loggerFactory(meta, logLevel).http(message),
179
+ write: (message) => loggerFactory(meta, logLevel, enableFileLogs).http(message),
168
180
  };
169
181
 
170
182
  morgan.token('host', function (req, res) {
@@ -1,39 +0,0 @@
1
- [
2
- {
3
- "context": "Editor",
4
- "bindings": {
5
- "ctrl-c": "editor::Copy",
6
- "ctrl-x": "editor::Cut",
7
- "ctrl-v": "editor::Paste",
8
- "ctrl-shift-c": "editor::CopyAndTrim",
9
- "ctrl-shift-v": "editor::Paste",
10
- "cmd-c": "editor::Copy",
11
- "cmd-x": "editor::Cut",
12
- "cmd-v": "editor::Paste"
13
- }
14
- },
15
- {
16
- "context": "Terminal",
17
- "bindings": {
18
- "ctrl-shift-c": "terminal::Copy",
19
- "ctrl-shift-v": "terminal::Paste",
20
- "cmd-shift-c": "terminal::Copy",
21
- "cmd-shift-v": "terminal::Paste"
22
- }
23
- },
24
- {
25
- "context": "Editor && edit_prediction",
26
- "bindings": {
27
- "tab": "editor::AcceptEditPrediction",
28
- "alt-tab": "editor::AcceptEditPrediction",
29
- "alt-l": null
30
- }
31
- },
32
- {
33
- "context": "Editor && edit_prediction_conflict",
34
- "bindings": {
35
- "alt-l": "editor::AcceptEditPrediction",
36
- "tab": "editor::ComposeCompletion"
37
- }
38
- }
39
- ]
@@ -1,20 +0,0 @@
1
- {
2
- "ui_font_size": 16,
3
- "buffer_font_size": 15,
4
- "theme": {
5
- "mode": "system",
6
- "light": "One Dark",
7
- "dark": "One Dark"
8
- },
9
-
10
- "features": {
11
- "edit_prediction_provider": "copilot",
12
- "copilot": true // https://github.com/login/device
13
- },
14
-
15
- "show_edit_predictions": true,
16
-
17
- "edit_predictions": {
18
- "mode": "eager"
19
- }
20
- }
@@ -1,163 +0,0 @@
1
- #!/bin/bash
2
-
3
- # Exit immediately if a command exits with a non-zero status.
4
- set -e
5
-
6
- echo "Starting Underpost Kubernetes Node Setup for Production (Kubeadm/K3s Use Case)..."
7
-
8
- # --- Disk Partition Resizing (Keep as is, seems functional) ---
9
- echo "Expanding /dev/sda2 partition and resizing filesystem..."
10
-
11
- # Check if parted is installed
12
- if ! command -v parted &>/dev/null; then
13
- echo "parted not found, installing..."
14
- sudo dnf install -y parted
15
- fi
16
-
17
- # Get start sector of /dev/sda2
18
- START_SECTOR=$(sudo parted /dev/sda -ms unit s print | awk -F: '/^2:/{print $2}' | sed 's/s//')
19
-
20
- # Resize the partition
21
- # Using 'sudo' for parted commands
22
- sudo parted /dev/sda ---pretend-input-tty <<EOF
23
- unit s
24
- resizepart 2 100%
25
- Yes
26
- quit
27
- EOF
28
-
29
- # Resize the filesystem
30
- sudo resize2fs /dev/sda2
31
-
32
- echo "Disk and filesystem resized successfully."
33
-
34
- # --- Essential System Package Installation ---
35
- echo "Installing essential system packages..."
36
- sudo dnf install -y tar bzip2 git epel-release
37
-
38
- # Perform a system update to ensure all packages are up-to-date
39
- sudo dnf -y update
40
-
41
- # --- NVM and Node.js Installation ---
42
- echo "Installing NVM and Node.js v24.10.0..."
43
- curl -o- https://cdn.jsdelivr.net/gh/nvm-sh/nvm@v0.40.1/install.sh | bash
44
-
45
- # Load nvm for the current session
46
- export NVM_DIR="$([ -z "${XDG_CONFIG_HOME-}" ] && printf %s "${HOME}/.nvm" || printf %s "${XDG_CONFIG_HOME}/nvm")"
47
- [ -s "$NVM_DIR/nvm.sh" ] && \. "$NVM_DIR/nvm.sh" # This loads nvm
48
-
49
- nvm install 24.10.0
50
- nvm use 24.10.0
51
-
52
- echo "
53
- ██╗░░░██╗███╗░░██╗██████╗░███████╗██████╗░██████╗░░█████╗░░██████╗████████╗
54
- ██║░░░██║████╗░██║██╔══██╗██╔════╝██╔══██╗██╔══██╗██╔══██╗██╔════╝╚══██╔══╝
55
- ██║░░░██║██╔██╗██║██║░░██║█████╗░░██████╔╝██████╔╝██║░░██║╚█████╗░░░░██║░░░
56
- ██║░░░██║██║╚████║██║░░██║██╔══╝░░██╔══██╗██╔═══╝░██║░░██║░╚═══██╗░░░██║░░░
57
- ╚██████╔╝██║░╚███║██████╔╝███████╗██║░░██║██║░░░░░╚█████╔╝██████╔╝░░░██║░░░
58
- ░╚═════╝░╚═╝░░╚══╝╚═════╝░╚══════╝╚═╝░░╚═╝╚═╝░░░░░░╚════╝░╚═════╝░░░░╚═╝░░░
59
-
60
- Installing underpost k8s node...
61
- "
62
-
63
- # Install underpost globally
64
- npm install -g underpost
65
-
66
- # Ensure underpost executable is in PATH and has execute permissions
67
- # Adjusting this for global npm install which usually handles permissions
68
- # If you still face issues, ensure /root/.nvm/versions/node/v24.10.0/bin is in your PATH
69
- # For global installs, it's usually handled automatically.
70
- # chmod +x /root/.nvm/versions/node/v24.10.0/bin/underpost # This might not be necessary for global npm installs
71
-
72
- # --- Kernel Module for Bridge Filtering ---
73
- # This is crucial for Kubernetes networking (CNI)
74
- echo "Loading br_netfilter kernel module..."
75
- sudo modprobe br_netfilter
76
-
77
- # --- Initial Host Setup for Kubernetes Prerequisites ---
78
- # This calls the initHost method in cluster.js to install Docker, Podman, Kind, Kubeadm, Helm.
79
- echo "Running initial host setup for Kubernetes prerequisites..."
80
- # Ensure the current directory is where 'underpost' expects its root, or use absolute paths.
81
- # Assuming 'underpost root' correctly points to the base directory of your project.
82
- cd "$(underpost root)/underpost"
83
- underpost cluster --init-host
84
-
85
- # --- Argument Parsing for Kubeadm/Kind/K3s/Worker ---
86
- USE_KUBEADM=false
87
- USE_KIND=false # Not the primary focus for this request, but keeping the logic
88
- USE_K3S=false # New K3s option
89
- USE_WORKER=false
90
-
91
- for arg in "$@"; do
92
- case "$arg" in
93
- --kubeadm)
94
- USE_KUBEADM=true
95
- ;;
96
- --kind)
97
- USE_KIND=true
98
- ;;
99
- --k3s) # New K3s argument
100
- USE_K3S=true
101
- ;;
102
- --worker)
103
- USE_WORKER=true
104
- ;;
105
- esac
106
- done
107
-
108
- echo "USE_KUBEADM = $USE_KUBEADM"
109
- echo "USE_KIND = $USE_KIND"
110
- echo "USE_K3S = $USE_K3S" # Display K3s flag status
111
- echo "USE_WORKER = $USE_WORKER"
112
-
113
- # --- Kubernetes Cluster Initialization Logic ---
114
-
115
- # Apply host configuration (SELinux, Containerd, Sysctl, and now firewalld disabling)
116
- echo "Applying Kubernetes host configuration (SELinux, Containerd, Sysctl, Firewalld)..."
117
- underpost cluster --config
118
-
119
- if $USE_KUBEADM; then
120
- if $USE_WORKER; then
121
- echo "Running worker node setup for kubeadm..."
122
- # For worker nodes, the 'underpost cluster --worker' command will handle joining
123
- # the cluster. The join command itself needs to be provided from the control plane.
124
- # This script assumes the join command will be executed separately or passed in.
125
- # Example: underpost cluster --worker --join-command "kubeadm join ..."
126
- # For now, this just runs the worker-specific config.
127
- underpost cluster --worker
128
- underpost cluster --chown
129
- echo "Worker node setup initiated. You will need to manually join this worker to your control plane."
130
- echo "On your control plane, run 'kubeadm token create --print-join-command' and execute the output here."
131
- else
132
- echo "Running control plane setup with kubeadm..."
133
- # This will initialize the kubeadm control plane and install Calico
134
- underpost cluster --kubeadm
135
- echo "Kubeadm control plane initialized. Check cluster status with 'kubectl get nodes'."
136
- fi
137
- elif $USE_K3S; then # New K3s initialization block
138
- if $USE_WORKER; then
139
- echo "Running worker node setup for K3s..."
140
- # For K3s worker nodes, the 'underpost cluster --worker' command will handle joining
141
- # the cluster. The K3s join command (k3s agent --server ...) needs to be provided.
142
- underpost cluster --worker --k3s
143
- underpost cluster --chown
144
- echo "K3s Worker node setup initiated. You will need to manually join this worker to your control plane."
145
- echo "On your K3s control plane, get the K3S_TOKEN from /var/lib/rancher/k3s/server/node-token"
146
- echo "and the K3S_URL (e.g., https://<control-plane-ip>:6443)."
147
- echo "Then execute: K3S_URL=${K3S_URL} K3S_TOKEN=${K3S_TOKEN} curl -sfL https://get.k3s.io | sh -"
148
- else
149
- echo "Running control plane setup with K3s..."
150
- underpost cluster --k3s
151
- echo "K3s control plane initialized. Check cluster status with 'kubectl get nodes'."
152
- fi
153
- elif $USE_KIND; then
154
- echo "Running control node with kind..."
155
- underpost cluster
156
- echo "Kind cluster initialized. Check cluster status with 'kubectl get nodes'."
157
- else
158
- echo "No specific cluster role (--kubeadm, --kind, --k3s, --worker) specified. Please provide one."
159
- exit 1
160
- fi
161
-
162
- echo "Underpost Kubernetes Node Setup completed."
163
- echo "Remember to verify cluster health with 'kubectl get nodes' and 'kubectl get pods --all-namespaces'."