mirror of
https://github.com/nix-community/home-manager.git
synced 2025-11-08 19:46:05 +01:00
syncthing: handle per-folder encryptionPasswordFile
This change allows configuring per-folder encryption passwords declaratively (and without leaking them into the store), modeled after the upstream Nixpkgs changes from https://github.com/NixOS/nixpkgs/pull/383442. Closes https://github.com/nix-community/home-manager/issues/7318. Co-authored-by: Jeremy Fleischman <jeremyfleischman@gmail.com> Co-authored-by: Aurimas Blažulionis <0x60@pm.me>
This commit is contained in:
parent
ef3762499b
commit
cb68b5cd6a
1 changed files with 112 additions and 8 deletions
|
|
@ -51,11 +51,11 @@ let
|
||||||
devices = map (
|
devices = map (
|
||||||
device:
|
device:
|
||||||
if builtins.isString device then
|
if builtins.isString device then
|
||||||
{
|
{ deviceId = cfg.settings.devices.${device}.id; }
|
||||||
deviceId = cfg.settings.devices.${device}.id;
|
else if builtins.isAttrs device then
|
||||||
}
|
{ deviceId = cfg.settings.devices.${device.name}.id; } // device
|
||||||
else
|
else
|
||||||
device
|
throw "Invalid type for devices in folder '${folder.label}'; expected list or attrset."
|
||||||
) folder.devices;
|
) folder.devices;
|
||||||
}
|
}
|
||||||
) (lib.filterAttrs (_: folder: folder.enable) cfg.settings.folders);
|
) (lib.filterAttrs (_: folder: folder.enable) cfg.settings.folders);
|
||||||
|
|
@ -152,9 +152,79 @@ let
|
||||||
# don't exist in the array given. That's why we use here `POST`, and
|
# don't exist in the array given. That's why we use here `POST`, and
|
||||||
# only if s.override == true then we DELETE the relevant folders
|
# only if s.override == true then we DELETE the relevant folders
|
||||||
# afterwards.
|
# afterwards.
|
||||||
(map (new_cfg: ''
|
(map (
|
||||||
curl -d ${lib.escapeShellArg (builtins.toJSON new_cfg)} -X POST ${s.baseAddress}
|
new_cfg:
|
||||||
''))
|
let
|
||||||
|
jsonPreSecretsFile = pkgs.writeTextFile {
|
||||||
|
name = "${conf_type}-${new_cfg.id}-conf-pre-secrets.json";
|
||||||
|
text = builtins.toJSON new_cfg;
|
||||||
|
};
|
||||||
|
injectSecretsJqCmd =
|
||||||
|
{
|
||||||
|
# There are no secrets in `devs`, so no massaging needed.
|
||||||
|
"devs" = "${jq} .";
|
||||||
|
"dirs" =
|
||||||
|
let
|
||||||
|
folder = new_cfg;
|
||||||
|
devicesWithSecrets = lib.pipe folder.devices [
|
||||||
|
(lib.filter (device: (builtins.isAttrs device) && device ? encryptionPasswordFile))
|
||||||
|
(map (device: {
|
||||||
|
deviceId = device.deviceId;
|
||||||
|
variableName = "secret_${builtins.hashString "sha256" device.encryptionPasswordFile}";
|
||||||
|
secretPath = device.encryptionPasswordFile;
|
||||||
|
}))
|
||||||
|
];
|
||||||
|
# At this point, `jsonPreSecretsFile` looks something like this:
|
||||||
|
#
|
||||||
|
# {
|
||||||
|
# ...,
|
||||||
|
# "devices": [
|
||||||
|
# {
|
||||||
|
# "deviceId": "id1",
|
||||||
|
# "encryptionPasswordFile": "/etc/bar-encryption-password",
|
||||||
|
# "name": "..."
|
||||||
|
# }
|
||||||
|
# ],
|
||||||
|
# }
|
||||||
|
#
|
||||||
|
# We now generate a `jq` command that can replace those
|
||||||
|
# `encryptionPasswordFile`s with `encryptionPassword`.
|
||||||
|
# The `jq` command ends up looking like this:
|
||||||
|
#
|
||||||
|
# jq --rawfile secret_DEADBEEF /etc/bar-encryption-password '
|
||||||
|
# .devices[] |= (
|
||||||
|
# if .deviceId == "id1" then
|
||||||
|
# del(.encryptionPasswordFile) |
|
||||||
|
# .encryptionPassword = $secret_DEADBEEF
|
||||||
|
# else
|
||||||
|
# .
|
||||||
|
# end
|
||||||
|
# )
|
||||||
|
# '
|
||||||
|
jqUpdates = map (device: ''
|
||||||
|
.devices[] |= (
|
||||||
|
if .deviceId == "${device.deviceId}" then
|
||||||
|
del(.encryptionPasswordFile) |
|
||||||
|
.encryptionPassword = ''$${device.variableName}
|
||||||
|
else
|
||||||
|
.
|
||||||
|
end
|
||||||
|
)
|
||||||
|
'') devicesWithSecrets;
|
||||||
|
jqRawFiles = map (
|
||||||
|
device: "--rawfile ${device.variableName} ${lib.escapeShellArg device.secretPath}"
|
||||||
|
) devicesWithSecrets;
|
||||||
|
in
|
||||||
|
"${jq} ${lib.concatStringsSep " " jqRawFiles} ${
|
||||||
|
lib.escapeShellArg (lib.concatStringsSep "|" ([ "." ] ++ jqUpdates))
|
||||||
|
}";
|
||||||
|
}
|
||||||
|
.${conf_type};
|
||||||
|
in
|
||||||
|
''
|
||||||
|
${injectSecretsJqCmd} ${jsonPreSecretsFile} | curl --json @- -X POST ${s.baseAddress}
|
||||||
|
''
|
||||||
|
))
|
||||||
(lib.concatStringsSep "\n")
|
(lib.concatStringsSep "\n")
|
||||||
]
|
]
|
||||||
/*
|
/*
|
||||||
|
|
@ -478,11 +548,45 @@ in
|
||||||
};
|
};
|
||||||
|
|
||||||
devices = mkOption {
|
devices = mkOption {
|
||||||
type = with types; listOf str;
|
type = types.listOf (
|
||||||
|
types.oneOf [
|
||||||
|
types.str
|
||||||
|
(types.submodule {
|
||||||
|
freeformType = settingsFormat.type;
|
||||||
|
options = {
|
||||||
|
name = mkOption {
|
||||||
|
type = types.str;
|
||||||
|
default = null;
|
||||||
|
description = ''
|
||||||
|
The name of a device defined in the
|
||||||
|
[devices](#opt-services.syncthing.settings.devices)
|
||||||
|
option.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
encryptionPasswordFile = mkOption {
|
||||||
|
type = types.nullOr (
|
||||||
|
types.pathWith {
|
||||||
|
inStore = false;
|
||||||
|
absolute = true;
|
||||||
|
}
|
||||||
|
);
|
||||||
|
default = null;
|
||||||
|
description = ''
|
||||||
|
Path to encryption password. If set, the file will be read during
|
||||||
|
service activation, without being embedded in derivation.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
};
|
||||||
|
})
|
||||||
|
]
|
||||||
|
);
|
||||||
default = [ ];
|
default = [ ];
|
||||||
description = ''
|
description = ''
|
||||||
The devices this folder should be shared with. Each device must
|
The devices this folder should be shared with. Each device must
|
||||||
be defined in the [devices](#opt-services.syncthing.settings.devices) option.
|
be defined in the [devices](#opt-services.syncthing.settings.devices) option.
|
||||||
|
|
||||||
|
A list of either strings or attribute sets, where values
|
||||||
|
are device names or device configurations.
|
||||||
'';
|
'';
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue