First of all, sorry for the long topic and sorry if the category is not the right one. None seemed to fit.
I’m working in a project involving a HW of our own design connected through USB for test purposes. I use GitLab pipelines for the build, test and deploy of the Firmware running on this HW. The runners are implemented as docker containers running in gitlab-runners.
I use the USB interface as a serial terminal (mapped to /dev/ttyACM0) to send test commands and as a usb mass storage to load the test files on the HW’s memory.
I have a gitlab job use the USB terminal, then switch to the USB mass storage, load some test files, then switch back to USB terminal and perform some tests.
There’s either the USB terminal or the USB mass storage available at one point in time. The terminal is the default one, so I configure the runner to map /dev/ttyACM0 (no issues there), but as there’s no USB mass storage, I cannot map it in the runner’s config (obviously).
So I need to map it and dynamically mount the USB volume. To do that I did the following:
- I set a udev rule in the runner’s host to a fixed path reading the device’s vendor ID and product ID (symlinked to a name in the like of “/dev/disk/by-dname/my-favourite-usb-drive”)
- I set an fstab rule to be able to mount the symlinked volume without super user permissions (using the “users” option) to a fixed mount point.
- Configure the runner to run the docker container as privileged and map the whole /dev/ directory using the runner config “devices” field (I know, this is super unsafe, but this is only for internal use and the idea is to get it running, then restrict the permissions to a minimum)
I tested this approach by executing a docker container in the same host where the runner is and then calling the test script in the same way I did in the pipeline’s job. The result was a success, the test script was working, the mass storage was being mapped, I could mount it, copy my test files, everything was great.
However, once I executed the runner and triggered the job, I saw the script failing. It could not mount the volume because the symlink I created on the udev rule didn’t exist.
I tried listing the contents of /dev/, and it wasn’t only my symlink that was missing, but the whole /dev/disk directory was missing too. I tried moving the symlink to “/dev/my-test-dir”, but nothing changed.
I tried checking the documentation, stack overflow, docker forums… nothing helped (I tried adding -net=host, seemed to help someone somewhere, but id didn’t help me)
I purposely left out several details because the might not be relevant and there’s enough stuff in this topic already, but I’ll answer questions the best I can.
All this was to ask what is going on here?
Why does this work on a manually executed docker container but it doesn’t in a gitlab-runner executed container? Something must be happening on the runner’s side to explain this right?
Maybe something to do with udev?
Thanks in advance.