Current status: Production
This document is designed to explain to existing users of servod inside of the ChromeOS SDK chroot how to use servod whilst operating outside of the chroot. For most users it should also provide a way to use servod without building any code. Unless you are changing code in servod you should be able to just run from a pre-built docker image.
See also go/servod-on-bruschetta if you are a Googler and want to run servod on a Chromebook.
This document assumes you:
Have followed the ChromiumOS developer guide link at least up to the “Getting the source code section”.
NOTE: It is not necessary to download all of ChromeOS if you only want servod. Running
git clone https://chromium.googlesource.com/chromiumos/third_party/hdctoolsis sufficient.
Are running a linux x86 distribution that supports docker engine.
Googlers:
Follow the instructions for Installation, Sudoless Docker And GCR credential helper
Note that sudoless docker and GCR credential helper are REQUIRED for servod to work, even though the general instructions suggest it is optional.
Non-Googlers:
Follow the instructions for your distribution to install docker engine at link
Also complete the post installation step to have “Manage Docker as a non-root user” setup link
The serial devices created by the docker container are owned by root - outside of the container the host will get a permission denied error if they try to access these devices
picocom /dev/pts/36 FATAL: cannot open /dev/pts/36: Permission denied
To solve this issue add your user into the tty group
sudo usermod -aG tty $USER
You may need to reboot your host for this change to take effect.
NOTE: If you want to use these serial devices also from inside chroot remember to add user to tty group also there. So inside chroot you need to modify
/etc/groupfile, adding your username to tty group.
Adjust to the directory where you checked out hdctools if necessary.
export PATH=~/chromiumos/src/third_party/hdctools/scripts:$PATH
To set it for every session you can also add this line at the end of yours shell configuration, like .bashrc. Below you can find example how to do it, that should work for you, just NOTE: - make sure you use proper path to chromiumos in your setup - this grep should prevent re-adding extra line to your .bashrc
grep "src/third_party/hdctools/scripts" ~/.bashrc || echo "export PATH=~/chromiumos/src/third_party/hdctools/scripts:\$PATH" >> ~/.bashrc
If you just need servod running for some simple dut-control commands there is no need to build anything. Assuming you just have one servo attached to your machine you can run:
start-servod --channel=release --board=<board name>
This will run the current released version of servod - typically from a branch cut 2-4 weeks ago. This is the version Satlab and most ChromeOS development and testing partners, are running.
There is also --channel=latest, which is a docker image that is rebuilt when a new CL lands in the main branch of hdctools. Typically there is about a 20 min lag from the submit to the image being ready to use. It is going to be pretty close to ToT but is not guaranteed to be as builds may finish out of order.
NOTE: start-servod DOES NOT expose servod port on 9999 host port by default. You should use -p [PORT] to map servod port to host port, e.g. if you want to use servod for FAFT/TAST testing.
It is not necessary - but strongly recommended that you provide a board and model parameter to your start-servod. Some servod functionality may not work without the board and model being passed in.
With a running servod can then just run dut-control commands like
dut-control -- servo_type servo_type:ccd_cr50
servodtool commands are also available:
servodtool -- instance wait-for-active -p 9999 Instance associated with id 9999 ready.
When you are finished running commands you can stop servod with:
stop-servod
start-servod [-c {local,latest,beta,release}] local, image built on this machine. latest, a close to ToT build, may have bugs beta, used for short period of time to test next release release, latest release version, typically 2-4 weeks behind, used by Satlab and most partners has significantly more testing. [-b BOARD] DUT board the servo is connected to. Not required but strongly suggested. [-m MODEL] DUT model the servo is connected to. Not required. [-s SERIAL] Servo serial number you want to connect to. [-n CONTAINER_NAME] Name to give your container, not required but useful if you are running multiple containers. [-t | --run_tests | --no-run_tests] Run the e2e tests rather than run servod. [-d | --sleep | --no-sleep] Run/setup the container but execute sleep infinity, useful in advanced use cases like running commands inside docker container without servod running in it. [--mount [MOUNT ...]] Mount a directory from the host to the container in the format: <host_directory>:<container_mount_point> Note multiple mount arguments are supported. [-p PORT] Map the internal XML RPC port to this port number on the host, allows for direct API access without having to run commands inside of the docker container [-f ] After the servod has started continue to follow the logs as they get generated rather than dropping back to the shell. CTRL+C will exit the servod on the command line. By default -f will show the debug logs but you can specify -f=WARNING or -f=INFO if you wish another level of logging. [--allow_offline] Every time you run start-servod the code will check for a newer version of the servod docker image. If you are not connected to the internet this check will fail with an error. This option suppresses that error and allows the servod to start with whatever version of the image is cached to the disk. If there is no cached version the script will still fail with an access error.
dut-control [-n CONTAINER_NAME] If you are running multiple servod containers use this to address a specific instance. -- Everything after the -- is passed to the dut-control command in the container. Example: dut-control -- servo_type servo_type:ccd_cr50 Note the exit code for the wrapper script is set to be the exit code of the dut-control command.
servodtool [-n CONTAINER_NAME] If you are running multiple servod containers use this to address a specific instance. -- Everything after the -- is passed to the servodtool command in the container. Example: servodtool -- instance servo_type:ccd_cr50 Note the exit code for the wrapper script is set to be the exit code of the dut-control command.
servod-ps Shows a list of the servod containers currently running Example: servod-ps Name Image Board Model Servo Serial Port 1700772381-docker_servod dev brya banshee SERVOV4P1-C-2306151088 9997
Any changes you have locally can be built by running the command
build-servod
Note the tests run in the build docker image - so if you make changes to the code you need to run build-servod then run-servod-tests
run-servod-tests
start-servod -n pytest -d docker exec -it pytest-docker_servod pytest -vvvvvv -o cli_log=true --log-level=DEBUG --log-cli-level=DEBUG 'hdctools/servo/tests/e2e/test_Metadata.py::TestMetadata::test_servo_type_4p1_cr50' stop-servod -n pytest
You can see a list of the running containers by running the command:
servod-ps Name Image Board Model Servo Serial Port 1700772381-docker_servod dev brya banshee SERVOV4P1-C-2306151088 9997
Containers are always named - if you do not supply a name then a timestamp is used - so in this case the containers are named 1692829089 and 1692827271.
The built in wrapper scripts append the -docker_servod on any docker command to namespace the servo containers distinctly from any other container you may be running.
Entering a container so you can run commands can be done with the command:
docker exec -it <name> bash Example: docker exec -it 1700772381-docker_servod bash
In particular if you use the:
start-servod --sleep
option, which just starts the container and executes sleep infinity, you can enter the container and start servod or run servo_updater with whatever arguments you wish.
Likely you have started two or more servod containers without giving them names, by default a timestamp is used for the container name if it is not provided.
You can see a list of the running containers by running the command:
servod-ps Name Image Board Model Servo Serial Port 1700772381-docker_servod dev brya banshee SERVOV4P1-C-2306151088 9997 1700778745-docker_servod release puff wyvern SERVOV4P1-C-2306153023 None
Then you can stop one a container by running
stop-servod -n 1700778745
Until you have only one servod container running. If you wish to have multiple containers it is best to explicitly name them with the -n parameter.
Start your servod container with the directory with the firmware to flash mounted so something like:
start-servod --mount=$HOME/firmware_build_output:/tmp/firmware_to_flash -n flashing_servod
You then have to enter the docker container ( since you named it we do not need to do a docker ps )
docker exec -it flashing_servod-docker_servod bash
You should then see your firmware directory in /tmp/firmware_to_flash and should be able to use flash_ec or any any other normal firmware flashing commands.
Alternatively, you can execute the flashing command directly, e.g. bash start-servod --channel=release --mount=chromiumos/src/platform/ec:/tmp/ec -n flashing_servod docker exec -it flashing_servod-docker_servod /tmp/ec/util/flash_ec --board atlas
Start your servod container with -p [PORT] parameter, which would map internal XML RPC port to specific port number on the host. Then you should be able to run TAST or FAFT tests as usual.
tast run -var=servo=localhost:<PORT> <DUT_IP> example.ServoEcho
or
test_that --autotest_dir <TESTS_PATH> --board=<BOARD> <DUT_IP> --args "servo_host=localhost servo_port=<PORT>" f:.*firmware_ConsecutiveBoot/control
You need to change the device limit on number of pty’s
sudo bash -c 'echo "kernel.pty.max = 8096" >> /etc/sysctl.conf' sudo sysctl -p
You should be able to check the setting has been applied by running
cat /proc/sys/kernel/pty/max 5120
Most likely your sudoless configuration of docker has not worked. Please review this section of the docker installation. The documentation says that a login/logout is sufficient for the changes to take effect, however experience has shown that reboot is often required.
To validate your docker is setup correctly you should be able to run the command:
docker run -it hello-world
With no errors and see an output similar to this:
Hello from Docker! This message shows that your installation appears to be working correctly. To generate this message, Docker took the following steps: 1. The Docker client contacted the Docker daemon. 2. The Docker daemon pulled the "hello-world" image from the Docker Hub. (amd64) 3. The Docker daemon created a new container from that image which runs the executable that produces the output you are currently reading. 4. The Docker daemon streamed that output to the Docker client, which sent it to your terminal. To try something more ambitious, you can run an Ubuntu container with: $ docker run -it ubuntu bash Share images, automate workflows, and more with a free Docker ID: https://hub.docker.com/ For more examples and ideas, visit: https://docs.docker.com/get-started/
If you see error messages please go through the instructions for sudoless docker again.
At this time no. The scripts rely on the docker api and Satlab/partners are using docker. If there is enough demand for podman we can suggest porting over but I do not think we can support/test multiple container engines simultaneously.
Rootless docker also does not work at this time. Quick experiments have shown that you quickly run into permission issues with devices.
There is a google group link for release notes and announcements are made there.
For non Googlers you will will need to email a request to chromeos-servo-announce-external+subscribe@google.com to join the group.
Google groups will reply to your request and you will have to reply back to confirm your subscription. The web UI does not work for external users.
A release branch is cut once per month at the start of the month. A post to the group with release notes and a new image tagged as beta - users have about a 2 week time frame to ensure the new release is functioning for their fleet/CI.
If no bugs are filed in that two week period then the image will be marked as release and an announcement to that effect sent to the group.
At this time we have some experimental ARM builds but they are not ready for dogfood.
Please file a feature request with your use case for running on ARM as this makes it more likely that the ARM project will be prioritized.
Building servod or getting a new version of servod requires a connection to the internet. However it is possible to use a previously cached version of the docker image to run servod without needing an internet connection.
You must have previously have run start-servod with the channel=[release | beta ] whilst connected to populate the cache.
Then when disconnected you can add the --allow-offline option to the command line
start-servod --allow-offline [ other start-servod options ]
There will still be a check to see if there is a newer version but the script will continue on with a cached version if it exists rather than failing with an error. If there is no cached version you still will get an error.
dut-console script ( not maintained by HW Tools team ) uses the XML RPC api to query the servod. start-servod does not expose that port to the host by default. If you wish to use dut-console you will need to run start-servod with a port number of your choosing on the host.
As an example:
start-servod -p 9999
There should be no authentication issues because our registry is configured to be wide open.
If your docker install is set up to authenticate with us-docker.pkg.dev using gcloud, and the gcloud credentials are broken for whatever reason, docker fails to authenticate and doesn't retry unauthenticated. To see if you might be impacted, check if $HOME/.docker/config.json contains a line stating "us-docker.pkg.dev": "gcloud". If so, docker will call into the gcloud tool to authenticate. Try running gcloud auth login to refresh the credentials and try again.
If this didn't help, please file an issue.
The logs are in a docker volume named ${container_name}_logs. You can see the path by running:
# Run servod-ps to see the container name container_name=1700772381 docker volume inspect ${container_name}_log # Using the path from the previous command sudo less /usr/local/google/docker/volumes/1700772381_log/_data/latest.DEBUG
Alternatively, you can enter the container and look at the logs directly, but there is no less command there.