From 0be8a07ebbac4e0a32700059de670affc70f3ac5 Mon Sep 17 00:00:00 2001 From: Simone Tollardo Date: Fri, 11 Apr 2025 14:39:15 +0200 Subject: [PATCH 1/7] feat: local deploy fail on error Signed-off-by: Simone Tollardo --- localinstall/1-rebuild_all.sh | 24 ++++++++---------------- localinstall/2-install_api.sh | 8 ++++++++ localinstall/3-install_pipeline.sh | 11 +++++++++-- localinstall/4-start-cycle.sh | 8 ++++++++ localinstall/kci-deploy.py | 19 +++++++++++++++---- 5 files changed, 48 insertions(+), 22 deletions(-) diff --git a/localinstall/1-rebuild_all.sh b/localinstall/1-rebuild_all.sh index 7ad8982..30a0656 100755 --- a/localinstall/1-rebuild_all.sh +++ b/localinstall/1-rebuild_all.sh @@ -1,6 +1,14 @@ #!/bin/bash . ./main.cfg +function fail_with_error() { + echo "ERROR: $1" + exit 1 +} + +set -e +trap 'fail_with_error "Command failed at line $LINENO"' ERR + # i am groot? if [ $(id -u) -ne 0 ]; then SUDO=sudo @@ -8,13 +16,6 @@ else SUDO= fi -function failonerror { - if [ $? -ne 0 ]; then - echo "Failed" - exit 1 - fi -} - # if directry kernelci doesn't exist, then we dont have repos cloned if [ ! -d kernelci ]; then echo Create kernelci directory, clone repos and checkout branches @@ -88,30 +89,21 @@ px_arg='--prefix=local/staging-' args="build --verbose $px_arg $build_args" echo Build docker images: kernelci args=$args ./kci docker $args kernelci -failonerror echo Build docker images: k8s+kernelci ./kci docker $args k8s kernelci -failonerror echo Build docker images: api ./kci docker $args kernelci api --version="$api_rev" -failonerror echo Build docker images: pipeline ./kci docker $args kernelci pipeline --version="$pipeline_rev" -failonerror echo Tag docker image of api to latest docker tag local/staging-kernelci:api-$api_rev local/staging-kernelci:api -failonerror echo Tag docker image of pipeline to latest docker tag local/staging-kernelci:pipeline-$pipeline_rev local/staging-kernelci:pipeline -failonerror echo Build docker images: clang-17+kselftest+kernelci for x86 ./kci docker $args clang-17 kselftest kernelci --arch x86 -failonerror echo Build docker images: gcc-12+kselftest+kernelci for x86 ./kci docker $args gcc-12 kselftest kernelci --arch x86 -failonerror echo Build docker images: gcc-12+kselftest+kernelci for arm64 ./kci docker $args gcc-12 kselftest kernelci --arch arm64 -failonerror diff --git a/localinstall/2-install_api.sh b/localinstall/2-install_api.sh index 102d3a5..797f979 100755 --- a/localinstall/2-install_api.sh +++ b/localinstall/2-install_api.sh @@ -9,6 +9,14 @@ else DOCKER_COMPOSE="docker-compose" fi +function fail_with_error() { + echo "ERROR: $1" + exit 1 +} + +set -e +trap 'fail_with_error "Command failed at line $LINENO"' ERR + # i am groot? if [ $(id -u) -ne 0 ]; then SUDO=sudo diff --git a/localinstall/3-install_pipeline.sh b/localinstall/3-install_pipeline.sh index f54a2e5..9a8b627 100755 --- a/localinstall/3-install_pipeline.sh +++ b/localinstall/3-install_pipeline.sh @@ -1,6 +1,14 @@ #!/bin/bash . ./main.cfg +function fail_with_error() { + echo "ERROR: $1" + exit 1 +} + +set -e +trap 'fail_with_error "Command failed at line $LINENO"' ERR + ## This is hacky way of inserting things that probably will outlive trivial patch after changes # find line number with storage: function append_storage() { @@ -69,8 +77,7 @@ sed -i 's/kernelci\/staging-/local\/staging-/g' kernelci/kernelci-pipeline/confi # check if kernelci/kernelci-pipeline/config/kernelci.toml # has [trigger] and then force = 1 # this will force builds on each restart -grep -q "force = 1" kernelci/kernelci-pipeline/config/kernelci.toml -if [ $? -ne 0 ]; then +if ! grep -q "force = 1" kernelci/kernelci-pipeline/config/kernelci.toml; then sed -i '/\[trigger\]/a force = 1' kernelci/kernelci-pipeline/config/kernelci.toml fi diff --git a/localinstall/4-start-cycle.sh b/localinstall/4-start-cycle.sh index caca6d4..72352d5 100755 --- a/localinstall/4-start-cycle.sh +++ b/localinstall/4-start-cycle.sh @@ -9,6 +9,14 @@ else DOCKER_COMPOSE="docker-compose" fi +function fail_with_error() { + echo "ERROR: $1" + exit 1 +} + +set -e +trap 'fail_with_error "Command failed at line $LINENO"' ERR + cd kernelci/kernelci-pipeline ${DOCKER_COMPOSE} down ${DOCKER_COMPOSE} up -d diff --git a/localinstall/kci-deploy.py b/localinstall/kci-deploy.py index 0e3f62d..0de6506 100644 --- a/localinstall/kci-deploy.py +++ b/localinstall/kci-deploy.py @@ -3,7 +3,18 @@ import os -os.system("./1-rebuild_all.sh") -os.system("./2-install_api.sh") -os.system("./3-install_pipeline.sh") -os.system("./4-start-cycle.sh") +res = os.system("./1-rebuild_all.sh") +if res != 0: + exit(1) + +res = os.system("./2-install_api.sh") +if res != 0: + exit(1) + +res = os.system("./3-install_pipeline.sh") +if res != 0: + exit(1) + +res = os.system("./4-start-cycle.sh") +if res != 0: + exit(1) From 6236f3d6d43f07ace98359f5e13543658d16cbd8 Mon Sep 17 00:00:00 2001 From: Simone Tollardo Date: Fri, 11 Apr 2025 14:40:50 +0200 Subject: [PATCH 2/7] explicit 'expect' call in local deployment Signed-off-by: Simone Tollardo --- localinstall/2-install_api.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/localinstall/2-install_api.sh b/localinstall/2-install_api.sh index 797f979..2af4a51 100755 --- a/localinstall/2-install_api.sh +++ b/localinstall/2-install_api.sh @@ -71,11 +71,11 @@ fi # INFO, if you have issues with stale/old data, check for # docker volume kernelci-api_mongodata and delete it -../../helpers/scripts_setup_admin_user.exp "${YOUR_EMAIL}" "${ADMIN_PASSWORD}" +expect ../../helpers/scripts_setup_admin_user.exp "${YOUR_EMAIL}" "${ADMIN_PASSWORD}" cd ../kernelci-core echo "Issuing token for admin user" -../../helpers/kci_user_token_admin.exp "${ADMIN_PASSWORD}" > ../../admin-token.txt +expect ../../helpers/kci_user_token_admin.exp "${ADMIN_PASSWORD}" > ../../admin-token.txt ADMIN_TOKEN=$(cat ../../admin-token.txt) echo "[kci.secrets] From 54801c93ca99d64be0d95ee169b70102f1b4b59d Mon Sep 17 00:00:00 2001 From: Simone Tollardo Date: Fri, 11 Apr 2025 14:42:36 +0200 Subject: [PATCH 3/7] fix: remove build of unused images for local deploy Signed-off-by: Simone Tollardo --- localinstall/1-rebuild_all.sh | 4 ---- 1 file changed, 4 deletions(-) diff --git a/localinstall/1-rebuild_all.sh b/localinstall/1-rebuild_all.sh index 30a0656..c679ed4 100755 --- a/localinstall/1-rebuild_all.sh +++ b/localinstall/1-rebuild_all.sh @@ -87,10 +87,6 @@ core_url=$(git remote get-url origin) build_args="--build-arg pipeline_rev=$pipeline_rev --build-arg core_rev=$core_rev --build-arg api_rev=$api_rev --build-arg pipeline_url=$pipeline_url --build-arg core_url=$core_url --build-arg api_url=$api_url" px_arg='--prefix=local/staging-' args="build --verbose $px_arg $build_args" -echo Build docker images: kernelci args=$args -./kci docker $args kernelci -echo Build docker images: k8s+kernelci -./kci docker $args k8s kernelci echo Build docker images: api ./kci docker $args kernelci api --version="$api_rev" echo Build docker images: pipeline From 86f19356e27a3dcfcc6bb1806c8e14b2ebb0cf0d Mon Sep 17 00:00:00 2001 From: Simone Tollardo Date: Fri, 11 Apr 2025 15:08:03 +0200 Subject: [PATCH 4/7] refactor: avoid double-step container image tagging Signed-off-by: Simone Tollardo --- localinstall/1-rebuild_all.sh | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/localinstall/1-rebuild_all.sh b/localinstall/1-rebuild_all.sh index c679ed4..41c1742 100755 --- a/localinstall/1-rebuild_all.sh +++ b/localinstall/1-rebuild_all.sh @@ -88,13 +88,9 @@ build_args="--build-arg pipeline_rev=$pipeline_rev --build-arg core_rev=$core_re px_arg='--prefix=local/staging-' args="build --verbose $px_arg $build_args" echo Build docker images: api -./kci docker $args kernelci api --version="$api_rev" +./kci docker $args kernelci api echo Build docker images: pipeline -./kci docker $args kernelci pipeline --version="$pipeline_rev" -echo Tag docker image of api to latest -docker tag local/staging-kernelci:api-$api_rev local/staging-kernelci:api -echo Tag docker image of pipeline to latest -docker tag local/staging-kernelci:pipeline-$pipeline_rev local/staging-kernelci:pipeline +./kci docker $args kernelci pipeline echo Build docker images: clang-17+kselftest+kernelci for x86 ./kci docker $args clang-17 kselftest kernelci --arch x86 echo Build docker images: gcc-12+kselftest+kernelci for x86 From fd67670ed9da2cef2d1b498fc87b192e71a8a820 Mon Sep 17 00:00:00 2001 From: Simone Tollardo Date: Fri, 11 Apr 2025 19:32:06 +0200 Subject: [PATCH 5/7] kci-deploy using docker in docker, refactor and clean Signed-off-by: Simone Tollardo --- localinstall/.gitignore | 7 ++ localinstall/Containerfile | 48 ++++++++++++ localinstall/README.md | 27 ++++--- localinstall/{ => config}/.env-api | 0 localinstall/{ => config}/api-configs.yaml | 0 localinstall/{ => config}/kernelci-cli.toml | 0 localinstall/{ => config}/main.cfg | 0 localinstall/kci-deploy.py | 20 ----- localinstall/kci-deploy.sh | 77 +++++++++++++++++++ localinstall/{ => scripts}/1-rebuild_all.sh | 8 +- localinstall/{ => scripts}/2-install_api.sh | 26 +++---- .../{ => scripts}/3-install_pipeline.sh | 11 +-- .../4-start_cycle.sh} | 7 +- localinstall/scripts/run.sh | 39 ++++++++++ 14 files changed, 202 insertions(+), 68 deletions(-) create mode 100644 localinstall/.gitignore create mode 100644 localinstall/Containerfile rename localinstall/{ => config}/.env-api (100%) rename localinstall/{ => config}/api-configs.yaml (100%) rename localinstall/{ => config}/kernelci-cli.toml (100%) rename localinstall/{ => config}/main.cfg (100%) delete mode 100644 localinstall/kci-deploy.py create mode 100755 localinstall/kci-deploy.sh rename localinstall/{ => scripts}/1-rebuild_all.sh (95%) rename localinstall/{ => scripts}/2-install_api.sh (76%) rename localinstall/{ => scripts}/3-install_pipeline.sh (94%) rename localinstall/{4-start-cycle.sh => scripts/4-start_cycle.sh} (84%) create mode 100755 localinstall/scripts/run.sh diff --git a/localinstall/.gitignore b/localinstall/.gitignore new file mode 100644 index 0000000..56112ea --- /dev/null +++ b/localinstall/.gitignore @@ -0,0 +1,7 @@ +kernelci +config/out/* +.sudo_as_admin_successful +.cache +.local +.docker +.bash_history \ No newline at end of file diff --git a/localinstall/Containerfile b/localinstall/Containerfile new file mode 100644 index 0000000..2fb255c --- /dev/null +++ b/localinstall/Containerfile @@ -0,0 +1,48 @@ +FROM kernelci/kernelci:latest + +ARG USER_ID=1000 +ARG GROUP_ID=1000 + +USER root + +# Install dependencies for Docker installation +RUN apt-get update && \ + apt-get install -y --no-install-recommends \ + sudo \ + ca-certificates \ + curl \ + gnupg \ + lsb-release + +# Add Docker's official GPG key +RUN mkdir -p /etc/apt/keyrings && \ + curl -fsSL https://download.docker.com/linux/debian/gpg | gpg --dearmor -o /etc/apt/keyrings/docker.gpg && \ + chmod a+r /etc/apt/keyrings/docker.gpg + +# Set up Docker repository (assuming Debian-based image) +RUN echo \ + "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.gpg] https://download.docker.com/linux/debian \ + $(lsb_release -cs) stable" | tee /etc/apt/sources.list.d/docker.list > /dev/null + +# Install Docker Engine, CLI, and Compose plugin +RUN apt-get update && \ + apt-get install -y --no-install-recommends \ + docker-ce \ + docker-ce-cli \ + containerd.io \ + docker-compose-plugin \ + expect + +# Make sure a user exists with the same USER_ID/GROUP_ID as the host user +# to allow access to the host docker socket +RUN groupadd -g ${GROUP_ID} kernelci || true && \ + useradd -u ${USER_ID} -g ${GROUP_ID} -m -s /bin/bash kernelci || true + +# Add the user to the sudoers +RUN usermod -aG sudo kernelci && \ + echo "kernelci ALL=(ALL) NOPASSWD:ALL" >> /etc/sudoers + +USER kernelci +WORKDIR /home/kernelci + +ENTRYPOINT ["/bin/bash", "./scripts/run.sh"] diff --git a/localinstall/README.md b/localinstall/README.md index 57cc887..2437ba5 100644 --- a/localinstall/README.md +++ b/localinstall/README.md @@ -1,16 +1,19 @@ -# kci-easy - +# kci-deploy Get your own KernelCI instance up and running in no time. -## Getting started - -### Prerequisites - -- git -- Docker (with `compose` plugin, set up for a regular user) -- Python environment with [KernelCI core dependencies](https://github.com/kernelci/kernelci-core/blob/main/requirements.txt) installed -- expect +## Prerequisites +- Docker -### Running +## Configure +Configure and setup credentials in config files located in `config` folder. -Change `ADMIN_PASSWORD` in the `main.cfg`, then run shell scripts from the root directory in their order. +## Run +You can start your KernelCI deployment by simply executing: +```bash +./kci-deploy.sh run +``` +and +```bash +./kci-deploy.sh stop +``` +to terminate it. diff --git a/localinstall/.env-api b/localinstall/config/.env-api similarity index 100% rename from localinstall/.env-api rename to localinstall/config/.env-api diff --git a/localinstall/api-configs.yaml b/localinstall/config/api-configs.yaml similarity index 100% rename from localinstall/api-configs.yaml rename to localinstall/config/api-configs.yaml diff --git a/localinstall/kernelci-cli.toml b/localinstall/config/kernelci-cli.toml similarity index 100% rename from localinstall/kernelci-cli.toml rename to localinstall/config/kernelci-cli.toml diff --git a/localinstall/main.cfg b/localinstall/config/main.cfg similarity index 100% rename from localinstall/main.cfg rename to localinstall/config/main.cfg diff --git a/localinstall/kci-deploy.py b/localinstall/kci-deploy.py deleted file mode 100644 index 0de6506..0000000 --- a/localinstall/kci-deploy.py +++ /dev/null @@ -1,20 +0,0 @@ -#!/usr/bin/env python3 -# - -import os - -res = os.system("./1-rebuild_all.sh") -if res != 0: - exit(1) - -res = os.system("./2-install_api.sh") -if res != 0: - exit(1) - -res = os.system("./3-install_pipeline.sh") -if res != 0: - exit(1) - -res = os.system("./4-start-cycle.sh") -if res != 0: - exit(1) diff --git a/localinstall/kci-deploy.sh b/localinstall/kci-deploy.sh new file mode 100755 index 0000000..264c6bf --- /dev/null +++ b/localinstall/kci-deploy.sh @@ -0,0 +1,77 @@ +#!/bin/bash + +set -e + +IMAGE_NAME="local/kernelci-deployer:latest" +BUILD_IMAGE=false +ACTION="" +CONTAINER_ARGS=() + +function print_help() { + echo "Usage: $0 [--build] (run|stop) [args...]" + echo + echo "Options:" + echo " --build Force rebuild of the Deployer image (optional)" + echo " run Run kernelci deployment (default if no action specified)" + echo " stop Stop and remove kernelci deployment" + echo " -h, --help Show this help message" + echo + echo "Arguments after 'run' or 'stop' are passed to the container entrypoint" + exit 0 +} + +# Parse args +while [[ $# -gt 0 ]]; do + case "$1" in + --build) + BUILD_IMAGE=true + shift + ;; + run|stop) + if [[ -n "$ACTION" ]]; then + echo "Error: Cannot use both 'run' and 'stop'" + exit 1 + fi + ACTION=$1 + shift + CONTAINER_ARGS=("$@") + break + ;; + -h|--help) + print_help + ;; + *) + echo "Unknown option: $1" + print_help + ;; + esac +done + +# Default +if [[ -z "$ACTION" ]]; then + ACTION="run" +fi + +USER_ID=$(id -u) +GROUP_ID=$(id -g) + +if [[ "$BUILD_IMAGE" = true || -z $(docker images -q "$IMAGE_NAME") ]]; then + echo "Building $IMAGE_NAME" + docker build \ + --build-arg USER_ID=$USER_ID \ + --build-arg GROUP_ID=$GROUP_ID \ + -f Containerfile \ + -t "$IMAGE_NAME" \ + . +fi + +echo "Running $IMAGE_NAME with action '$ACTION' and args: ${CONTAINER_ARGS[*]}" +docker run --rm \ + --name kernelci-deployer \ + -v /var/run/docker.sock:/var/run/docker.sock \ + -v "$(pwd)":"$(pwd)" \ + --workdir "$(pwd)" \ + --group-add "$(stat -c '%g' /var/run/docker.sock)" \ + --network host \ + "$IMAGE_NAME" \ + "$ACTION" "${CONTAINER_ARGS[@]}" diff --git a/localinstall/1-rebuild_all.sh b/localinstall/scripts/1-rebuild_all.sh similarity index 95% rename from localinstall/1-rebuild_all.sh rename to localinstall/scripts/1-rebuild_all.sh index 41c1742..9978e96 100755 --- a/localinstall/1-rebuild_all.sh +++ b/localinstall/scripts/1-rebuild_all.sh @@ -1,13 +1,8 @@ #!/bin/bash -. ./main.cfg -function fail_with_error() { - echo "ERROR: $1" - exit 1 -} +. ./config/main.cfg set -e -trap 'fail_with_error "Command failed at line $LINENO"' ERR # i am groot? if [ $(id -u) -ne 0 ]; then @@ -98,4 +93,3 @@ echo Build docker images: gcc-12+kselftest+kernelci for x86 echo Build docker images: gcc-12+kselftest+kernelci for arm64 ./kci docker $args gcc-12 kselftest kernelci --arch arm64 - diff --git a/localinstall/2-install_api.sh b/localinstall/scripts/2-install_api.sh similarity index 76% rename from localinstall/2-install_api.sh rename to localinstall/scripts/2-install_api.sh index 2af4a51..251bcf5 100755 --- a/localinstall/2-install_api.sh +++ b/localinstall/scripts/2-install_api.sh @@ -1,5 +1,4 @@ -#!/bin/sh -. ./main.cfg +#!/bin/bash # is docker-compose exists? if not use docker compose if [ -z "$(which docker-compose)" ]; then @@ -9,13 +8,9 @@ else DOCKER_COMPOSE="docker-compose" fi -function fail_with_error() { - echo "ERROR: $1" - exit 1 -} +. ./config/main.cfg set -e -trap 'fail_with_error "Command failed at line $LINENO"' ERR # i am groot? if [ $(id -u) -ne 0 ]; then @@ -24,24 +19,25 @@ else SUDO= fi -cp .env-api kernelci/kernelci-api/.env -cp api-configs.yaml kernelci/kernelci-core/config/core/ -cp kernelci-cli.toml kernelci/kernelci-core/kernelci.toml +cp config/.env-api kernelci/kernelci-api/.env +cp config/api-configs.yaml kernelci/kernelci-core/config/core/ +cp config/kernelci-cli.toml kernelci/kernelci-core/kernelci.toml cd kernelci/kernelci-api mkdir -p docker/redis/data ${SUDO} chmod -R 0777 docker/storage/data ${SUDO} chmod -R 0777 docker/redis/data # enable ssh and storage nginx +mkdir -p ../../config/out sed -i 's/^# / /' docker-compose.yaml -if [ -f ../../ssh.key ]; then +if [ -f ../../config/out/ssh.key ]; then echo "ssh.key already exists" else # generate non-interactively ssh key to ssh.key - ssh-keygen -t rsa -b 4096 -N "" -f ../../ssh.key + ssh-keygen -t rsa -b 4096 -N "" -f ../../config/out/ssh.key fi # get public key and add to docker/ssh/user-data/authorized_keys -cat ../../ssh.key.pub > docker/ssh/user-data/authorized_keys +cat ../../config/out/ssh.key.pub > docker/ssh/user-data/authorized_keys # down, just in case old containers are running ${DOCKER_COMPOSE} down @@ -75,8 +71,8 @@ expect ../../helpers/scripts_setup_admin_user.exp "${YOUR_EMAIL}" "${ADMIN_PASSW cd ../kernelci-core echo "Issuing token for admin user" -expect ../../helpers/kci_user_token_admin.exp "${ADMIN_PASSWORD}" > ../../admin-token.txt -ADMIN_TOKEN=$(cat ../../admin-token.txt) +expect ../../helpers/kci_user_token_admin.exp "${ADMIN_PASSWORD}" > ../../config/out/admin-token.txt +ADMIN_TOKEN=$(cat ../../config/out/admin-token.txt) echo "[kci.secrets] api.\"docker-host\".token = \"$ADMIN_TOKEN\" diff --git a/localinstall/3-install_pipeline.sh b/localinstall/scripts/3-install_pipeline.sh similarity index 94% rename from localinstall/3-install_pipeline.sh rename to localinstall/scripts/3-install_pipeline.sh index 9a8b627..75d4fb3 100755 --- a/localinstall/3-install_pipeline.sh +++ b/localinstall/scripts/3-install_pipeline.sh @@ -1,13 +1,8 @@ #!/bin/bash -. ./main.cfg -function fail_with_error() { - echo "ERROR: $1" - exit 1 -} +. ./config/main.cfg set -e -trap 'fail_with_error "Command failed at line $LINENO"' ERR ## This is hacky way of inserting things that probably will outlive trivial patch after changes # find line number with storage: @@ -62,7 +57,7 @@ sed -i "s|- '/data/kernelci-deploy-checkout/kernelci-pipeline/data/output/|- '$P # set 777 to data/output and data/ssh (TODO: or set proper uid, kernelci is 1000?) chmod -R 777 data chmod 777 data/ssh -cp ../../ssh.key data/ssh/id_rsa_tarball +cp ../../config/out/ssh.key data/ssh/id_rsa_tarball chown 1000:1000 data/ssh/id_rsa_tarball chmod 600 data/ssh/id_rsa_tarball cd ../.. @@ -95,7 +90,7 @@ EOF #KCI_STORAGE_CREDENTIALS=L0CALT0KEN #KCI_API_TOKEN= #API_TOKEN= -API_TOKEN=$(cat admin-token.txt) +API_TOKEN=$(cat config/out/admin-token.txt) echo "KCI_STORAGE_CREDENTIALS=/home/kernelci/data/ssh/id_rsa_tarball" > .env echo "KCI_API_TOKEN=${API_TOKEN}" >> .env echo "API_TOKEN=${API_TOKEN}" >> .env diff --git a/localinstall/4-start-cycle.sh b/localinstall/scripts/4-start_cycle.sh similarity index 84% rename from localinstall/4-start-cycle.sh rename to localinstall/scripts/4-start_cycle.sh index 72352d5..ad52701 100755 --- a/localinstall/4-start-cycle.sh +++ b/localinstall/scripts/4-start_cycle.sh @@ -1,5 +1,4 @@ #!/bin/bash -. ./main.cfg # is docker-compose exists? if not use docker compose if [ -z "$(which docker-compose)" ]; then @@ -9,13 +8,9 @@ else DOCKER_COMPOSE="docker-compose" fi -function fail_with_error() { - echo "ERROR: $1" - exit 1 -} +. ./config/main.cfg set -e -trap 'fail_with_error "Command failed at line $LINENO"' ERR cd kernelci/kernelci-pipeline ${DOCKER_COMPOSE} down diff --git a/localinstall/scripts/run.sh b/localinstall/scripts/run.sh new file mode 100755 index 0000000..61299ee --- /dev/null +++ b/localinstall/scripts/run.sh @@ -0,0 +1,39 @@ +#!/bin/bash + +set -e + +ACTION=$1 + +function print_help() { + echo "Usage: $0 (run|stop)" + echo + echo " run Execute deployment sequence" + echo " stop Stop and remove deployment" + exit 1 +} + +if [[ -z "$ACTION" ]]; then + echo "Error: Missing required action (run or stop)" + print_help +fi + +case "$ACTION" in + run) + echo "Starting deployment sequence, this may take a while..." + ./scripts/1-rebuild_all.sh + ./scripts/2-install_api.sh + ./scripts/3-install_pipeline.sh + ./scripts/4-start_cycle.sh + ;; + stop) + echo "Stopping deployment" + cd kernelci/kernelci-api + docker compose down + cd ../kernelci-pipeline + docker compose down + ;; + *) + echo "Error: Invalid action '$ACTION'" + print_help + ;; +esac From 52e707d99d27ea4b7dddbee9d02873c160eab7a1 Mon Sep 17 00:00:00 2001 From: Simone Tollardo Date: Wed, 16 Apr 2025 16:59:23 +0200 Subject: [PATCH 6/7] fix local deploy pipeline data permissions Signed-off-by: Simone Tollardo --- localinstall/scripts/3-install_pipeline.sh | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/localinstall/scripts/3-install_pipeline.sh b/localinstall/scripts/3-install_pipeline.sh index 75d4fb3..e63d979 100755 --- a/localinstall/scripts/3-install_pipeline.sh +++ b/localinstall/scripts/3-install_pipeline.sh @@ -54,12 +54,10 @@ sed -i "s|- 'data/ssh/|- '$PIPELINE_PWD/data/ssh/|g" config/pipeline.yaml sed -i "s|- '/data/kernelci-deploy-checkout/kernelci-pipeline/data/ssh/|- '$PIPELINE_PWD/data/ssh/|g" config/pipeline.yaml sed -i "s|- '/data/kernelci-deploy-checkout/kernelci-pipeline/data/output/|- '$PIPELINE_PWD/data/output/|g" config/pipeline.yaml -# set 777 to data/output and data/ssh (TODO: or set proper uid, kernelci is 1000?) -chmod -R 777 data chmod 777 data/ssh cp ../../config/out/ssh.key data/ssh/id_rsa_tarball -chown 1000:1000 data/ssh/id_rsa_tarball chmod 600 data/ssh/id_rsa_tarball +chown -R $(id -u):$(id -g) data/output cd ../.. #replace kernelci/staging- by local/staging- From 8db17247a15aa9c1589d90116b5977e39960e9d6 Mon Sep 17 00:00:00 2001 From: Simone Tollardo Date: Wed, 16 Apr 2025 17:43:28 +0200 Subject: [PATCH 7/7] separate deploy and start command Signed-off-by: Simone Tollardo --- localinstall/README.md | 13 ++- localinstall/kci-deploy.sh | 15 +-- localinstall/scripts/2-prepare_api.sh | 34 ++++++ localinstall/scripts/3-start_api.sh | 35 ++++++ localinstall/scripts/4-set_api_admin.sh | 33 ++++++ localinstall/scripts/5-prepare_pipeline.sh | 103 ++++++++++++++++++ .../{4-start_cycle.sh => 6-start_pipeline.sh} | 0 localinstall/scripts/run.sh | 35 ++++-- 8 files changed, 249 insertions(+), 19 deletions(-) create mode 100755 localinstall/scripts/2-prepare_api.sh create mode 100755 localinstall/scripts/3-start_api.sh create mode 100755 localinstall/scripts/4-set_api_admin.sh create mode 100755 localinstall/scripts/5-prepare_pipeline.sh rename localinstall/scripts/{4-start_cycle.sh => 6-start_pipeline.sh} (100%) diff --git a/localinstall/README.md b/localinstall/README.md index 2437ba5..f99864d 100644 --- a/localinstall/README.md +++ b/localinstall/README.md @@ -8,12 +8,17 @@ Get your own KernelCI instance up and running in no time. Configure and setup credentials in config files located in `config` folder. ## Run -You can start your KernelCI deployment by simply executing: +You can deploy your KernelCI deployment by simply executing: ```bash -./kci-deploy.sh run +./kci-deploy.sh deploy ``` -and + +You can stop your local deployment by executing: ```bash ./kci-deploy.sh stop ``` -to terminate it. +and +```bash +./kci-deploy.sh start +``` +to start it again. diff --git a/localinstall/kci-deploy.sh b/localinstall/kci-deploy.sh index 264c6bf..aeb740d 100755 --- a/localinstall/kci-deploy.sh +++ b/localinstall/kci-deploy.sh @@ -8,15 +8,16 @@ ACTION="" CONTAINER_ARGS=() function print_help() { - echo "Usage: $0 [--build] (run|stop) [args...]" + echo "Usage: $0 [--build] (deploy|start|stop) [args...]" echo echo "Options:" echo " --build Force rebuild of the Deployer image (optional)" - echo " run Run kernelci deployment (default if no action specified)" - echo " stop Stop and remove kernelci deployment" + echo " deploy Configure and start the kernelci deployment" + echo " start Start the already configured kernelci deployment (default if no action specified)" + echo " stop Stop the kernelci deployment" echo " -h, --help Show this help message" echo - echo "Arguments after 'run' or 'stop' are passed to the container entrypoint" + echo "Arguments after 'deploy', 'start' or 'stop' are passed to the container entrypoint" exit 0 } @@ -27,9 +28,9 @@ while [[ $# -gt 0 ]]; do BUILD_IMAGE=true shift ;; - run|stop) + deploy|start|stop) if [[ -n "$ACTION" ]]; then - echo "Error: Cannot use both 'run' and 'stop'" + echo "Error: Cannot use more than one command among 'deploy', 'start' or 'stop'" exit 1 fi ACTION=$1 @@ -49,7 +50,7 @@ done # Default if [[ -z "$ACTION" ]]; then - ACTION="run" + ACTION="start" fi USER_ID=$(id -u) diff --git a/localinstall/scripts/2-prepare_api.sh b/localinstall/scripts/2-prepare_api.sh new file mode 100755 index 0000000..ee9b57a --- /dev/null +++ b/localinstall/scripts/2-prepare_api.sh @@ -0,0 +1,34 @@ +#!/bin/bash + +. ./config/main.cfg + +set -e + +# i am groot? +if [ $(id -u) -ne 0 ]; then + SUDO=sudo +else + SUDO= +fi + +cp config/.env-api kernelci/kernelci-api/.env +cp config/api-configs.yaml kernelci/kernelci-core/config/core/ +cp config/kernelci-cli.toml kernelci/kernelci-core/kernelci.toml + +sed -i "s/#SECRET_KEY=/SECRET_KEY=${API_SECRET_KEY}/" kernelci/kernelci-api/.env + +cd kernelci/kernelci-api +mkdir -p docker/redis/data +${SUDO} chmod -R 0777 docker/storage/data +${SUDO} chmod -R 0777 docker/redis/data +# enable ssh and storage nginx +mkdir -p ../../config/out +sed -i 's/^# / /' docker-compose.yaml +if [ -f ../../config/out/ssh.key ]; then + echo "ssh.key already exists" +else + # generate non-interactively ssh key to ssh.key + ssh-keygen -t rsa -b 4096 -N "" -f ../../config/out/ssh.key +fi +# get public key and add to docker/ssh/user-data/authorized_keys +cat ../../config/out/ssh.key.pub > docker/ssh/user-data/authorized_keys diff --git a/localinstall/scripts/3-start_api.sh b/localinstall/scripts/3-start_api.sh new file mode 100755 index 0000000..34b0794 --- /dev/null +++ b/localinstall/scripts/3-start_api.sh @@ -0,0 +1,35 @@ +#!/bin/bash + +. ./config/main.cfg + +set -e + +# i am groot? +if [ $(id -u) -ne 0 ]; then + SUDO=sudo +else + SUDO= +fi + +cd kernelci/kernelci-api + +# down, just in case old containers are running +docker compose down +docker compose up -d +echo "Waiting for API to be up" +sleep 1 +# loop until the API is up, try 5 times +i=0 +while [ $i -lt 5 ]; do + ANSWER=$(curl http://localhost:8001/latest/) + # must be {"message":"KernelCI API"} + if [ "$ANSWER" != "{\"message\":\"KernelCI API\"}" ]; then + echo "API is not up" + i=$((i+1)) + sleep 5 + else + echo "API is up" + break + fi +done + diff --git a/localinstall/scripts/4-set_api_admin.sh b/localinstall/scripts/4-set_api_admin.sh new file mode 100755 index 0000000..db86d11 --- /dev/null +++ b/localinstall/scripts/4-set_api_admin.sh @@ -0,0 +1,33 @@ +#!/bin/bash + +. ./config/main.cfg + +set -e + +# i am groot? +if [ $(id -u) -ne 0 ]; then + SUDO=sudo +else + SUDO= +fi + +cd kernelci/kernelci-api + +# check for expect +if [ -z "$(which expect)" ]; then + echo "expect is not installed, please install it" + exit 1 +fi + +# INFO, if you have issues with stale/old data, check for +# docker volume kernelci-api_mongodata and delete it +expect ../../helpers/scripts_setup_admin_user.exp "${YOUR_EMAIL}" "${ADMIN_PASSWORD}" + +cd ../kernelci-core +echo "Issuing token for admin user" +expect ../../helpers/kci_user_token_admin.exp "${ADMIN_PASSWORD}" > ../../config/out/admin-token.txt +ADMIN_TOKEN=$(cat ../../config/out/admin-token.txt | tr -d '\r\n') + +echo "[kci.secrets] +api.\"docker-host\".token = \"$ADMIN_TOKEN\" +" >> kernelci.toml \ No newline at end of file diff --git a/localinstall/scripts/5-prepare_pipeline.sh b/localinstall/scripts/5-prepare_pipeline.sh new file mode 100755 index 0000000..053a89c --- /dev/null +++ b/localinstall/scripts/5-prepare_pipeline.sh @@ -0,0 +1,103 @@ +#!/bin/bash + +. ./config/main.cfg + +set -e + +## This is hacky way of inserting things that probably will outlive trivial patch after changes +# find line number with storage: +function append_storage() { +line=$(grep -n "^storage:$" kernelci/kernelci-pipeline/config/pipeline.yaml | cut -d: -f1) +head -n $line kernelci/kernelci-pipeline/config/pipeline.yaml > tmp.yaml +# insert after line with storage: the following lines +echo " + personal: + storage_type: backend + base_url: http://localhost:8080/user1/ + api_url: http://localhost:8080/" >> tmp.yaml +# insert the rest of the file +tail -n +$((line+1)) kernelci/kernelci-pipeline/config/pipeline.yaml >> tmp.yaml +mv tmp.yaml kernelci/kernelci-pipeline/config/pipeline.yaml +} + +# TODO: Check if this is already done +#append_storage + +# We can build on docker only +sed -i 's/name: k8s-all/name: docker/g' kernelci/kernelci-pipeline/config/pipeline.yaml + +sed -i 's/env_file: .env/env_file: .env\/.env/g' kernelci/kernelci-pipeline/config/pipeline.yaml + +#- - 'data/ssh/:/home/kernelci/data/ssh' +#- - 'data/output/:/home/kernelci/data/output' +#+ - '/root/kernelci-pipeline/data/ssh/:/home/kernelci/data/ssh' +#+ - '/root/kernelci-pipeline/data/output/:/home/kernelci/data/output' +cd kernelci/kernelci-pipeline +PIPELINE_PWD=$(pwd) +# replace lab_type: kubernetes to lab_type: docker +# This is BAD hack, but it works for now +sed -i 's/lab_type: kubernetes/lab_type: docker/g' config/pipeline.yaml + +# replace data/output by $PIPELINE_PWD/data/output +# might be two variants (default and staging) +# - '/data/kernelci-deploy-checkout/kernelci-pipeline/data/ssh/:/home/kernelci/data/ssh' +# - '/data/kernelci-deploy-checkout/kernelci-pipeline/data/output/:/home/kernelci/data/output' +# AND +# - 'data/ssh/:/home/kernelci/data/ssh' +# - 'data/output/:/home/kernelci/data/output' +sed -i "s|- 'data/output/|- '$PIPELINE_PWD/data/output/|g" config/pipeline.yaml +sed -i "s|- 'data/ssh/|- '$PIPELINE_PWD/data/ssh/|g" config/pipeline.yaml +# OR +sed -i "s|- '/data/kernelci-deploy-checkout/kernelci-pipeline/data/ssh/|- '$PIPELINE_PWD/data/ssh/|g" config/pipeline.yaml +sed -i "s|- '/data/kernelci-deploy-checkout/kernelci-pipeline/data/output/|- '$PIPELINE_PWD/data/output/|g" config/pipeline.yaml + +chmod 777 data/ssh +cp ../../config/out/ssh.key data/ssh/id_rsa_tarball +chmod 600 data/ssh/id_rsa_tarball +chown -R $(id -u):$(id -g) data/output +cd ../.. + +#replace kernelci/staging- by local/staging- +#TODO: Make PR to pipeline with ENV var for image prefix +sed -i 's/kernelci\/staging-/local\/staging-/g' kernelci/kernelci-pipeline/docker-compose.yaml + +# same for yaml files in config +sed -i 's/kernelci\/staging-/local\/staging-/g' kernelci/kernelci-pipeline/config/pipeline.yaml + +# check if kernelci/kernelci-pipeline/config/kernelci.toml +# has [trigger] and then force = 1 +# this will force builds on each restart +if ! grep -q "force = 1" kernelci/kernelci-pipeline/config/kernelci.toml; then + sed -i '/\[trigger\]/a force = 1' kernelci/kernelci-pipeline/config/kernelci.toml +fi + +# remove from pipeline yaml all build_configs: +sed -i '/build_configs:/,$d' kernelci/kernelci-pipeline/config/pipeline.yaml +# add +cat <> kernelci/kernelci-pipeline/config/pipeline.yaml +build_configs: + kernelci_staging-stable: + tree: kernelci + branch: 'staging-stable' +EOF + +#create .env +#KCI_STORAGE_CREDENTIALS=L0CALT0KEN +#KCI_API_TOKEN= +#API_TOKEN= +API_TOKEN=$(cat config/out/admin-token.txt) +echo "KCI_STORAGE_CREDENTIALS=/home/kernelci/data/ssh/id_rsa_tarball" > .env +echo "KCI_API_TOKEN=${API_TOKEN}" >> .env +echo "API_TOKEN=${API_TOKEN}" >> .env +cp .env kernelci/kernelci-pipeline/.docker-env +mv .env kernelci/kernelci-pipeline/.env + +# Add JWT section with the secret key to kernelci.toml for pipeline callback +sed -i 's/#\[jwt\]$/[jwt]/' kernelci/kernelci-pipeline/config/kernelci.toml +sed -i 's/#secret = "SomeSecretString"/secret = "'"${PIPELINE_SECRET_KEY}"'"/' kernelci/kernelci-pipeline/config/kernelci.toml +# Generate kci-dev token +pip install pyjwt +TOKEN=$(kernelci/kernelci-pipeline/tools/jwt_generator.py --toml kernelci/kernelci-pipeline/config/kernelci.toml \ +--email ${YOUR_EMAIL} --permissions checkout,testretry,patchset | grep "JWT token:" | cut -d' ' -f3) +echo $TOKEN > config/out/kci-dev-token.txt +echo "kci-dev token saved to config/out/kci-dev-token.txt" diff --git a/localinstall/scripts/4-start_cycle.sh b/localinstall/scripts/6-start_pipeline.sh similarity index 100% rename from localinstall/scripts/4-start_cycle.sh rename to localinstall/scripts/6-start_pipeline.sh diff --git a/localinstall/scripts/run.sh b/localinstall/scripts/run.sh index 61299ee..bd43832 100755 --- a/localinstall/scripts/run.sh +++ b/localinstall/scripts/run.sh @@ -5,27 +5,46 @@ set -e ACTION=$1 function print_help() { - echo "Usage: $0 (run|stop)" + echo "Usage: $0 (deploy|start|stop)" echo - echo " run Execute deployment sequence" - echo " stop Stop and remove deployment" + echo " deploy Configure and start deployment" + echo " start Start deployment" + echo " stop Stop deployment" exit 1 } +function check_deploy() { + if [ ! -f kernelci/.done ]; then + echo "Error: Deployment not completed. Please run 'deploy' first." + exit 1 + fi +} + if [[ -z "$ACTION" ]]; then - echo "Error: Missing required action (run or stop)" + echo "Error: Missing required action (deploy, start or stop)" print_help fi case "$ACTION" in - run) + deploy) + rm -f kernelci/.done echo "Starting deployment sequence, this may take a while..." ./scripts/1-rebuild_all.sh - ./scripts/2-install_api.sh - ./scripts/3-install_pipeline.sh - ./scripts/4-start_cycle.sh + ./scripts/2-prepare_api.sh + ./scripts/3-start_api.sh + ./scripts/4-set_api_admin.sh + ./scripts/5-prepare_pipeline.sh + ./scripts/6-start_pipeline.sh + touch kernelci/.done + ;; + start) + check_deploy + echo "Starting deployment" + ./scripts/3-start_api.sh + ./scripts/6-start_pipeline.sh ;; stop) + check_deploy echo "Stopping deployment" cd kernelci/kernelci-api docker compose down