diff options
author | Francesco Gazzetta <fgaz@fgaz.me> | 2020-11-19 17:18:02 +0100 |
---|---|---|
committer | Francesco Gazzetta <fgaz@fgaz.me> | 2020-12-20 21:22:47 +0100 |
commit | 6f21ae7a626cee022f5c20eacaaf934281e806c0 (patch) | |
tree | 6c7b4c59d618281178043290c27b4376c9e75bbf /nixos/lib | |
parent | 1e5a7a913514a8746ae94819c9591e13ed8f21f7 (diff) |
nixos/lib/make-disk-image.nix: support content mode and ownership
Diffstat (limited to 'nixos/lib')
-rw-r--r-- | nixos/lib/make-disk-image.nix | 48 |
1 files changed, 43 insertions, 5 deletions
diff --git a/nixos/lib/make-disk-image.nix b/nixos/lib/make-disk-image.nix index 0ad0cf1fef5af..3f50bb431c5e4 100644 --- a/nixos/lib/make-disk-image.nix +++ b/nixos/lib/make-disk-image.nix @@ -18,9 +18,13 @@ bootSize ? "256M" , # The files and directories to be placed in the target file system. - # This is a list of attribute sets {source, target} where `source' - # is the file system object (regular file or directory) to be - # grafted in the file system at path `target'. + # This is a list of attribute sets {source, target, mode, user, group} where + # `source' is the file system object (regular file or directory) to be + # grafted in the file system at path `target', `mode' is a string containing + # the permissions that will be set (ex. "755"), `user' and `group' are the + # user and group name that will be set as owner of the files. + # `mode', `user', and `group' are optional. + # When setting one of `user' or `group', the other needs to be set too. contents ? [] , # Type of partition table to use; either "legacy", "efi", or "none". @@ -60,6 +64,11 @@ assert partitionTableType == "legacy" || partitionTableType == "legacy+gpt" || partitionTableType == "efi" || partitionTableType == "hybrid" || partitionTableType == "none"; # We use -E offset=X below, which is only supported by e2fsprogs assert partitionTableType != "none" -> fsType == "ext4"; +# Either both or none of {user,group} need to be set +assert lib.all + (attrs: ((attrs.user or null) == null) + == ((attrs.group or null) == null)) + contents; with lib; @@ -148,6 +157,9 @@ let format' = format; in let # !!! should use XML. sources = map (x: x.source) contents; targets = map (x: x.target) contents; + modes = map (x: x.mode or "''") contents; + users = map (x: x.user or "''") contents; + groups = map (x: x.group or "''") contents; closureInfo = pkgs.closureInfo { rootPaths = [ config.system.build.toplevel channelSources ]; }; @@ -174,22 +186,33 @@ let format' = format; in let set -f sources_=(${concatStringsSep " " sources}) targets_=(${concatStringsSep " " targets}) + modes_=(${concatStringsSep " " modes}) set +f for ((i = 0; i < ''${#targets_[@]}; i++)); do source="''${sources_[$i]}" target="''${targets_[$i]}" + mode="''${modes_[$i]}" + if [ -n "$mode" ]; then + rsync_chmod_flags="--chmod=$mode" + else + rsync_chmod_flags="" + fi + # Unfortunately cptofs only supports modes, not ownership, so we can't use + # rsync's --chown option. Instead, we change the ownerships in the + # VM script with chown. + rsync_flags="-a --no-o --no-g $rsync_chmod_flags" if [[ "$source" =~ '*' ]]; then # If the source name contains '*', perform globbing. mkdir -p $root/$target for fn in $source; do - rsync -a --no-o --no-g "$fn" $root/$target/ + rsync $rsync_flags "$fn" $root/$target/ done else mkdir -p $root/$(dirname $target) if ! [ -e $root/$target ]; then - rsync -a --no-o --no-g $source $root/$target + rsync $rsync_flags $source $root/$target else echo "duplicate entry $target -> $source" exit 1 @@ -284,6 +307,21 @@ in pkgs.vmTools.runInLinuxVM ( # The above scripts will generate a random machine-id and we don't want to bake a single ID into all our images rm -f $mountPoint/etc/machine-id + # Set the ownerships of the contents. The modes are set in preVM. + # No globbing on targets, so no need to set -f + targets_=(${concatStringsSep " " targets}) + users_=(${concatStringsSep " " users}) + groups_=(${concatStringsSep " " groups}) + for ((i = 0; i < ''${#targets_[@]}; i++)); do + target="''${targets_[$i]}" + user="''${users_[$i]}" + group="''${groups_[$i]}" + if [ -n "$user$group" ]; then + # We have to nixos-enter since we need to use the user and group of the VM + nixos-enter --root $mountPoint -- chown -R "$user:$group" "$target" + fi + done + umount -R /mnt # Make sure resize2fs works. Note that resize2fs has stricter criteria for resizing than a normal |