6f5a86b189
Since 4f6df27aee
, nix.useSandbox defaults
to true which causes the Nix build within the containers-imperative test
to fail while trying to hardlink files into the chroot:
link("/nix/store/foo", "/nix/store/bar.drv.chroot/nix/store/foo")
= -1 EPERM (Operation not permitted)
The reason this happens is that the hosts store is mounted using 9p and
an overlayfs is mounted on top, so even if we would disable the tmpfs
for the upper directory the hardlink would still cross filesystem
boundaries, which then fails with the above error code.
I haven't yet seen any other test which fails in a similar way, which
might be because building within VM tests is not very common and the
installer tests build in a separate store, so they're not affected.
Signed-off-by: aszlig <aszlig@nix.build>
Issue: https://github.com/NixOS/nix/issues/2324
Cc: @aristidb, @edolstra, @chaoflow, @kampfschlaefer
107 lines
3.6 KiB
Nix
107 lines
3.6 KiB
Nix
# Test for NixOS' container support.
|
||
|
||
import ./make-test.nix ({ pkgs, ...} : {
|
||
name = "containers-imperative";
|
||
meta = with pkgs.stdenv.lib.maintainers; {
|
||
maintainers = [ aristid aszlig eelco chaoflow kampfschlaefer ];
|
||
};
|
||
|
||
machine =
|
||
{ config, pkgs, lib, ... }:
|
||
{ imports = [ ../modules/installer/cd-dvd/channel.nix ];
|
||
|
||
# XXX: Sandbox setup fails while trying to hardlink files from the host's
|
||
# store file system into the prepared chroot directory.
|
||
nix.useSandbox = false;
|
||
|
||
virtualisation.writableStore = true;
|
||
virtualisation.memorySize = 1024;
|
||
# Make sure we always have all the required dependencies for creating a
|
||
# container available within the VM, because we don't have network access.
|
||
virtualisation.pathsInNixDB = let
|
||
emptyContainer = import ../lib/eval-config.nix {
|
||
inherit (config.nixpkgs.localSystem) system;
|
||
modules = lib.singleton {
|
||
containers.foo.config = {
|
||
system.stateVersion = "18.03";
|
||
};
|
||
};
|
||
};
|
||
in [
|
||
pkgs.stdenv pkgs.stdenvNoCC emptyContainer.config.containers.foo.path
|
||
pkgs.libxslt
|
||
];
|
||
};
|
||
|
||
testScript =
|
||
''
|
||
# Make sure we have a NixOS tree (required by ‘nixos-container create’).
|
||
$machine->succeed("PAGER=cat nix-env -qa -A nixos.hello >&2");
|
||
|
||
# Create some containers imperatively.
|
||
my $id1 = $machine->succeed("nixos-container create foo --ensure-unique-name");
|
||
chomp $id1;
|
||
$machine->log("created container $id1");
|
||
|
||
my $id2 = $machine->succeed("nixos-container create foo --ensure-unique-name");
|
||
chomp $id2;
|
||
$machine->log("created container $id2");
|
||
|
||
die if $id1 eq $id2;
|
||
|
||
# Put the root of $id2 into a bind mount.
|
||
$machine->succeed(
|
||
"mv /var/lib/containers/$id2 /id2-bindmount",
|
||
"mount --bind /id2-bindmount /var/lib/containers/$id1"
|
||
);
|
||
|
||
my $ip1 = $machine->succeed("nixos-container show-ip $id1");
|
||
chomp $ip1;
|
||
my $ip2 = $machine->succeed("nixos-container show-ip $id2");
|
||
chomp $ip2;
|
||
die if $ip1 eq $ip2;
|
||
|
||
# Create a directory and a file we can later check if it still exists
|
||
# after destruction of the container.
|
||
$machine->succeed(
|
||
"mkdir /nested-bindmount",
|
||
"echo important data > /nested-bindmount/dummy",
|
||
);
|
||
|
||
# Create a directory with a dummy file and bind-mount it into both
|
||
# containers.
|
||
foreach ($id1, $id2) {
|
||
my $importantPath = "/var/lib/containers/$_/very/important/data";
|
||
$machine->succeed(
|
||
"mkdir -p $importantPath",
|
||
"mount --bind /nested-bindmount $importantPath"
|
||
);
|
||
}
|
||
|
||
# Start one of them.
|
||
$machine->succeed("nixos-container start $id1");
|
||
|
||
# Execute commands via the root shell.
|
||
$machine->succeed("nixos-container run $id1 -- uname") =~ /Linux/ or die;
|
||
|
||
# Stop and start (regression test for #4989)
|
||
$machine->succeed("nixos-container stop $id1");
|
||
$machine->succeed("nixos-container start $id1");
|
||
|
||
# Execute commands via the root shell.
|
||
$machine->succeed("nixos-container run $id1 -- uname") =~ /Linux/ or die;
|
||
|
||
# Destroy the containers.
|
||
$machine->succeed("nixos-container destroy $id1");
|
||
$machine->succeed("nixos-container destroy $id2");
|
||
|
||
$machine->succeed(
|
||
# Check whether destruction of any container has killed important data
|
||
"grep -qF 'important data' /nested-bindmount/dummy",
|
||
# Ensure that the container path is gone
|
||
"test ! -e /var/lib/containers/$id1"
|
||
);
|
||
'';
|
||
|
||
})
|