From 316ec8c526223ee60aec62cad75ce15a3cb4c8b4 Mon Sep 17 00:00:00 2001 From: a-kenji Date: Wed, 11 Jun 2025 13:47:29 +0200 Subject: [PATCH] borgbackup: Move tests close to service --- checks/flake-module.nix | 1 - clanServices/borgbackup/flake-module.nix | 13 +- clanServices/borgbackup/tests/vm/default.nix | 118 ++++++++++++++++++ .../tests/vm/sops/machines/clientone/key.json | 6 + .../vm/sops/secrets/clientone-age.key/secret | 15 +++ .../secrets/clientone-age.key/users/admin | 1 + .../tests/vm/sops/users/admin/key.json | 4 + .../borgbackup.repokey/machines/clientone | 1 + .../borgbackup/borgbackup.repokey/secret | 19 +++ .../borgbackup/borgbackup.repokey/users/admin | 1 + .../borgbackup/borgbackup.ssh.pub/value | 1 + .../borgbackup.ssh/machines/clientone | 1 + .../borgbackup/borgbackup.ssh/secret | 19 +++ .../borgbackup/borgbackup.ssh/users/admin | 1 + 14 files changed, 199 insertions(+), 2 deletions(-) create mode 100644 clanServices/borgbackup/tests/vm/default.nix create mode 100755 clanServices/borgbackup/tests/vm/sops/machines/clientone/key.json create mode 100644 clanServices/borgbackup/tests/vm/sops/secrets/clientone-age.key/secret create mode 120000 clanServices/borgbackup/tests/vm/sops/secrets/clientone-age.key/users/admin create mode 100644 clanServices/borgbackup/tests/vm/sops/users/admin/key.json create mode 120000 clanServices/borgbackup/tests/vm/vars/per-machine/clientone/borgbackup/borgbackup.repokey/machines/clientone create mode 100644 clanServices/borgbackup/tests/vm/vars/per-machine/clientone/borgbackup/borgbackup.repokey/secret create mode 120000 clanServices/borgbackup/tests/vm/vars/per-machine/clientone/borgbackup/borgbackup.repokey/users/admin create mode 100644 clanServices/borgbackup/tests/vm/vars/per-machine/clientone/borgbackup/borgbackup.ssh.pub/value create mode 120000 clanServices/borgbackup/tests/vm/vars/per-machine/clientone/borgbackup/borgbackup.ssh/machines/clientone create mode 100644 clanServices/borgbackup/tests/vm/vars/per-machine/clientone/borgbackup/borgbackup.ssh/secret create mode 120000 clanServices/borgbackup/tests/vm/vars/per-machine/clientone/borgbackup/borgbackup.ssh/users/admin diff --git a/checks/flake-module.nix b/checks/flake-module.nix index 3c61aae4e..bfb5f8caf 100644 --- a/checks/flake-module.nix +++ b/checks/flake-module.nix @@ -51,7 +51,6 @@ in postgresql = self.clanLib.test.containerTest ./postgresql nixosTestArgs; dummy-inventory-test = import ./dummy-inventory-test nixosTestArgs; - borgbackup = import ./borgbackup nixosTestArgs; data-mesher = import ./data-mesher nixosTestArgs; } // lib.optionalAttrs (pkgs.stdenv.hostPlatform.system == "aarch64-linux") { diff --git a/clanServices/borgbackup/flake-module.nix b/clanServices/borgbackup/flake-module.nix index e8eb5dd02..92c4fc46b 100644 --- a/clanServices/borgbackup/flake-module.nix +++ b/clanServices/borgbackup/flake-module.nix @@ -1,6 +1,17 @@ -{ lib, ... }: +{ lib, self, ... }: { clan.modules = { borgbackup = lib.modules.importApply ./default.nix { }; }; + perSystem = + { pkgs, ... }: + { + checks = lib.optionalAttrs (pkgs.stdenv.isLinux) { + borgbackup = import ./tests/vm/default.nix { + inherit pkgs; + clan-core = self; + nixosLib = import (self.inputs.nixpkgs + "/nixos/lib") { }; + }; + }; + }; } diff --git a/clanServices/borgbackup/tests/vm/default.nix b/clanServices/borgbackup/tests/vm/default.nix new file mode 100644 index 000000000..d8ed40e7b --- /dev/null +++ b/clanServices/borgbackup/tests/vm/default.nix @@ -0,0 +1,118 @@ +{ + pkgs, + nixosLib, + clan-core, + ... +}: +nixosLib.runTest ( + { ... }: + { + imports = [ + clan-core.modules.nixosVmTest.clanTest + ]; + + hostPkgs = pkgs; + + name = "borgbackup"; + + clan = { + directory = ./.; + test.useContainers = true; + modules."@clan/borgbackup" = ../../default.nix; + inventory = { + + machines.clientone = { }; + machines.serverone = { }; + + instances = { + borgone = { + + module.name = "@clan/borgbackup"; + + roles.client.machines."clientone" = { }; + roles.server.machines."serverone".settings.directory = "/tmp/borg-test"; + }; + }; + }; + }; + + nodes = { + + serverone = { + services.openssh.enable = true; + # Needed so PAM doesn't see the user as locked + users.users.borg.password = "borg"; + }; + + clientone = + { config, pkgs, ... }: + let + dependencies = [ + clan-core + pkgs.stdenv.drvPath + ] ++ builtins.map (i: i.outPath) (builtins.attrValues clan-core.inputs); + closureInfo = pkgs.closureInfo { rootPaths = dependencies; }; + + in + { + + services.openssh.enable = true; + + users.users.root.openssh.authorizedKeys.keyFiles = [ ../../../../checks/assets/ssh/pubkey ]; + + clan.core.networking.targetHost = config.networking.hostName; + + environment.systemPackages = [ clan-core.packages.${pkgs.system}.clan-cli ]; + + environment.etc.install-closure.source = "${closureInfo}/store-paths"; + nix.settings = { + substituters = pkgs.lib.mkForce [ ]; + hashed-mirrors = null; + connect-timeout = pkgs.lib.mkForce 3; + flake-registry = pkgs.writeText "flake-registry" ''{"flakes":[],"version":2}''; + }; + system.extraDependencies = dependencies; + + clan.core.state.test-backups.folders = [ "/var/test-backups" ]; + }; + + }; + + testScript = '' + import json + start_all() + + machines = [clientone, serverone] + + for m in machines: + m.systemctl("start network-online.target") + + for m in machines: + m.wait_for_unit("network-online.target") + + # dummy data + clientone.succeed("mkdir -p /var/test-backups /var/test-service") + clientone.succeed("echo testing > /var/test-backups/somefile") + + clientone.succeed("${pkgs.coreutils}/bin/install -Dm 600 ${../../../../checks/assets/ssh/privkey} /root/.ssh/id_ed25519") + clientone.succeed("${pkgs.coreutils}/bin/touch /root/.ssh/known_hosts") + clientone.wait_until_succeeds("timeout 2 ssh -o StrictHostKeyChecking=accept-new localhost hostname") + clientone.wait_until_succeeds("timeout 2 ssh -o StrictHostKeyChecking=accept-new $(hostname) hostname") + + # create + clientone.succeed("borgbackup-create >&2") + clientone.wait_until_succeeds("! systemctl is-active borgbackup-job-serverone >&2") + + # list + backup_id = json.loads(clientone.succeed("borg-job-serverone list --json"))["archives"][0]["archive"] + out = clientone.succeed("borgbackup-list").strip() + print(out) + assert backup_id in out, f"backup {backup_id} not found in {out}" + + # borgbackup restore + clientone.succeed("rm -f /var/test-backups/somefile") + clientone.succeed(f"NAME='serverone::borg@serverone:.::{backup_id}' borgbackup-restore >&2") + assert clientone.succeed("cat /var/test-backups/somefile").strip() == "testing", "restore failed" + ''; + } +) diff --git a/clanServices/borgbackup/tests/vm/sops/machines/clientone/key.json b/clanServices/borgbackup/tests/vm/sops/machines/clientone/key.json new file mode 100755 index 000000000..28a250742 --- /dev/null +++ b/clanServices/borgbackup/tests/vm/sops/machines/clientone/key.json @@ -0,0 +1,6 @@ +[ + { + "publickey": "age1tyyx2ratu8s9ugyre36xyksnquth9gxeh7wjdhvsk89rtf8yu5wq0pk04c", + "type": "age" + } +] diff --git a/clanServices/borgbackup/tests/vm/sops/secrets/clientone-age.key/secret b/clanServices/borgbackup/tests/vm/sops/secrets/clientone-age.key/secret new file mode 100644 index 000000000..384ad184a --- /dev/null +++ b/clanServices/borgbackup/tests/vm/sops/secrets/clientone-age.key/secret @@ -0,0 +1,15 @@ +{ + "data": "ENC[AES256_GCM,data:wCKoKuJo4uXycfqEUYAXDlRRMGJaWgOFiaQa4Wigs0jx1eCI80lP3cEZ1QKyrU/9m9POoZz0JlaKHcuhziTKUqaevHvGfVq2y00=,iv:pH5a90bJbK9Ro6zndNJ18qd4/rU+Tdm+y+jJZtY7UGg=,tag:9lHZJ9C/zIfy8nFrYt9JBQ==,type:str]", + "sops": { + "age": [ + { + "recipient": "age1qm0p4vf9jvcnn43s6l4prk8zn6cx0ep9gzvevxecv729xz540v8qa742eg", + "enc": "-----BEGIN AGE ENCRYPTED FILE-----\nYWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBwUDhpd1ZqbWFqR0I3dVFI\nOHlyZnFUYXJnWElrRWhoUHVNMzdKd0VrcGdRCkphQVhuYzlJV0p1MG9MSW5ncWJ3\nREp1OEJxMzQzS2MxTk9aMkJ1a3B0Q0kKLS0tIENweVJ2Tk1yeXlFc2F5cTNIV3F3\nTkRFOVZ1amRIYmg1K3hGWUFSTTl4Wk0KHJRJ7756Msod7Bsmn9SgtwRo53B8Ilp3\nhsAPv+TtdmOD8He9MvGV+BElKEXCsLUwhp/Py6n6CJCczu0VIr8owg==\n-----END AGE ENCRYPTED FILE-----\n" + } + ], + "lastmodified": "2025-05-20T13:33:56Z", + "mac": "ENC[AES256_GCM,data:FyfxXhnI6o4SVGJY2e1eMDnfkbMWiCkP4JL/G4PQvzz+c7OIuz8xaa03P3VW7b7o85NP2Tln4FMNTZ0FYtQwd0kKypLUnIxAHsixAHFCv4X8ul1gtZynzgbFbmc0GkfVWW8Lf+U+vvDwT+UrEVfcmksCjdvAOwP26PvlEhYEkSw=,iv:H+VrWYL+kLOLezCZrI8ZgeCsaUdpb7LxDMiLotezVPs=,tag:B/cbPdiEFumGKQHby5inCA==,type:str]", + "unencrypted_suffix": "_unencrypted", + "version": "3.10.2" + } +} diff --git a/clanServices/borgbackup/tests/vm/sops/secrets/clientone-age.key/users/admin b/clanServices/borgbackup/tests/vm/sops/secrets/clientone-age.key/users/admin new file mode 120000 index 000000000..9e21a9938 --- /dev/null +++ b/clanServices/borgbackup/tests/vm/sops/secrets/clientone-age.key/users/admin @@ -0,0 +1 @@ +../../../users/admin \ No newline at end of file diff --git a/clanServices/borgbackup/tests/vm/sops/users/admin/key.json b/clanServices/borgbackup/tests/vm/sops/users/admin/key.json new file mode 100644 index 000000000..e408aa96b --- /dev/null +++ b/clanServices/borgbackup/tests/vm/sops/users/admin/key.json @@ -0,0 +1,4 @@ +{ + "publickey": "age1qm0p4vf9jvcnn43s6l4prk8zn6cx0ep9gzvevxecv729xz540v8qa742eg", + "type": "age" +} diff --git a/clanServices/borgbackup/tests/vm/vars/per-machine/clientone/borgbackup/borgbackup.repokey/machines/clientone b/clanServices/borgbackup/tests/vm/vars/per-machine/clientone/borgbackup/borgbackup.repokey/machines/clientone new file mode 120000 index 000000000..230a86f98 --- /dev/null +++ b/clanServices/borgbackup/tests/vm/vars/per-machine/clientone/borgbackup/borgbackup.repokey/machines/clientone @@ -0,0 +1 @@ +../../../../../../sops/machines/clientone \ No newline at end of file diff --git a/clanServices/borgbackup/tests/vm/vars/per-machine/clientone/borgbackup/borgbackup.repokey/secret b/clanServices/borgbackup/tests/vm/vars/per-machine/clientone/borgbackup/borgbackup.repokey/secret new file mode 100644 index 000000000..ea1243ade --- /dev/null +++ b/clanServices/borgbackup/tests/vm/vars/per-machine/clientone/borgbackup/borgbackup.repokey/secret @@ -0,0 +1,19 @@ +{ + "data": "ENC[AES256_GCM,data:52vY68gqbwiZRMUBKc9SeXR06fuKAhuAPciLpxXgEOxI,iv:Y34AVoHaZzRiFFTDbekXP1X3W8zSXJmzVCYODYkdxnY=,tag:8WQaGEHQKT/n+auHUZCE0w==,type:str]", + "sops": { + "age": [ + { + "recipient": "age1qm0p4vf9jvcnn43s6l4prk8zn6cx0ep9gzvevxecv729xz540v8qa742eg", + "enc": "-----BEGIN AGE ENCRYPTED FILE-----\nYWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBOdUFUZUZ2M00zTGlhNjF4\nL0VlMVY4Z2xMbWRWR29zZlFwdm1XRk12NGtBCnkrb3A4M3BkalMyeWdDaUdQdStt\nUWY3SXJROXdpRzN0NlBJNEpjTEZ0aFkKLS0tIGZkMGhsTXB2RnRqVHVrUFQwL2lw\nZnBreWhWa3Jrcm4yOXBiaUlPWFM1aDAKRE+Zzrja7KeANEJUbmFYuVoO3qGyi4iH\n0cfH0W8irRe9vsKMXz7YJxtByYLwRulrT8tXtElHvIEVJG0mwwaf0Q==\n-----END AGE ENCRYPTED FILE-----\n" + }, + { + "recipient": "age1tyyx2ratu8s9ugyre36xyksnquth9gxeh7wjdhvsk89rtf8yu5wq0pk04c", + "enc": "-----BEGIN AGE ENCRYPTED FILE-----\nYWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBsNEljUFdnQ0tTQ1IxZ2Zo\nYkc4V2dCaUk0YXh5SzlSazhsRTVKVzFvVXhFCkRyMlMxR3EyWEZIRzFQV3d2dVpz\na3NPbk9XdWR1NmtMQlZsNlBuU0NkQWMKLS0tIDlDYzMzOExVL1g5SVRHYlpUQlBV\na2lpdTUwaEd4OXhWUWxuV04xRVVKNHcK9coohAD1IoarLOXSGg3MIRXQ3BsTIA4y\nKrcS/PxITKJs7ihg93RZin70R79Qsij1RHZLKGfgGJ67i8ZCxc4N0g==\n-----END AGE ENCRYPTED FILE-----\n" + } + ], + "lastmodified": "2025-05-20T13:33:59Z", + "mac": "ENC[AES256_GCM,data:eABMaIe07dwAMMlgrIUUpfpj73q1H5Keafql91MBQ5NN9Znr5lI/ennQsQsuLO8ZTCC34US/MJndliW34SqVM9y53p0jjPzqBxSKYq74iNcBz7+TxbjlY1aapgTRPr6Ta8I/5loohnxlHqjvLL70ZzfbChDN0/4jZsDVXYNfbIk=,iv:41Mz2u40JN0iE5zPUK6siaxo0rTtlk7fGWq7TF5NyUI=,tag:1A+h6XPH7DeQ6kxGDV3PgQ==,type:str]", + "unencrypted_suffix": "_unencrypted", + "version": "3.10.2" + } +} diff --git a/clanServices/borgbackup/tests/vm/vars/per-machine/clientone/borgbackup/borgbackup.repokey/users/admin b/clanServices/borgbackup/tests/vm/vars/per-machine/clientone/borgbackup/borgbackup.repokey/users/admin new file mode 120000 index 000000000..ca714e122 --- /dev/null +++ b/clanServices/borgbackup/tests/vm/vars/per-machine/clientone/borgbackup/borgbackup.repokey/users/admin @@ -0,0 +1 @@ +../../../../../../sops/users/admin \ No newline at end of file diff --git a/clanServices/borgbackup/tests/vm/vars/per-machine/clientone/borgbackup/borgbackup.ssh.pub/value b/clanServices/borgbackup/tests/vm/vars/per-machine/clientone/borgbackup/borgbackup.ssh.pub/value new file mode 100644 index 000000000..af244e2c1 --- /dev/null +++ b/clanServices/borgbackup/tests/vm/vars/per-machine/clientone/borgbackup/borgbackup.ssh.pub/value @@ -0,0 +1 @@ +ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIE3clYF6BDZ0PxfDdprx7YYM4U4PKEZkWUuhpre0wb7w nixbld@kiwi diff --git a/clanServices/borgbackup/tests/vm/vars/per-machine/clientone/borgbackup/borgbackup.ssh/machines/clientone b/clanServices/borgbackup/tests/vm/vars/per-machine/clientone/borgbackup/borgbackup.ssh/machines/clientone new file mode 120000 index 000000000..230a86f98 --- /dev/null +++ b/clanServices/borgbackup/tests/vm/vars/per-machine/clientone/borgbackup/borgbackup.ssh/machines/clientone @@ -0,0 +1 @@ +../../../../../../sops/machines/clientone \ No newline at end of file diff --git a/clanServices/borgbackup/tests/vm/vars/per-machine/clientone/borgbackup/borgbackup.ssh/secret b/clanServices/borgbackup/tests/vm/vars/per-machine/clientone/borgbackup/borgbackup.ssh/secret new file mode 100644 index 000000000..c9a6c8bd0 --- /dev/null +++ b/clanServices/borgbackup/tests/vm/vars/per-machine/clientone/borgbackup/borgbackup.ssh/secret @@ -0,0 +1,19 @@ +{ + "data": "ENC[AES256_GCM,data:tAjfBW75XDS8lfJCf/+9rPYH3aMjRX1nmdN5dPMxnrlhuEPM3Smv9AM93Tz36k7BKk31bUWcV/99ax+KaIK1Rzgym/CwKGGxIUziuVOEOwrCOBeOw7amZ9YGsgiLUTLIhoeO6SjfdZ4q2JxGPw7KqNfUM9kiZT01vx5JTLa24JdvBKpizbtHRlL1lappTRVt0dG2WhT9/YhQUGu9ZFqPs8+bPOBclc78qjCm2DAPgsprK+JCBuq+r+qHgAx4Ee1QHI7FC39e5NeGBTBeZfZ5d95+0klKuTx9FCPs6QRBkQ0tN29OpwzkdSuRAXGGHpzPkZ+FupbETtSQWCmnjma6jPzEl8oDUTWooKK0mUEz8icvTQvRfyM3Qt3mQpkX3e0rTEbZzoLdWCwTufP/tRQNDCWvI/NV7OjIHpNPjymqE5uPmiBpA6y6hhCH7zL1eDo11ICSIX3hkyFJH2svvFQn6oLrPAoByvNutfetKhd8z7NFpVeIOWwtuPzO7wU5M7zESHww0JF78vjFwimQYYhQ,iv:fVjeVez4dTGSrANi5ZeP9PJhsSySqeqqJzBDbd0gFW4=,tag:Aa89+bWLljxV1tlSHtpddw==,type:str]", + "sops": { + "age": [ + { + "recipient": "age1qm0p4vf9jvcnn43s6l4prk8zn6cx0ep9gzvevxecv729xz540v8qa742eg", + "enc": "-----BEGIN AGE ENCRYPTED FILE-----\nYWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBVaW94M3VwcFJ2elcrRGlv\nUGdzVk9vU2ZweFpIVVlIRUEyRVlSMlEyeHpVCnJuV0xIS3hMLy9IbG92S0pvL2RP\nL0J0WkVuWVhQdldHekdYNTVXdFkrUlEKLS0tIFQzdGErZVBwQUFNMXErbDBQVURZ\naHlsY2hDa1Zud1E2dFh0ZHl4VEJ2S0kKVABqwRcCUTcsBInfo9CpFtoM3kl4KMyU\nGXDjHOSjlX5df7OKZAvYukgX7Q2penvq+Fq4fa4A1Cmkqga7cHdJ+A==\n-----END AGE ENCRYPTED FILE-----\n" + }, + { + "recipient": "age1tyyx2ratu8s9ugyre36xyksnquth9gxeh7wjdhvsk89rtf8yu5wq0pk04c", + "enc": "-----BEGIN AGE ENCRYPTED FILE-----\nYWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBnbHRSVEg3Vi9qTnAwWGF6\nbEdIR2gvZ2laZnJMbVF3NjcvN25OdXF3WXowCnVUODdEa1NWU3JISXlrNldOMjVi\ndUlMTVdBaWxvZHlwSTdJY3NCcll4SjAKLS0tIEp6ZVlDTklqVXdNYzJ2dElCR21o\nUWphMDdyVVppVnFHOVlHZTNtajZzOXMKRB61lUrAkUXSYl3ffOOK8k4QgLA4bFln\naQ7GOol8f8W5H68zXBMZrhjP6k4kZDfknc9jgyoWM7jaZNSWC5J19Q==\n-----END AGE ENCRYPTED FILE-----\n" + } + ], + "lastmodified": "2025-05-20T13:33:59Z", + "mac": "ENC[AES256_GCM,data:NjVpDweqxTSQGt9VKR/CMfvbvHQJHCi8P7XbOuKLZKQ4GVoeZ5r4PsC6nxKHHikN6YL1oJCmaSxr0mJRk/sFZg/+wdW8L7F5aQeFRiWo9jCjH0MDMnfiu5a0xjRt21uPl/7LUJ9jNon5nyxPTlZMeYSvTP2Q9spnNuN8vqipP68=,iv:DPvbN9IvWiUfxiJk6mey/us8N1GGVJcSJrT8Bty4kB4=,tag:+emK8uSkfIGUXoYpaWeu3A==,type:str]", + "unencrypted_suffix": "_unencrypted", + "version": "3.10.2" + } +} diff --git a/clanServices/borgbackup/tests/vm/vars/per-machine/clientone/borgbackup/borgbackup.ssh/users/admin b/clanServices/borgbackup/tests/vm/vars/per-machine/clientone/borgbackup/borgbackup.ssh/users/admin new file mode 120000 index 000000000..ca714e122 --- /dev/null +++ b/clanServices/borgbackup/tests/vm/vars/per-machine/clientone/borgbackup/borgbackup.ssh/users/admin @@ -0,0 +1 @@ +../../../../../../sops/users/admin \ No newline at end of file