redhog / InfiniteGlass

Window manager with infinite desktop, infinite zoom and infinite window resolution
https://redhog.github.io/InfiniteGlass/
GNU General Public License v3.0
35 stars 5 forks source link

Docker image #87

Open IanTrudel opened 2 years ago

IanTrudel commented 2 years ago

The Docker image hasn't been updated in two years. See https://hub.docker.com/r/redhogorg/glass/tags.

Links

redhog commented 2 years ago

Yep, it needs rebuilding w latest version!

redhog commented 2 years ago

I don't use it myself, so it doesn't get properly tested :S

IanTrudel commented 2 years ago

I also attempted to build the image using Docker and Podman. No luck either. Something seems wrong because it doesn't contain the proper files (the script directory and dependencies.txt are missing, for example). Running with Podman, a Docker replacement, will require an extra parameter (--security-opt label=type:container_runtime_t). See https://major.io/2021/10/17/run-xorg-applications-with-podman/

To be noted, Docker is sort-of deprecated by Kubernetes in favour of OCI compliant tools, such as Podman and Buildah.

IanTrudel commented 2 years ago

https://github.com/redhog/InfiniteGlass/issues/89#issuecomment-1201509507

I have bugfixed run in docker! Pull the newest version, make sure to delete any old docker image and container and try run it!

The good news is that it is finally built properly on podman with all the required files. Unfortunately, Xephyr fails to connect to the display. DISPLAY is set to :0 by default in scripts/run-in-docker.sh but should be set to $DISPLAY (or simply -e DISPLAY). For example, mine is :1.

xauth should also use $DISPLAY, see here.

I also added xhost + at line 4 see here, otherwise resulting in Authorization required, but no authorization protocol specified. InfiniteGlass should not run as root though. The Linux community is slowly moving away from such practices, and more, e.g. you cannot log in locally on a GNOME session if you are also connected through VNC. Lots of nonsense going on.

Xephyr opens, and InfiniteGlass is engaging. Now getting a whole new set of issues that I hadn't encountered before.

Take note that I am running podman instead of docker. The packages are incompatibles and testing on both is troublesome. I gave a few rounds to docker but had no success. Both Arch and Rocky Linux favours podman over docker.

