diff options
Diffstat (limited to 'lib/xdsconfig')
-rw-r--r-- | lib/xdsconfig/config.go | 180 | ||||
-rw-r--r-- | lib/xdsconfig/fileconfig.go | 14 | ||||
-rw-r--r-- | lib/xdsconfig/folderconfig.go | 26 |
3 files changed, 34 insertions, 186 deletions
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 |