syncthing / syncthing-macos

Official frugal and native macOS Syncthing application bundle
https://syncthing.net
MIT License
2.73k stars 147 forks source link

Control Syncthing when on different wifi networks #172

Open qcksilver opened 2 years ago

qcksilver commented 2 years ago

I'm on a M1 MacBook Pro Monterey version 12.1 (21C52) I'm using syncthing-macos version 1.18.5-1

I'm trying to safely shutdown Syncthing from the terminal and I can't get it to work. I'm a new Mac user, so it's hard for me to know if this is just user error or if I've found a bug.

When I input: CURL -X POST -H "X-API-Key:" http://127.0.0.1:8384/rest/system/shutdown It outputs {"ok": "shutting down"}

So I know the command was correct, but syncthing doesn't actually shutdown. Sometimes the syncthing-macos menu bar icon very briefly shows syncthing as offline, so I'm wondering if syncthing-macos is restarting syncthing.

Does syncthing-macos automatically restart syncthing if it detects it's not running, even if syncthing got a valid shutdown command?

Is this it's intended behavior?

I also tried to add pkill syncthing after the shutdown command to kill syncthing-macos before it restarts syncthing, but pkill syncthing doesn't seem to actually kill the app.

qcksilver commented 2 years ago

Uhg I just got pkill to work. The s in syncthing must be capitalized.

So pkill Syncthing does work, but is that a safe shutdown?

I'm coming from windows and I know that syncthing on windows does not like to be improperly shutdown and improperly shutting down can cause some nasty corruption. But idk how syncthing behaves on macos.

What is the safest way to shutdown syncthing from the terminal if syncthing-macos is installed? Or is it not possible?

Thank you in advance!

xor-gate commented 2 years ago

Hi @qcksilver,

The syncthing-macos application bundle indeed manages the syncthing process. It automatically restarts when syncthing crashes (which almost never happens) or gets killed. You should stop syncthing from the application bundle as follows:

Screenshot 2022-01-08 at 12 41 07

The behaviour is intended because else people must manage syncthing process themselves and now it is a seamless experience so people don't have to setup e.g launchd syncthing service.

xor-gate commented 2 years ago

The unix command pkill sends by default the TERM signal and is the graceful manner to instruct a process to stop and cleanup after itself. Syncthing handles the TERM signal to stop the daemon and leave all its state uncorrupted. See https://github.com/syncthing/syncthing/blob/5237337626ce5c28afb9a5d56e5f4fb305a0f73b/cmd/syncthing/main.go#L707-L711

qcksilver commented 2 years ago

Ah I see. Thanks!

So just to confirm (sorry I'm a n00b at macos), I don't need to send the CURL API /rest command first, I can just pkill Syncthing and syncthing-macos will safely shutdown syncthing.

I'm trying to write a script to only open syncthing-macos if I'm connected to specific wifi networks. And to safely shutdown syncthing if it's running and I connect to any other network.

xor-gate commented 2 years ago

I think with your use-case you should not kill/stop syncthing daemon, but better pauze all syncing devices which puts syncthing in a 'standby' state. Then the syncthing daemon will stay running and the syncthing-macos tray application doesn't restart after kill. Better use the /rest/system/pause and /rest/system/resume REST endpoints for this. You can get the state from /rest/system/connections total.paused element. For scripting with REST from shell and JSON you should consider using jq which is nice and can be installed with homebrew.

Good luck!

qcksilver commented 2 years ago

That could definitely work, thanks! I'll also do some research on jq

xor-gate commented 2 years ago

@qcksilver when you figured out how to get it working maybe post here the solution for other people who like this. Feel free to ask questions if you don't get it working, i'm willing to help for a solution.

xor-gate commented 2 years ago

Are u using /System/Library/PrivateFrameworks/Apple80211.framework/Versions/Current/Resources/airport -I | grep SSID | grep -v BSSID to get the current SSID? There is also a post on Stackoverflow - Get wireless SSID through shell script on Mac OS X.

qcksilver commented 2 years ago

I started by trying to use the Shortcuts app since I'm new to mac, and I did manage to get a working shortcut, but it can only be run manually and I got a bit frustrated by the limitations of shortcuts, so I started trying to just build a bash script. Shortcuts was a good starting point for getting familiarized with macos though, so I don't regret the time I spent in it.

Are u using /System/Library/PrivateFrameworks/Apple80211.framework/Versions/Current/Resources/airport -I | grep SSID | grep -v BSSID to get the current SSID? There is also a post on Stackoverflow - Get wireless SSID through shell script on Mac OS X.

The one thing that was easy in the shortcuts app was getting SSID names, and I hadn't figured out how to do it in bash yet, so you just saved me a MASSIVE amount of time. Thank you!!!

xor-gate commented 2 years ago

Yeah the GUI applications for on Mac are "simple" but if you look under the hood it a UNIX-like operating system with a rock solid desktop. If you want to dive-deep you should indeed get into the commandline (and install Homebrew and iTerm2 from homebrew). Homebrew is like apt under Debian Linux, for installing opensource (commandline) tools, this saves you running a Linux virtual machine.

For scheduling periodic tasks/scripts the UNIX (user) cron scheduler can be used so in the background your Wifi polling script controls Syncthing. More info for example here.

xor-gate commented 2 years ago

Hi @qcksilver when I was hacking on the code I saw we never set the pause status icon. And for your case it would be nice to see if syncthing paused all connections. It seems there is something odd going on with the /rest/system/connections endpoint and the total.paused boolean. I have opened a forum topic to discus with people. See https://forum.syncthing.net/t/rest-endpoint-connections-total-incorrect-paused-status/17834

xor-gate commented 2 years ago

When we get it working it will look like this:

Screenshot 2022-01-08 at 16 00 51
xor-gate commented 2 years ago

After some discussions on the forum the total.paused should not be used and is removed for syncthing v1.19.0 and above. To toggle the pause state the /pause and /resume endpoints will still work but checking if all connections are paused you must loop through all connections.