_XSERVTransmkdir: Owner of /tmp/.X11-unix should be set to root
xinit: XFree86_VT property unexpectedly has 0 items instead of 1
Copying 1
Traceback (most recent call last):
  File "/InfiniteGlass/build/env/bin/glass-config-init", line 11, in <module>
    load_entry_point('glass-config-init', 'console_scripts', 'glass-config-init')()
  File "/InfiniteGlass/glass-config-init/glass_config_init/__init__.py", line 29, in main
    copy_dir(
  File "/InfiniteGlass/glass-config-init/glass_config_init/__init__.py", line 24, in copy_dir
    with open(dstpath, "wb") as outf:
PermissionError: [Errno 13] Permission denied: '/home/glass/.config/glass/ghosts.yml'
Xlib.xauth: warning, failed to parse part of xauthority file /tmp/.docker.xauth, aborting all further parsing
Xlib.xauth: warning, no xauthority details available
Ghost manager systemic failure, restarting: [Errno 2] No such file or directory: '/home/glass/.config/glass/ghosts.yml'
Traceback (most recent call last):
  File "/InfiniteGlass/glass-ghosts/glass_ghosts/main.py", line 47, in main
    InfiniteGlass.DEBUG("init", "Session manager listening to %s\n" % manager.session.listen_address())
  File "/InfiniteGlass/glass-lib/InfiniteGlass/display.py", line 114, in display_exit
    raise exc
  File "/InfiniteGlass/glass-ghosts/glass_ghosts/main.py", line 44, in main
    manager = glass_ghosts.manager.GhostManager(display)
  File "/InfiniteGlass/glass-ghosts/glass_ghosts/manager.py", line 22, in __init__
    with open(configpath) as f:
FileNotFoundError: [Errno 2] No such file or directory: '/home/glass/.config/glass/ghosts.yml'
Xlib.xauth: warning, failed to parse part of xauthority file /tmp/.docker.xauth, aborting all further parsing
Xlib.xauth: warning, no xauthority details available
Ghost manager systemic failure, restarting: [Errno 2] No such file or directory: '/home/glass/.config/glass/ghosts.yml'
Traceback (most recent call last):
  File "/InfiniteGlass/glass-ghosts/glass_ghosts/main.py", line 47, in main
    InfiniteGlass.DEBUG("init", "Session manager listening to %s\n" % manager.session.listen_address())
  File "/InfiniteGlass/glass-lib/InfiniteGlass/display.py", line 114, in display_exit
    raise exc
  File "/InfiniteGlass/glass-ghosts/glass_ghosts/main.py", line 44, in main
    manager = glass_ghosts.manager.GhostManager(display)
  File "/InfiniteGlass/glass-ghosts/glass_ghosts/manager.py", line 22, in __init__
    with open(configpath) as f:
FileNotFoundError: [Errno 2] No such file or directory: '/home/glass/.config/glass/ghosts.yml'
Xlib.xauth: warning, failed to parse part of xauthority file /tmp/.docker.xauth, aborting all further parsing
Xlib.xauth: warning, no xauthority details available
Ghost manager systemic failure, restarting: [Errno 2] No such file or directory: '/home/glass/.config/glass/ghosts.yml'
Traceback (most recent call last):
  File "/InfiniteGlass/glass-ghosts/glass_ghosts/main.py", line 47, in main
    InfiniteGlass.DEBUG("init", "Session manager listening to %s\n" % manager.session.listen_address())
  File "/InfiniteGlass/glass-lib/InfiniteGlass/display.py", line 114, in display_exit
    raise exc
  File "/InfiniteGlass/glass-ghosts/glass_ghosts/main.py", line 44, in main
    manager = glass_ghosts.manager.GhostManager(display)
  File "/InfiniteGlass/glass-ghosts/glass_ghosts/manager.py", line 22, in __init__
    with open(configpath) as f:
FileNotFoundError: [Errno 2] No such file or directory: '/home/glass/.config/glass/ghosts.yml'
Xlib.xauth: warning, failed to parse part of xauthority file /tmp/.docker.xauth, aborting all further parsing
Xlib.xauth: warning, no xauthority details available
Ghost manager systemic failure, restarting: [Errno 2] No such file or directory: '/home/glass/.config/glass/ghosts.yml'
Traceback (most recent call last):
  File "/InfiniteGlass/glass-ghosts/glass_ghosts/main.py", line 47, in main
    InfiniteGlass.DEBUG("init", "Session manager listening to %s\n" % manager.session.listen_address())
  File "/InfiniteGlass/glass-lib/InfiniteGlass/display.py", line 114, in display_exit
    raise exc
  File "/InfiniteGlass/glass-ghosts/glass_ghosts/main.py", line 44, in main
    manager = glass_ghosts.manager.GhostManager(display)
  File "/InfiniteGlass/glass-ghosts/glass_ghosts/manager.py", line 22, in __init__
    with open(configpath) as f:
FileNotFoundError: [Errno 2] No such file or directory: '/home/glass/.config/glass/ghosts.yml'
^R
Xlib.xauth: warning, failed to parse part of xauthority file /tmp/.docker.xauth, aborting all further parsing
Xlib.xauth: warning, no xauthority details available
redhog commented 2 years ago

$DISPLAY handling correction pushed

redhog commented 2 years ago

PermissionError: [Errno 13] Permission denied: '/home/glass/.config/glass/ghosts.yml'

is really curious to me. This is inside the container, in a path on the container disk, not a mount, so this must be Podmans' doing, as it works under docker for me...

As for xhost + you should not need that, if the Xauthority actually parses. I think this is just a follow up error to the assumption that DISPLAY is :0. Try it w my new fix and see if that solves this.

IG does not run as root, see the su to user glass here: https://github.com/redhog/InfiniteGlass/blob/master/scripts/docker-runner.sh#L5 Only the shellscript runs as root at first, to be able to get the ip number of the machine and update /etc/hosts

IanTrudel commented 2 years ago

PermissionError: [Errno 13] Permission denied: '/home/glass/.config/glass/ghosts.yml'

is really curious to me. This is inside the container, in a path on the container disk, not a mount, so this must be Podmans' doing, as it works under docker for me...

Curious, indeed! I even attempted to set the volume as rw (and also Z) to make sure. I will do some tests with a simple container and see if anything interesting comes out.

As for xhost + you should not need that, if the Xauthority actually parses. I think this is just a follow up error to the assumption that DISPLAY is :0. Try it w my new fix and see if that solves this.

An improvement for sure. You were correct about xhost + and Xephyr opens up as expected.

IG does not run as root, see the su to user glass here: https://github.com/redhog/InfiniteGlass/blob/master/scripts/docker-runner.sh#L5 Only the shellscript runs as root at first, to be able to get the ip number of the machine and update /etc/hosts

This might be so but there are a few conflicting things, such as docker is run with --user id -u root and Python packages are installed as root, for which pip complains about. Those would be small things but it seems that more and more Linux software implements security features, for the best or for the worst.

My apologies for giving you such a stress test for InfiniteGlass. I am however willing to test whatever you ask me to. You should perhaps also consider giving a try to Arch Linux on a virtual machine and see if you can get InfiniteGlass working.

IanTrudel commented 2 years ago

The files in /home/glass/.config/, notice that glass is not owned by glass:users!

drwxr-xr-x 1 glass users  6 Aug  1 22:45 dconf
drwxr-xr-x 2 root  root  26 Aug  1 23:23 glass
drwxr-xr-x 1 glass users  6 Aug  1 22:45 session-state
redhog commented 2 years ago

Wait, /home isn't volume / mount?

Could you try to run this with docker using the makefile? As in make run-in-docker and compare?

I could pip install in a virtualenv, but this then does not simulate installing globally, as in, how it would have to work if it was your real desktop, and I like the docker image to test this functionality too...

redhog commented 2 years ago

It is awesome that you test stuff properly. I can try a VM with Arch :)

