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

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions