Skip to content

Commit 35a338a

Browse files
authored
Merge pull request lightspeed-core#1643 from radofuchs/LCORE_2035_konflux_fix
LCORE-2035 konflux fix
2 parents 48d07fd + 485b77e commit 35a338a

9 files changed

Lines changed: 72 additions & 36 deletions

File tree

requirements-build.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -168,4 +168,4 @@ setuptools==82.0.1
168168
# trl
169169
# trove-classifiers
170170
# tzdata
171-
# vcs-versioning
171+
# vcs-versioning

requirements.hashes.source.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1056,4 +1056,4 @@ uvicorn==0.44.0 \
10561056
--hash=sha256:ce937c99a2cc70279556967274414c087888e8cec9f9c94644dfca11bd3ced89
10571057
wcwidth==0.6.0 \
10581058
--hash=sha256:1a3a1e510b553315f8e146c54764f4fb6264ffad731b3d78088cdb1478ffbdad \
1059-
--hash=sha256:cdc4e4262d6ef9a1a57e018384cbeb1208d8abbc64176027e2c2455c81313159
1059+
--hash=sha256:cdc4e4262d6ef9a1a57e018384cbeb1208d8abbc64176027e2c2455c81313159

requirements.hashes.wheel.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -262,4 +262,4 @@ yarl==1.22.0 \
262262
--hash=sha256:cee8af2825e29b4b31cce0c7272c29b66717ab164e3e2a5dc8dbe173c2901db2 \
263263
--hash=sha256:eb5d90c48762dd433d86eb6e3c6b4965fc3dff440c472e89047a628dd29271ac
264264
zipp==3.23.0 \
265-
--hash=sha256:2f6742e089020240e014478d428fd79059270c56a2f7947d37c6f1d2ae639174
265+
--hash=sha256:2f6742e089020240e014478d428fd79059270c56a2f7947d37c6f1d2ae639174

tests/e2e-prow/rhoai/manifests/lightspeed/lightspeed-stack.yaml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -51,9 +51,9 @@ spec:
5151
- name: config
5252
mountPath: /app-root/lightspeed-stack.yaml
5353
subPath: lightspeed-stack.yaml
54-
# MCPFileAuth E2E: same path as docker-compose (tests/e2e/secrets/mcp-token → secret mcp-file-auth-token)
54+
# MCPFileAuth E2E: must match authorization_headers paths in lightspeed-stack-mcp-file-auth.yaml (/tmp/mcp-token)
5555
- name: mcp-file-auth-token
56-
mountPath: /tmp/mcp-secret-token
56+
mountPath: /tmp/mcp-token
5757
subPath: token
5858
readOnly: true
5959
# InvalidMCPFileAuthConfig E2E: docker-compose mounts tests/e2e/secrets/invalid-mcp-token here

tests/e2e-prow/rhoai/pipeline-konflux.sh

