simple nixos wrapper module

This commit is contained in:
atagen 2025-11-09 01:30:04 +11:00
parent 2341a204bb
commit b11ab8a728
2 changed files with 105 additions and 5 deletions

View file

@ -1,6 +1,8 @@
{
inputs.nixpkgs.url = "github:nixos/nixpkgs/nixpkgs-unstable";
inputs.systems.url = "github:nix-systems/default-linux";
inputs = {
nixpkgs.url = "github:nixos/nixpkgs/nixpkgs-unstable";
systems.url = "github:nix-systems/default-linux";
};
outputs =
{
@ -34,10 +36,13 @@
yoke-lite = pkgs.rustPlatform.callPackage ./nix/package.nix { };
});
nixosModules.default =
{ pkgs, ... }:
{ pkgs, lib, ... }:
{
imports = [ ./nix/module.nix ];
programs.yoke.package = self.packages.${pkgs.system}.yoke;
config = {
imports = [ ./nix/module.nix ];
wrapperPkg = self.packages.${pkgs.system}.yoke-lite;
environment.systemPackages = [ self.packages.${pkgs.system}.yoke ];
};
};
};
}

95
nix/module.nix Normal file
View file

@ -0,0 +1,95 @@
{
pkgs,
lib,
config,
...
}:
let
inherit (lib) mkOption mkPackageOption types;
strNotEmpty = s: lib.stringLength s != 0;
wrapperType = lib.types.submodule {
options = {
package = mkPackageOption "wrapped" { } {
nullable = false;
};
executable = mkOption {
type = types.str;
default = "";
};
args = mkOption {
type = types.listOf types.str;
default = [ ];
};
env = mkOption {
type = types.attrsOf (types.listOf types.str);
default = { };
};
retainEnv = mkOption {
type = types.bool;
default = false;
};
addPwd = mkOption {
type = types.bool;
default = false;
};
additionalPaths = mkOption {
type = types.listOf types.str;
default = [ ];
};
};
};
in
{
options = {
wrappers = mkOption {
type = types.attrsOf wrapperType;
};
wrapperPkg = mkPackageOption "wrapper" { } { nullable = false; };
};
config =
let
wrap =
name: opts:
let
envs = lib.concatStringsSep " " (
lib.mapAttrsToList (n: v: "${n}=${lib.concatStringsSep ":" v}") opts.env
);
extra = lib.concatStringsSep " " opts.additionalPaths;
sandboxArgs = pkgs.stdenvNoCC.mkDerivation {
name = "${name}-opts";
__structuredAttrs = true;
exportReferencesGraph.closure = [ opts.package ];
preferLocalBuild = true;
nativeBuildInputs = [
pkgs.coreutils
pkgs.jq
];
buildCommand = ''
echo -n "--fs rx=" > $out
jq -r '.closure[].path' < "$NIX_ATTRS_JSON_FILE" \
| tr '\n' ':' | sed 's/:$//' >> $out
${if (lib.length opts.additionalPaths != 0) then "echo -n ' ${extra}' >> $out" else ""}
${if (strNotEmpty envs) then "echo -n ' --env ${envs}' >> $out" else ""}
'';
};
command = lib.getExe' opts.package (
if (strNotEmpty opts.executable) then opts.executable else opts.package.pname
);
wrappedArgs = lib.concatStringsSep " " opts.args;
script = ''
#! /usr/bin/env bash
${lib.getExe' config.wrapperPkg "yoke"} \
${if opts.addPwd then "--fs rwx=$PWD" else ""} \
${if opts.retainEnv then "--retain-env" else ""} \
--fd-args -- \
${command} \
${wrappedArgs} $@ \
3< ${sandboxArgs}
'';
in
pkgs.writeScriptBin "${name}" script;
in
{
environment.systemPackages = lib.mapAttrsToList wrap config.wrappers;
};
}