Compare commits
No commits in common. "2d8700956173cf9f514e95ffdd2b54cf15850e64" and "c2a45ec1bb2b74ab9e7e1faa94ba1ad469857c30" have entirely different histories.
2d87009561
...
c2a45ec1bb
|
@ -3,9 +3,8 @@
|
||||||
with lib;
|
with lib;
|
||||||
|
|
||||||
let
|
let
|
||||||
cfg = config.services.syncthings;
|
cfg = config.services.syncthing;
|
||||||
enabledInstances = filterAttrs (n: v: v.enable) cfg.instances;
|
opt = options.services.syncthing;
|
||||||
opt = options.services.syncthings;
|
|
||||||
defaultUser = "syncthing";
|
defaultUser = "syncthing";
|
||||||
defaultGroup = defaultUser;
|
defaultGroup = defaultUser;
|
||||||
settingsFormat = pkgs.formats.json { };
|
settingsFormat = pkgs.formats.json { };
|
||||||
|
@ -146,479 +145,489 @@ let
|
||||||
in {
|
in {
|
||||||
###### interface
|
###### interface
|
||||||
options = {
|
options = {
|
||||||
services.syncthings = {
|
services.syncthing = {
|
||||||
instances = mkOption {
|
|
||||||
description = mdDoc "Syncthing instance definitions";
|
enable = mkEnableOption
|
||||||
default = {};
|
(lib.mdDoc "Syncthing, a self-hosted open-source alternative to Dropbox and Bittorrent Sync");
|
||||||
type = types.attrsOf (types.submodule {
|
|
||||||
|
cert = mkOption {
|
||||||
|
type = types.nullOr types.str;
|
||||||
|
default = null;
|
||||||
|
description = mdDoc ''
|
||||||
|
Path to the `cert.pem` file, which will be copied into Syncthing's
|
||||||
|
[configDir](#opt-services.syncthing.configDir).
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
key = mkOption {
|
||||||
|
type = types.nullOr types.str;
|
||||||
|
default = null;
|
||||||
|
description = mdDoc ''
|
||||||
|
Path to the `key.pem` file, which will be copied into Syncthing's
|
||||||
|
[configDir](#opt-services.syncthing.configDir).
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
overrideDevices = mkOption {
|
||||||
|
type = types.bool;
|
||||||
|
default = true;
|
||||||
|
description = mdDoc ''
|
||||||
|
Whether to delete the devices which are not configured via the
|
||||||
|
[devices](#opt-services.syncthing.settings.devices) option.
|
||||||
|
If set to `false`, devices added via the web
|
||||||
|
interface will persist and will have to be deleted manually.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
overrideFolders = mkOption {
|
||||||
|
type = types.bool;
|
||||||
|
default = true;
|
||||||
|
description = mdDoc ''
|
||||||
|
Whether to delete the folders which are not configured via the
|
||||||
|
[folders](#opt-services.syncthing.settings.folders) option.
|
||||||
|
If set to `false`, folders added via the web
|
||||||
|
interface will persist and will have to be deleted manually.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
settings = mkOption {
|
||||||
|
type = types.submodule {
|
||||||
|
freeformType = settingsFormat.type;
|
||||||
options = {
|
options = {
|
||||||
|
# global options
|
||||||
enable = mkEnableOption
|
options = mkOption {
|
||||||
(lib.mdDoc "Syncthing, a self-hosted open-source alternative to Dropbox and Bittorrent Sync");
|
default = {};
|
||||||
|
|
||||||
cert = mkOption {
|
|
||||||
type = types.nullOr types.str;
|
|
||||||
default = null;
|
|
||||||
description = mdDoc ''
|
description = mdDoc ''
|
||||||
Path to the `cert.pem` file, which will be copied into Syncthing's
|
The options element contains all other global configuration options
|
||||||
[configDir](#opt-services.syncthing.configDir).
|
|
||||||
'';
|
'';
|
||||||
};
|
type = types.submodule ({ name, ... }: {
|
||||||
|
|
||||||
key = mkOption {
|
|
||||||
type = types.nullOr types.str;
|
|
||||||
default = null;
|
|
||||||
description = mdDoc ''
|
|
||||||
Path to the `key.pem` file, which will be copied into Syncthing's
|
|
||||||
[configDir](#opt-services.syncthing.configDir).
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
|
|
||||||
overrideDevices = mkOption {
|
|
||||||
type = types.bool;
|
|
||||||
default = true;
|
|
||||||
description = mdDoc ''
|
|
||||||
Whether to delete the devices which are not configured via the
|
|
||||||
[devices](#opt-services.syncthing.settings.devices) option.
|
|
||||||
If set to `false`, devices added via the web
|
|
||||||
interface will persist and will have to be deleted manually.
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
|
|
||||||
overrideFolders = mkOption {
|
|
||||||
type = types.bool;
|
|
||||||
default = true;
|
|
||||||
description = mdDoc ''
|
|
||||||
Whether to delete the folders which are not configured via the
|
|
||||||
[folders](#opt-services.syncthing.settings.folders) option.
|
|
||||||
If set to `false`, folders added via the web
|
|
||||||
interface will persist and will have to be deleted manually.
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
|
|
||||||
settings = mkOption {
|
|
||||||
type = types.submodule {
|
|
||||||
freeformType = settingsFormat.type;
|
freeformType = settingsFormat.type;
|
||||||
options = {
|
options = {
|
||||||
# global options
|
localAnnounceEnabled = mkOption {
|
||||||
options = mkOption {
|
type = types.nullOr types.bool;
|
||||||
default = {};
|
default = null;
|
||||||
description = mdDoc ''
|
description = lib.mdDoc ''
|
||||||
The options element contains all other global configuration options
|
Whether to send announcements to the local LAN, also use such announcements to find other devices.
|
||||||
'';
|
'';
|
||||||
type = types.submodule ({ name, ... }: {
|
};
|
||||||
|
|
||||||
|
localAnnouncePort = mkOption {
|
||||||
|
type = types.nullOr types.int;
|
||||||
|
default = null;
|
||||||
|
description = lib.mdDoc ''
|
||||||
|
The port on which to listen and send IPv4 broadcast announcements to.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
relaysEnabled = mkOption {
|
||||||
|
type = types.nullOr types.bool;
|
||||||
|
default = null;
|
||||||
|
description = lib.mdDoc ''
|
||||||
|
When true, relays will be connected to and potentially used for device to device connections.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
urAccepted = mkOption {
|
||||||
|
type = types.nullOr types.int;
|
||||||
|
default = null;
|
||||||
|
description = lib.mdDoc ''
|
||||||
|
Whether the user has accepted to submit anonymous usage data.
|
||||||
|
The default, 0, mean the user has not made a choice, and Syncthing will ask at some point in the future.
|
||||||
|
"-1" means no, a number above zero means that that version of usage reporting has been accepted.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
limitBandwidthInLan = mkOption {
|
||||||
|
type = types.nullOr types.bool;
|
||||||
|
default = null;
|
||||||
|
description = lib.mdDoc ''
|
||||||
|
Whether to apply bandwidth limits to devices in the same broadcast domain as the local device.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
maxFolderConcurrency = mkOption {
|
||||||
|
type = types.nullOr types.int;
|
||||||
|
default = null;
|
||||||
|
description = lib.mdDoc ''
|
||||||
|
This option controls how many folders may concurrently be in I/O-intensive operations such as syncing or scanning.
|
||||||
|
The mechanism is described in detail in a [separate chapter](https://docs.syncthing.net/advanced/option-max-concurrency.html).
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
};
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
# device settings
|
||||||
|
devices = mkOption {
|
||||||
|
default = {};
|
||||||
|
description = mdDoc ''
|
||||||
|
Peers/devices which Syncthing should communicate with.
|
||||||
|
|
||||||
|
Note that you can still add devices manually, but those changes
|
||||||
|
will be reverted on restart if [overrideDevices](#opt-services.syncthing.overrideDevices)
|
||||||
|
is enabled.
|
||||||
|
'';
|
||||||
|
example = {
|
||||||
|
bigbox = {
|
||||||
|
id = "7CFNTQM-IMTJBHJ-3UWRDIU-ZGQJFR6-VCXZ3NB-XUH3KZO-N52ITXR-LAIYUAU";
|
||||||
|
addresses = [ "tcp://192.168.0.10:51820" ];
|
||||||
|
};
|
||||||
|
};
|
||||||
|
type = types.attrsOf (types.submodule ({ name, ... }: {
|
||||||
|
freeformType = settingsFormat.type;
|
||||||
|
options = {
|
||||||
|
|
||||||
|
name = mkOption {
|
||||||
|
type = types.str;
|
||||||
|
default = name;
|
||||||
|
description = lib.mdDoc ''
|
||||||
|
The name of the device.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
id = mkOption {
|
||||||
|
type = types.str;
|
||||||
|
description = mdDoc ''
|
||||||
|
The device ID. See <https://docs.syncthing.net/dev/device-ids.html>.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
autoAcceptFolders = mkOption {
|
||||||
|
type = types.bool;
|
||||||
|
default = false;
|
||||||
|
description = mdDoc ''
|
||||||
|
Automatically create or share folders that this device advertises at the default path.
|
||||||
|
See <https://docs.syncthing.net/users/config.html?highlight=autoaccept#config-file-format>.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
};
|
||||||
|
}));
|
||||||
|
};
|
||||||
|
|
||||||
|
# folder settings
|
||||||
|
folders = mkOption {
|
||||||
|
default = {};
|
||||||
|
description = mdDoc ''
|
||||||
|
Folders which should be shared by Syncthing.
|
||||||
|
|
||||||
|
Note that you can still add folders manually, but those changes
|
||||||
|
will be reverted on restart if [overrideFolders](#opt-services.syncthing.overrideFolders)
|
||||||
|
is enabled.
|
||||||
|
'';
|
||||||
|
example = literalExpression ''
|
||||||
|
{
|
||||||
|
"/home/user/sync" = {
|
||||||
|
id = "syncme";
|
||||||
|
devices = [ "bigbox" ];
|
||||||
|
};
|
||||||
|
}
|
||||||
|
'';
|
||||||
|
type = types.attrsOf (types.submodule ({ name, ... }: {
|
||||||
|
freeformType = settingsFormat.type;
|
||||||
|
options = {
|
||||||
|
|
||||||
|
enable = mkOption {
|
||||||
|
type = types.bool;
|
||||||
|
default = true;
|
||||||
|
description = lib.mdDoc ''
|
||||||
|
Whether to share this folder.
|
||||||
|
This option is useful when you want to define all folders
|
||||||
|
in one place, but not every machine should share all folders.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
path = mkOption {
|
||||||
|
# TODO for release 23.05: allow relative paths again and set
|
||||||
|
# working directory to cfg.dataDir
|
||||||
|
type = types.str // {
|
||||||
|
check = x: types.str.check x && (substring 0 1 x == "/" || substring 0 2 x == "~/");
|
||||||
|
description = types.str.description + " starting with / or ~/";
|
||||||
|
};
|
||||||
|
default = name;
|
||||||
|
description = lib.mdDoc ''
|
||||||
|
The path to the folder which should be shared.
|
||||||
|
Only absolute paths (starting with `/`) and paths relative to
|
||||||
|
the [user](#opt-services.syncthing.user)'s home directory
|
||||||
|
(starting with `~/`) are allowed.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
id = mkOption {
|
||||||
|
type = types.str;
|
||||||
|
default = name;
|
||||||
|
description = lib.mdDoc ''
|
||||||
|
The ID of the folder. Must be the same on all devices.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
label = mkOption {
|
||||||
|
type = types.str;
|
||||||
|
default = name;
|
||||||
|
description = lib.mdDoc ''
|
||||||
|
The label of the folder.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
devices = mkOption {
|
||||||
|
type = types.listOf types.str;
|
||||||
|
default = [];
|
||||||
|
description = mdDoc ''
|
||||||
|
The devices this folder should be shared with. Each device must
|
||||||
|
be defined in the [devices](#opt-services.syncthing.settings.devices) option.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
versioning = mkOption {
|
||||||
|
default = null;
|
||||||
|
description = mdDoc ''
|
||||||
|
How to keep changed/deleted files with Syncthing.
|
||||||
|
There are 4 different types of versioning with different parameters.
|
||||||
|
See <https://docs.syncthing.net/users/versioning.html>.
|
||||||
|
'';
|
||||||
|
example = literalExpression ''
|
||||||
|
[
|
||||||
|
{
|
||||||
|
versioning = {
|
||||||
|
type = "simple";
|
||||||
|
params.keep = "10";
|
||||||
|
};
|
||||||
|
}
|
||||||
|
{
|
||||||
|
versioning = {
|
||||||
|
type = "trashcan";
|
||||||
|
params.cleanoutDays = "1000";
|
||||||
|
};
|
||||||
|
}
|
||||||
|
{
|
||||||
|
versioning = {
|
||||||
|
type = "staggered";
|
||||||
|
fsPath = "/syncthing/backup";
|
||||||
|
params = {
|
||||||
|
cleanInterval = "3600";
|
||||||
|
maxAge = "31536000";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
||||||
|
{
|
||||||
|
versioning = {
|
||||||
|
type = "external";
|
||||||
|
params.versionsPath = pkgs.writers.writeBash "backup" '''
|
||||||
|
folderpath="$1"
|
||||||
|
filepath="$2"
|
||||||
|
rm -rf "$folderpath/$filepath"
|
||||||
|
''';
|
||||||
|
};
|
||||||
|
}
|
||||||
|
]
|
||||||
|
'';
|
||||||
|
type = with types; nullOr (submodule {
|
||||||
freeformType = settingsFormat.type;
|
freeformType = settingsFormat.type;
|
||||||
options = {
|
options = {
|
||||||
localAnnounceEnabled = mkOption {
|
type = mkOption {
|
||||||
type = types.nullOr types.bool;
|
type = enum [ "external" "simple" "staggered" "trashcan" ];
|
||||||
default = null;
|
description = mdDoc ''
|
||||||
description = lib.mdDoc ''
|
The type of versioning.
|
||||||
Whether to send announcements to the local LAN, also use such announcements to find other devices.
|
See <https://docs.syncthing.net/users/versioning.html>.
|
||||||
'';
|
|
||||||
};
|
|
||||||
|
|
||||||
localAnnouncePort = mkOption {
|
|
||||||
type = types.nullOr types.int;
|
|
||||||
default = null;
|
|
||||||
description = lib.mdDoc ''
|
|
||||||
The port on which to listen and send IPv4 broadcast announcements to.
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
|
|
||||||
relaysEnabled = mkOption {
|
|
||||||
type = types.nullOr types.bool;
|
|
||||||
default = null;
|
|
||||||
description = lib.mdDoc ''
|
|
||||||
When true, relays will be connected to and potentially used for device to device connections.
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
|
|
||||||
urAccepted = mkOption {
|
|
||||||
type = types.nullOr types.int;
|
|
||||||
default = null;
|
|
||||||
description = lib.mdDoc ''
|
|
||||||
Whether the user has accepted to submit anonymous usage data.
|
|
||||||
The default, 0, mean the user has not made a choice, and Syncthing will ask at some point in the future.
|
|
||||||
"-1" means no, a number above zero means that that version of usage reporting has been accepted.
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
|
|
||||||
limitBandwidthInLan = mkOption {
|
|
||||||
type = types.nullOr types.bool;
|
|
||||||
default = null;
|
|
||||||
description = lib.mdDoc ''
|
|
||||||
Whether to apply bandwidth limits to devices in the same broadcast domain as the local device.
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
|
|
||||||
maxFolderConcurrency = mkOption {
|
|
||||||
type = types.nullOr types.int;
|
|
||||||
default = null;
|
|
||||||
description = lib.mdDoc ''
|
|
||||||
This option controls how many folders may concurrently be in I/O-intensive operations such as syncing or scanning.
|
|
||||||
The mechanism is described in detail in a [separate chapter](https://docs.syncthing.net/advanced/option-max-concurrency.html).
|
|
||||||
'';
|
'';
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
# device settings
|
copyOwnershipFromParent = mkOption {
|
||||||
devices = mkOption {
|
type = types.bool;
|
||||||
default = {};
|
default = false;
|
||||||
description = mdDoc ''
|
description = mdDoc ''
|
||||||
Peers/devices which Syncthing should communicate with.
|
On Unix systems, tries to copy file/folder ownership from the parent directory (the directory it’s located in).
|
||||||
|
Requires running Syncthing as a privileged user, or granting it additional capabilities (e.g. CAP_CHOWN on Linux).
|
||||||
Note that you can still add devices manually, but those changes
|
|
||||||
will be reverted on restart if [overrideDevices](#opt-services.syncthing.overrideDevices)
|
|
||||||
is enabled.
|
|
||||||
'';
|
'';
|
||||||
example = {
|
|
||||||
bigbox = {
|
|
||||||
id = "7CFNTQM-IMTJBHJ-3UWRDIU-ZGQJFR6-VCXZ3NB-XUH3KZO-N52ITXR-LAIYUAU";
|
|
||||||
addresses = [ "tcp://192.168.0.10:51820" ];
|
|
||||||
};
|
|
||||||
};
|
|
||||||
type = types.attrsOf (types.submodule ({ name, ... }: {
|
|
||||||
freeformType = settingsFormat.type;
|
|
||||||
options = {
|
|
||||||
|
|
||||||
name = mkOption {
|
|
||||||
type = types.str;
|
|
||||||
default = name;
|
|
||||||
description = lib.mdDoc ''
|
|
||||||
The name of the device.
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
|
|
||||||
id = mkOption {
|
|
||||||
type = types.str;
|
|
||||||
description = mdDoc ''
|
|
||||||
The device ID. See <https://docs.syncthing.net/dev/device-ids.html>.
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
|
|
||||||
autoAcceptFolders = mkOption {
|
|
||||||
type = types.bool;
|
|
||||||
default = false;
|
|
||||||
description = mdDoc ''
|
|
||||||
Automatically create or share folders that this device advertises at the default path.
|
|
||||||
See <https://docs.syncthing.net/users/config.html?highlight=autoaccept#config-file-format>.
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
|
|
||||||
};
|
|
||||||
}));
|
|
||||||
};
|
};
|
||||||
|
|
||||||
# folder settings
|
|
||||||
folders = mkOption {
|
|
||||||
default = {};
|
|
||||||
description = mdDoc ''
|
|
||||||
Folders which should be shared by Syncthing.
|
|
||||||
|
|
||||||
Note that you can still add folders manually, but those changes
|
|
||||||
will be reverted on restart if [overrideFolders](#opt-services.syncthing.overrideFolders)
|
|
||||||
is enabled.
|
|
||||||
'';
|
|
||||||
example = literalExpression ''
|
|
||||||
{
|
|
||||||
"/home/user/sync" = {
|
|
||||||
id = "syncme";
|
|
||||||
devices = [ "bigbox" ];
|
|
||||||
};
|
|
||||||
}
|
|
||||||
'';
|
|
||||||
type = types.attrsOf (types.submodule ({ name, ... }: {
|
|
||||||
freeformType = settingsFormat.type;
|
|
||||||
options = {
|
|
||||||
|
|
||||||
enable = mkOption {
|
|
||||||
type = types.bool;
|
|
||||||
default = true;
|
|
||||||
description = lib.mdDoc ''
|
|
||||||
Whether to share this folder.
|
|
||||||
This option is useful when you want to define all folders
|
|
||||||
in one place, but not every machine should share all folders.
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
|
|
||||||
path = mkOption {
|
|
||||||
# TODO for release 23.05: allow relative paths again and set
|
|
||||||
# working directory to cfg.dataDir
|
|
||||||
type = types.str // {
|
|
||||||
check = x: types.str.check x && (substring 0 1 x == "/" || substring 0 2 x == "~/");
|
|
||||||
description = types.str.description + " starting with / or ~/";
|
|
||||||
};
|
|
||||||
default = name;
|
|
||||||
description = lib.mdDoc ''
|
|
||||||
The path to the folder which should be shared.
|
|
||||||
Only absolute paths (starting with `/`) and paths relative to
|
|
||||||
the [user](#opt-services.syncthing.user)'s home directory
|
|
||||||
(starting with `~/`) are allowed.
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
|
|
||||||
id = mkOption {
|
|
||||||
type = types.str;
|
|
||||||
default = name;
|
|
||||||
description = lib.mdDoc ''
|
|
||||||
The ID of the folder. Must be the same on all devices.
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
|
|
||||||
label = mkOption {
|
|
||||||
type = types.str;
|
|
||||||
default = name;
|
|
||||||
description = lib.mdDoc ''
|
|
||||||
The label of the folder.
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
|
|
||||||
devices = mkOption {
|
|
||||||
type = types.listOf types.str;
|
|
||||||
default = [];
|
|
||||||
description = mdDoc ''
|
|
||||||
The devices this folder should be shared with. Each device must
|
|
||||||
be defined in the [devices](#opt-services.syncthing.settings.devices) option.
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
|
|
||||||
versioning = mkOption {
|
|
||||||
default = null;
|
|
||||||
description = mdDoc ''
|
|
||||||
How to keep changed/deleted files with Syncthing.
|
|
||||||
There are 4 different types of versioning with different parameters.
|
|
||||||
See <https://docs.syncthing.net/users/versioning.html>.
|
|
||||||
'';
|
|
||||||
example = literalExpression ''
|
|
||||||
[
|
|
||||||
{
|
|
||||||
versioning = {
|
|
||||||
type = "simple";
|
|
||||||
params.keep = "10";
|
|
||||||
};
|
|
||||||
}
|
|
||||||
{
|
|
||||||
versioning = {
|
|
||||||
type = "trashcan";
|
|
||||||
params.cleanoutDays = "1000";
|
|
||||||
};
|
|
||||||
}
|
|
||||||
{
|
|
||||||
versioning = {
|
|
||||||
type = "staggered";
|
|
||||||
fsPath = "/syncthing/backup";
|
|
||||||
params = {
|
|
||||||
cleanInterval = "3600";
|
|
||||||
maxAge = "31536000";
|
|
||||||
};
|
|
||||||
};
|
|
||||||
}
|
|
||||||
{
|
|
||||||
versioning = {
|
|
||||||
type = "external";
|
|
||||||
params.versionsPath = pkgs.writers.writeBash "backup" '''
|
|
||||||
folderpath="$1"
|
|
||||||
filepath="$2"
|
|
||||||
rm -rf "$folderpath/$filepath"
|
|
||||||
''';
|
|
||||||
};
|
|
||||||
}
|
|
||||||
]
|
|
||||||
'';
|
|
||||||
type = with types; nullOr (submodule {
|
|
||||||
freeformType = settingsFormat.type;
|
|
||||||
options = {
|
|
||||||
type = mkOption {
|
|
||||||
type = enum [ "external" "simple" "staggered" "trashcan" ];
|
|
||||||
description = mdDoc ''
|
|
||||||
The type of versioning.
|
|
||||||
See <https://docs.syncthing.net/users/versioning.html>.
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
};
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
copyOwnershipFromParent = mkOption {
|
|
||||||
type = types.bool;
|
|
||||||
default = false;
|
|
||||||
description = mdDoc ''
|
|
||||||
On Unix systems, tries to copy file/folder ownership from the parent directory (the directory it’s located in).
|
|
||||||
Requires running Syncthing as a privileged user, or granting it additional capabilities (e.g. CAP_CHOWN on Linux).
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
};
|
|
||||||
}));
|
|
||||||
};
|
|
||||||
|
|
||||||
};
|
};
|
||||||
};
|
}));
|
||||||
default = {};
|
|
||||||
description = mdDoc ''
|
|
||||||
Extra configuration options for Syncthing.
|
|
||||||
See <https://docs.syncthing.net/users/config.html>.
|
|
||||||
Note that this attribute set does not exactly match the documented
|
|
||||||
xml format. Instead, this is the format of the json rest api. There
|
|
||||||
are slight differences. For example, this xml:
|
|
||||||
```xml
|
|
||||||
<options>
|
|
||||||
<listenAddress>default</listenAddress>
|
|
||||||
<minHomeDiskFree unit="%">1</minHomeDiskFree>
|
|
||||||
</options>
|
|
||||||
```
|
|
||||||
corresponds to the json:
|
|
||||||
```json
|
|
||||||
{
|
|
||||||
options: {
|
|
||||||
listenAddresses = [
|
|
||||||
"default"
|
|
||||||
];
|
|
||||||
minHomeDiskFree = {
|
|
||||||
unit = "%";
|
|
||||||
value = 1;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
}
|
|
||||||
```
|
|
||||||
'';
|
|
||||||
example = {
|
|
||||||
options.localAnnounceEnabled = false;
|
|
||||||
gui.theme = "black";
|
|
||||||
};
|
|
||||||
};
|
};
|
||||||
|
|
||||||
guiAddress = mkOption {
|
|
||||||
type = types.str;
|
|
||||||
default = "127.0.0.1:8384";
|
|
||||||
description = lib.mdDoc ''
|
|
||||||
The address to serve the web interface at.
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
|
|
||||||
user = mkOption {
|
|
||||||
type = types.str;
|
|
||||||
default = defaultUser;
|
|
||||||
example = "yourUser";
|
|
||||||
description = mdDoc ''
|
|
||||||
The user to run Syncthing as.
|
|
||||||
By default, a user named `${defaultUser}` will be created whose home
|
|
||||||
directory is [dataDir](#opt-services.syncthing.dataDir).
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
|
|
||||||
group = mkOption {
|
|
||||||
type = types.str;
|
|
||||||
default = defaultGroup;
|
|
||||||
example = "yourGroup";
|
|
||||||
description = mdDoc ''
|
|
||||||
The group to run Syncthing under.
|
|
||||||
By default, a group named `${defaultGroup}` will be created.
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
|
|
||||||
all_proxy = mkOption {
|
|
||||||
type = with types; nullOr str;
|
|
||||||
default = null;
|
|
||||||
example = "socks5://address.com:1234";
|
|
||||||
description = mdDoc ''
|
|
||||||
Overwrites the all_proxy environment variable for the Syncthing process to
|
|
||||||
the given value. This is normally used to let Syncthing connect
|
|
||||||
through a SOCKS5 proxy server.
|
|
||||||
See <https://docs.syncthing.net/users/proxying.html>.
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
|
|
||||||
dataDir = mkOption {
|
|
||||||
type = types.path;
|
|
||||||
default = "/var/lib/syncthing";
|
|
||||||
example = "/home/yourUser";
|
|
||||||
description = lib.mdDoc ''
|
|
||||||
The path where synchronised directories will exist.
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
|
|
||||||
configDir = let
|
|
||||||
cond = versionAtLeast config.system.stateVersion "19.03";
|
|
||||||
in mkOption {
|
|
||||||
type = types.path;
|
|
||||||
description = lib.mdDoc ''
|
|
||||||
The path where the settings and keys will exist.
|
|
||||||
'';
|
|
||||||
default = cfg.dataDir + optionalString cond "/.config/syncthing";
|
|
||||||
defaultText = literalMD ''
|
|
||||||
* if `stateVersion >= 19.03`:
|
|
||||||
|
|
||||||
config.${opt.dataDir} + "/.config/syncthing"
|
|
||||||
* otherwise:
|
|
||||||
|
|
||||||
config.${opt.dataDir}
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
|
|
||||||
databaseDir = mkOption {
|
|
||||||
type = types.path;
|
|
||||||
description = lib.mdDoc ''
|
|
||||||
The directory containing the database and logs.
|
|
||||||
'';
|
|
||||||
default = cfg.configDir;
|
|
||||||
defaultText = literalExpression "config.${opt.configDir}";
|
|
||||||
};
|
|
||||||
|
|
||||||
extraFlags = mkOption {
|
|
||||||
type = types.listOf types.str;
|
|
||||||
default = [];
|
|
||||||
example = [ "--reset-deltas" ];
|
|
||||||
description = lib.mdDoc ''
|
|
||||||
Extra flags passed to the syncthing command in the service definition.
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
|
|
||||||
openPorts = mkOption {
|
|
||||||
type = types.bool;
|
|
||||||
default = false;
|
|
||||||
example = true;
|
|
||||||
description = mdDoc "Whether to open the transfer port and discovery port in the firewall.";
|
|
||||||
};
|
|
||||||
|
|
||||||
transferPort = mkOption {
|
|
||||||
type = types.port;
|
|
||||||
example = 22000;
|
|
||||||
description = mdDoc "The TCP/UDP port for transfers.";
|
|
||||||
};
|
|
||||||
|
|
||||||
discoveryPort = mkOption {
|
|
||||||
type = types.port;
|
|
||||||
example = 21027;
|
|
||||||
description = mdDoc "The UDP port for discovery.";
|
|
||||||
};
|
|
||||||
|
|
||||||
package = mkOption {
|
|
||||||
type = types.package;
|
|
||||||
default = pkgs.syncthing;
|
|
||||||
defaultText = literalExpression "pkgs.syncthing";
|
|
||||||
description = lib.mdDoc ''
|
|
||||||
The Syncthing package to use.
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
};
|
};
|
||||||
});
|
};
|
||||||
|
default = {};
|
||||||
|
description = mdDoc ''
|
||||||
|
Extra configuration options for Syncthing.
|
||||||
|
See <https://docs.syncthing.net/users/config.html>.
|
||||||
|
Note that this attribute set does not exactly match the documented
|
||||||
|
xml format. Instead, this is the format of the json rest api. There
|
||||||
|
are slight differences. For example, this xml:
|
||||||
|
```xml
|
||||||
|
<options>
|
||||||
|
<listenAddress>default</listenAddress>
|
||||||
|
<minHomeDiskFree unit="%">1</minHomeDiskFree>
|
||||||
|
</options>
|
||||||
|
```
|
||||||
|
corresponds to the json:
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
options: {
|
||||||
|
listenAddresses = [
|
||||||
|
"default"
|
||||||
|
];
|
||||||
|
minHomeDiskFree = {
|
||||||
|
unit = "%";
|
||||||
|
value = 1;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
||||||
|
```
|
||||||
|
'';
|
||||||
|
example = {
|
||||||
|
options.localAnnounceEnabled = false;
|
||||||
|
gui.theme = "black";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
guiAddress = mkOption {
|
||||||
|
type = types.str;
|
||||||
|
default = "127.0.0.1:8384";
|
||||||
|
description = lib.mdDoc ''
|
||||||
|
The address to serve the web interface at.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
systemService = mkOption {
|
||||||
|
type = types.bool;
|
||||||
|
default = true;
|
||||||
|
description = lib.mdDoc ''
|
||||||
|
Whether to auto-launch Syncthing as a system service.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
user = mkOption {
|
||||||
|
type = types.str;
|
||||||
|
default = defaultUser;
|
||||||
|
example = "yourUser";
|
||||||
|
description = mdDoc ''
|
||||||
|
The user to run Syncthing as.
|
||||||
|
By default, a user named `${defaultUser}` will be created whose home
|
||||||
|
directory is [dataDir](#opt-services.syncthing.dataDir).
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
group = mkOption {
|
||||||
|
type = types.str;
|
||||||
|
default = defaultGroup;
|
||||||
|
example = "yourGroup";
|
||||||
|
description = mdDoc ''
|
||||||
|
The group to run Syncthing under.
|
||||||
|
By default, a group named `${defaultGroup}` will be created.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
all_proxy = mkOption {
|
||||||
|
type = with types; nullOr str;
|
||||||
|
default = null;
|
||||||
|
example = "socks5://address.com:1234";
|
||||||
|
description = mdDoc ''
|
||||||
|
Overwrites the all_proxy environment variable for the Syncthing process to
|
||||||
|
the given value. This is normally used to let Syncthing connect
|
||||||
|
through a SOCKS5 proxy server.
|
||||||
|
See <https://docs.syncthing.net/users/proxying.html>.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
dataDir = mkOption {
|
||||||
|
type = types.path;
|
||||||
|
default = "/var/lib/syncthing";
|
||||||
|
example = "/home/yourUser";
|
||||||
|
description = lib.mdDoc ''
|
||||||
|
The path where synchronised directories will exist.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
configDir = let
|
||||||
|
cond = versionAtLeast config.system.stateVersion "19.03";
|
||||||
|
in mkOption {
|
||||||
|
type = types.path;
|
||||||
|
description = lib.mdDoc ''
|
||||||
|
The path where the settings and keys will exist.
|
||||||
|
'';
|
||||||
|
default = cfg.dataDir + optionalString cond "/.config/syncthing";
|
||||||
|
defaultText = literalMD ''
|
||||||
|
* if `stateVersion >= 19.03`:
|
||||||
|
|
||||||
|
config.${opt.dataDir} + "/.config/syncthing"
|
||||||
|
* otherwise:
|
||||||
|
|
||||||
|
config.${opt.dataDir}
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
databaseDir = mkOption {
|
||||||
|
type = types.path;
|
||||||
|
description = lib.mdDoc ''
|
||||||
|
The directory containing the database and logs.
|
||||||
|
'';
|
||||||
|
default = cfg.configDir;
|
||||||
|
defaultText = literalExpression "config.${opt.configDir}";
|
||||||
|
};
|
||||||
|
|
||||||
|
extraFlags = mkOption {
|
||||||
|
type = types.listOf types.str;
|
||||||
|
default = [];
|
||||||
|
example = [ "--reset-deltas" ];
|
||||||
|
description = lib.mdDoc ''
|
||||||
|
Extra flags passed to the syncthing command in the service definition.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
openDefaultPorts = mkOption {
|
||||||
|
type = types.bool;
|
||||||
|
default = false;
|
||||||
|
example = true;
|
||||||
|
description = lib.mdDoc ''
|
||||||
|
Whether to open the default ports in the firewall: TCP/UDP 22000 for transfers
|
||||||
|
and UDP 21027 for discovery.
|
||||||
|
|
||||||
|
If multiple users are running Syncthing on this machine, you will need
|
||||||
|
to manually open a set of ports for each instance and leave this disabled.
|
||||||
|
Alternatively, if you are running only a single instance on this machine
|
||||||
|
using the default ports, enable this.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
package = mkOption {
|
||||||
|
type = types.package;
|
||||||
|
default = pkgs.syncthing;
|
||||||
|
defaultText = literalExpression "pkgs.syncthing";
|
||||||
|
description = lib.mdDoc ''
|
||||||
|
The Syncthing package to use.
|
||||||
|
'';
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
imports = [
|
||||||
|
(mkRemovedOptionModule [ "services" "syncthing" "useInotify" ] ''
|
||||||
|
This option was removed because Syncthing now has the inotify functionality included under the name "fswatcher".
|
||||||
|
It can be enabled on a per-folder basis through the web interface.
|
||||||
|
'')
|
||||||
|
(mkRenamedOptionModule [ "services" "syncthing" "extraOptions" ] [ "services" "syncthing" "settings" ])
|
||||||
|
(mkRenamedOptionModule [ "services" "syncthing" "folders" ] [ "services" "syncthing" "settings" "folders" ])
|
||||||
|
(mkRenamedOptionModule [ "services" "syncthing" "devices" ] [ "services" "syncthing" "settings" "devices" ])
|
||||||
|
(mkRenamedOptionModule [ "services" "syncthing" "options" ] [ "services" "syncthing" "settings" "options" ])
|
||||||
|
] ++ map (o:
|
||||||
|
mkRenamedOptionModule [ "services" "syncthing" "declarative" o ] [ "services" "syncthing" o ]
|
||||||
|
) [ "cert" "key" "devices" "folders" "overrideDevices" "overrideFolders" "extraOptions"];
|
||||||
|
|
||||||
###### implementation
|
###### implementation
|
||||||
|
|
||||||
config = mkIf (enabledInstances != {}) {
|
config = mkIf cfg.enable {
|
||||||
networking.firewall = {
|
|
||||||
|
networking.firewall = mkIf cfg.openDefaultPorts {
|
||||||
allowedTCPPorts = [ 22000 ];
|
allowedTCPPorts = [ 22000 ];
|
||||||
allowedUDPPorts = [ 21027 22000 ];
|
allowedUDPPorts = [ 21027 22000 ];
|
||||||
};
|
};
|
||||||
|
|
||||||
systemd.packages = [ pkgs.syncthing ];
|
systemd.packages = [ pkgs.syncthing ];
|
||||||
|
|
||||||
users.users = mkIf (cfg.user == defaultUser) {
|
users.users = mkIf (cfg.systemService && cfg.user == defaultUser) {
|
||||||
${defaultUser} =
|
${defaultUser} =
|
||||||
{ group = cfg.group;
|
{ group = cfg.group;
|
||||||
home = cfg.dataDir;
|
home = cfg.dataDir;
|
||||||
|
@ -628,7 +637,7 @@ in {
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
users.groups = mkIf (cfg.group == defaultGroup) {
|
users.groups = mkIf (cfg.systemService && cfg.group == defaultGroup) {
|
||||||
${defaultGroup}.gid =
|
${defaultGroup}.gid =
|
||||||
config.ids.gids.syncthing;
|
config.ids.gids.syncthing;
|
||||||
};
|
};
|
||||||
|
@ -636,7 +645,7 @@ in {
|
||||||
systemd.services = {
|
systemd.services = {
|
||||||
# upstream reference:
|
# upstream reference:
|
||||||
# https://github.com/syncthing/syncthing/blob/main/etc/linux-systemd/system/syncthing%40.service
|
# https://github.com/syncthing/syncthing/blob/main/etc/linux-systemd/system/syncthing%40.service
|
||||||
syncthing = {
|
syncthing = mkIf cfg.systemService {
|
||||||
description = "Syncthing service";
|
description = "Syncthing service";
|
||||||
after = [ "network.target" ];
|
after = [ "network.target" ];
|
||||||
environment = {
|
environment = {
|
||||||
|
|
Loading…
Reference in New Issue