Add vmTest for Nixinate #16
7 changed files with 186 additions and 128 deletions
12
.gitignore
vendored
Normal file
12
.gitignore
vendored
Normal file
|
@ -0,0 +1,12 @@
|
|||
# Prevents Nix results from `nix build`, etc, from being checked in
|
||||
# accidentally.
|
||||
*result*
|
||||
|
||||
# Github Workflows are not what we use to perform CI, we use Hercules-CI
|
||||
# instead.
|
||||
.github/workflows
|
||||
|
||||
# Dockerfiles, or docker-compose files are not how we build or deploy software.
|
||||
# Only Nix expressions are allowed.
|
||||
*Dockerfile*
|
||||
*docker-compose*
|
124
examples/flake.lock
generated
124
examples/flake.lock
generated
|
@ -1,124 +0,0 @@
|
|||
{
|
||||
"nodes": {
|
||||
"examples": {
|
||||
"inputs": {
|
||||
"nixinate": "nixinate_2",
|
||||
"nixpkgs": "nixpkgs_2"
|
||||
},
|
||||
"locked": {
|
||||
"narHash": "sha256-1iruH96Aame+4NAAwSwVZAbHzfnKxhMLjgoVvJar6ls=",
|
||||
"path": "./examples",
|
||||
"type": "path"
|
||||
},
|
||||
"original": {
|
||||
"path": "./examples",
|
||||
"type": "path"
|
||||
}
|
||||
},
|
||||
"nixinate": {
|
||||
"inputs": {
|
||||
"examples": "examples",
|
||||
"nixpkgs": "nixpkgs_3"
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1646587087,
|
||||
"narHash": "sha256-SwOHL/tte1H8VvftnxtWCr5FIlZaGvNy57P9sMSrZ5Q=",
|
||||
"owner": "matthewcroughan",
|
||||
"repo": "nixinate",
|
||||
"rev": "886c6a2b3bef14cacf6c3021df0a75bb57f9fbc7",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "matthewcroughan",
|
||||
"repo": "nixinate",
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"nixinate_2": {
|
||||
"inputs": {
|
||||
"nixpkgs": "nixpkgs"
|
||||
},
|
||||
"locked": {
|
||||
"narHash": "sha256-lk8eIWYxtHqDT4ZmSFuXMlG067RdPqLCQocnN+hNE7U=",
|
||||
"path": "/etc/nixos/nixinate",
|
||||
"type": "path"
|
||||
},
|
||||
"original": {
|
||||
"path": "/etc/nixos/nixinate",
|
||||
"type": "path"
|
||||
}
|
||||
},
|
||||
"nixpkgs": {
|
||||
"locked": {
|
||||
"lastModified": 1640887906,
|
||||
"narHash": "sha256-Eupk1UlNicCD2UNZuEKt6yhE6kFWAxXM/HyziOjG9CA=",
|
||||
"owner": "nixos",
|
||||
"repo": "nixpkgs",
|
||||
"rev": "8a053bc2255659c5ca52706b9e12e76a8f50dbdd",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "nixos",
|
||||
"ref": "nixos-21.11",
|
||||
"repo": "nixpkgs",
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"nixpkgs_2": {
|
||||
"locked": {
|
||||
"lastModified": 1641147223,
|
||||
"narHash": "sha256-eJnmISYGR7LeqEev4bsI/qcU0SgeFKHs3jnL4vMGL+k=",
|
||||
"owner": "nixos",
|
||||
"repo": "nixpkgs",
|
||||
"rev": "08370e1e271f6fe00d302bebbe510fe0e2c611ca",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "nixos",
|
||||
"ref": "nixos-21.11",
|
||||
"repo": "nixpkgs",
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"nixpkgs_3": {
|
||||
"locked": {
|
||||
"lastModified": 1647893727,
|
||||
"narHash": "sha256-pOi7VdCb+s5Cwh5CS7YEZVRgH9uCmE87J5W7iXv29Ck=",
|
||||
"owner": "nixos",
|
||||
"repo": "nixpkgs",
|
||||
"rev": "1ec61dd4167f04be8d05c45780818826132eea0d",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "nixos",
|
||||
"ref": "nixos-unstable",
|
||||
"repo": "nixpkgs",
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"nixpkgs_4": {
|
||||
"locked": {
|
||||
"lastModified": 1641147223,
|
||||
"narHash": "sha256-eJnmISYGR7LeqEev4bsI/qcU0SgeFKHs3jnL4vMGL+k=",
|
||||
"owner": "nixos",
|
||||
"repo": "nixpkgs",
|
||||
"rev": "08370e1e271f6fe00d302bebbe510fe0e2c611ca",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "nixos",
|
||||
"ref": "nixos-21.11",
|
||||
"repo": "nixpkgs",
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"root": {
|
||||
"inputs": {
|
||||
"nixinate": "nixinate",
|
||||
"nixpkgs": "nixpkgs_4"
|
||||
}
|
||||
}
|
||||
},
|
||||
"root": "root",
|
||||
"version": 7
|
||||
}
|
24
flake.nix
24
flake.nix
|
@ -3,12 +3,15 @@
|
|||
inputs = {
|
||||
nixpkgs.url = "github:nixos/nixpkgs/nixos-unstable";
|
||||
};
|
||||
outputs = { self, nixpkgs, ... }:
|
||||
outputs = { self, nixpkgs, ... }@inputs:
|
||||
let
|
||||
version = builtins.substring 0 8 self.lastModifiedDate;
|
||||
supportedSystems = [ "x86_64-linux" "x86_64-darwin" "aarch64-linux" "aarch64-darwin" ];
|
||||
forAllSystems = nixpkgs.lib.genAttrs supportedSystems;
|
||||
nixpkgsFor = forAllSystems (system: import nixpkgs { inherit system; overlays = [ self.overlay ]; });
|
||||
forSystems = systems: f:
|
||||
nixpkgs.lib.genAttrs systems
|
||||
(system: f system nixpkgs.legacyPackages.${system});
|
||||
forAllSystems = forSystems supportedSystems;
|
||||
nixpkgsFor = forAllSystems (system: pkgs: import nixpkgs { inherit system; overlays = [ self.overlay ]; });
|
||||
in rec
|
||||
{
|
||||
overlay = final: prev: {
|
||||
|
@ -69,6 +72,19 @@
|
|||
);
|
||||
};
|
||||
};
|
||||
nixinate = forAllSystems (system: nixpkgsFor.${system}.generateApps);
|
||||
nixinate = forAllSystems (system: pkgs: nixpkgsFor.${system}.generateApps);
|
||||
checks = forAllSystems (system: pkgs:
|
||||
let
|
||||
vmTests = import ./tests {
|
||||
makeTest = (import (nixpkgs + "/nixos/lib/testing-python.nix") { inherit system; }).makeTest;
|
||||
inherit pkgs inputs;
|
||||
};
|
||||
in
|
||||
pkgs.lib.optionalAttrs pkgs.stdenv.isLinux vmTests # vmTests can only be ran on Linux, so append them only if on Linux.
|
||||
//
|
||||
{
|
||||
# Other checks here...
|
||||
}
|
||||
);
|
||||
};
|
||||
}
|
||||
|
|
5
tests/default.nix
Normal file
5
tests/default.nix
Normal file
|
@ -0,0 +1,5 @@
|
|||
{ pkgs, makeTest, inputs }:
|
||||
{
|
||||
vmTestLocal = (import ./vmTest { inherit pkgs makeTest inputs; }).local;
|
||||
vmTestRemote = (import ./vmTest { inherit pkgs makeTest inputs; }).remote;
|
||||
}
|
109
tests/vmTest/default.nix
Normal file
109
tests/vmTest/default.nix
Normal file
|
@ -0,0 +1,109 @@
|
|||
{ pkgs, makeTest, inputs }:
|
||||
let
|
||||
# Return a store path with a closure containing everything including
|
||||
# derivations and all build dependency outputs, all the way down.
|
||||
allDrvOutputs = pkg:
|
||||
let name = "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
|
||||
'';
|
||||
# Imports a flake with inputs passed in by hand, rather than
|
||||
# builtins.getFlake, which cannot be used in this way.
|
||||
callLocklessFlake = path: inputs: let
|
||||
r = {outPath = path;} //
|
||||
((import (path + "/flake.nix")).outputs (inputs // {self = r;}));
|
||||
in
|
||||
r;
|
||||
exampleFlake = pkgs.writeTextFile {
|
||||
name = "nixinate-example-flake";
|
||||
destination = "/flake.nix";
|
||||
text = ''
|
||||
{
|
||||
outputs = { self, nixpkgs }:
|
||||
let
|
||||
makeTest = (import (nixpkgs + "/nixos/lib/testing-python.nix") { system = "${pkgs.hostPlatform.system}"; }).makeTest;
|
||||
baseConfig = ((makeTest { nodes.baseConfig = { ... }: {}; testScript = "";}).nodes {}).baseConfig.extendModules {
|
||||
modules = [
|
||||
${builtins.readFile ./nixinateeBase.nix}
|
||||
${builtins.readFile ./nixinateeAdditional.nix}
|
||||
{
|
||||
_module.args.nixinate = {
|
||||
host = "nixinatee";
|
||||
sshUser = "nixinator";
|
||||
buildOn = "local"; # valid args are "local" or "remote"
|
||||
};
|
||||
}
|
||||
];
|
||||
};
|
||||
in
|
||||
{
|
||||
nixosConfigurations = {
|
||||
nixinatee = baseConfig;
|
||||
};
|
||||
};
|
||||
}
|
||||
'';
|
||||
};
|
||||
deployScript = inputs.self.nixinate.${pkgs.hostPlatform.system} (callLocklessFlake "${exampleFlake}" { nixpkgs = inputs.nixpkgs; });
|
||||
exampleSystem = (callLocklessFlake "${exampleFlake}" { nixpkgs = inputs.nixpkgs; }).nixosConfigurations.nixinatee.config.system.build.toplevel;
|
||||
mkNixinateTest = buildOn: makeTest {
|
||||
nodes = {
|
||||
nixinatee = { ... }: {
|
||||
imports = [
|
||||
./nixinateeBase.nix
|
||||
];
|
||||
virtualisation = {
|
||||
writableStore = true;
|
||||
};
|
||||
};
|
||||
nixinator = { ... }: {
|
||||
virtualisation = {
|
||||
additionalPaths = [
|
||||
(allDrvOutputs exampleSystem)
|
||||
]
|
||||
++ pkgs.lib.optional (buildOn == "remote") exampleFlake;
|
||||
};
|
||||
nix = {
|
||||
extraOptions =
|
||||
let empty_registry = builtins.toFile "empty-flake-registry.json" ''{"flakes":[],"version":2}''; in
|
||||
''
|
||||
experimental-features = nix-command flakes
|
||||
flake-registry = ${empty_registry}
|
||||
'';
|
||||
registry.nixpkgs.flake = inputs.nixpkgs;
|
||||
};
|
||||
};
|
||||
};
|
||||
testScript =
|
||||
''
|
||||
start_all()
|
||||
nixinatee.wait_for_unit("sshd.service")
|
||||
nixinator.wait_for_unit("multi-user.target")
|
||||
nixinator.succeed("mkdir ~/.ssh/")
|
||||
nixinator.succeed("ssh-keyscan -H nixinatee >> ~/.ssh/known_hosts")
|
||||
nixinator.succeed("exec ${deployScript.nixinate.nixinatee.program} >&2")
|
||||
nixinatee.wait_for_unit("nginx.service")
|
||||
nixinatee.wait_for_open_port("80")
|
||||
with subtest("Check that Nginx webserver can be reached by deployer after deployment"):
|
||||
assert "<title>Welcome to nginx!</title>" in nixinator.succeed(
|
||||
"curl -sSf http:/nixinatee/ | grep title"
|
||||
)
|
||||
with subtest("Check that Nginx webserver can be reached by deployee after deployment"):
|
||||
assert "<title>Welcome to nginx!</title>" in nixinatee.succeed(
|
||||
"curl -sSf http:/127.0.0.1/ | grep title"
|
||||
)
|
||||
'';
|
||||
};
|
||||
in
|
||||
{
|
||||
local = (mkNixinateTest "local");
|
||||
remote = (mkNixinateTest "remote");
|
||||
}
|
8
tests/vmTest/nixinateeAdditional.nix
Normal file
8
tests/vmTest/nixinateeAdditional.nix
Normal file
|
@ -0,0 +1,8 @@
|
|||
# Configuration that will be added to the nixinatee node. Nixinate will deploy
|
||||
# the combination of nixinateBase.nix + nixinateAdditional.nix
|
||||
{
|
||||
config = {
|
||||
services.nginx.enable = true;
|
||||
networking.firewall.allowedTCPPorts = [ 80 ];
|
||||
};
|
||||
}
|
32
tests/vmTest/nixinateeBase.nix
Normal file
32
tests/vmTest/nixinateeBase.nix
Normal file
|
@ -0,0 +1,32 @@
|
|||
# Common configuration of nixinatee node in the vmTest. This is the base
|
||||
# configuration which is required to perform the test.
|
||||
{
|
||||
config = {
|
||||
nix.trustedUsers = [ "nixinator" ];
|
||||
security.sudo.extraRules = [{
|
||||
users = [ "nixinator" ];
|
||||
commands = [{
|
||||
command = "ALL";
|
||||
options = [ "NOPASSWD" ];
|
||||
}];
|
||||
}];
|
||||
users = {
|
||||
mutableUsers = false;
|
||||
users = {
|
||||
nixinator = {
|
||||
extraGroups = [
|
||||
"wheel"
|
||||
];
|
||||
password = "";
|
||||
isNormalUser = true;
|
||||
};
|
||||
};
|
||||
};
|
||||
services.openssh = {
|
||||
enable = true;
|
||||
extraConfig = "PermitEmptyPasswords yes";
|
||||
};
|
||||
documentation.enable = false;
|
||||
boot.loader.grub.enable = false;
|
||||
};
|
||||
}
|
Loading…
Add table
Reference in a new issue