diff --git a/nixos/doc/manual/release-notes/rl-2411.section.md b/nixos/doc/manual/release-notes/rl-2411.section.md index 1874a3b336f47..c9ce5f5fb9d5b 100644 --- a/nixos/doc/manual/release-notes/rl-2411.section.md +++ b/nixos/doc/manual/release-notes/rl-2411.section.md @@ -75,6 +75,8 @@ - [Cyrus IMAP](https://github.com/cyrusimap/cyrus-imapd), an email, contacts and calendar server. Available as [services.cyrus-imap](#opt-services.cyrus-imap.enable) service. +- [Schroot](), a lightweight virtualisation tool. Securely enter a chroot and run a command or login shell. Available as [programs.schroot](#opt-programs.schroot.enable). + - [TaskChampion Sync-Server](https://github.com/GothenburgBitFactory/taskchampion-sync-server), a [Taskwarrior 3](https://taskwarrior.org/docs/upgrade-3/) sync server, replacing Taskwarrior 2's sync server named [`taskserver`](https://github.com/GothenburgBitFactory/taskserver). - [FlareSolverr](https://github.com/FlareSolverr/FlareSolverr), proxy server to bypass Cloudflare protection. Available as [services.flaresolverr](#opt-services.flaresolverr.enable) service. diff --git a/nixos/modules/module-list.nix b/nixos/modules/module-list.nix index 98340036f7b64..e096b6b89b38e 100644 --- a/nixos/modules/module-list.nix +++ b/nixos/modules/module-list.nix @@ -277,6 +277,7 @@ ./programs/rust-motd.nix ./programs/ryzen-monitor-ng.nix ./programs/screen.nix + ./programs/schroot.nix ./programs/seahorse.nix ./programs/sedutil.nix ./programs/shadow.nix diff --git a/nixos/modules/programs/schroot.nix b/nixos/modules/programs/schroot.nix new file mode 100644 index 0000000000000..a185cff1248aa --- /dev/null +++ b/nixos/modules/programs/schroot.nix @@ -0,0 +1,137 @@ +{ + config, + lib, + pkgs, + ... +}: + +let + cfg = config.programs.schroot; + iniFmt = pkgs.formats.ini { }; +in +{ + options = { + programs.schroot = { + enable = lib.mkEnableOption "schroot, a lightweight virtualisation tool"; + package = lib.mkPackageOption pkgs "schroot" { }; + + settings = lib.mkOption { + type = iniFmt.type; + default = { }; + example = { + "noble" = { + type = "directory"; + description = "Ubuntu 24.04 Noble"; + directory = "/srv/chroot/noble"; + users = "my-user"; + root-users = "my-user"; + personality = "linux"; + preserve-environment = false; + profile = "my-profile"; + shell = "/bin/bash"; + }; + }; + description = '' + Schroot configuration settings. + For more details, see {manpage}`schroot.conf(5)`. + ''; + }; + + profiles = lib.mkOption { + type = lib.types.attrsOf ( + lib.types.submodule { + options = { + copyfiles = lib.mkOption { + type = lib.types.listOf lib.types.str; + example = [ "/etc/resolv.conf" ]; + description = "A list of files to copy into the chroot from the host system."; + }; + fstab = lib.mkOption { + type = lib.types.path; + example = lib.literalExpression '' + pkgs.writeText "my-schroot-fstab" ''' + /proc /proc none rw,bind 0 0 + /sys /sys none rw,bind 0 0 + /dev /dev none rw,bind 0 0 + /dev/pts /dev/pts none rw,bind 0 0 + /home /home none rw,rbind 0 0 + /tmp /tmp none rw,bind 0 0 + /dev/shm /dev/shm none rw,bind 0 0 + /nix /nix none ro,bind 0 0 + /run/current-system /run/current-system none rw,bind 0 0 + /run/wrappers /run/wrappers none rw,bind 0 0 + ''' + ''; + description = '' + A file in the format described in {manpage}`fstab(5)`, used to mount filesystems inside the chroot. + The mount location is relative to the root of the chroot. + ''; + }; + nssdatabases = lib.mkOption { + type = lib.types.listOf lib.types.str; + example = [ + "passwd" + "shadow" + "group" + "gshadow" + "services" + "protocols" + "networks" + "hosts" + ]; + description = '' + System databases (as described in /etc/nsswitch.conf on GNU/Linux systems) to copy into the chroot from the host. + ''; + }; + }; + } + ); + default = { }; + description = "Custom configuration profiles for schroot."; + }; + }; + }; + + config = lib.mkIf cfg.enable { + environment = { + systemPackages = [ cfg.package ]; + + etc = + { + # schroot requires this directory to exist + "schroot/chroot.d/.keep".text = ""; + + "schroot/schroot.conf".source = iniFmt.generate "schroot.conf" cfg.settings; + } + // (lib.attrsets.concatMapAttrs ( + name: + { + copyfiles, + fstab, + nssdatabases, + }: + { + "schroot/${name}/copyfiles".text = lib.strings.concatStringsSep "\n" copyfiles; + "schroot/${name}/fstab".source = fstab; + "schroot/${name}/nssdatabases".text = lib.strings.concatStringsSep "\n" nssdatabases; + } + ) cfg.profiles); + }; + + security.wrappers.schroot = { + source = "${cfg.package}/bin/schroot"; + owner = "root"; + group = "root"; + setuid = true; + }; + + # Schroot requires these directories to exist + systemd.tmpfiles.rules = [ + "d /var/lib/schroot/session - root root - -" + "d /var/lib/schroot/unpack - root root - -" + "d /var/lib/schroot/union - root root - -" + "d /var/lib/schroot/union/overlay - root root - -" + "d /var/lib/schroot/union/underlay - root root - -" + ]; + }; +}