Bump Copyright to 2019
[src/xds/xds-server.git] / lib / xdsconfig / config.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 xdsconfig
19
20 import (
21         "fmt"
22         "io"
23         "os"
24         "os/user"
25         "path"
26         "path/filepath"
27
28         common "gerrit.automotivelinux.org/gerrit/src/xds/xds-common.git/golib"
29         "gerrit.automotivelinux.org/gerrit/src/xds/xds-server/lib/xsapiv1"
30         "github.com/Sirupsen/logrus"
31         "github.com/codegangsta/cli"
32 )
33
34 // Config parameters (json format) of /config command
35 type Config struct {
36         // Public APIConfig fields
37         xsapiv1.APIConfig
38
39         // Private (un-exported fields in REST GET /config route)
40         Options       Options        `json:"-"`
41         FileConf      FileConfig     `json:"-"`
42         Log           *logrus.Logger `json:"-"`
43         LogVerboseOut io.Writer      `json:"-"`
44 }
45
46 // Options set at the command line
47 type Options struct {
48         ConfigFile     string
49         LogLevel       string
50         LogFile        string
51         NoFolderConfig bool
52 }
53
54 // Config default values
55 const (
56         DefaultAPIVersion         = "1"
57         DefaultPort               = "8000"
58         DefaultShareDir           = "projects"
59         DefaultSTHomeDir          = "syncthing-config"
60         DefaultSdkScriptsDir      = "${EXEPATH}/sdks"
61         DefaultXdsUtilsScriptsDir = "${EXEPATH}/xds-utils"
62         DefaultSdkDbUpdate        = "startup"
63         DefaultXdsSrvUpdateTime   = "24h"
64 )
65
66 // Init loads the configuration on start-up
67 func Init(cliCtx *cli.Context, log *logrus.Logger) (*Config, error) {
68         var err error
69
70         dfltShareDir := path.Join(ConfigRootDir(), DefaultShareDir)
71         dfltSTHomeDir := path.Join(ConfigRootDir(), DefaultSTHomeDir)
72         if resDir, err := common.ResolveEnvVar(dfltShareDir); err == nil {
73                 dfltShareDir = resDir
74         }
75         if resDir, err := common.ResolveEnvVar(dfltSTHomeDir); err == nil {
76                 dfltSTHomeDir = resDir
77         }
78
79         // Retrieve Server ID (or create one the first time)
80         uuid, err := ServerIDGet()
81         if err != nil {
82                 return nil, err
83         }
84
85         // Define default configuration
86         c := Config{
87                 APIConfig: xsapiv1.APIConfig{
88                         ServerUID:        uuid,
89                         Version:          cliCtx.App.Metadata["version"].(string),
90                         APIVersion:       DefaultAPIVersion,
91                         VersionGitTag:    cliCtx.App.Metadata["git-tag"].(string),
92                         Builder:          xsapiv1.BuilderConfig{},
93                         SupportedSharing: map[string]bool{xsapiv1.TypePathMap: true},
94                 },
95
96                 Options: Options{
97                         ConfigFile:     cliCtx.GlobalString("config"),
98                         LogLevel:       cliCtx.GlobalString("log"),
99                         LogFile:        cliCtx.GlobalString("logfile"),
100                         NoFolderConfig: cliCtx.GlobalBool("no-folderconfig"),
101                 },
102                 FileConf: FileConfig{
103                         WebAppDir:          "www",
104                         ShareRootDir:       dfltShareDir,
105                         SdkScriptsDir:      DefaultSdkScriptsDir,
106                         XdsUtilsScriptsDir: DefaultXdsUtilsScriptsDir,
107                         SdkDbUpdate:        DefaultSdkDbUpdate,
108                         HTTPPort:           DefaultPort,
109                         SThgConf:           &SyncThingConf{Home: dfltSTHomeDir},
110                         LogsDir:            "",
111                         XdsSrvUpdateTime:   DefaultXdsSrvUpdateTime,
112                 },
113                 Log: log,
114         }
115
116         c.Log.Infoln("Server UUID:          ", uuid)
117
118         // config file settings overwrite default config
119         err = readGlobalConfig(&c, c.Options.ConfigFile)
120         if err != nil {
121                 return nil, err
122         }
123
124         // Update location of shared dir if needed
125         if !common.Exists(c.FileConf.ShareRootDir) {
126                 if err := os.MkdirAll(c.FileConf.ShareRootDir, 0770); err != nil {
127                         return nil, fmt.Errorf("No valid shared directory found: %v", err)
128                 }
129         }
130         c.Log.Infoln("Share root directory: ", c.FileConf.ShareRootDir)
131
132         // Where Logs are redirected:
133         //  default 'stdout' (logfile option default value)
134         //  else use file (or filepath) set by --logfile option
135         //  that may be overwritten by LogsDir field of config file
136         logF := c.Options.LogFile
137         logD := c.FileConf.LogsDir
138         if logF != "stdout" {
139                 if logD != "" {
140                         lf := filepath.Base(logF)
141                         if lf == "" || lf == "." {
142                                 lf = "xds-server.log"
143                         }
144                         logF = filepath.Join(logD, lf)
145                 } else {
146                         logD = filepath.Dir(logF)
147                 }
148         }
149         if logD == "" || logD == "." {
150                 logD = "/tmp/xds/logs"
151         }
152         c.Options.LogFile = logF
153         c.FileConf.LogsDir = logD
154
155         if c.FileConf.LogsDir != "" && !common.Exists(c.FileConf.LogsDir) {
156                 if err := os.MkdirAll(c.FileConf.LogsDir, 0770); err != nil {
157                         return nil, fmt.Errorf("Cannot create logs dir: %v", err)
158                 }
159         }
160
161         c.Log.Infoln("Logs file:            ", c.Options.LogFile)
162         c.Log.Infoln("Logs directory:       ", c.FileConf.LogsDir)
163
164         return &c, nil
165 }
166
167 // ConfigRootDir return the root directory where xds server save all config files
168 func ConfigRootDir() string {
169         root := "$HOME"
170         if usr, err := user.Current(); err == nil {
171                 root = usr.HomeDir
172         }
173
174         // Default $HOME/.xds/server but may be changed by an env variable
175         if envVar, envDef := os.LookupEnv("XDS_SERVER_ROOT_CFG_DIR"); envDef {
176                 root = envVar
177         }
178
179         return path.Join(root, "/.xds/server")
180 }
181
182 // WorkspaceRootDir return the path on server side where user xds-workspace dir is accessible
183 func WorkspaceRootDir() string {
184         // May be overloaded by an env variable
185         if envVar, envDef := os.LookupEnv("XDS_SERVER_WORKSPACE_DIR"); envDef {
186                 return envVar
187         }
188
189         home := "${HOME}"
190         if usr, err := user.Current(); err == nil {
191                 home = usr.HomeDir
192         }
193
194         // Default value $HOME/xds-workspace
195         return path.Join(home, "xds-workspace")
196 }