summaryrefslogtreecommitdiffstats
path: root/lib
diff options
context:
space:
mode:
authorSebastien Douheret <sebastien.douheret@iot.bzh>2017-05-16 22:51:32 +0200
committerSebastien Douheret <sebastien.douheret@iot.bzh>2017-05-17 14:04:32 +0200
commitc07adb807c41a1545a9a0f5bbf40080d86946538 (patch)
tree21e00efbcd03360416698663a1ea89536717ae86 /lib
parent8983eebdbe74489d62eae4097580fc430d75bd07 (diff)
Auto start Syncthing and Syncthing-inotify.
Signed-off-by: Sebastien Douheret <sebastien.douheret@iot.bzh>
Diffstat (limited to 'lib')
-rw-r--r--lib/apiv1/apiv1.go7
-rw-r--r--lib/apiv1/config.go2
-rw-r--r--lib/apiv1/exec.go2
-rw-r--r--lib/apiv1/folders.go4
-rw-r--r--lib/apiv1/make.go2
-rw-r--r--lib/model/folder.go99
-rw-r--r--lib/session/session.go2
-rw-r--r--lib/syncthing/st.go204
-rw-r--r--lib/webserver/server.go (renamed from lib/xdsserver/server.go)13
-rw-r--r--lib/xdsconfig/config.go180
-rw-r--r--lib/xdsconfig/fileconfig.go14
-rw-r--r--lib/xdsconfig/folderconfig.go26
12 files changed, 342 insertions, 213 deletions
diff --git a/lib/apiv1/apiv1.go b/lib/apiv1/apiv1.go
index 56c7503..c94849d 100644
--- a/lib/apiv1/apiv1.go
+++ b/lib/apiv1/apiv1.go
@@ -4,6 +4,7 @@ import (
"github.com/Sirupsen/logrus"
"github.com/gin-gonic/gin"
+ "github.com/iotbzh/xds-server/lib/model"
"github.com/iotbzh/xds-server/lib/session"
"github.com/iotbzh/xds-server/lib/xdsconfig"
)
@@ -13,17 +14,19 @@ type APIService struct {
router *gin.Engine
apiRouter *gin.RouterGroup
sessions *session.Sessions
- cfg xdsconfig.Config
+ cfg *xdsconfig.Config
+ mfolder *model.Folder
log *logrus.Logger
}
// New creates a new instance of API service
-func New(sess *session.Sessions, cfg xdsconfig.Config, r *gin.Engine) *APIService {
+func New(sess *session.Sessions, cfg *xdsconfig.Config, mfolder *model.Folder, r *gin.Engine) *APIService {
s := &APIService{
router: r,
sessions: sess,
apiRouter: r.Group("/api/v1"),
cfg: cfg,
+ mfolder: mfolder,
log: cfg.Log,
}
diff --git a/lib/apiv1/config.go b/lib/apiv1/config.go
index a2817a0..326b6fa 100644
--- a/lib/apiv1/config.go
+++ b/lib/apiv1/config.go
@@ -36,7 +36,7 @@ func (s *APIService) setConfig(c *gin.Context) {
s.log.Debugln("SET config: ", cfgArg)
- if err := s.cfg.UpdateAll(cfgArg); err != nil {
+ if err := s.mfolder.UpdateAll(cfgArg); err != nil {
common.APIError(c, err.Error())
return
}
diff --git a/lib/apiv1/exec.go b/lib/apiv1/exec.go
index b0bfd41..18fdc7e 100644
--- a/lib/apiv1/exec.go
+++ b/lib/apiv1/exec.go
@@ -75,7 +75,7 @@ func (s *APIService) execCmd(c *gin.Context) {
return
}
- prj := s.cfg.GetFolderFromID(id)
+ prj := s.mfolder.GetFolderFromID(id)
if prj == nil {
common.APIError(c, "Unknown id")
return
diff --git a/lib/apiv1/folders.go b/lib/apiv1/folders.go
index b1864a2..b4d2ac0 100644
--- a/lib/apiv1/folders.go
+++ b/lib/apiv1/folders.go
@@ -44,7 +44,7 @@ func (s *APIService) addFolder(c *gin.Context) {
s.log.Debugln("Add folder config: ", cfgArg)
- newFld, err := s.cfg.UpdateFolder(cfgArg)
+ newFld, err := s.mfolder.UpdateFolder(cfgArg)
if err != nil {
common.APIError(c, err.Error())
return
@@ -68,7 +68,7 @@ func (s *APIService) delFolder(c *gin.Context) {
var delEntry xdsconfig.FolderConfig
var err error
- if delEntry, err = s.cfg.DeleteFolder(id); err != nil {
+ if delEntry, err = s.mfolder.DeleteFolder(id); err != nil {
common.APIError(c, err.Error())
return
}
diff --git a/lib/apiv1/make.go b/lib/apiv1/make.go
index 9596e13..0f7561f 100644
--- a/lib/apiv1/make.go
+++ b/lib/apiv1/make.go
@@ -72,7 +72,7 @@ func (s *APIService) buildMake(c *gin.Context) {
return
}
- prj := s.cfg.GetFolderFromID(id)
+ prj := s.mfolder.GetFolderFromID(id)
if prj == nil {
common.APIError(c, "Unknown id")
return
diff --git a/lib/model/folder.go b/lib/model/folder.go
new file mode 100644
index 0000000..6687b68
--- /dev/null
+++ b/lib/model/folder.go
@@ -0,0 +1,99 @@
+package model
+
+import (
+ "fmt"
+
+ "github.com/iotbzh/xds-server/lib/syncthing"
+ "github.com/iotbzh/xds-server/lib/xdsconfig"
+)
+
+// Folder Represent a an XDS folder
+type Folder struct {
+ Conf *xdsconfig.Config
+ SThg *st.SyncThing
+}
+
+// NewFolder Create a new instance of Model Folder
+func NewFolder(cfg *xdsconfig.Config, st *st.SyncThing) *Folder {
+ return &Folder{
+ Conf: cfg,
+ SThg: st,
+ }
+}
+
+// GetFolderFromID retrieves the Folder config from id
+func (c *Folder) GetFolderFromID(id string) *xdsconfig.FolderConfig {
+ if idx := c.Conf.Folders.GetIdx(id); idx != -1 {
+ return &c.Conf.Folders[idx]
+ }
+ return nil
+}
+
+// UpdateAll updates all the current configuration
+func (c *Folder) UpdateAll(newCfg xdsconfig.Config) error {
+ return fmt.Errorf("Not Supported")
+ /*
+ if err := VerifyConfig(newCfg); err != nil {
+ return err
+ }
+
+ // TODO: c.Builder = c.Builder.Update(newCfg.Builder)
+ c.Folders = c.Folders.Update(newCfg.Folders)
+
+ // FIXME To be tested & improved error handling
+ for _, f := range c.Folders {
+ if err := c.SThg.FolderChange(st.FolderChangeArg{
+ ID: f.ID,
+ Label: f.Label,
+ RelativePath: f.RelativePath,
+ SyncThingID: f.SyncThingID,
+ ShareRootDir: c.ShareRootDir,
+ }); err != nil {
+ return err
+ }
+ }
+
+ return nil
+ */
+}
+
+// UpdateFolder updates a specific folder into the current configuration
+func (c *Folder) UpdateFolder(newFolder xdsconfig.FolderConfig) (xdsconfig.FolderConfig, error) {
+ // rootPath should not be empty
+ if newFolder.RootPath == "" {
+ newFolder.RootPath = c.Conf.ShareRootDir
+ }
+
+ // Sanity check of folder settings
+ if err := newFolder.Verify(); err != nil {
+ return xdsconfig.FolderConfig{}, err
+ }
+
+ c.Conf.Folders = c.Conf.Folders.Update(xdsconfig.FoldersConfig{newFolder})
+
+ err := c.SThg.FolderChange(st.FolderChangeArg{
+ ID: newFolder.ID,
+ Label: newFolder.Label,
+ RelativePath: newFolder.RelativePath,
+ SyncThingID: newFolder.SyncThingID,
+ ShareRootDir: c.Conf.ShareRootDir,
+ })
+ newFolder.BuilderSThgID = c.Conf.Builder.SyncThingID // FIXME - should be removed after local ST config rework
+ newFolder.Status = xdsconfig.FolderStatusEnable
+
+ return newFolder, err
+}
+
+// DeleteFolder deletes a specific folder
+func (c *Folder) DeleteFolder(id string) (xdsconfig.FolderConfig, error) {
+ var fld xdsconfig.FolderConfig
+ var err error
+
+ if err = c.SThg.FolderDelete(id); err != nil {
+ return fld, err
+ }
+
+ c.Conf.Folders, fld, err = c.Conf.Folders.Delete(id)
+
+ return fld, err
+}
diff --git a/lib/session/session.go b/lib/session/session.go
index 35dfdc6..d4e1ad3 100644
--- a/lib/session/session.go
+++ b/lib/session/session.go
@@ -205,8 +205,8 @@ func (s *Sessions) monitorSessMap() {
s.log.Debugln("Stop monitorSessMap")
return
case <-time.After(sessionMonitorTime * time.Second):
- s.log.Debugf("Sessions Map size: %d", len(s.sessMap))
if dbgFullTrace {
+ s.log.Debugf("Sessions Map size: %d", len(s.sessMap))
s.log.Debugf("Sessions Map : %v", s.sessMap)
}
diff --git a/lib/syncthing/st.go b/lib/syncthing/st.go
index 7d07b70..15cab0d 100644
--- a/lib/syncthing/st.go
+++ b/lib/syncthing/st.go
@@ -2,26 +2,207 @@ package st
import (
"encoding/json"
+ "os"
+ "os/exec"
+ "path"
+ "path/filepath"
+ "syscall"
+ "time"
"strings"
"fmt"
+ "io"
+
"github.com/Sirupsen/logrus"
"github.com/iotbzh/xds-server/lib/common"
+ "github.com/iotbzh/xds-server/lib/xdsconfig"
"github.com/syncthing/syncthing/lib/config"
)
// SyncThing .
type SyncThing struct {
BaseURL string
- client *common.HTTPClient
- log *logrus.Logger
+ APIKey string
+ Home string
+ STCmd *exec.Cmd
+
+ // Private fields
+ binDir string
+ logsDir string
+ exitSTChan chan ExitChan
+ client *common.HTTPClient
+ log *logrus.Logger
+}
+
+// ExitChan Channel used for process exit
+type ExitChan struct {
+ status int
+ err error
}
// NewSyncThing creates a new instance of Syncthing
-func NewSyncThing(url string, apikey string, log *logrus.Logger) *SyncThing {
- cl, err := common.HTTPNewClient(url,
+func NewSyncThing(conf *xdsconfig.Config, log *logrus.Logger) *SyncThing {
+ var url, apiKey, home, binDir string
+ var err error
+
+ stCfg := conf.FileConf.SThgConf
+ if stCfg != nil {
+ url = stCfg.GuiAddress
+ apiKey = stCfg.GuiAPIKey
+ home = stCfg.Home
+ binDir = stCfg.BinDir
+ }
+
+ if url == "" {
+ url = "http://localhost:8384"
+ }
+ if url[0:7] != "http://" {
+ url = "http://" + url
+ }
+
+ if home == "" {
+ home = "/mnt/share"
+ }
+
+ if binDir == "" {
+ if binDir, err = filepath.Abs(filepath.Dir(os.Args[0])); err != nil {
+ binDir = "/usr/local/bin"
+ }
+ }
+
+ s := SyncThing{
+ BaseURL: url,
+ APIKey: apiKey,
+ Home: home,
+ binDir: binDir,
+ logsDir: conf.FileConf.LogsDir,
+ log: log,
+ }
+
+ return &s
+}
+
+// Start Starts syncthing process
+func (s *SyncThing) startProc(exeName string, args []string, env []string, eChan *chan ExitChan) (*exec.Cmd, error) {
+
+ // Kill existing process (useful for debug ;-) )
+ if os.Getenv("DEBUG_MODE") != "" {
+ exec.Command("bash", "-c", "pkill -9 "+exeName).Output()
+ }
+
+ path, err := exec.LookPath(path.Join(s.binDir, exeName))
+ if err != nil {
+ return nil, fmt.Errorf("Cannot find %s executable in %s", exeName, s.binDir)
+ }
+ cmd := exec.Command(path, args...)
+ cmd.Env = os.Environ()
+ for _, ev := range env {
+ cmd.Env = append(cmd.Env, ev)
+ }
+
+ // open log file
+ var outfile *os.File
+ logFilename := filepath.Join(s.logsDir, exeName+".log")
+ if s.logsDir != "" {
+ outfile, err := os.Create(logFilename)
+ if err != nil {
+ return nil, fmt.Errorf("Cannot create log file %s", logFilename)
+ }
+
+ cmdOut, err := cmd.StdoutPipe()
+ if err != nil {
+ return nil, fmt.Errorf("Pipe stdout error for : %s", err)
+ }
+
+ go io.Copy(outfile, cmdOut)
+ }
+
+ err = cmd.Start()
+ if err != nil {
+ return nil, err
+ }
+
+ *eChan = make(chan ExitChan, 1)
+ go func(c *exec.Cmd, oF *os.File) {
+ status := 0
+ sts, err := c.Process.Wait()
+ if !sts.Success() {
+ s := sts.Sys().(syscall.WaitStatus)
+ status = s.ExitStatus()
+ }
+ if oF != nil {
+ oF.Close()
+ }
+ s.log.Debugf("%s exited with status %d, err %v", exeName, status, err)
+
+ *eChan <- ExitChan{status, err}
+ }(cmd, outfile)
+
+ return cmd, nil
+}
+
+// Start Starts syncthing process
+func (s *SyncThing) Start() (*exec.Cmd, error) {
+ var err error
+
+ s.log.Infof(" ST home=%s", s.Home)
+ s.log.Infof(" ST url=%s", s.BaseURL)
+
+ args := []string{
+ "--home=" + s.Home,
+ "-no-browser",
+ "--gui-address=" + s.BaseURL,
+ }
+
+ if s.APIKey != "" {
+ args = append(args, "-gui-apikey=\""+s.APIKey+"\"")
+ s.log.Infof(" ST apikey=%s", s.APIKey)
+ }
+ if s.log.Level == logrus.DebugLevel {
+ args = append(args, "-verbose")
+ }
+
+ env := []string{
+ "STNODEFAULTFOLDER=1",
+ }
+
+ s.STCmd, err = s.startProc("syncthing", args, env, &s.exitSTChan)
+
+ return s.STCmd, err
+}
+
+func (s *SyncThing) stopProc(pname string, proc *os.Process, exit chan ExitChan) {
+ if err := proc.Signal(os.Interrupt); err != nil {
+ s.log.Infof("Proc interrupt %s error: %s", pname, err.Error())
+
+ select {
+ case <-exit:
+ case <-time.After(time.Second):
+ // A bigger bonk on the head.
+ if err := proc.Signal(os.Kill); err != nil {
+ s.log.Infof("Proc term %s error: %s", pname, err.Error())
+ }
+ <-exit
+ }
+ }
+ s.log.Infof("%s stopped (PID %d)", pname, proc.Pid)
+}
+
+// Stop Stops syncthing process
+func (s *SyncThing) Stop() {
+ if s.STCmd == nil {
+ return
+ }
+ s.stopProc("syncthing", s.STCmd.Process, s.exitSTChan)
+ s.STCmd = nil
+}
+
+// Connect Establish HTTP connection with Syncthing
+func (s *SyncThing) Connect() error {
+ var err error
+ s.client, err = common.HTTPNewClient(s.BaseURL,
common.HTTPClientConfig{
URLPrefix: "/rest",
HeaderClientKeyName: "X-Syncthing-ID",
@@ -29,19 +210,14 @@ func NewSyncThing(url string, apikey string, log *logrus.Logger) *SyncThing {
if err != nil {
msg := ": " + err.Error()
if strings.Contains(err.Error(), "connection refused") {
- msg = fmt.Sprintf("(url: %s)", url)
+ msg = fmt.Sprintf("(url: %s)", s.BaseURL)
}
- log.Debugf("ERROR: cannot connect to Syncthing %s", msg)
- return nil
+ return fmt.Errorf("ERROR: cannot connect to Syncthing %s", msg)
}
-
- s := SyncThing{
- BaseURL: url,
- client: cl,
- log: log,
+ if s.client == nil {
+ return fmt.Errorf("ERROR: cannot connect to Syncthing (null client)")
}
-
- return &s
+ return nil
}
// IDGet returns the Syncthing ID of Syncthing instance running locally
diff --git a/lib/xdsserver/server.go b/lib/webserver/server.go
index 90d0f38..7be157a 100644
--- a/lib/xdsserver/server.go
+++ b/lib/webserver/server.go
@@ -1,4 +1,4 @@
-package xdsserver
+package webserver
import (
"net/http"
@@ -11,6 +11,7 @@ import (
"github.com/gin-gonic/gin"
"github.com/googollee/go-socket.io"
"github.com/iotbzh/xds-server/lib/apiv1"
+ "github.com/iotbzh/xds-server/lib/model"
"github.com/iotbzh/xds-server/lib/session"
"github.com/iotbzh/xds-server/lib/xdsconfig"
)
@@ -21,8 +22,9 @@ type ServerService struct {
api *apiv1.APIService
sIOServer *socketio.Server
webApp *gin.RouterGroup
- cfg xdsconfig.Config
+ cfg *xdsconfig.Config
sessions *session.Sessions
+ mfolder *model.Folder
log *logrus.Logger
stop chan struct{} // signals intentional stop
}
@@ -31,7 +33,7 @@ const indexFilename = "index.html"
const cookieMaxAge = "3600"
// NewServer creates an instance of ServerService
-func NewServer(cfg xdsconfig.Config) *ServerService {
+func NewServer(cfg *xdsconfig.Config, mfolder *model.Folder, log *logrus.Logger) *ServerService {
// Setup logging for gin router
if cfg.Log.Level == logrus.DebugLevel {
@@ -55,8 +57,9 @@ func NewServer(cfg xdsconfig.Config) *ServerService {
sIOServer: nil,
webApp: nil,
cfg: cfg,
- log: cfg.Log,
+ log: log,
sessions: nil,
+ mfolder: mfolder,
stop: make(chan struct{}),
}
@@ -77,7 +80,7 @@ func (s *ServerService) Serve() error {
s.sessions = session.NewClientSessions(s.router, s.log, cookieMaxAge)
// Create REST API
- s.api = apiv1.New(s.sessions, s.cfg, s.router)
+ s.api = apiv1.New(s.sessions, s.cfg, s.mfolder, s.router)
// Websocket routes
s.sIOServer, err = socketio.NewServer(nil)
diff --git a/lib/xdsconfig/config.go b/lib/xdsconfig/config.go
index 801891b..3f8a91d 100644
--- a/lib/xdsconfig/config.go
+++ b/lib/xdsconfig/config.go
@@ -2,15 +2,11 @@ package xdsconfig
import (
"fmt"
- "strings"
"os"
- "time"
-
"github.com/Sirupsen/logrus"
"github.com/codegangsta/cli"
- "github.com/iotbzh/xds-server/lib/syncthing"
)
// Config parameters (json format) of /config command
@@ -21,14 +17,12 @@ type Config struct {
Builder BuilderConfig `json:"builder"`
Folders FoldersConfig `json:"folders"`
- // Private / un-exported fields
- progName string
- fileConf FileConfig
+ // Private (un-exported fields in REST GET /config route)
+ FileConf FileConfig `json:"-"`
WebAppDir string `json:"-"`
HTTPPort string `json:"-"`
ShareRootDir string `json:"-"`
Log *logrus.Logger `json:"-"`
- SThg *st.SyncThing `json:"-"`
}
// Config default values
@@ -36,196 +30,48 @@ const (
DefaultAPIVersion = "1"
DefaultPort = "8000"
DefaultShareDir = "/mnt/share"
- DefaultLogLevel = "error"
)
// Init loads the configuration on start-up
-func Init(ctx *cli.Context) (Config, error) {
+func Init(cliCtx *cli.Context, log *logrus.Logger) (*Config, error) {
var err error
- // Set logger level and formatter
- log := ctx.App.Metadata["logger"].(*logrus.Logger)
-
- logLevel := ctx.GlobalString("log")
- if logLevel == "" {
- logLevel = DefaultLogLevel
- }
- if log.Level, err = logrus.ParseLevel(logLevel); err != nil {
- fmt.Printf("Invalid log level : \"%v\"\n", logLevel)
- os.Exit(1)
- }
- log.Formatter = &logrus.TextFormatter{}
-
// Define default configuration
c := Config{
- Version: ctx.App.Metadata["version"].(string),
+ Version: cliCtx.App.Metadata["version"].(string),
APIVersion: DefaultAPIVersion,
- VersionGitTag: ctx.App.Metadata["git-tag"].(string),
+ VersionGitTag: cliCtx.App.Metadata["git-tag"].(string),
Builder: BuilderConfig{},
Folders: FoldersConfig{},
- progName: ctx.App.Name,
WebAppDir: "webapp/dist",
HTTPPort: DefaultPort,
ShareRootDir: DefaultShareDir,
Log: log,
- SThg: nil,
}
// config file settings overwrite default config
- err = updateConfigFromFile(&c, ctx.GlobalString("config"))
+ err = updateConfigFromFile(&c, cliCtx.GlobalString("config"))
if err != nil {
- return Config{}, err
+ return nil, err
}
// Update location of shared dir if needed
if !dirExists(c.ShareRootDir) {
if err := os.MkdirAll(c.ShareRootDir, 0770); err != nil {
- c.Log.Fatalf("No valid shared directory found (err=%v)", err)
+ return nil, fmt.Errorf("No valid shared directory found: %v", err)
}
}
c.Log.Infoln("Share root directory: ", c.ShareRootDir)
- // FIXME - add a builder interface and support other builder type (eg. native)
- builderType := "syncthing"
-
- switch builderType {
- case "syncthing":
- // Syncthing settings only configurable from config.json file
- stGuiAddr := c.fileConf.SThgConf.GuiAddress
- stGuiApikey := c.fileConf.SThgConf.GuiAPIKey
- if stGuiAddr == "" {
- stGuiAddr = "http://localhost:8384"
- }
- if stGuiAddr[0:7] != "http://" {
- stGuiAddr = "http://" + stGuiAddr
- }
-
- // Retry if connection fail
- retry := 5
- for retry > 0 {
- c.SThg = st.NewSyncThing(stGuiAddr, stGuiApikey, c.Log)
- if c.SThg != nil {
- break
- }
- c.Log.Warningf("Establishing connection to Syncthing (retry %d/5)", retry)
- time.Sleep(time.Second)
- retry--
- }
- if c.SThg == nil {
- c.Log.Fatalf("ERROR: cannot connect to Syncthing (url: %s)", stGuiAddr)
- }
-
- // Retrieve Syncthing config
- id, err := c.SThg.IDGet()
- if err != nil {
- return Config{}, err
- }
-
- if c.Builder, err = NewBuilderConfig(id); err != nil {
- c.Log.Fatalln(err)
- }
-
- // Retrieve initial Syncthing config
- stCfg, err := c.SThg.ConfigGet()
- if err != nil {
- return Config{}, err
- }
- for _, stFld := range stCfg.Folders {
- relativePath := strings.TrimPrefix(stFld.RawPath, c.ShareRootDir)
- if relativePath == "" {
- relativePath = stFld.RawPath
- }
- newFld := NewFolderConfig(stFld.ID, stFld.Label, c.ShareRootDir, strings.Trim(relativePath, "/"))
- c.Folders = c.Folders.Update(FoldersConfig{newFld})
- }
-
- default:
- log.Fatalln("Unsupported builder type")
- }
-
- return c, nil
-}
-
-// GetFolderFromID retrieves the Folder config from id
-func (c *Config) GetFolderFromID(id string) *FolderConfig {
- if idx := c.Folders.GetIdx(id); idx != -1 {
- return &c.Folders[idx]
- }
- return nil
-}
-
-// UpdateAll updates all the current configuration
-func (c *Config) UpdateAll(newCfg Config) error {
- return fmt.Errorf("Not Supported")
- /*
- if err := VerifyConfig(newCfg); err != nil {
- return err
+ if c.FileConf.LogsDir != "" && !dirExists(c.FileConf.LogsDir) {
+ if err := os.MkdirAll(c.FileConf.LogsDir, 0770); err != nil {
+ return nil, fmt.Errorf("Cannot create logs dir: %v", err)
}
-
- // TODO: c.Builder = c.Builder.Update(newCfg.Builder)
- c.Folders = c.Folders.Update(newCfg.Folders)
-
- // SEB A SUP model.NotifyListeners(c, NotifyFoldersChange, FolderConfig{})
- // FIXME To be tested & improved error handling
- for _, f := range c.Folders {
- if err := c.SThg.FolderChange(st.FolderChangeArg{
- ID: f.ID,
- Label: f.Label,
- RelativePath: f.RelativePath,
- SyncThingID: f.SyncThingID,
- ShareRootDir: c.ShareRootDir,
- }); err != nil {
- return err
- }
- }
-
- return nil
- */
-}
-
-// UpdateFolder updates a specific folder into the current configuration
-func (c *Config) UpdateFolder(newFolder FolderConfig) (FolderConfig, error) {
- // rootPath should not be empty
- if newFolder.rootPath == "" {
- newFolder.rootPath = c.ShareRootDir
- }
-
- // Sanity check of folder settings
- if err := FolderVerify(newFolder); err != nil {
- return FolderConfig{}, err
}
+ c.Log.Infoln("Logs directory: ", c.FileConf.LogsDir)
- c.Folders = c.Folders.Update(FoldersConfig{newFolder})
-
- // SEB A SUP model.NotifyListeners(c, NotifyFolderAdd, newFolder)
- err := c.SThg.FolderChange(st.FolderChangeArg{
- ID: newFolder.ID,
- Label: newFolder.Label,
- RelativePath: newFolder.RelativePath,
- SyncThingID: newFolder.SyncThingID,
- ShareRootDir: c.ShareRootDir,
- })
-
- newFolder.BuilderSThgID = c.Builder.SyncThingID // FIXME - should be removed after local ST config rework
- newFolder.Status = FolderStatusEnable
-
- return newFolder, err
-}
-
-// DeleteFolder deletes a specific folder
-func (c *Config) DeleteFolder(id string) (FolderConfig, error) {
- var fld FolderConfig
- var err error
-
- //SEB A SUP model.NotifyListeners(c, NotifyFolderDelete, fld)
- if err = c.SThg.FolderDelete(id); err != nil {
- return fld, err
- }
-
- c.Folders, fld, err = c.Folders.Delete(id)
-
- return fld, err
+ return &c, nil
}
func dirExists(path string) bool {
diff --git a/lib/xdsconfig/fileconfig.go b/lib/xdsconfig/fileconfig.go
index 7370ed0..3daf77c 100644
--- a/lib/xdsconfig/fileconfig.go
+++ b/lib/xdsconfig/fileconfig.go
@@ -12,23 +12,25 @@ import (
)
type SyncThingConf struct {
+ BinDir string `json:"binDir"`
Home string `json:"home"`
GuiAddress string `json:"gui-address"`
GuiAPIKey string `json:"gui-apikey"`
}
type FileConfig struct {
- WebAppDir string `json:"webAppDir"`
- ShareRootDir string `json:"shareRootDir"`
- HTTPPort string `json:"httpPort"`
- SThgConf SyncThingConf `json:"syncthing"`
+ WebAppDir string `json:"webAppDir"`
+ ShareRootDir string `json:"shareRootDir"`
+ HTTPPort string `json:"httpPort"`
+ SThgConf *SyncThingConf `json:"syncthing"`
+ LogsDir string `json:"logsDir"`
}
// getConfigFromFile reads configuration from a config file.
// Order to determine which config file is used:
// 1/ from command line option: "--config myConfig.json"
// 2/ $HOME/.xds/config.json file
-// 3/ <current_dir>/agent-config.json file
+// 3/ <current_dir>/config.json file
// 4/ <xds-server executable dir>/config.json file
func updateConfigFromFile(c *Config, confFile string) error {
@@ -73,7 +75,7 @@ func updateConfigFromFile(c *Config, confFile string) error {
if err := json.NewDecoder(fd).Decode(&fCfg); err != nil {
return err
}
- c.fileConf = fCfg
+ c.FileConf = fCfg
// Support environment variables (IOW ${MY_ENV_VAR} syntax) in config.json
// TODO: better to use reflect package to iterate on fields and be more generic
diff --git a/lib/xdsconfig/folderconfig.go b/lib/xdsconfig/folderconfig.go
index f22e76f..e32f46a 100644
--- a/lib/xdsconfig/folderconfig.go
+++ b/lib/xdsconfig/folderconfig.go
@@ -30,8 +30,8 @@ type FolderConfig struct {
BuilderSThgID string `json:"builderSThgID"`
Status string `json:"status"`
- // Private fields
- rootPath string
+ // Not exported fields
+ RootPath string `json:"-"`
}
// NewFolderConfig creates a new folder object
@@ -43,7 +43,7 @@ func NewFolderConfig(id, label, rootDir, path string) FolderConfig {
Type: FolderTypeCloudSync,
SyncThingID: "",
Status: FolderStatusDisable,
- rootPath: rootDir,
+ RootPath: rootDir,
}
}
@@ -53,30 +53,30 @@ func (c *FolderConfig) GetFullPath(dir string) string {
dir = ""
}
if filepath.IsAbs(dir) {
- return filepath.Join(c.rootPath, dir)
+ return filepath.Join(c.RootPath, dir)
}
- return filepath.Join(c.rootPath, c.RelativePath, dir)
+ return filepath.Join(c.RootPath, c.RelativePath, dir)
}
-// FolderVerify is called to verify that a configuration is valid
-func FolderVerify(fCfg FolderConfig) error {
+// Verify is called to verify that a configuration is valid
+func (c *FolderConfig) Verify() error {
var err error
- if fCfg.Type != FolderTypeCloudSync {
+ if c.Type != FolderTypeCloudSync {
err = fmt.Errorf("Unsupported folder type")
}
- if fCfg.SyncThingID == "" {
+ if c.SyncThingID == "" {
err = fmt.Errorf("device id not set (SyncThingID field)")
}
- if fCfg.rootPath == "" {
- err = fmt.Errorf("rootPath must not be empty")
+ if c.RootPath == "" {
+ err = fmt.Errorf("RootPath must not be empty")
}
if err != nil {
- fCfg.Status = FolderStatusErrorConfig
- log.Printf("ERROR FolderVerify: %v\n", err)
+ c.Status = FolderStatusErrorConfig
+ log.Printf("ERROR Verify: %v\n", err)
}
return err