I'd just like for you to run things with docker the exact same way as me once and get that working so we have a baseline to compare to. Then we can see what differs from that...

redhog commented 2 years ago

Re not as root:

Docker does not set the real ip of the container as the ip for the hostname in /etc/hosts but we need that for X to work correctly.

So I do: echo "$(ip -4 addr show docker0 | grep -Po 'inet \K[\d.]+') $(hostname)" >> /etc/hosts

Which requires root. How can you get around that?

IanTrudel commented 2 years ago

Which requires root. How can you get around that?

We should consider using sudo for now. I have been reading the security and networking in rootless containers for podman but it's a long read. Alternatively, the value could be passed on docker run as environment variables.

Could you try to run this with docker using the makefile? As in make run-in-docker and compare?

I am using make run-in-docker!

I could pip install in a virtualenv, but this then does not simulate installing globally, as in, how it would have to work if it was your real desktop, and I like the docker image to test this functionality too...

This is an important question as to what kind of behaviour InfiniteGlass should have on a system installation. We should perhaps consider creating a shell-less (InfiniteGlass) glass user that would host the WM and add every user who has access to it to its group, thus allowing them to start InfiniteGlass in their session. Not anything unheard of, right?

Some interesting notes here: Do not run pip as root and pip safe.

redhog commented 2 years ago

Regarding the installation first: IG should install the same way other desktops or window managers install, that is, so that it is runnable by any user of the system. It should not run with other privileges than that user (having programs running as different users in the same X session is unsafe, and should really only be done if one of the two users is root). The python packages could still be installed in a virtualenv rather than globally, but for a package that itself is installed globally, this is wierd. However, this might be necessary, as not all python deps might exist as debian/rpm/whatever packages (this needs investigating when this is properly packaged). But regardless, they need to be installed so that any user can get to them. That means running pip as root, or changing the owner of the virtualenv after the fact to root.

redhog commented 2 years ago

I am using make run-in-docker! Hm, so what differs between my setup and yours? Is your docker command not the actual docker.io, but rather an alias for something similar but not the same (podman)?

redhog commented 2 years ago

Re IP: I'm not sure how you could pass it in as an env variable: the ip is assigned by docker when the container is created, so scripts on the host can not know this before starting the container... Sudo is possible, but then does not offer much of a difference from the current setup, except for more complex setup inside the container (sudoers file being correctly set up w/o password), and allowing root escalation (any command can be run as root using sudo at any time; currently, once privileges are dropped using su, there is no way to regain them from inside e.g. a terminal in the IG session).

IanTrudel commented 2 years ago

Regarding the installation first: IG should install the same way other desktops or window managers install, that is, so that it is runnable by any user of the system. It should not run with other privileges than that user (having programs running as different users in the same X session is unsafe, and should really only be done if one of the two users is root).

The idea is instead to create a group and setting group permission accordingly. A bit like sudo requires to be in the wheel group. However, this might not be necessary when you consider using venv. It would make things a whole lot easier when it comes to deployment; as you can imagine, dependencies.txt doesn't work on Arch (and many other distro).

A Virtual Environment will absolutely work as we would hope for:

9:54:52 root@machine Temp python -m pip install --upgrade pip
Requirement already satisfied: pip in /usr/lib/python3.10/site-packages (22.2.1)
WARNING: Running pip as the 'root' user can result in broken permissions and conflicting behaviour with the system package manager. It is recommended to use a virtual environment instead: https://pip.pypa.io/warnings/venv

9:55:07 root@machine Temp source bin/activate
(Temp) 9:55:30 root@machine Temp python -m pip install --upgrade pip
Requirement already satisfied: pip in ./lib/python3.10/site-packages (22.0.4)
Collecting pip
  Downloading pip-22.2.1-py3-none-any.whl (2.0 MB)
     ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 2.0/2.0 MB 11.4 MB/s eta 0:00:00
Installing collected packages: pip
  Attempting uninstall: pip
    Found existing installation: pip 22.0.4
    Uninstalling pip-22.0.4:
      Successfully uninstalled pip-22.0.4
Successfully installed pip-22.2.1
redhog commented 2 years ago

Re dependencies.txt: This is only a temporary measure until I / someone else has made a debian package. The same way, there should be an Arch package. Installing using Makefile directly is bad, but should be used by the build scripts for each distro to make their packages instead...

redhog commented 2 years ago

Do you have the list of arch packages needed by any chance / have you managed to run it natively / outside docker at all? If so, it would be awesome if you could add a dependencies.arch.txt with them!

IanTrudel commented 2 years ago

Re dependencies.txt: This is only a temporary measure until I / someone else has made a debian package. The same way, there should be an Arch package. Installing using Makefile directly is bad, but should be used by the build scripts for each distro to make their packages instead...

Shall we consider meson? It would allow us to define the dependencies clearly and it would output errors that people could understand in order to search and install the appropriate packages. It's part of the Python ecosystem, so it might be a good thing.

IanTrudel commented 2 years ago

We also used pkg-config on other projects, which might be helpful as well. It integrates well with meson and cmake. https://people.freedesktop.org/~dbn/pkg-config-guide.html

redhog commented 2 years ago

IG already uses pkg-config for the things that it can, see https://github.com/redhog/InfiniteGlass/blob/master/glass-renderer/Makefile#L2

