From e5f5ef0d17ca5191b5014781942eb747dbff012d Mon Sep 17 00:00:00 2001 From: Jonas Strassel Date: Wed, 27 Oct 2021 23:08:18 +0200 Subject: [PATCH 1/9] feat(greetd): add greetd to displaymanagers --- .../displaymanager/displaymanager.conf | 1 + .../displaymanager/displaymanager.schema.yaml | 2 +- src/modules/displaymanager/main.py | 70 ++++++++++++++++++- 3 files changed, 71 insertions(+), 2 deletions(-) diff --git a/src/modules/displaymanager/displaymanager.conf b/src/modules/displaymanager/displaymanager.conf index 7175c112d..0fd2af163 100644 --- a/src/modules/displaymanager/displaymanager.conf +++ b/src/modules/displaymanager/displaymanager.conf @@ -23,6 +23,7 @@ displaymanagers: - mdm - lxdm - kdm + - greetd # Enable the following settings to force a desktop environment # in your displaymanager configuration file. This will attempt diff --git a/src/modules/displaymanager/displaymanager.schema.yaml b/src/modules/displaymanager/displaymanager.schema.yaml index fc28fd66d..89d657a3b 100644 --- a/src/modules/displaymanager/displaymanager.schema.yaml +++ b/src/modules/displaymanager/displaymanager.schema.yaml @@ -10,7 +10,7 @@ properties: type: array items: type: string - enum: [slim, sddm, lightdm, gdm, mdm, lxdm, kdm] + enum: [slim, sddm, lightdm, gdm, mdm, lxdm, kdm, greetd] minItems: 1 # Must be non-empty, if present at all defaultDesktopEnvironment: type: object diff --git a/src/modules/displaymanager/main.py b/src/modules/displaymanager/main.py index 5fb228682..1fd6a26ca 100644 --- a/src/modules/displaymanager/main.py +++ b/src/modules/displaymanager/main.py @@ -17,7 +17,7 @@ import abc import os -import re +import toml import libcalamares import configparser @@ -835,6 +835,74 @@ class DMsddm(DisplayManager): pass +class DMgreetd(DisplayManager): + name = "greetd" + executable = "greetd" + config_data = {} + + def os_path(self, path): + return os.path.join(self.root_mount_point, path) + + def config_path(self): + return self.os_path("etc/greetd/config.toml") + + def environments_path(self): + return self.os_path("etc/greetd/environments") + + def config_load(self): + self.config_data = toml.loads(self.config_path()) + + def config_write(self): + toml.dump(self.config_data, self.config_path()) + + def basic_setup(self): + if libcalamares.utils.target_env_call( + ['getent', 'group', 'greetd'] + ) != 0: + libcalamares.utils.target_env_call( + ['groupadd', 'greetd'] + ) + + if libcalamares.utils.target_env_call( + ['getent', 'passwd', 'greeter'] + ) != 0: + libcalamares.utils.target_env_call( + ['useradd', + '-c', '"Greeter User"', + '-g', 'greetd', + '-s', '/bin/bash', + 'greeter' + ] + ) + self.config_load() + self.config_data['terminal']['vt'] = "next" + self.config_write() + + def desktop_environment_setup(self, default_desktop_environment): + with open(self.environments_path(), 'w') as envs_file: + envs_file.write(default_desktop_environment) + + def greeter_setup(self): + pass + + def set_autologin(self, username, do_autologin, default_desktop_environment): + self.config_load() + + if (os.path.exists(self.os_path("usr/bin/tuigreet"))): + tuigreet_base_cmd = "tuigreet --remember --time --issue --asterisks --cmd " + self.config_data['default_session']['command'] = tuigreet_base_cmd + default_desktop_environment + else: + print("no greeter detected") + + if (do_autologin == True): + self.config_data['initial_session'] = {} + self.config_data['initial_session']['command'] = default_desktop_environment + self.config_data['initial_session']['user'] = username + + self.config_write() + + + class DMsysconfig(DisplayManager): name = "sysconfig" executable = None From fbdb9e6779ecb3dff0d29e22d3c9e945fc25f41c Mon Sep 17 00:00:00 2001 From: Jonas Strassel Date: Thu, 28 Oct 2021 08:14:04 +0200 Subject: [PATCH 2/9] feat(greetd): add more greeter fallbacks --- src/modules/displaymanager/main.py | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/src/modules/displaymanager/main.py b/src/modules/displaymanager/main.py index 1fd6a26ca..cf918ce5c 100644 --- a/src/modules/displaymanager/main.py +++ b/src/modules/displaymanager/main.py @@ -844,13 +844,17 @@ class DMgreetd(DisplayManager): return os.path.join(self.root_mount_point, path) def config_path(self): - return self.os_path("etc/greetd/config.toml") + path = self.os_path("etc/greetd/config.toml") + if not os.path.exists(path): + open(path, 'a').close() + return path def environments_path(self): return self.os_path("etc/greetd/environments") def config_load(self): self.config_data = toml.loads(self.config_path()) + return self.config_data def config_write(self): toml.dump(self.config_data, self.config_path()) @@ -888,13 +892,17 @@ class DMgreetd(DisplayManager): def set_autologin(self, username, do_autologin, default_desktop_environment): self.config_load() - if (os.path.exists(self.os_path("usr/bin/tuigreet"))): + if os.path.exists(self.os_path("usr/bin/gtkgreed") and os.path.exists(self.os_path("usr/bin/cage")): + self.config_data['default_session']['command'] = "cage gtkgreet" + elif os.path.exists(self.os_path("usr/bin/tuigreet")): tuigreet_base_cmd = "tuigreet --remember --time --issue --asterisks --cmd " self.config_data['default_session']['command'] = tuigreet_base_cmd + default_desktop_environment + elif os.path.exists(self.os_path("usr/bin/ddlm")): + self.config_data['default_session']['command'] = "ddlm --target sway" else: - print("no greeter detected") + self.config_data['default_session']['command'] = "agreety --cmd " + default_desktop_environment - if (do_autologin == True): + if do_autologin == True: self.config_data['initial_session'] = {} self.config_data['initial_session']['command'] = default_desktop_environment self.config_data['initial_session']['user'] = username From 57019378838fcf570ee85a2acf23e48f0577dfad Mon Sep 17 00:00:00 2001 From: Jonas Strassel Date: Thu, 28 Oct 2021 09:06:35 +0200 Subject: [PATCH 3/9] fix(greetd): deal with no existing config --- src/modules/displaymanager/main.py | 42 ++++++++++++++++-------------- 1 file changed, 22 insertions(+), 20 deletions(-) diff --git a/src/modules/displaymanager/main.py b/src/modules/displaymanager/main.py index cf918ce5c..2fc4bead1 100644 --- a/src/modules/displaymanager/main.py +++ b/src/modules/displaymanager/main.py @@ -838,22 +838,30 @@ class DMsddm(DisplayManager): class DMgreetd(DisplayManager): name = "greetd" executable = "greetd" + greeter_user = "greeter" + greeter_group = "greetd" config_data = {} def os_path(self, path): return os.path.join(self.root_mount_point, path) def config_path(self): - path = self.os_path("etc/greetd/config.toml") - if not os.path.exists(path): - open(path, 'a').close() - return path + return self.os_path("etc/greetd/config.toml") def environments_path(self): return self.os_path("etc/greetd/environments") def config_load(self): - self.config_data = toml.loads(self.config_path()) + if (os.path.exists(self.config_path)): + self.config_data = toml.loads(self.config_path()) + + self.config_data['terminal'] = dict(vt = "next") + + if not os.path.exists(self.config_data['default_session']): + self.config_data['default_session'] = {} + + self.config_data['default_session']['user'] = self.greeter_user + return self.config_data def config_write(self): @@ -861,26 +869,23 @@ class DMgreetd(DisplayManager): def basic_setup(self): if libcalamares.utils.target_env_call( - ['getent', 'group', 'greetd'] + ['getent', 'group', self.greeter_group] ) != 0: libcalamares.utils.target_env_call( - ['groupadd', 'greetd'] + ['groupadd', self.greeter_group] ) if libcalamares.utils.target_env_call( - ['getent', 'passwd', 'greeter'] + ['getent', 'passwd', self.greeter_user] ) != 0: libcalamares.utils.target_env_call( ['useradd', '-c', '"Greeter User"', - '-g', 'greetd', + '-g', self.greeter_group, '-s', '/bin/bash', - 'greeter' + self.greeter_user ] ) - self.config_load() - self.config_data['terminal']['vt'] = "next" - self.config_write() def desktop_environment_setup(self, default_desktop_environment): with open(self.environments_path(), 'w') as envs_file: @@ -892,25 +897,22 @@ class DMgreetd(DisplayManager): def set_autologin(self, username, do_autologin, default_desktop_environment): self.config_load() - if os.path.exists(self.os_path("usr/bin/gtkgreed") and os.path.exists(self.os_path("usr/bin/cage")): - self.config_data['default_session']['command'] = "cage gtkgreet" + if os.path.exists(self.os_path("usr/bin/gtkgreed")) and os.path.exists(self.os_path("usr/bin/cage")): + self.config_data['default_session']['command'] = "cage -s -- gtkgreet" elif os.path.exists(self.os_path("usr/bin/tuigreet")): tuigreet_base_cmd = "tuigreet --remember --time --issue --asterisks --cmd " self.config_data['default_session']['command'] = tuigreet_base_cmd + default_desktop_environment elif os.path.exists(self.os_path("usr/bin/ddlm")): - self.config_data['default_session']['command'] = "ddlm --target sway" + self.config_data['default_session']['command'] = "ddlm --target " + default_desktop_environment else: self.config_data['default_session']['command'] = "agreety --cmd " + default_desktop_environment if do_autologin == True: - self.config_data['initial_session'] = {} - self.config_data['initial_session']['command'] = default_desktop_environment - self.config_data['initial_session']['user'] = username + self.config_data['initial_session'] = dict(command = default_desktop_environment, user = username) self.config_write() - class DMsysconfig(DisplayManager): name = "sysconfig" executable = None From 85f36c77b1cf066a0a6566b114a9de2ec9c819e4 Mon Sep 17 00:00:00 2001 From: Adriaan de Groot Date: Mon, 15 Nov 2021 11:42:25 +0100 Subject: [PATCH 4/9] [displaymanager] Import configparser only for the DMs that actually need it --- src/modules/displaymanager/main.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/modules/displaymanager/main.py b/src/modules/displaymanager/main.py index 2fc4bead1..a85781c7b 100644 --- a/src/modules/displaymanager/main.py +++ b/src/modules/displaymanager/main.py @@ -19,7 +19,6 @@ import abc import os import toml import libcalamares -import configparser from libcalamares.utils import gettext_path, gettext_languages @@ -796,6 +795,8 @@ class DMsddm(DisplayManager): executable = "sddm" def set_autologin(self, username, do_autologin, default_desktop_environment): + import configparser + # Systems with Sddm as Desktop Manager sddm_conf_path = os.path.join(self.root_mount_point, "etc/sddm.conf") From 58cf9ffeeb6622dd8aa699d20f801f1bee42661c Mon Sep 17 00:00:00 2001 From: Adriaan de Groot Date: Mon, 15 Nov 2021 11:43:47 +0100 Subject: [PATCH 5/9] [displaymanager] Import toml only for the DMs that actually need it --- src/modules/displaymanager/main.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/modules/displaymanager/main.py b/src/modules/displaymanager/main.py index a85781c7b..287e4cc6b 100644 --- a/src/modules/displaymanager/main.py +++ b/src/modules/displaymanager/main.py @@ -17,7 +17,6 @@ import abc import os -import toml import libcalamares from libcalamares.utils import gettext_path, gettext_languages @@ -853,6 +852,8 @@ class DMgreetd(DisplayManager): return self.os_path("etc/greetd/environments") def config_load(self): + import toml + if (os.path.exists(self.config_path)): self.config_data = toml.loads(self.config_path()) @@ -866,6 +867,7 @@ class DMgreetd(DisplayManager): return self.config_data def config_write(self): + import toml toml.dump(self.config_data, self.config_path()) def basic_setup(self): From fad2f6ea887b669423643b43bcf85aed785ad31c Mon Sep 17 00:00:00 2001 From: Adriaan de Groot Date: Mon, 15 Nov 2021 11:52:24 +0100 Subject: [PATCH 6/9] [displaymanager] Add simple test --- src/modules/displaymanager/tests/1.global | 3 +++ 1 file changed, 3 insertions(+) create mode 100644 src/modules/displaymanager/tests/1.global diff --git a/src/modules/displaymanager/tests/1.global b/src/modules/displaymanager/tests/1.global new file mode 100644 index 000000000..9b3f0ea7c --- /dev/null +++ b/src/modules/displaymanager/tests/1.global @@ -0,0 +1,3 @@ +# SPDX-FileCopyrightText: no +# SPDX-License-Identifier: CC0-1.0 +rootMountPoint: / From 11424195ef7932e62901a984f3e53cf8ba21c097 Mon Sep 17 00:00:00 2001 From: Adriaan de Groot Date: Mon, 15 Nov 2021 12:06:05 +0100 Subject: [PATCH 7/9] [displaymanager] Missing method call - Add `()` to call the config_path() method, because we need a path to pass to os.path.exists(). --- src/modules/displaymanager/main.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/modules/displaymanager/main.py b/src/modules/displaymanager/main.py index 287e4cc6b..d9832730b 100644 --- a/src/modules/displaymanager/main.py +++ b/src/modules/displaymanager/main.py @@ -854,7 +854,7 @@ class DMgreetd(DisplayManager): def config_load(self): import toml - if (os.path.exists(self.config_path)): + if (os.path.exists(self.config_path())): self.config_data = toml.loads(self.config_path()) self.config_data['terminal'] = dict(vt = "next") From 54fd81a87e2265c1eaeeae12cacbcd4d5b065ac2 Mon Sep 17 00:00:00 2001 From: Adriaan de Groot Date: Mon, 15 Nov 2021 12:07:59 +0100 Subject: [PATCH 8/9] [displaymanager] Handle case where config file doesn't exist or has no key - If the config file doesn't exist, the dictionary is empty - If it **does** exist, it might not have key 'default_session' in it Either case should avoid a KeyError by using get() (or setdefault, in this context). Subsequent use of os.path.exists() is strange, since the value is a **group** (e.g. a dictionary) in the config file. Just check if it exists, and then fill something in. --- src/modules/displaymanager/main.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/modules/displaymanager/main.py b/src/modules/displaymanager/main.py index d9832730b..5b92ccf8d 100644 --- a/src/modules/displaymanager/main.py +++ b/src/modules/displaymanager/main.py @@ -859,7 +859,8 @@ class DMgreetd(DisplayManager): self.config_data['terminal'] = dict(vt = "next") - if not os.path.exists(self.config_data['default_session']): + default_session_group = self.config_data.get('default_session', None) + if not default_session_group: self.config_data['default_session'] = {} self.config_data['default_session']['user'] = self.greeter_user From ce6aec158a1da66e0e1cc5c60c6d95a2193d8eed Mon Sep 17 00:00:00 2001 From: Adriaan de Groot Date: Mon, 15 Nov 2021 12:11:53 +0100 Subject: [PATCH 9/9] [displaymanager] Fix config loading-and-saving - toml.dump() takes a file-like object - toml.loads() takes a whole string to parse, (e.g. the TOML data), not a pathname, so change to toml.load() which takes a file-like object. --- src/modules/displaymanager/main.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/modules/displaymanager/main.py b/src/modules/displaymanager/main.py index 5b92ccf8d..3219e803f 100644 --- a/src/modules/displaymanager/main.py +++ b/src/modules/displaymanager/main.py @@ -855,7 +855,8 @@ class DMgreetd(DisplayManager): import toml if (os.path.exists(self.config_path())): - self.config_data = toml.loads(self.config_path()) + with open(self.config_path(), "r") as f: + self.config_data = toml.load(f) self.config_data['terminal'] = dict(vt = "next") @@ -869,7 +870,8 @@ class DMgreetd(DisplayManager): def config_write(self): import toml - toml.dump(self.config_data, self.config_path()) + with open(self.config_path(), "w") as f: + toml.dump(self.config_data, f) def basic_setup(self): if libcalamares.utils.target_env_call(