func loadAsset(path, defaultValue string) string { devPath := fmt.Sprintf( "%s/src/github.com/emccode/rexray/daemon/module/admin/html/%s", os.Getenv("GOPATH"), path) if gotil.FileExists(devPath) { v, _ := ioutil.ReadFile(devPath) log.Printf("Loaded %s from %s\n", path, devPath) return string(v) } exeDir, _, _ := gotil.GetThisPathParts() relPath := fmt.Sprintf( "%s/html/%s", exeDir, path) if gotil.FileExists(relPath) { v, _ := ioutil.ReadFile(devPath) log.Printf("Loaded %s from %s\n", path, relPath) return string(v) } return defaultValue }
func (c *CLI) initUsageTemplates() { var ut string utPath := fmt.Sprintf("%s/.rexray/usage.template", gotil.HomeDir()) log.WithField("path", utPath).Debug("usage template path") if gotil.FileExists(utPath) { dat, err := ioutil.ReadFile(utPath) if err != nil { panic(err) } log.WithField("source", utPath).Debug("loaded usage template") ut = string(dat) } else { log.WithField("source", "UsageTemplate").Debug("loaded usage template") ut = usageTemplate } c.c.SetUsageTemplate(ut) c.c.SetHelpTemplate(ut) cobra.AddTemplateFuncs(template.FuncMap{ "af": c.additionalFlags, "afs": c.additionalFlagSets, "hf": hasFlags, "lf": c.localFlags, "gf": c.globalFlags, "df": c.driverFlags, "ihf": isHelpFlag, "ivf": isVerboseFlag, "saf": c.sansAdditionalFlags, "cmds": commands, "rtrim": rtrim, }) }
// ValidateConfig validates a provided configuration file. func ValidateConfig(path string) { if !gotil.FileExists(path) { return } buf, err := ioutil.ReadFile(path) if err != nil { fmt.Fprintf( os.Stderr, "rexray: error reading config: %s\n%v\n", path, err) os.Exit(1) } s := string(buf) if _, err := gofigCore.ValidateYAMLString(s); err != nil { fmt.Fprintf( os.Stderr, "rexray: invalid config: %s\n\n %v\n\n", path, err) fmt.Fprint( os.Stderr, "paste the contents between ---BEGIN--- and ---END---\n") fmt.Fprint( os.Stderr, "into http://www.yamllint.com/ to discover the issue\n\n") fmt.Fprintln(os.Stderr, "---BEGIN---") fmt.Fprintln(os.Stderr, s) fmt.Fprintln(os.Stderr, "---END---") os.Exit(1) } }
func (c *CLI) status() { if !gotil.FileExists(util.PidFilePath()) { fmt.Println("REX-Ray is stopped") return } pid, _ := util.ReadPidFile() fmt.Printf("REX-Ray is running at pid %d\n", pid) }
func (d *driver) getVolumeByID(volumeID string) (*types.Volume, error) { volJSONPath := d.getVolPath(volumeID) if !gotil.FileExists(volJSONPath) { return nil, utils.NewNotFoundError(volumeID) } return readVolume(volJSONPath) }
func (d *driver) getSnapshotByID(snapshotID string) (*types.Snapshot, error) { snapJSONPath := d.getSnapPath(snapshotID) if !gotil.FileExists(snapJSONPath) { return nil, utils.NewNotFoundError(snapshotID) } return readSnapshot(snapJSONPath) }
func (c *CLI) restart() { checkOpPerms("restarted") if gotil.FileExists(util.PidFilePath()) { stop() } c.start() }
func (c *CLI) preRun(cmd *cobra.Command, args []string) { if c.cfgFile != "" && gotil.FileExists(c.cfgFile) { if err := c.r.Config.ReadConfigFile(c.cfgFile); err != nil { panic(err) } cmd.Flags().Parse(os.Args[1:]) } c.updateLogLevel() c.r.Config = c.r.Config.Scope("rexray.modules.default-docker") if isHelpFlag(cmd) { cmd.Help() panic(&helpFlagPanic{}) } if permErr := c.checkCmdPermRequirements(cmd); permErr != nil { if term.IsTerminal() { printColorizedError(permErr) } else { printNonColorizedError(permErr) } fmt.Println() cmd.Help() panic(&printedErrorPanic{}) } if c.isInitDriverManagersCmd(cmd) { if err := c.r.InitDrivers(); err != nil { if term.IsTerminal() { printColorizedError(err) } else { printNonColorizedError(err) } fmt.Println() helpCmd := cmd if cmd == c.volumeCmd { helpCmd = c.volumeGetCmd } else if cmd == c.snapshotCmd { helpCmd = c.snapshotGetCmd } else if cmd == c.deviceCmd { helpCmd = c.deviceGetCmd } else if cmd == c.adapterCmd { helpCmd = c.adapterGetTypesCmd } helpCmd.Help() panic(&printedErrorPanic{}) } } }
// LocalDevices returns a map of the system's local devices. func (d *driver) LocalDevices( ctx types.Context, opts *types.LocalDevicesOpts) (*types.LocalDevices, error) { ctx.WithFields(log.Fields{ "vfs.root": d.rootDir, "dev.path": d.devFilePath, }).Debug("config info") var devFileRWL *sync.RWMutex func() { devFileLocksRWL.RLock() defer devFileLocksRWL.RUnlock() devFileRWL = devFileLocks[d.devFilePath] }() devFileRWL.Lock() defer devFileRWL.Unlock() if !gotil.FileExists(d.devFilePath) { return nil, goof.New("device file missing") } f, err := os.Open(d.devFilePath) if err != nil { return nil, err } defer f.Close() localDevs := map[string]string{} scn := bufio.NewScanner(f) for { if !scn.Scan() { break } m := devRX.FindSubmatch(scn.Bytes()) if len(m) == 0 { continue } dev := m[1] var mountPoint []byte if len(m) > 2 { mountPoint = m[2] } localDevs[string(dev)] = string(mountPoint) } return &types.LocalDevices{Driver: vfs.Name, DeviceMap: localDevs}, nil }
func (d *driver) VolumeRemove( ctx types.Context, volumeID string, opts types.Store) error { context.MustSession(ctx) volJSONPath := d.getVolPath(volumeID) if !gotil.FileExists(volJSONPath) { return utils.NewNotFoundError(volumeID) } os.Remove(volJSONPath) return nil }
func (d *driver) SnapshotRemove( ctx types.Context, snapshotID string, opts types.Store) error { context.MustSession(ctx) snapJSONPath := d.getSnapPath(snapshotID) if !gotil.FileExists(snapJSONPath) { return utils.NewNotFoundError(snapshotID) } os.Remove(snapJSONPath) return nil }
func newConfigWithOptions( loadGlobalConfig, loadUserConfig bool, configName, configType string) *config { c := newConfigObj() log.Debug("initializing configuration") c.v.SetTypeByDefaultValue(false) c.v.SetConfigName(configName) c.v.SetConfigType(configType) c.processRegistrations() cfgFile := fmt.Sprintf("%s.%s", configName, configType) etcConfigFile := fmt.Sprintf("%s/%s", etcDirPath, cfgFile) usrConfigFile := fmt.Sprintf("%s/%s", usrDirPath, cfgFile) if loadGlobalConfig && gotil.FileExists(etcConfigFile) { log.WithField("path", etcConfigFile).Debug("loading global config file") if err := c.ReadConfigFile(etcConfigFile); err != nil { log.WithField("path", etcConfigFile).WithError(err).Debug( "error reading global config file") } } if loadUserConfig && gotil.FileExists(usrConfigFile) { log.WithField("path", usrConfigFile).Debug("loading user config file") if err := c.ReadConfigFile(usrConfigFile); err != nil { log.WithField("path", usrConfigFile).WithError(err).Debug( "error reading user config file") } } return c }
func checkPerms(k fileKey, mustPerm bool) bool { if k > maxDirKey { return true } p := k.get() fields := log.Fields{ "path": p, "perms": k.perms(), "mustPerm": mustPerm, } if gotil.FileExists(p) { if log.GetLevel() == log.DebugLevel { log.WithField("path", p).Debug("file exists") } } else { if Debug { log.WithFields(fields).Info("making libStorage directory") } noPermMkdirErr := fmt.Sprintf("mkdir %s: permission denied", p) if err := os.MkdirAll(p, k.perms()); err != nil { if err.Error() == noPermMkdirErr { if mustPerm { log.WithFields(fields).Panic(noPermMkdirErr) } return false } } } touchFilePath := path.Join(p, fmt.Sprintf(".touch-%v", time.Now().Unix())) defer os.RemoveAll(touchFilePath) noPermTouchErr := fmt.Sprintf("open %s: permission denied", touchFilePath) if _, err := os.Create(touchFilePath); err != nil { if err.Error() == noPermTouchErr { if mustPerm { log.WithFields(fields).Panic(noPermTouchErr) } return false } } return true }
func (d *driver) Init(ctx types.Context, config gofig.Config) error { d.config = config d.rootDir = vfs.RootDir(config) d.devFilePath = vfs.DeviceFilePath(config) if !gotil.FileExists(d.devFilePath) { err := ioutil.WriteFile(d.devFilePath, initialDeviceFile, 0644) if err != nil { return err } } devFileLocksRWL.Lock() defer devFileLocksRWL.Unlock() devFileLocks[d.devFilePath] = &sync.RWMutex{} return nil }
func stop() { checkOpPerms("stopped") if !gotil.FileExists(util.PidFilePath()) { fmt.Println("REX-Ray is already stopped") panic(1) } fmt.Print("Shutting down REX-Ray...") pid, pidErr := util.ReadPidFile() failOnError(pidErr) proc, procErr := os.FindProcess(pid) failOnError(procErr) killErr := proc.Signal(syscall.SIGHUP) failOnError(killErr) fmt.Println("SUCCESS!") }
// NextDevice returns the next available device. func (d *driver) NextDevice( ctx types.Context, opts types.Store) (string, error) { var devFileRWL *sync.RWMutex func() { devFileLocksRWL.RLock() defer devFileLocksRWL.RUnlock() devFileRWL = devFileLocks[d.devFilePath] }() devFileRWL.Lock() defer devFileRWL.Unlock() if !gotil.FileExists(d.devFilePath) { return "", goof.New("device file missing") } f, err := os.Open(d.devFilePath) if err != nil { return "", err } defer f.Close() scn := bufio.NewScanner(f) for { if !scn.Scan() { break } m := avaiDevRX.FindSubmatch(scn.Bytes()) if len(m) == 0 { continue } return string(m[1]), nil } return "", goof.New("no available devices") }
func (c *CLI) start() { checkOpPerms("started") log.WithField("os.Args", os.Args).Debug("invoking service start") pidFile := util.PidFilePath() if gotil.FileExists(pidFile) { pid, pidErr := util.ReadPidFile() if pidErr != nil { fmt.Printf("Error reading REX-Ray PID file at %s\n", pidFile) } else { fmt.Printf("REX-Ray already running at PID %d\n", pid) } panic(1) } if c.fg || c.client != "" { c.startDaemon() } else { c.tryToStartDaemon() } }
func (c *CLI) start() { checkOpPerms("started") log.WithField("os.Args", os.Args).Debug("invoking service start") pidFile := util.PidFilePath() if gotil.FileExists(pidFile) { pid, pidErr := util.ReadPidFile() if pidErr != nil { fmt.Printf("Error reading REX-Ray PID file at %s\n", pidFile) panic(1) } rrproc, err := findProcess(pid) if err != nil { fmt.Printf("Error finding process for PID %d", pid) panic(1) } if rrproc != nil { fmt.Printf("REX-Ray already running at PID %d\n", pid) panic(1) } if err := os.RemoveAll(pidFile); err != nil { fmt.Println("Error removing REX-Ray PID file") panic(1) } } if c.fg || c.client != "" { c.startDaemon() } else { c.tryToStartDaemon() } }
// ParseTLSConfig returns a new TLS configuration. func ParseTLSConfig( config gofig.Config, fields log.Fields, roots ...string) (*tls.Config, error) { f := func(k string, v interface{}) { if fields == nil { return } fields[k] = v } if !isSet(config, types.ConfigTLS, roots...) { return nil, nil } if isSet(config, types.ConfigTLSDisabled, roots...) { tlsDisabled := getBool(config, types.ConfigTLSDisabled, roots...) if tlsDisabled { f(types.ConfigTLSDisabled, true) return nil, nil } } if !isSet(config, types.ConfigTLSKeyFile, roots...) { return nil, goof.New("keyFile required") } keyFile := getString(config, types.ConfigTLSKeyFile, roots...) if !gotil.FileExists(keyFile) { return nil, goof.WithField("path", keyFile, "invalid key file") } f(types.ConfigTLSKeyFile, keyFile) if !isSet(config, types.ConfigTLSCertFile, roots...) { return nil, goof.New("certFile required") } certFile := getString(config, types.ConfigTLSCertFile, roots...) if !gotil.FileExists(certFile) { return nil, goof.WithField("path", certFile, "invalid cert file") } f(types.ConfigTLSCertFile, certFile) cer, err := tls.LoadX509KeyPair(certFile, keyFile) if err != nil { return nil, err } tlsConfig := &tls.Config{Certificates: []tls.Certificate{cer}} if isSet(config, types.ConfigTLSServerName, roots...) { serverName := getString(config, types.ConfigTLSServerName, roots...) tlsConfig.ServerName = serverName f(types.ConfigTLSServerName, serverName) } if isSet(config, types.ConfigTLSClientCertRequired, roots...) { clientCertRequired := getBool( config, types.ConfigTLSClientCertRequired, roots...) if clientCertRequired { tlsConfig.ClientAuth = tls.RequireAndVerifyClientCert } f(types.ConfigTLSClientCertRequired, clientCertRequired) } if isSet(config, types.ConfigTLSTrustedCertsFile, roots...) { trustedCertsFile := getString( config, types.ConfigTLSTrustedCertsFile, roots...) if !gotil.FileExists(trustedCertsFile) { return nil, goof.WithField( "path", trustedCertsFile, "invalid trust file") } f(types.ConfigTLSTrustedCertsFile, trustedCertsFile) buf, err := func() ([]byte, error) { f, err := os.Open(trustedCertsFile) if err != nil { return nil, err } defer f.Close() buf, err := ioutil.ReadAll(f) if err != nil { return nil, err } return buf, nil }() if err != nil { return nil, err } certPool := x509.NewCertPool() certPool.AppendCertsFromPEM(buf) tlsConfig.RootCAs = certPool tlsConfig.ClientCAs = certPool } return tlsConfig, nil }
func (c *CLI) preRun(cmd *cobra.Command, args []string) { if c.cfgFile != "" && gotil.FileExists(c.cfgFile) { util.ValidateConfig(c.cfgFile) if err := c.config.ReadConfigFile(c.cfgFile); err != nil { panic(err) } os.Setenv("REXRAY_CONFIG_FILE", c.cfgFile) cmd.Flags().Parse(os.Args[1:]) } c.updateLogLevel() // disable path caching for the CLI c.config.Set(apitypes.ConfigIgVolOpsPathCacheEnabled, false) if v := c.rrHost(); v != "" { c.config.Set(apitypes.ConfigHost, v) } if v := c.rrService(); v != "" { c.config.Set(apitypes.ConfigService, v) } if isHelpFlag(cmd) { cmd.Help() panic(&helpFlagPanic{}) } if permErr := c.checkCmdPermRequirements(cmd); permErr != nil { if term.IsTerminal() { printColorizedError(permErr) } else { printNonColorizedError(permErr) } fmt.Println() cmd.Help() panic(&printedErrorPanic{}) } c.ctx.WithField("val", os.Args).Debug("os.args") if c.activateLibStorage { if c.runAsync { c.ctx = c.ctx.WithValue("async", true) } c.ctx.WithField("cmd", cmd.Name()).Debug("activating libStorage") var err error c.ctx, c.config, c.rsErrs, err = util.ActivateLibStorage( c.ctx, c.config) if err == nil { c.ctx.WithField("cmd", cmd.Name()).Debug( "creating libStorage client") c.r, err = util.NewClient(c.ctx, c.config) } if err != nil { if term.IsTerminal() { printColorizedError(err) } else { printNonColorizedError(err) } fmt.Println() cmd.Help() panic(&printedErrorPanic{}) } } }
// Run the server. func Run() { server.CloseOnAbort() flag.Usage = printUsage flag.Parse() if flagVersion != nil && *flagVersion { _, _, thisExeAbsPath := gotil.GetThisPathParts() fmt.Fprintf(os.Stdout, "Binary: %s\n", thisExeAbsPath) fmt.Fprint(os.Stdout, api.Version.String()) os.Exit(0) } if flagEnv != nil && *flagEnv { for _, v := range os.Environ() { fmt.Fprintf(os.Stdout, "%s\n", v) } os.Exit(0) } // if a config is specified then do not care about any other options if flagConfig != nil && gotil.FileExists(*flagConfig) { config = gofigCore.New() if err := config.ReadConfigFile(*flagConfig); err != nil { fmt.Fprintf(os.Stderr, "%s: error: %v\n", os.Args[0], err) os.Exit(1) } if flagPrintConfig != nil && *flagPrintConfig { jstr, err := config.ToJSON() if err != nil { fmt.Fprintf(os.Stderr, "%s: error: %v\n", os.Args[0], err) os.Exit(1) } fmt.Fprintln(os.Stdout, jstr) os.Exit(0) } s, errs, err := server.Serve(nil, config) if err != nil { fmt.Fprintf(os.Stderr, "%s: error: %v\n", os.Args[0], err) os.Exit(1) } err = <-errs if err != nil { fmt.Fprintf(os.Stderr, "%s: error: %v\n", os.Args[0], err) os.Exit(1) } s.Close() os.Exit(0) } cfg, err := apiconfig.NewConfig() if err != nil { fmt.Fprintf(os.Stderr, "%s: error: %v\n", os.Args[0], err) os.Exit(1) } config = cfg for _, fs := range config.FlagSets() { flag.CommandLine.AddFlagSet(fs) } if flagHelp != nil && *flagHelp { flag.Usage() } if len(flag.Args()) == 0 { flag.Usage() } if flagHost != nil { os.Setenv("LIBSTORAGE_HOST", *flagHost) } if flagLogLvl != nil { os.Setenv("LIBSTORAGE_LOGGING_LEVEL", *flagLogLvl) } if lvl, err := log.ParseLevel( config.GetString(apitypes.ConfigLogLevel)); err == nil { log.SetLevel(lvl) } if flagPrintConfig != nil && *flagPrintConfig { jstr, err := config.ToJSON() if err != nil { fmt.Fprintf(os.Stderr, "%s: error: %v\n", os.Args[0], err) os.Exit(1) } fmt.Fprintln(os.Stdout, jstr) os.Exit(0) } buf := &bytes.Buffer{} fmt.Fprintf(buf, "libstorage:\n server:\n services:\n") for _, ds := range flag.Args() { dsp := strings.Split(ds, ":") dn := dsp[0] sn := dsp[0] if len(dsp) > 1 { sn = dsp[1] } fmt.Fprintf(buf, " %s:\n driver: %s\n", sn, dn) } if err := config.ReadConfig(buf); err != nil { fmt.Fprintf(os.Stderr, "%s: error: %v\n", os.Args[0], err) os.Exit(1) } server.CloseOnAbort() _, errs, err := server.Serve(nil, config) if err != nil { fmt.Fprintf(os.Stderr, "%s: error: %v\n", os.Args[0], err) os.Exit(1) } <-errs }
// Exists returns a flag indicating whether or not the file/directory exists. func (k fileKey) Exists() bool { return gotil.FileExists(k.String()) }
func readConfigFile(config gofig.Config, path string) error { if !gotil.FileExists(path) { return nil } return config.ReadConfigFile(path) }
func (m *mod) Start() error { proto, addr, parseAddrErr := gotil.ParseAddress(m.Address()) if parseAddrErr != nil { return parseAddrErr } if proto == "unix" { dir := filepath.Dir(addr) os.MkdirAll(dir, 0755) } const validProtoPatt = "(?i)^unix|tcp$" isProtoValid, matchProtoErr := regexp.MatchString(validProtoPatt, proto) if matchProtoErr != nil { return goof.WithFieldsE(goof.Fields{ "protocol": proto, "validProtoPatt": validProtoPatt, }, "error matching protocol", matchProtoErr) } if !isProtoValid { return goof.WithField("protocol", proto, "invalid protocol") } if err := m.r.InitDrivers(); err != nil { return goof.WithFieldsE(goof.Fields{ "m": m, "m.r": m.r, }, "error initializing drivers", err) } if err := os.MkdirAll("/etc/docker/plugins", 0755); err != nil { return err } var specPath string var startFunc func() error mux := m.buildMux() if proto == "unix" { sockFile := addr sockFileDir := filepath.Dir(sockFile) mkSockFileDirErr := os.MkdirAll(sockFileDir, 0755) if mkSockFileDirErr != nil { return mkSockFileDirErr } _ = os.RemoveAll(sockFile) specPath = m.Address() startFunc = func() error { l, lErr := net.Listen("unix", sockFile) if lErr != nil { return lErr } defer l.Close() defer os.Remove(sockFile) return http.Serve(l, mux) } } else { specPath = addr startFunc = func() error { s := &http.Server{ Addr: addr, Handler: mux, ReadTimeout: 10 * time.Second, WriteTimeout: 10 * time.Second, MaxHeaderBytes: 1 << 20, } return s.ListenAndServe() } } go func() { sErr := startFunc() if sErr != nil { panic(sErr) } }() spec := m.r.Config.GetString("spec") if spec == "" { if m.name == "default-docker" { spec = "/etc/docker/plugins/rexray.spec" } else { fname := cleanName(m.name) spec = fmt.Sprintf("/etc/docker/plugins/%s.spec", fname) } } log.WithField("path", spec).Debug("docker voldriver spec file") if !gotil.FileExists(spec) { if err := ioutil.WriteFile(spec, []byte(specPath), 0644); err != nil { return err } } return nil }
// IsLocalServerActive returns a flag indicating whether or not a local // libStorage is already running. func IsLocalServerActive( ctx apitypes.Context, config gofig.Config) (host string, running bool) { var ( isLocal bool specFile = SpecFilePath() ) if gotil.FileExists(specFile) { if h, _ := ReadSpecFile(); h != "" { host = h logHostSpec(ctx, host, "read spec file") defer func() { if running || !isLocal { return } host = "" os.RemoveAll(specFile) ctx.WithField("specFile", specFile).Info( "removed invalid spec file") }() } } if host == "" { host = config.GetString(apitypes.ConfigHost) } if host == "" { return "", false } proto, addr, err := gotil.ParseAddress(host) if err != nil { return "", false } switch proto { case "unix": isLocal = true ctx.WithField("sock", addr).Debug("is local unix server active") var sockExists, isActive bool if sockExists = gotil.FileExists(addr); sockExists { if isActive = IsAddressActive(proto, addr); !isActive { os.RemoveAll(addr) ctx.WithField("sockFile", addr).Info( "removed invalid sock file") } } return host, isActive case "tcp": m := localHostRX.FindStringSubmatch(addr) if len(m) < 3 { return "", false } isLocal = true port, err := strconv.Atoi(m[2]) if err != nil { return "", false } ctx.WithField("port", port).Debug("is local tcp server active") return host, IsAddressActive(proto, addr) } return "", false }
// NewConfig returns a new config object. func NewConfig(ctx apitypes.Context) gofig.Config { const cfgFileExt = "yml" loadConfig := func( allExists, usrExists, ignoreExists bool, allPath, usrPath, name string) (gofig.Config, bool) { fields := log.Fields{ "buildType": core.BuildType, "ignoreExists": ignoreExists, "configFileName": name, "globalConfigFilePath": allPath, "userConfigFilePath": usrPath, "globalConfigFileExists": allExists, "userConfigFileExists": usrExists, } ctx.WithFields(fields).Debug("loading config") if ignoreExists { ctx.WithFields(fields).Debug("disabled config file exist check") } else if !allExists && !usrExists { ctx.WithFields(fields).Debug("cannot find global or user file") return nil, false } if allExists { ctx.WithFields(fields).Debug("validating global config") ValidateConfig(allPath) } if usrExists { ctx.WithFields(fields).Debug("validating user config") ValidateConfig(usrPath) } ctx.WithFields(fields).Debug("created new config") return gofigCore.NewConfig( allExists || ignoreExists, usrExists || ignoreExists, name, cfgFileExt), true } // load build-type specific config switch core.BuildType { case "client", "agent", "controller": var ( fileName = BinFileName fileNameExt = fileName + "." + cfgFileExt allFilePath = EtcFilePath(fileNameExt) usrFilePath = path.Join(gotil.HomeDir(), DotDirName, fileNameExt) ) if config, ok := loadConfig( gotil.FileExists(allFilePath), gotil.FileExists(usrFilePath), false, allFilePath, usrFilePath, fileName); ok { return config } } // load config from rexray.yml? { var ( fileName = "rexray" fileNameExt = fileName + "." + cfgFileExt allFilePath = EtcFilePath(fileNameExt) usrFilePath = path.Join(gotil.HomeDir(), DotDirName, fileNameExt) ) if config, ok := loadConfig( gotil.FileExists(allFilePath), gotil.FileExists(usrFilePath), false, allFilePath, usrFilePath, fileName); ok { return config } } // load default config { var ( fileName = "config" fileNameExt = fileName + "." + cfgFileExt allFilePath = EtcFilePath(fileNameExt) usrFilePath = path.Join(gotil.HomeDir(), DotDirName, fileNameExt) ) config, _ := loadConfig( gotil.FileExists(allFilePath), gotil.FileExists(usrFilePath), true, allFilePath, usrFilePath, fileName) return config } }
func assertVolDir( t *testing.T, config gofig.Config, volumeID string, exists bool) { volDir := path.Join(vfs.VolumesDirPath(config), volumeID) assert.Equal(t, exists, gotil.FileExists(volDir)) }
func assertSnapDir( t *testing.T, config gofig.Config, snapshotID string, exists bool) { snapDir := path.Join(vfs.SnapshotsDirPath(config), snapshotID) assert.Equal(t, exists, gotil.FileExists(snapDir)) }