Using VirtualCAN inside docker on macOSPosted on
At SmartAg, we use Docker to manage the development and runtime environments for our embedded software. For performing full-system integrated tests, we have built comprehensive simulators that mimic the behavior of the hardware that we automate. Since most of the hardware communication happens over CAN, VirtualCAN is a great way of faking the hardware signals.
Until now, any code that required a CAN interface could not run on my Macbook Pro. This was primarily because the linux kernel used by Docker for Mac lacks support for SocketCAN or VirtualCAN. After much head-bashing, I realized that a better option would be
[docker-machine](https://docs.docker.com/machine/overview/) , which is how docker was originally run on macOS before the official “Docker for Mac” release.
Setting up a CAN-enabled docker-machine VM
- Install Homebrew if you don’t already have it.
docker-machineand some associated software
brew install docker docker-compose docker-machine docker-credential-helper docker-machine-driver-xhyve
3. Clone the repo from https://github.com/boot2docker/boot2docker
kernel_config in the
boot2docker repo and add the following at the bottom:
CONFIG\_CAN=y CONFIG\_CAN\_RAW=y CONFIG\_CAN\_VCAN=y CONFIG\_CAN\_DEV=y CAN\_SLCAN=y CAN\_BCM=y
5. Follow the instructions at https://github.com/boot2docker/boot2docker/blob/master/doc/BUILD.md to build your custom
boot2docker image. This basically boils down to:
docker build -t boot2docker . docker run --rm boot2docker > boot2docker-can.iso
6. Fix some permissions required by the
xhyve docker-machine driver.
sudo chown root:wheel $(brew --prefix)/opt/docker-machine-driver-xhyve/bin/docker-machine-driver-xhyve sudo chmod u+s $(brew --prefix)/opt/docker-machine-driver-xhyve/bin/docker-machine-driver-xhyve
7. Create your new
docker-machine VM with the following command. Change the command appropriately to allocate the desired number of CPUs, amount of RAM and disk space to the VM.
docker-machine create default --driver xhyve --xhyve-experimental-nfs-share --xhyve-cpu-count=4 --xhyve-memory-size=4096 --xhyve-disk-size=40000 --xhyve-boot2docker-url boot2docker-can.iso
docker-machine VM is now ready. It should already be running. If you restart your machine, you can start the VM by typing
docker-machine start default or stop it with
docker-machine stop default .
9. Set the environment parameters to use docker with your new VM by running
eval $(docker-machine env default) . This command has to be run every time you are in a new terminal. You can also add this to your
.bashrc to make it automatic.
10. Check that it all works:
docker run -it --rm --privileged alpine /bin/sh
Inside the docker container, run:
zcat /proc/config.gz | grep CAN
The command should display the CAN flags that you set while compiling the kernel. SocketCAN/VirtualCAN is now enabled in any docker container that you start on this VM.
docker-machine means that some things, such as port-forwarding does not work as you expect. A handy script for exposing any ports you want from your VM to
localhost can be found here: https://github.com/johanhaleby/docker-machine-port-forwarder