diff options
author | Frederik Rietdijk <fridh@fridh.nl> | 2020-08-24 11:50:58 +0200 |
---|---|---|
committer | Frederik Rietdijk <fridh@fridh.nl> | 2020-08-24 11:50:58 +0200 |
commit | 0a874ff2a6dad9d2693f08a733d58f8077f36916 (patch) | |
tree | 80360888241c761769d9a1074fd96b22d7664598 /nixos | |
parent | 91104b5417275b780f6947b46a5c1bcc0d99f10b (diff) | |
parent | bc00ecedfa709f4fa91d445dd76ecd792cb2c728 (diff) | |
download | nixpkgs-0a874ff2a6dad9d2693f08a733d58f8077f36916.tar nixpkgs-0a874ff2a6dad9d2693f08a733d58f8077f36916.tar.gz nixpkgs-0a874ff2a6dad9d2693f08a733d58f8077f36916.tar.bz2 nixpkgs-0a874ff2a6dad9d2693f08a733d58f8077f36916.tar.lz nixpkgs-0a874ff2a6dad9d2693f08a733d58f8077f36916.tar.xz nixpkgs-0a874ff2a6dad9d2693f08a733d58f8077f36916.tar.zst nixpkgs-0a874ff2a6dad9d2693f08a733d58f8077f36916.zip |
Merge master into staging-next
Diffstat (limited to 'nixos')
-rw-r--r-- | nixos/doc/manual/release-notes/rl-2009.xml | 11 | ||||
-rw-r--r-- | nixos/lib/eval-config.nix | 4 | ||||
-rw-r--r-- | nixos/lib/test-driver/test-driver.py | 7 | ||||
-rw-r--r-- | nixos/modules/services/misc/ssm-agent.nix | 6 | ||||
-rw-r--r-- | nixos/modules/services/monitoring/prometheus/default.nix | 27 | ||||
-rw-r--r-- | nixos/modules/virtualisation/docker-preloader.nix | 134 | ||||
-rw-r--r-- | nixos/modules/virtualisation/qemu-vm.nix | 1 | ||||
-rw-r--r-- | nixos/tests/all-tests.nix | 6 | ||||
-rw-r--r-- | nixos/tests/common/ec2.nix | 58 | ||||
-rw-r--r-- | nixos/tests/containers-reloadable.nix | 4 | ||||
-rw-r--r-- | nixos/tests/cri-o.nix | 19 | ||||
-rw-r--r-- | nixos/tests/docker-preloader.nix | 27 | ||||
-rw-r--r-- | nixos/tests/ec2.nix | 140 | ||||
-rw-r--r-- | nixos/tests/gnome3.nix | 10 | ||||
-rw-r--r-- | nixos/tests/hardened.nix | 114 | ||||
-rw-r--r-- | nixos/tests/hocker-fetchdocker/default.nix | 9 | ||||
-rw-r--r-- | nixos/tests/installer.nix | 2 | ||||
-rw-r--r-- | nixos/tests/openstack-image.nix | 70 |
18 files changed, 287 insertions, 362 deletions
diff --git a/nixos/doc/manual/release-notes/rl-2009.xml b/nixos/doc/manual/release-notes/rl-2009.xml index 83bc2f82bbf..b958aab07c5 100644 --- a/nixos/doc/manual/release-notes/rl-2009.xml +++ b/nixos/doc/manual/release-notes/rl-2009.xml @@ -128,7 +128,7 @@ GRANT ALL PRIVILEGES ON *.* TO 'mysql'@'localhost' WITH GRANT OPTION; </listitem> <listitem> <para> - Two new option <link linkend="opt-documentation.man.generateCaches">documentation.man.generateCaches</link> + The new option <link linkend="opt-documentation.man.generateCaches">documentation.man.generateCaches</link> has been added to automatically generate the <literal>man-db</literal> caches, which are needed by utilities like <command>whatis</command> and <command>apropos</command>. The caches are generated during the build of the NixOS configuration: since this can be expensive when a large number of packages are installed, the @@ -195,6 +195,15 @@ GRANT ALL PRIVILEGES ON *.* TO 'mysql'@'localhost' WITH GRANT OPTION; The NixOS module system now supports freeform modules as a mix between <literal>types.attrsOf</literal> and <literal>types.submodule</literal>. These allow you to explicitly declare a subset of options while still permitting definitions without an associated option. See <xref linkend='sec-freeform-modules'/> for how to use them. </para> </listitem> + <listitem> + <para> + The GRUB module gained support for basic password protection, which + allows to restrict non-default entries in the boot menu to one or more + users. The users and passwords are defined via the option + <option>boot.loader.grub.users</option>. + Note: Password support is only avaiable in GRUB version 2. + </para> + </listitem> </itemizedlist> </section> diff --git a/nixos/lib/eval-config.nix b/nixos/lib/eval-config.nix index c8824c2690d..15429a7160c 100644 --- a/nixos/lib/eval-config.nix +++ b/nixos/lib/eval-config.nix @@ -24,11 +24,11 @@ check ? true , prefix ? [] , lib ? import ../../lib +, extraModules ? let e = builtins.getEnv "NIXOS_EXTRA_MODULE_PATH"; + in if e == "" then [] else [(import e)] }: let extraArgs_ = extraArgs; pkgs_ = pkgs; - extraModules = let e = builtins.getEnv "NIXOS_EXTRA_MODULE_PATH"; - in if e == "" then [] else [(import e)]; in let diff --git a/nixos/lib/test-driver/test-driver.py b/nixos/lib/test-driver/test-driver.py index 7b8d5803aa5..f4e2bb6100f 100644 --- a/nixos/lib/test-driver/test-driver.py +++ b/nixos/lib/test-driver/test-driver.py @@ -424,15 +424,18 @@ class Machine: output += out return output - def fail(self, *commands: str) -> None: + def fail(self, *commands: str) -> str: """Execute each command and check that it fails.""" + output = "" for command in commands: with self.nested("must fail: {}".format(command)): - status, output = self.execute(command) + (status, out) = self.execute(command) if status == 0: raise Exception( "command `{}` unexpectedly succeeded".format(command) ) + output += out + return output def wait_until_succeeds(self, command: str) -> str: """Wait until a command returns success and return its output. diff --git a/nixos/modules/services/misc/ssm-agent.nix b/nixos/modules/services/misc/ssm-agent.nix index f7c05deeecb..00e806695fd 100644 --- a/nixos/modules/services/misc/ssm-agent.nix +++ b/nixos/modules/services/misc/ssm-agent.nix @@ -29,13 +29,15 @@ in { config = mkIf cfg.enable { systemd.services.ssm-agent = { + users.extraUsers.ssm-user = {}; + inherit (cfg.package.meta) description; after = [ "network.target" ]; wantedBy = [ "multi-user.target" ]; - path = [ fake-lsb-release ]; + path = [ fake-lsb-release pkgs.coreutils ]; serviceConfig = { - ExecStart = "${cfg.package}/bin/agent"; + ExecStart = "${cfg.package}/bin/amazon-ssm-agent"; KillMode = "process"; Restart = "on-failure"; RestartSec = "15min"; diff --git a/nixos/modules/services/monitoring/prometheus/default.nix b/nixos/modules/services/monitoring/prometheus/default.nix index 84a72afac2f..d7e06484b69 100644 --- a/nixos/modules/services/monitoring/prometheus/default.nix +++ b/nixos/modules/services/monitoring/prometheus/default.nix @@ -46,7 +46,7 @@ let cmdlineArgs = cfg.extraFlags ++ [ "--storage.tsdb.path=${workingDir}/data/" "--config.file=${prometheusYml}" - "--web.listen-address=${cfg.listenAddress}" + "--web.listen-address=${cfg.listenAddress}:${builtins.toString cfg.port}" "--alertmanager.notification-queue-capacity=${toString cfg.alertmanagerNotificationQueueCapacity}" "--alertmanager.timeout=${toString cfg.alertmanagerTimeout}s" ] ++ @@ -489,9 +489,17 @@ in { ''; }; + port = mkOption { + type = types.port; + default = 9090; + description = '' + Port to listen on. + ''; + }; + listenAddress = mkOption { type = types.str; - default = "0.0.0.0:9090"; + default = "0.0.0.0"; description = '' Address to listen on for the web interface, API, and telemetry. ''; @@ -619,6 +627,21 @@ in { }; config = mkIf cfg.enable { + assertions = [ + ( let + legacy = builtins.match "(.*):(.*)" cfg.listenAddress; + in { + assertion = legacy == null; + message = '' + Do not specify the port for Prometheus to listen on in the + listenAddress option; use the port option instead: + services.prometheus.listenAddress = ${builtins.elemAt legacy 0}; + services.prometheus.port = ${builtins.elemAt legacy 1}; + ''; + } + ) + ]; + users.groups.prometheus.gid = config.ids.gids.prometheus; users.users.prometheus = { description = "Prometheus daemon user"; diff --git a/nixos/modules/virtualisation/docker-preloader.nix b/nixos/modules/virtualisation/docker-preloader.nix deleted file mode 100644 index 6ab83058dee..00000000000 --- a/nixos/modules/virtualisation/docker-preloader.nix +++ /dev/null @@ -1,134 +0,0 @@ -{ config, lib, pkgs, ... }: - -with lib; -with builtins; - -let - cfg = config.virtualisation; - - sanitizeImageName = image: replaceStrings ["/"] ["-"] image.imageName; - hash = drv: head (split "-" (baseNameOf drv.outPath)); - # The label of an ext4 FS is limited to 16 bytes - labelFromImage = image: substring 0 16 (hash image); - - # The Docker image is loaded and some files from /var/lib/docker/ - # are written into a qcow image. - preload = image: pkgs.vmTools.runInLinuxVM ( - pkgs.runCommand "docker-preload-image-${sanitizeImageName image}" { - buildInputs = with pkgs; [ docker e2fsprogs utillinux curl kmod ]; - preVM = pkgs.vmTools.createEmptyImage { - size = cfg.dockerPreloader.qcowSize; - fullName = "docker-deamon-image.qcow2"; - }; - } - '' - mkfs.ext4 /dev/vda - e2label /dev/vda ${labelFromImage image} - mkdir -p /var/lib/docker - mount -t ext4 /dev/vda /var/lib/docker - - modprobe overlay - - # from https://github.com/tianon/cgroupfs-mount/blob/master/cgroupfs-mount - mount -t tmpfs -o uid=0,gid=0,mode=0755 cgroup /sys/fs/cgroup - cd /sys/fs/cgroup - for sys in $(awk '!/^#/ { if ($4 == 1) print $1 }' /proc/cgroups); do - mkdir -p $sys - if ! mountpoint -q $sys; then - if ! mount -n -t cgroup -o $sys cgroup $sys; then - rmdir $sys || true - fi - fi - done - - dockerd -H tcp://127.0.0.1:5555 -H unix:///var/run/docker.sock & - - until $(curl --output /dev/null --silent --connect-timeout 2 http://127.0.0.1:5555); do - printf '.' - sleep 1 - done - - docker load -i ${image} - - kill %1 - find /var/lib/docker/ -maxdepth 1 -mindepth 1 -not -name "image" -not -name "overlay2" | xargs rm -rf - ''); - - preloadedImages = map preload cfg.dockerPreloader.images; - -in - -{ - options.virtualisation.dockerPreloader = { - images = mkOption { - default = [ ]; - type = types.listOf types.package; - description = - '' - A list of Docker images to preload (in the /var/lib/docker directory). - ''; - }; - qcowSize = mkOption { - default = 1024; - type = types.int; - description = - '' - The size (MB) of qcow files. - ''; - }; - }; - - config = mkIf (cfg.dockerPreloader.images != []) { - assertions = [{ - # If docker.storageDriver is null, Docker choose the storage - # driver. So, in this case, we cannot be sure overlay2 is used. - assertion = cfg.docker.storageDriver == "overlay2" - || cfg.docker.storageDriver == "overlay" - || cfg.docker.storageDriver == null; - message = "The Docker image Preloader only works with overlay2 storage driver!"; - }]; - - virtualisation.qemu.options = - map (path: "-drive if=virtio,file=${path}/disk-image.qcow2,readonly,media=cdrom,format=qcow2") - preloadedImages; - - - # All attached QCOW files are mounted and their contents are linked - # to /var/lib/docker/ in order to make image available. - systemd.services.docker-preloader = { - description = "Preloaded Docker images"; - wantedBy = ["docker.service"]; - after = ["network.target"]; - path = with pkgs; [ mount rsync jq ]; - script = '' - mkdir -p /var/lib/docker/overlay2/l /var/lib/docker/image/overlay2 - echo '{}' > /tmp/repositories.json - - for i in ${concatStringsSep " " (map labelFromImage cfg.dockerPreloader.images)}; do - mkdir -p /mnt/docker-images/$i - - # The ext4 label is limited to 16 bytes - mount /dev/disk/by-label/$(echo $i | cut -c1-16) -o ro,noload /mnt/docker-images/$i - - find /mnt/docker-images/$i/overlay2/ -maxdepth 1 -mindepth 1 -not -name l\ - -exec ln -s '{}' /var/lib/docker/overlay2/ \; - cp -P /mnt/docker-images/$i/overlay2/l/* /var/lib/docker/overlay2/l/ - - rsync -a /mnt/docker-images/$i/image/ /var/lib/docker/image/ - - # Accumulate image definitions - cp /tmp/repositories.json /tmp/repositories.json.tmp - jq -s '.[0] * .[1]' \ - /tmp/repositories.json.tmp \ - /mnt/docker-images/$i/image/overlay2/repositories.json \ - > /tmp/repositories.json - done - - mv /tmp/repositories.json /var/lib/docker/image/overlay2/repositories.json - ''; - serviceConfig = { - Type = "oneshot"; - }; - }; - }; -} diff --git a/nixos/modules/virtualisation/qemu-vm.nix b/nixos/modules/virtualisation/qemu-vm.nix index a650dd72c2a..42e43f5ee02 100644 --- a/nixos/modules/virtualisation/qemu-vm.nix +++ b/nixos/modules/virtualisation/qemu-vm.nix @@ -264,7 +264,6 @@ in { imports = [ ../profiles/qemu-guest.nix - ./docker-preloader.nix ]; options = { diff --git a/nixos/tests/all-tests.nix b/nixos/tests/all-tests.nix index 0ce5f89b27c..7b8e1b2b56d 100644 --- a/nixos/tests/all-tests.nix +++ b/nixos/tests/all-tests.nix @@ -66,11 +66,13 @@ in containers-macvlans = handleTest ./containers-macvlans.nix {}; containers-physical_interfaces = handleTest ./containers-physical_interfaces.nix {}; containers-portforward = handleTest ./containers-portforward.nix {}; + containers-reloadable = handleTest ./containers-reloadable.nix {}; containers-restart_networking = handleTest ./containers-restart_networking.nix {}; containers-tmpfs = handleTest ./containers-tmpfs.nix {}; convos = handleTest ./convos.nix {}; corerad = handleTest ./corerad.nix {}; couchdb = handleTest ./couchdb.nix {}; + cri-o = handleTestOn ["x86_64-linux"] ./cri-o.nix {}; deluge = handleTest ./deluge.nix {}; dhparams = handleTest ./dhparams.nix {}; dnscrypt-proxy2 = handleTestOn ["x86_64-linux"] ./dnscrypt-proxy2.nix {}; @@ -79,15 +81,13 @@ in docker = handleTestOn ["x86_64-linux"] ./docker.nix {}; oci-containers = handleTestOn ["x86_64-linux"] ./oci-containers.nix {}; docker-edge = handleTestOn ["x86_64-linux"] ./docker-edge.nix {}; - docker-preloader = handleTestOn ["x86_64-linux"] ./docker-preloader.nix {}; docker-registry = handleTest ./docker-registry.nix {}; docker-tools = handleTestOn ["x86_64-linux"] ./docker-tools.nix {}; docker-tools-overlay = handleTestOn ["x86_64-linux"] ./docker-tools-overlay.nix {}; documize = handleTest ./documize.nix {}; dokuwiki = handleTest ./dokuwiki.nix {}; dovecot = handleTest ./dovecot.nix {}; - # ec2-config doesn't work in a sandbox as the simulated ec2 instance needs network access - #ec2-config = (handleTestOn ["x86_64-linux"] ./ec2.nix {}).boot-ec2-config or {}; + ec2-config = (handleTestOn ["x86_64-linux"] ./ec2.nix {}).boot-ec2-config or {}; ec2-nixops = (handleTestOn ["x86_64-linux"] ./ec2.nix {}).boot-ec2-nixops or {}; ecryptfs = handleTest ./ecryptfs.nix {}; ejabberd = handleTest ./xmpp/ejabberd.nix {}; diff --git a/nixos/tests/common/ec2.nix b/nixos/tests/common/ec2.nix index ba087bb6009..502fe96231f 100644 --- a/nixos/tests/common/ec2.nix +++ b/nixos/tests/common/ec2.nix @@ -20,30 +20,44 @@ with pkgs.lib; in makeTest { name = "ec2-" + name; nodes = {}; - testScript = - '' - my $imageDir = ($ENV{'TMPDIR'} // "/tmp") . "/vm-state-machine"; - mkdir $imageDir, 0700; - my $diskImage = "$imageDir/machine.qcow2"; - system("qemu-img create -f qcow2 -o backing_file=${image} $diskImage") == 0 or die; - system("qemu-img resize $diskImage 10G") == 0 or die; + testScript = '' + import os + import subprocess - # Note: we use net=169.0.0.0/8 rather than - # net=169.254.0.0/16 to prevent dhcpcd from getting horribly - # confused. (It would get a DHCP lease in the 169.254.* - # range, which it would then configure and prompty delete - # again when it deletes link-local addresses.) Ideally we'd - # turn off the DHCP server, but qemu does not have an option - # to do that. - my $startCommand = "qemu-kvm -m 1024"; - $startCommand .= " -device virtio-net-pci,netdev=vlan0"; - $startCommand .= " -netdev 'user,id=vlan0,net=169.0.0.0/8,guestfwd=tcp:169.254.169.254:80-cmd:${pkgs.micro-httpd}/bin/micro_httpd ${metaData}'"; - $startCommand .= " -drive file=$diskImage,if=virtio,werror=report"; - $startCommand .= " \$QEMU_OPTS"; + image_dir = os.path.join( + os.environ.get("TMPDIR", tempfile.gettempdir()), "tmp", "vm-state-machine" + ) + os.makedirs(image_dir, mode=0o700, exist_ok=True) + disk_image = os.path.join(image_dir, "machine.qcow2") + subprocess.check_call( + [ + "qemu-img", + "create", + "-f", + "qcow2", + "-o", + "backing_file=${image}", + disk_image, + ] + ) + subprocess.check_call(["qemu-img", "resize", disk_image, "10G"]) - my $machine = createMachine({ startCommand => $startCommand }); + # Note: we use net=169.0.0.0/8 rather than + # net=169.254.0.0/16 to prevent dhcpcd from getting horribly + # confused. (It would get a DHCP lease in the 169.254.* + # range, which it would then configure and prompty delete + # again when it deletes link-local addresses.) Ideally we'd + # turn off the DHCP server, but qemu does not have an option + # to do that. + start_command = ( + "qemu-kvm -m 1024" + + " -device virtio-net-pci,netdev=vlan0" + + " -netdev 'user,id=vlan0,net=169.0.0.0/8,guestfwd=tcp:169.254.169.254:80-cmd:${pkgs.micro-httpd}/bin/micro_httpd ${metaData}'" + + f" -drive file={disk_image},if=virtio,werror=report" + + " $QEMU_OPTS" + ) - ${script} - ''; + machine = create_machine({"startCommand": start_command}) + '' + script; }; } diff --git a/nixos/tests/containers-reloadable.nix b/nixos/tests/containers-reloadable.nix index 35aff91e85b..2d81f163938 100644 --- a/nixos/tests/containers-reloadable.nix +++ b/nixos/tests/containers-reloadable.nix @@ -9,13 +9,13 @@ let }; }; - # prevent make-test.nix to change IP + # prevent make-test-python.nix to change IP networking.interfaces = { eth1.ipv4.addresses = lib.mkOverride 0 [ ]; }; }; in { - name = "cotnainers-reloadable"; + name = "containers-reloadable"; meta = with pkgs.stdenv.lib.maintainers; { maintainers = [ danbst ]; }; diff --git a/nixos/tests/cri-o.nix b/nixos/tests/cri-o.nix new file mode 100644 index 00000000000..f13f1bdacb6 --- /dev/null +++ b/nixos/tests/cri-o.nix @@ -0,0 +1,19 @@ +# This test runs CRI-O and verifies via critest +import ./make-test-python.nix ({ pkgs, ... }: { + name = "cri-o"; + maintainers = with pkgs.stdenv.lib.maintainers; teams.podman.members; + + nodes = { + crio = { + virtualisation.cri-o.enable = true; + }; + }; + + testScript = '' + start_all() + crio.wait_for_unit("crio.service") + crio.succeed( + "critest --ginkgo.focus='Runtime info' --runtime-endpoint unix:///var/run/crio/crio.sock" + ) + ''; +}) diff --git a/nixos/tests/docker-preloader.nix b/nixos/tests/docker-preloader.nix deleted file mode 100644 index c3e8aced351..00000000000 --- a/nixos/tests/docker-preloader.nix +++ /dev/null @@ -1,27 +0,0 @@ -import ./make-test.nix ({ pkgs, ...} : { - name = "docker-preloader"; - meta = with pkgs.stdenv.lib.maintainers; { - maintainers = [ lewo ]; - }; - - nodes = { - docker = - { pkgs, ... }: - { - virtualisation.docker.enable = true; - virtualisation.dockerPreloader.images = [ pkgs.dockerTools.examples.nix pkgs.dockerTools.examples.bash ]; - - services.openssh.enable = true; - services.openssh.permitRootLogin = "yes"; - services.openssh.extraConfig = "PermitEmptyPasswords yes"; - users.extraUsers.root.password = ""; - }; - }; - testScript = '' - startAll; - - $docker->waitForUnit("sockets.target"); - $docker->succeed("docker run nix nix-store --version"); - $docker->succeed("docker run bash bash --version"); - ''; -}) diff --git a/nixos/tests/ec2.nix b/nixos/tests/ec2.nix index 5a59d65e602..df067248016 100644 --- a/nixos/tests/ec2.nix +++ b/nixos/tests/ec2.nix @@ -3,58 +3,58 @@ pkgs ? import ../.. { inherit system config; } }: -with import ../lib/testing.nix { inherit system pkgs; }; +with import ../lib/testing-python.nix { inherit system pkgs; }; with pkgs.lib; with import common/ec2.nix { inherit makeTest pkgs; }; let - imageCfg = - (import ../lib/eval-config.nix { - inherit system; - modules = [ - ../maintainers/scripts/ec2/amazon-image.nix - ../modules/testing/test-instrumentation.nix - ../modules/profiles/qemu-guest.nix - { ec2.hvm = true; - - # Hack to make the partition resizing work in QEMU. - boot.initrd.postDeviceCommands = mkBefore - '' - ln -s vda /dev/xvda - ln -s vda1 /dev/xvda1 - ''; - - # Needed by nixos-rebuild due to the lack of network - # access. Determined by trial and error. - system.extraDependencies = - with pkgs; ( - [ - # Needed for a nixos-rebuild. - busybox - stdenv - stdenvNoCC - mkinitcpio-nfs-utils - unionfs-fuse - cloud-utils - desktop-file-utils - texinfo - libxslt.bin - xorg.lndir - - # These are used in the configure-from-userdata tests - # for EC2. Httpd and valgrind are requested by the - # configuration. - apacheHttpd apacheHttpd.doc apacheHttpd.man valgrind.doc - ] - ); - } - ]; - }).config; + imageCfg = (import ../lib/eval-config.nix { + inherit system; + modules = [ + ../maintainers/scripts/ec2/amazon-image.nix + ../modules/testing/test-instrumentation.nix + ../modules/profiles/qemu-guest.nix + { + ec2.hvm = true; + + # Hack to make the partition resizing work in QEMU. + boot.initrd.postDeviceCommands = mkBefore '' + ln -s vda /dev/xvda + ln -s vda1 /dev/xvda1 + ''; + + # Needed by nixos-rebuild due to the lack of network + # access. Determined by trial and error. + system.extraDependencies = with pkgs; ( [ + # Needed for a nixos-rebuild. + busybox + cloud-utils + desktop-file-utils + libxslt.bin + mkinitcpio-nfs-utils + stdenv + stdenvNoCC + texinfo + unionfs-fuse + xorg.lndir + + # These are used in the configure-from-userdata tests + # for EC2. Httpd and valgrind are requested by the + # configuration. + apacheHttpd + apacheHttpd.doc + apacheHttpd.man + valgrind.doc + ]); + } + ]; + }).config; image = "${imageCfg.system.build.amazonImage}/${imageCfg.amazonImage.name}.vhd"; sshKeys = import ./ssh-keys.nix pkgs; snakeOilPrivateKey = sshKeys.snakeOilPrivateKey.text; + snakeOilPrivateKeyFile = pkgs.writeText "private-key" snakeOilPrivateKey; snakeOilPublicKey = sshKeys.snakeOilPublicKey; in { @@ -68,43 +68,47 @@ in { SSH_HOST_ED25519_KEY:${replaceStrings ["\n"] ["|"] snakeOilPrivateKey} ''; script = '' - $machine->start; - $machine->waitForFile("/etc/ec2-metadata/user-data"); - $machine->waitForUnit("sshd.service"); + machine.start() + machine.wait_for_file("/etc/ec2-metadata/user-data") + machine.wait_for_unit("sshd.service") - $machine->succeed("grep unknown /etc/ec2-metadata/ami-manifest-path"); + machine.succeed("grep unknown /etc/ec2-metadata/ami-manifest-path") # We have no keys configured on the client side yet, so this should fail - $machine->fail("ssh -o BatchMode=yes localhost exit"); + machine.fail("ssh -o BatchMode=yes localhost exit") # Let's install our client private key - $machine->succeed("mkdir -p ~/.ssh"); + machine.succeed("mkdir -p ~/.ssh") - $machine->succeed("echo '${snakeOilPrivateKey}' > ~/.ssh/id_ed25519"); - $machine->succeed("chmod 600 ~/.ssh/id_ed25519"); + machine.copy_from_host_via_shell( + "${snakeOilPrivateKeyFile}", "~/.ssh/id_ed25519" + ) + machine.succeed("chmod 600 ~/.ssh/id_ed25519") # We haven't configured the host key yet, so this should still fail - $machine->fail("ssh -o BatchMode=yes localhost exit"); + machine.fail("ssh -o BatchMode=yes localhost exit") # Add the host key; ssh should finally succeed - $machine->succeed("echo localhost,127.0.0.1 ${snakeOilPublicKey} > ~/.ssh/known_hosts"); - $machine->succeed("ssh -o BatchMode=yes localhost exit"); + machine.succeed( + "echo localhost,127.0.0.1 ${snakeOilPublicKey} > ~/.ssh/known_hosts" + ) + machine.succeed("ssh -o BatchMode=yes localhost exit") # Test whether the root disk was resized. - my $blocks = $machine->succeed("stat -c %b -f /"); - my $bsize = $machine->succeed("stat -c %S -f /"); - my $size = $blocks * $bsize; - die "wrong free space $size" if $size < 9.7 * 1024 * 1024 * 1024 || $size > 10 * 1024 * 1024 * 1024; + blocks, block_size = map(int, machine.succeed("stat -c %b:%S -f /").split(":")) + GB = 1024 ** 3 + assert 9.7 * GB <= blocks * block_size <= 10 * GB # Just to make sure resizing is idempotent. - $machine->shutdown; - $machine->start; - $machine->waitForFile("/etc/ec2-metadata/user-data"); + machine.shutdown() + machine.start() + machine.wait_for_file("/etc/ec2-metadata/user-data") ''; }; boot-ec2-config = makeEc2Test { name = "config-userdata"; + meta.broken = true; # amazon-init wants to download from the internet while building the system inherit image; sshPublicKey = snakeOilPublicKey; @@ -133,17 +137,17 @@ in { } ''; script = '' - $machine->start; + machine.start() # amazon-init must succeed. if it fails, make the test fail - # immediately instead of timing out in waitForFile. - $machine->waitForUnit('amazon-init.service'); + # immediately instead of timing out in wait_for_file. + machine.wait_for_unit("amazon-init.service") - $machine->waitForFile("/etc/testFile"); - $machine->succeed("cat /etc/testFile | grep -q 'whoa'"); + machine.wait_for_file("/etc/testFile") + assert "whoa" in machine.succeed("cat /etc/testFile") - $machine->waitForUnit("httpd.service"); - $machine->succeed("curl http://localhost | grep Valgrind"); + machine.wait_for_unit("httpd.service") + assert "Valgrind" in machine.succeed("curl http://localhost") ''; }; } diff --git a/nixos/tests/gnome3.nix b/nixos/tests/gnome3.nix index b3d7aff8bd7..7e301be49d1 100644 --- a/nixos/tests/gnome3.nix +++ b/nixos/tests/gnome3.nix @@ -23,6 +23,13 @@ import ./make-test-python.nix ({ pkgs, lib, ...} : { services.xserver.desktopManager.gnome3.enable = true; services.xserver.desktopManager.gnome3.debug = true; + environment.systemPackages = [ + (pkgs.makeAutostartItem { + name = "org.gnome.Terminal"; + package = pkgs.gnome3.gnome-terminal; + }) + ]; + virtualisation.memorySize = 1024; }; @@ -65,9 +72,6 @@ import ./make-test-python.nix ({ pkgs, lib, ...} : { ) with subtest("Open Gnome Terminal"): - machine.succeed( - "${gnomeTerminalCommand}" - ) # correct output should be (true, '"gnome-terminal-server"') machine.wait_until_succeeds( "${wmClass} | grep -q 'gnome-terminal-server'" diff --git a/nixos/tests/hardened.nix b/nixos/tests/hardened.nix index 5ed0dfcf9ab..8d845de70e2 100644 --- a/nixos/tests/hardened.nix +++ b/nixos/tests/hardened.nix @@ -1,4 +1,4 @@ -import ./make-test.nix ({ pkgs, latestKernel ? false, ... } : { +import ./make-test-python.nix ({ pkgs, latestKernel ? false, ... } : { name = "hardened"; meta = with pkgs.stdenv.lib.maintainers; { maintainers = [ joachifm ]; @@ -47,84 +47,88 @@ import ./make-test.nix ({ pkgs, latestKernel ? false, ... } : { }; in '' - $machine->waitForUnit("multi-user.target"); + machine.wait_for_unit("multi-user.target") + + + with subtest("AppArmor profiles are loaded"): + machine.succeed("systemctl status apparmor.service") - subtest "apparmor-loaded", sub { - $machine->succeed("systemctl status apparmor.service"); - }; # AppArmor securityfs - subtest "apparmor-securityfs", sub { - $machine->succeed("mountpoint -q /sys/kernel/security"); - $machine->succeed("cat /sys/kernel/security/apparmor/profiles"); - }; + with subtest("AppArmor securityfs is mounted"): + machine.succeed("mountpoint -q /sys/kernel/security") + machine.succeed("cat /sys/kernel/security/apparmor/profiles") + # Test loading out-of-tree modules - subtest "extra-module-packages", sub { - $machine->succeed("grep -Fq wireguard /proc/modules"); - }; + with subtest("Out-of-tree modules can be loaded"): + machine.succeed("grep -Fq wireguard /proc/modules") + # Test hidepid - subtest "hidepid", sub { - $machine->succeed("grep -Fq hidepid=2 /proc/mounts"); + with subtest("hidepid=2 option is applied and works"): + machine.succeed("grep -Fq hidepid=2 /proc/mounts") # cannot use pgrep -u here, it segfaults when access to process info is denied - $machine->succeed("[ `su - sybil -c 'ps --no-headers --user root | wc -l'` = 0 ]"); - $machine->succeed("[ `su - alice -c 'ps --no-headers --user root | wc -l'` != 0 ]"); - }; + machine.succeed("[ `su - sybil -c 'ps --no-headers --user root | wc -l'` = 0 ]") + machine.succeed("[ `su - alice -c 'ps --no-headers --user root | wc -l'` != 0 ]") + # Test kernel module hardening - subtest "lock-modules", sub { + with subtest("No more kernel modules can be loaded"): # note: this better a be module we normally wouldn't load ... - $machine->fail("modprobe dccp"); - }; + machine.fail("modprobe dccp") + # Test userns - subtest "userns", sub { - $machine->succeed("unshare --user true"); - $machine->fail("su -l alice -c 'unshare --user true'"); - }; + with subtest("User namespaces are restricted"): + machine.succeed("unshare --user true") + machine.fail("su -l alice -c 'unshare --user true'") + # Test dmesg restriction - subtest "dmesg", sub { - $machine->fail("su -l alice -c dmesg"); - }; + with subtest("Regular users cannot access dmesg"): + machine.fail("su -l alice -c dmesg") + # Test access to kcore - subtest "kcore", sub { - $machine->fail("cat /proc/kcore"); - }; + with subtest("Kcore is inaccessible as root"): + machine.fail("cat /proc/kcore") + # Test deferred mount - subtest "mount", sub { - $machine->fail("mountpoint -q /efi"); # was deferred - $machine->execute("mkdir -p /efi"); - $machine->succeed("mount /dev/disk/by-label/EFISYS /efi"); - $machine->succeed("mountpoint -q /efi"); # now mounted - }; + with subtest("Deferred mounts work"): + machine.fail("mountpoint -q /efi") # was deferred + machine.execute("mkdir -p /efi") + machine.succeed("mount /dev/disk/by-label/EFISYS /efi") + machine.succeed("mountpoint -q /efi") # now mounted + # Test Nix dæmon usage - subtest "nix-daemon", sub { - $machine->fail("su -l nobody -s /bin/sh -c 'nix ping-store'"); - $machine->succeed("su -l alice -c 'nix ping-store'") =~ "OK"; - }; + with subtest("nix-daemon cannot be used by all users"): + machine.fail("su -l nobody -s /bin/sh -c 'nix ping-store'") + machine.succeed("su -l alice -c 'nix ping-store'") + # Test kernel image protection - subtest "kernelimage", sub { - $machine->fail("systemctl hibernate"); - $machine->fail("systemctl kexec"); - }; + with subtest("The kernel image is protected"): + machine.fail("systemctl hibernate") + machine.fail("systemctl kexec") - # Test hardened memory allocator - sub runMallocTestProg { - my ($progName, $errorText) = @_; - my $text = "fatal allocator error: " . $errorText; - $machine->fail("${hardened-malloc-tests}/bin/" . $progName) =~ $text; - }; - subtest "hardenedmalloc", sub { - runMallocTestProg("double_free_large", "invalid free"); - runMallocTestProg("unaligned_free_small", "invalid unaligned free"); - runMallocTestProg("write_after_free_small", "detected write after free"); - }; + # Test hardened memory allocator + def runMallocTestProg(prog_name, error_text): + text = "fatal allocator error: " + error_text + if not text in machine.fail( + "${hardened-malloc-tests}/bin/" + + prog_name + + " 2>&1" + ): + raise Exception("Hardened malloc does not work for {}".format(error_text)) + + + with subtest("The hardened memory allocator works"): + runMallocTestProg("double_free_large", "invalid free") + runMallocTestProg("unaligned_free_small", "invalid unaligned free") + runMallocTestProg("write_after_free_small", "detected write after free") ''; }) diff --git a/nixos/tests/hocker-fetchdocker/default.nix b/nixos/tests/hocker-fetchdocker/default.nix index 4f30f01e403..978dbf310b1 100644 --- a/nixos/tests/hocker-fetchdocker/default.nix +++ b/nixos/tests/hocker-fetchdocker/default.nix @@ -1,15 +1,16 @@ -import ../make-test.nix ({ pkgs, ...} : { +import ../make-test-python.nix ({ pkgs, ...} : { name = "test-hocker-fetchdocker"; meta = with pkgs.stdenv.lib.maintainers; { maintainers = [ ixmatus ]; + broken = true; # tries to download from registry-1.docker.io - how did this ever work? }; machine = import ./machine.nix; testScript = '' - startAll; + start_all() - $machine->waitForUnit("sockets.target"); - $machine->waitUntilSucceeds("docker run registry-1.docker.io/v2/library/hello-world:latest"); + machine.wait_for_unit("sockets.target") + machine.wait_until_succeeds("docker run registry-1.docker.io/v2/library/hello-world:latest") ''; }) diff --git a/nixos/tests/installer.nix b/nixos/tests/installer.nix index 02b839fee3f..50c6af485da 100644 --- a/nixos/tests/installer.nix +++ b/nixos/tests/installer.nix @@ -799,7 +799,7 @@ in { "btrfs subvol create /mnt/badpath/boot", "btrfs subvol create /mnt/nixos", "btrfs subvol set-default " - + "$(btrfs subvol list /mnt | grep 'nixos' | awk '{print \$2}') /mnt", + + "$(btrfs subvol list /mnt | grep 'nixos' | awk '{print $2}') /mnt", "umount /mnt", "mount -o defaults LABEL=root /mnt", "mkdir -p /mnt/badpath/boot", # Help ensure the detection mechanism diff --git a/nixos/tests/openstack-image.nix b/nixos/tests/openstack-image.nix index 97c9137fe1d..0b57dfb8e7e 100644 --- a/nixos/tests/openstack-image.nix +++ b/nixos/tests/openstack-image.nix @@ -3,30 +3,30 @@ pkgs ? import ../.. { inherit system config; } }: -with import ../lib/testing.nix { inherit system pkgs; }; +with import ../lib/testing-python.nix { inherit system pkgs; }; with pkgs.lib; with import common/ec2.nix { inherit makeTest pkgs; }; let - image = - (import ../lib/eval-config.nix { - inherit system; - modules = [ - ../maintainers/scripts/openstack/openstack-image.nix - ../modules/testing/test-instrumentation.nix - ../modules/profiles/qemu-guest.nix - { - # Needed by nixos-rebuild due to lack of network access. - system.extraDependencies = with pkgs; [ - stdenv - ]; - } - ]; - }).config.system.build.openstackImage + "/nixos.qcow2"; + image = (import ../lib/eval-config.nix { + inherit system; + modules = [ + ../maintainers/scripts/openstack/openstack-image.nix + ../modules/testing/test-instrumentation.nix + ../modules/profiles/qemu-guest.nix + { + # Needed by nixos-rebuild due to lack of network access. + system.extraDependencies = with pkgs; [ + stdenv + ]; + } + ]; + }).config.system.build.openstackImage + "/nixos.qcow2"; sshKeys = import ./ssh-keys.nix pkgs; snakeOilPrivateKey = sshKeys.snakeOilPrivateKey.text; + snakeOilPrivateKeyFile = pkgs.writeText "private-key" snakeOilPrivateKey; snakeOilPublicKey = sshKeys.snakeOilPublicKey; in { @@ -39,32 +39,36 @@ in { SSH_HOST_ED25519_KEY:${replaceStrings ["\n"] ["|"] snakeOilPrivateKey} ''; script = '' - $machine->start; - $machine->waitForFile("/etc/ec2-metadata/user-data"); - $machine->waitForUnit("sshd.service"); + machine.start() + machine.wait_for_file("/etc/ec2-metadata/user-data") + machine.wait_for_unit("sshd.service") - $machine->succeed("grep unknown /etc/ec2-metadata/ami-manifest-path"); + machine.succeed("grep unknown /etc/ec2-metadata/ami-manifest-path") # We have no keys configured on the client side yet, so this should fail - $machine->fail("ssh -o BatchMode=yes localhost exit"); + machine.fail("ssh -o BatchMode=yes localhost exit") # Let's install our client private key - $machine->succeed("mkdir -p ~/.ssh"); + machine.succeed("mkdir -p ~/.ssh") - $machine->succeed("echo '${snakeOilPrivateKey}' > ~/.ssh/id_ed25519"); - $machine->succeed("chmod 600 ~/.ssh/id_ed25519"); + machine.copy_from_host_via_shell( + "${snakeOilPrivateKeyFile}", "~/.ssh/id_ed25519" + ) + machine.succeed("chmod 600 ~/.ssh/id_ed25519") # We haven't configured the host key yet, so this should still fail - $machine->fail("ssh -o BatchMode=yes localhost exit"); + machine.fail("ssh -o BatchMode=yes localhost exit") # Add the host key; ssh should finally succeed - $machine->succeed("echo localhost,127.0.0.1 ${snakeOilPublicKey} > ~/.ssh/known_hosts"); - $machine->succeed("ssh -o BatchMode=yes localhost exit"); + machine.succeed( + "echo localhost,127.0.0.1 ${snakeOilPublicKey} > ~/.ssh/known_hosts" + ) + machine.succeed("ssh -o BatchMode=yes localhost exit") # Just to make sure resizing is idempotent. - $machine->shutdown; - $machine->start; - $machine->waitForFile("/etc/ec2-metadata/user-data"); + machine.shutdown() + machine.start() + machine.wait_for_file("/etc/ec2-metadata/user-data") ''; }; @@ -86,9 +90,9 @@ in { } ''; script = '' - $machine->start; - $machine->waitForFile("/etc/testFile"); - $machine->succeed("cat /etc/testFile | grep -q 'whoa'"); + machine.start() + machine.wait_for_file("/etc/testFile") + assert "whoa" in machine.succeed("cat /etc/testFile") ''; }; } |