underpost 3.2.21 → 3.2.22

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/CHANGELOG.md CHANGED
@@ -1,6 +1,43 @@
1
1
  # Changelog
2
2
 
3
- ## 2026-06-06
3
+ ## 2026-06-07
4
+
5
+ ### repository
6
+
7
+ - Add safe repo config in pullSourceRepo ([4325c1ba7](https://github.com/underpostnet/engine/commit/4325c1ba736b4e2fa64f0570dc5bedb9b33e351f))
8
+
9
+ ### docs
10
+
11
+ - Restore runtimeConfig docs logic ([819792d1d](https://github.com/underpostnet/engine/commit/819792d1de4e20e490c7bdffca66f794ef810868))
12
+ - Enhance favicon resolution logic in buildJsDocs function to handle missing files ([4b4b6cca2](https://github.com/underpostnet/engine/commit/4b4b6cca2b31f1b41c1e893e58a3bb94b67c4f26))
13
+ - Fix favicon path resolution in buildJsDocs function to handle missing files ([a572ffaf8](https://github.com/underpostnet/engine/commit/a572ffaf88de3e07b0c90fb485f57e9032d4e5bb))
14
+ - Update favicon path in buildJsDocs function to use publicClientId for dynamic resolution ([d839d6a02](https://github.com/underpostnet/engine/commit/d839d6a02b6a49a2aa6923ce5392ff4509c36f43))
15
+
16
+ ### monitor
17
+
18
+ - Add support for custom image names in deployment scripts ([2d4ddf731](https://github.com/underpostnet/engine/commit/2d4ddf731565e45e90b7e105ce17e6a56862e17f))
19
+ - Enhance transport handling in UnderpostMonitor: Default to exec, add opt-in for http ([eebe7ef03](https://github.com/underpostnet/engine/commit/eebe7ef0318e3bbe2533e31701bba7af9483e73c))
20
+ - Refactor test-monitor script: Enhance deployment modes and flag parsing ([07b65b004](https://github.com/underpostnet/engine/commit/07b65b0040d34883f67ebf6d9fa61872ff4c81f2))
21
+ - Enhance runtime status handling with exec transport and kubernetes gate ([135773938](https://github.com/underpostnet/engine/commit/135773938dcbd4e466e09afea73ccc8994a6509e))
22
+
23
+ ### deploy
24
+
25
+ - Refactor deployment commands to use dynamic node names and update MongoDB flag in run command ([b6a1dc9c7](https://github.com/underpostnet/engine/commit/b6a1dc9c751a09fd677d9778b252d967a08225cb))
26
+
27
+ ### cli-start
28
+
29
+ - Add error handling for deployment build/init process in UnderpostStartUp class ([6c7d7e056](https://github.com/underpostnet/engine/commit/6c7d7e0568903f89a0a3a06683b726e4f34fa843))
30
+ - Add support for private test repositories in build and monitor scripts ([23837d02b](https://github.com/underpostnet/engine/commit/23837d02b6a250ecc420e903a095d5be397494bb))
31
+
32
+ ### ipfs
33
+
34
+ - Refactor IPFS API URL functions to include container check for development environment ([61e3fcd1e](https://github.com/underpostnet/engine/commit/61e3fcd1e08b9ec43dca29a151a4309f2a44f276))
35
+
36
+ ### client-core
37
+
38
+ - Fix bug Panel component; when the user writes markdown content but uploads missing reload md file ([f91da9780](https://github.com/underpostnet/engine/commit/f91da97807b991bf9c6b8693c9c97bb8365df6f4))
39
+
40
+ ## New release v:3.2.21 (2026-06-06)
4
41
 
5
42
  ### release
6
43
 
package/CLI-HELP.md CHANGED
@@ -1,6 +1,6 @@
1
1
  ## Underpost CLI
2
2
 
3
- > underpost ci/cd cli v3.2.21
3
+ > underpost ci/cd cli v3.2.22
4
4
 
5
5
  **Usage:** `underpost [options] [command]`
6
6
 
@@ -132,6 +132,7 @@ Initiates application servers, build pipelines, or other defined services based
132
132
  | `--skip-pull-base` | Skips cloning repositories, uses current workspace code directly. |
133
133
  | `--skip-full-build` | Skips the full client bundle build during deployment. |
134
134
  | `--pull-bundle` | Downloads the pre-built client bundle from Cloudinary via pull-bundle before starting. Use together with --skip-full-build to skip the local build entirely. |
135
+ | `--private-test-repo` | During --build, clone the private test source repo (engine-test-<id>) instead of the production engine-<id> repo. |
135
136
  | `-h, --help` | display help for command |
136
137
 
137
138
  ---
@@ -888,6 +889,7 @@ Runs specified scripts using various runners.
888
889
  | `--skip-full-build` | Skip client bundle rebuild; triggers pull-bundle in container startup (supported by: sync, template-deploy). |
889
890
  | `--pull-bundle` | Explicitly download the pre-built client bundle from Cloudinary inside the container (supported by: sync, template-deploy). Use together with --skip-full-build. |
890
891
  | `--remove` | Remove/teardown resources |
892
+ | `--test` | Enables test/generic-purpose mode for the runner (e.g. use self-signed TLS instead of cert-manager). |
891
893
  | `-h, --help` | display help for command |
892
894
 
893
895
  ---
package/README.md CHANGED
@@ -16,7 +16,7 @@
16
16
 
17
17
  <div align="center">
18
18
 
19
- [![Node.js CI](https://github.com/underpostnet/engine/actions/workflows/docker-image.ci.yml/badge.svg?branch=master)](https://github.com/underpostnet/engine/actions/workflows/docker-image.ci.yml) [![Test](https://github.com/underpostnet/engine/actions/workflows/coverall.ci.yml/badge.svg?branch=master)](https://github.com/underpostnet/engine/actions/workflows/coverall.ci.yml) [![Downloads](https://img.shields.io/npm/dm/underpost.svg)](https://www.npmjs.com/package/underpost) [![](https://data.jsdelivr.com/v1/package/npm/underpost/badge)](https://www.jsdelivr.com/package/npm/underpost) [![Socket Badge](https://socket.dev/api/badge/npm/package/underpost/3.2.21)](https://socket.dev/npm/package/underpost/overview/3.2.21) [![Coverage Status](https://coveralls.io/repos/github/underpostnet/engine/badge.svg?branch=master)](https://coveralls.io/github/underpostnet/engine?branch=master) [![Version](https://img.shields.io/npm/v/underpost.svg)](https://www.npmjs.org/package/underpost) [![License](https://img.shields.io/npm/l/underpost.svg)](https://www.npmjs.com/package/underpost)
19
+ [![Node.js CI](https://github.com/underpostnet/engine/actions/workflows/docker-image.ci.yml/badge.svg?branch=master)](https://github.com/underpostnet/engine/actions/workflows/docker-image.ci.yml) [![Test](https://github.com/underpostnet/engine/actions/workflows/coverall.ci.yml/badge.svg?branch=master)](https://github.com/underpostnet/engine/actions/workflows/coverall.ci.yml) [![Downloads](https://img.shields.io/npm/dm/underpost.svg)](https://www.npmjs.com/package/underpost) [![](https://data.jsdelivr.com/v1/package/npm/underpost/badge)](https://www.jsdelivr.com/package/npm/underpost) [![Socket Badge](https://socket.dev/api/badge/npm/package/underpost/3.2.22)](https://socket.dev/npm/package/underpost/overview/3.2.22) [![Coverage Status](https://coveralls.io/repos/github/underpostnet/engine/badge.svg?branch=master)](https://coveralls.io/github/underpostnet/engine?branch=master) [![Version](https://img.shields.io/npm/v/underpost.svg)](https://www.npmjs.org/package/underpost) [![License](https://img.shields.io/npm/l/underpost.svg)](https://www.npmjs.com/package/underpost)
20
20
 
21
21
  </div>
22
22
 
@@ -88,7 +88,7 @@ npm run dev
88
88
  <!-- cli-index-start -->
89
89
  ## Underpost CLI
90
90
 
91
- > underpost ci/cd cli v3.2.21
91
+ > underpost ci/cd cli v3.2.22
92
92
 
93
93
  **Usage:** `underpost [options] [command]`
94
94
 
package/bin/build.js CHANGED
@@ -11,6 +11,7 @@ import {
11
11
  syncPrivateConf,
12
12
  syncDeployIdSources,
13
13
  buildTemplate,
14
+ updatePrivateEngineTestRepo,
14
15
  } from '../src/server/conf.js';
15
16
  import { loadDeployCatalog } from '../src/server/catalog.js';
16
17
  import UnderpostRepository from '../src/cli/repository.js';
@@ -191,6 +192,11 @@ program
191
192
  '--no-template-rebuild',
192
193
  'Skip the from-scratch base template reconstruction before assembly (assemble onto the existing template).',
193
194
  )
195
+ .option(
196
+ '--update-private',
197
+ 'After assembling each deploy id, publish it to its private test source repo (underpostnet/engine-test-<id>) for isolated test deploys.',
198
+ false,
199
+ )
194
200
  .action(async (confName, env, options) => {
195
201
  const deployList = resolveDeployList(confName);
196
202
  logger.info('Build repository', { confName, basePath, deployList, conf: !!options.conf });
@@ -207,7 +213,12 @@ program
207
213
  // build run leaks into this one. Opt out with --no-template-rebuild.
208
214
  if (options.templateRebuild) await buildTemplate({ toPath: basePath });
209
215
 
210
- for (const deployId of deployList) await buildDeployTemplate(deployId);
216
+ for (const deployId of deployList) {
217
+ await buildDeployTemplate(deployId);
218
+ // Publish the just-assembled tree to the deploy id's private test repo so a
219
+ // pod started with `--private-test-repo` clones this work-in-progress source.
220
+ if (options.updatePrivate) await updatePrivateEngineTestRepo(deployId);
221
+ }
211
222
  });
212
223
 
213
224
  await program.parseAsync();
@@ -23,7 +23,7 @@ spec:
23
23
  spec:
24
24
  containers:
25
25
  - name: dd-cron-backup
26
- image: underpost/underpost-engine:v3.2.21
26
+ image: underpost/underpost-engine:v3.2.22
27
27
  command:
28
28
  - /bin/sh
29
29
  - -c
@@ -23,7 +23,7 @@ spec:
23
23
  spec:
24
24
  containers:
25
25
  - name: dd-cron-dns
26
- image: underpost/underpost-engine:v3.2.21
26
+ image: underpost/underpost-engine:v3.2.22
27
27
  command:
28
28
  - /bin/sh
29
29
  - -c
@@ -17,7 +17,7 @@ spec:
17
17
  spec:
18
18
  containers:
19
19
  - name: dd-default-development-blue
20
- image: underpost/underpost-engine:v3.2.21
20
+ image: underpost/underpost-engine:v3.2.22
21
21
  # resources:
22
22
  # requests:
23
23
  # memory: "124Ki"
@@ -98,7 +98,7 @@ spec:
98
98
  spec:
99
99
  containers:
100
100
  - name: dd-default-development-green
101
- image: underpost/underpost-engine:v3.2.21
101
+ image: underpost/underpost-engine:v3.2.22
102
102
  # resources:
103
103
  # requests:
104
104
  # 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": "3.2.21",
5
+ "version": "3.2.22",
6
6
  "description": "Underpost Platform — end-to-end CI/CD and application-delivery toolchain CLI. Covers bare metal, Kubernetes, K3s, kubeadm, LXD, container/image orchestration, secrets, databases, cron jobs, monitoring, SSH, runners, PWA + Workbox delivery, and release orchestration. Extensible via downstream CLIs.",
7
7
  "scripts": {
8
8
  "start": "node --max-old-space-size=8192 src/server",
@@ -1,86 +1,250 @@
1
-
2
1
  #!/usr/bin/env bash
2
+ #
3
+ # test-monitor.sh — end-to-end deploy + two-phase monitor smoke test.
4
+ #
5
+ # Two deployment shapes are supported (see
6
+ # src/client/public/nexodev/docs/references/Deploy-Monitor-PRD.md and
7
+ # 'Deploy custom instance to K8S.md'):
8
+ #
9
+ # --mode runtime `underpost start` deploy (e.g. dd-test). Monitored with the
10
+ # HTTP gate: /_internal/ready probes + port-forward status.
11
+ # --mode instance Custom instances from conf.instances.json (e.g. cyberia
12
+ # mmo-server / mmo-client). Monitored with the kubernetes gate
13
+ # (TCP readinessProbe) + exec status transport.
14
+ #
15
+ # Every variable in the DEFAULTS block below is overridable with a flag of the
16
+ # same name (--env, --deploy-id, …). Run with --help for the full list.
17
+ #
3
18
  set -euo pipefail
4
19
 
5
- ENV=development
6
- DEPLOY_ID=dd-test
7
- IMAGE=underpost/wp:v3.2.14
8
- USE_CERT=false # Set to true to use --cert, false to use --disable-update-proxy
9
- USE_PULL_BUNDLE=false # Set to true to include --pull-bundle in start command, false to omit it
10
- USE_TLS=false # Set to true to generate self-signed certs and expose via HTTPS
11
- VERSIONS=green
12
-
13
- # Parse --tls flag from script arguments
14
- for arg in "$@"; do
15
- case $arg in
16
- --tls) USE_TLS=true ;;
17
- esac
18
- done
20
+ SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
21
+ ENGINE_DIR="$(cd "${SCRIPT_DIR}/.." && pwd)"
22
+ cd "$ENGINE_DIR"
23
+
24
+ # ─────────────────────────── DEFAULTS (all overridable) ───────────────────────────
25
+ MODE=runtime # runtime | instance
26
+ ENV=development # development | production
27
+ DEPLOY_ID=dd-test # deploy id (instance mode: parent of conf.instances.json)
28
+ INSTANCE_IDS= # instance mode: csv of ids (default: all in conf.instances.json)
29
+ IMAGE=underpost/wp:v3.2.14 # runtime mode image (instance mode reads image from conf)
30
+ VERSIONS=green # csv of blue/green versions
31
+ REPLICAS=1 # replicas per deployment
32
+ NAMESPACE=default # k8s namespace
33
+ CLUSTER= # kind | kubeadm | k3s | "" (auto/none)
34
+ TIMEOUT_RESPONSE=300000ms # HTTPProxy per-route response timeout
35
+ TEMPLATE_REPO=underpostnet/pwa-microservices-template-private # runtime mode link repo
36
+ ENVOY_NAMESPACE=projectcontour # ingress namespace (instance TLS exposure)
37
+ ENVOY_SERVICE=envoy # ingress service (instance TLS exposure)
38
+ HTTPS_PORT=443 # local https port for instance TLS exposure
39
+
40
+ USE_CERT=false # runtime: pass --cert to the proxy step
41
+ USE_PULL_BUNDLE=false # runtime: include --pull-bundle in the start cmd
42
+ USE_TLS=false # generate self-signed certs + expose over HTTPS
43
+ USE_TEST_REPO=false # runtime: publish src to engine-test-<id> + pod clones it (--private-test-repo)
44
+ DO_BUILD_TEMPLATE=true # run `node bin/build.template --update-private`
45
+ DO_CLUSTER_MANIFESTS=true # run `node bin run build-cluster-deployment-manifests`
46
+ DO_EXPOSE=true # expose locally after deploy + monitor
47
+
48
+ usage() {
49
+ cat <<'EOF'
50
+ Usage: scripts/test-monitor.sh [flags]
51
+
52
+ Modes:
53
+ --mode <runtime|instance> Deployment shape to test (default: runtime)
54
+
55
+ Common (every default is overridable):
56
+ --env <development|production>
57
+ --deploy-id <id>
58
+ --instance-ids <csv> instance mode only; default = all ids in conf.instances.json
59
+ --image <image> runtime mode only
60
+ --versions <csv> e.g. green or blue,green
61
+ --replicas <n>
62
+ --namespace <ns>
63
+ --cluster <kind|kubeadm|k3s|none>
64
+ --timeout-response <dur> e.g. 300000ms
65
+ --template-repo <owner/repo> runtime mode link repo
66
+ --envoy-namespace <ns> instance TLS exposure ingress namespace
67
+ --envoy-service <name> instance TLS exposure ingress service
68
+ --https-port <port> local https port for instance TLS exposure
69
+
70
+ Toggles (use --x / --no-x):
71
+ --tls | --no-tls self-signed certs + HTTPS exposure (default: off)
72
+ --cert | --no-cert runtime proxy --cert (default: off)
73
+ --pull-bundle | --no-pull-bundle runtime start --pull-bundle (default: off)
74
+ --test-repo | --no-test-repo runtime: publish src to engine-test-<id> and have the
75
+ pod clone it via --private-test-repo (default: off)
76
+ --expose | --no-expose local exposure after monitor (default: on)
77
+ --build-template | --no-build-template sync private template (default: on)
78
+ --cluster-manifests | --no-cluster-manifests rebuild cluster manifests (default: on)
19
79
 
20
- # Optional to concat in link cmd:
21
- # underpost secret underpost --create-from-env
80
+ -h, --help
22
81
 
23
- LINK_CMD="cd /home/dd,underpost clone underpostnet/pwa-microservices-template-private,cd /home/dd/pwa-microservices-template-private,npm install,npm link"
24
- PROXY_FLAG=""
82
+ Examples:
83
+ # Runtime deploy (default), no TLS
84
+ scripts/test-monitor.sh
85
+
86
+ # Runtime deploy over HTTPS
87
+ scripts/test-monitor.sh --tls
88
+
89
+ # Runtime deploy from a work-in-progress test source repo (engine-test-<id>)
90
+ scripts/test-monitor.sh --test-repo
91
+
92
+ # Cyberia instances (both), dev on kind, no TLS
93
+ scripts/test-monitor.sh --mode instance --deploy-id dd-cyberia --cluster kind
94
+
95
+ # Only the mmo-server instance, production, over HTTPS
96
+ scripts/test-monitor.sh --mode instance --deploy-id dd-cyberia \
97
+ --instance-ids mmo-server --env production --cluster kubeadm --tls
98
+ EOF
99
+ }
100
+
101
+ # ─────────────────────────── flag parsing ───────────────────────────
102
+ # Supports `--key value` and `--key=value` for value flags, plus --x/--no-x toggles.
103
+ needval() { [[ $# -ge 2 ]] || { echo "Missing value for $1" >&2; exit 1; }; }
104
+ while [[ $# -gt 0 ]]; do
105
+ case "$1" in
106
+ --mode) needval "$@"; MODE="$2"; shift 2;; --mode=*) MODE="${1#*=}"; shift;;
107
+ --env) needval "$@"; ENV="$2"; shift 2;; --env=*) ENV="${1#*=}"; shift;;
108
+ --deploy-id) needval "$@"; DEPLOY_ID="$2"; shift 2;; --deploy-id=*) DEPLOY_ID="${1#*=}"; shift;;
109
+ --instance-ids) needval "$@"; INSTANCE_IDS="$2"; shift 2;; --instance-ids=*) INSTANCE_IDS="${1#*=}"; shift;;
110
+ --image) needval "$@"; IMAGE="$2"; shift 2;; --image=*) IMAGE="${1#*=}"; shift;;
111
+ --versions) needval "$@"; VERSIONS="$2"; shift 2;; --versions=*) VERSIONS="${1#*=}"; shift;;
112
+ --replicas) needval "$@"; REPLICAS="$2"; shift 2;; --replicas=*) REPLICAS="${1#*=}"; shift;;
113
+ --namespace) needval "$@"; NAMESPACE="$2"; shift 2;; --namespace=*) NAMESPACE="${1#*=}"; shift;;
114
+ --cluster) needval "$@"; CLUSTER="$2"; shift 2;; --cluster=*) CLUSTER="${1#*=}"; shift;;
115
+ --timeout-response) needval "$@"; TIMEOUT_RESPONSE="$2"; shift 2;; --timeout-response=*) TIMEOUT_RESPONSE="${1#*=}"; shift;;
116
+ --template-repo) needval "$@"; TEMPLATE_REPO="$2"; shift 2;; --template-repo=*) TEMPLATE_REPO="${1#*=}"; shift;;
117
+ --envoy-namespace) needval "$@"; ENVOY_NAMESPACE="$2"; shift 2;; --envoy-namespace=*) ENVOY_NAMESPACE="${1#*=}"; shift;;
118
+ --envoy-service) needval "$@"; ENVOY_SERVICE="$2"; shift 2;; --envoy-service=*) ENVOY_SERVICE="${1#*=}"; shift;;
119
+ --https-port) needval "$@"; HTTPS_PORT="$2"; shift 2;; --https-port=*) HTTPS_PORT="${1#*=}"; shift;;
120
+ --tls) USE_TLS=true; shift;; --no-tls) USE_TLS=false; shift;;
121
+ --cert) USE_CERT=true; shift;; --no-cert) USE_CERT=false; shift;;
122
+ --pull-bundle) USE_PULL_BUNDLE=true; shift;; --no-pull-bundle) USE_PULL_BUNDLE=false; shift;;
123
+ --test-repo) USE_TEST_REPO=true; shift;; --no-test-repo) USE_TEST_REPO=false; shift;;
124
+ --expose) DO_EXPOSE=true; shift;; --no-expose) DO_EXPOSE=false; shift;;
125
+ --build-template) DO_BUILD_TEMPLATE=true; shift;; --no-build-template) DO_BUILD_TEMPLATE=false; shift;;
126
+ --cluster-manifests) DO_CLUSTER_MANIFESTS=true; shift;; --no-cluster-manifests) DO_CLUSTER_MANIFESTS=false; shift;;
127
+ -h|--help) usage; exit 0;;
128
+ *) echo "Unknown flag: $1" >&2; usage; exit 1;;
129
+ esac
130
+ done
131
+
132
+ # ─────────────────────────── derived flags ───────────────────────────
25
133
  CLUSTER_FLAG=""
