diff --git a/Makefile b/Makefile index b46181de..022918e4 100644 --- a/Makefile +++ b/Makefile @@ -84,3 +84,38 @@ build-mo: release: @goreleaser release --clean + +CLIENT_VM := abra-client +vm-client-status: + sudo systemctl status microvm@$(CLIENT_VM).service +vm-client-create: + sudo microvm -f git+file://$$(pwd) -c $(CLIENT_VM) +vm-client-start: + sudo systemctl start microvm@$(CLIENT_VM).service +vm-client-update: + sudo microvm -R -f git+file://$$(pwd) -u $(CLIENT_VM) +vm-client-run: + sudo microvm -f git+file://$$(pwd) -r $(CLIENT_VM) +vm-client-stop: + sudo systemctl stop microvm@$(CLIENT_VM) +vm-client-delete: vm-client-stop + sudo rm -rf /var/lib/microvms/$(CLIENT_VM) + +SERVER_VM := abra-server +vm-server-status: + sudo systemctl status microvm@$(SERVER_VM).service +vm-server-create: + sudo microvm -f git+file://$$(pwd) -c $(SERVER_VM) +vm-server-start: + sudo systemctl start microvm@$(SERVER_VM).service +vm-server-update: + sudo microvm -R -f git+file://$$(pwd) -u $(SERVER_VM) +vm-server-run: + sudo microvm -f git+file://$$(pwd) -r $(SERVER_VM) +vm-server-stop: + sudo systemctl stop microvm@$(SERVER_VM) +vm-server-delete: vm-stop + sudo rm -rf /var/lib/microvms/$(SERVER_VM) + +test-integration: + ssh-keygen -t ed25519 -f ./test-integration -q -N "" -C "abra integration test" diff --git a/flake.lock b/flake.lock index 9448fe0f..57e2bd06 100644 --- a/flake.lock +++ b/flake.lock @@ -18,6 +18,48 @@ "type": "github" } }, + "home-manager": { + "inputs": { + "nixpkgs": [ + "nixpkgs" + ] + }, + "locked": { + "lastModified": 1785119570, + "narHash": "sha256-Rgs2xKnGLFWQscxUaXX07oyZeuMDOHEbqDOsgliLFGM=", + "owner": "nix-community", + "repo": "home-manager", + "rev": "d4fd24667c8cbef124bb70a20380cab75ec8474d", + "type": "github" + }, + "original": { + "owner": "nix-community", + "ref": "release-26.05", + "repo": "home-manager", + "type": "github" + } + }, + "microvm": { + "inputs": { + "nixpkgs": [ + "nixpkgs" + ], + "spectrum": "spectrum" + }, + "locked": { + "lastModified": 1784666190, + "narHash": "sha256-xgfS6slV7J3baMooNN1UuBi51RIgg9y0DbCxfSA0668=", + "owner": "astro", + "repo": "microvm.nix", + "rev": "fa5340ac684cdce8a22b6d4a0bcebb0cc999275e", + "type": "github" + }, + "original": { + "owner": "astro", + "repo": "microvm.nix", + "type": "github" + } + }, "nixpkgs": { "locked": { "lastModified": 1778443072, @@ -37,9 +79,27 @@ "root": { "inputs": { "flake-utils": "flake-utils", + "home-manager": "home-manager", + "microvm": "microvm", "nixpkgs": "nixpkgs" } }, + "spectrum": { + "flake": false, + "locked": { + "lastModified": 1783694892, + "narHash": "sha256-xO8f7Qng+18FK2UlB9vcrkxCaQMCt5WjCH24aW/11eg=", + "ref": "refs/heads/main", + "rev": "24c4346e30fdea8d8e80f34aec3554a15a667d24", + "revCount": 1410, + "type": "git", + "url": "https://spectrum-os.org/git/spectrum" + }, + "original": { + "type": "git", + "url": "https://spectrum-os.org/git/spectrum" + } + }, "systems": { "locked": { "lastModified": 1681028828, diff --git a/flake.nix b/flake.nix index fdc35b22..878081c8 100644 --- a/flake.nix +++ b/flake.nix @@ -3,35 +3,71 @@ inputs = { nixpkgs.url = "github:nixos/nixpkgs?ref=nixos-unstable"; + home-manager = { + url = "github:nix-community/home-manager/release-26.05"; + inputs.nixpkgs.follows = "nixpkgs"; + }; flake-utils.url = "github:numtide/flake-utils"; + microvm = { + url = "github:astro/microvm.nix"; + inputs.nixpkgs.follows = "nixpkgs"; + }; }; outputs = { self, nixpkgs, + microvm, + home-manager, flake-utils, }: - flake-utils.lib.eachDefaultSystem ( - system: - let - pkgs = nixpkgs.legacyPackages.${system}; - in - { - packages = rec { - abra = pkgs.callPackage ./package.nix { }; - default = abra; - }; - apps = rec { - abra = flake-utils.lib.mkApp { drv = self.packages.${system}.abra; }; - default = abra; - }; - devShells.default = pkgs.mkShell { - packages = with pkgs; [ - go_1_26 - gnumake + let + system = "x86_64-linux"; + pkgs = nixpkgs.legacyPackages.${system}; + publicKey = builtins.readFile ./test-integration.pub; + privateKey = builtins.readFile ./test-integration; + in + { + nixosConfigurations = { + abra-client = nixpkgs.lib.nixosSystem { + system = "x86_64-linux"; + modules = [ + microvm.nixosModules.microvm + home-manager.nixosModules.home-manager + ./nix/hosts/client/configuration.nix ]; + specialArgs = { inherit publicKey privateKey; }; }; - } - ); + abra-server = nixpkgs.lib.nixosSystem { + system = "x86_64-linux"; + modules = [ + microvm.nixosModules.microvm + ./nix/hosts/server/configuration.nix + ]; + specialArgs = { inherit publicKey privateKey; }; + }; + }; + packages = rec { + abra = pkgs.callPackage ./package.nix { }; + default = abra; + }; + apps = rec { + abra = flake-utils.lib.mkApp { drv = self.packages.${system}.abra; }; + default = abra; + }; + devShells.${system}.default = pkgs.mkShell { + # testing env variables + BATS_LIB_PATH = "~/.local/share/bats/"; + TEST_SERVER = "abra.local"; + ABRA_DIR = "$HOME/.abra_test"; + + packages = with pkgs; [ + go_1_26 + gnumake + gopls + ]; + }; + + }; } diff --git a/nix/hosts/client/configuration.nix b/nix/hosts/client/configuration.nix new file mode 100644 index 00000000..ccccd999 --- /dev/null +++ b/nix/hosts/client/configuration.nix @@ -0,0 +1,162 @@ +{ + lib, + pkgs, + publicKey, + privateKey, + ... +}: +let + index = 2; + mac = "00:00:00:00:00:01"; + serverIp = "10.0.0.3"; +in +{ + microvm = { + vcpu = 4; + mem = 2049; # see issue related in microvm repo with 2048, so add 1MB + interfaces = [ + { + id = "vm${toString index}"; + type = "tap"; + inherit mac; + } + ]; + shares = [ + { + proto = "virtiofs"; + tag = "repo"; + # Source path can be absolute or relative + # to /var/lib/microvms/$hostName + source = "/home/dev/Documents/abra"; + mountPoint = "/home/dev/abra"; + } + ]; + }; + + boot.tmp = { + useTmpfs = true; + tmpfsSize = "2G"; + }; + + networking = { + hostName = "abra-client"; + useNetworkd = true; + }; + systemd.network.networks."10-eth" = { + matchConfig.MACAddress = mac; + # Static IP configuration + address = [ + "10.0.0.${toString index}/32" + "fec0::${lib.toHexString index}/128" + ]; + routes = [ + { + # A route to the host + Destination = "10.0.0.0/32"; + GatewayOnLink = true; + } + { + # Route to server + Destination = "${serverIp}/32"; + Gateway = "10.0.0.0"; + GatewayOnLink = true; + } + { + # Default route + Destination = "0.0.0.0/0"; + Gateway = "10.0.0.0"; + GatewayOnLink = true; + } + { + # Default route + Destination = "::/0"; + Gateway = "fec0::"; + GatewayOnLink = true; + } + ]; + networkConfig = { + # DNS servers no longer come from DHCP nor Router + # Advertisements. Perhaps you want to change the defaults: + DNS = [ + # Quad9.net + "9.9.9.9" + "149.112.112.112" + "2620:fe::fe" + "2620:fe::9" + ]; + }; + }; + + # open the ports to allow ssh access from the host + networking.firewall.allowedTCPPorts = [ 22 ]; + networking.firewall.allowedUDPPorts = [ 22 ]; + + networking.extraHosts = '' + ${serverIp} abra.local + ${serverIp} app_check_bats.abra.local + ''; + + environment.variables = { + CGO_ENABLED = 0; + TEST_SERVER = "abra.local"; + ABRA_DIR = "$HOME/.abra_test"; + }; + + users.users.dev = { + isNormalUser = true; + password = "test"; + home = "/home/dev"; + description = "Alice Foobar"; + extraGroups = [ + "wheel" + "networkmanager" + ]; + openssh.authorizedKeys.keys = [ + publicKey + ]; + }; + # ssh agent with askpass + programs.ssh = { + startAgent = true; + }; + services.openssh = { + enable = true; + settings = { + PasswordAuthentication = false; + PermitRootLogin = "no"; + AllowUsers = [ "dev" ]; + }; + }; + programs.git.enable = true; + + environment.systemPackages = with pkgs; [ + # build dependencies, copied from flake.nix + go_1_26 + gnumake + # testing dependencies + (bats.withLibraries (p: [ + p.bats-assert + p.bats-file + p.bats-support + ])) + jq + ]; + + home-manager = { + useGlobalPkgs = true; + useUserPackages = true; + users.dev = + { ... }: + { + imports = [ + ./home.nix + ]; + }; + # pass args to home-manager + extraSpecialArgs = { + publicKey = publicKey; + privateKey = privateKey; + serverIp = serverIp; + }; + }; +} diff --git a/nix/hosts/client/home.nix b/nix/hosts/client/home.nix new file mode 100644 index 00000000..905a22f8 --- /dev/null +++ b/nix/hosts/client/home.nix @@ -0,0 +1,41 @@ +{ + serverIp, + ... +}: +{ + # Home Manager needs a bit of information about you and the + # paths it should manage. + home.username = "dev"; + home.homeDirectory = "/home/dev"; + + # This value determines the Home Manager release that your + # configuration is compatible with. This helps avoid breakage + # when a new Home Manager release introduces backwards + # incompatible changes. + # + # You can update Home Manager without changing this value. See + # the Home Manager release notes for a list of state version + # changes in each release. + home.stateVersion = "26.05"; + + # Let Home Manager install and manage itself. + programs.home-manager.enable = true; + programs.ssh = { + enable = true; + enableDefaultConfig = false; + settings = { + "abra.local" = { + HostName = serverIp; + User = "dev"; + Port = 22; + IdentityFile = "/home/dev/abra/test-integration"; + }; + "*.abra.local" = { + HostName = serverIp; + User = "dev"; + Port = 22; + IdentityFile = "/home/dev/abra/test-integration"; + }; + }; + }; +} diff --git a/nix/hosts/server/configuration.nix b/nix/hosts/server/configuration.nix new file mode 100644 index 00000000..e4a739fb --- /dev/null +++ b/nix/hosts/server/configuration.nix @@ -0,0 +1,116 @@ +{ + lib, + publicKey, + ... +}: +let + index = 3; + mac = "00:00:00:00:00:02"; + clientIp = "10.0.0.2"; +in +{ + microvm = { + vcpu = 2; + mem = 2049; # see issue related in microvm repo with 2048, so add 1MB + interfaces = [ + { + id = "vm${toString index}"; + type = "tap"; + inherit mac; + } + ]; + }; + + boot.tmp = { + useTmpfs = true; + tmpfsSize = "2G"; + }; + + networking = { + hostName = "abra-server"; + useNetworkd = true; + }; + systemd.network.networks."11-eth" = { + matchConfig.MACAddress = mac; + # Static IP configuration + address = [ + "10.0.0.${toString index}/32" + "fec0::${lib.toHexString index}/128" + ]; + routes = [ + { + # A route to the host + Destination = "10.0.0.0/32"; + GatewayOnLink = true; + } + { + # Route to server + Destination = "${clientIp}/32"; + Gateway = "10.0.0.0"; + GatewayOnLink = true; + } + { + # Default route + Destination = "0.0.0.0/0"; + Gateway = "10.0.0.0"; + GatewayOnLink = true; + } + { + # Default route + Destination = "::/0"; + Gateway = "fec0::"; + GatewayOnLink = true; + } + ]; + networkConfig = { + # DNS servers no longer come from DHCP nor Router + # Advertisements. Perhaps you want to change the defaults: + DNS = [ + # Quad9.net + "9.9.9.9" + "149.112.112.112" + "2620:fe::fe" + "2620:fe::9" + ]; + }; + }; + + # open the ports to allow ssh access from the host + networking.firewall.allowedTCPPorts = [ + 22 + 80 + 443 + ]; + networking.firewall.allowedUDPPorts = [ + 22 + 80 + 443 + ]; + + users.users.dev = { + isNormalUser = true; + password = "test"; + home = "/home/dev"; + description = "Alice Foobar"; + extraGroups = [ + "wheel" + "networkmanager" + "docker" + ]; + openssh.authorizedKeys.keys = [ + publicKey + ]; + }; + services.openssh = { + enable = true; + settings = { + PasswordAuthentication = false; + PermitRootLogin = "no"; + AllowUsers = [ "dev" ]; + }; + }; + virtualisation.docker = { + enable = true; + liveRestore = false; + }; +}