Components needed for a smooth experience*:
Kevin: Main daemonJustin: Container provider daemonChantal: In-container agent to run the jobMandy: Webinterface
* Disclaimer: The experience may not actually be smooth and likely more components are needed.
- Install
kevinon a server - Create/edit
kevin.conf,justin.confand add a config for all your projects to be built - Set up a VM or container with active SSH and add it to
justin.conf - Add
kevin-cias github webhook - Run
kevinandjustin(e.g. assystemdservice) - Add the
kevinfilecontrol file to your project repo - Pull requests are built inside a temporary container copy
- Set up a webserver to serve the
mandywebinterface and your build output folder
-
kevininteracts with the outside world (your git hoster). It gets notified by pull requests. You need a server for it. -
kevincontactsjustinto start a VM. You need a server forjustinagain, but it can be the same machine wherekevinis running on. There can be multiplejustins. -
justinlaunches a container/virtual machine provided by you. You create the machine template (just set up a debian...) or use docker, etc. Your pull request is then built inside that container bychantal. -
After the job was run, the machine is reverted back to the template.
-
mandypresents the build progress in your browser in real-time.
You are responsible for managing and updating the container 😄.
Which is one of the main reasons we created kevin.
kevin is designed in a way that arbitrary code can be executed in the
container and will not harm your host system, apart from the usual virtual
machine/container exit exploits that we can't prevent.
Our code is of course 100% bugfree, we even have created a program to verify that kevin can never hang up. Hrr hrr...
Kevin supports hosting multiple projects. Each project can spawn as many "jobs" as you like to have.
- Build: Equal to a commit hash. Spawns jobs which must succeed.
- Job: Performed by chantal inside a container.
- Step: One step in a job, as defined in the in-repo
kevinfilecontrol file. - Command: Each step runs one or more commands.
We support different container backends.
Have a look inside justin/machine/ to see which ones and to add more container types.
Kevin gets a notification that it should build something, and kevin then notifies justin to provide a container.
- Install
python >=3.11aiohttp >=2.0
- Create user
kevin(you can, of course, change that)- Create
/etc/kevin/kevin.conffromkevin.conf.example - Create a password-less SSH key with
ssh-keygen -t rsa -b 4096for the userkevin
- Create
- Install the
kevinPython module (ideally, as a systemd unit or whatever)
Justin starts and cleans up containers when Kevin requests them.
-
Install
python >=3.6- your container implementation of choice:
qemu,libpod,docker, ...
-
Create
/etc/kevin/justin.conffromjustin.conf.example -
Register this
justinby adding it to thekevin.conf[justin]section.-
If this
justinis on the same machine askevin:- add
justin_name=userid@/run/kevin/justinandkevinwill use this Unix socket to contactjustin
- add
-
If this
justinis a different physical machine than the host forkevin:- Create user
justinon thejustinhost - In
kevin.conf, section[justin], addjustin_name=justin@vmserver.name,kevinwill then contact justin via SSH - In
~justin/.ssh/authorized_keys, force the ssh command tocommand="python3 -m justin.shell useridentifier" ssh-rsa kevinkeyblabla...This sets up password-less SSH access (ssh-copy-id..) forkevintojustin@vmserver.nameand forces the justin shell.
- Create user
-
-
optional: create firewall rules to prevent the VMs launched by
justinfrom talking to internals of your network
Setting up the guest system depends on the container technology you use.
- Qemu
- Podman
- LXD
- Your favorite-to-be-implemented backend
The project config determines active Kevin plugins and their configuration.
-
On the
kevinmachine, create a folder where project configurations reside in/etc/kevin/projects/may be a good location- In there, create
lolmyproject.conffrom theetc/project.conf.examplefile - For each project, create a file with a suitable name in
/etc/kevin/projects/
-
For the project you want to test, create kevin control file
kevinfilein the project repo root (e.g.~/dev/openage/kevinfile)- You can change the name to anything you want, even
kartoffelsalat - If you change it, set the name in the
lolmyproject.conf
- You can change the name to anything you want, even
-
- Settings > Webhooks and Services > Add Webhook
- content type: JSON, URL:
http://your-kevin-host:webhook_port/hook-github - Create a secret with e.g.
pwgen 1 30and save it in the github webhook and yourprojects/yourproject.confsection[github_webhook] - Select events: Pull Request and Push
- Just serve the
mandyfolder on any machine in the world. - Use
nginxorlighttpdorapache, it does not matter. - Enter the location where
mandycan be reached inkevin.conf - To allow output file downloads, you have to serve your static folder with another (or the same) webserver.
- You can directly run Chantal without all the other fuzz and see how it will build stuff.
- Kevin would do the same thing in the container/VM.
- To test, invoke
python3 -m chantal --helpand be enlightnened.-
You can run Chantal inside your project without cloning it:
-
python3 -m chantal --dir /your/project/repo $jobname -
$jobnameis used for evaluating conditions in thekevinfile. Later, thejobnamepassed to Chantal will be taken from the job name you set up for a project in the its config filelolmyproject.conf. -
The same test can be done within your VM/container:
-
python3 -m chantal --dir /tmp/clonedest --clone $clone_url --checkout $branchname_or_hashname $jobname
-
-
Persistent storage for
kevinis done in[projects]/output_folder.- All build data will be stored there.
- There's no cleanup mechanism yet (you may implemente it :)
-
systemd setup
- copy and adjust
etc/kevin.serviceto/etc/systemd/system/kevin.service - copy and adjust
etc/justin.serviceto/etc/systemd/system/justin.service - copy and adjust
etc/tmpfiles.d/kevin.confto/etc/tmpfiles.d/kevin.conf - enable the service with
systemctl enable $name.service - start them with
systemctl start $name.service
- copy and adjust
-
Non-daemon launch
- Run
kevinwithpython3 -m kevin - Run
justinwithpython3 -m justin
- Run
-
After setup, manage a container with
python3 -m justin.manage- For example:
python3 -m justin.manage unix:///run/kevin/justin your_vm_id
- For example:
-
We recommend to first test with a dummy repository that just contains a simple
kevinfile, instead of the "real" project. -
Test without
github: Try using the Kevin Simulator -
Test with
github: Just make a pull request!
If you encounter any problem, please contact us and ask!
If things crash, bug, or whatever, create an issue!
If you think this guide or anything else in this project is crap and sucks, just do better!