diff --git a/.github/workflows/e2e-playwright.yaml b/.github/workflows/e2e-playwright.yaml index 00ab34091..e974155d3 100644 --- a/.github/workflows/e2e-playwright.yaml +++ b/.github/workflows/e2e-playwright.yaml @@ -123,7 +123,7 @@ jobs: rm packages/ui/zarf-package-leapfrogai-ui-amd64-e2e-test.tar.zst # Run the playwright UI tests using the deployed Supabase endpoint and upload report as an artifact - # Note - workflow doesn't need teardown and causes import issues + # NOTE: the workflow doesn't need `global.teardown.ts` and it also causes import issues - name: UI/API/Supabase E2E Playwright Tests run: | cp src/leapfrogai_ui/.env.example src/leapfrogai_ui/.env diff --git a/.github/workflows/nightly-uds-badge-verification.yaml b/.github/workflows/nightly-uds-badge-verification.yaml index 12060fc3d..eb6c69b5e 100644 --- a/.github/workflows/nightly-uds-badge-verification.yaml +++ b/.github/workflows/nightly-uds-badge-verification.yaml @@ -29,6 +29,7 @@ jobs: uds-badge-verification: runs-on: ai-ubuntu-big-boy-8-core name: nightly_uds_badge_verification + if: ${{ !github.event.pull_request.draft }} steps: - name: Checkout Repo diff --git a/.github/workflows/pytest.yaml b/.github/workflows/pytest.yaml index f906032a3..8a45a86d6 100644 --- a/.github/workflows/pytest.yaml +++ b/.github/workflows/pytest.yaml @@ -3,11 +3,11 @@ name: pytest on: pull_request: types: - - opened # default trigger - - reopened # default trigger - - synchronize # default trigger - - ready_for_review # don't run on draft PRs - - milestoned # allows us to trigger on bot PRs + - opened # default trigger + - reopened # default trigger + - synchronize # default trigger + - ready_for_review # don't run on draft PRs + - milestoned # allows us to trigger on bot PRs paths: - "**" - "!.github/**" @@ -58,10 +58,10 @@ jobs: - name: Setup Repeater env: - LOCAL_VERSION: e2e-test + VERSION: e2e-test run: | - make docker-repeater - docker run -p 50051:50051 -d --name=repeater ghcr.io/defenseunicorns/leapfrogai/repeater:$LOCAL_VERSION + uds run create:repeater-image --set VERSION=${VERSION} + uds run deploy:repeater-image --set VERSION=${VERSION} - name: Run Pytest run: make test-api-unit @@ -90,10 +90,10 @@ jobs: - name: Setup Repeater env: - LOCAL_VERSION: e2e-test + VERSION: e2e-test run: | - make docker-repeater - docker run -p 50051:50051 -d --name=repeater ghcr.io/defenseunicorns/leapfrogai/repeater:$LOCAL_VERSION + uds run create:repeater-image --set VERSION=${VERSION} + uds run deploy:repeater-image --set VERSION=${VERSION} - name: Setup UDS Cluster uses: ./.github/actions/uds-cluster diff --git a/.github/workflows/weekly-registry1-flavor-test.yaml b/.github/workflows/weekly-registry1-flavor-test.yaml index 4fca5b5fe..69cc2e9a3 100644 --- a/.github/workflows/weekly-registry1-flavor-test.yaml +++ b/.github/workflows/weekly-registry1-flavor-test.yaml @@ -75,11 +75,18 @@ jobs: - name: Mutation of the Zarf Packages run: | + # API uds zarf tools yq -i ' .components[].images[0] |= sub(":v[0-9\.]+$", ":v${{ steps.get_version.outputs.LFAI_VERSION }}") ' packages/api/zarf.yaml uds zarf tools yq -i '.api.image.tag = "v${{ steps.get_version.outputs.LFAI_VERSION }}"' packages/api/values/registry1-values.yaml + # UI + uds zarf tools yq -i ' + .components[].images[0] |= sub(":v[0-9\.]+$", ":v${{ steps.get_version.outputs.LFAI_VERSION }}") + ' packages/ui/zarf.yaml + uds zarf tools yq -i '.ui.image.tag = "v${{ steps.get_version.outputs.LFAI_VERSION }}"' packages/api/values/registry1-values.yaml + - name: Print the Modified Zarf Packages run: | cat packages/api/zarf.yaml @@ -97,10 +104,16 @@ jobs: uds zarf tools yq -i '.packages[].ref |= sub("^[^ ]+-upstream$", "${{ steps.get_version.outputs.LFAI_VERSION }}-upstream")' bundles/latest/cpu/uds-bundle.yaml + # API uds zarf tools yq -i '.packages[1] |= del(.repository)' bundles/latest/cpu/uds-bundle.yaml uds zarf tools yq -i '.packages[1] |= .ref = "${{ steps.get_version.outputs.LFAI_VERSION }}"' bundles/latest/cpu/uds-bundle.yaml uds zarf tools yq -i '.packages[1] |= .path = "../../../"' bundles/latest/cpu/uds-bundle.yaml + # UI + uds zarf tools yq -i '.packages[5] |= del(.repository)' bundles/latest/cpu/uds-bundle.yaml + uds zarf tools yq -i '.packages[5] |= .ref = "${{ steps.get_version.outputs.LFAI_VERSION }}"' bundles/latest/cpu/uds-bundle.yaml + uds zarf tools yq -i '.packages[5] |= .path = "../../../"' bundles/latest/cpu/uds-bundle.yaml + - name: Print the Modified UDS Bundle run: | cat bundles/latest/cpu/uds-config.yaml @@ -152,6 +165,8 @@ jobs: npm --prefix src/leapfrogai_ui ci npx --prefix src/leapfrogai_ui playwright install + # NOTE: the workflow doesn't need `global.teardown.ts` and it also causes import issues + # TODO: some tests on main for `api-keys.test.ts` are failing in 0.13.1, re-enable post-0.13.1 - name: Run Playwright E2E Tests env: SERVICE_ROLE_KEY: ${{ steps.generate_secrets.outputs.SERVICE_KEY }} @@ -165,6 +180,9 @@ jobs: mkdir -p playwright/auth touch playwright/auth.user.json + rm src/leapfrogai_ui/tests/api-keys.test.ts + rm src/leapfrogai_ui/tests/global.teardown.ts + SERVICE_ROLE_KEY=$SERVICE_ROLE_KEY TEST_ENV=CI USERNAME=doug PASSWORD=$FAKE_E2E_USER_PASSWORD PUBLIC_SUPABASE_ANON_KEY=$ANON_KEY DEFAULT_MODEL=llama-cpp-python npm --prefix src/leapfrogai_ui run test:integration:ci - name: Archive Playwright Report diff --git a/Makefile b/Makefile index da9266246..5280f6c70 100644 --- a/Makefile +++ b/Makefile @@ -10,14 +10,6 @@ SILENT_ZARF_FLAGS := --no-progress -l warn --no-color MAX_JOBS := 4 ###################################################################################### -.PHONY: help -help: ## Display this help information - @grep -E '^[a-zA-Z0-9_-]+:.*?## .*$$' $(MAKEFILE_LIST) \ - | sort | awk 'BEGIN {FS = ":.*?## "}; \ - {printf "\033[36m%-30s\033[0m %s\n", $$1, $$2}' - -## Clean up targets for test artifacts, cachce, etc. -include mk-clean.mk gen-python: ## Generate the protobufs for the OpenAI typing within the leapfrogai_api module python3 -m grpc_tools.protoc -I src/leapfrogai_sdk/proto \ @@ -26,148 +18,12 @@ gen-python: ## Generate the protobufs for the OpenAI typing within the leapfroga --grpc_python_out=src/. \ src/leapfrogai_sdk/proto/leapfrogai_sdk/**/*.proto -local-registry: ## Start up a local container registry. Errors in this target are ignored. - @echo "Creating local Docker registry..." - -@docker run -d -p ${REG_PORT}:5000 --restart=always --name ${REG_NAME} registry:2 - @echo "Local registry created at localhost:${REG_PORT}" - - # Clean up: Stop and remove the local registry clean-registry: @echo "Cleaning up..." @docker stop ${REG_NAME} @docker rm ${REG_NAME} -sdk-wheel: ## build wheels for the leapfrogai_sdk package as a dependency for other lfai components - docker build ${DOCKER_FLAGS} --platform=linux/${ARCH} -t ghcr.io/defenseunicorns/leapfrogai/leapfrogai-sdk:${LOCAL_VERSION} -f src/leapfrogai_sdk/Dockerfile . - -docker-supabase: - ## Build the migration container for this version of the supabase package - docker build ${DOCKER_FLAGS} -t ghcr.io/defenseunicorns/leapfrogai/supabase-migrations:${LOCAL_VERSION} -f Dockerfile.migrations --build-arg="MIGRATIONS_DIR=packages/supabase/migrations" . - docker tag ghcr.io/defenseunicorns/leapfrogai/supabase-migrations:${LOCAL_VERSION} localhost:${REG_PORT}/defenseunicorns/leapfrogai/supabase-migrations:${LOCAL_VERSION} - -build-supabase: local-registry docker-supabase - docker push ${DOCKER_FLAGS} localhost:${REG_PORT}/defenseunicorns/leapfrogai/supabase-migrations:${LOCAL_VERSION} - - ## Build the Zarf package - uds zarf package create packages/supabase --flavor ${FLAVOR} -a ${ARCH} -o packages/supabase --registry-override=ghcr.io=localhost:${REG_PORT} --set IMAGE_VERSION=${LOCAL_VERSION} ${ZARF_FLAGS} --confirm - -docker-api: local-registry sdk-wheel - @echo $(DOCKER_FLAGS) - @echo $(ZARF_FLAGS) - - ## Build the API image (and tag it for the local registry) - docker build ${DOCKER_FLAGS} --platform=linux/${ARCH} --build-arg LOCAL_VERSION=${LOCAL_VERSION} -t ghcr.io/defenseunicorns/leapfrogai/leapfrogai-api:${LOCAL_VERSION} -f packages/api/Dockerfile . - docker tag ghcr.io/defenseunicorns/leapfrogai/leapfrogai-api:${LOCAL_VERSION} localhost:${REG_PORT}/defenseunicorns/leapfrogai/leapfrogai-api:${LOCAL_VERSION} - - ## Build the migration container for this version of the API - docker build ${DOCKER_FLAGS} --platform=linux/${ARCH} -t ghcr.io/defenseunicorns/leapfrogai/api-migrations:${LOCAL_VERSION} -f Dockerfile.migrations --build-arg="MIGRATIONS_DIR=packages/api/supabase/migrations" . - docker tag ghcr.io/defenseunicorns/leapfrogai/api-migrations:${LOCAL_VERSION} localhost:${REG_PORT}/defenseunicorns/leapfrogai/api-migrations:${LOCAL_VERSION} - -## If registry1, don't locally Docker-build anything -ifeq ($(FLAVOR),upstream) - DOCKER_TARGETS := local-registry docker-api -else - DOCKER_TARGETS := -endif - -build-api: $(DOCKER_TARGETS) ## Build the leapfrogai_api container and Zarf package - ## Only push to local registry and build if this is an upstream-flavored package -ifeq ($(FLAVOR),upstream) - ## Push the images to the local registry (Zarf is super slow if the image is only in the local daemon) - docker push ${DOCKER_FLAGS} localhost:${REG_PORT}/defenseunicorns/leapfrogai/leapfrogai-api:${LOCAL_VERSION} - docker push ${DOCKER_FLAGS} localhost:${REG_PORT}/defenseunicorns/leapfrogai/api-migrations:${LOCAL_VERSION} - ## Build the Zarf package - uds zarf package create packages/api --flavor ${FLAVOR} -a ${ARCH} -o packages/api --registry-override=ghcr.io=localhost:${REG_PORT} --insecure --set IMAGE_VERSION=${LOCAL_VERSION} ${ZARF_FLAGS} --confirm -else - ## Build the registry1 Zarf package - ZARF_CONFIG=packages/api/zarf-config.yaml uds zarf package create packages/api --flavor ${FLAVOR} -a ${ARCH} -o packages/api ${ZARF_FLAGS} --confirm -endif - -docker-ui: - ## Build the UI image (and tag it for the local registry) - docker build ${DOCKER_FLAGS} --platform=linux/${ARCH} -t ghcr.io/defenseunicorns/leapfrogai/leapfrogai-ui:${LOCAL_VERSION} src/leapfrogai_ui - docker tag ghcr.io/defenseunicorns/leapfrogai/leapfrogai-ui:${LOCAL_VERSION} localhost:${REG_PORT}/defenseunicorns/leapfrogai/leapfrogai-ui:${LOCAL_VERSION} - - ## Build the migration container for the version of the UI - docker build ${DOCKER_FLAGS} --platform=linux/${ARCH} -t ghcr.io/defenseunicorns/leapfrogai/ui-migrations:${LOCAL_VERSION} -f Dockerfile.migrations --build-arg="MIGRATIONS_DIR=src/leapfrogai_ui/supabase/migrations" . - docker tag ghcr.io/defenseunicorns/leapfrogai/ui-migrations:${LOCAL_VERSION} localhost:${REG_PORT}/defenseunicorns/leapfrogai/ui-migrations:${LOCAL_VERSION} - -build-ui: local-registry docker-ui ## Build the leapfrogai_ui container and Zarf package - ## Push the image to the local registry (Zarf is super slow if the image is only in the local daemon) - docker push ${DOCKER_FLAGS} localhost:${REG_PORT}/defenseunicorns/leapfrogai/leapfrogai-ui:${LOCAL_VERSION} - docker push ${DOCKER_FLAGS} localhost:${REG_PORT}/defenseunicorns/leapfrogai/ui-migrations:${LOCAL_VERSION} - - ## Build the Zarf package - uds zarf package create packages/ui --flavor ${FLAVOR} -a ${ARCH} -o packages/ui --registry-override=ghcr.io=localhost:${REG_PORT} --insecure --set IMAGE_VERSION=${LOCAL_VERSION} ${ZARF_FLAGS} --confirm - -docker-llama-cpp-python: sdk-wheel - ## Build the image (and tag it for the local registry) - docker build ${DOCKER_FLAGS} --platform=linux/${ARCH} --build-arg LOCAL_VERSION=${LOCAL_VERSION} -t ghcr.io/defenseunicorns/leapfrogai/llama-cpp-python:${LOCAL_VERSION} -f packages/llama-cpp-python/Dockerfile . - docker tag ghcr.io/defenseunicorns/leapfrogai/llama-cpp-python:${LOCAL_VERSION} localhost:${REG_PORT}/defenseunicorns/leapfrogai/llama-cpp-python:${LOCAL_VERSION} - -build-llama-cpp-python: local-registry docker-llama-cpp-python ## Build the llama-cpp-python (cpu) container and Zarf package - ## Push the image to the local registry (Zarf is super slow if the image is only in the local daemon) - docker push ${DOCKER_FLAGS} localhost:${REG_PORT}/defenseunicorns/leapfrogai/llama-cpp-python:${LOCAL_VERSION} - - ## Build the Zarf package - uds zarf package create packages/llama-cpp-python --flavor ${FLAVOR} -a ${ARCH} -o packages/llama-cpp-python --registry-override=ghcr.io=localhost:${REG_PORT} --insecure --set IMAGE_VERSION=${LOCAL_VERSION} ${ZARF_FLAGS} --confirm - -docker-vllm: sdk-wheel - ## Build the image (and tag it for the local registry) - docker build ${DOCKER_FLAGS} --platform=linux/${ARCH} --build-arg LOCAL_VERSION=${LOCAL_VERSION} -t ghcr.io/defenseunicorns/leapfrogai/vllm:${LOCAL_VERSION} -f packages/vllm/Dockerfile . - docker tag ghcr.io/defenseunicorns/leapfrogai/vllm:${LOCAL_VERSION} localhost:${REG_PORT}/defenseunicorns/leapfrogai/vllm:${LOCAL_VERSION} - -build-vllm: local-registry docker-vllm ## Build the vllm container and Zarf package - ## Push the image to the local registry (Zarf is super slow if the image is only in the local daemon) - docker push ${DOCKER_FLAGS} localhost:${REG_PORT}/defenseunicorns/leapfrogai/vllm:${LOCAL_VERSION} - - ## Build the Zarf package - ZARF_CONFIG=packages/vllm/zarf-config.yaml uds zarf package create packages/vllm --flavor ${FLAVOR} -a ${ARCH} -o packages/vllm --registry-override=ghcr.io=localhost:${REG_PORT} --insecure --set IMAGE_VERSION=${LOCAL_VERSION} ${ZARF_FLAGS} --confirm - -docker-text-embeddings: sdk-wheel - ## Build the image (and tag it for the local registry) - docker build ${DOCKER_FLAGS} --platform=linux/${ARCH} --build-arg LOCAL_VERSION=${LOCAL_VERSION} -t ghcr.io/defenseunicorns/leapfrogai/text-embeddings:${LOCAL_VERSION} -f packages/text-embeddings/Dockerfile . - docker tag ghcr.io/defenseunicorns/leapfrogai/text-embeddings:${LOCAL_VERSION} localhost:${REG_PORT}/defenseunicorns/leapfrogai/text-embeddings:${LOCAL_VERSION} - -build-text-embeddings: local-registry docker-text-embeddings ## Build the text-embeddings container and Zarf package - ## Push the image to the local registry (Zarf is super slow if the image is only in the local daemon) - docker push ${DOCKER_FLAGS} localhost:${REG_PORT}/defenseunicorns/leapfrogai/text-embeddings:${LOCAL_VERSION} - - ## Build the Zarf package - uds zarf package create packages/text-embeddings --flavor ${FLAVOR} -a ${ARCH} -o packages/text-embeddings --registry-override=ghcr.io=localhost:${REG_PORT} --insecure --set IMAGE_VERSION=${LOCAL_VERSION} ${ZARF_FLAGS} --confirm - - -docker-whisper: sdk-wheel - ## Build the image (and tag it for the local registry) - docker build ${DOCKER_FLAGS} --platform=linux/${ARCH} --build-arg LOCAL_VERSION=${LOCAL_VERSION} -t ghcr.io/defenseunicorns/leapfrogai/whisper:${LOCAL_VERSION} -f packages/whisper/Dockerfile . - docker tag ghcr.io/defenseunicorns/leapfrogai/whisper:${LOCAL_VERSION} localhost:${REG_PORT}/defenseunicorns/leapfrogai/whisper:${LOCAL_VERSION} - -build-whisper: local-registry docker-whisper ## Build the whisper container and zarf package - ## Push the image to the local registry (Zarf is super slow if the image is only in the local daemon) - docker push ${DOCKER_FLAGS} localhost:${REG_PORT}/defenseunicorns/leapfrogai/whisper:${LOCAL_VERSION} - - ## Build the Zarf package - uds zarf package create packages/whisper --flavor ${FLAVOR} -a ${ARCH} -o packages/whisper --registry-override=ghcr.io=localhost:${REG_PORT} --insecure --set IMAGE_VERSION=${LOCAL_VERSION} ${ZARF_FLAGS} --confirm - -docker-repeater: sdk-wheel - ## Build the image (and tag it for the local registry) - docker build ${DOCKER_FLAGS} --platform=linux/${ARCH} --build-arg LOCAL_VERSION=${LOCAL_VERSION} -t ghcr.io/defenseunicorns/leapfrogai/repeater:${LOCAL_VERSION} -f packages/repeater/Dockerfile . - docker tag ghcr.io/defenseunicorns/leapfrogai/repeater:${LOCAL_VERSION} localhost:${REG_PORT}/defenseunicorns/leapfrogai/repeater:${LOCAL_VERSION} - -build-repeater: local-registry docker-repeater ## Build the repeater container and zarf package - ## Push the image to the local registry (Zarf is super slow if the image is only in the local daemon) - docker push ${DOCKER_FLAGS} localhost:${REG_PORT}/defenseunicorns/leapfrogai/repeater:${LOCAL_VERSION} - - ## Build the Zarf package - uds zarf package create packages/repeater --flavor ${FLAVOR} -a ${ARCH} -o packages/repeater --registry-override=ghcr.io=localhost:${REG_PORT} --insecure --set IMAGE_VERSION=${LOCAL_VERSION} ${ZARF_FLAGS} --confirm - -build-cpu: build-supabase build-api build-ui build-llama-cpp-python build-text-embeddings build-whisper ## Build all zarf packages for a cpu-enabled deployment of LFAI - -build-gpu: build-supabase build-api build-ui build-vllm build-text-embeddings build-whisper ## Build all zarf packages for a gpu-enabled deployment of LFAI - -build-all: build-cpu build-gpu ## Build all of the LFAI packages - include tests/Makefile include packages/k3d-gpu/Makefile @@ -306,35 +162,3 @@ silent-deploy-gpu: @echo "Deploying UI..." @$(MAKE) silent-deploy-ui-package ZARF_FLAGS="${ZARF_FLAGS} ${SILENT_ZARF_FLAGS} --set=MODEL='vllm'" @echo "All deployments completed" - -silent-fresh-leapfrogai-gpu: - @echo "Cleaning up previous artifacts..." - @$(MAKE) clean-artifacts > /dev/null 2>&1 - @echo "Logs at .logs/*.log" - @mkdir -p .logs - @echo "Creating a uds gpu enabled cluster..." - @$(MAKE) create-uds-gpu-cluster DOCKER_FLAGS="${SILENT_DOCKER_FLAGS}" ZARF_FLAGS="${SILENT_ZARF_FLAGS}" > .logs/create-uds-gpu-cluster.log 2>&1 - @echo "Testing the uds gpu cluster..." - @$(MAKE) test-uds-gpu-cluster > .logs/test-uds-gpu-cluster.log 2>&1 - @echo "Building all packages..." - @$(MAKE) silent-build-gpu - @echo "Deploying all packages..." - @$(MAKE) silent-deploy-gpu - @echo "Done!" - @echo "UI is available at https://ai.uds.dev" - @echo "API is available at https://leapfrogai-api.uds.dev" - -silent-fresh-leapfrogai-cpu: - @echo "Cleaning up previous artifacts..." - @$(MAKE) clean-artifacts > /dev/null 2>&1 - @echo "Logs at .logs/*.log" - @mkdir -p .logs - @echo "Creating a uds cpu-only cluster..." - @$(MAKE) create-uds-cpu-cluster DOCKER_FLAGS="${SILENT_DOCKER_FLAGS}" ZARF_FLAGS="${SILENT_ZARF_FLAGS}" > .logs/create-uds-cpu-cluster.log 2>&1 - @echo "Building all packages..." - @$(MAKE) silent-build-cpu - @echo "Deploying all packages..." - @$(MAKE) silent-deploy-cpu - @echo "Done!" - @echo "UI is available at https://ai.uds.dev" - @echo "API is available at https://leapfrogai-api.uds.dev" diff --git a/README.md b/README.md index 2429da763..65974c479 100644 --- a/README.md +++ b/README.md @@ -77,6 +77,8 @@ leapfrogai/ ├── bundles/ │ ├── dev/ # uds bundles for local uds dev deployments │ └── latest/ # uds bundles for the most current uds deployments +├── tasks/ # uds task sub-modules (e.g., create, deploy, setup, etc.) +├── task.yaml # uds tasks for declarative, local development and CI, workflows ├── Makefile ├── pyproject.toml ├── README.md @@ -136,7 +138,7 @@ Below is the current component flavors list: | Component | `upstream` | `registry1` | | ---------------------------------------------- | ------------ | ------------- | | [api](packages/api/) | ✅ | ✅ | -| [ui](packages/ui/) | ✅ | 🚧 | +| [ui](packages/ui/) | ✅ | ✅ | | [supabase](packages/supabase/) | ✅ | 🚧 | | [migrations](./Dockerfile.migrations) | ✅ | 🚧 | | [llama-cpp-python](packages/llama-cpp-python/) | ✅ | 🚧 | diff --git a/mk-clean.mk b/mk-clean.mk deleted file mode 100644 index 4ca00ae89..000000000 --- a/mk-clean.mk +++ /dev/null @@ -1,31 +0,0 @@ - -clean-all: clean-artifacts clean-cache clean-env clean-logs clean-models - - -clean-artifacts: # Zarf packages, UDS bundles, Python build artifacts, etc. - -rm zarf-package-*.tar.zst - -rm packages/**/zarf-package-*.tar.zst - -rm -rf build - -rm -rf src/**/build - -rm -rf packages/**/build - find . -name 'uds-bundle-*-*.tar.zst' -delete - find . -type d -name 'zarf-sbom' -exec rm -rf {} + - find . -name '*.whl' -delete - find . -type d -name '*.egg-info' -exec rm -rf {} + - -clean-cache: - -rm -rf ./**/__pycache__ ./**/*/__pycache__ ./**/**/*/__pycache__ - -rm -rf ./.ruff_cache ./**/*/.ruff_cache ./**/.ruff_cache - -rm -rf ./.pytest_cache ./**/.pytest_cache ./**/*/.pytest_cache - -rm -rf ./.mypy_cache - -clean-env: - rm -f .env - rm -f .env.email - rm -f .env.password - -clean-logs: - -rm -rf ./.logs - -clean-models: - -rm -rf ./packages/**/.model diff --git a/packages/k3d-gpu/Makefile b/packages/k3d-gpu/Makefile deleted file mode 100644 index d9971f00c..000000000 --- a/packages/k3d-gpu/Makefile +++ /dev/null @@ -1,34 +0,0 @@ -MAKEFILE_DIR := $(dir $(abspath $(lastword $(MAKEFILE_LIST)))) - -UDS_VERSION := k3d-core-slim-dev:0.26.1 -LOCAL_VERSION ?= $(shell git rev-parse --short HEAD) -DOCKER_FLAGS := -ZARF_FLAGS := - -build-k3d-gpu: - @cd ${MAKEFILE_DIR} && \ - docker build \ - ${DOCKER_FLAGS} \ - --platform linux/amd64 \ - -t ghcr.io/defenseunicorns/leapfrogai/k3d-gpu:${LOCAL_VERSION} . - -create-uds-gpu-cluster: build-k3d-gpu - @uds deploy ${UDS_VERSION} \ - ${ZARF_FLAGS} \ - --set K3D_EXTRA_ARGS="--gpus=all \ - --image=ghcr.io/defenseunicorns/leapfrogai/k3d-gpu:${LOCAL_VERSION}" --confirm - -create-uds-cpu-cluster: - @uds deploy ${UDS_VERSION} \ - ${ZARF_FLAGS} \ - --confirm - -test-uds-gpu-cluster: - @cd ${MAKEFILE_DIR} && \ - uds zarf tools kubectl apply -f ./test/cuda-vector-add.yaml - @uds zarf tools kubectl wait --for=jsonpath='{.status.phase}'=Succeeded --timeout=15s pod -l app=gpu-pod - @uds zarf tools kubectl logs -l app=gpu-pod - @cd ${MAKEFILE_DIR} && \ - uds zarf tools kubectl delete -f ./test/cuda-vector-add.yaml - -.PHONY: build-k3d-gpu create-uds-gpu-cluster create-uds-cpu-cluster test-uds-gpu-cluster diff --git a/packages/k3d-gpu/README.md b/packages/k3d-gpu/README.md index 1a67e353b..8d2837000 100644 --- a/packages/k3d-gpu/README.md +++ b/packages/k3d-gpu/README.md @@ -13,25 +13,25 @@ All system requirements and pre-requisites from the [LeapfrogAI documentation we ### Deployment > [!NOTE] -> The following Make targets can be executed from the root of the LeapfrogAI repository or within this sub-directory. +> The following UDS Tasks must be executed from the root of the LeapfrogAI repository. To deploy a new K3d cluster with [UDS Core Slim Dev](https://github.com/defenseunicorns/uds-core#uds-package-development), use one of the following Make targets. ```bash -make create-uds-gpu-cluster # create a uds cluster equipped with the k3d-gpu image +uds run setup:k3d-gpu-cluster-slim # create a uds cluster equipped with the k3d-gpu image -make test-uds-gpu-cluster # deploy a test gpu pod to see if everything is working +uds run test:k3d-gpu-cluster # deploy a test gpu pod to see if everything is working ``` ### Local Development > [!NOTE] -> The following Make targets can be executed from the root of the LeapfrogAI repository or within this sub-directory +> The following UDS Tasks must be executed from the root of the LeapfrogAI repository. To build **just** the K3s CUDA image for container debugging, use the following Make target. ```bash -make build-k3d-gpu # build the image +uds run create:k3d-gpu-image # build the image ``` ## References diff --git a/packages/ui/common/zarf.yaml b/packages/ui/common/zarf.yaml new file mode 100644 index 000000000..1768d5170 --- /dev/null +++ b/packages/ui/common/zarf.yaml @@ -0,0 +1,34 @@ +# yaml-language-server: $schema=https://raw.githubusercontent.com/defenseunicorns/uds-cli/v0.14.0/zarf.schema.json + +kind: ZarfPackageConfig +metadata: + description: "LeapfrogAI UI common" + name: leapfrogai-ui-common + version: "###ZARF_PKG_TMPL_IMAGE_VERSION###" + +components: + - name: leapfrogai-ui + description: "A UI for LeapfrogAI" + required: true + charts: + - name: leapfrogai-ui + namespace: leapfrogai + localPath: ../chart + # x-release-please-start-version + version: 0.13.1 + # x-release-please-end + actions: + onDeploy: + after: + - wait: + cluster: + kind: Job + name: leapfrogai-ui-migrations-###ZARF_PKG_TMPL_IMAGE_VERSION### + namespace: leapfrogai + condition: complete + - wait: + cluster: + kind: Deployment + name: leapfrogai-ui + namespace: leapfrogai + condition: Available diff --git a/packages/ui/values/registry1-values.yaml b/packages/ui/values/registry1-values.yaml new file mode 100644 index 000000000..6ce6fdd7f --- /dev/null +++ b/packages/ui/values/registry1-values.yaml @@ -0,0 +1,48 @@ +image: + repository: "registry1.dso.mil/ironbank/opensource/defenseunicorns/leapfrogai/ui" + tag: v###ZARF_CONST_IMAGE_VERSION### + +env: + - name: LEAPFROGAI_API_BASE_URL + value: "###ZARF_VAR_LEAPFROGAI_API_BASE_URL###" + - name: ORIGIN + value: "https://###ZARF_VAR_SUBDOMAIN###.###ZARF_VAR_DOMAIN###" + - name: DEFAULT_MODEL + value: "###ZARF_VAR_MODEL###" + - name: DEFAULT_SYSTEM_PROMPT + value: "###ZARF_VAR_SYSTEM_PROMPT###" + - name: DEFAULT_TEMPERATURE + value: "###ZARF_VAR_TEMPERATURE###" + - name: OPENAI_API_KEY + value: "###ZARF_VAR_OPENAI_API_KEY###" + - name: PUBLIC_SUPABASE_URL + value: "https://supabase-kong.###ZARF_VAR_DOMAIN###" + - name: PUBLIC_DISABLE_KEYCLOAK + value: "###ZARF_VAR_DISABLE_KEYCLOAK###" + - name: PUBLIC_MESSAGE_LENGTH_LIMIT + value: "10000" + - name: SUPABASE_AUTH_EXTERNAL_KEYCLOAK_URL + value: "https://sso.uds.dev/realms/uds" + - name: SUPABASE_AUTH_KEYCLOAK_CLIENT_ID + valueFrom: + secretKeyRef: + name: sso-client-uds-supabase + key: clientId + - name: SUPABASE_AUTH_KEYCLOAK_SECRET + valueFrom: + secretKeyRef: + name: sso-client-uds-supabase + key: secret + +extraEnv: + # Only required when Supabase is hosted via PaaS outside of the cluster + supabaseAnonKey: "###ZARF_VAR_SUPABASE_ANON_KEY###" + # UDS package CR hosting subdomain (e.g. `ai` will produce a VirtualService with `ai.uds.dev`) + host: "###ZARF_VAR_SUBDOMAIN###" + +migration: + image: + # TODO: replace with Ironbank image once hardened: registry1.dso.mil/ironbank/opensource/defenseunicorns/leapfrogai/ui/migrations + repository: ghcr.io/defenseunicorns/leapfrogai/ui-migrations + tag: "###ZARF_CONST_IMAGE_VERSION###" + imagePullPolicy: Always diff --git a/packages/ui/zarf-config.yaml b/packages/ui/zarf-config.yaml new file mode 100644 index 000000000..475ac2d48 --- /dev/null +++ b/packages/ui/zarf-config.yaml @@ -0,0 +1,6 @@ +package: + create: + set: + # x-release-please-start-version + image_version: "0.13.1" + # x-release-please-end diff --git a/packages/ui/zarf.yaml b/packages/ui/zarf.yaml index 7a0741a5e..6c91508c0 100644 --- a/packages/ui/zarf.yaml +++ b/packages/ui/zarf.yaml @@ -63,9 +63,12 @@ variables: components: - name: leapfrogai-ui + description: "A UI for LeapfrogAI" required: true only: flavor: upstream + import: + path: common charts: - name: leapfrogai-ui namespace: leapfrogai @@ -78,18 +81,20 @@ components: images: - ghcr.io/defenseunicorns/leapfrogai/leapfrogai-ui:###ZARF_PKG_TMPL_IMAGE_VERSION### - ghcr.io/defenseunicorns/leapfrogai/ui-migrations:###ZARF_PKG_TMPL_IMAGE_VERSION### - actions: - onDeploy: - after: - - wait: - cluster: - kind: Job - name: leapfrogai-ui-migrations-###ZARF_PKG_TMPL_IMAGE_VERSION### - namespace: leapfrogai - condition: complete - - wait: - cluster: - kind: Deployment - name: leapfrogai-ui - namespace: leapfrogai - condition: Available + + - name: leapfrogai-ui + description: "A Python API that shadows the OpenAI API specification" + only: + flavor: registry1 + required: true + import: + path: common + charts: + - name: leapfrogai-ui + namespace: leapfrogai + valuesFiles: + - "values/registry1-values.yaml" + images: + - "registry1.dso.mil/ironbank/opensource/defenseunicorns/leapfrogai/ui:v###ZARF_PKG_TMPL_IMAGE_VERSION###" + # TODO: replace with Ironbank image once hardened: registry1.dso.mil/ironbank/opensource/defenseunicorns/leapfrogai/ui/migrations + - "ghcr.io/defenseunicorns/leapfrogai/ui-migrations:###ZARF_PKG_TMPL_IMAGE_VERSION###" diff --git a/tasks.yaml b/tasks.yaml index d89f87420..e950f159b 100644 --- a/tasks.yaml +++ b/tasks.yaml @@ -1,133 +1,151 @@ # yaml-language-server: $schema=https://raw.githubusercontent.com/defenseunicorns/uds-cli/v0.16.0/tasks.schema.json +variables: + - name: VERSION + description: "Explicitly set this to mutate the version away from the latest tagged release (e.g., `dev`)" + # x-release-please-start-version + default: "0.13.1" + # x-release-please-end + - name: FLAVOR + description: "Explicitly set this to mutate the flavor away from `upstream` (e.g., `registry1`)" + default: "upstream" + - name: ARCHITECTURE + description: "Explicitly set this to mutate the architecture away from `amd64` (e.g., `arm64`)" + default: "amd64" + + - name: LOCAL_REGISTRY_NAME + description: "Explicitly set this to mutate the local registry name away from `registry`" + default: "registry" + - name: LOCAL_REGISTRY_PORT + description: "Explicitly set this to mutate the local registry port away from `5000` (e.g., `5001` for MacOS)" + default: "5000" + + - name: ENABLE_INSECURE_KEYCLOAK_ADMIN_PASSWORD + description: "Explicitly set this to `false` to disable insecure KeyCloak admin password generation" + default: "true" + includes: - - badge: https://raw.githubusercontent.com/defenseunicorns/uds-common/82e63be82766a2e550a847af904b2d738c9d3478/tasks/badge.yaml + ######################### + # UDS COMMON TASK IMPORTS + ######################### + - badge-common: https://raw.githubusercontent.com/defenseunicorns/uds-common/086215582247e53a69c507a9105b281ba7642c88/tasks/badge.yaml + + ########################### + # LEAPFROGAI-SPECIFIC TASKS + ########################### + - badge: ./tasks/badge.yaml + - create: ./tasks/create.yaml + - publish: ./tasks/publish.yaml + - setup: ./tasks/setup.yaml + - deploy: ./tasks/deploy.yaml + - utils: ./tasks/utils.yaml + - test: ./tasks/test.yaml tasks: - - name: nightly-uds-badge-verification - description: "Runs in a pipeline and produces a report for archiving" + ####### + # SETUP + ####### + - name: python-development + description: "Check and setup a local Python environment for LeapfrogAI development" actions: - - description: "Create Reports Directory" - cmd: | - mkdir -p reports - - description: "Run UDS Badge Verification Task" - cmd: | - uds run verify-uds-badge-cpu --no-progress 2>&1 | tee ./reports/intermediate-report.txt - - description: "Clean Up Final Report" - cmd: | - python3 .github/scripts/uds_verification_report.py | tee ./reports/final-report.txt + - task: setup:check-python + - task: setup:python-dependencies - ############# - # BADGE TASKS - ############# - - name: verify-uds-badge-cpu - description: "Runs through all CPU UDS bundle packages with the UDS badge verification test" + ####### + # UTILS + ####### + - name: clean-all + description: "Cleans all artifact, cached, env, log, and model files" actions: - - task: verify-uds-badge-api - - task: verify-uds-badge-ui - - task: verify-uds-badge-llama-cpp-python - - task: verify-uds-badge-text-embeddings - - task: verify-uds-badge-whisper - - task: verify-uds-badge-supabase + - task: utils:clean-artifacts + - task: utils:clean-cache + - task: utils:clean-env + - task: utils:clean-logs + - task: utils:clean-models + - task: utils:clean-ui - - name: verify-uds-badge-gpu - description: "Runs through all GPU UDS bundle packages with the UDS badge verification test" + ######## + # CREATE + ######## + - name: create-all + description: "Creates all Zarf packages within the LeapfrogAI repository" actions: - - task: verify-uds-badge-api - - task: verify-uds-badge-ui - - task: verify-uds-badge-vllm - - task: verify-uds-badge-text-embeddings - - task: verify-uds-badge-whisper - - task: verify-uds-badge-supabase + - task: create:supabase + - task: create:api + - task: create:ui + - task: create:repeater + - task: create:vllm + - task: create:llama-cpp-python + - task: create:text-embeddings + - task: create:whisper - ####################### - # RE-USABLE BADGE TASKS - ####################### - - - name: verify-uds-badge-api + - name: create-cpu + description: "Creates CPU deployment Zarf packages within the LeapfrogAI repository" actions: - - description: "Verify API" - cmd: | - uds run badge:verify-badge \ - --set CHART_PATH="chart" \ - --set GROUP_NAME="package" \ - --set COMMON_ZARF="true" \ - --set PACKAGE_DIR="packages/api" \ - --no-progress + - task: create:supabase + - task: create:api + - task: create:ui + - task: create:llama-cpp-python + - task: create:text-embeddings + - task: create:whisper - - name: verify-uds-badge-ui + - name: create-gpu + description: "Creates GPU deployment Zarf packages within the LeapfrogAI repository" actions: - - description: "Verify UI" - cmd: | - uds run badge:verify-badge \ - --set CHART_PATH="chart" \ - --set GROUP_NAME="package" \ - --set COMMON_ZARF="false" \ - --set PACKAGE_DIR="packages/ui" \ - --no-progress + - task: create:supabase + - task: create:api + - task: create:ui + - task: create:vllm + - task: create:text-embeddings + - task: create:whisper - - name: verify-uds-badge-llama-cpp-python + ######## + # DEPLOY + ######## + - name: deploy-all + description: "Deploys all Zarf packages within the LeapfrogAI repository" actions: - - description: "Verify LLaMA-CPP-Python" - cmd: | - uds run badge:verify-badge \ - --set CHART_PATH="chart" \ - --set GROUP_NAME="package" \ - --set COMMON_ZARF="false" \ - --set PACKAGE_DIR="packages/llama-cpp-python" \ - --no-progress + - task: deploy:supabase + - task: deploy:api + - task: deploy:ui + - task: deploy:repeater + - task: deploy:vllm + - task: deploy:llama-cpp-python + - task: deploy:text-embeddings + - task: deploy:whisper - - name: verify-uds-badge-vllm + - name: deploy-cpu + description: "Deploys CPU deployment Zarf packages within the LeapfrogAI repository" actions: - - description: "Verify vLLM" - cmd: | - uds run badge:verify-badge \ - --set CHART_PATH="chart" \ - --set GROUP_NAME="package" \ - --set COMMON_ZARF="false" \ - --set PACKAGE_DIR="packages/vllm" \ - --no-progress + - task: deploy:supabase + - task: deploy:api + - task: deploy:ui + - task: deploy:llama-cpp-python + - task: deploy:text-embeddings + - task: deploy:whisper - - name: verify-uds-badge-text-embeddings + - name: deploy-gpu + description: "Deploys GPU deployment Zarf packages within the LeapfrogAI repository" actions: - - description: "Verify Text-Embeddings" - cmd: | - uds run badge:verify-badge \ - --set CHART_PATH="chart" \ - --set GROUP_NAME="package" \ - --set COMMON_ZARF="false" \ - --set PACKAGE_DIR="packages/text-embeddings" \ - --no-progress + - task: deploy:supabase + - task: deploy:api + - task: deploy:ui + - task: deploy:vllm + - task: deploy:text-embeddings + - task: deploy:whisper - - name: verify-uds-badge-whisper + ####### + # BADGE + ####### + - name: nightly-uds-badge-verification + description: "Runs in a pipeline and produces a report for archiving" actions: - - description: "Verify Whisper" + - description: "Create Reports Directory" cmd: | - uds run badge:verify-badge \ - --set CHART_PATH="chart" \ - --set GROUP_NAME="package" \ - --set COMMON_ZARF="false" \ - --set PACKAGE_DIR="packages/whisper" \ - --no-progress - - - name: verify-uds-badge-repeater - actions: - - description: "Verify Repeater" + mkdir -p reports + - description: "Run UDS Badge Verification Task" cmd: | - uds run badge:verify-badge \ - --set CHART_PATH="chart" \ - --set GROUP_NAME="package" \ - --set COMMON_ZARF="false" \ - --set PACKAGE_DIR="packages/repeater" \ - --no-progress - - - name: verify-uds-badge-supabase - actions: - - description: "Verify Supabase" + uds run badge:verify-uds-badge-cpu --no-progress 2>&1 | tee ./reports/intermediate-report.txt + - description: "Clean Up Final Report" cmd: | - uds run badge:verify-badge \ - --set CHART_PATH="chart" \ - --set GROUP_NAME="package" \ - --set COMMON_ZARF="false" \ - --set PACKAGE_DIR="packages/supabase" \ - --no-progress + python3 .github/scripts/uds_verification_report.py | tee ./reports/final-report.txt diff --git a/tasks/badge.yaml b/tasks/badge.yaml new file mode 100644 index 000000000..7e274fcff --- /dev/null +++ b/tasks/badge.yaml @@ -0,0 +1,117 @@ +# yaml-language-server: $schema=https://raw.githubusercontent.com/defenseunicorns/uds-cli/v0.14.0/tasks.schema.json + +tasks: + ############# + # BADGE TASKS + ############# + - name: verify-uds-badge-cpu + description: "Runs through all CPU UDS bundle packages with the UDS badge verification test" + actions: + - task: verify-uds-badge-api + - task: verify-uds-badge-ui + - task: verify-uds-badge-llama-cpp-python + - task: verify-uds-badge-text-embeddings + - task: verify-uds-badge-whisper + - task: verify-uds-badge-supabase + + - name: verify-uds-badge-gpu + description: "Runs through all GPU UDS bundle packages with the UDS badge verification test" + actions: + - task: verify-uds-badge-api + - task: verify-uds-badge-ui + - task: verify-uds-badge-vllm + - task: verify-uds-badge-text-embeddings + - task: verify-uds-badge-whisper + - task: verify-uds-badge-supabase + + ####################### + # RE-USABLE BADGE TASKS + ####################### + + - name: verify-uds-badge-api + actions: + - description: "Verify API" + cmd: | + uds run badge-common:verify-badge \ + --set CHART_PATH="chart" \ + --set GROUP_NAME="package" \ + --set COMMON_ZARF="true" \ + --set PACKAGE_DIR="packages/api" \ + --no-progress + + - name: verify-uds-badge-ui + actions: + - description: "Verify UI" + cmd: | + uds run badge-common:verify-badge \ + --set CHART_PATH="chart" \ + --set GROUP_NAME="package" \ + --set COMMON_ZARF="false" \ + --set PACKAGE_DIR="packages/ui" \ + --no-progress + + - name: verify-uds-badge-llama-cpp-python + actions: + - description: "Verify LLaMA-CPP-Python" + cmd: | + uds run badge-common:verify-badge \ + --set CHART_PATH="chart" \ + --set GROUP_NAME="package" \ + --set COMMON_ZARF="false" \ + --set PACKAGE_DIR="packages/llama-cpp-python" \ + --no-progress + + - name: verify-uds-badge-vllm + actions: + - description: "Verify vLLM" + cmd: | + uds run badge-common:verify-badge \ + --set CHART_PATH="chart" \ + --set GROUP_NAME="package" \ + --set COMMON_ZARF="false" \ + --set PACKAGE_DIR="packages/vllm" \ + --no-progress + + - name: verify-uds-badge-text-embeddings + actions: + - description: "Verify Text-Embeddings" + cmd: | + uds run badge-common:verify-badge \ + --set CHART_PATH="chart" \ + --set GROUP_NAME="package" \ + --set COMMON_ZARF="false" \ + --set PACKAGE_DIR="packages/text-embeddings" \ + --no-progress + + - name: verify-uds-badge-whisper + actions: + - description: "Verify Whisper" + cmd: | + uds run badge-common:verify-badge \ + --set CHART_PATH="chart" \ + --set GROUP_NAME="package" \ + --set COMMON_ZARF="false" \ + --set PACKAGE_DIR="packages/whisper" \ + --no-progress + + - name: verify-uds-badge-repeater + actions: + - description: "Verify Repeater" + cmd: | + uds run badge-common:verify-badge \ + --set CHART_PATH="chart" \ + --set GROUP_NAME="package" \ + --set COMMON_ZARF="false" \ + --set PACKAGE_DIR="packages/repeater" \ + --no-progress + + - name: verify-uds-badge-supabase + actions: + - description: "Verify Supabase" + cmd: | + uds run badge-common:verify-badge \ + --set CHART_PATH="chart" \ + --set GROUP_NAME="package" \ + --set COMMON_ZARF="false" \ + --set PACKAGE_DIR="packages/supabase" \ + --no-progress diff --git a/tasks/create.yaml b/tasks/create.yaml new file mode 100644 index 000000000..7e1a8cb9a --- /dev/null +++ b/tasks/create.yaml @@ -0,0 +1,621 @@ +# yaml-language-server: $schema=https://raw.githubusercontent.com/defenseunicorns/uds-cli/v0.14.0/tasks.schema.json +includes: + ######################### + # UDS COMMON TASK IMPORTS + ######################### + - create-common: https://raw.githubusercontent.com/defenseunicorns/uds-common/086215582247e53a69c507a9105b281ba7642c88/tasks/create.yaml + + ########################### + # LEAPFROGAI-SPECIFIC TASKS + ########################### + - utils: ./utils.yaml + +tasks: + ######### + # UTILITY + ######### + - name: local-registry + description: "Creates a local registry for pushing images to, speeding up the local Zarf package creation process" + inputs: + port: + description: "The port at which to expose the local registry" + default: "5000" + name: + description: "The name of the local registry" + default: "registry" + # TODO: remove once Ironbank image for api-migrations and ui-migrations exists + override: + description: "Specifically for packages that are only partially in IronBank (e.g., migrations)" + default: "false" + actions: + - description: "If not running or if local package development, create a local registry" + shell: + linux: bash + darwin: bash + cmd: | + if [[ ${FLAVOR} != "upstream" || ${{ .inputs.override }} != "false" ]]; then + if [ ! "$(docker ps -q -f name=${{ .inputs.name }})" ]; then + docker run -d -p ${{ .inputs.port }}:5000 --restart=always -q --name ${{ .inputs.name }} registry:2 > /dev/null 2>&1 + fi + fi + mute: true + + ########### + # REUSEABLE + ########### + - name: image + description: "Create a Docker image" + inputs: + dockerfile: + description: "Path to the Dockerfile" + required: true + buildContext: + description: "Path to the Docker build context" + default: "." + required: false + options: + description: "Extra Docker CLI options" + default: "-q" + required: false + buildOptions: + description: "Extra Docker build arguments" + default: "" + required: false + architecture: + description: "Architecture of the Docker image being created" + required: true + version: + description: "Set the version of the Docker image" + required: true + imageRepository: + description: "Image repository for the image tag" + required: true + actions: + - task: utils:log + with: + log: "Creating image at ${{ .inputs.dockerfile }}" + - description: "Build the Docker image" + shell: + linux: bash + darwin: bash + cmd: | + if [[ ${FLAVOR} = "upstream" || ${{ .inputs.dockerfile }} = "Dockerfile.migrations" ]]; then + docker build ${{ .inputs.options }} \ + --platform=linux/${{ .inputs.architecture }} \ + -t ${{ .inputs.imageRepository }}:${{ .inputs.version }} \ + -f ${{ .inputs.dockerfile }} \ + --build-arg LOCAL_VERSION=${{ .inputs.version }} \ + ${{ .inputs.buildOptions }} ${{ .inputs.buildContext }} \ + > /dev/null 2>&1 + echo "false" + else + echo "true" + fi + mute: true + setVariables: + - name: ENABLE_LOG + - task: utils:log + with: + log: "Non-upstream flavor detected, skipping local image build" + enable: ${ENABLE_LOG} + + - name: package + description: "Create a Zarf package" + inputs: + path: + description: "Path to the Zarf package being created" + required: true + outputPath: + description: "Output path to the Zarf package being created" + required: true + zarfConfig: + description: "Zarf Config of the Zarf package being created" + default: "" + required: false + options: + description: "Extra Zarf package creation options" + default: "--log-level warn --no-progress" + required: false + createOptions: + description: "Extra Zarf package create arguments" + default: "" + required: false + flavor: + description: "Flavor of the Zarf package being created" + default: "upstream" + required: false + architecture: + description: "Architecture of the Zarf package being created" + required: true + version: + description: "Set the version of the Zarf package and target image(s)" + required: true + actions: + - task: utils:log + with: + log: "Creating package at ${{ .inputs.path }}" + - description: "Create the Zarf package" + task: create-common:package + env: + - "FLAVOR=${{ .inputs.flavor }}" + with: + options: ${{ .inputs.createOptions }} ${{ .inputs.options }} -o ${{ .inputs.outputPath }} --set IMAGE_VERSION=${{ .inputs.version }} + path: ${{ .inputs.path }} + architecture: ${{ .inputs.architecture }} + config: ${{ .inputs.zarfConfig }} + + - name: bundle + description: "Create a UDS bundle" + inputs: + path: + description: "Path to the UDS bundle being created" + required: true + outputPath: + description: "Output path to the UDS bundle being created" + required: true + udsConfig: + description: "UDS configuration manifest for deployment" + required: true + options: + description: "Extra UDS CLI options" + default: "--log-level warn --oci-concurrency 8 --no-progress" + required: false + createOptions: + description: "Extra UDS bundle create arguments" + default: "" + required: false + actions: + - task: utils:log + with: + log: "Creating bundle at ${{ .inputs.path }}" + - description: "Create the UDS bundle" + task: create-common:test-bundle + with: + options: ${{ .inputs.options }} -o ${{ .inputs.outputPath }} + path: ${{ .inputs.path }} + architecture: ${{ .inputs.architecture }} + config: ${{ .inputs.udsConfig }} + + ######## + # IMAGES + ######## + + - name: k3d-gpu-image + description: "Create the K3s CUDA image for K3d" + actions: + - description: "Create the K3s CUDA image" + task: image + with: + dockerfile: "packages/k3d-gpu/Dockerfile" + architecture: "amd64" + version: ${VERSION} + imageRepository: "ghcr.io/defenseunicorns/leapfrogai/k3d-gpu" + buildContext: "packages/k3d-gpu" + + - name: sdk-image + description: "Create the LeapfrogAI SDK Docker image" + inputs: + architecture: + description: "Architecture of the Zarf package being created" + required: true + imageRepository: + description: "Image repository for the image tag" + required: true + actions: + - description: "Create the SDK image" + task: image + with: + dockerfile: "src/leapfrogai_sdk/Dockerfile" + architecture: ${{ .inputs.architecture }} + version: ${VERSION} + imageRepository: ${{ .inputs.imageRepository }} + + - name: api-migrations-image + description: "Build the upstream LeapfrogAI API migrations image" + actions: + - task: local-registry + with: + name: ${LOCAL_REGISTRY_NAME} + port: ${LOCAL_REGISTRY_PORT} + override: "true" + + - description: "Create the API migrations image" + task: image + with: + dockerfile: "Dockerfile.migrations" + buildOptions: "--build-arg='MIGRATIONS_DIR=packages/supabase/migrations'" + architecture: ${ARCHITECTURE} + version: ${VERSION} + imageRepository: "ghcr.io/defenseunicorns/leapfrogai/api-migrations" + + - name: api-image + description: "Build the upstream LeapfrogAI API image" + actions: + - task: local-registry + with: + name: ${LOCAL_REGISTRY_NAME} + port: ${LOCAL_REGISTRY_PORT} + + - description: "Create the SDK image" + task: sdk-image + with: + architecture: ${ARCHITECTURE} + imageRepository: "ghcr.io/defenseunicorns/leapfrogai/leapfrogai-sdk" + + - description: "Create the API image" + task: image + with: + dockerfile: "packages/api/Dockerfile" + architecture: ${ARCHITECTURE} + version: ${VERSION} + imageRepository: "ghcr.io/defenseunicorns/leapfrogai/leapfrogai-api" + + - name: ui-migrations-image + description: "Build the upstream LeapfrogAI UI migrations image" + actions: + - task: local-registry + with: + name: ${LOCAL_REGISTRY_NAME} + port: ${LOCAL_REGISTRY_PORT} + override: "true" + + - description: "Create the UI migrations image" + task: image + with: + dockerfile: "Dockerfile.migrations" + buildOptions: "--build-arg='MIGRATIONS_DIR=packages/supabase/migrations'" + architecture: ${ARCHITECTURE} + version: ${VERSION} + imageRepository: "ghcr.io/defenseunicorns/leapfrogai/ui-migrations" + + - name: ui-image + description: "Build the upstream LeapfrogAI API image" + actions: + - task: local-registry + with: + name: ${LOCAL_REGISTRY_NAME} + port: ${LOCAL_REGISTRY_PORT} + + - description: "Create the UI image" + task: image + with: + dockerfile: "src/leapfrogai_ui/Dockerfile" + buildContext: "src/leapfrogai_ui" + architecture: ${ARCHITECTURE} + version: ${VERSION} + imageRepository: "ghcr.io/defenseunicorns/leapfrogai/leapfrogai-ui" + + - name: supabase-migrations-image + description: "Build the upstream Supabase migrations image" + actions: + - task: local-registry + with: + name: ${LOCAL_REGISTRY_NAME} + port: ${LOCAL_REGISTRY_PORT} + override: "true" + + - description: "Create the Supabase migrations image" + task: image + with: + dockerfile: "Dockerfile.migrations" + buildOptions: "--build-arg='MIGRATIONS_DIR=packages/supabase/migrations'" + architecture: ${ARCHITECTURE} + version: ${VERSION} + imageRepository: "ghcr.io/defenseunicorns/leapfrogai/supabase-migrations" + + - name: repeater-image + description: "Build the upstream Repeater image" + actions: + - task: local-registry + with: + name: ${LOCAL_REGISTRY_NAME} + port: ${LOCAL_REGISTRY_PORT} + + - description: "Create the SDK image" + task: sdk-image + with: + architecture: ${ARCHITECTURE} + imageRepository: "ghcr.io/defenseunicorns/leapfrogai/leapfrogai-sdk" + + - description: "Create the Repeater image" + task: image + with: + dockerfile: "packages/repeater/Dockerfile" + architecture: ${ARCHITECTURE} + version: ${VERSION} + imageRepository: "ghcr.io/defenseunicorns/leapfrogai/repeater" + + - name: vllm-image + description: "Build the upstream vLLM image" + actions: + - task: local-registry + with: + name: ${LOCAL_REGISTRY_NAME} + port: ${LOCAL_REGISTRY_PORT} + + - description: "Create the SDK image" + task: sdk-image + with: + architecture: ${ARCHITECTURE} + imageRepository: "ghcr.io/defenseunicorns/leapfrogai/leapfrogai-sdk" + + - description: "Create the vLLM image" + task: image + with: + dockerfile: "packages/vllm/Dockerfile" + architecture: ${ARCHITECTURE} + version: ${VERSION} + imageRepository: "ghcr.io/defenseunicorns/leapfrogai/vllm" + + - name: llama-cpp-python-image + description: "Build the upstream LLaMA-CPP-Python image" + actions: + - task: local-registry + with: + name: ${LOCAL_REGISTRY_NAME} + port: ${LOCAL_REGISTRY_PORT} + + - description: "Create the SDK image" + task: sdk-image + with: + architecture: ${ARCHITECTURE} + imageRepository: "ghcr.io/defenseunicorns/leapfrogai/leapfrogai-sdk" + + - description: "Create the LLaMA-CPP-Python image" + task: image + with: + dockerfile: "packages/llama-cpp-python/Dockerfile" + architecture: ${ARCHITECTURE} + version: ${VERSION} + imageRepository: "ghcr.io/defenseunicorns/leapfrogai/llama-cpp-python" + + - name: text-embeddings-image + description: "Build the upstream Text-Embeddings image" + actions: + - task: local-registry + with: + name: ${LOCAL_REGISTRY_NAME} + port: ${LOCAL_REGISTRY_PORT} + + - description: "Create the SDK image" + task: sdk-image + with: + architecture: ${ARCHITECTURE} + imageRepository: "ghcr.io/defenseunicorns/leapfrogai/leapfrogai-sdk" + + - description: "Create the Text-Embeddings image" + task: image + with: + dockerfile: "packages/text-embeddings/Dockerfile" + architecture: ${ARCHITECTURE} + version: ${VERSION} + imageRepository: "ghcr.io/defenseunicorns/leapfrogai/text-embeddings" + + - name: whisper-image + description: "Build the upstream Whisper image" + actions: + - task: local-registry + with: + name: ${LOCAL_REGISTRY_NAME} + port: ${LOCAL_REGISTRY_PORT} + + - description: "Create the SDK image" + task: sdk-image + with: + architecture: ${ARCHITECTURE} + imageRepository: "ghcr.io/defenseunicorns/leapfrogai/leapfrogai-sdk" + + - description: "Create the Whisper image" + task: image + with: + dockerfile: "packages/whisper/Dockerfile" + architecture: ${ARCHITECTURE} + version: ${VERSION} + imageRepository: "ghcr.io/defenseunicorns/leapfrogai/whisper" + + ########## + # PACKAGES + ########## + + - name: api + description: "Build the LeapfrogAI API Zarf package" + actions: + - task: api-migrations-image + - task: utils:tag + with: + current: "ghcr.io/defenseunicorns/leapfrogai/api-migrations:${VERSION}" + new: "localhost:${LOCAL_REGISTRY_PORT}/defenseunicorns/leapfrogai/api-migrations:${VERSION}" + override: "true" + - task: utils:docker + with: + tag: "localhost:${LOCAL_REGISTRY_PORT}/defenseunicorns/leapfrogai/api-migrations:${VERSION}" + override: "true" + + - task: api-image + - task: utils:tag + with: + current: "ghcr.io/defenseunicorns/leapfrogai/leapfrogai-api:${VERSION}" + new: "localhost:${LOCAL_REGISTRY_PORT}/defenseunicorns/leapfrogai/leapfrogai-api:${VERSION}" + - task: utils:docker + with: + tag: "localhost:${LOCAL_REGISTRY_PORT}/defenseunicorns/leapfrogai/leapfrogai-api:${VERSION}" + + - task: package + with: + path: "packages/api" + outputPath: "packages/api" + zarfConfig: "packages/api/zarf-config.yaml" + flavor: ${FLAVOR} + architecture: ${ARCHITECTURE} + version: ${VERSION} + # the build options below do not affect registry1 builds + createOptions: "--insecure --registry-override=ghcr.io=localhost:${LOCAL_REGISTRY_PORT}" + + - name: ui + description: "Build the LeapfrogAI UI Zarf package" + actions: + - task: ui-migrations-image + - task: utils:tag + with: + current: "ghcr.io/defenseunicorns/leapfrogai/ui-migrations:${VERSION}" + new: "localhost:${LOCAL_REGISTRY_PORT}/defenseunicorns/leapfrogai/ui-migrations:${VERSION}" + override: "true" + - task: utils:docker + with: + tag: "localhost:${LOCAL_REGISTRY_PORT}/defenseunicorns/leapfrogai/ui-migrations:${VERSION}" + override: "true" + + - task: ui-image + - task: utils:tag + with: + current: "ghcr.io/defenseunicorns/leapfrogai/leapfrogai-ui:${VERSION}" + new: "localhost:${LOCAL_REGISTRY_PORT}/defenseunicorns/leapfrogai/leapfrogai-ui:${VERSION}" + - task: utils:docker + with: + tag: "localhost:${LOCAL_REGISTRY_PORT}/defenseunicorns/leapfrogai/leapfrogai-ui:${VERSION}" + + - task: package + with: + path: "packages/ui" + outputPath: "packages/ui" + zarfConfig: "packages/ui/zarf-config.yaml" + flavor: ${FLAVOR} + architecture: ${ARCHITECTURE} + version: ${VERSION} + # the build options below do not affect registry1 builds + createOptions: "--insecure --registry-override=ghcr.io=localhost:${LOCAL_REGISTRY_PORT}" + + - name: supabase + description: "Build the Supabase Zarf package" + actions: + - task: supabase-migrations-image + - task: utils:tag + with: + current: "ghcr.io/defenseunicorns/leapfrogai/supabase-migrations:${VERSION}" + new: "localhost:${LOCAL_REGISTRY_PORT}/defenseunicorns/leapfrogai/supabase-migrations:${VERSION}" + override: "true" + - task: utils:docker + with: + tag: "localhost:${LOCAL_REGISTRY_PORT}/defenseunicorns/leapfrogai/supabase-migrations:${VERSION}" + override: "true" + + - task: package + with: + path: "packages/supabase" + outputPath: "packages/supabase" + flavor: ${FLAVOR} + architecture: ${ARCHITECTURE} + version: ${VERSION} + # the build options below do not affect registry1 builds + createOptions: "--insecure --registry-override=ghcr.io=localhost:${LOCAL_REGISTRY_PORT}" + + - name: repeater + description: "Build the Repeater Zarf package" + actions: + - task: repeater-image + - task: utils:tag + with: + current: "ghcr.io/defenseunicorns/leapfrogai/repeater:${VERSION}" + new: "localhost:${LOCAL_REGISTRY_PORT}/defenseunicorns/leapfrogai/repeater:${VERSION}" + - task: utils:docker + with: + tag: "localhost:${LOCAL_REGISTRY_PORT}/defenseunicorns/leapfrogai/repeater:${VERSION}" + + - task: package + with: + path: "packages/repeater" + outputPath: "packages/repeater" + flavor: ${FLAVOR} + architecture: ${ARCHITECTURE} + version: ${VERSION} + # the build options below do not affect registry1 builds + createOptions: "--insecure --registry-override=ghcr.io=localhost:${LOCAL_REGISTRY_PORT}" + + - name: vllm + description: "Build the vLLM Zarf package" + actions: + - task: vllm-image + - task: utils:tag + with: + current: "ghcr.io/defenseunicorns/leapfrogai/vllm:${VERSION}" + new: "localhost:${LOCAL_REGISTRY_PORT}/defenseunicorns/leapfrogai/vllm:${VERSION}" + - task: utils:docker + with: + tag: "localhost:${LOCAL_REGISTRY_PORT}/defenseunicorns/leapfrogai/vllm:${VERSION}" + + - task: package + with: + path: "packages/vllm" + outputPath: "packages/vllm" + flavor: ${FLAVOR} + architecture: ${ARCHITECTURE} + version: ${VERSION} + zarfConfig: "packages/vllm/zarf-config.yaml" + # the build options below do not affect registry1 builds + createOptions: "--insecure --registry-override=ghcr.io=localhost:${LOCAL_REGISTRY_PORT}" + + - name: llama-cpp-python + description: "Build the LLaMA-CPP-Python Zarf package" + actions: + - task: llama-cpp-python-image + - task: utils:tag + with: + current: "ghcr.io/defenseunicorns/leapfrogai/llama-cpp-python:${VERSION}" + new: "localhost:${LOCAL_REGISTRY_PORT}/defenseunicorns/leapfrogai/llama-cpp-python:${VERSION}" + - task: utils:docker + with: + tag: "localhost:${LOCAL_REGISTRY_PORT}/defenseunicorns/leapfrogai/llama-cpp-python:${VERSION}" + + - task: package + with: + path: "packages/llama-cpp-python" + outputPath: "packages/llama-cpp-python" + flavor: ${FLAVOR} + architecture: ${ARCHITECTURE} + version: ${VERSION} + # the build options below do not affect registry1 builds + createOptions: "--insecure --registry-override=ghcr.io=localhost:${LOCAL_REGISTRY_PORT}" + + - name: text-embeddings + description: "Build the Text-Embeddings Zarf package" + actions: + - task: text-embeddings-image + - task: utils:tag + with: + current: "ghcr.io/defenseunicorns/leapfrogai/text-embeddings:${VERSION}" + new: "localhost:${LOCAL_REGISTRY_PORT}/defenseunicorns/leapfrogai/text-embeddings:${VERSION}" + - task: utils:docker + with: + tag: "localhost:${LOCAL_REGISTRY_PORT}/defenseunicorns/leapfrogai/text-embeddings:${VERSION}" + + - task: package + with: + path: "packages/text-embeddings" + outputPath: "packages/text-embeddings" + flavor: ${FLAVOR} + architecture: ${ARCHITECTURE} + version: ${VERSION} + # the build options below do not affect registry1 builds + createOptions: "--insecure --registry-override=ghcr.io=localhost:${LOCAL_REGISTRY_PORT}" + + - name: whisper + description: "Build the Whisper Zarf package" + actions: + - task: whisper-image + - task: utils:tag + with: + current: "ghcr.io/defenseunicorns/leapfrogai/whisper:${VERSION}" + new: "localhost:${LOCAL_REGISTRY_PORT}/defenseunicorns/leapfrogai/whisper:${VERSION}" + - task: utils:docker + with: + tag: "localhost:${LOCAL_REGISTRY_PORT}/defenseunicorns/leapfrogai/whisper:${VERSION}" + + - task: package + with: + path: "packages/whisper" + outputPath: "packages/whisper" + flavor: ${FLAVOR} + architecture: ${ARCHITECTURE} + version: ${VERSION} + # the build options below do not affect registry1 builds + createOptions: "--insecure --registry-override=ghcr.io=localhost:${LOCAL_REGISTRY_PORT}" diff --git a/tasks/deploy.yaml b/tasks/deploy.yaml new file mode 100644 index 000000000..1ba98cf5c --- /dev/null +++ b/tasks/deploy.yaml @@ -0,0 +1,193 @@ +# yaml-language-server: $schema=https://raw.githubusercontent.com/defenseunicorns/uds-cli/v0.14.0/tasks.schema.json +includes: + ######################### + # UDS COMMON TASK IMPORTS + ######################### + - deploy-common: https://raw.githubusercontent.com/defenseunicorns/uds-common/086215582247e53a69c507a9105b281ba7642c88/tasks/deploy.yaml + + ########################### + # LEAPFROGAI-SPECIFIC TASKS + ########################### + - utils: ./utils.yaml + +tasks: + ########### + # REUSEABLE + ########### + + - name: image + description: "Run a Docker image" + inputs: + name: + description: "Name to tag the running container with" + required: true + options: + description: "Extra Docker CLI options" + default: "-q -d --rm" + required: false + version: + description: "Set the version of the Docker image" + required: true + imageRepository: + description: "Image repository for the image tag" + required: true + containerPort: + description: "Container port to expose" + required: true + hostPort: + description: "Host port to expose container port at" + required: true + actions: + - task: utils:log + with: + log: "Running the image ${{ .inputs.name }}" + - description: "Run the Docker image" + shell: + linux: bash + darwin: bash + cmd: | + docker run \ + -p ${{ .inputs.hostPort }}:${{ .inputs.containerPort }} \ + --name=${{ .inputs.name }} ${{ .inputs.options }} \ + ${{ .inputs.imageRepository }}:${{ .inputs.version }} + - task: utils:log + with: + log: "Docker image, ${{ .inputs.name }}, is now running!" + + - name: package + description: "Deploy a Zarf package" + inputs: + path: + description: "Path to the Zarf package to being deployed" + required: true + zarfConfig: + description: "Zarf Config of the Zarf package being deployed" + default: "" + required: false + options: + description: "Extra Zarf package deployment options" + default: "--log-level warn --no-progress --confirm" + required: false + actions: + - task: utils:log + with: + log: "Deploying package at ${{ .inputs.path }}" + - description: Get the current Zarf package name + cmd: cat ${{ .inputs.path }}/zarf.yaml | uds zarf tools yq .metadata.name + setVariables: + - name: PACKAGE_NAME + mute: true + - description: "Deploy the Zarf package" + env: + - ZARF_CONFIG=${{ .inputs.zarfConfig }} + cmd: | + uds zarf package deploy ${{ .inputs.path }}/zarf-package-${PACKAGE_NAME}-${ARCHITECTURE}-${VERSION}.tar.zst ${{ .inputs.options }} + + - name: bundle + description: "Deploy a UDS bundle" + inputs: + path: + description: "Path to the UDS Bundle to being deployed" + required: true + udsConfig: + description: "UDS Config of the UDS Bundle being deployed" + default: "" + required: false + options: + description: "Extra UDS Bundle deployment options" + default: "--log-level warn" + required: false + architecture: + description: "Architecture of the UDS Bundle being created" + required: true + version: + description: "Set the version of the UDS Bundle and target image(s)" + required: true + actions: + - task: utils:log + with: + log: "Deploying bundle at ${{ .inputs.path }}" + - task: deploy-common:test-bundle + env: + - UDS_ARCH=${{ .inputs.architecture }} + with: + options: ${{ .inputs.options }} + path: ${{ .inputs.path }} + + ######## + # IMAGES + ######## + + - name: repeater-image + description: "Run the Repeater Docker container" + actions: + - task: image + with: + name: "repeater" + version: ${VERSION} + imageRepository: "ghcr.io/defenseunicorns/leapfrogai/repeater" + containerPort: "50051" + hostPort: "50051" + + ########## + # PACKAGES + ########## + + - name: api + description: "Deploy the LeapfrogAI API Zarf package" + actions: + - task: package + with: + path: "packages/api" + zarfConfig: "packages/api/zarf-config.yaml" + + - name: ui + description: "Deploy the LeapfrogAI API Zarf package" + actions: + - task: package + with: + path: "packages/ui" + zarfConfig: "packages/ui/zarf-config.yaml" + + - name: supabase + description: "Deploy the Supabase Zarf package" + actions: + - task: package + with: + path: "packages/supabase" + + - name: repeater + description: "Deploy the Repeater Zarf package" + actions: + - task: package + with: + path: "packages/repeater" + + - name: vllm + description: "Deploy the vLLM Zarf package" + actions: + - task: package + with: + path: "packages/vllm" + zarfConfig: "packages/vllm/zarf-config.yaml" + + - name: llama-cpp-python + description: "Deploy the LLaMA-CPP-Python Zarf package" + actions: + - task: package + with: + path: "packages/llama-cpp-python" + + - name: text-embeddings + description: "Deploy the Text-Embeddings Zarf package" + actions: + - task: package + with: + path: "packages/text-embeddings" + + - name: whisper + description: "Deploy the Whisper Zarf package" + actions: + - task: package + with: + path: "packages/whisper" diff --git a/tasks/setup.yaml b/tasks/setup.yaml new file mode 100644 index 000000000..47ce51e4d --- /dev/null +++ b/tasks/setup.yaml @@ -0,0 +1,107 @@ +# yaml-language-server: $schema=https://raw.githubusercontent.com/defenseunicorns/uds-cli/v0.14.0/tasks.schema.json +includes: + ######################### + # UDS COMMON TASK IMPORTS + ######################### + - setup-common: https://raw.githubusercontent.com/defenseunicorns/uds-common/086215582247e53a69c507a9105b281ba7642c88/tasks/setup.yaml + + ########################### + # LEAPFROGAI-SPECIFIC TASKS + ########################### + - create: ./create.yaml + +tasks: + ####### + # TESTS + ####### + - name: e2e-test-user + description: "Creates a test user in KeyCloak with fake credentials, mainly for CI testing workflows" + actions: + - task: setup-common:create-doug-user + + ######### + # CLUSTER + ######### + + - name: k3d-cpu-cluster-slim + description: "Creates a UDS K3d cluster with slim UDS Core and CPU-only Capability" + actions: + - task: setup-common:k3d-test-cluster + + - name: k3d-gpu-cluster-slim + description: "Creates a UDS K3d cluster with slim UDS Core and NVIDIA GPU Capability" + actions: + - task: create:k3d-gpu-image + - task: setup-common:k3d-test-cluster + with: + version: 0.27.3 + snapshots: "false" + insecure_keycloak_admin: ${ENABLE_INSECURE_KEYCLOAK_ADMIN_PASSWORD} + options: "--set K3D_EXTRA_ARGS='--gpus=all --image=ghcr.io/defenseunicorns/leapfrogai/k3d-gpu:${VERSION}'" + + - name: k3d-cpu-cluster-full + description: "Creates a UDS K3d cluster with full UDS Core and CPU-only Capability" + actions: + - task: setup-common:k3d-full-cluster + with: + version: 0.27.3 + snapshots: "false" + insecure_keycloak_admin: ${ENABLE_INSECURE_KEYCLOAK_ADMIN_PASSWORD} + + - name: k3d-gpu-cluster-full + description: "Creates a UDS K3d cluster with full UDS Core and NVIDIA GPU Capability" + actions: + - task: create:k3d-gpu-image + - task: setup-common:k3d-full-cluster + with: + version: 0.27.3 + snapshots: "false" + insecure_keycloak_admin: ${ENABLE_INSECURE_KEYCLOAK_ADMIN_PASSWORD} + options: "--set K3D_EXTRA_ARGS='--gpus=all --image=ghcr.io/defenseunicorns/leapfrogai/k3d-gpu:${VERSION}'" + + ######## + # PYTHON + ######## + + - name: python-dependencies + description: "Install or re-install all development dependencies into a local Python environment" + actions: + - description: "Fresh installation of all Python dependencies" + cmd: | + python -m pip install ".[dev,dev-vllm,dev-whisper]" "src/leapfrogai_api" "src/leapfrogai_sdk" --no-cache-dir --force-reinstall + mute: true + + - name: check-python + description: "Checks the local Python environment" + inputs: + path: + description: "Path to the pyproject.toml" + default: "pyproject.toml" + required: false + actions: + - description: "Check the local Python environment version" + shell: + linux: bash + darwin: bash + env: + - PYPROJECT_TOML=${{ .inputs.path }} + cmd: | + # Extract Python version requirement from pyproject.toml + PYTHON_REQ=$(uds zarf tools yq -o yaml -p toml '.project."requires-python"' "$PYPROJECT_TOML") + + # Get the local Python version (e.g., 3.11.9) + LOCAL_PYTHON_VERSION=$(python3 -c "import sys; print(f'{sys.version_info.major}.{sys.version_info.minor}.{sys.version_info.micro}')") + + # Function to compare versions using 'packaging.specifiers' library + version_satisfies() { + python3 -c "from packaging.version import Version; from packaging.specifiers import SpecifierSet; \ + import sys; sys.exit(0) if Version('$LOCAL_PYTHON_VERSION') in SpecifierSet('$1') else sys.exit(1)" + } + + # Check if local Python version satisfies the requirements + if ! version_satisfies "$PYTHON_REQ"; then + exit 1 + else + echo "Python version matches the requirement: $LOCAL_PYTHON_VERSION" + fi + mute: true diff --git a/tasks/test.yaml b/tasks/test.yaml new file mode 100644 index 000000000..3ff3791e0 --- /dev/null +++ b/tasks/test.yaml @@ -0,0 +1,20 @@ +# yaml-language-server: $schema=https://raw.githubusercontent.com/defenseunicorns/uds-cli/v0.14.0/tasks.schema.json + +tasks: + ######### + # CLUSTER + ######### + + - name: k3d-gpu-cluster + description: "Tests CUDA GPU scheduling and capability within the UDS K3d cluster" + actions: + - description: "Deploy the vector addition test pod to the cluster" + cmd: | + uds zarf tools kubectl apply -f packages/k3d-gpu/test/cuda-vector-add.yaml + - description: "Await test completion and then display the test results" + cmd: | + uds zarf tools wait-for Pod gpu-pod '{.status.phase}'=Succeeded -n default --no-progress + uds zarf tools kubectl logs -l app=gpu-pod -n default + - description: "Remove the completed test pod" + cmd: | + uds zarf tools kubectl delete Pod gpu-pod diff --git a/tasks/utils.yaml b/tasks/utils.yaml new file mode 100644 index 000000000..dbdba115e --- /dev/null +++ b/tasks/utils.yaml @@ -0,0 +1,154 @@ +# yaml-language-server: $schema=https://raw.githubusercontent.com/defenseunicorns/uds-cli/v0.14.0/tasks.schema.json + +tasks: + - name: log + description: "LeapfrogAI logger" + inputs: + log: + description: "Content to be logged to the CLI" + required: true + enable: + description: "Whether to enable or disable the logging" + default: "true" + required: false + actions: + - description: "Printed LeapfrogAI logs" + shell: + linux: bash + darwin: bash + cmd: | + if [[ ${{ .inputs.enable }} == "true" ]]; then + printf "\n🐸 ${{ .inputs.log }}\n\n" + fi + + - name: tag + description: "Re-tags an existing Docker image" + inputs: + current: + description: "The current image tag" + required: true + new: + description: "The new image tag" + required: true + # TODO: remove once Ironbank image for api-migrations and ui-migrations exists + override: + description: "Specifically for packages that are only partially in IronBank (e.g., migrations)" + default: "false" + required: false + actions: + - description: "Re-tag the Docker image" + shell: + linux: bash + darwin: bash + mute: true + cmd: | + if [[ ${FLAVOR} = "upstream" || ${{ .inputs.override }} = "true" ]]; then + docker tag ${{ .inputs.current }} ${{ .inputs.new }} + fi + + - name: docker + description: "Push an existing Docker image to its tagged repository" + inputs: + tag: + description: "The full Docker image tag" + required: true + options: + description: "Extra Docker CLI options" + default: "-q" + required: false + # TODO: remove once Ironbank image for api-migrations and ui-migrations exists + override: + description: "Specifically for packages that are only partially in IronBank (e.g., migrations)" + default: "false" + required: false + actions: + - description: "Push the Docker image" + shell: + linux: bash + darwin: bash + mute: true + cmd: | + if [[ ${FLAVOR} = "upstream" || ${{ .inputs.override }} = "true" ]]; then + docker push ${{ .inputs.tag }} ${{ .inputs.options }} + fi + + ######### + # CLEANUP + ######### + - name: clean-artifacts + actions: + - description: "Clean artifacts" + shell: + linux: bash + darwin: bash + cmd: | + rm -f zarf-package-*.tar.zst + rm -f packages/**/zarf-package-*.tar.zst + rm -rf build + rm -rf src/**/build + rm -rf packages/**/build + find . -name 'uds-bundle-*-*.tar.zst' -delete + find . -type d -name 'zarf-sbom' -exec rm -rf {} + + find . -name '*.whl' -delete + find . -type d -name '*.egg-info' -exec rm -rf {} + + mute: true + + - name: clean-ui + actions: + - description: "Clean UI artifacts" + shell: + linux: bash + darwin: bash + cmd: | + rm -rf src/leapfrogai_ui/playwright + rm -rf src/leapfrogai_ui/.svelte-kit + rm -rf src/leapfrogai_ui/node_modules + rm -rf src/leapfrogai_ui/test-results + rm -f src/leapfrogai_ui/.env + rm -rf src/leapfrogai_ui/e2e-report + mute: true + + - name: clean-cache + actions: + - description: "Clean cache" + shell: + linux: bash + darwin: bash + cmd: | + rm -rf ./**/__pycache__ ./**/*/__pycache__ ./**/**/*/__pycache__ + rm -rf ./.ruff_cache ./**/*/.ruff_cache ./**/.ruff_cache + rm -rf ./.pytest_cache ./**/.pytest_cache ./**/*/.pytest_cache + rm -rf ./.mypy_cache + mute: true + + - name: clean-env + actions: + - description: "Clean env files" + shell: + linux: bash + darwin: bash + cmd: | + rm -f .env + rm -f .env.email + rm -f .env.password + mute: true + + - name: clean-logs + actions: + - description: "Clean log files" + shell: + linux: bash + darwin: bash + cmd: | + rm -rf ./.logs + mute: true + + - name: clean-models + actions: + - description: "Clean model files" + shell: + linux: bash + darwin: bash + cmd: | + rm -rf ./packages/**/.model + mute: true diff --git a/website/content/en/docs/local-deploy-guide/components.md b/website/content/en/docs/local-deploy-guide/components.md index f062994f0..b384d1404 100644 --- a/website/content/en/docs/local-deploy-guide/components.md +++ b/website/content/en/docs/local-deploy-guide/components.md @@ -33,7 +33,7 @@ Below is the current component flavors list: | Component | `upstream` | `registry1` | | ---------------------------------------------- | ------------ | ------------- | | [api](packages/api/) | ✅ | ✅ | -| [ui](packages/ui/) | ✅ | 🚧 | +| [ui](packages/ui/) | ✅ | ✅ | | [supabase](packages/supabase/) | ✅ | 🚧 | | [migrations](./Dockerfile.migrations) | ✅ | 🚧 | | [llama-cpp-python](packages/llama-cpp-python/) | ✅ | 🚧 | diff --git a/website/content/en/docs/local-deploy-guide/quick_start.md b/website/content/en/docs/local-deploy-guide/quick_start.md index 95f04fda7..05c8f06fa 100644 --- a/website/content/en/docs/local-deploy-guide/quick_start.md +++ b/website/content/en/docs/local-deploy-guide/quick_start.md @@ -61,9 +61,9 @@ If you already have a pre-built UDS bundle, please skip to [Deploying the UDS Bu 1. Deploy a UDS Kubernetes cluster with **ONE** of the following: ```bash - make create-uds-cpu-cluster # if you have CPUs only + uds run setup:k3d-cpu-cluster-slim # if you have CPUs only # OR - make create-uds-gpu-cluster # if you have GPUs (macOS not supported) + uds run setup:k3d-gpu-cluster-slim # if you have GPUs (macOS not supported) ``` 2. Deploy the bundle you created in the [previous steps](#building-the-uds-bundle):