If that integrates with meson then maybe that's a good idea too :) I'll read up on it!

redhog commented 2 years ago

Just had a look at meson, and here are my conclusions:

IanTrudel commented 2 years ago

For now, the references to pkg-config list in the Makefile are enough for me to play around.

Does not make distro packaging easier, it only replaces GNU Make. If it integrated with setup.py it could be useful, but it does not :(

What about the other way around? https://mesonbuild.com/Python-module.html

It is comparable to SCons, but uses it's own mini language instead of Python, making me think that SCons would be a better candidate, if I were to replace Make (esp since so much of IG is already written in Python).

I don't know about SCons but I can see the appeal. We should open an issue and investigate later on.

IanTrudel commented 2 years ago

Here is a Dockerfile using Arch Linux instead of Ubuntu. This is as minimalistic as possible and yet somewhat reflective of my machine configuration. https://gist.github.com/IanTrudel/21fe4f6f30874f6cf609403ab6909b42

IanTrudel commented 2 years ago

https://github.com/redhog/InfiniteGlass/blob/master/scripts/run-in-docker.sh#L30

-v /tmp/.docker.xauth:/tmp/.docker.xauth \ does not reflect the change in -e XAUTHORITY=/tmp/.docker.$DISPLAY.xauth \. It causes an error if you didn't already have an existing /tmp/.docker.xauth file on your host system.

redhog commented 2 years ago

Bugfixed in latest master

IanTrudel commented 2 years ago

Bugfixed in latest master

Did you push your commit? The last commit on master was 12 days ago.

redhog commented 2 years ago

Oups

IanTrudel commented 2 years ago

The change helps. I could use InfiniteGlass for a session — once — where I could do the things I remember from before. Zooming, moving around, rofi, tiling (worked well!), etc.

Any small changes to the build, however, is causing troubles. Even restarting the container is troublesome.

We should find a way to ensure compatibility amongst Linux distros. I have ran InfiniteGlass on 3 or 4 distros, so far, plus on macOS and it's been quite difficult despite the modest requirements.

We have three methods to run InfiniteGlass and each of them has its own challenges; some distro wouldn't allow one or another.

Let me know how I can assist you in this endeavour.

redhog commented 2 years ago

I think there are three different problems here:

Some solutions:

redhog commented 2 years ago

You can probably help with both Dockerfile and packaging for Arch as that's what you use? I will try to package for Debian & Ubuntu.

redhog commented 2 years ago

I have modded make run-in-docker to take an optional argument DOCKEROS=arch make run-in-docker to use Dockerfile.arch instead of Dockerfile.ubuntu.

IanTrudel commented 2 years ago

Yes, absolutely. I can prepare a few dockerfiles for Alpine, Arch and possibly a few more.

We should also test on those slim/minimal images since they are considerably trimmed down, forcing us to know our dependencies better.

We should add support for podman, so it will ensure a proper build. It does override docker and is mostly compatible but running a WM in docker is no small thing. The edit-build-run-debug cycle isn't too friendly right now.

I'm not sure that we need distro specific packages as long as anyone could clone this repo and configure and make. (Automake/autoconf?) It suggests that we need to do better for the diagnosis on missing packages, faulty configuration.

An AppImage would be helpful though. It usually contains all the dependencies. It could be running Xephyr. A better way to try out InfiniteGlass.

Overall, I think this exercise will help InfiniteGlass to be easier to install on any distro, find portability and stability.

IanTrudel commented 2 years ago

A bit of feedback since your last commit. InfiniteGlass is now starting consistently on docker (your image, not arch). It's however spewing a lot of miscellaneous errors such as ModuleNotFoundError: No module named 'gi' , cairo errors, sqlite3 errors, failed to parse xauthority, etc. I'm trying to reproduce the errors in a predictable manner to give you a better idea of what's going on, stay tuned.

Capture d’écran du 2022-08-18 11-16-23