GUI Apps in LXD container

Hi @simos
Is this your blog

If it is
I followed it and got stuck.

here are the results:

sherab@Sherab-PureOS:~$ sudo su
[sudo] password for sherab: 
root@Sherab-PureOS:/home/sherab# /snap/bin/lxc profile list
+---------+---------+
|  NAME   | USED BY |
+---------+---------+
| default | 3       |
+---------+---------+
| gui     | 2       |
+---------+---------+
root@Sherab-PureOS:/home/sherab# /snap/bin/lxc profile show gui
config:
  environment.DISPLAY: :0
  raw.idmap: both 1000 1000
  user.user-data: |
    #cloud-config
    runcmd:
      - 'sed -i "s/; enable-shm = yes/enable-shm = no/g" /etc/pulse/client.conf'
      - 'echo export PULSE_SERVER=unix:/tmp/.pulse-native | tee --append /home/ubuntu/.profile'
    packages:
      - x11-apps
      - mesa-utils
      - pulseaudio
description: GUI LXD profile
devices:
  PASocket:
    path: /tmp/.pulse-native
    source: /run/user/1000/pulse/native
    type: disk
  X0:
    path: /tmp/.X11-unix/X0
    source: /tmp/.X11-unix/X0
    type: disk
  mygpu:
    type: gpu
name: gui
used_by:
- /1.0/containers/gui1804
- /1.0/containers/gui1604
root@Sherab-PureOS:/home/sherab# /snap/bin/lxc list -c n,4,s,t
+------------+---------------------+---------+------------+
|    NAME    |        IPV4         |  STATE  |    TYPE    |
+------------+---------------------+---------+------------+
| gui1604    | 10.15.35.82 (eth0)  | RUNNING | PERSISTENT |
+------------+---------------------+---------+------------+
| gui1804    | 10.15.35.96 (eth0)  | RUNNING | PERSISTENT |
+------------+---------------------+---------+------------+
| ubu18-test | 10.15.35.235 (eth0) | RUNNING | PERSISTENT |
+------------+---------------------+---------+------------+
root@Sherab-PureOS:/home/sherab# /snap/bin/lxc exec gui1804 -- sudo --user ubuntu --login
ubuntu@gui1804:~$ tail -6 /var/log/cloud-init.log 
2019-04-22 16:57:22,922 - main.py[DEBUG]: Ran 20 modules with 0 failures
2019-04-22 16:57:22,923 - util.py[DEBUG]: Creating symbolic link from '/run/cloud-init/result.json' => '../../var/lib/cloud/data/result.json'
2019-04-22 16:57:22,923 - util.py[DEBUG]: Reading from /proc/uptime (quiet=False)
2019-04-22 16:57:22,924 - util.py[DEBUG]: Read 11 bytes from /proc/uptime
2019-04-22 16:57:22,924 - util.py[DEBUG]: cloud-init mode 'modules' took 0.131 seconds (0.00)
2019-04-22 16:57:22,924 - handlers.py[DEBUG]: finish: modules-final: SUCCESS: running modules for final
ubuntu@gui1804:~$ glxgears
Error: couldn't open display :0
ubuntu@gui1804:~$ sudo glxinfo
Error: unable to open display :0
ubuntu@gui1804:~$ 

Can you advise please

Hi!

First of all, I notice that you use sudo lxc ... to run the lxc commands.
If your non-root user account is myusername, then run the following and logout/relogin. This commands adds your non-root account to the lxd group that has full access to the lxc ... commands.

sudo usermod -a -G lxd myusername

Then, you can add /snap/bin/ to your $PATH. Run the following both for root and myusername, with

echo 'PATH=/snap/bin/:$PATH' >> ~/.profile 

Log out and log in again to take effect.

PureOS is likely a bit different from Ubuntu, and may have some different paths.

First, you need to verify where is the X11 Unix socket located.
On Ubuntu, it is at /tmp/.X11-unix/X0. Try to find it on your system.
If you have two graphics cards, then maybe your socket is /tmp/.X11-unix/X1 instead.

Then, you need to find the UID of your non-root account. Run id to find it.
On Ubuntu, the default value is 1000. If it is different on your distribution, you need to edit accordingly the profile.

Go through these two and we will take it from there.

Hi @simos
thanks for detailed reply

I can confirm

