system-manager/test/nix/modules/default.nix
2023-10-12 11:16:50 +02:00

295 lines
10 KiB
Nix

{ lib
, system-manager
, system
}:
let
images = lib.importJSON ../images.json;
forEachUbuntuImage = lib.flip lib.mapAttrs' images.ubuntu.${system};
# To test reload and restart, we include two services, one that can be reloaded
# and one that cannot.
# The id parameter is a string that can be used to force reloading the services
# between two configs by changing their contents.
testModule = id: { lib, pkgs, ... }: {
systemd.services = {
has-reload = {
enable = true;
description = "service-reload";
serviceConfig = {
Type = "oneshot";
RemainAfterExit = true;
ExecReload = ''
${lib.getBin pkgs.coreutils}/bin/true
'';
};
wantedBy = [ "system-manager.target" ];
script = ''
echo "I can be reloaded (id: ${id})"
'';
};
has-no-reload = {
enable = true;
description = "service-no-reload";
serviceConfig.Type = "simple";
wantedBy = [ "system-manager.target" ];
script = ''
while true; do
echo "I cannot be reloaded (id: ${id})"
done
'';
};
};
};
newConfig = system-manager.lib.makeSystemConfig {
modules = [
(testModule "new")
({ lib, pkgs, ... }: {
config = {
nixpkgs.hostPlatform = system;
services.nginx.enable = false;
environment = {
etc = {
foo_new = {
text = ''
This is just a test!
'';
};
};
systemPackages = [
pkgs.fish
];
};
systemd.services = {
new-service = {
enable = true;
description = "new-service";
serviceConfig = {
Type = "oneshot";
RemainAfterExit = true;
ExecReload = "${lib.getBin pkgs.coreutils}/bin/true";
};
wantedBy = [ "system-manager.target" "default.target" ];
script = ''
sleep 2
'';
};
};
};
})
];
};
in
forEachUbuntuImage
(imgName: image: lib.nameValuePair
"vm-test-example-${imgName}"
(system-manager.lib.make-vm-test "vm-test-example-${imgName}" {
inherit system;
modules = [
({ config, ... }:
let
inherit (config) hostPkgs;
in
{
nodes = {
node1 = { config, ... }: {
modules = [
(testModule "old")
../../../examples/example.nix
];
virtualisation.rootImage = system-manager.lib.prepareUbuntuImage {
inherit hostPkgs image;
nodeConfig = config;
};
};
};
testScript = ''
# Start all machines in parallel
start_all()
node1.wait_for_unit("default.target")
node1.succeed("touch /etc/foo_test")
node1.succeed("/system-manager-profile/bin/activate 2>&1 | tee /tmp/output.log")
node1.succeed("grep -F 'Error while creating file in /etc: Unmanaged path already exists in filesystem, please remove it and run system-manager again: /etc/foo_test' /tmp/output.log")
node1.succeed("rm /etc/foo_test")
${system-manager.lib.activateProfileSnippet { node = "node1"; }}
node1.wait_for_unit("system-manager.target")
node1.succeed("systemctl status service-9.service")
node1.succeed("test -f /etc/baz/bar/foo2")
node1.succeed("test -f /etc/a/nested/example/foo3")
node1.succeed("test -f /etc/foo.conf")
node1.succeed("grep -F 'launch_the_rockets = true' /etc/foo.conf")
node1.fail("grep -F 'launch_the_rockets = false' /etc/foo.conf")
node1.succeed("test -d /var/tmp/system-manager")
${system-manager.lib.activateProfileSnippet { node = "node1"; profile = newConfig; }}
node1.succeed("systemctl status new-service.service")
node1.fail("systemctl status service-9.service")
node1.fail("test -f /etc/a/nested/example/foo3")
node1.fail("test -f /etc/baz/bar/foo2")
node1.fail("test -f /etc/systemd/system/nginx.service")
node1.succeed("test -f /etc/foo_new")
node1.succeed("test -d /var/tmp/system-manager")
node1.succeed("touch /var/tmp/system-manager/foo1")
# Simulate a reboot, to check that the services defined with
# system-manager start correctly after a reboot.
# TODO: can we find an easy way to really reboot the VM and not
# loose the root FS state?
node1.systemctl("isolate rescue.target")
# We need to send a return character to dismiss the rescue-mode prompt
node1.send_key("ret")
node1.systemctl("isolate default.target")
node1.wait_for_unit("default.target")
node1.succeed("systemctl status new-service.service")
node1.fail("systemctl status service-9.service")
node1.fail("test -f /etc/a/nested/example/foo3")
node1.fail("test -f /etc/baz/bar/foo2")
node1.succeed("test -f /etc/foo_new")
${system-manager.lib.deactivateProfileSnippet { node = "node1"; profile = newConfig; }}
node1.fail("systemctl status new-service.service")
node1.fail("test -f /etc/foo_new")
#node1.fail("test -f /var/tmp/system-manager/foo1")
'';
})
];
})
)
//
forEachUbuntuImage
(imgName: image: lib.nameValuePair
"vm-test-prepopulate-${imgName}"
(system-manager.lib.make-vm-test "vm-test-prepopulate-${imgName}" {
inherit system;
modules = [
({ config, ... }:
let
inherit (config) hostPkgs;
in
{
nodes = {
node1 = { config, ... }: {
modules = [
../../../examples/example.nix
];
virtualisation.rootImage = system-manager.lib.prepareUbuntuImage {
inherit hostPkgs image;
nodeConfig = config;
};
};
};
testScript = ''
# Start all machines in parallel
start_all()
node1.wait_for_unit("default.target")
${system-manager.lib.prepopulateProfileSnippet { node = "node1"; }}
node1.systemctl("daemon-reload")
# Simulate a reboot, to check that the services defined with
# system-manager start correctly after a reboot.
# TODO: can we find an easy way to really reboot the VM and not
# loose the root FS state?
node1.systemctl("isolate rescue.target")
# We need to send a return character to dismiss the rescue-mode prompt
node1.send_key("ret")
node1.systemctl("isolate default.target")
node1.wait_for_unit("system-manager.target")
node1.succeed("systemctl status service-9.service")
node1.succeed("test -f /etc/baz/bar/foo2")
node1.succeed("test -f /etc/a/nested/example/foo3")
node1.succeed("test -f /etc/foo.conf")
node1.succeed("grep -F 'launch_the_rockets = true' /etc/foo.conf")
node1.fail("grep -F 'launch_the_rockets = false' /etc/foo.conf")
${system-manager.lib.activateProfileSnippet { node = "node1"; profile = newConfig; }}
node1.succeed("systemctl status new-service.service")
node1.fail("systemctl status service-9.service")
node1.fail("test -f /etc/a/nested/example/foo3")
node1.fail("test -f /etc/baz/bar/foo2")
node1.succeed("test -f /etc/foo_new")
${system-manager.lib.deactivateProfileSnippet { node = "node1"; profile = newConfig; }}
node1.fail("systemctl status new-service.service")
node1.fail("test -f /etc/foo_new")
'';
}
)
];
})
)
//
forEachUbuntuImage
(imgName: image: lib.nameValuePair
"vm-test-system-path-${imgName}"
(system-manager.lib.make-vm-test "vm-test-system-path-${imgName}" {
inherit system;
modules = [
({ config, ... }:
let
inherit (config) hostPkgs;
in
{
nodes = {
node1 = { config, ... }: {
modules = [
../../../examples/example.nix
];
virtualisation.rootImage = system-manager.lib.prepareUbuntuImage {
inherit hostPkgs image;
nodeConfig = config;
};
};
};
testScript = ''
# Start all machines in parallel
start_all()
node1.wait_for_unit("default.target")
node1.fail("bash --login -c '$(which rg)'")
node1.fail("bash --login -c '$(which fd)'")
${system-manager.lib.activateProfileSnippet { node = "node1"; }}
node1.wait_for_unit("system-manager.target")
node1.wait_for_unit("system-manager-path.service")
node1.fail("bash --login -c '$(which fish)'")
node1.succeed("bash --login -c 'realpath $(which rg) | grep -F ${hostPkgs.ripgrep}/bin/rg'")
node1.succeed("bash --login -c 'realpath $(which fd) | grep -F ${hostPkgs.fd}/bin/fd'")
${system-manager.lib.activateProfileSnippet { node = "node1"; profile = newConfig; }}
node1.fail("bash --login -c '$(which rg)'")
node1.fail("bash --login -c '$(which fd)'")
node1.succeed("bash --login -c 'realpath $(which fish) | grep -F ${hostPkgs.fish}/bin/fish'")
'';
})
];
})
)