8 "github.com/iotbzh/xds-agent/lib/syncthing"
9 "github.com/syncthing/syncthing/lib/sync"
12 // Projects Represent a an XDS Projects
13 type Projects struct {
16 projects map[string]*IPROJECT
17 //SEB registerCB []RegisteredCB
21 type RegisteredCB struct {
27 // Mutex to make add/delete atomic
28 var pjMutex = sync.NewMutex()
30 // NewProjects Create a new instance of Project Model
31 func NewProjects(ctx *Context, st *st.SyncThing) *Projects {
35 projects: make(map[string]*IPROJECT),
36 //registerCB: []RegisteredCB{},
40 // Init Load Projects configuration
41 func (p *Projects) Init(server *XdsServer) error {
42 svrList := make(map[string]*XdsServer)
43 // If server not set, load for all servers
45 svrList = p.xdsServers
47 svrList[server.ID] = server
50 for _, svr := range svrList {
54 xFlds := []FolderConfig{}
55 if err := svr.HTTPGet("/folders", &xFlds); err != nil {
56 errMsg += fmt.Sprintf("Cannot retrieve folders config of XDS server ID %s : %v \n", svr.ID, err.Error())
59 p.Log.Debugf("Server %s, %d projects detected", svr.ID[:8], len(xFlds))
60 for _, prj := range xFlds {
61 newP := svr.FolderToProject(prj)
62 if /*nPrj*/ _, err := p.createUpdate(newP, false, true); err != nil {
63 errMsg += "Error while creating project id " + prj.ID + ": " + err.Error() + "\n "
67 /* FIXME emit EVTProjectChange event ?
68 if err := p.events.Emit(EVTProjectChange, *nPrj); err != nil {
69 p.Log.Warningf("Cannot notify project change: %v", err)
76 p.Log.Infof("Number of loaded Projects: %d", len(p.projects))
79 return fmt.Errorf(errMsg)
84 // Get returns the folder config or nil if not existing
85 func (p *Projects) Get(id string) *IPROJECT {
89 fc, exist := p.projects[id]
96 // GetProjectArr returns the config of all folders as an array
97 func (p *Projects) GetProjectArr() []ProjectConfig {
99 defer pjMutex.Unlock()
101 return p.GetProjectArrUnsafe()
104 // GetProjectArrUnsafe Same as GetProjectArr without mutex protection
105 func (p *Projects) GetProjectArrUnsafe() []ProjectConfig {
106 conf := []ProjectConfig{}
107 for _, v := range p.projects {
108 prj := (*v).GetProject()
109 conf = append(conf, *prj)
114 // Add adds a new folder
115 func (p *Projects) Add(newF ProjectConfig) (*ProjectConfig, error) {
116 prj, err := p.createUpdate(newF, true, false)
121 // Notify client with event
122 if err := p.events.Emit(EVTProjectAdd, *prj); err != nil {
123 p.Log.Warningf("Cannot notify project deletion: %v", err)
129 // CreateUpdate creates or update a folder
130 func (p *Projects) createUpdate(newF ProjectConfig, create bool, initial bool) (*ProjectConfig, error) {
134 defer pjMutex.Unlock()
137 if _, exist := p.projects[newF.ID]; create && exist {
138 return nil, fmt.Errorf("ID already exists")
140 if newF.ClientPath == "" {
141 return nil, fmt.Errorf("ClientPath must be set")
143 if newF.ServerID == "" {
144 return nil, fmt.Errorf("Server ID must be set")
148 if svr, exist = p.xdsServers[newF.ServerID]; !exist {
149 return nil, fmt.Errorf("Unknown Server ID %s", newF.ServerID)
152 // Check type supported
153 b, exist := svr.ServerConfig.SupportedSharing[string(newF.Type)]
155 return nil, fmt.Errorf("Server doesn't support project type %s", newF.Type)
158 // Create a new folder object
164 /*SEB fld = f.SThg.NewFolderST(f.Conf)*/
165 fld = NewProjectST(p.Context, svr)
167 return nil, fmt.Errorf("Cloud Sync project not supported")
172 fld = NewProjectPathMap(p.Context, svr)
174 return nil, fmt.Errorf("Unsupported folder type")
177 var newPrj *ProjectConfig
179 // Add project on server
180 if newPrj, err = fld.Add(newF); err != nil {
181 newF.Status = StatusErrorConfig
182 log.Printf("ERROR Adding folder: %v\n", err)
186 // Just update project config
187 newPrj = fld.SetProject(newF)
192 log.Printf("ERROR project ID empty: %v", newF)
193 return newPrj, fmt.Errorf("Project ID empty")
196 // Add to folders list
197 p.projects[newPrj.ID] = &fld
199 // Force sync after creation
200 // (need to defer to be sure that WS events will arrive after HTTP creation reply)
202 time.Sleep(time.Millisecond * 500)
209 // Delete deletes a specific folder
210 func (p *Projects) Delete(id string) (ProjectConfig, error) {
214 defer pjMutex.Unlock()
216 fld := ProjectConfig{}
217 fc, exist := p.projects[id]
219 return fld, fmt.Errorf("unknown id")
222 prj := (*fc).GetProject()
224 if err = (*fc).Delete(); err != nil {
228 delete(p.projects, id)
230 // Notify client with event
231 if err := p.events.Emit(EVTProjectDelete, *prj); err != nil {
232 p.Log.Warningf("Cannot notify project deletion: %v", err)
238 // ForceSync Force the synchronization of a folder
239 func (p *Projects) ForceSync(id string) error {
242 return fmt.Errorf("Unknown id")
247 // IsProjectInSync Returns true when folder is in sync
248 func (p *Projects) IsProjectInSync(id string) (bool, error) {
251 return false, fmt.Errorf("Unknown id")
253 return (*fc).IsInSync()