Unverified Commit d5e090d2 authored by Naïm Favier's avatar Naïm Favier
Browse files

Revert "nixos/syncthing: use rfc42 style settings"

This reverts commit 32866f8d.
This reverts commit 40a2df0f.
This reverts commit 47629326.
parent 9c6ea01e
Loading
Loading
Loading
Loading
+258 −256
Original line number Diff line number Diff line
@@ -7,26 +7,25 @@ let
  opt = options.services.syncthing;
  defaultUser = "syncthing";
  defaultGroup = defaultUser;
  settingsFormat = pkgs.formats.json { };

  devices = mapAttrsToList (_: device: device // {
  devices = mapAttrsToList (name: device: {
    deviceID = device.id;
  }) cfg.settings.devices;

  folders = mapAttrsToList (_: folder: folder //
    throwIf (folder?rescanInterval || folder?watch || folder?watchDelay) ''
      The options services.syncthing.settings.folders.<name>.{rescanInterval,watch,watchDelay}
      were removed. Please use, respectively, {rescanIntervalS,fsWatcherEnabled,fsWatcherDelayS} instead.
    '' {
    devices = map (device:
      if builtins.isString device then
        { deviceId = cfg.settings.devices.${device}.id; }
      else
        device
    ) folder.devices;
  }) (filterAttrs (_: folder:
    inherit (device) name addresses introducer autoAcceptFolders;
  }) cfg.devices;

  folders = mapAttrsToList ( _: folder: {
    inherit (folder) path id label type;
    devices = map (device: { deviceId = cfg.devices.${device}.id; }) folder.devices;
    rescanIntervalS = folder.rescanInterval;
    fsWatcherEnabled = folder.watch;
    fsWatcherDelayS = folder.watchDelay;
    ignorePerms = folder.ignorePerms;
    ignoreDelete = folder.ignoreDelete;
    versioning = folder.versioning;
  }) (filterAttrs (
    _: folder:
    folder.enable
  ) cfg.settings.folders);
  ) cfg.folders);

  updateConfig = pkgs.writers.writeDash "merge-syncthing-config" ''
    set -efu
@@ -55,10 +54,10 @@ let
    old_cfg=$(curl ${cfg.guiAddress}/rest/config)

    # generate the new config by merging with the NixOS config options
    new_cfg=$(printf '%s\n' "$old_cfg" | ${pkgs.jq}/bin/jq -c ${escapeShellArg ''. * ${builtins.toJSON cfg.settings} * {
        "devices": (${builtins.toJSON devices}${optionalString (cfg.settings.devices == {} || ! cfg.overrideDevices) " + .devices"}),
        "folders": (${builtins.toJSON folders}${optionalString (cfg.settings.folders == {} || ! cfg.overrideFolders) " + .folders"})
    }''})
    new_cfg=$(printf '%s\n' "$old_cfg" | ${pkgs.jq}/bin/jq -c '. * {
        "devices": (${builtins.toJSON devices}${optionalString (cfg.devices == {} || ! cfg.overrideDevices) " + .devices"}),
        "folders": (${builtins.toJSON folders}${optionalString (cfg.folders == {} || ! cfg.overrideFolders) " + .folders"})
    } * ${builtins.toJSON cfg.extraOptions}')

    # send the new config
    curl -X PUT -d "$new_cfg" ${cfg.guiAddress}/rest/config
