Unable to get input in container

Hi there!
I am quite new to the topic of containerization and stuff…

I managed to run kodi --standalone in a ubuntu 20.04 container.
Here are my container infos:

Name: kodicont1
Status: RUNNING
Type: container
Architecture: x86_64
PID: 137824
Created: 2022/03/01 00:33 UTC
Last Used: 2022/03/19 21:37 UTC

Resources:
Processes: 68
Disk usage:
root: 1.66GiB
CPU usage:
CPU usage (in seconds): 82
Memory usage:
Memory (current): 434.59MiB
Memory (peak): 747.05MiB
Network usage:
eth0:
Type: broadcast
State: UP
Host interface: vethe497055d
MAC address: 00:16:3e:d5:e2:50
MTU: 1500
Bytes received: 92.41kB
Bytes sent: 41.59kB
Packets received: 271
Packets sent: 322
IP addresses:
inet: 10.128.122.227/24 (global)
inet6: fd42:50c5:e295:34d7:216:3eff:fed5:e250/64 (global)
inet6: fe80::216:3eff:fed5:e250/64 (link)
lo:
Type: loopback
State: UP
MTU: 65536
Bytes received: 12.39kB
Bytes sent: 12.39kB
Packets received: 116
Packets sent: 116
IP addresses:
inet: 127.0.0.1/8 (local)
inet6: ::1/128 (local)

i use the follwing script to fire up X (wait_for_x.sh):

#!/bin/bash

waitForX [ [ …]]

Wait for X Server to be ready, then run the given command once X server

is ready. (Or simply return if no command is provided.)

Source: wait for an X11 server to be ready (good for running under XVFB when testing chrome) Β· GitHub

function LOG {
# echo $(date -R): $0: $*
echo $*
}

if [ -z β€œ$DISPLAY” ]; then
LOG β€œFATAL: No DISPLAY environment variable set. No X.”
exit 13
fi

LOG β€œWaiting for X Server $DISPLAY to be available”

MAX=120 # About 60 seconds
CT=0
while ! xdpyinfo >/dev/null 2>&1; do
sleep 0.50s
CT=$(( CT + 1 ))
if [ β€œ$CT” -ge β€œ$MAX” ]; then
LOG β€œFATAL: $0: Gave up waiting for X server $DISPLAY”
exit 11
fi
done

LOG β€œX is available”

if [ -n β€œ$1” ]; then
exec β€œ$@”
fi

#eof

and the systemd services:
/etc/systemd/system/xorg.service

[Unit]
Description=X11 Server

[Service]
ExecStartPost=/root/wait_for_x.sh
Type=simple
Environment=β€œDISPLAY=:0”
ExecStart=/usr/bin/Xorg -nolisten tcp :0 vt7

[Install]
WantedBy=multi-user.target
and kodi.service
[Unit]
Description=Kodi media center
Requires=xorg.service
After=xorg.service

[Service]
Type=simple
Environment=β€œDISPLAY=:0”
ExecStart=/usr/bin/kodi --standalone
Restart=on-success
User=ubuntu
Group=ubuntu

[Install]
WantedBy=multi-user.target

When i start the container kodi boots perfectly but i cannot get the imput devices to work.
What i have tried: Used a small script to add all the /dev/imput/events to the container:

#/bin/bash!

for i in {0…20…1}
do
lxc config device add kodicont1 event$i unix-char source=/dev/input/event$i path=/dev/input/event$i required=false mode=0666 major=13 minor=$[64 + $i]
done

But that doesn’t help. Still i cannot use mouse or keyboard in kodi.
Can someone help my with the input devices? How do I get them to work in the container?

Thanks, Benjamin.

Here is the container config:

