refactor: optimize eval time
lifting `let` bindings up where possible helps reduce the number of thunks nix has to allocate. this patch only does that by 0.3%-ish, though
This commit is contained in:
@@ -62,14 +62,13 @@ rec {
|
||||
# now items is a list where every element is undecorated at the toplevel.
|
||||
# e.g. each item is an ordinary attrset or primitive.
|
||||
# we still need to discharge the *rest* of the path though, for every item.
|
||||
name = lib.head path;
|
||||
downstream = lib.tail path;
|
||||
dischargeDownstream = it: if path != [] && it ? name then
|
||||
builtins.map (v: it // { "${name}" = v; }) (dischargeToPath downstream it."${name}")
|
||||
else
|
||||
[ it ];
|
||||
in
|
||||
lib.concatMap dischargeDownstream items;
|
||||
lib.concatMap (dischargeDownstream path) items;
|
||||
|
||||
dischargeDownstream = path: it: if path != [] && it ? name then
|
||||
builtins.map (v: it // { "${lib.head path}" = v; }) (dischargeToPath (lib.tail path) it."${lib.head path}")
|
||||
else
|
||||
[ it ];
|
||||
|
||||
# discharge many items but only over one path.
|
||||
# Type: dischargeItemsToPaths :: [Attrs] -> String -> [Attrs]
|
||||
@@ -92,9 +91,10 @@ rec {
|
||||
# since the act of discharging should have forced all the relevant data out to the leaves,
|
||||
# we just set each expected terminal to null (initializing the parents when necessary)
|
||||
# and that gives a standard value for any fully-consumed items that we can do equality comparisons with.
|
||||
wipePath = acc: path: lib.recursiveUpdate acc (lib.setAttrByPath path null);
|
||||
remainder = builtins.foldl' wipePath i paths;
|
||||
expected-remainder = builtins.foldl' wipePath {} paths;
|
||||
remainder = builtins.foldl' _wipePath i paths;
|
||||
expected-remainder = builtins.foldl' _wipePath {} paths;
|
||||
in
|
||||
assert remainder == expected-remainder; true;
|
||||
|
||||
_wipePath = acc: path: lib.recursiveUpdate acc (lib.setAttrByPath path null);
|
||||
}
|
||||
|
@@ -118,6 +118,19 @@ let
|
||||
}
|
||||
];
|
||||
|
||||
# set the `store` attribute on one dir attrset
|
||||
annotateWithStore = store: dir: {
|
||||
"${dir.path}".store = store;
|
||||
};
|
||||
# convert an `entryInStore` to an `entryAtPath` (less the `store` item)
|
||||
dirToAttrs = dir: {
|
||||
"${dir.path}" = builtins.removeAttrs dir ["path"];
|
||||
};
|
||||
# AttrSet -> (store -> path -> AttrSet) -> [AttrSet]
|
||||
applyToAllStores = byStore: f: lib.concatMap
|
||||
(store: map (f store) byStore."${store}")
|
||||
(builtins.attrNames byStore);
|
||||
|
||||
# this submodule converts store-based access to path-based access so that the user can specify e.g.:
|
||||
# <top>.byStore.private = [ ".cache/vim" ];
|
||||
# <top>.byStore.private = [ { path=".cache/vim"; mode = "0700"; } ];
|
||||
@@ -140,29 +153,12 @@ let
|
||||
'';
|
||||
};
|
||||
};
|
||||
config = let
|
||||
# set the `store` attribute on one dir attrset
|
||||
annotateWithStore = store: dir: {
|
||||
"${dir.path}".store = store;
|
||||
};
|
||||
# convert an `entryInStore` to an `entryAtPath` (less the `store` item)
|
||||
dirToAttrs = dir: {
|
||||
"${dir.path}" = builtins.removeAttrs dir ["path"];
|
||||
};
|
||||
# store-names = attrNames cfg.stores;
|
||||
# :: (store -> entry -> AttrSet) -> [AttrSet]
|
||||
# applyToAllStores = f: lib.concatMap
|
||||
# (store: map (f store) config.byStore."${store}")
|
||||
# store-names;
|
||||
applyToAllStores = f: lib.concatMap
|
||||
(store: map (f store) config.byStore."${store}")
|
||||
(builtins.attrNames config.byStore);
|
||||
in {
|
||||
config = {
|
||||
byPath = lib.mkMerge (concatLists [
|
||||
# convert the list-style per-store entries into attrsOf entries
|
||||
(applyToAllStores (_store: dirToAttrs))
|
||||
(applyToAllStores config.byStore (_store: dirToAttrs))
|
||||
# add the `store` attr to everything we ingested
|
||||
(applyToAllStores annotateWithStore)
|
||||
(applyToAllStores config.byStore annotateWithStore)
|
||||
]);
|
||||
};
|
||||
});
|
||||
|
@@ -3,6 +3,9 @@ let
|
||||
saneCfg = config.sane;
|
||||
cfg = config.sane.programs;
|
||||
|
||||
makeSandboxArgs = pkgs.callPackage ./make-sandbox-args.nix { };
|
||||
makeSandboxed = pkgs.callPackage ./make-sandboxed.nix { };
|
||||
|
||||
# create a map:
|
||||
# {
|
||||
# "${pkgName}" = {
|
||||
@@ -38,9 +41,6 @@ let
|
||||
package
|
||||
else
|
||||
let
|
||||
makeSandboxArgs = pkgs.callPackage ./make-sandbox-args.nix { };
|
||||
makeSandboxed = pkgs.callPackage ./make-sandboxed.nix { };
|
||||
|
||||
vpn = if sandbox.net == "vpn" then
|
||||
lib.findSingle (v: v.isDefault) null null (builtins.attrValues config.sane.vpn)
|
||||
else if sandbox.net == "vpn.wg-home" then
|
||||
|
@@ -1,20 +1,4 @@
|
||||
{ lib }:
|
||||
{
|
||||
method,
|
||||
allowedPaths ? [],
|
||||
allowedHomePaths ? [],
|
||||
allowedRunPaths ? [],
|
||||
autodetectCliPaths ? false,
|
||||
capabilities ? [],
|
||||
dns ? null,
|
||||
keepIpc ? false,
|
||||
keepPids ? false,
|
||||
tryKeepUsers ? false,
|
||||
netDev ? null,
|
||||
netGateway ? null,
|
||||
whitelistPwd ? false,
|
||||
extraConfig ? [],
|
||||
}:
|
||||
let
|
||||
saneboxGenerators = {
|
||||
autodetectCliPaths = style: [ "--sanebox-autodetect" style ];
|
||||
@@ -26,9 +10,9 @@ let
|
||||
method = method: [ "--sanebox-method" method ];
|
||||
netDev = netDev: [ "--sanebox-net-dev" netDev ];
|
||||
netGateway = netGateway: [ "--sanebox-net-gateway" netGateway ];
|
||||
path = p: [ "--sanebox-path" p ];
|
||||
path-home = p: [ "--sanebox-home-path" p ];
|
||||
path-run = p: [ "--sanebox-run-path" p ];
|
||||
path.unqualified = p: [ "--sanebox-path" p ];
|
||||
path.home = p: [ "--sanebox-home-path" p ];
|
||||
path.run = p: [ "--sanebox-run-path" p ];
|
||||
whitelistPwd = [ "--sanebox-add-pwd" ];
|
||||
};
|
||||
bunpenGenerators = {
|
||||
@@ -61,32 +45,50 @@ let
|
||||
else
|
||||
[ "--bunpen-path" "/dev/net/tun" "--bunpen-net-dev" n ];
|
||||
netGateway = netGateway: [ "--bunpen-net-gateway" netGateway ];
|
||||
path = p: [ "--bunpen-path" p ];
|
||||
path-home = p: [ "--bunpen-home-path" p ];
|
||||
path-run = p: [ "--bunpen-run-path" p ];
|
||||
path.unqualified = p: [ "--bunpen-path" p ];
|
||||
path.home = p: [ "--bunpen-home-path" p ];
|
||||
path.run = p: [ "--bunpen-run-path" p ];
|
||||
tryKeepUsers = [ "--bunpen-try-keep-users" ];
|
||||
whitelistPwd = [ "--bunpen-path" "." ];
|
||||
};
|
||||
in
|
||||
{
|
||||
method,
|
||||
allowedPaths ? [],
|
||||
allowedHomePaths ? [],
|
||||
allowedRunPaths ? [],
|
||||
autodetectCliPaths ? false,
|
||||
capabilities ? [],
|
||||
dns ? null,
|
||||
keepIpc ? false,
|
||||
keepPids ? false,
|
||||
tryKeepUsers ? false,
|
||||
netDev ? null,
|
||||
netGateway ? null,
|
||||
whitelistPwd ? false,
|
||||
extraConfig ? [],
|
||||
}:
|
||||
let
|
||||
gen = if method == "bunpen" then
|
||||
bunpenGenerators
|
||||
else
|
||||
saneboxGenerators
|
||||
;
|
||||
allowPaths = flavor: paths: lib.flatten (builtins.map gen."path${flavor}" paths);
|
||||
allowPaths = flavor: paths: lib.flatten (builtins.map gen.path."${flavor}" paths);
|
||||
|
||||
capabilityFlags = lib.flatten (builtins.map gen.capability capabilities);
|
||||
|
||||
netItems = lib.optionals (netDev != null) (gen.netDev netDev)
|
||||
++ lib.optionals (netGateway != null) (gen.netGateway netGateway)
|
||||
++ lib.optionals (dns != null) (lib.flatten (builtins.map gen.dns dns))
|
||||
++ lib.optionals (netGateway != null) (gen.netGateway netGateway)
|
||||
++ lib.optionals (dns != null) (lib.flatten (builtins.map gen.dns dns))
|
||||
;
|
||||
|
||||
in
|
||||
(gen.method method)
|
||||
++ netItems
|
||||
++ allowPaths "" allowedPaths
|
||||
++ allowPaths "-home" allowedHomePaths
|
||||
++ allowPaths "-run" allowedRunPaths
|
||||
++ allowPaths "unqualified" allowedPaths
|
||||
++ allowPaths "home" allowedHomePaths
|
||||
++ allowPaths "run" allowedRunPaths
|
||||
++ capabilityFlags
|
||||
++ lib.optionals (autodetectCliPaths != null) (gen.autodetectCliPaths autodetectCliPaths)
|
||||
++ lib.optionals keepIpc gen.keepIpc
|
||||
|
@@ -1,14 +1,15 @@
|
||||
# this overlay exists specifically to control the order in which other overlays are applied.
|
||||
# for example, `pkgs` *must* be added before `cross`, as the latter applies overrides
|
||||
# to the packages defined in the former.
|
||||
|
||||
final: prev:
|
||||
let
|
||||
pkgs = import ./pkgs.nix;
|
||||
preferences = import ./preferences.nix;
|
||||
cross = import ./cross.nix;
|
||||
pkgs-ccache = import ./pkgs-ccache.nix;
|
||||
pkgs-debug = import ./pkgs-debug.nix;
|
||||
in
|
||||
final: prev:
|
||||
let
|
||||
|
||||
isCross = prev.stdenv.hostPlatform != prev.stdenv.buildPlatform;
|
||||
ifCross = overlay: if isCross then overlay else (_: _: {});
|
||||
|
Reference in New Issue
Block a user