RFC: Add first working version of OpenBSD Chroot Builds

Closed username-removed-20462 requested to merge srinkes/gitlab-ci-multi-runner:chroot into master

This Diffs adds a new runner, called chroot after chroot(8) of OpenBSD.

The chroot command changes its root directory to the supplied directory newroot and executes command, if supplied, or an interactive copy of the user's shell.

Since there is no bash(1) by default on OpenBSD, this also adds a ksh(1) interface. We want the image to be as small as possible and with no software from ports required.

This MR is just a RFC, if you are interested in such a feature and some feedback on my go style ;)

How your build is running in chroot:

  • The runner will setup a chroot Environment given by the "image". The image is copied for each run and removed afterwards.
  • The image gets mounted via vnd(4) (usually an OpenBSD system has 4 vnd-nodes, but this number can be easily increased for build hosts)
  • BuildStagePrepare, BuildStageUserScript, BuildStageAfterScript are started via chroot in the setup Environment This ensures User given commands can't run directly on the Build Host.
  • In the end the chroot Environment is cleared and everything gets removed

Why I think it makes sense to have such a runner:

  • runner usually have to run as root, since builds want to install packages and so on. But as a responsible admin you don't want to run user given commands as root.
  • there is no docker or VirtualBox on OpenBSD
  • vmm(4) is not ready to use yet. (would be much more awesome to also boot own kernels)
  • you can compile and test (as long you don't do kernel stuff) your code for multiple OpenBSD-Versions on one machine. See the example below (3. gitlab-ci.yml), where the build runs in OpenBSD 6.0 and 6.1-beta userland.

ToDos:

  • CleanUp Code
  • Add Tests
  • Script for generating images from ISOs/CDs
  • Add Code to download missing images from an http(s) server

Now some Infos from the real world:

  • Create Image from OpenBSD ISOs/CDs

This is just a basic example. I'm working on a tool to generate images with ease and small as possible (no manpages, samples, docs, ... etc.).

$ vmctl create openbsd61-amd64.img -s 512M
$ vnconfig vnd0 openbsd61-amd64.img
$ disklabel -E vnd0
Label editor (enter '?' for help at any prompt)
> a a
offset: [0]
size: [1048576]
FS type: [4.2BSD]
> w
> q
No label changes.
$ newfs /dev/rvnd0a
$ mount /dev/vnd0a /mnt/chroots/
$ tar -C /mnt/chroots/ -xzf /cdrom/6.1/amd64/base61.tgz
$ tar -C /mnt/chroots/ -xzf /cdrom/6.1/amd64/comp61.tgz
$ umount /mnt/chroots/
$ vnconfig -u vnd0
$ cp openbsd61-amd64.img /var/spool/images/
$ ln -s /var/spool/images/openbsd61-amd64.img /var/spool/images/default-image.img
  • Configure gitlab chroot runner
[[runners]]
  name = "openbsd-amd64-chroot"
  url = "http://gitlab"
  token = ""
  executor = "chroot"
  [runners.chroot]
    image_dir = "/var/spool/images"
    image = "default-image"
    work_dir = "/mnt/gitlab-runner/"
  • Use it in .gitlab-ci.yml
variables:
  ARCH: amd64

.build_template: &build_template
  stage: build
  script:
    - uname -a
    - echo 'hello' > hello
    - dmesg | head -n 2
    - make
    - ./hello_world
  artifacts:
    paths:
    - hello
    expire_in: 1 min
  tags:
  - chroot

test_default_chroot:
  <<: *build_template

test_chroot:
  image: openbsd61-$ARCH
  <<: *build_template

test60_chroot:
  image: openbsd60-$ARCH
    <<: *build_template
  • Sample Output
Running with gitlab-ci-multi-runner 9.0.0~beta.23.g67b3a0a5 (67b3a0a5)
  on openbsd-amd64-chroot (41e6f590)
Preparing chroot env
Checking vnd:  0
Using Chroot executor with image /var/spool/images/default-image.img mounted on vnd0 ...
Copying Image /var/spool/images/default-image.img to /mnt/gitlab-runner//runner-41e6f590-project-1-concurrent-0-default-image.img
Running cmd: vnconfig [vnd0 /mnt/gitlab-runner//runner-41e6f590-project-1-concurrent-0-default-image.img]
Running cmd: mount [/dev/vnd0a /mnt/gitlab-runner//runner-41e6f590-project-1-concurrent-0]
Running on openbsd-amd64...
Cloning repository...
Cloning into '/mnt/gitlab-runner//runner-41e6f590-project-1-concurrent-0//builds/41e6f590/0/srinkes/runner-openbsd-test'...
Checking out a56abda0 as chroot...
Skipping Git submodules setup
$ pwd
/builds/41e6f590/0/srinkes/runner-openbsd-test
$ uname -a
OpenBSD openbsd-amd64 6.1 GENERIC.MP#0 amd64
$ echo hello > hello
$ dmesg | head -n 2
OpenBSD 6.1-beta (GENERIC.MP) #0: Thu Mar  9 11:02:54 CET 2017
    srinkes@openbsd-amd64-dev:/usr/src/sys/arch/amd64/compile/GENERIC.MP
$ make
cc -O2 -pipe    -c hello_world.c
cc   -o hello_world hello_world.o
$ ./hello_world
Hello World
$ ls -l
total 40
drwxr-xr-x  5 0  0   512 Mar 11 02:33 .git
-rw-r--r--  1 0  0   384 Mar 11 02:33 .gitlab-ci.yml
-rw-r--r--  1 0  0    75 Mar 11 02:33 Makefile
-rw-r--r--  1 0  0     6 Mar 11 02:33 hello
-rwxr-xr-x  1 0  0  7303 Mar 11 02:33 hello_world
-rw-r--r--  1 0  0    72 Mar 11 02:33 hello_world.c
-rw-r--r--  1 0  0  1328 Mar 11 02:33 hello_world.o
Uploading artifacts...
hello: found 1 matching files
Uploading artifacts to coordinator... ok            id=222 responseStatus=201 Created token=RcyyrJje
Job succeeded