26
- EXPOSE_FLAGS=""
27
-
28
- node bin run build-cluster-deployment-manifests
29
- node bin/build.template --update-private
30
-
31
- if [ "$USE_PULL_BUNDLE" = true ]; then
32
- DEPLOY_CMD="$LINK_CMD,underpost start --build --run --pull-bundle $DEPLOY_ID $ENV"
33
- else
34
- DEPLOY_CMD="$LINK_CMD,underpost start --build --run $DEPLOY_ID $ENV"
35
- fi
36
-
37
- if [ "$USE_CERT" = true ]; then
38
- PROXY_FLAG="--cert"
39
- fi
40
-
41
- if [ "$USE_TLS" = true ]; then
42
- PROXY_FLAG="--self-signed"
43
- fi
44
-
45
- node bin deploy $DEPLOY_ID $ENV $CLUSTER_FLAG --sync --build-manifest --image $IMAGE --timeout-response 300000ms --versions $VERSIONS --replicas 1 --cmd "$DEPLOY_CMD"
46
- node bin deploy $DEPLOY_ID $ENV $CLUSTER_FLAG --disable-update-proxy $PROXY_FLAG
47
- node bin monitor $DEPLOY_ID $ENV --ready-deployment --promote --timeout-response 300000ms --versions $VERSIONS --replicas 1
48
-
49
- node bin run etc-hosts --deploy-id $DEPLOY_ID
50
-
51
- # Generate self-signed TLS certs and create k8s TLS secrets for all hosts
52
- if [ "$USE_TLS" = true ]; then
53
- SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
54
- ENGINE_DIR="$(cd "${SCRIPT_DIR}/.." && pwd)"
55
- SSL_BASE="${ENGINE_DIR}/engine-private/ssl"
56
- NAMESPACE=default
57
-
58
- # Extract hosts from conf.server.json
59
- HOSTS=$(node -e "
60
- const conf = require('./engine-private/conf/${DEPLOY_ID}/conf.server.json');
61
- console.log(Object.keys(conf).join(' '));
62
- ")
63
-
64
- for HOST in $HOSTS; do
65
- CERT_DIR="${SSL_BASE}/${HOST}"
66
- mkdir -p "$CERT_DIR"
67
-
68
- # Regenerate self-signed cert (idempotent overwrites existing files)
69
- bash "${SCRIPT_DIR}/ssl.sh" "$CERT_DIR" "$HOST"
70
-
71
- NAME_SAFE="${HOST//[^a-zA-Z0-9_.-]/_}"
72
- CERT_FILE="${CERT_DIR}/${NAME_SAFE}.pem"
73
- KEY_FILE="${CERT_DIR}/${NAME_SAFE}-key.pem"
74
-
75
- # Create / replace k8s TLS secret (name matches host, as referenced by HTTPProxy)
76
- kubectl delete secret "$HOST" -n "$NAMESPACE" --ignore-not-found
77
- kubectl create secret tls "$HOST" \
78
- --cert="$CERT_FILE" \
79
- --key="$KEY_FILE" \
80
- -n "$NAMESPACE"
134
+ case "$CLUSTER" in
135
+ kind) CLUSTER_FLAG="--kind";;
136
+ kubeadm) CLUSTER_FLAG="--kubeadm";;
137
+ k3s) CLUSTER_FLAG="--k3s";;
138
+ ""|none) CLUSTER_FLAG="";;
139
+ *) echo "Unknown --cluster: $CLUSTER (expected kind|kubeadm|k3s|none)" >&2; exit 1;;
140
+ esac
141
+ DEV_FLAG=""; [ "$ENV" = development ] && DEV_FLAG="--dev"
142
+ INSTANCES_CONF="./engine-private/conf/${DEPLOY_ID}/conf.instances.json"
143
+ SERVER_CONF="./engine-private/conf/${DEPLOY_ID}/conf.server.json"
144
+
145
+ echo "[test-monitor] mode=$MODE env=$ENV deploy=$DEPLOY_ID cluster=${CLUSTER:-none} tls=$USE_TLS test-repo=$USE_TEST_REPO expose=$DO_EXPOSE"
146
+
147
+ # ─────────────────────────── shared helpers ───────────────────────────
148
+
149
+ # setup_tls_secrets <host> [<host> …] regenerate self-signed certs and create
150
+ # the per-host k8s TLS secret the HTTPProxy references (name == host).
151
+ setup_tls_secrets() {
152
+ local ssl_base="${ENGINE_DIR}/engine-private/ssl"
153
+ for host in "$@"; do
154
+ local cert_dir="${ssl_base}/${host}"
155
+ mkdir -p "$cert_dir"
156
+ bash "${SCRIPT_DIR}/ssl.sh" "$cert_dir" "$host"
157
+ local name_safe="${host//[^a-zA-Z0-9_.-]/_}"
158
+ kubectl delete secret "$host" -n "$NAMESPACE" --ignore-not-found
159
+ kubectl create secret tls "$host" \
160
+ --cert="${cert_dir}/${name_safe}.pem" \
161
+ --key="${cert_dir}/${name_safe}-key.pem" \
162
+ -n "$NAMESPACE"
163
+ done
164
+ }
165
+
166
+ # hosts_from <conf.json> — unique hosts declared in a conf.server.json or conf.instances.json.
167
+ hosts_from() {
168
+ node -e "
169
+ const c = require('$1');
170
+ const hosts = Array.isArray(c) ? c.map(i => i.host) : Object.keys(c);
171
+ console.log([...new Set(hosts)].join(' '));
172
+ "
173
+ }
174
+
175
+ # ─────────────────────────── pre-steps ───────────────────────────
176
+ [ "$DO_CLUSTER_MANIFESTS" = true ] && node bin run build-cluster-deployment-manifests
177
+ [ "$DO_BUILD_TEMPLATE" = true ] && node bin/build.template --update-private
178
+
179
+ # ─────────────────────────── runtime mode ───────────────────────────
180
+ run_runtime_mode() {
181
+ local link_cmd="cd /home/dd,underpost clone ${TEMPLATE_REPO},cd /home/dd/${TEMPLATE_REPO##*/},npm install,npm link"
182
+ local deploy_cmd proxy_flag="" expose_flags="" start_flags=""
183
+
184
+ # Publish the local engine src to underpostnet/engine-test-<id> so the pod
185
+ # (started with --private-test-repo) clones this work-in-progress source.
186
+ [ "$USE_TEST_REPO" = true ] && node bin/build "$DEPLOY_ID" --update-private
187
+
188
+ [ "$USE_PULL_BUNDLE" = true ] && start_flags="${start_flags} --pull-bundle"
189
+ [ "$USE_TEST_REPO" = true ] && start_flags="${start_flags} --private-test-repo"
190
+ deploy_cmd="${link_cmd},underpost start --build --run${start_flags} ${DEPLOY_ID} ${ENV}"
191
+
192
+ [ "$USE_CERT" = true ] && proxy_flag="--cert"
193
+ [ "$USE_TLS" = true ] && proxy_flag="--self-signed"
194
+
195
+ node bin deploy "$DEPLOY_ID" "$ENV" $CLUSTER_FLAG --sync --build-manifest \
196
+ --image "$IMAGE" --timeout-response "$TIMEOUT_RESPONSE" --versions "$VERSIONS" --replicas "$REPLICAS" --cmd "$deploy_cmd"
197
+ node bin deploy "$DEPLOY_ID" "$ENV" $CLUSTER_FLAG --disable-update-proxy $proxy_flag
198
+ node bin monitor "$DEPLOY_ID" "$ENV" --ready-deployment --promote \
199
+ --timeout-response "$TIMEOUT_RESPONSE" --versions "$VERSIONS" --replicas "$REPLICAS"
200
+
201
+ node bin run etc-hosts --deploy-id "$DEPLOY_ID"
202
+
203
+ if [ "$USE_TLS" = true ]; then
204
+ setup_tls_secrets $(hosts_from "$SERVER_CONF")
205
+ expose_flags="--tls"
206
+ fi
207
+ [ "$DO_EXPOSE" = true ] && node bin deploy --expose --local-proxy "$DEPLOY_ID" "$ENV" $expose_flags
208
+ }
209
+
210
+ # ─────────────────────────── instance mode ───────────────────────────
211
+ run_instance_mode() {
212
+ [ -f "$INSTANCES_CONF" ] || { echo "Missing $INSTANCES_CONF" >&2; exit 1; }
213
+ if [ -z "$INSTANCE_IDS" ]; then
214
+ INSTANCE_IDS=$(node -e "console.log(require('$INSTANCES_CONF').map(i=>i.id).join(','))")
215
+ fi
216
+ local tls_flag=""; [ "$USE_TLS" = true ] && tls_flag="--tls --test"
217
+
218
+ # `run instance` builds/pulls the image, applies the manifest, monitors with the
219
+ # kubernetes gate (TCP readinessProbe) + exec status, then promotes traffic.
220
+ IFS=',' read -ra ids <<< "$INSTANCE_IDS"
221
+ for id in "${ids[@]}"; do
222
+ [ -n "$id" ] || continue
223
+ echo "[test-monitor] deploying instance ${DEPLOY_ID},${id}"
224
+ node bin run instance "${DEPLOY_ID},${id},${REPLICAS}" \
225
+ $DEV_FLAG $CLUSTER_FLAG --namespace "$NAMESPACE" --etc-hosts $tls_flag \
226
+ ${IMAGE:+--image-name "$IMAGE"}
227
+ done
228
+
229
+ [ "$DO_EXPOSE" = true ] || return 0
230
+ if [ "$USE_TLS" = true ]; then
231
+ # Instances are routed by the Contour ingress; port-forward Envoy so the
232
+ # HTTPProxy host routing (server/client.cyberiaonline.com) works locally.
233
+ echo "[test-monitor] exposing HTTPS via ${ENVOY_NAMESPACE}/${ENVOY_SERVICE} on :${HTTPS_PORT}"
234
+ sudo kubectl port-forward -n "$ENVOY_NAMESPACE" "svc/${ENVOY_SERVICE}" "${HTTPS_PORT}:443" &
235
+ else
236
+ # Plain HTTP: port-forward each instance service port directly.
237
+ for id in "${ids[@]}"; do
238
+ [ -n "$id" ] || continue
239
+ node bin deploy --expose "${DEPLOY_ID}-${id}" "$ENV" --namespace "$NAMESPACE" || true
81
240
  done
82
-
83
- EXPOSE_FLAGS="--tls"
84
- fi
241
+ fi
242
+ }
243
+
244
+ case "$MODE" in
245
+ runtime) run_runtime_mode;;
246
+ instance) run_instance_mode;;
247
+ *) echo "Unknown --mode: $MODE (expected runtime|instance)" >&2; exit 1;;
248
+ esac
85
249
 
