Syncthing is the BEST! Help me detect "Up to Date" with REST

Syncthing is the BEST!

I’ve eventually dumped Resilio Sync for this amazing open source product because of its REST API.

I wanted to know how to determine if a device (using id) is “Up to Date” thru REST. I can see it on the Web GUI but I don’t see the API for it.

Basically what I’m trying to do is, all devices should be initially paused, and have a nodejs script to Sync-on-command to a specific device (but syncthing is always-on at the background). Then I will wait for the device to be on “Up to Date” state then pause it again (via REST) and print out “Sync success!” and exit.

Thanks!

I am wondering the same thing, although not quite to the same purpose; I have a folder that I know isn’t syncing, and I’m trying to see how to have a script detect this.

The only thing I’ve found that actually shows anything wrong for this folder (that, as I said, I’m quite sure isn’t successfully syncing) is:

/rest/db/completion?folder=src&device=[specific_device_id]

If I do that, I get:

{
  "completion": 99.14897162188355,
  "globalBytes": 78764706,
  "needBytes": 670310,
  "needDeletes": 0
}

This means I have to iterate over every directory and every device to see problems!

In particular,

/rest/db/status?folder=src

shows:

{
  "globalBytes": 78764706,
  "globalDeleted": 3188,
  "globalDirectories": 977,
  "globalFiles": 4999,
  "globalSymlinks": 12,
  "ignorePatterns": false,
  "inSyncBytes": 78764706,
  "inSyncFiles": 4999,
  "invalid": "",
  "localBytes": 78764706,
  "localDeleted": 3147,
  "localDirectories": 977,
  "localFiles": 4999,
  "localSymlinks": 12,
  "needBytes": 0,
  "needDeletes": 0,
  "needDirectories": 0,
  "needFiles": 0,
  "needSymlinks": 0,
  "sequence": 44122,
  "state": "idle",
  "stateChanged": "2017-11-17T18:55:14.3305827-08:00",
  "version": 44122
}

which looks completely OK!

I hope there is a better way, but this is the best I’ve found so far.

1 Like

Wow! Hacky but it works :wink: Thanks a lot man!

1 Like

Happy to help.

FWIW, here’s the code I’m currently using to mean “don’t continue until sync is complete”:

syncthing_api_key="$(grep -i apikey ~/.config/syncthing/config.xml | sed -e 's/[^>]*>//' -e 's/<.*//')"
syncthing_vrici="$(grep -i vrici ~/.config/syncthing/config.xml | sed -e 's/^.*<device id="//' -e 's/".*//')"
for folder in $(grep '<folder' ~/.config/syncthing/config.xml | sed -e 's/.*<folder id="//' -e 's/".*//')
do
  while :
  do
    curl -s -L -k -X GET -H "X-API-Key: $syncthing_api_key" "https://127.0.0.1:8384/rest/db/completion?folder=$folder&device=$syncthing_vrici" || true
    completion=$(curl -s -L -k -X GET -H "X-API-Key: $syncthing_api_key" "https://127.0.0.1:8384/rest/db/completion?folder=$folder&device=$syncthing_vrici" | jq '.completion' | sed 's/\..*//')
    if [ "$completion" -eq 100 ]
    then
      echo "Folder $folder is synced."
      break
    else
      echo "Folder $folder sync is at $completion ; waiting."
      sleep 1
    fi
  done
done
1 Like

What you should do is listen to the FolderCompletion event. This gives you the same data, but instead of polling and iterating you get fed updates as they happen. Do a GET /rest/events?since=0&events=FolderCompletion to start the subscription and increase the since for each call depending on the returned events. See the event documentation for more info.

1 Like

@rlpowell Your script looks like it serves a similar purpose as the wait-for-idle command of my syncthingctl utility. Here’s an excerpt from its --help:

wait-for-idle, -w
  waits until the specified dirs/devs are idling
  --dir, -d [ID]
    specifies the directories, default is all dirs
  --dev [ID]
    specifies the devices, default is all devs
  --at-least, -a [number]
    specifies for how many milliseconds Syncthing must idle (prevents exiting to early in case of flaky status)
  --timeout, -t [number]
    specifies how many milliseconds to wait at most

  example: syncthingctl wait-for-idle --timeout 1800000 --at-least 5000 && systemctl poweroff
           syncthingctl wait-for-idle --dir dir1 --dir dir2 --dev dev1 --dev dev2 --at-least 5000

The utility is using the event API Jakob mentioned.

Oh, I didn’t know about that tool! That’s lovely, thank you!

Oh, too bad it’s a giant Qt5 thing. My machines don’t even have X installed. I wonder if I can easily compile just the CLI thing…

@rlpowell Qt 5 applications have in general no hard dependency against X libraries because the connection to the X server is implemented as a plugin. Of course it is possible to build only the CLI (which is able to run without X/Wayland/Windows/… plugin). This is documented in the build instructions.

Oh, cool. Thanks!