formats: add nixConf
adds `nixConf` (to generate `nix.conf` files) as a file format to `lib.formats`, and uses it for serializing `nix.settings`. this makes it easier to 'manually' serialize `nix.settings`, which is relevant in e.g. safely handling sensitive values such as that of `nix.settings.access-tokens`. Signed-off-by: cinereal <cinereal@riseup.net>
This commit is contained in:
@@ -16,40 +16,21 @@
|
||||
|
||||
let
|
||||
inherit (lib)
|
||||
concatStringsSep
|
||||
boolToString
|
||||
escape
|
||||
filterAttrs
|
||||
floatToString
|
||||
getVersion
|
||||
hasPrefix
|
||||
isBool
|
||||
isDerivation
|
||||
isFloat
|
||||
isInt
|
||||
isList
|
||||
isString
|
||||
literalExpression
|
||||
mapAttrsToList
|
||||
mkAfter
|
||||
mkIf
|
||||
mkOption
|
||||
mkRenamedOptionModuleWith
|
||||
optionalString
|
||||
optionals
|
||||
strings
|
||||
systems
|
||||
toPretty
|
||||
types
|
||||
versionAtLeast
|
||||
;
|
||||
|
||||
cfg = config.nix;
|
||||
|
||||
nixPackage = cfg.package.out;
|
||||
|
||||
isNixAtLeast = versionAtLeast (getVersion nixPackage);
|
||||
|
||||
defaultSystemFeatures = [
|
||||
"nixos-test"
|
||||
"benchmark"
|
||||
@@ -98,74 +79,17 @@ let
|
||||
attrsOf (either confAtom (listOf confAtom));
|
||||
|
||||
nixConf =
|
||||
assert isNixAtLeast "2.2";
|
||||
let
|
||||
|
||||
mkValueString =
|
||||
v:
|
||||
if v == null then
|
||||
""
|
||||
else if isInt v then
|
||||
toString v
|
||||
else if isBool v then
|
||||
boolToString v
|
||||
else if isFloat v then
|
||||
floatToString v
|
||||
else if isList v then
|
||||
toString v
|
||||
else if isDerivation v then
|
||||
toString v
|
||||
else if builtins.isPath v then
|
||||
toString v
|
||||
else if isString v then
|
||||
v
|
||||
else if strings.isConvertibleWithToString v then
|
||||
toString v
|
||||
else
|
||||
abort "The nix conf value: ${toPretty { } v} can not be encoded";
|
||||
|
||||
mkKeyValue = k: v: "${escape [ "=" ] k} = ${mkValueString v}";
|
||||
|
||||
mkKeyValuePairs = attrs: concatStringsSep "\n" (mapAttrsToList mkKeyValue attrs);
|
||||
|
||||
isExtra = key: hasPrefix "extra-" key;
|
||||
|
||||
in
|
||||
pkgs.writeTextFile {
|
||||
name = "nix.conf";
|
||||
# workaround for https://github.com/NixOS/nix/issues/9487
|
||||
# extra-* settings must come after their non-extra counterpart
|
||||
text = ''
|
||||
# WARNING: this file is generated from the nix.* options in
|
||||
# your NixOS configuration, typically
|
||||
# /etc/nixos/configuration.nix. Do not edit it!
|
||||
${mkKeyValuePairs (filterAttrs (key: value: !(isExtra key)) cfg.settings)}
|
||||
${mkKeyValuePairs (filterAttrs (key: value: isExtra key) cfg.settings)}
|
||||
${cfg.extraOptions}
|
||||
'';
|
||||
checkPhase = lib.optionalString cfg.checkConfig (
|
||||
if pkgs.stdenv.hostPlatform != pkgs.stdenv.buildPlatform then
|
||||
''
|
||||
echo "Ignoring validation for cross-compilation"
|
||||
''
|
||||
else
|
||||
let
|
||||
showCommand = if isNixAtLeast "2.20pre" then "config show" else "show-config";
|
||||
in
|
||||
''
|
||||
echo "Validating generated nix.conf"
|
||||
ln -s $out ./nix.conf
|
||||
set -e
|
||||
set +o pipefail
|
||||
NIX_CONF_DIR=$PWD \
|
||||
${cfg.package}/bin/nix ${showCommand} ${optionalString (isNixAtLeast "2.3pre") "--no-net"} \
|
||||
${optionalString (isNixAtLeast "2.4pre") "--option experimental-features nix-command"} \
|
||||
|& sed -e 's/^warning:/error:/' \
|
||||
| (! grep '${if cfg.checkAllErrors then "^error:" else "^error: unknown setting"}')
|
||||
set -o pipefail
|
||||
''
|
||||
);
|
||||
};
|
||||
(pkgs.formats.nixConf {
|
||||
inherit (cfg)
|
||||
package
|
||||
checkAllErrors
|
||||
checkConfig
|
||||
extraOptions
|
||||
;
|
||||
inherit (nixPackage) version;
|
||||
}).generate
|
||||
"nix.conf"
|
||||
cfg.settings;
|
||||
|
||||
in
|
||||
{
|
||||
|
||||
+104
-1
@@ -1,11 +1,16 @@
|
||||
{ lib, pkgs }:
|
||||
let
|
||||
inherit (lib)
|
||||
boolToString
|
||||
concatStringsSep
|
||||
escape
|
||||
filterAttrs
|
||||
flatten
|
||||
hasPrefix
|
||||
id
|
||||
isAttrs
|
||||
isBool
|
||||
isDerivation
|
||||
isFloat
|
||||
isInt
|
||||
isList
|
||||
@@ -16,8 +21,11 @@ let
|
||||
optionalAttrs
|
||||
optionalString
|
||||
pipe
|
||||
types
|
||||
singleton
|
||||
strings
|
||||
toPretty
|
||||
types
|
||||
versionAtLeast
|
||||
warn
|
||||
;
|
||||
|
||||
@@ -863,6 +871,101 @@ optionalAttrs allowAliases aliases
|
||||
lib.mkRaw = lib.mkLuaInline;
|
||||
};
|
||||
|
||||
nixConf =
|
||||
{
|
||||
package,
|
||||
version,
|
||||
extraOptions ? "",
|
||||
checkAllErrors ? true,
|
||||
checkConfig ? true,
|
||||
}:
|
||||
let
|
||||
isNixAtLeast = versionAtLeast version;
|
||||
in
|
||||
assert isNixAtLeast "2.2";
|
||||
{
|
||||
type =
|
||||
let
|
||||
atomType = nullOr (oneOf [
|
||||
bool
|
||||
int
|
||||
float
|
||||
str
|
||||
path
|
||||
package
|
||||
]);
|
||||
in
|
||||
attrsOf atomType;
|
||||
generate =
|
||||
name: value:
|
||||
let
|
||||
|
||||
# note that list type has been omitted here as the separator varies, see `nix.settings.*`
|
||||
mkValueString =
|
||||
v:
|
||||
if v == null then
|
||||
""
|
||||
else if isInt v then
|
||||
toString v
|
||||
else if isBool v then
|
||||
boolToString v
|
||||
else if isFloat v then
|
||||
strings.floatToString v
|
||||
else if isDerivation v then
|
||||
toString v
|
||||
else if builtins.isPath v then
|
||||
toString v
|
||||
else if isString v then
|
||||
v
|
||||
else if strings.isConvertibleWithToString v then
|
||||
toString v
|
||||
else
|
||||
abort "The nix conf value: ${toPretty { } v} can not be encoded";
|
||||
|
||||
mkKeyValue = k: v: "${escape [ "=" ] k} = ${mkValueString v}";
|
||||
|
||||
mkKeyValuePairs = attrs: concatStringsSep "\n" (mapAttrsToList mkKeyValue attrs);
|
||||
|
||||
isExtra = key: hasPrefix "extra-" key;
|
||||
|
||||
in
|
||||
pkgs.writeTextFile {
|
||||
inherit name;
|
||||
# workaround for https://github.com/NixOS/nix/issues/9487
|
||||
# extra-* settings must come after their non-extra counterpart
|
||||
text = ''
|
||||
# WARNING: this file is generated from the nix.* options in
|
||||
# your NixOS configuration, typically
|
||||
# /etc/nixos/configuration.nix. Do not edit it!
|
||||
${mkKeyValuePairs (filterAttrs (key: _: !(isExtra key)) value)}
|
||||
${mkKeyValuePairs (filterAttrs (key: _: isExtra key) value)}
|
||||
${extraOptions}
|
||||
'';
|
||||
checkPhase = lib.optionalString checkConfig (
|
||||
if pkgs.stdenv.hostPlatform != pkgs.stdenv.buildPlatform then
|
||||
''
|
||||
echo "Ignoring validation for cross-compilation"
|
||||
''
|
||||
else
|
||||
let
|
||||
showCommand = if isNixAtLeast "2.20pre" then "config show" else "show-config";
|
||||
in
|
||||
''
|
||||
echo "Validating generated nix.conf"
|
||||
ln -s $out ./nix.conf
|
||||
set -e
|
||||
set +o pipefail
|
||||
NIX_CONF_DIR=$PWD \
|
||||
${package}/bin/nix ${showCommand} ${optionalString (isNixAtLeast "2.3pre") "--no-net"} \
|
||||
${optionalString (isNixAtLeast "2.4pre") "--option experimental-features nix-command"} \
|
||||
|& sed -e 's/^warning:/error:/' \
|
||||
| (! grep '${if checkAllErrors then "^error:" else "^error: unknown setting"}')
|
||||
set -o pipefail
|
||||
''
|
||||
);
|
||||
};
|
||||
};
|
||||
|
||||
# Outputs a succession of Python variable assignments
|
||||
# Useful for many Django-based services
|
||||
pythonVars =
|
||||
|
||||
@@ -850,6 +850,31 @@ runBuildTests {
|
||||
'';
|
||||
};
|
||||
|
||||
nixConfAtoms = shouldPass {
|
||||
format = formats.nixConf {
|
||||
package = pkgs.nix;
|
||||
version = pkgs.nix.version;
|
||||
extraOptions = ''ignore-try = false'';
|
||||
};
|
||||
input = {
|
||||
auto-optimise-store = true;
|
||||
cores = 0;
|
||||
store = "auto";
|
||||
};
|
||||
# note that null type is hard to test here,
|
||||
# as it involves a trailing space our formatter will remove here
|
||||
expected = ''
|
||||
# WARNING: this file is generated from the nix.* options in
|
||||
# your NixOS configuration, typically
|
||||
# /etc/nixos/configuration.nix. Do not edit it!
|
||||
auto-optimise-store = true
|
||||
cores = 0
|
||||
store = auto
|
||||
|
||||
ignore-try = false
|
||||
'';
|
||||
};
|
||||
|
||||
phpAtoms = shouldPass rec {
|
||||
format = formats.php { finalVariable = "config"; };
|
||||
input = {
|
||||
|
||||
Reference in New Issue
Block a user