Quantcast
Channel: Syncthing Community Forum - Latest topics
Viewing all articles
Browse latest Browse all 6191

no output from 'syncthing cli' within system service (systemd)

$
0
0

New user here, well versed in development and linux. Using syncthing to build a distributed system for sharing photos across photobooths and digital signage for a small business, loving things it so far, fantastic documentation, seriously. I work with a lot of FOSS projects and documentation is really hit-or-miss most of the time.

To accomplish my goal, I have a system service running syncthing under a user, deployed using the guide found at: Starting Syncthing Automatically — Syncthing v1 documentation

I am making a ancillary services to handle some periodic tasks that involve the local syncthing api. These services run a bash script that depends on knowing the api key for the local api. Normally this can be retrieved with syncthing cli config gui apikey get via cli while the syncthing daemon is running. This is where my issue begins.

Consider the following script ran as a service.

#!/bin/bash

https_port='8384'
my_api_key=$(syncthing cli config gui apikey get)
discover_wait_sec=30

function check-discovery()
{
    echo "$(curl -X GET -s -k -H "X-API-Key: ${my_api_key}" https://127.0.0.1:${https_port}/rest/system/discovery)"
}

echo "key: $(syncthing cli config gui apikey get)"

# Check discovery events for peers
while :
do
    echo "Running device discovery"
    disc_sleep=5
    i=$(($discover_wait_sec / $disc_sleep))
    while [ -z "$discovery_j" ]; do
        discovery_j=$(check-discovery)
        # Check if we found something, if not sleep and decrement
        if [ -z "$discovery_j" ]; then
            echo "None found, sleeping for $disc_sleep seconds..."
            sleep $disc_sleep
            i=$((i-1))
        fi
        # If we have done this for n seconds (i * sleep) without success, exit
        if [ $i == 0 ]; then
            echo "Discovery Failed (None Found) after ${discover_wait_sec} seconds, Exiting"
            exit 1
        fi
    done
    # Only run this check at most every 60s
    sleep 60
done

The important bit is these two lines:

my_api_key=$(syncthing cli config gui apikey get)
echo "key: $my_api_key"

With the result being null, we are unable to execute curl successfully.

When running this script as a service, the output of syncthing cli config gui apikey get is null. I can confirm that this service is running as the same user as the syncthing system service. I’ve done quite a bit of debugging around environment variables, access to files and file permissions, etc.

The same behavior is true of any other similar command. syncthing cli config gui user get also outputs null when used in the same manner, so its not specific to any cli command (as far as I can tell).

Other commands however, do work fine. self_id=$(syncthing --device-id) works from within the same service. From what I can tell its only commands using syncthing cli which I believe just accesses the local API anyway? Perhaps it interacts directly with the ~/.config/syncthing/config.xml file.

Short of diving into the source code (im pretty rusty with GO), I was hoping to find an answer here.

My Question: Is there an obvious reason that I am missing as to why this command isn’t working the way I expect from within a system service invoked as the same user as the syncthing daemon?

My Guess: There is some kind of flag or variable somewhere that needs to be present that syncthing doesn’t have, and I just am not familiar enough with syncthing yet to know where that is or what to look for.

  • Why don’t you just add the api key as a var in the script?
    • I am building a lot of this for auto provisioning of new devices, so everything needs to be as programmatic as possible. This means statically updating each device’s service file to have this API Key would be far too cumbersome. There are some interpolations I could do with sed, but that gets really clunky and doesn’t work well with potential changes in the future (needing to roll api keys)
  • Why don’t you just add an exported variable in the user’s env?
    • Unfortunately exported variables from profile files (like .profile / .bashrc) aren’t available to the service, and I prefer not exposing the apikey globally.

I’m hoping someone has a suggestion or idea. Thank you in advance for any assistance!

6 posts - 2 participants

Read full topic


Viewing all articles
Browse latest Browse all 6191

Trending Articles