root@Sherab-PureOS:/tmp/.X11-unix# ls
X0  X1024

So I take it that X11 Unix socket is located where you’d expect it?

and here is the output for the UID

root@Sherab-PureOS:~# id
uid=0(root) gid=0(root) groups=0(root)

So now what does it mean edit profile accordingly?

Cheers

p.s will this info be of any use?

root@Sherab-PureOS:~# lshw -numeric -C display
  *-display                 
       description: VGA compatible controller
       product: HD Graphics 520 [8086:1916]
       vendor: Intel Corporation [8086]
       physical id: 2
       bus info: pci@0000:00:02.0
       version: 07
       width: 64 bits
       clock: 33MHz
       capabilities: pciexpress msi pm vga_controller bus_master cap_list rom
       configuration: driver=i915 latency=0
       resources: irq:125 memory:d0000000-d0ffffff memory:c0000000-cfffffff ioport:1c00(size=64) memory:c0000-dffff
root@Sherab-PureOS:~#

The Unix socket is either X0 or X1024. I do not know what is the deal with X1024, however the answer should be a few Google searches away. Let’s work with X0 first.

This is your root user account. In PureOS, is there a non-root user, a user account that you use to log in and launch a graphical interface? You should have such a non-root user, and it is a big security issue if you DO use root as the desktop user.

I suppose that the proper use of PureOS would advocate for the use of a non-root user account.
Can you look into that? If you need to create such an account, please do so,
and perform the necessary steps to

  1. make that non-root user to be able to run the lxc commands (add to lxd group)
  2. run the id command in order to verify the UID

of course you are right I just used a lot of the root in order to do things with the snap lxc

but here is the normal user:

sherab@Sherab-PureOS:~$ id
uid=1000(sherab) gid=1000(sherab) groups=1000(sherab),27(sudo),997(lxd)

and this shows sherab is a member of the lxd group:

sherab@Sherab-PureOS:~$ groups sherab
sherab : sherab sudo lxd
sherab@Sherab-PureOS:~$

All these look good. Let’s check if LXD complains about something.
Run the following to see what logs are there.

sudo ls -l /var/snap/lxd/common/lxd/logs/gui1804/

You can safely ignore any warnings (newuidmap binary is missing and Invalid argument - Failed to unmount old devpts instance).
We are looking if there is any error with creating the X0 Unix socket proxy device.

In the container, run the following,

echo $DISPLAY
glxinfo

$DISPLAY should show a value (:0), and glxinfo should show lots of text lines.

There would be an issue if PureOS uses Wayland, and there is no X11 compatibility package (XWayland) installed to PureOS. My instructions are for X11-only at the moment.
The existence of those X0 and X1024 socket files is a good indication that XWayland is somehow enabled.

Therefore, try as it is with the instructions. If it does not work, then

  1. Edit the gui profile and change the source from X0 to X1024.
  2. Restart the container (lxc restart gui1804). By restarting, LXD will adjust the Unix socket.
  3. Check and report back.

Here’s the root@Sherab-PureOS:/var/snap/lxd/common/lxd/logs/gui1804# less lxc.log

lxc gui1804 20190422165712.651 WARN     conf - conf.c:lxc_map_ids:2970 - newuidmap binary is missing
lxc gui1804 20190422165712.651 WARN     conf - conf.c:lxc_map_ids:2976 - newgidmap binary is missing
lxc gui1804 20190422165712.659 WARN     conf - conf.c:lxc_map_ids:2970 - newuidmap binary is missing
lxc gui1804 20190422165712.659 WARN     conf - conf.c:lxc_map_ids:2976 - newgidmap binary is missing
lxc gui1804 20190422165712.789 WARN     conf - conf.c:lxc_setup_devpts:1641 - Invalid argument - Failed to unmount old devpts instance

seems like no errors other than what you mentioned.

and here is the rest

sherab@Sherab-PureOS:~$ lxc exec gui1804 bash
root@gui1804:~# echo $DISPLAY
:0
root@gui1804:~# glxinfo
No protocol specified
Error: unable to open display :0
root@gui1804:~# 

I am sorry to have to ask for little more explanation on changing the gui profile

Do I change the originally downloaded file caldled lxdguiprofile.txt? and after that I do a lxc restart gui1804 ??
or is the profile somewhere inside the gui1804 contianer itself?? although I searched and could not find anything [doesn’t mean much as I don’t really know where to look for it…:slight_smile: ]

