etc: uid/gid support for copied files

Signed-off-by: Austin Seipp <aseipp@pobox.com>

Changed files
+32
nixos
modules
+20
nixos/modules/system/etc/etc.nix
···
sources = map (x: x.source) etc';
targets = map (x: x.target) etc';
modes = map (x: x.mode) etc';
+
uids = map (x: x.uid) etc';
+
gids = map (x: x.gid) etc';
};
in
···
If set to something else than <literal>symlink</literal>,
the file is copied instead of symlinked, with the given
file mode.
+
'';
+
};
+
+
uid = mkOption {
+
default = 0;
+
type = types.int;
+
description = ''
+
UID of created file. Only takes affect when the file is
+
copied (that is, the mode is not 'symlink').
+
'';
+
};
+
+
gid = mkOption {
+
default = 0;
+
type = types.int;
+
description = ''
+
GID of created file. Only takes affect when the file is
+
copied (that is, the mode is not 'symlink').
'';
};
+4
nixos/modules/system/etc/make-etc.sh
···
sources_=($sources)
targets_=($targets)
modes_=($modes)
+
uids_=($uids)
+
gids_=($gids)
set +f
for ((i = 0; i < ${#targets_[@]}; i++)); do
···
if test "${modes_[$i]}" != symlink; then
echo "${modes_[$i]}" > $out/etc/$target.mode
+
echo "${uids_[$i]}" > $out/etc/$target.uid
+
echo "${gids_[$i]}" > $out/etc/$target.gid
fi
fi
+8
nixos/modules/system/etc/setup-etc.pl
···
if ($mode eq "direct-symlink") {
atomicSymlink readlink("$static/$fn"), $target or warn;
} else {
+
open UID, "<$_.uid";
+
my $uid = <UID>; chomp $uid;
+
close UID;
+
open GID, "<$_.gid";
+
my $gid = <GID>; chomp $gid;
+
close GID;
+
copy "$static/$fn", "$target.tmp" or warn;
+
chown int($uid), int($gid), "$target.tmp" or warn;
chmod oct($mode), "$target.tmp" or warn;
rename "$target.tmp", $target or warn;
}