17ec681f3SmrgBare-metal CI
27ec681f3Smrg=============
37ec681f3Smrg
47ec681f3SmrgThe bare-metal scripts run on a system with gitlab-runner and Docker,
57ec681f3Smrgconnected to potentially multiple bare-metal boards that run tests of
67ec681f3SmrgMesa.  Currently only "fastboot" and "ChromeOS Servo" devices are
77ec681f3Smrgsupported.
87ec681f3Smrg
97ec681f3SmrgIn comparison with LAVA, this doesn't involve maintaining a separate
107ec681f3Smrgweb service with its own job scheduler and replicating jobs between the
117ec681f3Smrgtwo.  It also places more of the board support in Git, instead of
127ec681f3Smrgweb service configuration.  On the other hand, the serial interactions
137ec681f3Smrgand bootloader support are more primitive.
147ec681f3Smrg
157ec681f3SmrgRequirements (fastboot)
167ec681f3Smrg-----------------------
177ec681f3Smrg
187ec681f3SmrgThis testing requires power control of the DUTs by the gitlab-runner
197ec681f3Smrgmachine, since this is what we use to reset the system and get back to
207ec681f3Smrga pristine state at the start of testing.
217ec681f3Smrg
227ec681f3SmrgWe require access to the console output from the gitlab-runner system,
237ec681f3Smrgsince that is how we get the final results back from the tests.  You
247ec681f3Smrgshould probably have the console on a serial connection, so that you
257ec681f3Smrgcan see bootloader progress.
267ec681f3Smrg
277ec681f3SmrgThe boards need to be able to have a kernel/initramfs supplied by the
287ec681f3Smrggitlab-runner system, since the initramfs is what contains the Mesa
297ec681f3Smrgtesting payload.
307ec681f3Smrg
317ec681f3SmrgThe boards should have networking, so that we can extract the dEQP .xml
327ec681f3Smrgresults to artifacts on GitLab.
337ec681f3Smrg
347ec681f3SmrgRequirements (servo)
357ec681f3Smrg--------------------
367ec681f3Smrg
377ec681f3SmrgFor servo-connected boards, we can use the EC connection for power
387ec681f3Smrgcontrol to reboot the board.  However, loading a kernel is not as easy
397ec681f3Smrgas fastboot, so we assume your bootloader can do TFTP, and that your
407ec681f3Smrggitlab-runner mounts the runner's tftp directory specific to the board
417ec681f3Smrgat /tftp in the container.
427ec681f3Smrg
437ec681f3SmrgSince we're going the TFTP route, we also use NFS root.  This avoids
447ec681f3Smrgpacking the rootfs and sending it to the board as a ramdisk, which
457ec681f3Smrgmeans we can support larger rootfses (for piglit testing), at the cost
467ec681f3Smrgof needing more storage on the runner.
477ec681f3Smrg
487ec681f3SmrgTelling the board about where its TFTP and NFS should come from is
497ec681f3Smrgdone using dnsmasq on the runner host.  For example, this snippet in
507ec681f3Smrgthe dnsmasq.conf.d in the google farm, with the gitlab-runner host we
517ec681f3Smrgcall "servo"::
527ec681f3Smrg
537ec681f3Smrg  dhcp-host=1c:69:7a:0d:a3:d3,10.42.0.10,set:servo
547ec681f3Smrg
557ec681f3Smrg  # Fixed dhcp addresses for my sanity, and setting a tag for
567ec681f3Smrg  # specializing other DHCP options
577ec681f3Smrg  dhcp-host=a0:ce:c8:c8:d9:5d,10.42.0.11,set:cheza1
587ec681f3Smrg  dhcp-host=a0:ce:c8:c8:d8:81,10.42.0.12,set:cheza2
597ec681f3Smrg
607ec681f3Smrg  # Specify the next server, watch out for the double ',,'.  The
617ec681f3Smrg  # filename didn't seem to get picked up by the bootloader, so we use
627ec681f3Smrg  # tftp-unique-root and mount directories like
637ec681f3Smrg  # /srv/tftp/10.42.0.11/jwerner/cheza as /tftp in the job containers.
647ec681f3Smrg  tftp-unique-root
657ec681f3Smrg  dhcp-boot=tag:cheza1,cheza1/vmlinuz,,10.42.0.10
667ec681f3Smrg  dhcp-boot=tag:cheza2,cheza2/vmlinuz,,10.42.0.10
677ec681f3Smrg
687ec681f3Smrg  dhcp-option=tag:cheza1,option:root-path,/srv/nfs/cheza1
697ec681f3Smrg  dhcp-option=tag:cheza2,option:root-path,/srv/nfs/cheza2
707ec681f3Smrg
717ec681f3SmrgSetup
727ec681f3Smrg-----
737ec681f3Smrg
747ec681f3SmrgEach board will be registered in freedesktop.org GitLab.  You'll want
757ec681f3Smrgsomething like this to register a fastboot board:
767ec681f3Smrg
777ec681f3Smrg.. code-block:: console
787ec681f3Smrg
797ec681f3Smrg  sudo gitlab-runner register \
807ec681f3Smrg       --url https://gitlab.freedesktop.org \
817ec681f3Smrg       --registration-token $1 \
827ec681f3Smrg       --name MY_BOARD_NAME \
837ec681f3Smrg       --tag-list MY_BOARD_TAG \
847ec681f3Smrg       --executor docker \
857ec681f3Smrg       --docker-image "alpine:latest" \
867ec681f3Smrg       --docker-volumes "/dev:/dev" \
877ec681f3Smrg       --docker-network-mode "host" \
887ec681f3Smrg       --docker-privileged \
897ec681f3Smrg       --non-interactive
907ec681f3Smrg
917ec681f3SmrgFor a servo board, you'll need to also volume mount the board's NFS
927ec681f3Smrgroot dir at /nfs and TFTP kernel directory at /tftp.
937ec681f3Smrg
947ec681f3SmrgThe registration token has to come from a freedesktop.org GitLab admin
957ec681f3Smrggoing to https://gitlab.freedesktop.org/admin/runners
967ec681f3Smrg
977ec681f3SmrgThe name scheme for Google's lab is google-freedreno-boardname-n, and
987ec681f3Smrgour tag is something like google-freedreno-db410c.  The tag is what
997ec681f3Smrgidentifies a board type so that board-specific jobs can be dispatched
1007ec681f3Smrginto that pool.
1017ec681f3Smrg
1027ec681f3SmrgWe need privileged mode and the /dev bind mount in order to get at the
1037ec681f3Smrgserial console and fastboot USB devices (--device arguments don't
1047ec681f3Smrgapply to devices that show up after container start, which is the case
1057ec681f3Smrgwith fastboot, and the servo serial devices are actually links to
1067ec681f3Smrg/dev/pts).  We use host network mode so that we can spin up a nginx
1077ec681f3Smrgserver to collect XML results for fastboot.
1087ec681f3Smrg
1097ec681f3SmrgOnce you've added your boards, you're going to need to add a little
1107ec681f3Smrgmore customization in ``/etc/gitlab-runner/config.toml``.  First, add
1117ec681f3Smrg``concurrent = <number of boards>`` at the top ("we should have up to
1127ec681f3Smrgthis many jobs running managed by this gitlab-runner").  Then for each
1137ec681f3Smrgboard's runner, set ``limit = 1`` ("only 1 job served by this board at a
1147ec681f3Smrgtime").  Finally, add the board-specific environment variables
1157ec681f3Smrgrequired by your bare-metal script, something like::
1167ec681f3Smrg
1177ec681f3Smrg  [[runners]]
1187ec681f3Smrg    name = "google-freedreno-db410c-1"
1197ec681f3Smrg    environment = ["BM_SERIAL=/dev/ttyDB410c8", "BM_POWERUP=google-power-up.sh 8", "BM_FASTBOOT_SERIAL=15e9e390", "FDO_CI_CONCURRENT=4"]
1207ec681f3Smrg
1217ec681f3SmrgThe ``FDO_CI_CONCURRENT`` variable should be set to the number of CPU threads on
1227ec681f3Smrgthe board, which is used for auto-tuning of job parallelism.
1237ec681f3Smrg
1247ec681f3SmrgOnce you've updated your runners' configs, restart with ``sudo service
1257ec681f3Smrggitlab-runner restart``
1267ec681f3Smrg
1277ec681f3SmrgCaching downloads
1287ec681f3Smrg-----------------
1297ec681f3Smrg
1307ec681f3SmrgTo improve the runtime for downloading traces during traces job runs, you will
1317ec681f3Smrgwant a pass-through HTTP cache.  On your runner box, install nginx:
1327ec681f3Smrg
1337ec681f3Smrg.. code-block:: console
1347ec681f3Smrg
1357ec681f3Smrg  sudo apt install nginx libnginx-mod-http-lua
1367ec681f3Smrg
1377ec681f3SmrgAdd the server setup files:
1387ec681f3Smrg
1397ec681f3Smrg.. literalinclude: fdo-cache:
1407ec681f3Smrg   :name: /etc/nginx/sites-available/fdo-cache
1417ec681f3Smrg
1427ec681f3Smrg.. literalinclude: uri-caching.conf:
1437ec681f3Smrg   :name: /etc/nginx/sites-available/snippets/uri-caching.conf
1447ec681f3Smrg
1457ec681f3SmrgEdit the listener addresses in fdo-cache to suit the ethernet interface that
1467ec681f3Smrgyour devices are on.
1477ec681f3Smrg
1487ec681f3SmrgEnable the site and restart nginx:
1497ec681f3Smrg
1507ec681f3Smrg.. code-block:: console
1517ec681f3Smrg
1527ec681f3Smrg  sudo ln -s /etc/nginx/sites-available/fdo-cache /etc/nginx/sites-enabled/fdo-cache
1537ec681f3Smrg  sudo service nginx restart
1547ec681f3Smrg
1557ec681f3Smrg  # First download will hit the internet
1567ec681f3Smrg  wget http://localhost/cache/?uri=https://minio-packet.freedesktop.org/mesa-tracie-public/itoral-gl-terrain-demo/demo.trace
1577ec681f3Smrg  # Second download should be cached.
1587ec681f3Smrg  wget http://localhost/cache/?uri=https://minio-packet.freedesktop.org/mesa-tracie-public/itoral-gl-terrain-demo/demo.trace
1597ec681f3Smrg
1607ec681f3SmrgNow, set ``download-url`` in your ``traces-*.yml`` entry to something like
1617ec681f3Smrg``http://10.42.0.1:8888/cache/?uri=https://minio-packet.freedesktop.org/mesa-tracie-public``
1627ec681f3Smrgand you should have cached downloads for traces.  Add it to
1637ec681f3Smrg``FDO_HTTP_CACHE_URI=`` in your ``config.toml`` runner environment lines and you
1647ec681f3Smrgcan use it for cached artifact downloads instead of going all the way to
1657ec681f3Smrgfreedesktop.org on each job.
166