diff options
Diffstat (limited to 'lib/agent/project-st.go')
-rw-r--r-- | lib/agent/project-st.go | 155 |
1 files changed, 124 insertions, 31 deletions
diff --git a/lib/agent/project-st.go b/lib/agent/project-st.go index 28a287c..c0d2550 100644 --- a/lib/agent/project-st.go +++ b/lib/agent/project-st.go @@ -1,16 +1,17 @@ package agent -import "github.com/iotbzh/xds-agent/lib/syncthing" - -// SEB TODO +import ( + st "github.com/iotbzh/xds-agent/lib/syncthing" +) // IPROJECT interface implementation for syncthing projects // STProject . type STProject struct { *Context - server *XdsServer - folder *FolderConfig + server *XdsServer + folder *XdsFolderConfig + eventIDs []int } // NewProjectST Create a new instance of STProject @@ -18,7 +19,7 @@ func NewProjectST(ctx *Context, svr *XdsServer) *STProject { p := STProject{ Context: ctx, server: svr, - folder: &FolderConfig{}, + folder: &XdsFolderConfig{}, } return &p } @@ -27,6 +28,7 @@ func NewProjectST(ctx *Context, svr *XdsServer) *STProject { func (p *STProject) Add(cfg ProjectConfig) (*ProjectConfig, error) { var err error + // Add project/folder into XDS Server err = p.server.FolderAdd(p.server.ProjectToFolder(cfg), p.folder) if err != nil { return nil, err @@ -34,19 +36,37 @@ func (p *STProject) Add(cfg ProjectConfig) (*ProjectConfig, error) { svrPrj := p.GetProject() // Declare project into local Syncthing - p.SThg.FolderChange(st.FolderChangeArg{ - ID: cfg.ID, - Label: cfg.Label, + id, err := p.SThg.FolderChange(st.FolderChangeArg{ + ID: svrPrj.ID, + Label: svrPrj.Label, RelativePath: cfg.ClientPath, SyncThingID: p.server.ServerConfig.Builder.SyncThingID, }) + if err != nil { + return nil, err + } - return svrPrj, nil + locPrj, err := p.SThg.FolderConfigGet(id) + if err != nil { + svrPrj.Status = StatusErrorConfig + return nil, err + } + if svrPrj.ID != locPrj.ID { + p.Log.Errorf("Project ID in XDSServer and local ST differ: %s != %s", svrPrj.ID, locPrj.ID) + } + + // Use Update function to setup remains fields + return p.UpdateProject(*svrPrj) } // Delete a project func (p *STProject) Delete() error { - return p.server.FolderDelete(p.folder.ID) + errSvr := p.server.FolderDelete(p.folder.ID) + errLoc := p.SThg.FolderDelete(p.folder.ID) + if errSvr != nil { + return errSvr + } + return errLoc } // GetProject Get public part of project config @@ -56,38 +76,111 @@ func (p *STProject) GetProject() *ProjectConfig { return &prj } -// SetProject Set project config -func (p *STProject) SetProject(prj ProjectConfig) *ProjectConfig { - // SEB TODO +// UpdateProject Update project config +func (p *STProject) UpdateProject(prj ProjectConfig) (*ProjectConfig, error) { + // Update folder p.folder = p.server.ProjectToFolder(prj) - return p.GetProject() + svrPrj := p.GetProject() + + // Register events to update folder status + // Register to XDS Server events + p.server.EventOn("event:FolderStateChanged", p._cbServerFolderChanged) + if err := p.server.EventRegister("FolderStateChanged", svrPrj.ID); err != nil { + p.Log.Warningf("XDS Server EventRegister failed: %v", err) + return svrPrj, err + } + + // Register to Local Syncthing events + for _, evName := range []string{st.EventStateChanged, st.EventFolderPaused} { + evID, err := p.SThg.Events.Register(evName, p._cbLocalSTEvents, svrPrj.ID, nil) + if err != nil { + return nil, err + } + p.eventIDs = append(p.eventIDs, evID) + } + + return svrPrj, nil } // GetServer Get the XdsServer that holds this project func (p *STProject) GetServer() *XdsServer { - // SEB TODO return p.server } -// GetFullPath returns the full path of a directory (from server POV) -func (p *STProject) GetFullPath(dir string) string { - /* SEB - if &dir == nil { - return p.folder.DataSTProject.ServerPath - } - return filepath.Join(p.folder.DataSTProject.ServerPath, dir) - */ - return "SEB TODO" -} - // Sync Force project files synchronization func (p *STProject) Sync() error { - // SEB TODO - return nil + if err := p.server.FolderSync(p.folder.ID); err != nil { + return err + } + return p.SThg.FolderScan(p.folder.ID, "") } // IsInSync Check if project files are in-sync func (p *STProject) IsInSync() (bool, error) { - // SEB TODO - return false, nil + // Should be up-to-date by callbacks (see below) + return p.folder.IsInSync, nil +} + +/** +** Private functions +***/ + +// callback use to update (XDS Server) folder IsInSync status + +func (p *STProject) _cbServerFolderChanged(data interface{}) { + evt := data.(XdsEventFolderChange) + + // Only process event that concerns this project/folder ID + if p.folder.ID != evt.Folder.ID { + return + } + + if evt.Folder.IsInSync != p.folder.DataCloudSync.STSvrIsInSync || + evt.Folder.Status != p.folder.DataCloudSync.STSvrStatus { + + p.folder.DataCloudSync.STSvrIsInSync = evt.Folder.IsInSync + p.folder.DataCloudSync.STSvrStatus = evt.Folder.Status + + if err := p.events.Emit(EVTProjectChange, p.server.FolderToProject(*p.folder)); err != nil { + p.Log.Warningf("Cannot notify project change: %v", err) + } + } +} + +// callback use to update IsInSync status +func (p *STProject) _cbLocalSTEvents(ev st.Event, data *st.EventsCBData) { + + inSync := p.folder.DataCloudSync.STLocIsInSync + sts := p.folder.DataCloudSync.STLocStatus + prevSync := inSync + prevStatus := sts + + switch ev.Type { + + case st.EventStateChanged: + to := ev.Data["to"] + switch to { + case "scanning", "syncing": + sts = StatusSyncing + case "idle": + sts = StatusEnable + } + inSync = (to == "idle") + + case st.EventFolderPaused: + if sts == StatusEnable { + sts = StatusPause + } + inSync = false + } + + if prevSync != inSync || prevStatus != sts { + + p.folder.DataCloudSync.STLocIsInSync = inSync + p.folder.DataCloudSync.STLocStatus = sts + + if err := p.events.Emit(EVTProjectChange, p.server.FolderToProject(*p.folder)); err != nil { + p.Log.Warningf("Cannot notify project change: %v", err) + } + } } |