GUI apps in LXD (Archlinux Host)

Hi @simos, sorry i’m gonna bother you - again - with the topic of gui in lxd.
I did follow your great tutorial to make gui app works in containers but when I launch xlock I still get “No protocol specified can’t open display: :0”
I don’t use root account but regular user.

My current config reflects the @stgraber tutorial “Custom user mappings in LXD containers” to make shared folders (host<->container) works.

As I already set raw.idmap, I could not set it as you suggest (both 1000 1000) because if I do it I have a forkstart error.

So I’m wondering if it’s possible to have shared folder and GUI works together?
As i just started to use lxd, I don’t completely understand it all.

Thanks!

Hi!

There are two ways for the user in the container to perform the necessary authentication and be allowed to show apps on the host’s desktop.

The first is the both 1000 1000 (where 1000 is the UID and GID of the desktop user on the host).
With the idmap, the host’s X server allows the access from the container just because the UID of the access is 1000 (same with the desktop user). When you access the Unix socket, the access sends to the receiver your UID.

The second way is with an .Xauthority file. You create an authority on the host, and place it into the container. Then, the user in the container can project applications on the host just because it can authenticate from this .Xauthority file it has. With this way, no idmap is required.

Therefore, can you show me the exact commands you use to share a folder between the host and the container? I would like to replicate what you are getting and see what’s the best solution.

My /etc/subuid, /etc/subguid

lxd:100000:1000000000
root:100000:100000000
lxd: 1000:1
root: 1000:1

I use profile for reuse but here’s the commands from @stgraber tutorial

lxc config set test security.idmap.isolated true

lxc config device add test home disk source=/home/host/sharefolder path=/home/user

printf "lxd:$(id -u):1\nroot:$(id -u):1\n" | sudo tee -a /etc/subuid
printf "lxd:$(id -g):1\nroot:$(id -g):1\n" | sudo tee -a /etc/subgid

printf "uid $(id -u) 1000\ngid $(id -g) 1000" | lxc config set test raw.idmap -

Then i took your profile and removed all stuff about gpu and pusle audio not needed for now.

the gui profile :

config:
environment; DISPLAY: :0
devices:
  X0:
    path: /tmp/.X11-unix/X0
    source: /tmp/.X11-unix/X0
    type: disk
Xauth:
    path: /home/user/.Xauthority
    source: /home/host/.Xauthority
    type: disk
name: gui

The .Xauthority file is mounted in the container but still the same error.

When You say “You create an authority on the host” do I have something to do? The file was already there so I didn’t do anything. Moreover does the hostname of the host in this file as to be the same as the container?
I’m sorry if I don’t explain things clearly…

On Ubuntu there is no default ~/.Xauthority file, therefore you would have to create it if you need it. Which distribution are you running? Do you have the snap package of LXD?

I’m on arch and I used aur to install lxd

There is a typo here, I suppose it is just from the copy/paste?

I understand that you are using three LXD profiles to create a container? Like in

lxc launch ubuntu:18.04 mycontainer --profile default --profile sharefolder --profile gui

I do not know the content in the sharefolder profile and how it may collide with that of the gui.
But you need to add in there the raw.idmap: both 1000 1000 part because without it, the X11 socket access from the container to the host is not allowed.

My mistake I just typed it too fast

Correct!

config:
raw.idmap: |-
uid 1000 1000
gid 998 1000
security.idmap.isolated : "true"
devices:
 share:
path: /home/user
source: /home/host/sharefolder
type: disk
name:share

The issue is if I do that I have a forkstart error. I tried to replace the actual raw.idmap by both and same error…

I tried to just apply default and gui with raw.idmap both 1000 1000
And I have a forkstart error. It complains about “newgidmap failed to write mapping newgidmap”

I just tried with sharing a directory from the host to the container, on a GUI container. The directory was shared, and I could run xclock. In your case, you would need to look for the newgidmap issue. Note that it does not complain about newuidmap, perhaps the 998 that you used is at issue?

My testing,

lxc launch ubuntu:18.04 mycontainer --profile default --profile gui
mkdir ~/LXDSHARED/
lxc config device add mycontainer mydirectory disk source=/home/myusername/LXDSHARED path=/LXDSHARED

I can write in /LXDSHARED in the container, and also I can run xclock.

When I do id command on the host my uid = 1000 & gid = 998(wheel).
If I do that same command on the host I have uid = 1000(user) gid = 1000(user).

Do you think that using wheel group could cause issues with my config?

Perhaps there is the typo there? You mention that you get the different output when running id on the host, both times.

Oh sorry! I meant in the container I get uid = 1000(user) gid = 1000(user).
I have gid = 998(wheel) on the host.

I reconfigured from scratch and now I have shared folder working perfectly with raw.idmap both 1000 1000.
But even with Xauthority, raw.idmap (both) and path to X0 I still have no protocol specified.
I also tried with and without my shared folder mounted just in case.

I don’t understand what I miss…

I created this following minimal profile and it works for me.

$ lxc profile show guishared
config:
  environment.DISPLAY: :0
  raw.idmap: |
    uid 1000 1000
    gid 1000 1000
  security.idmap.isolated: "true"
description: GUI LXD profile and shared folder
devices:
  X0:
    path: /tmp/.X11-unix/X0
    source: /tmp/.X11-unix/X1
    type: disk
  mygpu:
    type: gpu
  mysharedfolder:
    path: /LXDSHARED
    source: /home/myusername/LXDSHARED
    type: disk
name: guishared
used_by:
-

raw.idmap: both 1000 1000 should work for you, even if the group ID is different, because you get correct the UID. I have tried in my case to set a different GID and it worked.

Note that in any case, when you make changes in the profile, you need to restart the container so that the profiles are reapplied.

I dink that something goes wrong with the application of the idmap. You need to verify that the uid/gid that is received at the X11 socket on the host, is the uid/gid of your desktop user. But how to you verify that?
See https://shenaniganslabs.io/2019/05/21/LXD-LPE.html and create this Python file that creates a socket, and shows you the UID/GID of the process that opens this socket. By doing so, you will be able to verify conclusively the UID/GID of the container process that opens the socket. For this test, change temporary the X11 socket to echo.sock.

So I tried your minimal profile and shared folder is fine but I still have the same error about X0 not specified…

I changed it by /tmp/.X11-unix/X0 like your tuto on your blog because it does not find X1 on my system.

I also followed your advice with the python script and I’ve got:
Host : UID:1000, GID:998
Container : UID:0, GID:0

Wow I even follow this guide https://gist.github.com/stueja/447bd3bc0d510a0a7e50f9f1ef58ad75 step by step, straightforward and specifically design for arch and It does not work at all. It’s driving me nuts!

Are these copied and pasted? Because the script shows the output in a different format.

Also, how do you get this Container: line? Why do you get 0, 0? Do you run something as root?

Not copy pasted. I typed it.
The actual output of the script gives (for the host) PID: 1150, UID: 1000, GID:998 and (for the container) PID: 4035, UID:0, GID:0
I typed Host: and Container to make a difference between each other.

I really don’t know, when I saw the output from the container UID & GID :0 I was really surprised because I was logged in with my regular user and not using sudo with the nc -U command. And my container is an unprivileged one.

Hmmm, what command do you use to get a shell in the container?

As I’m not yet used to lxc exec… I use

lxc console container

then I log in with the regular user, that’s the reason I’m surprised that the output give me UID 0.