amsd-pipeline 1.37.0 → 2.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 (2) hide show
  1. package/install.sh +71 -4
  2. package/package.json +1 -1
package/install.sh CHANGED
@@ -4,6 +4,10 @@
4
4
  # ./orchestrations-installer/install.sh install for the default stack, with dashboards if docker is up
5
5
  # ./install.sh --stack codemie install for a specific stack
6
6
  # ./install.sh --no-docker skip dashboards entirely
7
+ # ./install.sh --replay on record every run to Langfuse so it can be replayed for $0
8
+ # (default off; needs LANGFUSE_SECRET_KEY + LANGFUSE_PUBLIC_KEY
9
+ # in .env or the environment — recording without them is
10
+ # silent, and a run not recorded can never be replayed)
7
11
  # ./install.sh --check verify an existing install, change nothing
8
12
  # ./install.sh --dest ~/somewhere --ref v1.7 package that ref into a NEW tree, then install it
9
13
  #
@@ -60,6 +64,20 @@ while [ $# -gt 0 ]; do
60
64
  --stack) STACK="${2:-}"; shift 2 ;;
61
65
  --no-docker) USE_DOCKER=no; shift ;;
62
66
  --docker) USE_DOCKER=yes; shift ;;
67
+ # DOCUMENTED SINCE BEFORE IT EXISTED. orchestrations/config/env-vars.json describes both
68
+ # Langfuse keys as belonging to "replay (--replay on / EPAM_REPLAY=on)", and this parser
69
+ # had no --replay arm — so an operator following the configuration got
70
+ # "unknown option '--replay'" and exit 1. The env var keeps working; this is the flag the
71
+ # docs already promised.
72
+ --replay)
73
+ REPLAY_MODE="${2:-}"
74
+ case "$REPLAY_MODE" in
75
+ on|off) ;;
76
+ # Never silently fall back to off: that produces an install recording nothing
77
+ # while the operator believes it records, and the loss is one-way.
78
+ *) _bad "--replay takes 'on' or 'off', not '${2:-}'"; exit 1 ;;
79
+ esac
80
+ shift 2 ;;
63
81
  --check) CHECK_ONLY=1; shift ;;
64
82
  --uninstall) UNINSTALL=1; shift ;;
65
83
  --help|-h) sed -n '2,15p' "$0" | sed 's/^# \{0,1\}//'; exit 0 ;;
@@ -340,6 +358,7 @@ RUNNER="$("$NODE_BIN" -e '
340
358
  if [ -n "$RUNNER" ]; then
341
359
  if command -v "$RUNNER" >/dev/null 2>&1; then _ok "$RUNNER (the '$STACK' runner)"
342
360
  else _bad "'$RUNNER' is not on PATH — the '$STACK' stack cannot run without it"; FAILED=1; fi
361
+ fi
343
362
 
344
363
  # PYTHON IS A RUNTIME DEPENDENCY, not an optional extra: 88 handlers under
345
364
  # orchestrations/scripts/lib/handlers are executed with it.
@@ -348,12 +367,17 @@ if [ -n "$RUNNER" ]; then
348
367
  # stdlib, plus one LOCAL module (_testfile, imported by siblings in the same directory). So there
349
368
  # is no venv to provision, no pip install, no requirements.txt — the interpreter is the whole
350
369
  # requirement, and checking for it is the whole job.
370
+ #
371
+ # UNCONDITIONAL, and it was not. This check sat INSIDE the `[ -n "$RUNNER" ]` block above, so a
372
+ # stack whose settings file declares no runner skipped a stated hard requirement entirely and the
373
+ # install reported ready without it. pipeline-health.sh has always checked python3
374
+ # unconditionally, so the two disagreed about whether the machine was fit to run — and the
375
+ # installer, the one an operator trusts first, was the lenient one.
351
376
  if command -v python3 >/dev/null 2>&1; then
352
377
  _ok "python3 ($(python3 -V 2>&1 | awk '{print $2}')) — 88 handlers need it"
353
378
  else
354
379
  _bad "python3 is not on PATH — 88 pipeline handlers cannot run without it"; FAILED=1
355
380
  fi
356
- fi
357
381
 
358
382
  # ── Credentials: what this stack needs, from what it declares ───────────────
359
383
  _head "Credentials"
@@ -591,9 +615,29 @@ case "$REPLAY_MODE" in
591
615
  # LangfuseTracer.ts:30 gates on BOTH keys. A fresh install has empty volumes, so no project
592
616
  # and no keys exist — and recording is silently off while the containers run and capture
593
617
  # nothing. That is the one case where a warning is not enough.
