From 3dde60673d9c2bbcac44734e6fbd67f633787046 Mon Sep 17 00:00:00 2001 From: Simone Tollardo Date: Fri, 11 Apr 2025 14:39:15 +0200 Subject: [PATCH 1/9] 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 7ad89826..30a06565 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 cb641c54..06252ea6 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 f54a2e54..9a8b627f 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 caca6d46..72352d57 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 0e3f62d1..0de6506e 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 02dcb5016d72a7b878fc2251b4e7c5e278f78094 Mon Sep 17 00:00:00 2001 From: Simone Tollardo Date: Fri, 11 Apr 2025 14:40:50 +0200 Subject: [PATCH 2/9] explicit 'expect' call in local deployment Signed-off-by: Simone Tollardo --- localinstall/2-install_api.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/localinstall/2-install_api.sh b/localinstall/2-install_api.sh index 06252ea6..3f3933c4 100755 --- a/localinstall/2-install_api.sh +++ b/localinstall/2-install_api.sh @@ -71,7 +71,7 @@ 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" From 8d76e622d89ec3454d5c119837c672b8f3b1608d Mon Sep 17 00:00:00 2001 From: Simone Tollardo Date: Fri, 11 Apr 2025 14:42:36 +0200 Subject: [PATCH 3/9] 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 30a06565..c679ed4a 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 1c855f4a17f2923faf00735ebaba1eac5b12db8e Mon Sep 17 00:00:00 2001 From: Simone Tollardo Date: Fri, 11 Apr 2025 15:08:03 +0200 Subject: [PATCH 4/9] 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 c679ed4a..41c17421 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 68a9a8a5f1868ab520707d255afbbbb5690fca1a Mon Sep 17 00:00:00 2001 From: Simone Tollardo Date: Fri, 11 Apr 2025 19:32:06 +0200 Subject: [PATCH 5/9] 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 | 22 +++--- .../{ => scripts}/3-install_pipeline.sh | 11 +-- .../4-start_cycle.sh} | 7 +- localinstall/scripts/run.sh | 39 ++++++++++ 14 files changed, 200 insertions(+), 66 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 (80%) 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 00000000..56112eac --- /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 00000000..2fb255c9 --- /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 57cc8876..2437ba54 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 0de6506e..00000000 --- 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 00000000..264c6bfa --- /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 41c17421..9978e96d 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 80% rename from localinstall/2-install_api.sh rename to localinstall/scripts/2-install_api.sh index 3f3933c4..c1bcc36c 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 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 9a8b627f..75d4fb31 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 72352d57..ad527016 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 00000000..61299ee9 --- /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 012d28654e27309d96cc6cac1c4d7a022cb62df0 Mon Sep 17 00:00:00 2001 From: Simone Tollardo Date: Wed, 16 Apr 2025 16:59:23 +0200 Subject: [PATCH 6/9] 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 75d4fb31..e63d9791 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 d57785b85c6e7db785153760f5cca2c9f259fd7c Mon Sep 17 00:00:00 2001 From: Simone Tollardo Date: Wed, 16 Apr 2025 17:43:28 +0200 Subject: [PATCH 7/9] separate deploy and start command Signed-off-by: Simone Tollardo --- localinstall/README.md | 13 ++- localinstall/kci-deploy.sh | 15 ++-- localinstall/scripts/2-install_api.sh | 80 ------------------- localinstall/scripts/2-prepare_api.sh | 34 ++++++++ localinstall/scripts/3-start_api.sh | 35 ++++++++ localinstall/scripts/4-set_api_admin.sh | 33 ++++++++ ...tall_pipeline.sh => 5-prepare_pipeline.sh} | 13 ++- .../{4-start_cycle.sh => 6-start_pipeline.sh} | 0 localinstall/scripts/run.sh | 40 ++++++++-- 9 files changed, 161 insertions(+), 102 deletions(-) delete mode 100755 localinstall/scripts/2-install_api.sh 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 rename localinstall/scripts/{3-install_pipeline.sh => 5-prepare_pipeline.sh} (85%) rename localinstall/scripts/{4-start_cycle.sh => 6-start_pipeline.sh} (100%) diff --git a/localinstall/README.md b/localinstall/README.md index 2437ba54..f99864d8 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 264c6bfa..aeb740dd 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-install_api.sh b/localinstall/scripts/2-install_api.sh deleted file mode 100755 index c1bcc36c..00000000 --- a/localinstall/scripts/2-install_api.sh +++ /dev/null @@ -1,80 +0,0 @@ -#!/bin/bash - -# is docker-compose exists? if not use docker compose -if [ -z "$(which docker-compose)" ]; then - echo "docker-compose is not installed, using docker compose" - DOCKER_COMPOSE="docker compose" -else - DOCKER_COMPOSE="docker-compose" -fi - -. ./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 - -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 - -# 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 - -# 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" -../../helpers/kci_user_token_admin.exp "${ADMIN_PASSWORD}" > ../../admin-token.txt -ADMIN_TOKEN=$(cat ../../admin-token.txt | tr -d '\r\n') - -echo "[kci.secrets] -api.\"docker-host\".token = \"$ADMIN_TOKEN\" -" >> kernelci.toml - diff --git a/localinstall/scripts/2-prepare_api.sh b/localinstall/scripts/2-prepare_api.sh new file mode 100755 index 00000000..ee9b57af --- /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 00000000..34b07944 --- /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 00000000..db86d119 --- /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/3-install_pipeline.sh b/localinstall/scripts/5-prepare_pipeline.sh similarity index 85% rename from localinstall/scripts/3-install_pipeline.sh rename to localinstall/scripts/5-prepare_pipeline.sh index e63d9791..053a89c8 100755 --- a/localinstall/scripts/3-install_pipeline.sh +++ b/localinstall/scripts/5-prepare_pipeline.sh @@ -20,9 +20,6 @@ tail -n +$((line+1)) kernelci/kernelci-pipeline/config/pipeline.yaml >> tmp.yaml mv tmp.yaml kernelci/kernelci-pipeline/config/pipeline.yaml } -# replace in pipeline.yaml http://172.17.0.1:8001 to http://localhost:8001 -sed -i 's/http:\/\/172.17.0.1:8001/http:\/\/host.docker.internal:8001/g' kernelci/kernelci-pipeline/config/pipeline.yaml - # TODO: Check if this is already done #append_storage @@ -94,3 +91,13 @@ 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 61299ee9..7b1cffc0 100755 --- a/localinstall/scripts/run.sh +++ b/localinstall/scripts/run.sh @@ -5,27 +5,51 @@ 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) + # Check if kernelci directory exists + if [ -f kernelci/.done ]; then + echo "Stopping previous deployment..." + $0 stop + fi + sudo rm -rf kernelci 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 From 3cb4e1b43d2ac06da3501d13ead41b743b6a4d00 Mon Sep 17 00:00:00 2001 From: Simone Tollardo Date: Fri, 23 May 2025 16:14:54 +0200 Subject: [PATCH 8/9] increase api up check timeout Signed-off-by: Simone Tollardo --- localinstall/scripts/3-start_api.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/localinstall/scripts/3-start_api.sh b/localinstall/scripts/3-start_api.sh index 34b07944..2762e66c 100755 --- a/localinstall/scripts/3-start_api.sh +++ b/localinstall/scripts/3-start_api.sh @@ -17,7 +17,7 @@ cd kernelci/kernelci-api docker compose down docker compose up -d echo "Waiting for API to be up" -sleep 1 +sleep 5 # loop until the API is up, try 5 times i=0 while [ $i -lt 5 ]; do From beab2936f2843ba79241111b0c18f2f6195ff9f7 Mon Sep 17 00:00:00 2001 From: Simone Tollardo Date: Sun, 25 May 2025 15:13:35 +0200 Subject: [PATCH 9/9] More robust replace for docker runtime named volumes abs path Signed-off-by: Simone Tollardo --- localinstall/scripts/5-prepare_pipeline.sh | 17 +++++------------ 1 file changed, 5 insertions(+), 12 deletions(-) diff --git a/localinstall/scripts/5-prepare_pipeline.sh b/localinstall/scripts/5-prepare_pipeline.sh index 053a89c8..d7b3974d 100755 --- a/localinstall/scripts/5-prepare_pipeline.sh +++ b/localinstall/scripts/5-prepare_pipeline.sh @@ -38,18 +38,11 @@ PIPELINE_PWD=$(pwd) # 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 +# replace named data/output and data/ssh volumes with absolute path since it is needed +sed -i '/volumes:/,/data\/output/{ + s|['\''"].*data\/ssh\/|'\'''"$PIPELINE_PWD"'\/data\/ssh\/|g; + s|['\''"].*data\/output\/|'\'''"$PIPELINE_PWD"'\/data\/output\/|g; +}' config/pipeline.yaml chmod 777 data/ssh cp ../../config/out/ssh.key data/ssh/id_rsa_tarball