Koji POC

Run koji on kubernetes.

Builders (kojid) depends on kubevirt to run.

Requirements:

  • 15GB+ of memory
  • minikube (kubernetes 1.18+)
  • kubectl
  • virtctl

Guide

This guide is a simple walkthrough to deploy koji in kubernetes and run a simple package build.

Kubernetes

Start minikube:

minikube start

Ingress Controller

Enable ingress-nginx plugin:

minikube addons enable ingress

Wait for all pods to be ready in ingress-nginx namespace:

kubectl get po -w -n ingress-nginx

Edit the nginx controller deployment so it can support ssl passthrough in i ts requests:

kubectl edit deployment/ingress-nginx-controller -n ingress-nginx
...
spec:
  containers:
    - args:
        - /nginx-ingress-controller
        - --ingress-class=nginx
        - --configmap=$(POD_NAMESPACE)/ingress-nginx-controller
        - --report-node-internal-ip-address
        - --tcp-services-configmap=$(POD_NAMESPACE)/tcp-services
        - --udp-services-configmap=$(POD_NAMESPACE)/udp-services
        - --validating-webhook=:8443
        - --validating-webhook-certificate=/usr/local/certificates/cert
        - --validating-webhook-key=/usr/local/certificates/key
        - --enable-ssl-passthrough # add this line
...

Run kubectl get po -w -n ingress-nginx and wait for all pods to be ready again.

Kubevirt

Install kubevirt by running:

minikube addons enable kubevirt

Check kubevirt readiness by running:

kubectl get kubevirt.kubevirt.io/kubevirt -w -n kubevirt -o=jsonpath="{.status.phase}"

You also need virtctl to run command in the VM, follow the steps from the upstream kubevirt docs to do so: https://kubevirt.io/quickstart_minikube/

It will show a "Deployed" status once it is ready.

Koji

Create a koji namespace:

kubectl create ns koji

Set koji as your default namespace:

kubectl config set-context --current --namespace=koji

Database

Deploy a postgre instance:

cd deploy
kubectl apply -f postgres/

Koji-Hub

Generate self-signed certs and create them as kubernetes secrets:

cd deploy/certs/ca
./gen
./appy
cd deploy/certs/httpd
./gen
./appy
cd deploy/certs/clients/kojiadmin
./gen
./appy
cd deploy/certs/clients/koji-web
./gen
./appy

Deploy koji-hub:

kubectl apply -f koji-hub/

Wait for the koji pod readiness:

kubectl get po -w

Get the service IP:

minikube service koji-hub -n koji --url

Create an entry in /etc/hosts to direct koji-hub.local to that IP:

echo '$SVC_IP koji-hub.local' >> /etc/hosts

Allow the web interface to access the koji-hub service by its name:

minikube ssh
sudo ip link set docker0 promisc on

Import the koji schema into postgre:

kubectl exec -it $(kubectl get po --selector='app=koji' -o jsonpath='{.items[0].metadata.name}') -- /bin/bash

psql --username koji --password --host postgres koji < /usr/share/doc/koji*/docs/schema.sql

Whilte still in the pod, connect to postgre and add kojiadmin as an admin user:

psql --username koji --password --host postgres
INSERT INTO users(name, status, usertype) VALUES('kojiadmin', 0, 0) ON CONFLICT DO NOTHING;
INSERT INTO user_perms (user_id, perm_id, creator_id) VALUES (1, 1, 1) ON CONFLICT DO NOTHING;

You can now exit psql and the pod itself.

Try accessing https://koji-hub.local/koji/ in your browser - it should show the koji-web interface.

Run the following bash script to create kojira and some builders in the koji database:

cd koji/ops
./users

Kojira

Create the client certificate and key:

cd deploy/certs/clients/kojira
./gen
./appy

Create a kojira user with repo permissions (if you didn't run ops/koji/users.sh):

cd ops/koji
./sync # downloads kojiadmin ca, cert and key
koji -c config.ini add-user kojira
koji -c config.ini grant-permission repo kojira

Deploy kojira

cd deploy/
kubectl apply -f kojira/

Check the status of the kojira pod:

kubectl get po/$(kubectl get po --selector='app=kojira' -o jsonpath='{.items[0].metadata.name}') -w

Koji-Builder (repo)

Create the client certificate and key:

cd deploy/certs/clients/koji-builder
./gen
./apply

Create the koji-builder as koji host and subscribe it to the createrepo channel (if you didn't run ops/koji/users.sh):

cd ops/koji
./sync # downloads kojiadmin ca, cert and key
koji -c config.ini add-host repo.k8s.io noarch
koji -c config.ini add-host-to-channel repo.k8s.io createrepo

Deploy the builder:

kubectl apply -f koji-builder-repo/

Check the status of the deployment:

kubectl get po/$(kubectl get po --selector='app=koji-builder-repo' -o jsonpath='{.items[0].metadata.name}') -w

Setup an external repository with a few tags by running the repos script:

cd ops/koji
./sync.sh
./repo.sh

Check the web interface, a new newRepo task should pop up.

This builder will be responsible for generating koji repositories.

Koji-Builder (package builder)

This builder will run in a VM managed by kubernetes, this is where kubevirt comes into play.

Notes:

  • /var/lib/mock need some extra space since this is where builds are executed
  • it needs at least 5GB of available memory
  • extra configuration is done by accesing the VM which should be done either via SSH or already built in a custom image

Create the client cert and key:

cd deploy/certs/clients/koji-builder-vm
./gen
./apply

Create the koji-builder as koji host and subscribe it to the default channel (if you didn't run ops/koji/users.sh):

cd ops/koji
./sync # downloads kojiadmin ca, cert and key
koji -c config.ini add-host x86-64.virt.k8s.io x86_64
koji -c config.ini add-host-to-channel x86-64.virt.k8s.io default

Deploy the VM:

kubectl apply -f koji-builder-vm/

"Console into" the VM using virtctl, it may take a while for some output show up:

virtctl x86-64.virt.k8s.io

You can login as root/koji.

Execute the setup script in /tmp/setup.sh.

This script will setup the environment so kojid can run.

Run kojid:

/usr/sbin/kojid --fg --force-lock --verbose

Building

Add the time package to the dist-kube tag:

koji -c config.ini add-pkg --owner=kojiadmin dist-kube time

Trigger a build by running:

koji -c config.ini build dist-kube rpms/time/time-1.9-11.fc32.src.rpm

It should take a while since it is using an external repository (depending on your internet speed).

You can check the build status in the web UI.

License

MIT