Skip to content

Refactor kci-deploy for improved reliability, structure, and full Docker-in-Docker deployment #228

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 7 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions localinstall/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
kernelci
config/out/*
.sudo_as_admin_successful
.cache
.local
.docker
.bash_history
48 changes: 48 additions & 0 deletions localinstall/Containerfile
Original file line number Diff line number Diff line change
@@ -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"]
30 changes: 19 additions & 11 deletions localinstall/README.md
Original file line number Diff line number Diff line change
@@ -1,16 +1,24 @@
# kci-easy

# kci-deploy
Get your own KernelCI instance up and running in no time.

## Getting started

### Prerequisites
## Prerequisites
- Docker

- 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
## Configure
Configure and setup credentials in config files located in `config` folder.

### Running
## Run
You can deploy your KernelCI deployment by simply executing:
```bash
./kci-deploy.sh deploy
```

Change `ADMIN_PASSWORD` in the `main.cfg`, then run shell scripts from the root directory in their order.
You can stop your local deployment by executing:
```bash
./kci-deploy.sh stop
```
and
```bash
./kci-deploy.sh start
```
to start it again.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
9 changes: 0 additions & 9 deletions localinstall/kci-deploy.py

This file was deleted.

78 changes: 78 additions & 0 deletions localinstall/kci-deploy.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
#!/bin/bash

set -e

IMAGE_NAME="local/kernelci-deployer:latest"
BUILD_IMAGE=false
ACTION=""
CONTAINER_ARGS=()

function print_help() {
echo "Usage: $0 [--build] (deploy|start|stop) [args...]"
echo
echo "Options:"
echo " --build Force rebuild of the Deployer image (optional)"
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 'deploy', 'start' or 'stop' are passed to the container entrypoint"
exit 0
}

# Parse args
while [[ $# -gt 0 ]]; do
case "$1" in
--build)
BUILD_IMAGE=true
shift
;;
deploy|start|stop)
if [[ -n "$ACTION" ]]; then
echo "Error: Cannot use more than one command among 'deploy', 'start' or '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="start"
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[@]}"
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
#!/bin/bash
. ./main.cfg

. ./config/main.cfg

set -e

# i am groot?
if [ $(id -u) -ne 0 ]; then
Expand All @@ -8,13 +11,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
Expand Down Expand Up @@ -86,32 +82,14 @@ 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
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
./kci docker $args kernelci api
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
./kci docker $args kernelci pipeline
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


Original file line number Diff line number Diff line change
@@ -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
Expand All @@ -9,31 +8,36 @@ 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 .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
Expand Down Expand Up @@ -63,12 +67,12 @@ 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
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\"
Expand Down
34 changes: 34 additions & 0 deletions localinstall/scripts/2-prepare_api.sh
Original file line number Diff line number Diff line change
@@ -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
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
#!/bin/bash
. ./main.cfg

. ./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:
Expand Down Expand Up @@ -51,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 ../../ssh.key data/ssh/id_rsa_tarball
chown 1000:1000 data/ssh/id_rsa_tarball
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-
Expand All @@ -69,8 +70,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

Expand All @@ -88,7 +88,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
Expand Down
Loading