amsd-pipeline 2.0.7 → 2.0.8
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/install.sh +72 -17
- package/package.json +1 -1
package/install.sh
CHANGED
|
@@ -145,11 +145,20 @@ if [ "$UNINSTALL" = "1" ]; then
|
|
|
145
145
|
_UN_FILE="${_UN_SPEC%%:*}"; _UN_PROJECT="${_UN_SPEC##*:}"
|
|
146
146
|
_UN_COMPOSE="$_UN_ROOT/$_UN_FILE"
|
|
147
147
|
if [ -f "$_UN_COMPOSE" ]; then
|
|
148
|
-
|
|
149
|
-
-f "$(basename "$_UN_COMPOSE")" -p "$_UN_PROJECT" down -v --remove-orphans --rmi local) >/dev/null 2>&1
|
|
148
|
+
(cd "$(dirname "$_UN_COMPOSE")" && container_compose \
|
|
149
|
+
-f "$(basename "$_UN_COMPOSE")" -p "$_UN_PROJECT" down -v --remove-orphans --rmi local) >/dev/null 2>&1 || true
|
|
150
|
+
# COMPOSE DOWN IS NOT THE WHOLE JOB, AND ITS EXIT CODE IS NOT THE ANSWER. A non-zero
|
|
151
|
+
# `down` used to be reported as "nothing to remove or already gone" — the most
|
|
152
|
+
# reassuring wording available for the case where nothing was removed. Live
|
|
153
|
+
# 2026-09-07 that left EIGHT containers and TWO networks behind, which then held the
|
|
154
|
+
# ports the next install needed, so a fresh install validated itself against the
|
|
155
|
+
# previous install's services. Sweep by label, then verify, then report the machine's
|
|
156
|
+
# actual state rather than a command's exit code.
|
|
157
|
+
if purge_project "$_UN_PROJECT"; then
|
|
150
158
|
_ok "removed $_UN_PROJECT (containers, network, volumes, images)"
|
|
151
159
|
else
|
|
152
|
-
|
|
160
|
+
_bad "$_UN_PROJECT: containers remain after uninstall — they will hold this install's ports"
|
|
161
|
+
FAILED=1
|
|
153
162
|
fi
|
|
154
163
|
# SCOPED PRUNE, never a bare `docker system prune` — that would also sweep up the dev
|
|
155
164
|
# environment's own dangling layers. Compose stamps every image it builds with this
|
|
@@ -715,14 +724,32 @@ compose_up() {
|
|
|
715
724
|
# exact stack already running, or a second install) steps to the next attempt's offset, so
|
|
716
725
|
# no manual port flag is ever required for this to just work.
|
|
717
726
|
local _off=$((_i * 10))
|
|
727
|
+
# PROBED, NOT ASSUMED. The offset says where to START looking; whether a port is free is
|
|
728
|
+
# a question only the machine can answer. Deriving them arithmetically meant a clash was
|
|
729
|
+
# discovered only when compose failed — and compose does not always fail: live 2026-09-07
|
|
730
|
+
# it exited 0 over six containers stuck in `created` with "address already in use", so
|
|
731
|
+
# nothing discovered the clash at all. Each service takes the first genuinely free port
|
|
732
|
+
# at or after its candidate, so another install holding 3100 costs one step, not a run.
|
|
733
|
+
local _p_ch _p_lf _p_dash _p_graf
|
|
734
|
+
_p_ch="$(find_free_port $((8123 + _off)))" || { _bad "no free port for clickhouse"; return 1; }
|
|
735
|
+
_p_lf="$(find_free_port $((3100 + _off)))" || { _bad "no free port for langfuse"; return 1; }
|
|
736
|
+
_p_dash="$(find_free_port $((8092 + _off)))" || { _bad "no free port for the dashboard"; return 1; }
|
|
737
|
+
_p_graf="$(find_free_port $((3001 + _off)))" || { _bad "no free port for grafana"; return 1; }
|
|
718
738
|
if (cd "$ROOT" && EPAM_OBS_SUBNET="$_subnet" \
|
|
719
|
-
EPAM_OBS_CLICKHOUSE_PORT
|
|
720
|
-
EPAM_OBS_LANGFUSE_PORT
|
|
721
|
-
EPAM_OBS_DASHBOARD_PORT
|
|
722
|
-
EPAM_OBS_GRAFANA_PORT
|
|
739
|
+
EPAM_OBS_CLICKHOUSE_PORT="$_p_ch" \
|
|
740
|
+
EPAM_OBS_LANGFUSE_PORT="$_p_lf" \
|
|
741
|
+
EPAM_OBS_DASHBOARD_PORT="$_p_dash" \
|
|
742
|
+
EPAM_OBS_GRAFANA_PORT="$_p_graf" \
|
|
723
743
|
container_compose -f "$COMPOSE_FILE" -p "$_OBS_PROJECT" up -d) >"$_log" 2>&1; then
|
|
724
|
-
|
|
725
|
-
|
|
744
|
+
# UP EXITED 0 — THAT IS NOT THE SAME AS RUNNING. podman-compose returns 0 with
|
|
745
|
+
# containers left in `created`; live 2026-09-07 six of eight sat there holding
|
|
746
|
+
# "address already in use" while this loop recorded success and never retried the
|
|
747
|
+
# next port offset. Appending to the SAME log the retry greps means the container's
|
|
748
|
+
# own error can match 'address already in use' and drive the next attempt.
|
|
749
|
+
if compose_services_running "$_OBS_PROJECT" >>"$_log" 2>&1; then
|
|
750
|
+
_up=0
|
|
751
|
+
break
|
|
752
|
+
fi
|
|
726
753
|
fi
|
|
727
754
|
# ONLY RETRY ON A SUBNET OR PORT COLLISION — any other failure would fail identically on
|
|
728
755
|
# every candidate, burning through all of them and hiding the real error behind repeats.
|
|
@@ -750,10 +777,15 @@ compose_up() {
|
|
|
750
777
|
{
|
|
751
778
|
printf 'OBS_PROJECT=%s\n' "$_OBS_PROJECT"
|
|
752
779
|
printf 'OBS_SUBNET=%s\n' "$_subnet"
|
|
753
|
-
|
|
754
|
-
|
|
755
|
-
|
|
756
|
-
|
|
780
|
+
# THE PORTS ACTUALLY USED, not the ones arithmetic proposed. These are probed now
|
|
781
|
+
# (find_free_port), so an offset that was occupied yields a different port — recording
|
|
782
|
+
# the formula instead of the result would make this file name ports no container listens
|
|
783
|
+
# on, and service_url()/langfuse-emit.js read it to find this install's own services.
|
|
784
|
+
printf 'OBS_CLICKHOUSE_PORT=%s\n' "$_p_ch"
|
|
785
|
+
printf 'OBS_LANGFUSE_PORT=%s\n' "$_p_lf"
|
|
786
|
+
printf 'OBS_DASHBOARD_PORT=%s\n' "$_p_dash"
|
|
787
|
+
printf 'OBS_GRAFANA_PORT=%s\n' "$_p_graf"
|
|
788
|
+
# (the rest of the identity — mock server, etc — follows below)
|
|
757
789
|
# THE REHEARSAL SERVER'S IDENTITY, resolved here and started nowhere.
|
|
758
790
|
#
|
|
759
791
|
# llm-defaults.mockserver.json points all 40 seams at MockServer, and until now nothing in
|
|
@@ -771,6 +803,16 @@ compose_up() {
|
|
|
771
803
|
printf 'MOCK_PROJECT=%s\n' "$(isolated_project_name "$ROOT" mock)"
|
|
772
804
|
printf 'MOCK_SUBNET=%s\n' "$(isolated_subnet_candidates "$ROOT-mock" | head -1)"
|
|
773
805
|
} > "$ROOT/.pipeline-services-state.env"
|
|
806
|
+
|
|
807
|
+
# THE .env MUST NAME THIS INSTALL'S OWN SERVICES. langfuse-emit.js resolves
|
|
808
|
+
# `env.LANGFUSE_BASE_URL || allocatedBase()`, so a literal in .env WINS over what this install
|
|
809
|
+
# allocated. Live 2026-09-07: an install whose Langfuse came up on 3120 carried a copied
|
|
810
|
+
# LANGFUSE_BASE_URL=http://localhost:3100 — a PREVIOUS install's — so every trace from a run
|
|
811
|
+
# would have been written into that other install's database, while looking perfectly healthy.
|
|
812
|
+
# Copied .env files are the normal case here, not an edge one.
|
|
813
|
+
if reconcile_env_endpoint "$ROOT/.env" LANGFUSE_BASE_URL "http://localhost:${_p_lf}"; then
|
|
814
|
+
_ok "LANGFUSE_BASE_URL points at this install's own Langfuse (port ${_p_lf})"
|
|
815
|
+
fi
|
|
774
816
|
rm -f "$_log" 2>/dev/null
|
|
775
817
|
return 0
|
|
776
818
|
}
|
|
@@ -960,12 +1002,25 @@ else
|
|
|
960
1002
|
# attempts, and a second teardown here changes what one attempt means.
|
|
961
1003
|
for _LD_SUBNET in $(isolated_subnet_candidates "$ROOT-launch"); do
|
|
962
1004
|
_LD_TRY_PORT=$((_LD_PORT + _LD_I * 10))
|
|
1005
|
+
# WRITTEN INTO THE .env COMPOSE READS, not only exported. Docker Compose lets the
|
|
1006
|
+
# shell environment win over the project .env; PODMAN-COMPOSE DOES NOT — with
|
|
1007
|
+
# LAUNCH_UI_PORT=8109 exported, `podman compose config` still resolved `ports:
|
|
1008
|
+
# 8099:80` from launch-dashboard/.env. So every retry republished the SAME port while
|
|
1009
|
+
# the installer health-checked the next one, and a dashboard that was up and serving
|
|
1010
|
+
# on 8099 was declared "never answered healthy at :8109". Writing the file is correct
|
|
1011
|
+
# on both runtimes — docker reads it too — and removes the precedence difference
|
|
1012
|
+
# rather than depending on it.
|
|
1013
|
+
reconcile_env_endpoint "$LAUNCH_DIR/.env" LAUNCH_UI_PORT "$_LD_TRY_PORT" || true
|
|
963
1014
|
if (cd "$LAUNCH_DIR" && LAUNCH_SUBNET="$_LD_SUBNET" LAUNCH_UI_PORT="$_LD_TRY_PORT" \
|
|
964
1015
|
container_compose -f "$LAUNCH_COMPOSE" -p "$_LD_PROJECT" up -d --build --force-recreate) >"$_LD_LOG" 2>&1; then
|
|
965
|
-
|
|
966
|
-
|
|
967
|
-
|
|
968
|
-
|
|
1016
|
+
# Same trap as the observability stack: compose can exit 0 over containers that
|
|
1017
|
+
# never started, and the port-collision retry below only fires on a failure.
|
|
1018
|
+
if compose_services_running "$_LD_PROJECT" >>"$_LD_LOG" 2>&1; then
|
|
1019
|
+
_LD_UP=0
|
|
1020
|
+
_LD_PORT="$_LD_TRY_PORT"
|
|
1021
|
+
_LD_HEALTH_URL="http://localhost:${_LD_PORT}/api/health"
|
|
1022
|
+
break
|
|
1023
|
+
fi
|
|
969
1024
|
fi
|
|
970
1025
|
grep -qiE 'overlap|pool|port is already allocated|address already in use' "$_LD_LOG" || break
|
|
971
1026
|
# TEAR DOWN BEFORE THE NEXT ATTEMPT — same fix as the observability stack's retry
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "amsd-pipeline",
|
|
3
|
-
"version": "2.0.
|
|
3
|
+
"version": "2.0.8",
|
|
4
4
|
"description": "Installer for the amsd-pipeline orchestration stack. Clones, packages and provisions the full stack with one command — no separate git clone step.",
|
|
5
5
|
"bin": {
|
|
6
6
|
"amsd-pipeline": "bin/amsd-pipeline.js"
|