WIP: Ly display manager minimal config

This is a reference commit and shall not be merger in master. This code is distributed
in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied
warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
Public License for more details.

This commit brings experimental support for using ly as a display manager.
Unfortunatelly, further support is needed from upstream before a proper merge request
can be issued against nixpkgs. Notably https://github.com/cylgom/ly/pull/137 must be
merged. Some other minor issues must be addresed in the submodules too.

From `nixos-config/machines/`, you can build and run a VM with xmonad by issuing the
following command (will delete any qcow2 images you may have under the same directory):

```
NIXOS_CONFIG="$(readlink -f test-ly.nix)" nixos-rebuild build-vm && (rm -fr *.qcow2 ||
true) && ./result/bin/run-*-vm -chardev stdio,mux=on,id=char0,signal=off -mon
chardev=char0,mode=readline -serial chardev:char0 -snapshot
```

user and password as described in test-ly.nix. Window manager is xmonad and the
default keybinding for spawning a shell is Alt+Shift+Return.
Signed-off-by: Roosemberth Palacios's avatarRoosembert Palacios <[email protected]>
parent 71cc88a6
{ config, pkgs, lib, ... }:
{
imports = [../modules];
boot.loader.grub.device = "nodev";
environment.systemPackages = (with pkgs; [ vim curl htop alacritty cacert ]);
fileSystems."/".device = "/dev/sda";
i18n.consoleFont = "sun12x22";
networking.hostName = "test-ly"; # Define your hostname.
security.pam.loginLimits = [{
domain = "*"; item = "core"; type = "-"; value = "-1";
}];
security.sudo.enable = true;
security.sudo.wheelNeedsPassword = false;
services.xserver = {
enable = true;
displayManager.ly.enable = true;
displayManager.ly.defaultUser = "roos";
displayManager.ly.defaultSessionIndex = 4;
windowManager.xmonad.enable = true;
windowManager.default = "xmonad";
desktopManager.default = "none";
};
services.journald.console = "/dev/ttyS0";
services.mingetty.autologinUser = "roos";
system.stateVersion = "19.09";
systemd.coredump.enable = true;
users.mutableUsers = false;
users.extraUsers.roos = {
password = "roos";
isNormalUser = true;
extraGroups = ["wheel" "tty" "video" "input"];
};
}
{ config, lib, pkgs, ... }:
with lib;
let
cfg = dmcfg.ly;
dmcfg = config.services.xserver.displayManager;
xcfg = config.services.xserver;
mk_save = cfg.defaultUser != null;
save_file = if ! mk_save then "" else pkgs.writeText "ly-prefs" ''
${cfg.defaultUser}
${toString cfg.defaultSessionIndex}
'';
lyConfig = pkgs.writeText "ly.cfg.ini" ''
load=${if mk_save then "true" else "false"}
mcookie_cmd=${pkgs.utillinux}/bin/mcookie
# An empty path variable will prevent ly from setting it
path=
restart_cmd=${pkgs.systemd}/bin/systemctl reboot
save=false
save_file=${save_file}
# service name (pam needs this set to login)
service_name=login
shutdown_cmd=${pkgs.systemd}/bin/systemctl poweroff
term_reset_cmd=${pkgs.ncurses6}/bin/tput reset
tty=${toString xcfg.tty}
# wayland setup command
#wayland_cmd=/etc/ly/wsetup.sh
# wayland desktop environments
#waylandsessions=/usr/share/wayland-sessions
x_cmd=${dmcfg.xserverBin} ${toString dmcfg.xserverArgs} -keeptty vt7 -verbose 2 -logfile /tmp/x11.log
x_cmd_setup=${dmcfg.session.wrapper}
xauth_cmd = ${dmcfg.xauthBin}
xsessions=${dmcfg.session.desktops}/share/xsessions
${cfg.extraConfig}
'';
lyPkg = pkgs.callPackage ../pkgs/ly {};
in
{
###### interface
options = {
services.xserver.displayManager.ly = {
enable = mkOption {
type = types.bool;
default = false;
description = ''
Whether to enable Ly as the display manager.
'';
};
defaultUser = mkOption {
type = types.nullOr types.str;
default = null;
example = "login";
description = ''
The default user to load. If you put a username here you
get it automatically loaded into the username field, and
the focus is placed on the password.
'';
};
defaultSessionIndex = mkOption {
type = lib.types.ints.unsigned;
default = 0;
example = 1;
description = ''
Index of the default session to load. This session will be
preselected.
'';
};
extraConfig = mkOption {
type = types.lines;
default = "";
description = ''
Extra configuration options for SLiM login manager. Do not
add options that can be configured directly.
'';
};
package = mkOption {
default = lyPkg;
description = "ly package to use.";
};
};
};
###### implementation
config = mkIf cfg.enable {
services.xserver = {
displayManager.job.execCmd = "exec ${lyPkg}/bin/ly -c ${lyConfig}";
displayManager.lightdm.enable = lib.mkForce false;
};
systemd.services.display-manager.serviceConfig = {
Type = "idle";
After = ["systemd-user-sessions.service" "plymouth-quit-wait.service" "[email protected]${toString xcfg.tty}.service"];
StandardInput = "tty";
TTYPath = "/dev/tty${toString xcfg.tty}";
TTYReset = true;
TTYVHangup = true;
};
};
}
From 757ec5221717a337c439e0de94bcbf7c1923c890 Mon Sep 17 00:00:00 2001
From: Roosembert Palacios <[email protected]>
Date: Sun, 22 Dec 2019 20:24:13 +0100
Subject: [PATCH 1/6] login.c: fix minor out of bound strncpy
Signed-off-by: Roosembert Palacios <[email protected]>
---
src/login.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/src/login.c b/src/login.c
index 11cd938..ee3b978 100644
--- a/src/login.c
+++ b/src/login.c
@@ -431,7 +431,7 @@ void shell(struct passwd* pwd)
pos = pwd->pw_shell;
}
- strncpy(args + 1, pos, 1024);
+ strncpy(args + 1, pos, 1023);
execl(pwd->pw_shell, args, NULL);
}
@@ -671,4 +671,4 @@ void auth(
{
pam_diagnose(ok, buf);
}
-}
\ No newline at end of file
+}
--
2.23.1
From 28b094febbce600cf70c3ce928754f217347d98c Mon Sep 17 00:00:00 2001
From: Roosembert Palacios <[email protected]>
Date: Sat, 26 Oct 2019 09:14:25 +0200
Subject: [PATCH 2/6] login.c: Move XDG initialization before opening the pam
session
As per https://www.freedesktop.org/wiki/Software/systemd/writing-display-managers/,
in order for logind to register the display manager and session using pam_systemd
(https://www.freedesktop.org/software/systemd/man/pam_systemd.html), the corresponding
XDG variables must be set prior to opening the pam session.
This change has no effect if the system is not configured to use pam_systemd.
Signed-off-by: Roosembert Palacios <[email protected]>
---
src/login.c | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/src/login.c b/src/login.c
index ee3b978..f4041ef 100644
--- a/src/login.c
+++ b/src/login.c
@@ -465,6 +465,8 @@ void auth(
const char* creds[2] = {login->text, password->text};
struct pam_conv conv = {login_conv, creds};
struct pam_handle* handle;
+ char tty_id [3];
+ snprintf(tty_id, 3, "%d", config.tty);
ok = pam_start(config.service_name, NULL, &conv, &handle);
@@ -496,6 +498,8 @@ void auth(
return;
}
+ // Set XDG variables to that pam_systemd can open the correct session type
+ env_xdg(tty_id, desktop->display_server[desktop->cur]);
ok = pam_do(pam_open_session, handle, 0, buf);
if (ok != PAM_SUCCESS)
@@ -571,11 +575,9 @@ void auth(
// get a display
int display_id = get_free_display();
char display_name[3];
- char tty_id [3];
char vt[5];
snprintf(display_name, 3, ":%d", display_id);
- snprintf(tty_id, 3, "%d", config.tty);
snprintf(vt, 5, "vt%d", config.tty);
// set env
@@ -594,8 +596,6 @@ void auth(
putenv(env[i]);
}
- // add xdg variables
- env_xdg(tty_id, desktop->display_server[desktop->cur]);
// execute
int ok = chdir(pwd->pw_dir);
--
2.23.1
From 8c6f0526ae45f5237f31ed25179b3129d7487f72 Mon Sep 17 00:00:00 2001
From: Roosembert Palacios <[email protected]>
Date: Sat, 26 Oct 2019 12:58:14 +0200
Subject: [PATCH 3/6] login.c: fix several `-Werror=format-truncation`
Signed-off-by: Roosembert Palacios <[email protected]>
---
src/login.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/src/login.c b/src/login.c
index f4041ef..cc7c797 100644
--- a/src/login.c
+++ b/src/login.c
@@ -466,7 +466,7 @@ void auth(
struct pam_conv conv = {login_conv, creds};
struct pam_handle* handle;
char tty_id [3];
- snprintf(tty_id, 3, "%d", config.tty);
+ snprintf(tty_id, 3, "%d", (unsigned int)config.tty % 99);
ok = pam_start(config.service_name, NULL, &conv, &handle);
@@ -578,7 +578,7 @@ void auth(
char vt[5];
snprintf(display_name, 3, ":%d", display_id);
- snprintf(vt, 5, "vt%d", config.tty);
+ snprintf(vt, 5, "vt%d", (unsigned int)config.tty % 99);
// set env
env_init(pwd, display_name);
--
2.23.1
From 9b1123fc772186c826d8bb6411caba0bd54d18c7 Mon Sep 17 00:00:00 2001
From: Roosembert Palacios <[email protected]>
Date: Sun, 22 Dec 2019 20:26:35 +0100
Subject: [PATCH 4/6] login.c: remove useless indentation on empty lines
Signed-off-by: Roosembert Palacios <[email protected]>
---
src/login.c | 10 +++++-----
1 file changed, 5 insertions(+), 5 deletions(-)
diff --git a/src/login.c b/src/login.c
index cc7c797..fa1d2fc 100644
--- a/src/login.c
+++ b/src/login.c
@@ -526,7 +526,7 @@ void auth(
if (pwd->pw_shell[0] == '\0')
{
setusershell();
-
+
char* shell = getusershell();
if (shell != NULL)
@@ -547,7 +547,7 @@ void auth(
if (pid == 0)
{
- // set user info
+ // set user info
ok = initgroups(pwd->pw_name, pwd->pw_gid);
if (ok != 0)
@@ -652,21 +652,21 @@ void auth(
// close pam session
ok = pam_do(pam_close_session, handle, 0, buf);
-
+
if (ok != PAM_SUCCESS)
{
return;
}
ok = pam_do(pam_setcred, handle, PAM_DELETE_CRED, buf);
-
+
if (ok != PAM_SUCCESS)
{
return;
}
ok = pam_end(handle, 0);
-
+
if (ok != PAM_SUCCESS)
{
pam_diagnose(ok, buf);
--
2.23.1
From 3fd81b5f6d0b3145c016da7884f57f14c1fa4108 Mon Sep 17 00:00:00 2001
From: Roosembert Palacios <[email protected]>
Date: Sun, 27 Oct 2019 17:25:10 +0100
Subject: [PATCH 5/6] login.c: Initialize the environment before setting XDG
and the pam session
Signed-off-by: Roosembert Palacios <[email protected]>
---
src/login.c | 40 +++++++++++++++++++---------------------
1 file changed, 19 insertions(+), 21 deletions(-)
diff --git a/src/login.c b/src/login.c
index fa1d2fc..ace4e68 100644
--- a/src/login.c
+++ b/src/login.c
@@ -498,6 +498,23 @@ void auth(
return;
}
+ // get passwd structure
+ struct passwd* pwd = getpwnam(login->text);
+ endpwent();
+
+ // get a display
+ int display_id = get_free_display();
+ char display_name[3];
+ snprintf(display_name, 3, ":%d", display_id);
+
+ // set env
+ env_init(pwd, display_name);
+
+ if (dgn_catch())
+ {
+ exit(EXIT_FAILURE);
+ }
+
// Set XDG variables to that pam_systemd can open the correct session type
env_xdg(tty_id, desktop->display_server[desktop->cur]);
ok = pam_do(pam_open_session, handle, 0, buf);
@@ -511,10 +528,6 @@ void auth(
input_text_free(password);
input_text(password, config.max_password_len);
- // get passwd structure
- struct passwd* pwd = getpwnam(login->text);
- endpwent();
-
if (pwd == NULL)
{
dgn_throw(DGN_PWNAM);
@@ -572,22 +585,6 @@ void auth(
exit(EXIT_FAILURE);
}
- // get a display
- int display_id = get_free_display();
- char display_name[3];
- char vt[5];
-
- snprintf(display_name, 3, ":%d", display_id);
- snprintf(vt, 5, "vt%d", (unsigned int)config.tty % 99);
-
- // set env
- env_init(pwd, display_name);
-
- if (dgn_catch())
- {
- exit(EXIT_FAILURE);
- }
-
// add pam variables
char** env = pam_getenvlist(handle);
@@ -596,7 +593,6 @@ void auth(
putenv(env[i]);
}
-
// execute
int ok = chdir(pwd->pw_dir);
@@ -622,6 +618,8 @@ void auth(
case DS_XINITRC:
case DS_XORG:
{
+ char vt[5];
+ snprintf(vt, 5, "vt%d", (unsigned int)config.tty % 99);
xorg(pwd, display_name, vt, desktop->cmd[desktop->cur]);
break;
}
--
2.23.1
From 520a2097fd20e2330683841fa7429311b4a44317 Mon Sep 17 00:00:00 2001
From: Roosembert Palacios <[email protected]>
Date: Sun, 27 Oct 2019 17:20:57 +0100
Subject: [PATCH 6/6] login.c: Do not clear the environment upon init
Signed-off-by: Roosembert Palacios <[email protected]>
---
src/login.c | 11 +----------
1 file changed, 1 insertion(+), 10 deletions(-)
diff --git a/src/login.c b/src/login.c
index ace4e68..ea89172 100644
--- a/src/login.c
+++ b/src/login.c
@@ -207,17 +207,9 @@ void pam_diagnose(int error, struct term_buf* buf)
void env_init(struct passwd* pwd, const char* display_name)
{
- extern char** environ;
char* term = getenv("TERM");
- char* lang = getenv("LANG");
- // clean env
- environ[0] = NULL;
- if (term != NULL)
- {
- setenv("TERM", term, 1);
- }
- else
+ if (term == NULL)
{
setenv("TERM", "linux", 1);
}
@@ -228,7 +220,6 @@ void env_init(struct passwd* pwd, const char* display_name)
setenv("USER", pwd->pw_name, 1);
setenv("LOGNAME", pwd->pw_name, 1);
setenv("DISPLAY", display_name, 1);
- setenv("LANG", lang, 1);
// Set PATH if specified in the configuration
if (strlen(config.path))
--
2.23.1
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Roosembert Palacios <[email protected]>
Date: Mon, 13 Jan 2020 14:27:10 +0100
Subject: [PATCH 1/1] Termbox: Add assert on fn with warn_unused_result call
Signed-off-by: Roosembert Palacios <[email protected]>
---
diff --git a/sub/termbox_next/src/memstream.c b/sub/termbox_next/src/memstream.c
index d218b54..482e77d 100644
--- a/sub/termbox_next/src/memstream.c
+++ b/sub/termbox_next/src/memstream.c
@@ -1,3 +1,4 @@
+#include <assert.h>
#include <string.h>
#include <stdio.h>
#include <unistd.h>
@@ -13,7 +14,7 @@ void memstream_init(struct memstream* s, int fd, void* buffer, size_t len)
void memstream_flush(struct memstream* s)
{
- write(s->file, s->data, s->pos);
+ assert(write(s->file, s->data, s->pos) != -1);
s->pos = 0;
}
diff --git a/sub/termbox_next/src/termbox.c b/sub/termbox_next/src/termbox.c
index 72a4335..2d0ebc2 100644
--- a/sub/termbox_next/src/termbox.c
+++ b/sub/termbox_next/src/termbox.c
@@ -777,7 +777,7 @@ static void sigwinch_handler(int xxx)
{
(void) xxx;
const int zzz = 1;
- write(winch_fds[1], &zzz, sizeof(int));
+ assert(write(winch_fds[1], &zzz, sizeof(int)) != -1);
}
static void update_size(void)
@@ -876,7 +876,7 @@ static int wait_fill_event(struct tb_event* event, struct timeval* timeout)
{
event->type = TB_EVENT_RESIZE;
int zzz = 0;
- read(winch_fds[0], &zzz, sizeof(int));
+ assert(read(winch_fds[0], &zzz, sizeof(int)) != -1);
buffer_size_change_request = 1;
get_term_size(&event->w, &event->h);
return TB_EVENT_RESIZE;
{ stdenv
, fetchFromGitHub
, linux-pam
, xlibs
, lib
}:
stdenv.mkDerivation rec {
pname = "ly";
version = "0.4.0-git";
# This does not work, .gitmodules is not in the correct location, see
# https://github.com/cylgom/ly/blob/master/makefile#L110
#src = fetchFromGitHub {
# owner = "cylgom";
# repo = "ly";
# fetchSubmodules = true;
# rev = "aaa34e09da646ed241cae649adecd05ff879bbe7";
# sha256 = lib.fakeSha256;
#};
# Impure build, because I don't have the time to manually package the submodules.
src = assert (lib.assertMsg (lib.pathIsDirectory /tmp/ly)
"Impure source of ly not found. Please clone ly and its submodules\"
\"as specified in the project readme under /tmp/ly."
); /tmp/ly;
patches = [
./0001-login.c-fix-minor-out-of-bound-strncpy.patch
./0002-login.c-Move-XDG-initialization-before-opening-the-p.patch
./0003-login.c-fix-several-Werror-format-truncation.patch
./0004-login.c-remove-useless-indentation-on-empty-lines.patch
./0005-login.c-Initialize-the-environment-before-setting-XD.patch
./0006-login.c-Do-not-clear-the-environment-upon-init.patch
./0007-termbox-add-missing-assert-statements.patch
];
#src = ../tmp/ly;
makeFlags = [ "DESTDIR=$(out)" "DATADIR=$(out)/lib/ly" ];
postInstall = ''
mv $out/usr/bin $out/bin
'';
buildInputs = [ linux-pam xlibs.libxcb ];
postPatch = ''
substituteInPlace sub/configator/src/configator.h --replace \
"#define CONFIGATOR_MAX_LINE 80" \
"#define CONFIGATOR_MAX_LINE 500"
'';
}
Markdown is supported
0% or