1
0
Fork 0
mirror of https://github.com/LnL7/nix-darwin.git synced 2025-03-06 16:57:08 +00:00
nix-darwin/modules/users/default.nix
Daiderd Jordan b1645201f1
users: add support for group members
Unlike user options this is updated if the group already exists.
2018-01-14 13:26:18 +01:00

125 lines
4.3 KiB
Nix
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

{ config, lib, pkgs, ... }:
with lib;
let
cfg = config.users;
group = import ./group.nix;
user = import ./user.nix;
toArguments = concatMapStringsSep " " (v: "'${v}'");
isCreated = list: name: elem name list;
isDeleted = attrs: name: ! elem name (mapAttrsToList (n: v: v.name) attrs);
createdGroups = mapAttrsToList (n: v: v) (filterAttrs (n: v: isCreated cfg.knownGroups v.name) cfg.groups);
createdUsers = mapAttrsToList (n: v: v) (filterAttrs (n: v: isCreated cfg.knownUsers v.name) cfg.users);
deletedGroups = filter (n: isDeleted cfg.groups n) cfg.knownGroups;
deletedUsers = filter (n: isDeleted cfg.users n) cfg.knownUsers;
in
{
options = {
users.knownGroups = mkOption {
type = types.listOf types.str;
default = [];
description = "List of groups that should be created and configured.";
};
users.knownUsers = mkOption {
type = types.listOf types.str;
default = [];
description = "List of users that should be created and configured.";
};
users.groups = mkOption {
type = types.loaOf (types.submodule group);
default = {};
description = "Configuration for groups.";
};
users.users = mkOption {
type = types.loaOf (types.submodule user);
default = {};
description = "Configuration for users.";
};
};
config = {
system.activationScripts.groups.text = mkIf (cfg.knownGroups != []) ''
echo "setting up groups..." >&2
${concatMapStringsSep "\n" (v: ''
g=$(dscl . -read '/Groups/${v.name}' PrimaryGroupID 2> /dev/null) || true
g=''${g#PrimaryGroupID: }
if [ -z "$g" ]; then
echo "creating group ${v.name}..." >&2
dscl . -create '/Groups/${v.name}' PrimaryGroupID ${toString v.gid}
dscl . -create '/Groups/${v.name}' RealName '${v.description}'
g=${toString v.gid}
fi
if [ "$g" -eq ${toString v.gid} ]; then
g=$(dscl . -read '/Groups/${v.name}' GroupMembership 2> /dev/null) || true
if [ "$g" != 'GroupMembership: ${concatStringsSep " " v.members}' ]; then
echo "updating group members ${v.name}..." >&2
dscl . -create '/Groups/${v.name}' GroupMembership ${toArguments v.members}
fi
else
echo "warning: existing group '${v.name}' has unexpected gid $g, skipping..." >&2
fi
'') createdGroups}
${concatMapStringsSep "\n" (name: ''
g=$(dscl . -read '/Groups/${name}' PrimaryGroupID 2> /dev/null) || true
g=''${g#PrimaryGroupID: }
if [ -n "$g" ]; then
if [ "$g" -gt 501 ]; then
echo "deleting group ${name}..." >&2
dscl . -delete '/Groups/${name}' 2> /dev/null
else
echo "warning: existing group '${name}' has unexpected gid $g, skipping..." >&2
fi
fi
'') deletedGroups}
'';
system.activationScripts.users.text = mkIf (cfg.knownUsers != []) ''
echo "setting up users..." >&2
${concatMapStringsSep "\n" (v: ''
u=$(dscl . -read '/Users/${v.name}' UniqueID 2> /dev/null) || true
u=''${u#UniqueID: }
if [ -z "$u" ]; then
echo "creating user ${v.name}..." >&2
dscl . -create '/Users/${v.name}' UniqueID ${toString v.uid}
dscl . -create '/Users/${v.name}' PrimaryGroupID ${toString v.gid}
dscl . -create '/Users/${v.name}' IsHidden ${if v.isHidden then "1" else "0"}
dscl . -create '/Users/${v.name}' RealName '${v.description}'
dscl . -create '/Users/${v.name}' NFSHomeDirectory '${v.home}'
dscl . -create '/Users/${v.name}' UserShell '${v.shell}'
else
if [ "$u" -ne ${toString v.uid} ]; then
echo "warning: existing user '${v.name}' has unexpected uid $u, skipping..." >&2
fi
fi
'') createdUsers}
${concatMapStringsSep "\n" (name: ''
u=$(dscl . -read '/Users/${name}' UniqueID 2> /dev/null) || true
u=''${u#UniqueID: }
if [ -n "$u" ]; then
if [ "$u" -gt 501 ]; then
echo "deleting user ${name}..." >&2
dscl . -delete '/Users/${name}' 2> /dev/null
else
echo "warning: existing user '${name}' has unexpected uid $u, skipping..." >&2
fi
fi
'') deletedUsers}
'';
};
}