Use go module as dependency tool instead of glide
[src/xds/xds-server.git] / lib / xdsserver / folder-pathmap.go
1 /*
2  * Copyright (C) 2017-2018 "IoT.bzh"
3  * Author Sebastien Douheret <sebastien@iot.bzh>
4  *
5  * Licensed under the Apache License, Version 2.0 (the "License");
6  * you may not use this file except in compliance with the License.
7  * You may obtain a copy of the License at
8  *
9  *   http://www.apache.org/licenses/LICENSE-2.0
10  *
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an "AS IS" BASIS,
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  * See the License for the specific language governing permissions and
15  * limitations under the License.
16  */
17
18 package xdsserver
19
20 import (
21         "fmt"
22         "io/ioutil"
23         "os"
24         "path/filepath"
25         "strings"
26
27         common "gerrit.automotivelinux.org/gerrit/src/xds/xds-common.git"
28         "gerrit.automotivelinux.org/gerrit/src/xds/xds-server.git/lib/xsapiv1"
29         uuid "github.com/satori/go.uuid"
30 )
31
32 // IFOLDER interface implementation for native/path mapping folders
33
34 // PathMap .
35 type PathMap struct {
36         *Context
37         fConfig xsapiv1.FolderConfig
38 }
39
40 // NewFolderPathMap Create a new instance of PathMap
41 func NewFolderPathMap(ctx *Context) *PathMap {
42         f := PathMap{
43                 Context: ctx,
44                 fConfig: xsapiv1.FolderConfig{
45                         Status: xsapiv1.StatusDisable,
46                 },
47         }
48         return &f
49 }
50
51 // NewUID Get a UUID
52 func (f *PathMap) NewUID(suffix string) string {
53         uuid := uuid.NewV1().String()
54         if len(suffix) > 0 {
55                 uuid += "_" + suffix
56         }
57         return uuid
58 }
59
60 // Add a new folder
61 func (f *PathMap) Add(cfg xsapiv1.FolderConfig) (*xsapiv1.FolderConfig, error) {
62         return f.Setup(cfg)
63 }
64
65 // Setup Setup local project config
66 func (f *PathMap) Setup(cfg xsapiv1.FolderConfig) (*xsapiv1.FolderConfig, error) {
67
68         if cfg.DataPathMap.ServerPath == "" {
69                 return nil, fmt.Errorf("ServerPath must be set")
70         }
71
72         // Use shareRootDir if ServerPath is a relative path
73         dir := cfg.DataPathMap.ServerPath
74         if !filepath.IsAbs(dir) {
75                 dir = filepath.Join(f.Config.FileConf.ShareRootDir, dir)
76         }
77
78         // Sanity check
79         if !common.Exists(dir) {
80                 // try to create if not existing
81                 if err := os.MkdirAll(dir, 0755); err != nil {
82                         return nil, fmt.Errorf("Cannot create ServerPath directory: %s", dir)
83                 }
84         }
85         if !common.Exists(dir) {
86                 return nil, fmt.Errorf("ServerPath directory is not accessible: %s", dir)
87         }
88
89         f.fConfig = cfg
90         f.fConfig.RootPath = dir
91         f.fConfig.DataPathMap.ServerPath = dir
92         f.fConfig.IsInSync = true
93
94         // Verify file created by XDS agent when needed
95         if cfg.DataPathMap.CheckFile != "" {
96                 errMsg := "ServerPath sanity check error (%d): %v"
97                 ckFile := f.ConvPathCli2Svr(cfg.DataPathMap.CheckFile)
98                 if !common.Exists(ckFile) {
99                         return nil, fmt.Errorf(errMsg, 1, "file not present")
100                 }
101                 if cfg.DataPathMap.CheckContent != "" {
102                         fd, err := os.OpenFile(ckFile, os.O_APPEND|os.O_RDWR, 0600)
103                         if err != nil {
104                                 return nil, fmt.Errorf(errMsg, 2, err)
105                         }
106                         defer fd.Close()
107
108                         // Check specific message written by agent
109                         content, err := ioutil.ReadAll(fd)
110                         if err != nil {
111                                 return nil, fmt.Errorf(errMsg, 3, err)
112                         }
113                         if string(content) != cfg.DataPathMap.CheckContent {
114                                 return nil, fmt.Errorf(errMsg, 4, "file content differ")
115                         }
116
117                         // Write a specific message that will be check back on agent side
118                         msg := "Pathmap checked message written by xds-server ID: " + f.Config.ServerUID + "\n"
119                         if n, err := fd.WriteString(msg); n != len(msg) || err != nil {
120                                 return nil, fmt.Errorf(errMsg, 5, err)
121                         }
122                 }
123         }
124
125         f.fConfig.Status = xsapiv1.StatusEnable
126
127         return &f.fConfig, nil
128 }
129
130 // GetConfig Get public part of folder config
131 func (f *PathMap) GetConfig() xsapiv1.FolderConfig {
132         return f.fConfig
133 }
134
135 // GetFullPath returns the full path of a directory (from server POV)
136 func (f *PathMap) GetFullPath(dir string) string {
137         if &dir == nil {
138                 return f.fConfig.DataPathMap.ServerPath
139         }
140         return filepath.Join(f.fConfig.DataPathMap.ServerPath, dir)
141 }
142
143 // ConvPathCli2Svr Convert path from Client to Server
144 func (f *PathMap) ConvPathCli2Svr(s string) string {
145         if f.fConfig.ClientPath != "" && f.fConfig.DataPathMap.ServerPath != "" {
146                 return strings.Replace(s,
147                         f.fConfig.ClientPath,
148                         f.fConfig.DataPathMap.ServerPath,
149                         -1)
150         }
151         return s
152 }
153
154 // ConvPathSvr2Cli Convert path from Server to Client
155 func (f *PathMap) ConvPathSvr2Cli(s string) string {
156         if f.fConfig.ClientPath != "" && f.fConfig.DataPathMap.ServerPath != "" {
157                 return strings.Replace(s,
158                         f.fConfig.DataPathMap.ServerPath,
159                         f.fConfig.ClientPath,
160                         -1)
161         }
162         return s
163 }
164
165 // Remove a folder
166 func (f *PathMap) Remove() error {
167         // nothing to do
168         return nil
169 }
170
171 // Update update some fields of a folder
172 func (f *PathMap) Update(cfg xsapiv1.FolderConfig) (*xsapiv1.FolderConfig, error) {
173         if f.fConfig.ID != cfg.ID {
174                 return nil, fmt.Errorf("Invalid id")
175         }
176         f.fConfig = cfg
177         return &f.fConfig, nil
178 }
179
180 // Sync Force folder files synchronization
181 func (f *PathMap) Sync() error {
182         return nil
183 }
184
185 // IsInSync Check if folder files are in-sync
186 func (f *PathMap) IsInSync() (bool, error) {
187         return true, nil
188 }