1bf215546Sopenharmony_ciBare-metal CI
2bf215546Sopenharmony_ci=============
3bf215546Sopenharmony_ci
4bf215546Sopenharmony_ciThe bare-metal scripts run on a system with gitlab-runner and Docker,
5bf215546Sopenharmony_ciconnected to potentially multiple bare-metal boards that run tests of
6bf215546Sopenharmony_ciMesa.  Currently "fastboot", "ChromeOS Servo", and POE-powered devices are
7bf215546Sopenharmony_cisupported.
8bf215546Sopenharmony_ci
9bf215546Sopenharmony_ciIn comparison with LAVA, this doesn't involve maintaining a separate
10bf215546Sopenharmony_ciweb service with its own job scheduler and replicating jobs between the
11bf215546Sopenharmony_citwo.  It also places more of the board support in Git, instead of
12bf215546Sopenharmony_ciweb service configuration.  On the other hand, the serial interactions
13bf215546Sopenharmony_ciand bootloader support are more primitive.
14bf215546Sopenharmony_ci
15bf215546Sopenharmony_ciRequirements (fastboot)
16bf215546Sopenharmony_ci-----------------------
17bf215546Sopenharmony_ci
18bf215546Sopenharmony_ciThis testing requires power control of the DUTs by the gitlab-runner
19bf215546Sopenharmony_cimachine, since this is what we use to reset the system and get back to
20bf215546Sopenharmony_cia pristine state at the start of testing.
21bf215546Sopenharmony_ci
22bf215546Sopenharmony_ciWe require access to the console output from the gitlab-runner system,
23bf215546Sopenharmony_cisince that is how we get the final results back from the tests.  You
24bf215546Sopenharmony_cishould probably have the console on a serial connection, so that you
25bf215546Sopenharmony_cican see bootloader progress.
26bf215546Sopenharmony_ci
27bf215546Sopenharmony_ciThe boards need to be able to have a kernel/initramfs supplied by the
28bf215546Sopenharmony_cigitlab-runner system, since Mesa often needs to update the kernel either for new
29bf215546Sopenharmony_ciDRM functionality, or to fix kernel bugs.
30bf215546Sopenharmony_ci
31bf215546Sopenharmony_ciThe boards must have networking, so that we can extract the dEQP .xml results to
32bf215546Sopenharmony_ciartifacts on GitLab, and so that we can download traces (too large for an
33bf215546Sopenharmony_ciinitramfs) for trace replay testing.  Given that we need networking already, and
34bf215546Sopenharmony_ciour deqp/piglit/etc. payload is large, we use nfs from the x86 runner system
35bf215546Sopenharmony_cirather than initramfs.
36bf215546Sopenharmony_ci
37bf215546Sopenharmony_ciSee `src/freedreno/ci/gitlab-ci.yml` for an example of fastboot on DB410c and
38bf215546Sopenharmony_ciDB820c (freedreno-a306 and freereno-a530).
39bf215546Sopenharmony_ci
40bf215546Sopenharmony_ciRequirements (servo)
41bf215546Sopenharmony_ci--------------------
42bf215546Sopenharmony_ci
43bf215546Sopenharmony_ciFor servo-connected boards, we can use the EC connection for power
44bf215546Sopenharmony_cicontrol to reboot the board.  However, loading a kernel is not as easy
45bf215546Sopenharmony_cias fastboot, so we assume your bootloader can do TFTP, and that your
46bf215546Sopenharmony_cigitlab-runner mounts the runner's tftp directory specific to the board
47bf215546Sopenharmony_ciat /tftp in the container.
48bf215546Sopenharmony_ci
49bf215546Sopenharmony_ciSince we're going the TFTP route, we also use NFS root.  This avoids
50bf215546Sopenharmony_cipacking the rootfs and sending it to the board as a ramdisk, which
51bf215546Sopenharmony_cimeans we can support larger rootfses (for piglit testing), at the cost
52bf215546Sopenharmony_ciof needing more storage on the runner.
53bf215546Sopenharmony_ci
54bf215546Sopenharmony_ciTelling the board about where its TFTP and NFS should come from is
55bf215546Sopenharmony_cidone using dnsmasq on the runner host.  For example, this snippet in
56bf215546Sopenharmony_cithe dnsmasq.conf.d in the google farm, with the gitlab-runner host we
57bf215546Sopenharmony_cicall "servo"::
58bf215546Sopenharmony_ci
59bf215546Sopenharmony_ci  dhcp-host=1c:69:7a:0d:a3:d3,10.42.0.10,set:servo
60bf215546Sopenharmony_ci
61bf215546Sopenharmony_ci  # Fixed dhcp addresses for my sanity, and setting a tag for
62bf215546Sopenharmony_ci  # specializing other DHCP options
63bf215546Sopenharmony_ci  dhcp-host=a0:ce:c8:c8:d9:5d,10.42.0.11,set:cheza1
64bf215546Sopenharmony_ci  dhcp-host=a0:ce:c8:c8:d8:81,10.42.0.12,set:cheza2
65bf215546Sopenharmony_ci
66bf215546Sopenharmony_ci  # Specify the next server, watch out for the double ',,'.  The
67bf215546Sopenharmony_ci  # filename didn't seem to get picked up by the bootloader, so we use
68bf215546Sopenharmony_ci  # tftp-unique-root and mount directories like
69bf215546Sopenharmony_ci  # /srv/tftp/10.42.0.11/jwerner/cheza as /tftp in the job containers.
70bf215546Sopenharmony_ci  tftp-unique-root
71bf215546Sopenharmony_ci  dhcp-boot=tag:cheza1,cheza1/vmlinuz,,10.42.0.10
72bf215546Sopenharmony_ci  dhcp-boot=tag:cheza2,cheza2/vmlinuz,,10.42.0.10
73bf215546Sopenharmony_ci
74bf215546Sopenharmony_ci  dhcp-option=tag:cheza1,option:root-path,/srv/nfs/cheza1
75bf215546Sopenharmony_ci  dhcp-option=tag:cheza2,option:root-path,/srv/nfs/cheza2
76bf215546Sopenharmony_ci
77bf215546Sopenharmony_ciSee `src/freedreno/ci/gitlab-ci.yml` for an example of servo on cheza.  Note
78bf215546Sopenharmony_cithat other servo boards in CI are managed using LAVA.
79bf215546Sopenharmony_ci
80bf215546Sopenharmony_ciRequirements (POE)
81bf215546Sopenharmony_ci------------------
82bf215546Sopenharmony_ci
83bf215546Sopenharmony_ciFor boards with 30W or less power consumption, POE can be used for the power
84bf215546Sopenharmony_cicontrol.  The parts list ends up looking something like (for example):
85bf215546Sopenharmony_ci
86bf215546Sopenharmony_ci- x86-64 gitlab-runner machine with a mid-range CPU, and 3+ GB of SSD storage
87bf215546Sopenharmony_ci  per board.  This can host at least 15 boards in our experience.
88bf215546Sopenharmony_ci- Cisco 2960S gigabit ethernet switch with POE. (Cisco 3750G, 3560G, or 2960G
89bf215546Sopenharmony_ci  were also recommended as reasonable-priced HW, but make sure the name ends in
90bf215546Sopenharmony_ci  G, X, or S)
91bf215546Sopenharmony_ci- POE splitters to power the boards (you can find ones that go to micro USB,
92bf215546Sopenharmony_ci  USBC, and 5V barrel jacks at least)
93bf215546Sopenharmony_ci- USB serial cables (Adafruit sells pretty reliable ones)
94bf215546Sopenharmony_ci- A large powered USB hub for all the serial cables
95bf215546Sopenharmony_ci- A pile of ethernet cables
96bf215546Sopenharmony_ci
97bf215546Sopenharmony_ciYou'll talk to the Cisco for configuration using its USB port, which provides a
98bf215546Sopenharmony_ciserial terminal at 9600 baud.  You need to enable SNMP control, which we'll do
99bf215546Sopenharmony_ciusing a "mesaci" community name that the gitlab runner can access as its
100bf215546Sopenharmony_ciauthentication (no password) to configure.  To talk to the SNMP on the router,
101bf215546Sopenharmony_ciyou need to put an ip address on the default vlan (vlan 1).
102bf215546Sopenharmony_ci
103bf215546Sopenharmony_ciSetting that up looks something like:
104bf215546Sopenharmony_ci
105bf215546Sopenharmony_ci.. code-block: console
106bf215546Sopenharmony_ci
107bf215546Sopenharmony_ci  Switch>
108bf215546Sopenharmony_ci  Password:
109bf215546Sopenharmony_ci  Switch#configure terminal
110bf215546Sopenharmony_ci  Switch(config)#interface Vlan 1
111bf215546Sopenharmony_ci  Switch(config-if)#ip address 10.42.0.2 255.255.0.0
112bf215546Sopenharmony_ci  Switch(config-if)#end
113bf215546Sopenharmony_ci  Switch(config)#snmp-server community mesaci RW
114bf215546Sopenharmony_ci  Switch(config)#end
115bf215546Sopenharmony_ci  Switch#copy running-config startup-config
116bf215546Sopenharmony_ci
117bf215546Sopenharmony_ciWith that set up, you should be able to power on/off a port with something like:
118bf215546Sopenharmony_ci
119bf215546Sopenharmony_ci.. code-block: console
120bf215546Sopenharmony_ci
121bf215546Sopenharmony_ci  % snmpset -v2c -r 3 -t 30 -cmesaci 10.42.0.2 1.3.6.1.4.1.9.9.402.1.2.1.1.1.1 i 1
122bf215546Sopenharmony_ci  % snmpset -v2c -r 3 -t 30 -cmesaci 10.42.0.2 1.3.6.1.4.1.9.9.402.1.2.1.1.1.1 i 4
123bf215546Sopenharmony_ci
124bf215546Sopenharmony_ciNote that the "1.3.6..." SNMP OID changes between switches.  The last digit
125bf215546Sopenharmony_ciabove is the interface id (port number).  You can probably find the right OID by
126bf215546Sopenharmony_cigoogle, that was easier than figuring it out from finding the switch's MIB
127bf215546Sopenharmony_cidatabase.  You can query the POE status from the switch serial using the `show
128bf215546Sopenharmony_cipower inline` command.
129bf215546Sopenharmony_ci
130bf215546Sopenharmony_ciOther than that, find the dnsmasq/tftp/nfs setup for your boards "servo" above.
131bf215546Sopenharmony_ci
132bf215546Sopenharmony_ciSee `src/broadcom/ci/gitlab-ci.yml` and `src/nouveau/ci/gitlab-ci.yml` for an
133bf215546Sopenharmony_ciexamples of POE for Raspberry Pi 3/4, and Jetson Nano.
134bf215546Sopenharmony_ci
135bf215546Sopenharmony_ciSetup
136bf215546Sopenharmony_ci-----
137bf215546Sopenharmony_ci
138bf215546Sopenharmony_ciEach board will be registered in freedesktop.org GitLab.  You'll want
139bf215546Sopenharmony_cisomething like this to register a fastboot board:
140bf215546Sopenharmony_ci
141bf215546Sopenharmony_ci.. code-block:: console
142bf215546Sopenharmony_ci
143bf215546Sopenharmony_ci  sudo gitlab-runner register \
144bf215546Sopenharmony_ci       --url https://gitlab.freedesktop.org \
145bf215546Sopenharmony_ci       --registration-token $1 \
146bf215546Sopenharmony_ci       --name MY_BOARD_NAME \
147bf215546Sopenharmony_ci       --tag-list MY_BOARD_TAG \
148bf215546Sopenharmony_ci       --executor docker \
149bf215546Sopenharmony_ci       --docker-image "alpine:latest" \
150bf215546Sopenharmony_ci       --docker-volumes "/dev:/dev" \
151bf215546Sopenharmony_ci       --docker-network-mode "host" \
152bf215546Sopenharmony_ci       --docker-privileged \
153bf215546Sopenharmony_ci       --non-interactive
154bf215546Sopenharmony_ci
155bf215546Sopenharmony_ciFor a servo board, you'll need to also volume mount the board's NFS
156bf215546Sopenharmony_ciroot dir at /nfs and TFTP kernel directory at /tftp.
157bf215546Sopenharmony_ci
158bf215546Sopenharmony_ciThe registration token has to come from a freedesktop.org GitLab admin
159bf215546Sopenharmony_cigoing to https://gitlab.freedesktop.org/admin/runners
160bf215546Sopenharmony_ci
161bf215546Sopenharmony_ciThe name scheme for Google's lab is google-freedreno-boardname-n, and
162bf215546Sopenharmony_ciour tag is something like google-freedreno-db410c.  The tag is what
163bf215546Sopenharmony_ciidentifies a board type so that board-specific jobs can be dispatched
164bf215546Sopenharmony_ciinto that pool.
165bf215546Sopenharmony_ci
166bf215546Sopenharmony_ciWe need privileged mode and the /dev bind mount in order to get at the
167bf215546Sopenharmony_ciserial console and fastboot USB devices (--device arguments don't
168bf215546Sopenharmony_ciapply to devices that show up after container start, which is the case
169bf215546Sopenharmony_ciwith fastboot, and the servo serial devices are actually links to
170bf215546Sopenharmony_ci/dev/pts).  We use host network mode so that we can spin up a nginx
171bf215546Sopenharmony_ciserver to collect XML results for fastboot.
172bf215546Sopenharmony_ci
173bf215546Sopenharmony_ciOnce you've added your boards, you're going to need to add a little
174bf215546Sopenharmony_cimore customization in ``/etc/gitlab-runner/config.toml``.  First, add
175bf215546Sopenharmony_ci``concurrent = <number of boards>`` at the top ("we should have up to
176bf215546Sopenharmony_cithis many jobs running managed by this gitlab-runner").  Then for each
177bf215546Sopenharmony_ciboard's runner, set ``limit = 1`` ("only 1 job served by this board at a
178bf215546Sopenharmony_citime").  Finally, add the board-specific environment variables
179bf215546Sopenharmony_cirequired by your bare-metal script, something like::
180bf215546Sopenharmony_ci
181bf215546Sopenharmony_ci  [[runners]]
182bf215546Sopenharmony_ci    name = "google-freedreno-db410c-1"
183bf215546Sopenharmony_ci    environment = ["BM_SERIAL=/dev/ttyDB410c8", "BM_POWERUP=google-power-up.sh 8", "BM_FASTBOOT_SERIAL=15e9e390", "FDO_CI_CONCURRENT=4"]
184bf215546Sopenharmony_ci
185bf215546Sopenharmony_ciThe ``FDO_CI_CONCURRENT`` variable should be set to the number of CPU threads on
186bf215546Sopenharmony_cithe board, which is used for auto-tuning of job parallelism.
187bf215546Sopenharmony_ci
188bf215546Sopenharmony_ciOnce you've updated your runners' configs, restart with ``sudo service
189bf215546Sopenharmony_cigitlab-runner restart``
190bf215546Sopenharmony_ci
191bf215546Sopenharmony_ciCaching downloads
192bf215546Sopenharmony_ci-----------------
193bf215546Sopenharmony_ci
194bf215546Sopenharmony_ciTo improve the runtime for downloading traces during traces job runs, you will
195bf215546Sopenharmony_ciwant a pass-through HTTP cache.  On your runner box, install nginx:
196bf215546Sopenharmony_ci
197bf215546Sopenharmony_ci.. code-block:: console
198bf215546Sopenharmony_ci
199bf215546Sopenharmony_ci  sudo apt install nginx libnginx-mod-http-lua
200bf215546Sopenharmony_ci
201bf215546Sopenharmony_ciAdd the server setup files:
202bf215546Sopenharmony_ci
203bf215546Sopenharmony_ci.. literalinclude:: fdo-cache
204bf215546Sopenharmony_ci   :name: /etc/nginx/sites-available/fdo-cache
205bf215546Sopenharmony_ci   :caption: /etc/nginx/sites-available/fdo-cache
206bf215546Sopenharmony_ci
207bf215546Sopenharmony_ci.. literalinclude:: uri-caching.conf
208bf215546Sopenharmony_ci   :name: /etc/nginx/snippets/uri-caching.conf
209bf215546Sopenharmony_ci   :caption: /etc/nginx/snippets/uri-caching.conf
210bf215546Sopenharmony_ci
211bf215546Sopenharmony_ciEdit the listener addresses in fdo-cache to suit the ethernet interface that
212bf215546Sopenharmony_ciyour devices are on.
213bf215546Sopenharmony_ci
214bf215546Sopenharmony_ciEnable the site and restart nginx:
215bf215546Sopenharmony_ci
216bf215546Sopenharmony_ci.. code-block:: console
217bf215546Sopenharmony_ci
218bf215546Sopenharmony_ci  sudo ln -s /etc/nginx/sites-available/fdo-cache /etc/nginx/sites-enabled/fdo-cache
219bf215546Sopenharmony_ci  sudo service nginx restart
220bf215546Sopenharmony_ci
221bf215546Sopenharmony_ci  # First download will hit the internet
222bf215546Sopenharmony_ci  wget http://localhost/cache/?uri=https://s3.freedesktop.org/mesa-tracie-public/itoral-gl-terrain-demo/demo.trace
223bf215546Sopenharmony_ci  # Second download should be cached.
224bf215546Sopenharmony_ci  wget http://localhost/cache/?uri=https://s3.freedesktop.org/mesa-tracie-public/itoral-gl-terrain-demo/demo.trace
225bf215546Sopenharmony_ci
226bf215546Sopenharmony_ciNow, set ``download-url`` in your ``traces-*.yml`` entry to something like
227bf215546Sopenharmony_ci``http://10.42.0.1:8888/cache/?uri=https://s3.freedesktop.org/mesa-tracie-public``
228bf215546Sopenharmony_ciand you should have cached downloads for traces.  Add it to
229bf215546Sopenharmony_ci``FDO_HTTP_CACHE_URI=`` in your ``config.toml`` runner environment lines and you
230bf215546Sopenharmony_cican use it for cached artifact downloads instead of going all the way to
231bf215546Sopenharmony_cifreedesktop.org on each job.
232