618
+ # READ THE INSTALL'S .env, NOT THIS SHELL.
619
+ #
620
+ # This tested ${LANGFUSE_SECRET_KEY:-} from the installer's own environment. .env IS loaded
621
+ # earlier — but inside a command substitution (_missing_creds="$( set -a; . .env; ... )"),
622
+ # so it dies with that subshell and never reaches here. An operator whose .env was
623
+ # correctly filled in was told "replay: on but missing: LANGFUSE_SECRET_KEY
624
+ # LANGFUSE_PUBLIC_KEY" and the install FAILED — while the credentials step three sections
625
+ # above read the same file and reported it filled. One file, one run, two answers.
626
+ #
627
+ # A value already exported still wins: an operator who exports the keys in their shell
628
+ # must not start failing because .env does not repeat them. Read in a subshell so the keys
629
+ # are not leaked into everything the installer runs afterwards.
630
+ _lf_sk="${LANGFUSE_SECRET_KEY:-}"
631
+ _lf_pk="${LANGFUSE_PUBLIC_KEY:-}"
632
+ if [ -f "$ROOT/.env" ]; then
633
+ _lf_from_env="$( set -a; . "$ROOT/.env" 2>/dev/null; set +a
634
+ printf '%s\t%s' "${LANGFUSE_SECRET_KEY:-}" "${LANGFUSE_PUBLIC_KEY:-}" )"
635
+ [ -z "$_lf_sk" ] && _lf_sk="$(printf '%s' "$_lf_from_env" | cut -f1)"
636
+ [ -z "$_lf_pk" ] && _lf_pk="$(printf '%s' "$_lf_from_env" | cut -f2)"
637
+ fi
594
638
  _lf_missing=""
595
- [ -z "${LANGFUSE_SECRET_KEY:-}" ] && _lf_missing="$_lf_missing LANGFUSE_SECRET_KEY"
596
- [ -z "${LANGFUSE_PUBLIC_KEY:-}" ] && _lf_missing="$_lf_missing LANGFUSE_PUBLIC_KEY"
639
+ [ -z "$_lf_sk" ] && _lf_missing="$_lf_missing LANGFUSE_SECRET_KEY"
640
+ [ -z "$_lf_pk" ] && _lf_missing="$_lf_missing LANGFUSE_PUBLIC_KEY"
597
641
  if [ -n "$_lf_missing" ]; then
598
642
  _bad "replay: on but missing:$_lf_missing — nothing would be recorded, and a run not recorded can never be replayed"
599
643
  FAILED=1
@@ -649,6 +693,22 @@ compose_up() {
649
693
  fi
650
694
  local _up=1 _log _subnet _i=0
651
695
  _log="$(mktemp)"
696
+
697
+ # A CONTAINER GETS ITS SERVICE ALIAS WHEN IT IS CREATED, AND ONLY THEN.
698
+ #
699
+ # `up -d` leaves an existing container alone. If that container was created while the network
700
+ # create was failing — the pool-overlap case this loop exists to walk past — compose made it
701
+ # unattached and CONNECTED it afterwards, and a plain connect carries no service alias. The
702
+ # stack then comes up with every container healthy and no DNS at all: `getent hosts postgres`
703
+ # unresolved, `nc: bad address`, and langfuse crash-looping on "Can't reach database server"
704
+ # while postgres sits healthy beside it. Measured 2026-09-07 on pipeline-tests-29 — postgres
705
+ # aliases=[] before, aliases=[...-postgres-1 postgres] after a down/up — and it survived three
706
+ # re-installs because every one of them was an `up` over containers that already existed.
707
+ #
708
+ # So a re-install starts them fresh. Volumes are untouched (no -v), which is what keeps the
709
+ # langfuse database and its migrations across installs; only the containers are rebuilt.
710
+ (cd "$ROOT" && container_compose -f "$COMPOSE_FILE" -p "$_OBS_PROJECT" down) >/dev/null 2>&1 || true
711
+
652
712
  for _subnet in $(isolated_subnet_candidates "$ROOT"); do
653
713
  # ATTEMPT 0 KEEPS THE WELL-KNOWN PORTS EXACTLY (offset 0) — a normal single-install machine
654
714
  # sees no change at all, still :3100, :8092, :8123, :3001. Only a genuine collision (this
@@ -866,7 +926,14 @@ else
866
926
  _LD_UP=1
867
927
  _LD_LOG="$(mktemp)"
868
928
  _LD_SUBNET=""; _LD_I=0
869
- for _LD_SUBNET in $(isolated_subnet_candidates "$ROOT"); do
929
+ # SEEDED APART FROM THE OBSERVABILITY STACK. Both used the bare $ROOT, so one install's
930
+ # two stacks were handed the SAME ordered candidates and raced for the first one. Live
931
+ # 2026-09-06 on pipeline-tests-29: the launch dashboard took the subnet the observability
932
+ # stack wanted, that stack's network create then failed, and its retry came up with
933
+ # containers carrying NO network aliases — `getent hosts postgres` unresolved, so langfuse
934
+ # could never reach its database however healthy postgres reported itself. The mock stack
935
+ # has been seeded with "$ROOT-mock" since it was added; this one never was.
936
+ for _LD_SUBNET in $(isolated_subnet_candidates "$ROOT-launch"); do
870
937
  _LD_TRY_PORT=$((_LD_PORT + _LD_I * 10))
871
938
  if (cd "$LAUNCH_DIR" && LAUNCH_SUBNET="$_LD_SUBNET" LAUNCH_UI_PORT="$_LD_TRY_PORT" \
872
939
  container_compose -f "$LAUNCH_COMPOSE" -p "$_LD_PROJECT" up -d --build) >"$_LD_LOG" 2>&1; then
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "amsd-pipeline",
3
- "version": "1.37.0",
3
+ "version": "2.0.0",
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"