Skip to content

Bar toggle uses systemctl start/stop, so Syncthing never survives a reboot on pre-existing installs #42

Description

@renews

Summary

The bar's service toggle calls systemctl --user start/stop, never enable/disable. For anyone whose Syncthing was not installed through the plugin's own installer, syncthing.service is left disabled, so the service never comes back after a reboot — the toggle has to be flipped by hand at every login.

The two code paths

The unit is enabled in exactly one place, inside the installer:

https://github.com/ilyaZar/syncshell/blob/main/scripts/syncthing-install.sh#L100-L101

systemctl --user daemon-reload
systemctl --user enable --now "$service_name"

But that path is unreachable when Syncthing already exists. install_package() opens with ensure_initial_install(), which hard-fails unless state is missing:

ensure_initial_install() {
  local state=""
  state="$(installation_state)"
  [[ $state == missing ]] || fail \
    "Syncthing must be absent before installing it (state: $state)"
}

and detect_status() classifies any present binary as existing:

executable="$(command -v syncthing 2>/dev/null || true)"
...
if [[ -n $executable_path ]]; then
  state="existing"
  label="Existing installation found: working"

So for a pre-existing install, the only remaining control is the panel toggle:

https://github.com/ilyaZar/syncshell/blob/main/core/InstallationController.qml#L119

controlProcess.command = [
  "systemctl", "--user", start ? "start" : "stop", "syncthing.service"
]

Runtime-only. Nothing in the plugin ever enables the unit on this path.

Related: the plugin can't see enabled state at all

detect_status() reads LoadState and ActiveState and reports serviceAvailable / serviceRunning. UnitFileState is never queried anywhere in the repo. The panel therefore shows a green/running Syncthing that is silently set to not come back after reboot, with no indication anything is off.

Reproduce

# Arch, Syncthing installed outside the plugin
pacman -S syncthing            # or `omarchy pkg add syncthing`
systemctl --user is-enabled syncthing.service   # -> disabled

Add the plugin to the bar, click the toggle to start Syncthing:

systemctl --user is-active syncthing.service    # -> active
systemctl --user is-enabled syncthing.service   # -> disabled  (unchanged)

Reboot → Syncthing is not running.

Suggested fix

Make the toggle express persistent intent, matching what the installer already does:

controlProcess.command = [
  "systemctl", "--user", start ? "enable" : "disable", "--now", "syncthing.service"
]

enable --now / disable --now are idempotent and cover the runtime action too, so this is a drop-in for the current behaviour plus persistence.

Two things worth considering alongside it:

  1. Surface the state. Add UnitFileState to detect_status() and emit e.g. serviceEnabled, so the panel can distinguish "running" from "running and will survive reboot". Even without a UI change this makes the condition diagnosable.
  2. Don't couple the two irreversibly. Some people deliberately run Syncthing on demand. If mixing them is a concern, an alternative is to keep the toggle as start/stop and add a separate "Start at login" switch in the settings menu bound to enable/disable — more code, but it doesn't take the choice away.

Either way the current state is a trap: the plugin presents a service control that silently forgets.

Environment

  • syncshell 0.1.6 (9454b41)
  • Omarchy 4.0.1-1
  • syncthing 2.1.3-1 (Arch)

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions