underpost 3.2.21 → 3.2.28

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 (55) hide show
  1. package/.github/workflows/ghpkg.ci.yml +1 -1
  2. package/.github/workflows/gitlab.ci.yml +1 -1
  3. package/.github/workflows/npmpkg.ci.yml +1 -1
  4. package/.github/workflows/publish.ci.yml +2 -2
  5. package/.github/workflows/pwa-microservices-template-page.cd.yml +1 -1
  6. package/.github/workflows/pwa-microservices-template-test.ci.yml +1 -1
  7. package/CHANGELOG.md +178 -1
  8. package/CLI-HELP.md +58 -2
  9. package/README.md +3 -2
  10. package/baremetal/commission-workflows.json +1 -0
  11. package/bin/build.js +13 -1
  12. package/docker-compose.yml +224 -0
  13. package/manifests/cronjobs/dd-cron/dd-cron-backup.yaml +1 -1
  14. package/manifests/cronjobs/dd-cron/dd-cron-dns.yaml +1 -1
  15. package/manifests/deployment/dd-default-development/deployment.yaml +2 -2
  16. package/package.json +27 -15
  17. package/scripts/kubeadm-node-setup.sh +317 -0
  18. package/scripts/rocky-kickstart.sh +877 -185
  19. package/scripts/rpmfusion-ffmpeg-setup.sh +26 -50
  20. package/scripts/test-monitor.sh +242 -78
  21. package/src/cli/baremetal.js +717 -16
  22. package/src/cli/cluster.js +3 -1
  23. package/src/cli/deploy.js +11 -10
  24. package/src/cli/docker-compose.js +591 -0
  25. package/src/cli/fs.js +35 -11
  26. package/src/cli/index.js +83 -0
  27. package/src/cli/kickstart.js +142 -20
  28. package/src/cli/monitor.js +114 -29
  29. package/src/cli/repository.js +75 -11
  30. package/src/cli/run.js +275 -6
  31. package/src/cli/ssh.js +190 -0
  32. package/src/cli/static.js +2 -2
  33. package/src/client/components/core/PanelForm.js +44 -44
  34. package/src/{server → client-builder}/client-build-docs.js +15 -5
  35. package/src/{server → client-builder}/client-build-live.js +3 -3
  36. package/src/{server → client-builder}/client-build.js +25 -22
  37. package/src/{server → client-builder}/client-dev-server.js +3 -3
  38. package/src/{server → client-builder}/client-icons.js +2 -2
  39. package/src/{server → client-builder}/ssr.js +5 -5
  40. package/src/client.build.js +1 -1
  41. package/src/client.dev.js +1 -1
  42. package/src/index.js +12 -1
  43. package/src/mailer/EmailRender.js +1 -1
  44. package/src/{server → projects/underpost}/catalog-underpost.js +1 -2
  45. package/src/runtime/express/Express.js +2 -2
  46. package/src/runtime/nginx/Nginx.js +250 -0
  47. package/src/server/catalog.js +7 -14
  48. package/src/server/conf.js +61 -12
  49. package/src/server/start.js +17 -5
  50. package/src/server.js +1 -1
  51. package/test/deploy-monitor.test.js +33 -5
  52. package/typedoc.json +3 -1
  53. package/src/server/ipfs-client.js +0 -597
  54. /package/src/client/ssr/{Render.js → RootDocument.js} +0 -0
  55. /package/src/{server → client-builder}/client-formatted.js +0 -0
@@ -1,56 +1,32 @@
1
1
  #!/usr/bin/env bash
2
2
  set -euo pipefail
3
3
 
4
- # Purpose: enable required repos (CRB, EPEL, RPM Fusion) and attempt to install ffmpeg on Rocky/Alma/RHEL-9 compatible systems.
4
+ echo "1) Ensure dnf-plugins-core is installed"
5
+ dnf -y install dnf-plugins-core
5
6
 
6
- if [ "${EUID:-$(id -u)}" -ne 0 ]; then
7
- echo "This script must be run as root or with sudo. Exiting."
8
- exit 1
9
- fi
7
+ echo "2) Enable CRB"
8
+ dnf config-manager --set-enabled crb || true
10
9
 
11
- echo "1) Ensure dnf-plugins-core is available (for config-manager)"
12
- dnf -y install dnf-plugins-core
10
+ echo "3) Install EPEL"
11
+ dnf -y install epel-release \
12
+ || dnf -y install https://dl.fedoraproject.org/pub/epel/epel-release-latest-9.noarch.rpm
13
+
14
+ echo "4) Install RPM Fusion repositories"
15
+ dnf -y install \
16
+ https://download1.rpmfusion.org/free/el/rpmfusion-free-release-9.noarch.rpm \
17
+ https://download1.rpmfusion.org/nonfree/el/rpmfusion-nonfree-release-9.noarch.rpm
18
+
19
+
20
+ echo "5) Install libwebp-tools (for ffmpeg to support WebP)"
21
+ dnf -y install libwebp-tools
22
+
23
+ echo "6) Refresh metadata"
24
+ dnf clean all
25
+ dnf makecache --refresh
26
+
27
+ echo "7) Install ffmpeg"
28
+ dnf -y install ffmpeg ffmpeg-devel --allowerasing
13
29
 
14
- echo "2) Enable CodeReady / CRB (needed for some deps, e.g. ladspa)"
15
- # On RHEL you'd use subscription-manager; on CentOS/Rocky/Alma use config-manager
16
- dnf config-manager --set-enabled crb
17
-
18
- echo "3) Install EPEL release (required by some ffmpeg deps)"
19
- dnf -y install https://dl.fedoraproject.org/pub/epel/epel-release-latest-9.noarch.rpm
20
-
21
- echo "4) Add RPM Fusion (free + nonfree) repositories"
22
- # Using mirrors.rpmfusion.org recommended links
23
- dnf -y install https://mirrors.rpmfusion.org/free/el/rpmfusion-free-release-9.noarch.rpm \
24
- https://mirrors.rpmfusion.org/nonfree/el/rpmfusion-nonfree-release-9.noarch.rpm
25
-
26
- echo "5) Refresh metadata and update system"
27
- dnf -y makecache
28
- # Optional: update system packages (comment out if you don't want a full update)
29
- # dnf -y update
30
-
31
- echo "6) Try to install audio helper packages that sometimes block ffmpeg (ladspa, rubberband)"
32
- # These may be provided by CRB/EPEL or other compatible repos
33
- dnf -y install ladspa || echo "ladspa not available from enabled repos (will try later)"
34
- dnf -y install rubberband || echo "rubberband not available from enabled repos (will try later)"
35
- dnf -y install libwebp-tools || echo "libwebp-tools not available from enabled repos (will try later)"
36
-
37
- echo "7) Try installing ffmpeg (several fallbacks tried)"
38
- if dnf -y install ffmpeg ffmpeg-devel --allowerasing; then
39
- echo "ffmpeg installed successfully (used --allowerasing)."
40
- elif dnf -y install ffmpeg ffmpeg-devel --nobest; then
41
- echo "ffmpeg installed successfully (used --nobest)."
42
- elif dnf -y install ffmpeg ffmpeg-devel --skip-broken; then
43
- echo "ffmpeg installed (skip-broken). Some optional packages may have been skipped."
44
- else
45
- echo "Automatic install failed."
46
- echo "Helpful troubleshooting steps:"
47
- echo " - Check which repo provides ladspa: dnf repoquery --whatprovides 'ladspa'"
48
- echo " - Check which package provides librubberband: dnf repoquery --whatprovides 'librubberband.so.2'"
49
- echo " - Try enabling CRB and EPEL (we already attempted that). If ladspa/rubberband are still missing you can fetch their EL9 rpm from a trusted mirror or build them."
50
- echo " - Example manual install (ONLY if you trust the source): sudo dnf install /path/to/ladspa-*.el9.rpm /path/to/rubberband-*.el9.rpm"
51
- echo " - After satisfying ladspa/rubberband, rerun: sudo dnf install ffmpeg ffmpeg-devel"
52
- exit 2
53
- fi
54
-
55
- echo "\nInstallation finished. Verify with: ffmpeg -version"
56
- exit 0
30
+ echo
31
+ echo "Done."
32
+ ffmpeg -version | head -n 1
@@ -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)"