Merge pull request #142035 from hercules-ci/nixops-test

NixOps test

Changed files
+190 -13
nixos
lib
maintainers
scripts
azure-new
examples
basic
tests
pkgs
applications
networking
cluster
nixops
+11 -4
nixos/lib/build-vms.nix
···
prefixLength = 24;
} ];
});
-
in
-
{ key = "ip-address";
-
config =
+
+
networkConfig =
{ networking.hostName = mkDefault m.fst;
networking.interfaces = listToAttrs interfaces;
···
in flip concatMap interfacesNumbered
({ fst, snd }: qemu-common.qemuNICFlags snd fst m.snd);
};
-
}
+
+
in
+
{ key = "ip-address";
+
config = networkConfig // {
+
# Expose the networkConfig items for tests like nixops
+
# that need to recreate the network config.
+
system.build.networkConfig = networkConfig;
+
};
+
}
)
(getAttr m.fst nodes)
] );
+1 -1
nixos/maintainers/scripts/azure-new/examples/basic/image.nix
···
let
pkgs = (import ../../../../../../default.nix {});
-
machine = import "${pkgs.path}/nixos/lib/eval-config.nix" {
+
machine = import (pkgs.path + "/nixos/lib/eval-config.nix") {
system = "x86_64-linux";
modules = [
({config, ...}: { imports = [ ./system.nix ]; })
+1
nixos/tests/all-tests.nix
···
nitter = handleTest ./nitter.nix {};
nix-serve = handleTest ./nix-ssh-serve.nix {};
nix-ssh-serve = handleTest ./nix-ssh-serve.nix {};
+
nixops = handleTest ./nixops/default.nix {};
nixos-generate-config = handleTest ./nixos-generate-config.nix {};
node-red = handleTest ./node-red.nix {};
nomad = handleTest ./nomad.nix {};
+115
nixos/tests/nixops/default.nix
···
+
{ pkgs, ... }:
+
let
+
inherit (pkgs) lib;
+
+
tests = {
+
# TODO: uncomment stable
+
# - Blocked on https://github.com/NixOS/nixpkgs/issues/138584 which has a
+
# PR in staging: https://github.com/NixOS/nixpkgs/pull/139986
+
# - Alternatively, blocked on a NixOps 2 release
+
# https://github.com/NixOS/nixops/issues/1242
+
# stable = testsLegacyNetwork { nixopsPkg = pkgs.nixops; };
+
unstable = testsForPackage { nixopsPkg = pkgs.nixopsUnstable; };
+
+
# inherit testsForPackage;
+
};
+
+
testsForPackage = lib.makeOverridable (args: lib.recurseIntoAttrs {
+
legacyNetwork = testLegacyNetwork args;
+
});
+
+
testLegacyNetwork = { nixopsPkg }: pkgs.nixosTest ({
+
nodes = {
+
deployer = { config, lib, nodes, pkgs, ... }: {
+
imports = [ ../../modules/installer/cd-dvd/channel.nix ];
+
environment.systemPackages = [ nixopsPkg ];
+
nix.binaryCaches = lib.mkForce [ ];
+
users.users.person.isNormalUser = true;
+
virtualisation.writableStore = true;
+
virtualisation.memorySize = 1024 /*MiB*/;
+
virtualisation.pathsInNixDB = [
+
pkgs.hello
+
pkgs.figlet
+
+
# This includes build dependencies all the way down. Not efficient,
+
# but we do need build deps to an *arbitrary* depth, which is hard to
+
# determine.
+
(allDrvOutputs nodes.server.config.system.build.toplevel)
+
];
+
};
+
server = { lib, ... }: {
+
imports = [ ./legacy/base-configuration.nix ];
+
};
+
};
+
+
testScript = { nodes }:
+
let
+
deployerSetup = pkgs.writeScript "deployerSetup" ''
+
#!${pkgs.runtimeShell}
+
set -eux -o pipefail
+
cp --no-preserve=mode -r ${./legacy} unicorn
+
cp --no-preserve=mode ${../ssh-keys.nix} unicorn/ssh-keys.nix
+
mkdir -p ~/.ssh
+
cp ${snakeOilPrivateKey} ~/.ssh/id_ed25519
+
chmod 0400 ~/.ssh/id_ed25519
+
'';
+
serverNetworkJSON = pkgs.writeText "server-network.json"
+
(builtins.toJSON nodes.server.config.system.build.networkConfig);
+
in
+
''
+
import shlex
+
+
def deployer_do(cmd):
+
cmd = shlex.quote(cmd)
+
return deployer.succeed(f"su person -l -c {cmd} &>/dev/console")
+
+
start_all()
+
+
deployer_do("cat /etc/hosts")
+
+
deployer_do("${deployerSetup}")
+
deployer_do("cp ${serverNetworkJSON} unicorn/server-network.json")
+
+
# Establish that ssh works, regardless of nixops
+
# Easy way to accept the server host key too.
+
server.wait_for_open_port(22)
+
deployer.wait_for_unit("network.target")
+
+
# Put newlines on console, to flush the console reader's line buffer
+
# in case nixops' last output did not end in a newline, as is the case
+
# with a status line (if implemented?)
+
deployer.succeed("while sleep 60s; do echo [60s passed] >/dev/console; done &")
+
+
deployer_do("cd ~/unicorn; ssh -oStrictHostKeyChecking=accept-new root@server echo hi")
+
+
# Create and deploy
+
deployer_do("cd ~/unicorn; nixops create")
+
+
deployer_do("cd ~/unicorn; nixops deploy --confirm")
+
+
deployer_do("cd ~/unicorn; nixops ssh server 'hello | figlet'")
+
'';
+
});
+
+
inherit (import ../ssh-keys.nix pkgs) snakeOilPrivateKey snakeOilPublicKey;
+
+
/*
+
Return a store path with a closure containing everything including
+
derivations and all build dependency outputs, all the way down.
+
*/
+
allDrvOutputs = pkg:
+
let name = lib.strings.sanitizeDerivationName "allDrvOutputs-${pkg.pname or pkg.name or "unknown"}";
+
in
+
pkgs.runCommand name { refs = pkgs.writeReferencesToFile pkg.drvPath; } ''
+
touch $out
+
while read ref; do
+
case $ref in
+
*.drv)
+
cat $ref >>$out
+
;;
+
esac
+
done <$refs
+
'';
+
+
in
+
tests
+31
nixos/tests/nixops/legacy/base-configuration.nix
···
+
{ lib, modulesPath, pkgs, ... }:
+
let
+
ssh-keys =
+
if builtins.pathExists ../../ssh-keys.nix
+
then # Outside sandbox
+
../../ssh-keys.nix
+
else # In sandbox
+
./ssh-keys.nix;
+
+
inherit (import ssh-keys pkgs)
+
snakeOilPrivateKey snakeOilPublicKey;
+
in
+
{
+
imports = [
+
(modulesPath + "/virtualisation/qemu-vm.nix")
+
(modulesPath + "/testing/test-instrumentation.nix")
+
];
+
virtualisation.writableStore = true;
+
nix.binaryCaches = lib.mkForce [ ];
+
virtualisation.graphics = false;
+
documentation.enable = false;
+
services.qemuGuest.enable = true;
+
boot.loader.grub.enable = false;
+
+
services.openssh.enable = true;
+
users.users.root.openssh.authorizedKeys.keys = [
+
snakeOilPublicKey
+
];
+
security.pam.services.sshd.limits =
+
[{ domain = "*"; item = "memlock"; type = "-"; value = 1024; }];
+
}
+15
nixos/tests/nixops/legacy/nixops.nix
···
+
{
+
network = {
+
description = "Legacy Network using <nixpkgs> and legacy state.";
+
# NB this is not really what makes it a legacy network; lack of flakes is.
+
storage.legacy = { };
+
};
+
server = { lib, pkgs, ... }: {
+
deployment.targetEnv = "none";
+
imports = [
+
./base-configuration.nix
+
(lib.modules.importJSON ./server-network.json)
+
];
+
environment.systemPackages = [ pkgs.hello pkgs.figlet ];
+
};
+
}
+16 -8
pkgs/applications/networking/cluster/nixops/default.nix
···
-
{ pkgs
+
{ nixosTests
+
, pkgs
, poetry2nix
, lib
, overrides ? (self: super: {})
···
}
).python;
-
in interpreter.pkgs.nixops.withPlugins(ps: [
-
ps.nixops-encrypted-links
-
ps.nixops-virtd
-
ps.nixops-aws
-
ps.nixops-gcp
-
ps.nixopsvbox
-
])
+
pkg = interpreter.pkgs.nixops.withPlugins(ps: [
+
ps.nixops-encrypted-links
+
ps.nixops-virtd
+
ps.nixops-aws
+
ps.nixops-gcp
+
ps.nixopsvbox
+
]) // rec {
+
# Workaround for https://github.com/NixOS/nixpkgs/issues/119407
+
# TODO after #1199407: Use .overrideAttrs(pkg: old: { passthru.tests = .....; })
+
tests = nixosTests.nixops.unstable.override { nixopsPkg = pkg; };
+
# Not strictly necessary, but probably expected somewhere; part of the workaround:
+
passthru.tests = tests;
+
};
+
in pkg