@@ -100,91 +99,12 @@ in {
        default = true;
        description = mdDoc ''
          Whether to delete the devices which are not configured via the
          [devices](#opt-services.syncthing.settings.devices) option.
          [devices](#opt-services.syncthing.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 = {
            # global options
            options = mkOption {
              default = {};
              description = mdDoc ''
                The options element contains all other global configuration options
              '';
              type = types.submodule ({ name, ... }: {
                freeformType = settingsFormat.type;
                options = {
                  localAnnounceEnabled = mkOption {
                    type = types.bool;
                    default = true;
                    description = lib.mdDoc ''
                      Whether to send announcements to the local LAN, also use such announcements to find other devices.
                    '';
                  };

                  localAnnouncePort = mkOption {
                    type = types.int;
                    default = 21027;
                    description = lib.mdDoc ''
                      The port on which to listen and send IPv4 broadcast announcements to.
                    '';
                  };

                  relaysEnabled = mkOption {
                    type = types.bool;
                    default = true;
                    description = lib.mdDoc ''
                      When true, relays will be connected to and potentially used for device to device connections.
                    '';
                  };

                  urAccepted = mkOption {
                    type = types.int;
                    default = 0;
                    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.bool;
                    default = false;
                    description = lib.mdDoc ''
                      Whether to apply bandwidth limits to devices in the same broadcast domain as the local device.
                    '';
                  };

                  maxFolderConcurrency = mkOption {
                    type = types.int;
                    default = 0;
                    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 ''
@@ -201,7 +121,6 @@ in {
          };
        };
        type = types.attrsOf (types.submodule ({ name, ... }: {
                freeformType = settingsFormat.type;
          options = {

            name = mkOption {
@@ -212,6 +131,15 @@ in {
              '';
            };

            addresses = mkOption {
              type = types.listOf types.str;
              default = [];
              description = lib.mdDoc ''
                The addresses used to connect to the device.
                If this is left empty, dynamic configuration is attempted.
              '';
            };

            id = mkOption {
              type = types.str;
              description = mdDoc ''
@@ -219,6 +147,16 @@ in {
              '';
            };

            introducer = mkOption {
              type = types.bool;
              default = false;
              description = mdDoc ''
                Whether the device should act as an introducer and be allowed
                to add folders on this computer.
                See <https://docs.syncthing.net/users/introducer.html>.
              '';
            };

            autoAcceptFolders = mkOption {
              type = types.bool;
              default = false;
@@ -232,7 +170,17 @@ in {
        }));
      };

            # folder settings
      overrideFolders = mkOption {
        type = types.bool;
        default = true;
        description = mdDoc ''
          Whether to delete the folders which are not configured via the
          [folders](#opt-services.syncthing.folders) option.
          If set to `false`, folders added via the web
          interface will persist and will have to be deleted manually.
        '';
      };

      folders = mkOption {
        default = {};
        description = mdDoc ''
@@ -251,7 +199,6 @@ in {
          }
        '';
        type = types.attrsOf (types.submodule ({ name, ... }: {
                freeformType = settingsFormat.type;
          options = {

            enable = mkOption {
@@ -301,7 +248,7 @@ in {
              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.
                be defined in the [devices](#opt-services.syncthing.devices) option.
              '';
            };

@@ -349,7 +296,6 @@ in {
                ]
              '';
              type = with types; nullOr (submodule {
                      freeformType = settingsFormat.type;
                options = {
                  type = mkOption {
                    type = enum [ "external" "simple" "staggered" "trashcan" ];
@@ -358,24 +304,82 @@ in {
                      See <https://docs.syncthing.net/users/versioning.html>.
                    '';
                  };
                  fsPath = mkOption {
                    default = "";
                    type = either str path;
                    description = mdDoc ''
                      Path to the versioning folder.
                      See <https://docs.syncthing.net/users/versioning.html>.
                    '';
                  };
                  params = mkOption {
                    type = attrsOf (either str path);
                    description = mdDoc ''
                      The parameters for versioning. Structure depends on
                      [versioning.type](#opt-services.syncthing.folders._name_.versioning.type).
                      See <https://docs.syncthing.net/users/versioning.html>.
                    '';
                  };
                };
              });
            };

                  copyOwnershipFromParent = mkOption {
            rescanInterval = mkOption {
              type = types.int;
              default = 3600;
              description = lib.mdDoc ''
                How often the folder should be rescanned for changes.
              '';
            };

            type = mkOption {
              type = types.enum [ "sendreceive" "sendonly" "receiveonly" "receiveencrypted" ];
              default = "sendreceive";
              description = lib.mdDoc ''
                Whether to only send changes for this folder, only receive them
                or both. `receiveencrypted` can be used for untrusted devices. See
                <https://docs.syncthing.net/users/untrusted.html> for reference.
              '';
            };

            watch = mkOption {
              type = types.bool;
              default = true;
              description = lib.mdDoc ''
                Whether the folder should be watched for changes by inotify.
              '';
            };

            watchDelay = mkOption {
              type = types.int;
              default = 10;
              description = lib.mdDoc ''
                The delay after an inotify event is triggered.
              '';
            };

            ignorePerms = mkOption {
              type = types.bool;
              default = true;
              description = lib.mdDoc ''
                Whether to ignore permission changes.
              '';
            };

            ignoreDelete = 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).
                Whether to skip deleting files that are deleted by peers.
                See <https://docs.syncthing.net/advanced/folder-ignoredelete.html>.
              '';
            };
          };
        }));
      };

          };
        };
      extraOptions = mkOption {
        type = types.addCheck (pkgs.formats.json {}).type isAttrs;
        default = {};
        description = mdDoc ''
          Extra configuration options for Syncthing.
@@ -526,10 +530,6 @@ in {
      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"];
@@ -615,7 +615,9 @@ in {
          ];
        };
      };
      syncthing-init = mkIf (cfg.settings != {}) {
      syncthing-init = mkIf (
        cfg.devices != {} || cfg.folders != {} || cfg.extraOptions != {}
      ) {
        description = "Syncthing configuration updater";
        requisite = [ "syncthing.service" ];
        after = [ "syncthing.service" ];
+7 −14
Original line number Diff line number Diff line
@@ -9,21 +9,14 @@ in {
  nodes.machine = {
    services.syncthing = {
      enable = true;
      settings = {
        options.crashReportingEnabled = false;
      devices.testDevice = {
        id = testId;
      };
      folders.testFolder = {
        path = "/tmp/test";
        devices = [ "testDevice" ];
          versioning = {
            type = "simple";
            params.keep = "10";
          };
        };
        gui.user = "guiUser";
      };
      extraOptions.gui.user = "guiUser";
    };
  };