diff --git a/.tekton/lightspeed-stack-pull-request.yaml b/.tekton/lightspeed-stack-pull-request.yaml index fa6eb497d..0419ffd1a 100644 --- a/.tekton/lightspeed-stack-pull-request.yaml +++ b/.tekton/lightspeed-stack-pull-request.yaml @@ -44,6 +44,10 @@ spec: "type": "rpm", "path": "." }, + { + "type": "generic", + "path": "." + }, { "type": "pip", "path": ".", diff --git a/.tekton/lightspeed-stack-push.yaml b/.tekton/lightspeed-stack-push.yaml index 2a038f781..d074a2d11 100644 --- a/.tekton/lightspeed-stack-push.yaml +++ b/.tekton/lightspeed-stack-push.yaml @@ -36,6 +36,10 @@ spec: "type": "rpm", "path": "." }, + { + "type": "generic", + "path": "." + }, { "type": "pip", "path": ".", diff --git a/Containerfile b/Containerfile index 8e79bd999..8adddc50a 100644 --- a/Containerfile +++ b/Containerfile @@ -34,6 +34,33 @@ RUN pip3.12 install "uv>=0.8.15" COPY ${LSC_SOURCE_DIR}/src ./src COPY ${LSC_SOURCE_DIR}/pyproject.toml ${LSC_SOURCE_DIR}/LICENSE ${LSC_SOURCE_DIR}/README.md ${LSC_SOURCE_DIR}/uv.lock ${LSC_SOURCE_DIR}/requirements.*.txt ./ +# lightspeed-providers: +# Fully hermetic — uses prefetched artifact or pinned commit from GitHub +ARG LIGHTSPEED_PROVIDERS_COMMIT=9e073aaaa43a8a5bac38a3bbddbe6cf24842847b +RUN set -eux; \ + ZIP_PATH="/tmp/lightspeed-providers.zip"; \ + EXTRACT_DIR="/tmp/providers"; \ + \ + # Use hermetic pre-fetched artifact if available, otherwise download pinned commit + if [ -f "/cachi2/output/deps/generic/lightspeed-providers.zip" ]; then \ + cp "/cachi2/output/deps/generic/lightspeed-providers.zip" "${ZIP_PATH}"; \ + else \ + curl -fL "https://github.com/lightspeed-core/lightspeed-providers/archive/${LIGHTSPEED_PROVIDERS_COMMIT}.zip" -o "${ZIP_PATH}"; \ + fi; \ + \ + # Extract zip (stdlib zipfile — no unzip RPM; works on minimal Konflux builders) + mkdir -p "${EXTRACT_DIR}"; \ + export ZIP_PATH EXTRACT_DIR; \ + ROOT_DIR="$(python3.12 -c 'import os, zipfile; z=zipfile.ZipFile(os.environ["ZIP_PATH"]); print(z.namelist()[0].split("/")[0])')"; \ + python3.12 -c 'import os, zipfile; zipfile.ZipFile(os.environ["ZIP_PATH"]).extractall(os.environ["EXTRACT_DIR"])'; \ + \ + # Move relevant directories into container filesystem + mv "${EXTRACT_DIR}/${ROOT_DIR}/lightspeed_stack_providers" /app-root/; \ + mv "${EXTRACT_DIR}/${ROOT_DIR}/resources/external_providers" /app-root/providers.d; \ + \ + # Cleanup + rm -rf "${ZIP_PATH}" "${EXTRACT_DIR}" + # Bundle additional dependencies for library mode. # Source cachi2 environment for hermetic builds if available, otherwise use normal installation # cachi2.env has these env vars: @@ -99,6 +126,10 @@ RUN mkdir -p /opt/app-root/src/.cache/huggingface && \ # Add executables from .venv to system PATH ENV PATH="/app-root/.venv/bin:$PATH" +# Library mode: Llama Stack expects external provider configs under a path named providers.d (hardcoded). +# We place them at /app-root/providers.d. YAMLs there reference lightspeed_stack_providers.*, so that package must be on PYTHONPATH. +ENV PYTHONPATH="/app-root" + # Run the application EXPOSE 8080 ENTRYPOINT ["python3.12", "src/lightspeed_stack.py"] diff --git a/Makefile b/Makefile index f324cd32b..0bf77aec7 100644 --- a/Makefile +++ b/Makefile @@ -124,6 +124,9 @@ konflux-requirements: ## Generate hermetic requirements.*.txt file for konflux b konflux-rpm-lock: ## Generate rpm.lock.yaml file for konflux build ./scripts/generate-rpm-lock.sh +konflux-artifacts-lock: ## Regenerate artifacts.lock.yaml file for konflux build + ./scripts/generate-artifacts-lock.sh + help: ## Show this help screen @echo 'Usage: make ... ' @echo '' diff --git a/artifacts.lock.yaml b/artifacts.lock.yaml new file mode 100644 index 000000000..182c615b8 --- /dev/null +++ b/artifacts.lock.yaml @@ -0,0 +1,8 @@ +# Regenerated by: make konflux-artifacts-lock (from lightspeed-providers.revision) +metadata: + version: "1.0" + +artifacts: + - download_url: https://github.com/lightspeed-core/lightspeed-providers/archive/9e073aaaa43a8a5bac38a3bbddbe6cf24842847b.zip + checksum: sha256:52cd105c351c3645b0b0fbc7c06df5ca200274b843f82f97dfbbb8918aac3a11 + filename: lightspeed-providers.zip diff --git a/scripts/generate-artifacts-lock.sh b/scripts/generate-artifacts-lock.sh new file mode 100755 index 000000000..602c44710 --- /dev/null +++ b/scripts/generate-artifacts-lock.sh @@ -0,0 +1,30 @@ +#!/usr/bin/env bash +# Recompute sha256 for the archive at artifacts.lock.yaml download_url and update checksum only. +# +# Maintainer flow: set download_url to the GitHub archive URL for the desired commit (and update the +# optional revision comment). Hermeto rejects extra YAML keys (name, type, source, revision) on artifacts. +# Run this script to refresh the checksum line only. +# +# Usage: +# make konflux-artifacts-lock + +set -euo pipefail + +ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)" +LOCK="${ROOT}/artifacts.lock.yaml" +TMP="$(mktemp)" +trap 'rm -f "${TMP}"' EXIT + +URL="$(grep -m1 '^[[:space:]]*download_url:' "${LOCK}" | sed -E 's/^[[:space:]]*download_url:[[:space:]]*//' | tr -d "'\"")" +if [[ -z "${URL}" ]]; then + echo "ERROR: could not parse download_url from ${LOCK}" >&2 + exit 1 +fi + +echo "Downloading ${URL}" +curl -fsSL "${URL}" -o "${TMP}" +SUM="$(sha256sum "${TMP}" | awk '{print $1}')" + +sed -i "s/^\([[:space:]]*checksum: \)sha256:[a-fA-F0-9]*/\1sha256:${SUM}/" "${LOCK}" + +echo "Updated checksum in ${LOCK} (sha256:${SUM})"