From decf15cbe31f9bea6af84cd82adf281e711a1a7c Mon Sep 17 00:00:00 2001 From: Jacek Galowicz Date: Sat, 14 Dec 2024 13:33:47 +0100 Subject: [PATCH] Generate and test .deb package for Debian and Ubuntu --- .gitignore | 1 + flake.lock | 24 ++++++++++++++++++ flake.nix | 21 +++++++++++++--- pkgs/example.toml | 9 +++++++ pkgs/package-deb.nix | 30 ++++++++++++++++++++++ tests/packaging/deb.nix | 44 +++++++++++++++++++++++++++++++++ tests/packaging/prepare-test.sh | 30 ++++++++++++++++++++++ 7 files changed, 156 insertions(+), 3 deletions(-) create mode 100644 pkgs/example.toml create mode 100644 pkgs/package-deb.nix create mode 100644 tests/packaging/deb.nix create mode 100644 tests/packaging/prepare-test.sh diff --git a/.gitignore b/.gitignore index 4270d4ea8..966c47cbb 100644 --- a/.gitignore +++ b/.gitignore @@ -25,3 +25,4 @@ _markdown_* .vscode /output +.nixos-test-history diff --git a/flake.lock b/flake.lock index 06183ae06..2b21eb74f 100644 --- a/flake.lock +++ b/flake.lock @@ -39,6 +39,29 @@ "type": "github" } }, + "nix-vm-test": { + "inputs": { + "flake-utils": [ + "flake-utils" + ], + "nixpkgs": [ + "nixpkgs" + ] + }, + "locked": { + "lastModified": 1734178503, + "narHash": "sha256-R2HSewN6ekutGwBA1RY5EKT1eV3idY/KjSUvPpQT+Gg=", + "owner": "tfc", + "repo": "nix-vm-test", + "rev": "7216720e54ff058744d84dba3a6057e52ebb4fbc", + "type": "github" + }, + "original": { + "owner": "tfc", + "repo": "nix-vm-test", + "type": "github" + } + }, "nixpkgs": { "locked": { "lastModified": 1728193676, @@ -59,6 +82,7 @@ "inputs": { "fenix": "fenix", "flake-utils": "flake-utils", + "nix-vm-test": "nix-vm-test", "nixpkgs": "nixpkgs" } }, diff --git a/flake.nix b/flake.nix index 14baded36..7ce27509a 100644 --- a/flake.nix +++ b/flake.nix @@ -6,9 +6,15 @@ # for rust nightly with llvm-tools-preview fenix.url = "github:nix-community/fenix"; fenix.inputs.nixpkgs.follows = "nixpkgs"; + + # TODO: Switch to github:numtide/nix-vm-tests when pull request + # https://github.com/numtide/nix-vm-test/pull/71 is through + nix-vm-test.url = "github:tfc/nix-vm-test"; + nix-vm-test.inputs.nixpkgs.follows = "nixpkgs"; + nix-vm-test.inputs.flake-utils.follows = "flake-utils"; }; - outputs = { self, nixpkgs, flake-utils, ... }@inputs: + outputs = { self, nixpkgs, flake-utils, nix-vm-test, ... }@inputs: nixpkgs.lib.foldl (a: b: nixpkgs.lib.recursiveUpdate a b) { } [ @@ -77,10 +83,16 @@ inherit system; # apply our own overlay, overriding/inserting our packages as defined in ./pkgs - overlays = [ self.overlays.default ]; + overlays = [ + self.overlays.default + nix-vm-test.overlays.default + ]; }; in { + packages.package-deb = pkgs.callPackage ./pkgs/package-deb.nix { + rosenpass = pkgs.pkgsStatic.rosenpass; + }; # ### Reading materials ### @@ -150,7 +162,10 @@ { nativeBuildInputs = [ pkgs.nodePackages.prettier ]; } '' cd ${./.} && prettier --check . && touch $out ''; - }; + } // pkgs.lib.optionalAttrs (system == "x86_64-linux") (import ./tests/packaging/deb.nix { + inherit pkgs; + rosenpass-deb = self.packages.${system}.package-deb; + }); formatter = pkgs.nixpkgs-fmt; })) diff --git a/pkgs/example.toml b/pkgs/example.toml new file mode 100644 index 000000000..659a90a9c --- /dev/null +++ b/pkgs/example.toml @@ -0,0 +1,9 @@ +dev = "rp-example" +ip = "fc00::1/64" +listen = "[::]:51821" +private_keys_dir = "/run/credentials/rp@example.service" +verbose = true + +[[peers]] +public_keys_dir = "/etc/rosenpass/example/peers/client" +allowed_ips = "fc00::2" diff --git a/pkgs/package-deb.nix b/pkgs/package-deb.nix new file mode 100644 index 000000000..d7194d6f2 --- /dev/null +++ b/pkgs/package-deb.nix @@ -0,0 +1,30 @@ +{ runCommand, dpkg, rosenpass }: + +let + inherit (rosenpass) version; +in + +runCommand "rosenpass-${version}.deb" { } '' + mkdir -p packageroot/DEBIAN + + cat << EOF > packageroot/DEBIAN/control + Package: rosenpass + Version: ${version} + Architecture: all + Maintainer: Jacek Galowicz + Depends: + Description: Post-quantum-secure VPN tool Rosenpass + Rosenpass is a post-quantum-secure VPN + that uses WireGuard to transport the actual data. + EOF + + + mkdir -p packageroot/usr/bin + install -m755 -t packageroot/usr/bin ${rosenpass}/bin/* + + mkdir -p packageroot/etc/rosenpass + cp -r ${rosenpass}/lib/systemd packageroot/etc/ + cp ${./example.toml} packageroot/etc/rosenpass/example.toml + + ${dpkg}/bin/dpkg --build packageroot $out +'' diff --git a/tests/packaging/deb.nix b/tests/packaging/deb.nix new file mode 100644 index 000000000..994d93ca6 --- /dev/null +++ b/tests/packaging/deb.nix @@ -0,0 +1,44 @@ +{ pkgs, rosenpass-deb }: + +let + wg-deb = pkgs.fetchurl { + url = "http://ftp.de.debian.org/debian/pool/main/w/wireguard/wireguard-tools_1.0.20210914-1.1_amd64.deb"; + hash = "sha256-s/hCUisQLR19kEbV6d8JXzzTAWUPM+NV0APgHizRGA4="; + }; + pkgsDir = pkgs.runCommand "packages" {} '' + mkdir $out + cp ${rosenpass-deb} $out/rosenpass.deb + cp ${wg-deb} $out/wireguard.deb + cp ${./prepare-test.sh} $out/prepare-test.sh + ''; + + testAttrs = { + sharedDirs.share = { + source = pkgsDir; + target = "/mnt/share"; + }; + testScript = '' + vm.wait_for_unit("multi-user.target") + vm.succeed("dpkg --install /mnt/share/wireguard.deb") + vm.succeed("dpkg --install /mnt/share/rosenpass.deb") + vm.succeed("bash /mnt/share/prepare-test.sh") + + vm.succeed(f"systemctl start rp@server") + vm.succeed(f"systemctl start rp@client") + + vm.wait_for_unit("rp@server.service") + vm.wait_for_unit("rp@client.service") + + vm.wait_until_succeeds("wg show all preshared-keys | grep --invert-match none", timeout=5); + + psk_server = vm.succeed("wg show rp-server preshared-keys").strip().split()[-1] + psk_client = vm.succeed("wg show rp-client preshared-keys").strip().split()[-1] + + assert psk_server == psk_client, "preshared-key exchange must be successful" + ''; + }; +in +{ + debian-13 = (pkgs.testers.legacyDistros.debian."13" testAttrs).sandboxed; + ubuntu-23_10 = (pkgs.testers.legacyDistros.ubuntu."23_10" testAttrs).sandboxed; +} diff --git a/tests/packaging/prepare-test.sh b/tests/packaging/prepare-test.sh new file mode 100644 index 000000000..a10c97f99 --- /dev/null +++ b/tests/packaging/prepare-test.sh @@ -0,0 +1,30 @@ +#!/usr/bin/env bash + +set -euxo pipefail + +< /etc/rosenpass/example.toml \ + sed 's@example@server@' > /etc/rosenpass/server.toml + +< /etc/rosenpass/example.toml \ + sed 's@listen.*@@' | + sed 's@client@server@' | + sed 's@example@client@' | + sed 's@fc00::2@fc00::1@' | + sed 's@fc00::1/64@fc00::2/64@' > /etc/rosenpass/client.toml + +echo 'endpoint = "[::1]:51821"' >> /etc/rosenpass/client.toml + +rp genkey server-sk +rp pubkey server-sk server-pk + +rp genkey client-sk +rp pubkey client-sk client-pk + +mkdir -p /etc/rosenpass/server/peers/client +mkdir -p /etc/rosenpass/client/peers/server + +cp server-sk/{pqpk,pqsk,wgsk} /etc/rosenpass/server/ +cp client-sk/{pqpk,pqsk,wgsk} /etc/rosenpass/client/ + +cp client-pk/{pqpk,wgpk} /etc/rosenpass/server/peers/client +cp server-pk/{pqpk,wgpk} /etc/rosenpass/client/peers/server