Unverified Commit a6253e6b authored by digital's avatar digital Committed by GitHub
Browse files

nixos/syncthing: support syncthing gui and api over unix sockets (#247343)

parent 855223de
Loading
Loading
Loading
Loading
+21 −7
Original line number Diff line number Diff line
@@ -10,6 +10,21 @@ let
  settingsFormat = pkgs.formats.json { };
  cleanedConfig = converge (filterAttrsRecursive (_: v: v != null && v != {})) cfg.settings;

  isUnixGui = (builtins.substring 0 1 cfg.guiAddress) == "/";

  # Syncthing supports serving the GUI over Unix sockets. If that happens, the
  # API is served over the Unix socket as well.  This function returns the correct
  # curl arguments for the address portion of the curl command for both network
  # and Unix socket addresses.
  curlAddressArgs = path: if isUnixGui
    # if cfg.guiAddress is a unix socket, tell curl explicitly about it
    # note that the dot in front of `${path}` is the hostname, which is
    # required.
    then "--unix-socket ${cfg.guiAddress} http://.${path}"
    # no adjustements are needed if cfg.guiAddress is a network address
    else "${cfg.guiAddress}${path}"
    ;

  devices = mapAttrsToList (_: device: device // {
    deviceID = device.id;
  }) cfg.settings.devices;
@@ -62,14 +77,14 @@ let
      GET_IdAttrName = "deviceID";
      override = cfg.overrideDevices;
      conf = devices;
      baseAddress = "${cfg.guiAddress}/rest/config/devices";
      baseAddress = curlAddressArgs "/rest/config/devices";
    };
    dirs = {
      new_conf_IDs = map (v: v.id) folders;
      GET_IdAttrName = "id";
      override = cfg.overrideFolders;
      conf = folders;
      baseAddress = "${cfg.guiAddress}/rest/config/folders";
      baseAddress = curlAddressArgs "/rest/config/folders";
    };
  } [
    # Now for each of these attributes, write the curl commands that are
@@ -117,15 +132,14 @@ let
    builtins.attrNames
    (lib.subtractLists ["folders" "devices"])
    (map (subOption: ''
      curl -X PUT -d ${lib.escapeShellArg (builtins.toJSON cleanedConfig.${subOption})} \
        ${cfg.guiAddress}/rest/config/${subOption}
      curl -X PUT -d ${lib.escapeShellArg (builtins.toJSON cleanedConfig.${subOption})} ${curlAddressArgs "/rest/config/${subOption}"}
    ''))
    (lib.concatStringsSep "\n")
  ]) + ''
    # restart Syncthing if required
    if curl ${cfg.guiAddress}/rest/config/restart-required |
    if curl ${curlAddressArgs "/rest/config/restart-required"} |
       ${jq} -e .requiresRestart > /dev/null; then
        curl -X POST ${cfg.guiAddress}/rest/system/restart
        curl -X POST ${curlAddressArgs "/rest/system/restart"}
    fi
  '');
in {
@@ -651,7 +665,7 @@ in {
          ExecStart = ''
            ${cfg.package}/bin/syncthing \
              -no-browser \
              -gui-address=${cfg.guiAddress} \
              -gui-address=${if isUnixGui then "unix://" else ""}${cfg.guiAddress} \
              -home=${cfg.configDir} ${escapeShellArgs cfg.extraFlags}
          '';
          MemoryDenyWriteExecute = true;