"io"
+ "io/ioutil"
+
+ "regexp"
+
"github.com/Sirupsen/logrus"
- "github.com/iotbzh/xds-server/lib/common"
+ common "github.com/iotbzh/xds-common/golib"
"github.com/iotbzh/xds-server/lib/xdsconfig"
"github.com/syncthing/syncthing/lib/config"
)
Home string
STCmd *exec.Cmd
STICmd *exec.Cmd
+ MyID string
// Private fields
binDir string
logsDir string
exitSTChan chan ExitChan
exitSTIChan chan ExitChan
+ conf *xdsconfig.Config
client *common.HTTPClient
log *logrus.Logger
+ Events *Events
}
// ExitChan Channel used for process exit
err error
}
+// ConfigInSync Check whether if Syncthing configuration is in sync
+type configInSync struct {
+ ConfigInSync bool `json:"configInSync"`
+}
+
+// FolderStatus Information about the current status of a folder.
+type FolderStatus struct {
+ GlobalFiles int `json:"globalFiles"`
+ GlobalDirectories int `json:"globalDirectories"`
+ GlobalSymlinks int `json:"globalSymlinks"`
+ GlobalDeleted int `json:"globalDeleted"`
+ GlobalBytes int64 `json:"globalBytes"`
+
+ LocalFiles int `json:"localFiles"`
+ LocalDirectories int `json:"localDirectories"`
+ LocalSymlinks int `json:"localSymlinks"`
+ LocalDeleted int `json:"localDeleted"`
+ LocalBytes int64 `json:"localBytes"`
+
+ NeedFiles int `json:"needFiles"`
+ NeedDirectories int `json:"needDirectories"`
+ NeedSymlinks int `json:"needSymlinks"`
+ NeedDeletes int `json:"needDeletes"`
+ NeedBytes int64 `json:"needBytes"`
+
+ InSyncFiles int `json:"inSyncFiles"`
+ InSyncBytes int64 `json:"inSyncBytes"`
+
+ State string `json:"state"`
+ StateChanged time.Time `json:"stateChanged"`
+
+ Sequence int64 `json:"sequence"`
+
+ IgnorePatterns bool `json:"ignorePatterns"`
+}
+
// NewSyncThing creates a new instance of Syncthing
func NewSyncThing(conf *xdsconfig.Config, log *logrus.Logger) *SyncThing {
var url, apiKey, home, binDir string
binDir: binDir,
logsDir: conf.FileConf.LogsDir,
log: log,
+ conf: conf,
}
+ // Create Events monitoring
+ s.Events = s.NewEventListener()
+
return &s
}
env := []string{
"STNODEFAULTFOLDER=1",
+ "STNOUPGRADE=1",
+ "STNORESTART=1", // FIXME SEB remove ?
}
s.STCmd, err = s.startProc("syncthing", args, env, &s.exitSTChan)
+ // Use autogenerated apikey if not set by config.json
+ if err == nil && s.APIKey == "" {
+ if fd, err := os.Open(filepath.Join(s.Home, "config.xml")); err == nil {
+ defer fd.Close()
+ if b, err := ioutil.ReadAll(fd); err == nil {
+ re := regexp.MustCompile("<apikey>(.*)</apikey>")
+ key := re.FindStringSubmatch(string(b))
+ if len(key) >= 1 {
+ s.APIKey = key[1]
+ }
+ }
+ }
+ }
+
return s.STCmd, err
}
// StartInotify Starts syncthing-inotify process
func (s *SyncThing) StartInotify() (*exec.Cmd, error) {
var err error
+ exeName := "syncthing-inotify"
- s.log.Infof(" STI home=%s", s.Home)
s.log.Infof(" STI url=%s", s.BaseURL)
args := []string{
- "--home=" + s.Home,
"-target=" + s.BaseURL,
}
+ if s.APIKey != "" {
+ args = append(args, "-api="+s.APIKey)
+ s.log.Infof("%s uses apikey=%s", exeName, s.APIKey)
+ }
if s.log.Level == logrus.DebugLevel {
args = append(args, "-verbosity=4")
}
env := []string{}
- s.STICmd, err = s.startProc("syncthing-inotify", args, env, &s.exitSTIChan)
+ s.STICmd, err = s.startProc(exeName, args, env, &s.exitSTIChan)
return s.STICmd, err
}
return fmt.Errorf("ERROR: cannot connect to Syncthing (null client)")
}
- s.client.SetLogger(s.log)
+ // Redirect HTTP log into a file
+ s.client.SetLogLevel(s.conf.Log.Level.String())
+ s.client.LoggerPrefix = "SYNCTHING: "
+ s.client.LoggerOut = s.conf.LogVerboseOut
+
+ s.MyID, err = s.IDGet()
+ if err != nil {
+ return fmt.Errorf("ERROR: cannot retrieve ID")
+ }
+
+ // Start events monitoring
+ err = s.Events.Start()
- return nil
+ return err
}
// IDGet returns the Syncthing ID of Syncthing instance running locally
}
return s.client.HTTPPost("system/config", string(body))
}
+
+// IsConfigInSync Returns true if configuration is in sync
+func (s *SyncThing) IsConfigInSync() (bool, error) {
+ var data []byte
+ var d configInSync
+ if err := s.client.HTTPGet("system/config/insync", &data); err != nil {
+ return false, err
+ }
+ if err := json.Unmarshal(data, &d); err != nil {
+ return false, err
+ }
+ return d.ConfigInSync, nil
+}