I am not sure exactly what to change in it

from this original code

  X0:
    path: /tmp/.X11-unix/X0
    source: /tmp/.X11-unix/X0
    type: disk
  mygpu:
    type: gpu
name: gui
used_by:

to this

  X1024:
    path: /tmp/.X11-unix/X1024
    source: /tmp/.X11-unix/X1024
    type: disk
  mygpu:
    type: gpu
name: gui
used_by:

or to this where I only changed the source

  X0:
    path: /tmp/.X11-unix/X0
    source: /tmp/.X11-unix/X1024
    type: disk
  mygpu:
    type: gpu
name: gui
used_by:

First of all, I suggest to run xclock as a primary test to see whether the container can run GUI applications on your desktop. glxgears and glxinfo require a bit more from the X server, and may fail even if xclock is working.

When you created the gui1804 container, you assigned two profiles, default and gui (in this order).
This assignment is something that LXD remembers for you, and applies to this container whenever you start/restart it.

To edit a profile, you use lxc profile edit gui. It opens up your default text editor and lets you edit verbatim the profile configuration. Then, when you exit/save, the profile is changed.
Finally, you just need to restart the container (lxc restart gui1804) and it will update to the new configuration. That means that it will recreate the appropriate Unix sockets.

Regarding the change, try both cases that you list there. I am not familiar with X1024, therefore you are investigating as well on what should be put there.

Hi @simos
nothing seems to work.
however I just done the following

sherab@Sherab-PureOS:/tmp/.X11-unix$ stat X0
  File: X0
  Size: 0         	Blocks: 0          IO Block: 4096   socket
Device: 2bh/43d	Inode: 41923       Links: 1
Access: (0755/srwxr-xr-x)  Uid: ( 1000/  sherab)   Gid: ( 1000/  sherab)
Access: 2019-04-23 22:05:06.249116217 +0100
Modify: 2019-04-23 22:05:06.249116217 +0100
Change: 2019-04-23 22:05:06.249116217 +0100
 Birth: -
sherab@Sherab-PureOS:/tmp/.X11-unix$ stat X1024 
  File: X1024
  Size: 0         	Blocks: 0          IO Block: 4096   socket
Device: 2bh/43d	Inode: 29215       Links: 1
Access: (0755/srwxr-xr-x)  Uid: (  120/Debian-gdm)   Gid: (  127/Debian-gdm)
Access: 2019-04-23 22:04:52.420373012 +0100
Modify: 2019-04-23 22:04:52.420373012 +0100
Change: 2019-04-23 22:04:52.420373012 +0100
 Birth: -
sherab@Sherab-PureOS:/tmp/.X11-unix$

And I find it interesting that the size of both the X10 and X1024 are 0 - does it mean the file is empty?

also do you think it might do anything with this:

sherab@Sherab-PureOS:~$ lxc exec gui1804 bash
root@gui1804:~# xclock 
No protocol specified
Error: Can't open display: :0
root@gui1804:~# xauth list
xauth:  file /root/.Xauthority does not exist
root@gui1804:~#

First of all, you try to run GUI apps as root in the gui1804 container. That will not work without additional work not described in the tutorial. Please try again as user ubuntu.

Second, the Unix socket file are of size zero. They are special files that are associated with some running process. Without that running process, these file do not do something and have no content.
To see the Process ID of the associated process, run

$ sudo fuser /tmp/.X11-unix/X0 
/tmp/.X11-unix/X0:    2299

Perform the following only if you still get issues about Xauthority, when you connect as ubuntu in the gui1804 container. I wrote the following without noticing first that you connected as root to the container.

With this line in the gui profile, we are normally able to avoid copying the .Xauthority file from the host to the gui1804 container. In your case it does not appear that we can avoid that, therefore you would need to follow the older guide for the .Xauthority file, at https://blog.simos.info/how-to-run-graphics-accelerated-gui-apps-in-lxd-containers-on-your-ubuntu-desktop/

In a nutshell, you would need to additionally run the following,

 lxc config device add gui1804 Xauthority disk path=/home/ubuntu/.Xauthority source=${XAUTHORITY}

See the older blogpost for an explanation of the command.

I am very happy to inform that YES both xclock and glxgears are working!!
Thanks @simos

