* 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
This commit is contained in:
parent
235ea24ec4
commit
d587329615
@ -7,64 +7,75 @@ let
|
|||||||
ids = config.ids;
|
ids = config.ids;
|
||||||
users = config.users;
|
users = config.users;
|
||||||
|
|
||||||
userOpts = {name, config, ...}:
|
userOpts = { name, config, ... }: {
|
||||||
|
|
||||||
{
|
|
||||||
options = {
|
options = {
|
||||||
|
|
||||||
name = mkOption {
|
name = mkOption {
|
||||||
type = with types; uniq string;
|
type = with types; uniq string;
|
||||||
description = "The name of the user account. If undefined, the name of the attribute set will be used.";
|
description = "The name of the user account. If undefined, the name of the attribute set will be used.";
|
||||||
};
|
};
|
||||||
|
|
||||||
description = mkOption {
|
description = mkOption {
|
||||||
type = with types; uniq string;
|
type = with types; uniq string;
|
||||||
default = "";
|
default = "";
|
||||||
description = "A short description of the user account.";
|
description = "A short description of the user account.";
|
||||||
};
|
};
|
||||||
|
|
||||||
uid = mkOption {
|
uid = mkOption {
|
||||||
type = with types; uniq (nullOr int);
|
type = with types; uniq (nullOr int);
|
||||||
default = null;
|
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 {
|
group = mkOption {
|
||||||
type = with types; uniq string;
|
type = with types; uniq string;
|
||||||
default = "nogroup";
|
default = "nogroup";
|
||||||
description = "The user's primary group.";
|
description = "The user's primary group.";
|
||||||
};
|
};
|
||||||
|
|
||||||
extraGroups = mkOption {
|
extraGroups = mkOption {
|
||||||
type = types.listOf types.string;
|
type = types.listOf types.string;
|
||||||
default = [];
|
default = [];
|
||||||
description = "The user's auxiliary groups.";
|
description = "The user's auxiliary groups.";
|
||||||
};
|
};
|
||||||
|
|
||||||
home = mkOption {
|
home = mkOption {
|
||||||
type = with types; uniq string;
|
type = with types; uniq string;
|
||||||
default = "/var/empty";
|
default = "/var/empty";
|
||||||
description = "The user's home directory.";
|
description = "The user's home directory.";
|
||||||
};
|
};
|
||||||
|
|
||||||
shell = mkOption {
|
shell = mkOption {
|
||||||
type = with types; uniq string;
|
type = with types; uniq string;
|
||||||
default = "/noshell";
|
default = "/noshell";
|
||||||
description = "The path to the user's shell.";
|
description = "The path to the user's shell.";
|
||||||
};
|
};
|
||||||
|
|
||||||
createHome = mkOption {
|
createHome = mkOption {
|
||||||
type = types.bool;
|
type = types.bool;
|
||||||
default = false;
|
default = false;
|
||||||
description = "If true, the home directory will be created automatically.";
|
description = "If true, the home directory will be created automatically.";
|
||||||
};
|
};
|
||||||
|
|
||||||
useDefaultShell = mkOption {
|
useDefaultShell = mkOption {
|
||||||
type = types.bool;
|
type = types.bool;
|
||||||
default = false;
|
default = false;
|
||||||
description = "If true, the user's shell will be set to <literal>users.defaultUserShell</literal>.";
|
description = "If true, the user's shell will be set to <literal>users.defaultUserShell</literal>.";
|
||||||
};
|
};
|
||||||
|
|
||||||
password = mkOption {
|
password = mkOption {
|
||||||
type = with types; uniq (nullOr string);
|
type = with types; uniq (nullOr string);
|
||||||
default = null;
|
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.";
|
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 {
|
isSystemUser = mkOption {
|
||||||
type = types.bool;
|
type = types.bool;
|
||||||
default = true;
|
default = true;
|
||||||
description = "Indicates if the user is a system user or not.";
|
description = "Indicates if the user is a system user or not.";
|
||||||
};
|
};
|
||||||
|
|
||||||
createUser = mkOption {
|
createUser = mkOption {
|
||||||
type = types.bool;
|
type = types.bool;
|
||||||
default = true;
|
default = true;
|
||||||
@ -74,6 +85,7 @@ let
|
|||||||
then not modify any of the basic properties for the user account.
|
then not modify any of the basic properties for the user account.
|
||||||
";
|
";
|
||||||
};
|
};
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
config = {
|
config = {
|
||||||
@ -81,71 +93,32 @@ let
|
|||||||
uid = mkDefault (attrByPath [name] null ids.uids);
|
uid = mkDefault (attrByPath [name] null ids.uids);
|
||||||
shell = mkIf config.useDefaultShell (mkDefault users.defaultUserShell);
|
shell = mkIf config.useDefaultShell (mkDefault users.defaultUserShell);
|
||||||
};
|
};
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
# Groups to be created/updated by NixOS.
|
groupOpts = { name, config, ... }: {
|
||||||
groups =
|
|
||||||
let
|
options = {
|
||||||
defaultGroups =
|
|
||||||
[ { name = "root";
|
name = mkOption {
|
||||||
gid = ids.gids.root;
|
type = with types; uniq string;
|
||||||
}
|
description = "The name of the group. If undefined, the name of the attribute set will be used.";
|
||||||
{ name = "wheel";
|
};
|
||||||
gid = ids.gids.wheel;
|
|
||||||
}
|
gid = mkOption {
|
||||||
{ name = "disk";
|
type = with types; uniq (nullOr int);
|
||||||
gid = ids.gids.disk;
|
default = null;
|
||||||
}
|
description = "The GID of the group. If undefined, NixOS will select a free GID.";
|
||||||
{ 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);
|
|
||||||
|
|
||||||
|
config = {
|
||||||
|
name = mkDefault name;
|
||||||
|
gid = mkDefault (attrByPath [name] null ids.gids);
|
||||||
|
};
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
# Note: the 'X' in front of the password is to distinguish between
|
# Note: the 'X' in front of the password is to distinguish between
|
||||||
# having an empty password, and not having a password.
|
# having an empty password, and not having a password.
|
||||||
@ -188,15 +161,16 @@ in
|
|||||||
};
|
};
|
||||||
|
|
||||||
users.extraGroups = mkOption {
|
users.extraGroups = mkOption {
|
||||||
default = [];
|
default = {};
|
||||||
example =
|
example =
|
||||||
[ { name = "students";
|
{ students.gid = 1001;
|
||||||
gid = 1001;
|
hackers = { };
|
||||||
}
|
};
|
||||||
];
|
type = types.loaOf types.optionSet;
|
||||||
description = ''
|
description = ''
|
||||||
Additional groups to be created automatically by the system.
|
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" ]
|
system.activationScripts.rootPasswd = stringAfter [ "etc" ]
|
||||||
''
|
''
|
||||||
# If there is no password file yet, create a root account with an
|
# If there is no password file yet, create a root account with an
|
||||||
@ -313,7 +307,7 @@ in
|
|||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
done <<EndOfGroupList
|
done <<EndOfGroupList
|
||||||
${concatStringsSep "\n" (map serializedGroup groups)}
|
${concatStringsSep "\n" (map serializedGroup (attrValues config.users.extraGroups))}
|
||||||
EndOfGroupList
|
EndOfGroupList
|
||||||
'';
|
'';
|
||||||
|
|
||||||
|
@ -12,6 +12,13 @@
|
|||||||
$machine->succeed("[ `nixos-version | wc -w` = 1 ]");
|
$machine->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.
|
# Regression test for GMP aborts on QEMU.
|
||||||
subtest "gmp", sub {
|
subtest "gmp", sub {
|
||||||
$machine->succeed("expr 1 + 2");
|
$machine->succeed("expr 1 + 2");
|
||||||
|
Loading…
x
Reference in New Issue
Block a user