lxc config show kodicont1
architecture: x86_64
config:
image.architecture: amd64
image.description: ubuntu 20.04 LTS amd64 (release) (20220118)
image.label: release
image.os: ubuntu
image.release: focal
image.serial: β€œ20220118”
image.type: squashfs
image.version: β€œ20.04”
security.privileged: β€œtrue”
volatile.base_image: 44650bc10c092105a5695a240307f518b9f5a6f3a6c8094f340d663331191e48
volatile.eth0.host_name: vethe497055d
volatile.eth0.hwaddr: 00:16:3e:d5:e2:50
volatile.idmap.base: β€œ0”
volatile.idmap.current: β€˜β€™
volatile.idmap.next: β€˜β€™
volatile.last_state.idmap: β€˜β€™
volatile.last_state.power: RUNNING
volatile.uuid: fa8ea563-cba4-4dbf-bb38-8733b5e3849b
devices:
allusb:
mode: β€œ666”
type: usb
event0:
major: β€œ13”
minor: β€œ64”
mode: β€œ0666”
path: /dev/input/event0
required: β€œfalse”
source: /dev/input/event0
type: unix-char
event1:
major: β€œ13”
minor: β€œ65”
mode: β€œ0666”
path: /dev/input/event1
required: β€œfalse”
source: /dev/input/event1
type: unix-char
event2:
major: β€œ13”
minor: β€œ66”
mode: β€œ0666”
path: /dev/input/event2
required: β€œfalse”
source: /dev/input/event2
type: unix-char
event3:
major: β€œ13”
minor: β€œ67”
mode: β€œ0666”
path: /dev/input/event3
required: β€œfalse”
source: /dev/input/event3
type: unix-char
event4:
major: β€œ13”
minor: β€œ68”
mode: β€œ0666”
path: /dev/input/event4
required: β€œfalse”
source: /dev/input/event4
type: unix-char
event5:
major: β€œ13”
minor: β€œ69”
mode: β€œ0666”
path: /dev/input/event5
required: β€œfalse”
source: /dev/input/event5
type: unix-char
event6:
major: β€œ13”
minor: β€œ70”
mode: β€œ0666”
path: /dev/input/event6
required: β€œfalse”
source: /dev/input/event6
type: unix-char
event7:
major: β€œ13”
minor: β€œ71”
mode: β€œ0666”
path: /dev/input/event7
required: β€œfalse”
source: /dev/input/event7
type: unix-char
event8:
major: β€œ13”
minor: β€œ72”
mode: β€œ0666”
path: /dev/input/event8
required: β€œfalse”
source: /dev/input/event8
type: unix-char
event9:
major: β€œ13”
minor: β€œ73”
mode: β€œ0666”
path: /dev/input/event9
required: β€œfalse”
source: /dev/input/event9
type: unix-char
event10:
major: β€œ13”
minor: β€œ74”
mode: β€œ0666”
path: /dev/input/event10
required: β€œfalse”
source: /dev/input/event10
type: unix-char
event11:
major: β€œ13”
minor: β€œ75”
mode: β€œ0666”
path: /dev/input/event11
required: β€œfalse”
source: /dev/input/event11
type: unix-char
event12:
major: β€œ13”
minor: β€œ76”
mode: β€œ0666”
path: /dev/input/event12
required: β€œfalse”
source: /dev/input/event12
type: unix-char
event13:
major: β€œ13”
minor: β€œ77”
mode: β€œ0666”
path: /dev/input/event13
required: β€œfalse”
source: /dev/input/event13
type: unix-char
event14:
major: β€œ13”
minor: β€œ78”
mode: β€œ0666”
path: /dev/input/event14
required: β€œfalse”
source: /dev/input/event14
type: unix-char
event15:
major: β€œ13”
minor: β€œ79”
mode: β€œ0666”
path: /dev/input/event15
required: β€œfalse”
source: /dev/input/event15
type: unix-char
event16:
major: β€œ13”
minor: β€œ80”
mode: β€œ0666”
path: /dev/input/event16
required: β€œfalse”
source: /dev/input/event16
type: unix-char
event17:
major: β€œ13”
minor: β€œ81”
mode: β€œ0666”
path: /dev/input/event17
required: β€œfalse”
source: /dev/input/event17
type: unix-char
event18:
major: β€œ13”
minor: β€œ82”
mode: β€œ0666”
path: /dev/input/event18
required: β€œfalse”
source: /dev/input/event18
type: unix-char
event19:
major: β€œ13”
minor: β€œ83”
mode: β€œ0666”
path: /dev/input/event19
required: β€œfalse”
source: /dev/input/event19
type: unix-char
event20:
major: β€œ13”
minor: β€œ84”
mode: β€œ0666”
path: /dev/input/event20
required: β€œfalse”
source: /dev/input/event20
type: unix-char
gpu:
type: gpu
hdiraw0:
mode: β€œ0666”
path: /dev/hdiraw0
required: β€œfalse”
source: /dev/hdiraw0
type: unix-char
hdiraw1:
mode: β€œ0666”
path: /dev/hdiraw1
required: β€œfalse”
source: /dev/hdiraw0
type: unix-char
inp2:
gid: β€œ107”
path: /dev/input/event1
type: unix-char
uid: β€œ0”
inp5:
gid: β€œ107”
path: /dev/input/event4
type: unix-char
uid: β€œ0”
inp6:
gid: β€œ107”
path: /dev/input/event5
type: unix-char
uid: β€œ0”
inp7:
gid: β€œ107”
path: /dev/input/event6
type: unix-char
uid: β€œ0”
inp11:
gid: β€œ107”
path: /dev/input/mice
type: unix-char
uid: β€œ0”
inp16:
gid: β€œ107”
path: /dev/input/event0
type: unix-char
uid: β€œ0”
inpa:
gid: β€œ107”
path: /dev/input/event2
type: unix-char
uid: β€œ0”
inpb:
gid: β€œ107”
path: /dev/input/event3
type: unix-char
uid: β€œ0”
keyboard:
productid: β€œ8000”
type: usb
vendorid: 0c40
mice:
mode: β€œ0666”
path: /dev/input/mice
required: β€œfalse”
source: /dev/input/mice
type: unix-char
myport8080:
connect: tcp:127.0.0.1:8080
listen: tcp:0.0.0.0:8080
type: proxy
myport9090:
connect: tcp:127.0.0.1:9090
listen: tcp:0.0.0.0:9090
type: proxy
myport9777:
connect: tcp:127.0.0.1:9777
listen: tcp:0.0.0.0:9777
type: proxy
rcv:
gid: β€œ126”
mode: β€œ0660”
productid: β€œ8000”
type: unix-hotplug
uid: β€œ0”
vendorid: 0c40
root:
path: /
pool: lxcpool
type: disk
snd1:
gid: β€œ29”
path: /dev/snd/controlC0
type: unix-char
uid: β€œ0”
snd2:
gid: β€œ29”
path: /dev/snd/hwC0D0
type: unix-char
uid: β€œ0”
snd3:
gid: β€œ29”
path: /dev/snd/hwC0D2
type: unix-char
uid: β€œ0”
snd4:
gid: β€œ29”
path: /dev/snd/pcmC0D0c
type: unix-char
uid: β€œ0”
snd5:
gid: β€œ29”
path: /dev/snd/pcmC0D0p
type: unix-char
uid: β€œ0”
snd7:
gid: β€œ29”
path: /dev/snd/pcmC0D10p
type: unix-char
uid: β€œ0”
snd9:
gid: β€œ29”
path: /dev/snd/pcmC0D3p
type: unix-char
uid: β€œ0”
snd11:
gid: β€œ29”
path: /dev/snd/pcmC0D7p
type: unix-char
uid: β€œ0”
snd12:
gid: β€œ29”
path: /dev/snd/pcmC0D8p
type: unix-char
uid: β€œ0”
snd13:
gid: β€œ29”
path: /dev/snd/pcmC0D9p
type: unix-char
uid: β€œ0”
snd14:
gid: β€œ29”
path: /dev/snd/seq
type: unix-char
uid: β€œ0”
snd15:
gid: β€œ29”
path: /dev/snd/timer
type: unix-char
uid: β€œ0”
tty7:
gid: β€œ5”
mode: β€œ620”
path: /dev/tty7
source: /dev/tty7
type: unix-char
uid: β€œ0”
ephemeral: false
profiles:

  • default
    stateful: false
    description: β€œβ€