86
- node bin deploy --expose --local-proxy $DEPLOY_ID $ENV $EXPOSE_FLAGS
250
+ echo "[test-monitor] done (mode=$MODE tls=$USE_TLS)"
package/src/cli/deploy.js CHANGED
@@ -1072,15 +1072,12 @@ EOF`);
1072
1072
  if (options.gitClean && volume.volumeMountPath) {
1073
1073
  Underpost.repo.clean({ paths: [volume.volumeMountPath] });
1074
1074
  }
1075
- if (options.nodeName) {
1076
- if (!fs.existsSync(rootVolumeHostPath)) fs.mkdirSync(rootVolumeHostPath, { recursive: true });
1077
- fs.copySync(volume.volumeMountPath, rootVolumeHostPath);
1078
- } else if (clusterContext === 'kind') {
1079
- shellExec(`docker exec -i kind-worker bash -c "mkdir -p ${rootVolumeHostPath}"`);
1080
- // shellExec(`docker cp ${volume.volumeMountPath} kind-worker:${rootVolumeHostPath}`);
1081
- shellExec(`tar -C ${volume.volumeMountPath} -c . | docker cp - kind-worker:${rootVolumeHostPath}`);
1075
+ if (clusterContext === 'kind') {
1076
+ const kindNode = options.nodeName || 'kind-worker';
1077
+ shellExec(`docker exec -i ${kindNode} bash -c "mkdir -p ${rootVolumeHostPath}"`);
1078
+ shellExec(`tar -C ${volume.volumeMountPath} -c . | docker cp - ${kindNode}:${rootVolumeHostPath}`);
1082
1079
  shellExec(
1083
- `docker exec -i kind-worker bash -c "chown -R 1000:1000 ${rootVolumeHostPath}; chmod -R 755 ${rootVolumeHostPath}"`,
1080
+ `docker exec -i ${kindNode} bash -c "chown -R 1000:1000 ${rootVolumeHostPath}; chmod -R 755 ${rootVolumeHostPath}"`,
1084
1081
  );
1085
1082
  } else {
1086
1083
  if (!fs.existsSync(rootVolumeHostPath)) fs.mkdirSync(rootVolumeHostPath, { recursive: true });
package/src/cli/index.js CHANGED
@@ -70,6 +70,10 @@ program
70
70
  '--pull-bundle',
71
71
  'Downloads the pre-built client bundle from Cloudinary via pull-bundle before starting. Use together with --skip-full-build to skip the local build entirely.',
72
72
  )
73
+ .option(
74
+ '--private-test-repo',
75
+ 'During --build, clone the private test source repo (engine-test-<id>) instead of the production engine-<id> repo.',
76
+ )
73
77
  .action(Underpost.start.callback)
74
78
  .description('Initiates application servers, build pipelines, or other defined services based on the deployment ID.');
75
79
 
@@ -727,6 +731,10 @@ program
727
731
  'Explicitly download the pre-built client bundle from Cloudinary inside the container (supported by: sync, template-deploy). Use together with --skip-full-build.',
728
732
  )
729
733
  .option('--remove', 'Remove/teardown resources')
734
+ .option(
735
+ '--test',
736
+ 'Enables test/generic-purpose mode for the runner (e.g. use self-signed TLS instead of cert-manager).',
737
+ )
730
738
  .description('Runs specified scripts using various runners.')
731
739
  .action(Underpost.run.callback);
732
740