From d58732961540ccbf7f78753a60888814c07f530b Mon Sep 17 00:00:00 2001 From: Eelco Dolstra Date: Fri, 20 Apr 2012 12:55:09 +0000 Subject: [PATCH] * Turn users.extraGroups into an attribute set (using types.loaOf). Also the gid is looked up in ids.gids if not specified. svn path=/nixos/trunk/; revision=33860 --- modules/config/users-groups.nix | 138 +++++++++++++++----------------- tests/misc.nix | 7 ++ 2 files changed, 73 insertions(+), 72 deletions(-) diff --git a/modules/config/users-groups.nix b/modules/config/users-groups.nix index ea71562e313..6c54222537a 100644 --- a/modules/config/users-groups.nix +++ b/modules/config/users-groups.nix @@ -7,64 +7,75 @@ let ids = config.ids; users = config.users; - userOpts = {name, config, ...}: - - { + userOpts = { name, config, ... }: { + options = { + name = mkOption { type = with types; uniq string; description = "The name of the user account. If undefined, the name of the attribute set will be used."; }; + description = mkOption { type = with types; uniq string; default = ""; description = "A short description of the user account."; }; + uid = mkOption { type = with types; uniq (nullOr int); default = null; - description = "The account UID. If undefined, NixOS will select a UID."; + description = "The account UID. If undefined, NixOS will select a free UID."; }; + group = mkOption { type = with types; uniq string; default = "nogroup"; description = "The user's primary group."; }; + extraGroups = mkOption { type = types.listOf types.string; default = []; description = "The user's auxiliary groups."; }; + home = mkOption { type = with types; uniq string; default = "/var/empty"; description = "The user's home directory."; }; + shell = mkOption { type = with types; uniq string; default = "/noshell"; description = "The path to the user's shell."; }; + createHome = mkOption { type = types.bool; default = false; description = "If true, the home directory will be created automatically."; }; + useDefaultShell = mkOption { type = types.bool; default = false; description = "If true, the user's shell will be set to users.defaultUserShell."; }; + password = mkOption { type = with types; uniq (nullOr string); default = null; description = "The user's password. If undefined, no password is set for the user. Warning: do not set confidential information here because this data would be readable by all. This option should only be used for public account such as guest."; }; + isSystemUser = mkOption { type = types.bool; default = true; description = "Indicates if the user is a system user or not."; }; + createUser = mkOption { type = types.bool; default = true; @@ -74,6 +85,7 @@ let then not modify any of the basic properties for the user account. "; }; + }; config = { @@ -81,71 +93,32 @@ let uid = mkDefault (attrByPath [name] null ids.uids); shell = mkIf config.useDefaultShell (mkDefault users.defaultUserShell); }; + }; - # Groups to be created/updated by NixOS. - groups = - let - defaultGroups = - [ { name = "root"; - gid = ids.gids.root; - } - { name = "wheel"; - gid = ids.gids.wheel; - } - { name = "disk"; - gid = ids.gids.disk; - } - { name = "kmem"; - gid = ids.gids.kmem; - } - { name = "tty"; - gid = ids.gids.tty; - } - { name = "floppy"; - gid = ids.gids.floppy; - } - { name = "uucp"; - gid = ids.gids.uucp; - } - { name = "lp"; - gid = ids.gids.lp; - } - { name = "cdrom"; - gid = ids.gids.cdrom; - } - { name = "tape"; - gid = ids.gids.tape; - } - { name = "audio"; - gid = ids.gids.audio; - } - { name = "video"; - gid = ids.gids.video; - } - { name = "dialout"; - gid = ids.gids.dialout; - } - { name = "nogroup"; - gid = ids.gids.nogroup; - } - { name = "users"; - gid = ids.gids.users; - } - { name = "nixbld"; - gid = ids.gids.nixbld; - } - { name = "utmp"; - gid = ids.gids.utmp; - } - ]; - - addAttrs = - { name, gid ? "" }: - { inherit name gid; }; - - in map addAttrs (defaultGroups ++ config.users.extraGroups); + groupOpts = { name, config, ... }: { + + options = { + + name = mkOption { + type = with types; uniq string; + description = "The name of the group. If undefined, the name of the attribute set will be used."; + }; + + gid = mkOption { + type = with types; uniq (nullOr int); + default = null; + description = "The GID of the group. If undefined, NixOS will select a free GID."; + }; + + }; + config = { + name = mkDefault name; + gid = mkDefault (attrByPath [name] null ids.gids); + }; + + }; # Note: the 'X' in front of the password is to distinguish between # having an empty password, and not having a password. @@ -188,15 +161,16 @@ in }; users.extraGroups = mkOption { - default = []; + default = {}; example = - [ { name = "students"; - gid = 1001; - } - ]; + { students.gid = 1001; + hackers = { }; + }; + type = types.loaOf types.optionSet; description = '' Additional groups to be created automatically by the system. ''; + options = [ groupOpts ]; }; }; @@ -218,6 +192,26 @@ in }; }; + users.extraGroups = { + root = { }; + wheel = { }; + disk = { }; + kmem = { }; + tty = { }; + floppy = { }; + uucp = { }; + lp = { }; + cdrom = { }; + tape = { }; + audio = { }; + video = { }; + dialout = { }; + nogroup = { }; + users = { }; + nixbld = { }; + utmp = { }; + }; + system.activationScripts.rootPasswd = stringAfter [ "etc" ] '' # If there is no password file yet, create a root account with an @@ -313,7 +307,7 @@ in fi fi done <succeed("[ `nixos-version | wc -w` = 1 ]"); }; + # Sanity check for uid/gid assignment. + subtest "users-groups", sub { + $machine->succeed("[ `id -u messagebus` = 4 ]"); + $machine->succeed("[ `id -g messagebus` = 4 ]"); + $machine->succeed("[ `getent group users` = 'users:x:100:' ]"); + }; + # Regression test for GMP aborts on QEMU. subtest "gmp", sub { $machine->succeed("expr 1 + 2");