Thank you for your patience.
Now for my next jobs

  1. install crossover in my gui container on PureOS [which I managed installing crossover on lxd gui container in my linux mint 19.1]
  2. Install scapple inside that container and then run the scapple application with the crossover [in my gui container on my linux mint I managed running crossover and started installing the scapple file but there were some error messages]

Many many for you healp and again thanks for your patience - I appreciate you guys are busy with your life and yet you take the time to patiently guide people like me

Much appreciated

1 Like

I tried to follow this blog post and I’m hitting the following error when the gui container tries to start,

$ lxc info --show-log local:gui1804
Name: gui1804
Remote: unix://
Architecture: x86_64
Created: 2019/08/14 23:19 UTC
Status: Stopped
Type: persistent
Profiles: default, gui

Log:

lxc gui1804 20190814231943.577 ERROR    conf - conf.c:lxc_map_ids:2999 - newuidmap failed to write mapping "newuidmap: uid range [0-1001) -> [100000-101001) not allowed": newuidmap 7782 0 100000 1001 1001 1001 1 1002 101002 64534
lxc gui1804 20190814231943.577 ERROR    start - start.c:lxc_spawn:1708 - Failed to set up id mapping.
lxc gui1804 20190814231943.700 WARN     network - network.c:lxc_delete_network_priv:2613 - Invalid argument - Failed to remove interface "vethOQNJIP" from "lxdbr0"
lxc gui1804 20190814231943.700 ERROR    lxccontainer - lxccontainer.c:wait_on_daemonized_start:842 - Received container state "ABORTING" instead of "RUNNING"
lxc gui1804 20190814231943.700 ERROR    start - start.c:__lxc_start:1939 - Failed to spawn container "gui1804"
lxc gui1804 20190814231943.705 ERROR    conf - conf.c:lxc_map_ids:2999 - newuidmap failed to write mapping "newuidmap: uid range [0-1001) -> [100000-101001) not allowed": newuidmap 7803 0 100000 1001 65536 0 1
lxc gui1804 20190814231943.705 ERROR    conf - conf.c:userns_exec_1:4352 - Error setting up {g,u}id mappings for child process "7803"
lxc gui1804 20190814231943.705 WARN     cgfsng - cgroups/cgfsng.c:cgfsng_payload_destroy:1122 - Failed to destroy cgroups
lxc 20190814231943.706 WARN     commands - commands.c:lxc_cmd_rsp_recv:132 - Connection reset by peer - Failed to receive response for command "get_state"

It seems like I am having problems with uid/gid mappings.

$ id -u
1001
$ lxc profile show gui
config:
  environment.DISPLAY: :0
  raw.idmap: both 1001 1001
  user.user-data: |
    #cloud-config
    runcmd:
      - 'sed -i "s/; enable-shm = yes/enable-shm = no/g" /etc/pulse/client.conf'
      - 'echo export PULSE_SERVER=unix:/tmp/.pulse-native | tee --append /home/ubuntu/.profile'
    packages:
      - x11-apps
      - mesa-utils
      - pulseaudio
description: GUI LXD profile
devices:
  PASocket:
    path: /tmp/.pulse-native
    source: /run/user/1001/pulse/native
    type: disk
  X0:
    path: /tmp/.X11-unix/X0
    source: /tmp/.X11-unix/X0
    type: disk
  mygpu:
    type: gpu
name: gui
used_by:
- /1.0/containers/gui1804

This is the configuration I found,