I suspect it may have to do with Xorg trying to list things through udev and udev not having database entries for those devices.

You could maybe cheat by copying the /run/udev data across to the container prior to starting Xorg, though I wonder if it wouldn’t be cleaner to run Xorg outside of the container, leaving all the input stuff handled there and then just expose the X11 socket to the container for it to run kodi against.

That’d be closer to other setups described on this forum before for running things like steam inside of a container.

Thanks for your reply!

Thing is, that the host is meant to run only as a server without xserver. I would like to keep the host as clean as possible. I only need x in the container, due to the fact, that all other containers and the host don’t need x to run.
On hostside: Which minimal packages would be required to get the stuff working?
And one more question: Could you describe how to do the β€œcheat” (handling over udev to the container)?
… a simple push is not working:

lxc file push -r /run/udev/ kodicont1/run/
Error: β€˜/var/lib/snapd/hostfs/run/udev/control’ isn’t a supported file
type

/run/udev/db is likely the part you care about and should be made of normal text files.

1 Like

Thanks for the help! Adding /run/udev/data to the container did the trick! Works perfectly!
Detailed explanation:

  1. Add devices /dev/input/event*
  2. Hand over /run/udev/data to the container:

lxc config device add kodicont1 udev_data disk source=/run/udev/data path=/home/ubuntu/udev/data

in the container I added the following lines to the wait_for_x.sh (ontop! before x is starting):

mkdir /run/udev
mkdir /run/udev/data
cp /home/ubuntu/data/* /run/udev/data/

…I think I will write a lxd tutorial how to setup kodi on a headless server. It still seems to be missing in the internet :wink:

2 Likes

Kind poster, I spent a week trying to get a hardware keyboard working with a X11 desktop. And this little udev hack restored my sanity. Thank you.

That would be very nice of you!

Meanwhile, can you please advise on your setup (sorry for using this topic for it) - have you been able to completely push all graphics-related assets into the container, keeping host OS completely clean?
Also, are you by chance using any of graphic accelerations (mesa, vulkan) in your environment? If yes, are they also kelpt in the container?