diff --git a/flake.lock b/flake.lock index a9491cb9..9c582016 100644 --- a/flake.lock +++ b/flake.lock @@ -36,24 +36,6 @@ "type": "github" } }, - "flake-utils_3": { - "inputs": { - "systems": "systems_3" - }, - "locked": { - "lastModified": 1710146030, - "narHash": "sha256-SZ5L6eA7HJ/nmkzGG7/ISclqe6oZdOZTNoesiInkXPQ=", - "owner": "numtide", - "repo": "flake-utils", - "rev": "b1d9ab70662946ef0850d488da1c9019f3a9752a", - "type": "github" - }, - "original": { - "owner": "numtide", - "repo": "flake-utils", - "type": "github" - } - }, "nixpkgs": { "locked": { "lastModified": 1716357214, @@ -72,52 +54,24 @@ "nixpkgs-matrix": { "inputs": { "flake-utils": "flake-utils_2", - "nixpkgs": "nixpkgs", - "polykey-cli": "polykey-cli" - }, - "locked": { - "lastModified": 1718671111, - "narHash": "sha256-7mgQvoUeAUeLkCh+wub8JNTT6x7onmIFyT90FT4uw88=", - "owner": "matrixai", - "repo": "nixpkgs-matrix", - "rev": "f00e00b892026a8588c9c01edde195585303ee84", - "type": "github" - }, - "original": { - "owner": "matrixai", - "repo": "nixpkgs-matrix", - "type": "github" - } - }, - "polykey-cli": { - "inputs": { - "flake-utils": "flake-utils_3", - "nixpkgs": [ - "nixpkgs-matrix", - "nixpkgs" - ] + "nixpkgs": "nixpkgs" }, "locked": { - "lastModified": 1718605364, - "narHash": "sha256-1JVAPfZ3s47ehaAaDY22UIAeYcxlB/5CSY4VYHPKf34=", + "lastModified": 1724224531, + "narHash": "sha256-413lAGcRWYYggDemwvhfbBTCoXNBHpXCdP/w9eUDZ7E=", "owner": "MatrixAI", - "repo": "Polykey-CLI", - "rev": "5973090c8fab456d048bac93b378af712dc5590f", + "repo": "nixpkgs-matrix", + "rev": "9f169070eedd7d7dd6d2f496bcb012d305bfe054", "type": "github" }, "original": { - "owner": "MatrixAI", - "repo": "Polykey-CLI", - "type": "github" + "id": "nixpkgs-matrix", + "type": "indirect" } }, "root": { "inputs": { "flake-utils": "flake-utils", - "nixpkgs": [ - "nixpkgs-matrix", - "nixpkgs" - ], "nixpkgs-matrix": "nixpkgs-matrix" } }, @@ -150,21 +104,6 @@ "repo": "default", "type": "github" } - }, - "systems_3": { - "locked": { - "lastModified": 1681028828, - "narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=", - "owner": "nix-systems", - "repo": "default", - "rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e", - "type": "github" - }, - "original": { - "owner": "nix-systems", - "repo": "default", - "type": "github" - } } }, "root": "root", diff --git a/flake.nix b/flake.nix index 91d8f284..42272438 100644 --- a/flake.nix +++ b/flake.nix @@ -1,175 +1,21 @@ { inputs = { - nixpkgs.url = "github:nixos/nixpkgs"; + nixpkgs-matrix.url = "github:MatrixAI/nixpkgs-matrix"; flake-utils.url = "github:numtide/flake-utils"; - - nixpkgs-matrix.url = "github:matrixai/nixpkgs-matrix"; - nixpkgs.follows = "nixpkgs-matrix/nixpkgs"; }; - outputs = { self, nixpkgs, flake-utils, ... }: + outputs = { self, nixpkgs-matrix, flake-utils, ... }: let - # The system being used to build the outputs - buildSystem = "x86_64-linux"; - # The target systems and their vercel/pkg mapping - systems = { - "x86_64-linux" = [ "linux" "x64" ]; - }; - in - { - nixosModules.default = { config, ... }: with nixpkgs; with lib; - { - options = { - services.polykey = { - enable = mkEnableOption "Enable the Polykey agent. Users with the `polykey` group or root permissions will be able to manage the agent."; - - passwordFilePath = mkOption { - type = with types; uniq str; - description = '' - The path to the Polykey password file. This is required to be set for the module to work, otherwise this module will fail. - ''; - }; - - recoveryCodeFilePath = mkOption { - type = with types; uniq str; - default = ""; - description = '' - The path to the Polykey recovery code file. This is not required, but if set will read a recovery code from the provided path to bootstrap a new state with. - ''; - }; - - recoveryCodeOutPath = mkOption { - type = with types; uniq str; - description = '' - The path to the Polykey recovery code file output location. - ''; - }; - - statePath = mkOption { - type = with types; uniq str; - default = "/var/lib/polykey"; - description = "The path to the Polykey node state directory. Will default to `/var/lib/polykey`, but can be overwritten to a custom path."; - }; - }; - programs.polykey = { - enable = mkEnableOption "Enable the per-user Polykey agent."; - - passwordFilePath = mkOption { - type = with types; uniq str; - description = '' - The path to the Polykey password file. This is required to be set for the module to work, otherwise this module will fail. - ''; - }; - - recoveryCodeFilePath = mkOption { - type = with types; uniq str; - default = ""; - description = '' - The path to the Polykey recovery code file. This is not required, but if set will read a recovery code from the provided path to bootstrap a new state with. - ''; - }; - - recoveryCodeOutPath = mkOption { - type = with types; uniq str; - description = '' - The path to the Polykey recovery code file output location. - ''; - }; - - statePath = mkOption { - type = with types; uniq str; - default = "%h/.local/share/polykey"; - description = "The path to the Polykey node state directory. Will default to `$HOME/.local/share/polykey`, but can be overwritten to a custom path."; - }; - }; - }; - config = mkMerge [ - (mkIf config.services.polykey.enable { - users.groups.polykey = {}; - - environment.systemPackages = [ - self.outputs.packages.${buildSystem}.default - ]; - - system.activationScripts.makeAgentPaths = '' - mkdir -p ${config.services.polykey.statePath} - chgrp -R polykey ${config.services.polykey.statePath} - chmod 770 ${config.services.polykey.statePath} - ''; - - systemd.services.polykey = { - description = "Polykey Agent"; - wantedBy = [ "multi-user.target" ]; - after = [ "network.target" ]; - serviceConfig = { - User = "root"; - Group = "polykey"; - PermissionsStartOnly = true; - LoadCredential = [ - "password:${config.services.polykey.passwordFilePath}" - ]; - ExecStartPre = '' - -${self.outputs.packages.${buildSystem}.default}/bin/polykey \ - --password-file ''${CREDENTIALS_DIRECTORY}/password \ - --node-path ${config.services.polykey.statePath} \ - bootstrap ${lib.optionalString (config.services.polykey.recoveryCodeFilePath != "") '' -rcf ${config.services.polykey.recoveryCodeFilePath}''}\ - --recovery-code-out-file ${config.services.polykey.recoveryCodeOutPath} - ''; - ExecStart = '' - ${self.outputs.packages.${buildSystem}.default}/bin/polykey \ - --password-file ''${CREDENTIALS_DIRECTORY}/password \ - --node-path ${config.services.polykey.statePath} \ - agent start \ - --recovery-code-out-file ${config.services.polykey.recoveryCodeOutPath} - ''; - }; - }; - }) - (mkIf config.programs.polykey.enable { - environment.systemPackages = [ - self.outputs.packages.${buildSystem}.default - ]; - - system.activationScripts.makeUserAgentPaths = '' - mkdir -p ${config.programs.polykey.statePath} - ''; - - systemd.user.services.polykey = { - description = "Polykey Agent"; - wantedBy = [ "default.target" ]; - after = [ "network.target" ]; - serviceConfig = { - ExecStartPre = '' - -${self.outputs.packages.${buildSystem}.default}/bin/polykey \ - --password-file ${config.programs.polykey.passwordFilePath} \ - --node-path ${config.programs.polykey.statePath} \ - bootstrap ${lib.optionalString (config.programs.polykey.recoveryCodeFilePath != "") '' -rcf ${config.programs.polykey.recoveryCodeFilePath}''}\ - --recovery-code-out-file ${config.programs.polykey.recoveryCodeOutPath} - ''; - ExecStart = '' - ${self.outputs.packages.${buildSystem}.default}/bin/polykey \ - --password-file ${config.programs.polykey.passwordFilePath} \ - --node-path ${config.programs.polykey.statePath} \ - agent start \ - --recovery-code-out-file ${config.programs.polykey.recoveryCodeOutPath} - ''; - }; - }; - }) - ]; - }; - } // - flake-utils.lib.eachSystem (builtins.attrNames systems) (targetSystem: + systems = { "x86_64-linux" = [ "linux" "x64" ]; }; + in flake-utils.lib.eachSystem (builtins.attrNames systems) (system: let - platform = builtins.elemAt systems.${targetSystem} 0; - arch = builtins.elemAt systems.${targetSystem} 1; + pkgs = nixpkgs-matrix.legacyPackages.${system}; - pkgs = import nixpkgs { - system = buildSystem; - }; + platform = builtins.elemAt systems.${system} 0; + arch = builtins.elemAt systems.${system} 1; - utils = pkgs.callPackage ./utils.nix {}; + utils = pkgs.callPackage ./utils.nix { }; commitHash = toString (self.rev or self.dirtyRev); npmDepsHash = builtins.readFile ./npmDepsHash; @@ -199,7 +45,8 @@ polykey-cli-executable = pkgs.buildNpmPackage { inherit npmDepsHash; - name = "${utils.packageName}-${utils.packageVersion}-${platform}-${arch}"; + name = + "${utils.packageName}-${utils.packageVersion}-${platform}-${arch}"; src = utils.src; PKG_CACHE_PATH = utils.pkgCachePath; PKG_IGNORE_TAG = 1; @@ -219,7 +66,8 @@ dontFixup = true; }; - buildJSON = builtins.fromJSON (builtins.readFile "${polykey-cli}/build.json"); + buildJSON = + builtins.fromJSON (builtins.readFile "${polykey-cli}/build.json"); docker = pkgs.dockerTools.buildImage { name = polykey-cli.name; @@ -235,53 +83,51 @@ }; }; - shell = { ci ? false }: with pkgs; pkgs.mkShell { - nativeBuildInputs = [ - nodejs_20 - prefetch-npm-deps - shellcheck - gitAndTools.gh - gitAndTools.git - awscli2 - skopeo - jq - ]; - PKG_CACHE_PATH = utils.pkgCachePath; - PKG_IGNORE_TAG = 1; - shellHook = '' - echo "Entering $(npm pkg get name)" - set -o allexport - . ./.env - set +o allexport - set -v - ${ - lib.optionalString ci - '' - set -o errexit - set -o nounset - set -o pipefail - shopt -s inherit_errexit - '' - } - mkdir --parents "$(pwd)/tmp" + shell = { ci ? false }: + with pkgs; + pkgs.mkShell { + nativeBuildInputs = [ + nodejs_20 + prefetch-npm-deps + shellcheck + gitAndTools.gh + gitAndTools.git + awscli2 + skopeo + jq + ]; + PKG_CACHE_PATH = utils.pkgCachePath; + PKG_IGNORE_TAG = 1; + shellHook = '' + echo "Entering $(npm pkg get name)" + set -o allexport + . ./.env + set +o allexport + set -v + ${lib.optionalString ci '' + set -o errexit + set -o nounset + set -o pipefail + shopt -s inherit_errexit + ''} + mkdir --parents "$(pwd)/tmp" - export PATH="$(pwd)/dist/bin:$(npm root)/.bin:$PATH" + export PATH="$(pwd)/dist/bin:$(npm root)/.bin:$PATH" - npm install --ignore-scripts + npm install --ignore-scripts - set +v - ''; - }; - in - { + set +v + ''; + }; + in { apps = { - default ={ + default = { type = "app"; - program = "${self.packages.${targetSystem}.default}/bin/polykey"; + program = "${polykey-cli}/bin/polykey"; }; executable = { type = "app"; - program = "${self.packages.${targetSystem}.executable}"; + program = polykey-cli-executable; }; }; @@ -295,6 +141,164 @@ default = shell { ci = false; }; ci = shell { ci = true; }; }; - } - ); + }) // { + nixosModules.default = { config, ... }: + with nixpkgs-matrix.lib; { + options = { + services.polykey = { + enable = mkEnableOption + "Enable the Polykey agent. Users with the `polykey` group or root permissions will be able to manage the agent."; + + passwordFilePath = mkOption { + type = with types; uniq str; + description = '' + The path to the Polykey password file. This is required to be set for the module to work, otherwise this module will fail. + ''; + }; + + recoveryCodeFilePath = mkOption { + type = with types; uniq str; + default = ""; + description = '' + The path to the Polykey recovery code file. This is not required, but if set will read a recovery code from the provided path to bootstrap a new state with. + ''; + }; + + recoveryCodeOutPath = mkOption { + type = with types; uniq str; + description = '' + The path to the Polykey recovery code file output location. + ''; + }; + + statePath = mkOption { + type = with types; uniq str; + default = "/var/lib/polykey"; + description = + "The path to the Polykey node state directory. Will default to `/var/lib/polykey`, but can be overwritten to a custom path."; + }; + }; + programs.polykey = { + enable = mkEnableOption "Enable the per-user Polykey agent."; + + passwordFilePath = mkOption { + type = with types; uniq str; + description = '' + The path to the Polykey password file. This is required to be set for the module to work, otherwise this module will fail. + ''; + }; + + recoveryCodeFilePath = mkOption { + type = with types; uniq str; + default = ""; + description = '' + The path to the Polykey recovery code file. This is not required, but if set will read a recovery code from the provided path to bootstrap a new state with. + ''; + }; + + recoveryCodeOutPath = mkOption { + type = with types; uniq str; + description = '' + The path to the Polykey recovery code file output location. + ''; + }; + + statePath = mkOption { + type = with types; uniq str; + default = "%h/.local/share/polykey"; + description = + "The path to the Polykey node state directory. Will default to `$HOME/.local/share/polykey`, but can be overwritten to a custom path."; + }; + }; + }; + config = mkMerge [ + (mkIf config.services.polykey.enable { + users.groups.polykey = { }; + + environment.systemPackages = + [ self.outputs.packages.${buildSystem}.default ]; + + system.activationScripts.makeAgentPaths = '' + mkdir -p ${config.services.polykey.statePath} + chgrp -R polykey ${config.services.polykey.statePath} + chmod 770 ${config.services.polykey.statePath} + ''; + + systemd.services.polykey = { + description = "Polykey Agent"; + wantedBy = [ "multi-user.target" ]; + after = [ "network.target" ]; + serviceConfig = { + User = "root"; + Group = "polykey"; + PermissionsStartOnly = true; + LoadCredential = [ + "password:${config.services.polykey.passwordFilePath}" + ]; + ExecStartPre = '' + -${ + self.outputs.packages.${buildSystem}.default + }/bin/polykey \ + --password-file ''${CREDENTIALS_DIRECTORY}/password \ + --node-path ${config.services.polykey.statePath} \ + bootstrap ${ + lib.optionalString + (config.services.polykey.recoveryCodeFilePath != "") + "-rcf ${config.services.polykey.recoveryCodeFilePath}" + }\ + --recovery-code-out-file ${config.services.polykey.recoveryCodeOutPath} + ''; + ExecStart = '' + ${ + self.outputs.packages.${buildSystem}.default + }/bin/polykey \ + --password-file ''${CREDENTIALS_DIRECTORY}/password \ + --node-path ${config.services.polykey.statePath} \ + agent start \ + --recovery-code-out-file ${config.services.polykey.recoveryCodeOutPath} + ''; + }; + }; + }) + (mkIf config.programs.polykey.enable { + environment.systemPackages = + [ self.outputs.packages.${buildSystem}.default ]; + + system.activationScripts.makeUserAgentPaths = '' + mkdir -p ${config.programs.polykey.statePath} + ''; + + systemd.user.services.polykey = { + description = "Polykey Agent"; + wantedBy = [ "default.target" ]; + after = [ "network.target" ]; + serviceConfig = { + ExecStartPre = '' + -${ + self.outputs.packages.${buildSystem}.default + }/bin/polykey \ + --password-file ${config.programs.polykey.passwordFilePath} \ + --node-path ${config.programs.polykey.statePath} \ + bootstrap ${ + lib.optionalString + (config.programs.polykey.recoveryCodeFilePath != "") + "-rcf ${config.programs.polykey.recoveryCodeFilePath}" + }\ + --recovery-code-out-file ${config.programs.polykey.recoveryCodeOutPath} + ''; + ExecStart = '' + ${ + self.outputs.packages.${buildSystem}.default + }/bin/polykey \ + --password-file ${config.programs.polykey.passwordFilePath} \ + --node-path ${config.programs.polykey.statePath} \ + agent start \ + --recovery-code-out-file ${config.programs.polykey.recoveryCodeOutPath} + ''; + }; + }; + }) + ]; + }; + }; } diff --git a/utils.nix b/utils.nix index 1ea9aadf..1354bfac 100644 --- a/utils.nix +++ b/utils.nix @@ -1,9 +1,4 @@ -{ nix-gitignore -, linkFarm -, nodejs_20 -, lib -, fetchurl -}: +{ nix-gitignore, linkFarm, nodejs_20, lib, fetchurl }: rec { nodeVersion = builtins.elemAt (lib.versions.splitVersion nodejs_20.version) 0; @@ -33,45 +28,50 @@ rec { pkgBuilds = { "3.5" = { "linux-x64" = fetchurl { - url = "https://github.com/yao-pkg/pkg-fetch/releases/download/v3.5/node-v20.11.1-linux-x64"; - sha256 = "0f065bb2ccfdedaa7889e04604516604c2d0c0a0d9d13869578a6b3916b9a93e"; + url = + "https://github.com/yao-pkg/pkg-fetch/releases/download/v3.5/node-v20.11.1-linux-x64"; + sha256 = + "0f065bb2ccfdedaa7889e04604516604c2d0c0a0d9d13869578a6b3916b9a93e"; }; "win32-x64" = fetchurl { - url = "https://github.com/yao-pkg/pkg-fetch/releases/download/v3.5/node-v20.11.1-win-x64"; - sha256 = "140c377c2c91751832e673cb488724cbd003f01aa237615142cd2907f34fa1a2"; + url = + "https://github.com/yao-pkg/pkg-fetch/releases/download/v3.5/node-v20.11.1-win-x64"; + sha256 = + "140c377c2c91751832e673cb488724cbd003f01aa237615142cd2907f34fa1a2"; }; "macos-x64" = fetchurl { - url = "https://github.com/yao-pkg/pkg-fetch/releases/download/v3.5/node-v20.11.1-macos-x64"; - sha256 = "1558a49dfea01ae42702a71eaa1c7a6479abde8b2778bc7cb4f9a65d65a0afa6"; + url = + "https://github.com/yao-pkg/pkg-fetch/releases/download/v3.5/node-v20.11.1-macos-x64"; + sha256 = + "1558a49dfea01ae42702a71eaa1c7a6479abde8b2778bc7cb4f9a65d65a0afa6"; }; "macos-arm64" = fetchurl { - url = "https://github.com/yao-pkg/pkg-fetch/releases/download/v3.5/node-v20.11.1-macos-arm64"; - sha256 = "1fa7f9e233820cfc5668ba21b70c463214f981fc69f1b8175b25dfa871451e26"; + url = + "https://github.com/yao-pkg/pkg-fetch/releases/download/v3.5/node-v20.11.1-macos-arm64"; + sha256 = + "1fa7f9e233820cfc5668ba21b70c463214f981fc69f1b8175b25dfa871451e26"; }; }; }; - pkgCachePath = - let - pkgBuild = pkgBuilds."3.5"; - fetchedName = n: builtins.replaceStrings ["node"] ["fetched"] n; - in - linkFarm "pkg-cache" - [ - { - name = fetchedName pkgBuild.linux-x64.name; - path = pkgBuild.linux-x64; - } - { - name = fetchedName pkgBuild.win32-x64.name; - path = pkgBuild.win32-x64; - } - { - name = fetchedName pkgBuild.macos-x64.name; - path = pkgBuild.macos-x64; - } - { - name = fetchedName pkgBuild.macos-arm64.name; - path = pkgBuild.macos-arm64; - } - ]; + pkgCachePath = let + pkgBuild = pkgBuilds."3.5"; + fetchedName = n: builtins.replaceStrings [ "node" ] [ "fetched" ] n; + in linkFarm "pkg-cache" [ + { + name = fetchedName pkgBuild.linux-x64.name; + path = pkgBuild.linux-x64; + } + { + name = fetchedName pkgBuild.win32-x64.name; + path = pkgBuild.win32-x64; + } + { + name = fetchedName pkgBuild.macos-x64.name; + path = pkgBuild.macos-x64; + } + { + name = fetchedName pkgBuild.macos-arm64.name; + path = pkgBuild.macos-arm64; + } + ]; }