1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
|
package agent
import (
"fmt"
"io/ioutil"
"os"
"strings"
"github.com/iotbzh/xds-agent/lib/apiv1"
common "github.com/iotbzh/xds-common/golib"
)
// IPROJECT interface implementation for native/path mapping projects
// PathMap .
type PathMap struct {
*Context
server *XdsServer
folder *XdsFolderConfig
}
// NewProjectPathMap Create a new instance of PathMap
func NewProjectPathMap(ctx *Context, svr *XdsServer) *PathMap {
p := PathMap{
Context: ctx,
server: svr,
folder: &XdsFolderConfig{},
}
return &p
}
// Add a new project
func (p *PathMap) Add(cfg apiv1.ProjectConfig) (*apiv1.ProjectConfig, error) {
var err error
var file *os.File
errMsg := "ClientPath sanity check error (%d): %v"
// Sanity check to verify that we have RW permission and path-mapping is correct
dir := cfg.ClientPath
if !common.Exists(dir) {
// try to create if not existing
if err := os.MkdirAll(dir, 0755); err != nil {
return nil, fmt.Errorf("Cannot create ClientPath directory: %s", dir)
}
}
if !common.Exists(dir) {
return nil, fmt.Errorf("ClientPath directory is not accessible: %s", dir)
}
if file, err = ioutil.TempFile(dir, ".xds_pathmap_check"); err != nil {
return nil, fmt.Errorf(errMsg, 1, err)
}
// Write a specific message that will be check by server during folder add
msg := "Pathmap checked message written by xds-agent ID: " + p.Config.AgentUID + "\n"
if n, err := file.WriteString(msg); n != len(msg) || err != nil {
return nil, fmt.Errorf(errMsg, 2, err)
}
defer func() {
if file != nil {
os.Remove(file.Name())
file.Close()
}
}()
// Convert to Xds folder
fld := p.server.ProjectToFolder(cfg)
fld.DataPathMap.CheckFile = file.Name()
fld.DataPathMap.CheckContent = msg
// Send request to create folder on XDS server side
err = p.server.FolderAdd(fld, p.folder)
if err != nil {
return nil, err
}
// 2nd part of sanity checker
// check specific message added by XDS Server during folder add processing
content, err := ioutil.ReadFile(file.Name())
if err != nil {
return nil, fmt.Errorf(errMsg, 3, err)
}
if !strings.Contains(string(content),
"Pathmap checked message written by xds-server ID") {
return nil, fmt.Errorf(errMsg, 4, "file content differ")
}
return p.GetProject(), nil
}
// Delete a project
func (p *PathMap) Delete() error {
return p.server.FolderDelete(p.folder.ID)
}
// GetProject Get public part of project config
func (p *PathMap) GetProject() *apiv1.ProjectConfig {
prj := p.server.FolderToProject(*p.folder)
prj.ServerID = p.server.ID
return &prj
}
// Setup Setup local project config
func (p *PathMap) Setup(prj apiv1.ProjectConfig) (*apiv1.ProjectConfig, error) {
p.folder = p.server.ProjectToFolder(prj)
np := p.GetProject()
if err := p.events.Emit(apiv1.EVTProjectChange, np, ""); err != nil {
return np, err
}
return np, nil
}
// Update Update some field of a project
func (p *PathMap) Update(prj apiv1.ProjectConfig) (*apiv1.ProjectConfig, error) {
if p.folder.ID != prj.ID {
return nil, fmt.Errorf("Invalid id")
}
err := p.server.FolderUpdate(p.server.ProjectToFolder(prj), p.folder)
if err != nil {
return nil, err
}
return p.GetProject(), nil
}
// GetServer Get the XdsServer that holds this project
func (p *PathMap) GetServer() *XdsServer {
return p.server
}
// Sync Force project files synchronization
func (p *PathMap) Sync() error {
return nil
}
// IsInSync Check if project files are in-sync
func (p *PathMap) IsInSync() (bool, error) {
return true, nil
}
|