Rationale: I started my internship at Open Robotics and I needed to get a development environment set up on my laptop and could not be arsed to set up an ubuntu partition (and I’m a little too bound to my current rat’s nest of config files).
So, like any other rational being, I invested twice the time and effort than it would’ve taken to get an ubuntu partition running into using LXD to fire up something that would compile ROS 2
1.
Initial Setup
There are many resources out there for getting lxd
going.
The general steps for me were:
yay -S lxd
sudo lxd init
- Just follow the prompts, the default values are fine
- Create a container with
lxc launch ubuntu:22.04 <container_name>
- This will create a new container with the name
<container_name>
- The container will be running Ubuntu 22.04 or whatever you want.
- This will create a new container with the name
- Enter the system:
lxc exec <container_name> -- sudo --login --user ubuntu
I think you may need to use
-- su
instead of-- sudo
depending on your lxd version
Mount a directory
It is also useful to mount a directory and share it with your host machine. This way you can use your host editors while building/running in the container.
lxc config device add osrf osrf disk source=/home/ihasdapie/osrf path=/home/ihasdapie/osrf
In my case I wanted to keep paths consistent between my container and its host, so I just renamed the default ‘ubuntu’ user to ‘ihasdapie’. The following command from stackoverflow will change the name, group, home directory, and ownership over appropriately.
|
|
The directory can then be mounted with the following command:
|
|
Fix permissions
Some user/group id black magick must be performed in order for file access to be seamless between the container and host. It is also a good idea to make the containers unpriviledged
- Setting
/etc/subgid
,/etc/subuid
These config files are of format <user>:<id>:<count>
and lay out what sub{u,g}ids are available.
See subuid(5)
, subgid(5)
for more.
Create or edit your files to resemble the following. Or if you have a different setup…you probably already know what you’re doing so just map it out however makes sense for your system.
|
|
|
|
Sometimes things aren’t recognized, especially with the user ids. A reboot of the host system usually triggers the recognition.
/etc/lxc/default.conf
,~/.config/lxc/default.conf
These config entries tell lxc
to map the subordinate ids inside the container to the host ids we delegated in /etc/{u,g}id
.
I had the same entries for both.
|
|
In order for the permissions to work out you have to make the {u,g}id
s match up between the container and the host. This can be accomplished
with
lxc config set osrf raw.idmap "both 1000 1000"
That is, assuming that your host uid
and gid
are both 1000
and the
same goes for the user in the container. If not then you would have to
modify that command a little bit. Alternatively, just use
lxc config edit container
If your user inside the container does not have the correct uid/gid then file access will not work properly. The easiest way to do this is with some
usermod
/groupmod
commands to change theirgid
anduid
. See this link
In any case with this done you should be able to seamlessly work on a directory inside and out of the container.
Networking
Depending on your host system firewall you may not be able to connect to the internet in your container.
You can either 1) disable it or 2) add some more firewall rules! See this for an explanation for how to make it work with firewalld
Sharing host X11, Wayland
I chose to share my host Wayland and XWayland server with the container.
What this entailed was the sharing of a few unix
sockets.
- Make sure you have
weston
andxorg-wayland
installed on your host system. And your container should havexorg
installed 2
- Add your GPU to the container
1 2 3
devices: mygpu: type: gpu
- Look for where your wayland and xwayland sockets are. You will also need your host’s
Xauthority
file, which is usually located at~/.Xauthority
. In my case I screwed with it a little much and the file is in/run/user/1000/xauth_<random_chars_here>
.- For me they were in
/run/user/1000/wayland-0
and/tmp/.X11-unix/X1
- For me they were in
- Add these to your container. Here I link them to the container and then symlink it to the desired location.
|
|
If you find an error with “cannot connect to
/mnt/wayland1/wayland-0
” you may have tomkdir /mnt/wayland1
in the container
The downside of this is that the symlinks don’t persist after the container restarts.
I just check for it in my ~/.zprofile
.
- Set some environment variables
I put these into the ~/.zprofile
inside the container. You can do the same with your ~/.profile
or however you choose to handle environment variables. I think lxc
provides some tools to set them in the lxc
config for the container.
|
|
- Enjoy!
You should now be able to run
xclock
orrviz
or any gui application and find it working.
ROS
As for ROS
, steps to get started working with ROS
development are
the same as anywhere else. See this.
My workflow typically involves using the container for compiling and testing and editing from my host machine. For more, see this post
Summary & Misc
A few useful things:
- Make a bash function for changing the terminal theme while inside the container. With kitty it looks something like this:
|
|
Not the best way to do this but it works.
- If networking doesn’t work
- allow lxd in firewalld and fix iptables
|
|