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.
|
# now items is a list where every element is undecorated at the toplevel.
|
||||||
# e.g. each item is an ordinary attrset or primitive.
|
# e.g. each item is an ordinary attrset or primitive.
|
||||||
# we still need to discharge the *rest* of the path though, for every item.
|
# we still need to discharge the *rest* of the path though, for every item.
|
||||||
name = lib.head path;
|
in
|
||||||
downstream = lib.tail path;
|
lib.concatMap (dischargeDownstream path) items;
|
||||||
dischargeDownstream = it: if path != [] && it ? name then
|
|
||||||
builtins.map (v: it // { "${name}" = v; }) (dischargeToPath downstream it."${name}")
|
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
|
else
|
||||||
[ it ];
|
[ it ];
|
||||||
in
|
|
||||||
lib.concatMap dischargeDownstream items;
|
|
||||||
|
|
||||||
# discharge many items but only over one path.
|
# discharge many items but only over one path.
|
||||||
# Type: dischargeItemsToPaths :: [Attrs] -> String -> [Attrs]
|
# 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,
|
# 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)
|
# 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.
|
# 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;
|
||||||
remainder = builtins.foldl' wipePath i paths;
|
expected-remainder = builtins.foldl' _wipePath {} paths;
|
||||||
expected-remainder = builtins.foldl' wipePath {} paths;
|
|
||||||
in
|
in
|
||||||
assert remainder == expected-remainder; true;
|
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.:
|
# 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 = [ ".cache/vim" ];
|
||||||
# <top>.byStore.private = [ { path=".cache/vim"; mode = "0700"; } ];
|
# <top>.byStore.private = [ { path=".cache/vim"; mode = "0700"; } ];
|
||||||
@@ -140,29 +153,12 @@ let
|
|||||||
'';
|
'';
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
config = let
|
config = {
|
||||||
# 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 {
|
|
||||||
byPath = lib.mkMerge (concatLists [
|
byPath = lib.mkMerge (concatLists [
|
||||||
# convert the list-style per-store entries into attrsOf entries
|
# 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
|
# add the `store` attr to everything we ingested
|
||||||
(applyToAllStores annotateWithStore)
|
(applyToAllStores config.byStore annotateWithStore)
|
||||||
]);
|
]);
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
|
@@ -3,6 +3,9 @@ let
|
|||||||
saneCfg = config.sane;
|
saneCfg = config.sane;
|
||||||
cfg = config.sane.programs;
|
cfg = config.sane.programs;
|
||||||
|
|
||||||
|
makeSandboxArgs = pkgs.callPackage ./make-sandbox-args.nix { };
|
||||||
|
makeSandboxed = pkgs.callPackage ./make-sandboxed.nix { };
|
||||||
|
|
||||||
# create a map:
|
# create a map:
|
||||||
# {
|
# {
|
||||||
# "${pkgName}" = {
|
# "${pkgName}" = {
|
||||||
@@ -38,9 +41,6 @@ let
|
|||||||
package
|
package
|
||||||
else
|
else
|
||||||
let
|
let
|
||||||
makeSandboxArgs = pkgs.callPackage ./make-sandbox-args.nix { };
|
|
||||||
makeSandboxed = pkgs.callPackage ./make-sandboxed.nix { };
|
|
||||||
|
|
||||||
vpn = if sandbox.net == "vpn" then
|
vpn = if sandbox.net == "vpn" then
|
||||||
lib.findSingle (v: v.isDefault) null null (builtins.attrValues config.sane.vpn)
|
lib.findSingle (v: v.isDefault) null null (builtins.attrValues config.sane.vpn)
|
||||||
else if sandbox.net == "vpn.wg-home" then
|
else if sandbox.net == "vpn.wg-home" then
|
||||||
|
@@ -1,20 +1,4 @@
|
|||||||
{ lib }:
|
{ lib }:
|
||||||
{
|
|
||||||
method,
|
|
||||||
allowedPaths ? [],
|
|
||||||
allowedHomePaths ? [],
|
|
||||||
allowedRunPaths ? [],
|
|
||||||
autodetectCliPaths ? false,
|
|
||||||
capabilities ? [],
|
|
||||||
dns ? null,
|
|
||||||
keepIpc ? false,
|
|
||||||
keepPids ? false,
|
|
||||||
tryKeepUsers ? false,
|
|
||||||
netDev ? null,
|
|
||||||
netGateway ? null,
|
|
||||||
whitelistPwd ? false,
|
|
||||||
extraConfig ? [],
|
|
||||||
}:
|
|
||||||
let
|
let
|
||||||
saneboxGenerators = {
|
saneboxGenerators = {
|
||||||
autodetectCliPaths = style: [ "--sanebox-autodetect" style ];
|
autodetectCliPaths = style: [ "--sanebox-autodetect" style ];
|
||||||
@@ -26,9 +10,9 @@ let
|
|||||||
method = method: [ "--sanebox-method" method ];
|
method = method: [ "--sanebox-method" method ];
|
||||||
netDev = netDev: [ "--sanebox-net-dev" netDev ];
|
netDev = netDev: [ "--sanebox-net-dev" netDev ];
|
||||||
netGateway = netGateway: [ "--sanebox-net-gateway" netGateway ];
|
netGateway = netGateway: [ "--sanebox-net-gateway" netGateway ];
|
||||||
path = p: [ "--sanebox-path" p ];
|
path.unqualified = p: [ "--sanebox-path" p ];
|
||||||
path-home = p: [ "--sanebox-home-path" p ];
|
path.home = p: [ "--sanebox-home-path" p ];
|
||||||
path-run = p: [ "--sanebox-run-path" p ];
|
path.run = p: [ "--sanebox-run-path" p ];
|
||||||
whitelistPwd = [ "--sanebox-add-pwd" ];
|
whitelistPwd = [ "--sanebox-add-pwd" ];
|
||||||
};
|
};
|
||||||
bunpenGenerators = {
|
bunpenGenerators = {
|
||||||
@@ -61,18 +45,36 @@ let
|
|||||||
else
|
else
|
||||||
[ "--bunpen-path" "/dev/net/tun" "--bunpen-net-dev" n ];
|
[ "--bunpen-path" "/dev/net/tun" "--bunpen-net-dev" n ];
|
||||||
netGateway = netGateway: [ "--bunpen-net-gateway" netGateway ];
|
netGateway = netGateway: [ "--bunpen-net-gateway" netGateway ];
|
||||||
path = p: [ "--bunpen-path" p ];
|
path.unqualified = p: [ "--bunpen-path" p ];
|
||||||
path-home = p: [ "--bunpen-home-path" p ];
|
path.home = p: [ "--bunpen-home-path" p ];
|
||||||
path-run = p: [ "--bunpen-run-path" p ];
|
path.run = p: [ "--bunpen-run-path" p ];
|
||||||
tryKeepUsers = [ "--bunpen-try-keep-users" ];
|
tryKeepUsers = [ "--bunpen-try-keep-users" ];
|
||||||
whitelistPwd = [ "--bunpen-path" "." ];
|
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
|
gen = if method == "bunpen" then
|
||||||
bunpenGenerators
|
bunpenGenerators
|
||||||
else
|
else
|
||||||
saneboxGenerators
|
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);
|
capabilityFlags = lib.flatten (builtins.map gen.capability capabilities);
|
||||||
|
|
||||||
@@ -84,9 +86,9 @@ let
|
|||||||
in
|
in
|
||||||
(gen.method method)
|
(gen.method method)
|
||||||
++ netItems
|
++ netItems
|
||||||
++ allowPaths "" allowedPaths
|
++ allowPaths "unqualified" allowedPaths
|
||||||
++ allowPaths "-home" allowedHomePaths
|
++ allowPaths "home" allowedHomePaths
|
||||||
++ allowPaths "-run" allowedRunPaths
|
++ allowPaths "run" allowedRunPaths
|
||||||
++ capabilityFlags
|
++ capabilityFlags
|
||||||
++ lib.optionals (autodetectCliPaths != null) (gen.autodetectCliPaths autodetectCliPaths)
|
++ lib.optionals (autodetectCliPaths != null) (gen.autodetectCliPaths autodetectCliPaths)
|
||||||
++ lib.optionals keepIpc gen.keepIpc
|
++ lib.optionals keepIpc gen.keepIpc
|
||||||
|
@@ -1,14 +1,15 @@
|
|||||||
# this overlay exists specifically to control the order in which other overlays are applied.
|
# 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
|
# for example, `pkgs` *must* be added before `cross`, as the latter applies overrides
|
||||||
# to the packages defined in the former.
|
# to the packages defined in the former.
|
||||||
|
|
||||||
final: prev:
|
|
||||||
let
|
let
|
||||||
pkgs = import ./pkgs.nix;
|
pkgs = import ./pkgs.nix;
|
||||||
preferences = import ./preferences.nix;
|
preferences = import ./preferences.nix;
|
||||||
cross = import ./cross.nix;
|
cross = import ./cross.nix;
|
||||||
pkgs-ccache = import ./pkgs-ccache.nix;
|
pkgs-ccache = import ./pkgs-ccache.nix;
|
||||||
pkgs-debug = import ./pkgs-debug.nix;
|
pkgs-debug = import ./pkgs-debug.nix;
|
||||||
|
in
|
||||||
|
final: prev:
|
||||||
|
let
|
||||||
|
|
||||||
isCross = prev.stdenv.hostPlatform != prev.stdenv.buildPlatform;
|
isCross = prev.stdenv.hostPlatform != prev.stdenv.buildPlatform;
|
||||||
ifCross = overlay: if isCross then overlay else (_: _: {});
|
ifCross = overlay: if isCross then overlay else (_: _: {});
|
||||||
|
Reference in New Issue
Block a user