Merge pull request #104292 from fgaz/image-contents
nixos/lib/make-disk-image.nix: support content mode and ownership
This commit is contained in:
commit
a5a819e059
@ -18,9 +18,13 @@
|
|||||||
bootSize ? "256M"
|
bootSize ? "256M"
|
||||||
|
|
||||||
, # The files and directories to be placed in the target file system.
|
, # The files and directories to be placed in the target file system.
|
||||||
# This is a list of attribute sets {source, target} where `source'
|
# This is a list of attribute sets {source, target, mode, user, group} where
|
||||||
# is the file system object (regular file or directory) to be
|
# `source' is the file system object (regular file or directory) to be
|
||||||
# grafted in the file system at path `target'.
|
# 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 ? []
|
contents ? []
|
||||||
|
|
||||||
, # Type of partition table to use; either "legacy", "efi", or "none".
|
, # 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";
|
assert partitionTableType == "legacy" || partitionTableType == "legacy+gpt" || partitionTableType == "efi" || partitionTableType == "hybrid" || partitionTableType == "none";
|
||||||
# We use -E offset=X below, which is only supported by e2fsprogs
|
# We use -E offset=X below, which is only supported by e2fsprogs
|
||||||
assert partitionTableType != "none" -> fsType == "ext4";
|
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;
|
with lib;
|
||||||
|
|
||||||
@ -148,6 +157,9 @@ let format' = format; in let
|
|||||||
# !!! should use XML.
|
# !!! should use XML.
|
||||||
sources = map (x: x.source) contents;
|
sources = map (x: x.source) contents;
|
||||||
targets = map (x: x.target) 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 ]; };
|
closureInfo = pkgs.closureInfo { rootPaths = [ config.system.build.toplevel channelSources ]; };
|
||||||
|
|
||||||
@ -174,22 +186,33 @@ let format' = format; in let
|
|||||||
set -f
|
set -f
|
||||||
sources_=(${concatStringsSep " " sources})
|
sources_=(${concatStringsSep " " sources})
|
||||||
targets_=(${concatStringsSep " " targets})
|
targets_=(${concatStringsSep " " targets})
|
||||||
|
modes_=(${concatStringsSep " " modes})
|
||||||
set +f
|
set +f
|
||||||
|
|
||||||
for ((i = 0; i < ''${#targets_[@]}; i++)); do
|
for ((i = 0; i < ''${#targets_[@]}; i++)); do
|
||||||
source="''${sources_[$i]}"
|
source="''${sources_[$i]}"
|
||||||
target="''${targets_[$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 [[ "$source" =~ '*' ]]; then
|
||||||
# If the source name contains '*', perform globbing.
|
# If the source name contains '*', perform globbing.
|
||||||
mkdir -p $root/$target
|
mkdir -p $root/$target
|
||||||
for fn in $source; do
|
for fn in $source; do
|
||||||
rsync -a --no-o --no-g "$fn" $root/$target/
|
rsync $rsync_flags "$fn" $root/$target/
|
||||||
done
|
done
|
||||||
else
|
else
|
||||||
mkdir -p $root/$(dirname $target)
|
mkdir -p $root/$(dirname $target)
|
||||||
if ! [ -e $root/$target ]; then
|
if ! [ -e $root/$target ]; then
|
||||||
rsync -a --no-o --no-g $source $root/$target
|
rsync $rsync_flags $source $root/$target
|
||||||
else
|
else
|
||||||
echo "duplicate entry $target -> $source"
|
echo "duplicate entry $target -> $source"
|
||||||
exit 1
|
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
|
# 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
|
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
|
umount -R /mnt
|
||||||
|
|
||||||
# Make sure resize2fs works. Note that resize2fs has stricter criteria for resizing than a normal
|
# Make sure resize2fs works. Note that resize2fs has stricter criteria for resizing than a normal
|
||||||
|
@ -280,6 +280,7 @@ in
|
|||||||
openssh = handleTest ./openssh.nix {};
|
openssh = handleTest ./openssh.nix {};
|
||||||
openstack-image-metadata = (handleTestOn ["x86_64-linux"] ./openstack-image.nix {}).metadata or {};
|
openstack-image-metadata = (handleTestOn ["x86_64-linux"] ./openstack-image.nix {}).metadata or {};
|
||||||
openstack-image-userdata = (handleTestOn ["x86_64-linux"] ./openstack-image.nix {}).userdata or {};
|
openstack-image-userdata = (handleTestOn ["x86_64-linux"] ./openstack-image.nix {}).userdata or {};
|
||||||
|
image-contents = handleTest ./image-contents.nix {};
|
||||||
orangefs = handleTest ./orangefs.nix {};
|
orangefs = handleTest ./orangefs.nix {};
|
||||||
os-prober = handleTestOn ["x86_64-linux"] ./os-prober.nix {};
|
os-prober = handleTestOn ["x86_64-linux"] ./os-prober.nix {};
|
||||||
osrm-backend = handleTest ./osrm-backend.nix {};
|
osrm-backend = handleTest ./osrm-backend.nix {};
|
||||||
|
51
nixos/tests/image-contents.nix
Normal file
51
nixos/tests/image-contents.nix
Normal file
@ -0,0 +1,51 @@
|
|||||||
|
# Tests the contents attribute of nixos/lib/make-disk-image.nix
|
||||||
|
# including its user, group, and mode attributes.
|
||||||
|
{ system ? builtins.currentSystem,
|
||||||
|
config ? {},
|
||||||
|
pkgs ? import ../.. { inherit system config; }
|
||||||
|
}:
|
||||||
|
|
||||||
|
with import ../lib/testing-python.nix { inherit system pkgs; };
|
||||||
|
with pkgs.lib;
|
||||||
|
|
||||||
|
with import common/ec2.nix { inherit makeTest pkgs; };
|
||||||
|
|
||||||
|
let
|
||||||
|
config = (import ../lib/eval-config.nix {
|
||||||
|
inherit system;
|
||||||
|
modules = [
|
||||||
|
../modules/testing/test-instrumentation.nix
|
||||||
|
../modules/profiles/qemu-guest.nix
|
||||||
|
{
|
||||||
|
fileSystems."/".device = "/dev/disk/by-label/nixos";
|
||||||
|
boot.loader.grub.device = "/dev/vda";
|
||||||
|
boot.loader.timeout = 0;
|
||||||
|
}
|
||||||
|
];
|
||||||
|
}).config;
|
||||||
|
image = (import ../lib/make-disk-image.nix {
|
||||||
|
inherit pkgs config;
|
||||||
|
lib = pkgs.lib;
|
||||||
|
format = "qcow2";
|
||||||
|
contents = [{
|
||||||
|
source = pkgs.writeText "testFile" "contents";
|
||||||
|
target = "/testFile";
|
||||||
|
user = "1234";
|
||||||
|
group = "5678";
|
||||||
|
mode = "755";
|
||||||
|
}];
|
||||||
|
}) + "/nixos.qcow2";
|
||||||
|
|
||||||
|
in makeEc2Test {
|
||||||
|
name = "image-contents";
|
||||||
|
inherit image;
|
||||||
|
userData = null;
|
||||||
|
script = ''
|
||||||
|
machine.start()
|
||||||
|
assert "content" in machine.succeed("cat /testFile")
|
||||||
|
fileDetails = machine.succeed("ls -l /testFile")
|
||||||
|
assert "1234" in fileDetails
|
||||||
|
assert "5678" in fileDetails
|
||||||
|
assert "rwxr-xr-x" in fileDetails
|
||||||
|
'';
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user