Lines changed: 19 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,7 @@ create_secret() {
6969

7070
create_secret openai-api-key-secret --from-literal=key="$OPENAI_API_KEY"
7171

72-
# MCPFileAuth E2E: file at /tmp/mcp-secret-token in LCS pod (docker-compose mounts tests/e2e/secrets/mcp-token)
72+
# MCPFileAuth E2E: secret mounted at /tmp/mcp-token in LCS pod (same as docker-compose)
7373
if [ -f "$REPO_ROOT/tests/e2e/secrets/mcp-token" ]; then
7474
oc create secret generic mcp-file-auth-token -n "$NAMESPACE" \
7575
--from-file=token="$REPO_ROOT/tests/e2e/secrets/mcp-token" \
@@ -187,6 +187,7 @@ else
187187
log "⚠️ No kv_store.db found at $RAG_DB_PATH"
188188
fi
189189

190+
190191
# ConfigMap for Llama Stack run-from-source (init container clones this repo @ this revision)
191192
REPO_URL="${REPO_URL:-$(cd "$REPO_ROOT" && git config --get remote.origin.url 2>/dev/null)}"
192193
REPO_REVISION="${REPO_REVISION:-$(cd "$REPO_ROOT" && git rev-parse HEAD 2>/dev/null)}"
@@ -200,14 +201,6 @@ log "llama-stack-source ConfigMap: repo @ ${REPO_REVISION}"
200201

201202
"$PIPELINE_DIR/pipeline-services-konflux.sh"
202203

203-
progress "Waiting for lightspeed-stack and llama-stack pods"
204-
if ! oc wait pod/lightspeed-stack-service pod/llama-stack-service \
205-
-n "$NAMESPACE" --for=condition=Ready --timeout=600s; then
206-
progress "❌ One or both service pods failed to become ready within timeout"
207-
exit 1
208-
fi
209-
log "✅ Both service pods are ready"
210-
211204
# Print pod logs with echo so CI/Konflux log capture shows each line (especially when QUIET=1)
212205
e2e_echo_pod_logs() {
213206
local n="${1:-120}"
@@ -221,6 +214,15 @@ e2e_echo_pod_logs() {
221214
done < <(oc logs llama-stack-service -n "$NAMESPACE" --tail="$n" 2>&1) || true
222215
}
223216

217+
progress "Waiting for lightspeed-stack and llama-stack pods"
218+
if ! oc wait pod/lightspeed-stack-service pod/llama-stack-service \
219+
-n "$NAMESPACE" --for=condition=Ready --timeout=600s; then
220+
progress "❌ One or both service pods failed to become ready within timeout"
221+
e2e_echo_pod_logs 200
222+
exit 1
223+
fi
224+
log "✅ Both service pods are ready"
225+
224226
if [ "$QUIET" = "1" ]; then
225227
e2e_echo_pod_logs 80
226228
else
@@ -290,8 +292,10 @@ for i in $(seq 1 36); do
290292
break
291293
fi
292294
if [ $i -eq 36 ]; then
293-
echo "❌ Port-forward to lightspeed-stack never became ready (3 min)"
294-
echo "[e2e] ========== diagnostics: pod logs after port-forward timeout =========="
295+
echo "❌ Port-forward to lightspeed-stack never became ready (3 min)" | tee /dev/stderr
296+
echo "[e2e] ========== diagnostics: pod logs after port-forward timeout ==========" | tee /dev/stderr
297+
trap - ERR
298+
set +e
295299
e2e_echo_pod_logs 250
296300
echo "[e2e] ========== diagnostics: recent events =========="
297301
while IFS= read -r line || [[ -n "$line" ]]; do
@@ -319,8 +323,10 @@ for i in $(seq 1 36); do
319323
break
320324
fi
321325
if [ $i -eq 36 ]; then
322-
echo "❌ Port-forward to llama-stack never became healthy (3 min)"
323-
e2e_echo_pod_logs 200
326+
echo "❌ Port-forward to llama-stack never became healthy (3 min)" | tee /dev/stderr
327+
trap - ERR
328+
set +e
329+
e2e_echo_pod_logs 250
324330
kill $PF_LCS_PID 2>/dev/null || true
325331
kill $PF_JWKS_PID 2>/dev/null || true
326332
kill $PF_LLAMA_PID 2>/dev/null || true

tests/e2e-prow/rhoai/pipeline-services-konflux.sh

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ LIGHTSPEED_STACK_IMAGE="${LIGHTSPEED_STACK_IMAGE:-quay.io/lightspeed-core/lights
3737
export LIGHTSPEED_STACK_IMAGE
3838
LIGHTSPEED_MANIFEST="$BASE_DIR/manifests/lightspeed/lightspeed-stack.yaml"
3939
if command -v envsubst >/dev/null 2>&1; then
40-
envsubst < "$LIGHTSPEED_MANIFEST" | oc apply -n "$NAMESPACE" -f -
40+
envsubst '${LIGHTSPEED_STACK_IMAGE}' < "$LIGHTSPEED_MANIFEST" | oc apply -n "$NAMESPACE" -f -
4141
else
4242
# ubi-minimal etc. may lack gettext; template only expands LIGHTSPEED_STACK_IMAGE
4343
sed "s|\${LIGHTSPEED_STACK_IMAGE}|${LIGHTSPEED_STACK_IMAGE}|g" "$LIGHTSPEED_MANIFEST" |

tests/e2e/features/environment.py

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -145,13 +145,19 @@ def _ensure_prow_port_forward(context: Context) -> None:
145145
146146
Probes localhost:{E2E_LSC_PORT}/readiness — if it fails, calls e2e-ops
147147
restart-port-forward to re-establish the tunnel before the scenario runs.
148+
149+
Treat HTTP 503 like 200/401 here: it means the tunnel reached Lightspeed and the
150+
app responded. ``llama_stack_disrupted`` leaves Llama stopped on purpose; readiness
151+
then returns 503. Previously we treated 503 as a dead tunnel and ran
152+
``restart-lightspeed``, which restores Llama via e2e-ops and breaks later scenarios
153+
that skip disruption (once-per-feature) while expecting Llama to stay down.
148154
"""
149155
host = os.getenv("E2E_LSC_HOSTNAME", "localhost")
150156
port = os.getenv("E2E_LSC_PORT", "8080")
151157
url = f"http://{host}:{port}/readiness"
152158
try:
153159
resp = requests.get(url, timeout=5)
154-
if resp.status_code in (200, 401):
160+
if resp.status_code in (200, 401, 503):
155161
return
156162
except requests.RequestException:
157163
pass

tests/e2e/features/proxy.feature

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,9 @@ Feature: Proxy and TLS networking tests for Llama Stack providers
55
remote inference providers are configured with proxy and TLS settings
66
via the run.yaml NetworkConfig.
77

8-
Query bodies use shield_ids: [] because Llama Guard moderation issues a separate
9-
OpenAI request inside Llama Stack that does not inherit the same proxy/TLS CA
10-
trust as remote::openai inference, which breaks MITM interception tests.
8+
Query bodies use shield_ids: [] because Llama Guard moderation can issue
9+
separate provider calls inside Llama Stack that may not inherit the same
10+
proxy/TLS CA trust as the scenario's remote inference provider.
1111

1212
Background:
1313
Given The service is started locally

tests/e2e/features/steps/proxy.py

Lines changed: 37 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
33
These tests configure Llama Stack's run.yaml with NetworkConfig settings
44
(proxy, TLS) and verify the full pipeline works through the Lightspeed Stack.
5-
The proxy sits between Llama Stack and the LLM provider (e.g., OpenAI).
5+
The proxy sits between Llama Stack and whichever remote LLM provider is active.
66
77
Config switching uses the same pattern as other e2e tests: overwrite the
88
host-mounted run.yaml and restart Docker containers. Restarts are not
@@ -138,17 +138,41 @@ def _write_config(config: dict[str, Any], path: str) -> None:
138138
yaml.dump(config, f, default_flow_style=False)
139139

140140

141-
def _find_openai_provider(config: dict[str, Any]) -> dict[str, Any]:
142-
"""Find the OpenAI inference provider in the config.
141+
def _find_inference_provider(
142+
context: Context, config: dict[str, Any]
143+
) -> dict[str, Any]:
144+
"""Find the target remote inference provider in the config.
145+
146+
Priority:
147+
1. ``context.default_provider`` (detected in ``before_all``), if present.
148+
2. First remote inference provider in ``run.yaml``.
143149
144150
Raises:
145-
AssertionError: If no remote::openai provider is found.
151+
AssertionError: If no suitable remote inference provider is found.
146152
"""
147153
providers = config.get("providers", {})
148-
for provider in providers.get("inference", []):
149-
if provider.get("provider_type") == "remote::openai":
154+
inference_providers = providers.get("inference", [])
155+
target_provider_id = getattr(context, "default_provider", None)
156+
157+
if target_provider_id:
158+
for provider in inference_providers:
159+
if provider.get("provider_id") == target_provider_id:
160+
provider_type = str(provider.get("provider_type", ""))
161+
assert provider_type.startswith("remote::"), (
162+
"Configured default provider "
163+
f"'{target_provider_id}' is not a remote provider in run.yaml"
164+
)
165+
return provider
166+
167+
for provider in inference_providers:
168+
provider_type = str(provider.get("provider_type", ""))
169+
if provider_type.startswith("remote::"):
150170
return provider
151-
raise AssertionError("No remote::openai provider found in run.yaml")
171+
172+
raise AssertionError(
173+
"No remote inference provider found in run.yaml "
174+
"(expected provider_type starting with 'remote::')"
175+
)
152176

153177

154178
def _backup_llama_config() -> None:
@@ -244,7 +268,7 @@ def configure_llama_tunnel_proxy(context: Context) -> None:
244268
proxy = context.tunnel_proxy
245269
proxy_host = _get_proxy_host(context.is_docker_mode)
246270
config = _load_llama_config()
247-
provider = _find_openai_provider(config)
271+
provider = _find_inference_provider(context, config)
248272

249273
if "config" not in provider:
250274
provider["config"] = {}
@@ -262,7 +286,7 @@ def configure_llama_unreachable_proxy(context: Context, proxy_url: str) -> None:
262286
"""Modify run.yaml with a proxy URL (may be unreachable)."""
263287
_backup_llama_config()
264288
config = _load_llama_config()
265-
provider = _find_openai_provider(config)
289+
provider = _find_inference_provider(context, config)
266290

267291
if "config" not in provider:
268292
provider["config"] = {}
@@ -326,7 +350,7 @@ def configure_llama_interception_with_ca(context: Context) -> None:
326350
proxy = context.interception_proxy
327351
proxy_host = _get_proxy_host(context.is_docker_mode)
328352
config = _load_llama_config()
329-
provider = _find_openai_provider(config)
353+
provider = _find_inference_provider(context, config)
330354

331355
if "config" not in provider:
332356
provider["config"] = {}
@@ -353,7 +377,7 @@ def configure_llama_interception_no_ca(context: Context) -> None:
353377
proxy = context.interception_proxy
354378
proxy_host = _get_proxy_host(context.is_docker_mode)
355379
config = _load_llama_config()
356-
provider = _find_openai_provider(config)
380+
provider = _find_inference_provider(context, config)
357381

358382
if "config" not in provider:
359383
provider["config"] = {}
@@ -374,7 +398,7 @@ def configure_llama_tls_version(context: Context, version: str) -> None:
374398
"""Modify run.yaml with TLS version config."""
375399
_backup_llama_config()
376400
config = _load_llama_config()
377-
provider = _find_openai_provider(config)
401+
provider = _find_inference_provider(context, config)
378402

379403
if "config" not in provider:
380404
provider["config"] = {}
@@ -392,7 +416,7 @@ def configure_llama_ciphers(context: Context, ciphers: str) -> None:
392416
"""Modify run.yaml with cipher suite config."""
393417
_backup_llama_config()
394418
config = _load_llama_config()
395-
provider = _find_openai_provider(config)
419+
provider = _find_inference_provider(context, config)
396420

397421
if "config" not in provider:
398422
provider["config"] = {}

0 commit comments

Comments
 (0)