$ sudo cat /var/log/lxd/gui1804/lxc.conf
lxc.log.file = /var/log/lxd/gui1804/lxc.log
lxc.log.level = warn
lxc.console.buffer.size = auto
lxc.console.size = auto
lxc.console.logfile = /var/log/lxd/gui1804/console.log
lxc.mount.auto = proc:rw sys:rw
lxc.autodev = 1
lxc.pty.max = 1024
lxc.mount.entry = /dev/fuse dev/fuse none bind,create=file,optional
lxc.mount.entry = /dev/net/tun dev/net/tun none bind,create=file,optional
lxc.mount.entry = /proc/sys/fs/binfmt_misc proc/sys/fs/binfmt_misc none rbind,create=dir,optional
lxc.mount.entry = /sys/firmware/efi/efivars sys/firmware/efi/efivars none rbind,create=dir,optional
lxc.mount.entry = /sys/fs/fuse/connections sys/fs/fuse/connections none rbind,create=dir,optional
lxc.mount.entry = /sys/fs/pstore sys/fs/pstore none rbind,create=dir,optional
lxc.mount.entry = /sys/kernel/debug sys/kernel/debug none rbind,create=dir,optional
lxc.mount.entry = /sys/kernel/security sys/kernel/security none rbind,create=dir,optional
lxc.mount.entry = /dev/mqueue dev/mqueue none rbind,create=dir,optional
lxc.include = /usr/share/lxc/config/common.conf.d/
lxc.arch = linux64
lxc.hook.pre-start = /usr/lib/lxd/lxd callhook /var/lib/lxd 10 start
lxc.hook.post-stop = /usr/lib/lxd/lxd callhook /var/lib/lxd 10 stop
lxc.tty.max = 0
lxc.uts.name = gui1804
lxc.mount.entry = /var/lib/lxd/devlxd dev/lxd none bind,create=dir 0 0
lxc.apparmor.profile = lxd-gui1804_</var/lib/lxd>//&:lxd-gui1804_<var-lib-lxd>:
lxc.seccomp.profile = /var/lib/lxd/security/seccomp/gui1804
lxc.idmap = u 0 100000 1001
lxc.idmap = u 1001 1001 1
lxc.idmap = g 1001 1001 1
lxc.idmap = u 1002 101002 64534
lxc.idmap = g 0 100000 1001
lxc.idmap = g 1002 101002 64534
lxc.environment = DISPLAY=:0
lxc.rootfs.path = dir:/var/lib/lxd/containers/gui1804/rootfs
lxc.mount.entry = /var/lib/lxd/devices/gui1804/disk.X0.tmp-.X11-unix-X0 tmp/.X11-unix/X0 none bind,create=file
lxc.mount.entry = /var/lib/lxd/devices/gui1804/disk.PASocket.tmp-.pulse-native tmp/.pulse-native none bind,create=file
lxc.net.0.type = veth
lxc.net.0.flags = up
lxc.net.0.link = lxdbr0
lxc.net.0.hwaddr = 00:16:3e:ac:8f:ea
lxc.net.0.name = eth0
lxc.mount.entry = /var/lib/lxd/shmounts/gui1804 dev/.lxd-mounts none bind,create=dir 0 0
lxc.mount.entry = /var/lib/lxd/devices/gui1804/unix.mygpu.dev-dri-card0 dev/dri/card0 none bind,create=file
lxc.mount.entry = /var/lib/lxd/devices/gui1804/unix.mygpu.dev-dri-controlD64 dev/dri/controlD64 none bind,create=file
lxc.mount.entry = /var/lib/lxd/devices/gui1804/unix.mygpu.dev-dri-renderD128 dev/dri/renderD128 none bind,create=file

My subuid / subgid entries,

$ cat /etc/subuid
myusername:165536:65536
lxd:100000:1000000000
root:100000:1000000000
$ cat /etc/subgid
myusername:165536:65536
lxd:100000:1000000000
root:100000:1000000000

I read about the root and lxd mappings in https://stgraber.org/2017/06/15/custom-user-mappings-in-lxd-containers/

Any idea what is the matter? @simos?

Hi!

The problem you are facing is with the ID mapping. The error message is

Failed to set up id mapping.
newuidmap failed to write mapping "newuidmap: uid range [0-1001) -> [100000-101001) not allowed": newuidmap 7782 0 100000 1001 1001 1001 1 1002 101002 64534

The relevant configuration that could cause this issue is

  raw.idmap: both 1001 1001

But what does both and these two numbers actually mean? Contrary to the popular belief,
the first number is the UID and GID for the non-root user on the host.
The second number is the UID and GID for the non-root user in the container.

Which means that for your case, with UID/GID 1001 on the host, you should have used instead

  raw.idmap: both 1001 1000

because the Ubuntu LXD container images default to UID/GID 1000 for the ubuntu account.

You can edit the profile by running lxc profile edit gui, and change the 1001 into a 1000.

Hi @simos,

Thank you for your detailed reply. I can confirm that it now works. I believe your blog post may require a correction when you comment about lxc profile set gui raw.idmap "both 1001 1001". I didn’t read all the comments there but should have, since the last commenter at the time of writing pointed it out as well.

Anyway, got GUI applications working now, thanks a lot!