diff --git a/CHANGELOG.md b/CHANGELOG.md index b728640..4deead8 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,8 @@ Changes yet to be released are documented here. +- Add nixos, home-manager, and darwin-nix modules + ## v0.1.0 Initial release. diff --git a/flake.nix b/flake.nix index a5a5919..72df013 100644 --- a/flake.nix +++ b/flake.nix @@ -6,6 +6,7 @@ let systems = [ "x86_64-linux" + "aarch64-linux" "aarch64-darwin" ]; forAllSystems = fn: nixpkgs.lib.genAttrs systems (system: fn nixpkgs.legacyPackages.${system}); @@ -23,18 +24,24 @@ }; }); - checks = forAllSystems (pkgs: { - tests = self.packages.${pkgs.stdenv.hostPlatform.system}.default.overrideAttrs (_: { - pname = "nix-cache-login-tests"; - checkPhase = '' - runHook preCheck - go test ./... - runHook postCheck - ''; - doCheck = true; - }); - devShell = self.devShells.${pkgs.stdenv.hostPlatform.system}.default; - }); + checks = forAllSystems ( + pkgs: + { + tests = self.packages.${pkgs.stdenv.hostPlatform.system}.default.overrideAttrs (_: { + pname = "nix-cache-login-tests"; + checkPhase = '' + runHook preCheck + go test ./... + runHook postCheck + ''; + doCheck = true; + }); + devShell = self.devShells.${pkgs.stdenv.hostPlatform.system}.default; + } + // pkgs.lib.optionalAttrs pkgs.stdenv.isLinux { + nixos-module = pkgs.testers.runNixOSTest (import ./nixos-test.nix self); + } + ); devShells = forAllSystems (pkgs: { default = pkgs.mkShell { @@ -45,6 +52,23 @@ }; }); + homeModules = { + # Workstation (Linux + macOS): home-manager module running `nix-cache-login refresh` + default = + { + config, + lib, + pkgs, + ... + }: + { + imports = [ ./home-module.nix ]; + services.nix-cache-login.package = + lib.mkDefault + self.packages.${pkgs.stdenv.hostPlatform.system}.default; + }; + }; + nixosModules = { # Workstation: systemd user timer+service running `nix-cache-login refresh` default = diff --git a/home-module.nix b/home-module.nix new file mode 100644 index 0000000..90e80ab --- /dev/null +++ b/home-module.nix @@ -0,0 +1,62 @@ +{ + config, + lib, + ... +}: +let + cfg = config.services.nix-cache-login; +in +{ + options.services.nix-cache-login = { + enable = lib.mkEnableOption "nix-cache-login automatic token refresh"; + package = lib.mkOption { + type = lib.types.package; + description = "The nix-cache-login package to use."; + }; + refreshInterval = lib.mkOption { + type = lib.types.ints.positive; + default = 900; + description = '' + How often to attempt token refresh, in seconds. + If no valid session exists, the service logs an error and retries on + the next interval. Run {command}`nix-cache-login` to log in. + ''; + example = 1800; + }; + }; + + config = lib.mkIf cfg.enable { + home.packages = [ cfg.package ]; + systemd.user.services.nix-cache-login = { + Unit.Description = "Nix cache login - refresh access token"; + Service = { + Type = "oneshot"; + ExecStart = "${cfg.package}/bin/nix-cache-login refresh"; + }; + }; + + systemd.user.timers.nix-cache-login = { + Unit.Description = "Nix cache login - periodic token refresh"; + Timer = { + OnBootSec = "2min"; + OnUnitActiveSec = "${toString cfg.refreshInterval}s"; + }; + Install.WantedBy = [ "timers.target" ]; + }; + + launchd.agents.nix-cache-login = { + enable = true; + config = { + ProgramArguments = [ + "${cfg.package}/bin/nix-cache-login" + "refresh" + ]; + StartInterval = cfg.refreshInterval; + RunAtLoad = true; + ProcessType = "Background"; + StandardOutPath = "${config.home.homeDirectory}/Library/Logs/nix-cache-login.log"; + StandardErrorPath = "${config.home.homeDirectory}/Library/Logs/nix-cache-login.log"; + }; + }; + }; +} diff --git a/nixos-test.nix b/nixos-test.nix new file mode 100644 index 0000000..9c5840f --- /dev/null +++ b/nixos-test.nix @@ -0,0 +1,29 @@ +self: { + name = "nix-cache-login-nixos-module"; + + nodes.machine = + { ... }: + { + imports = [ self.nixosModules.default ]; + services.nix-cache-login.enable = true; + }; + + testScript = '' + machine.wait_for_unit("multi-user.target") + + # The module should install timer and service unit files for all users + machine.succeed("test -f /etc/systemd/user/nix-cache-login.timer") + machine.succeed("test -f /etc/systemd/user/nix-cache-login.service") + + # wantedBy = ["timers.target"] should create this symlink + machine.succeed( + "test -L /etc/systemd/user/timers.target.wants/nix-cache-login.timer" + ) + + # Service unit should reference the correct subcommand + unit = machine.succeed("cat /etc/systemd/user/nix-cache-login.service") + assert "nix-cache-login refresh" in unit, ( + f"ExecStart not found in service unit:\n{unit}" + ) + ''; +}