Skip to content

Commit

Permalink
Merge pull request #238 from stuarteberg/allow-relative-paths-in-toml
Browse files Browse the repository at this point in the history
server_local: Allow TOML to contain relative paths
  • Loading branch information
DocSavage authored Sep 20, 2017
2 parents 4095be8 + e200a98 commit db07124
Show file tree
Hide file tree
Showing 3 changed files with 108 additions and 1 deletion.
16 changes: 16 additions & 0 deletions dvid/utils.go
Original file line number Diff line number Diff line change
Expand Up @@ -147,6 +147,22 @@ func (fname Filename) HasExtensionPrefix(exts ...string) bool {
return false
}

// Converts the given (possibly) relative path into an absolute path,
// relative to the given anchor directory, not the current working directory.
// If the given relativePath is already an absolute path,
// it is returned unchanged.
func ConvertToAbsolute(relativePath string, anchorDir string) (string, error) {
if filepath.IsAbs(relativePath) {
return relativePath, nil
}
absDir, err := filepath.Abs(anchorDir)
if err != nil {
return relativePath, fmt.Errorf("Could not decode TOML config: %v\n", err)
}
absPath := filepath.Join(absDir, relativePath)
return absPath, nil
}

// DataFromPost returns data submitted in the given key of a POST request.
func DataFromPost(r *http.Request, key string) ([]byte, error) {
f, _, err := r.FormFile(key)
Expand Down
46 changes: 45 additions & 1 deletion server/server_local.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ package server
import (
"bytes"
"fmt"
"path/filepath"
"net/smtp"
"os"
"os/exec"
Expand Down Expand Up @@ -68,6 +69,45 @@ type tomlConfig struct {
Groupcache storage.GroupcacheConfig
}

// Some settings in the TOML can be given as relative paths.
// This function converts them in-place to absolute paths,
// assuming the given paths were relative to the TOML file's own directory.
func (c *tomlConfig) ConvertPathsToAbsolute(configPath string) error {
var err error

configDir := filepath.Dir(configPath)

// [server].webClient
c.Server.WebClient, err = dvid.ConvertToAbsolute(c.Server.WebClient, configDir)
if err != nil {
return fmt.Errorf("Error converting webClient setting to absolute path")
}

// [logging].logfile
c.Logging.Logfile, err = dvid.ConvertToAbsolute(c.Logging.Logfile, configDir)
if err != nil {
return fmt.Errorf("Error converting logfile setting to absolute path")
}

// [store.foobar].path
for alias, sc := range c.Store {
p, ok := sc["path"]
if !ok {
continue
}
path, ok := p.(string)
if !ok {
return fmt.Errorf("Don't understand path setting for store %q", alias)
}
absPath, err := dvid.ConvertToAbsolute(path, configDir)
if err != nil {
return fmt.Errorf("Error converting store.%s.path to absolute path: %q", alias, path)
}
sc["path"] = absPath
}
return nil
}

func (c tomlConfig) Stores() (map[storage.Alias]dvid.StoreConfig, error) {
stores := make(map[storage.Alias]dvid.StoreConfig, len(c.Store))
for alias, sc := range c.Store {
Expand Down Expand Up @@ -154,11 +194,15 @@ func LoadConfig(filename string) (*datastore.InstanceConfig, *dvid.LogConfig, *s
if _, err := toml.DecodeFile(filename, &tc); err != nil {
return nil, nil, nil, fmt.Errorf("Could not decode TOML config: %v\n", err)
}
var err error
err = tc.ConvertPathsToAbsolute(filename)
if err != nil {
return nil, nil, nil, fmt.Errorf("Could not convert relative paths to absolute paths in TOML config: %v\n", err)
}

// Get all defined stores.
backend := new(storage.Backend)
backend.Groupcache = tc.Groupcache
var err error
backend.Stores, err = tc.Stores()
if err != nil {
return nil, nil, nil, err
Expand Down
47 changes: 47 additions & 0 deletions server/server_local_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import (
"io/ioutil"
"os"
"testing"
"github.com/janelia-flyem/dvid/storage"
)

func loadConfigFile(t *testing.T, filename string) string {
Expand Down Expand Up @@ -35,3 +36,49 @@ func TestParseConfig(t *testing.T) {
t.Errorf("Bad backend configuration retrieval: %v\n", backendCfg)
}
}

func TestTOMLConfigAbsolutePath(t *testing.T) {
// Initialize the filepath settings
var c tomlConfig
c.Server.WebClient = "dvid-distro/dvid-console"
c.Logging.Logfile = "./foobar.log"

c.Store = make(map[storage.Alias]storeConfig)

c.Store["foo"] = make(storeConfig)
c.Store["foo"]["engine"] = "basholeveldb"
c.Store["foo"]["path"] = "foo-storage-db"

c.Store["bar"] = make(storeConfig)
c.Store["bar"]["engine"] = "basholeveldb"
c.Store["bar"]["path"] = "/tmp/bar-storage-db" // Already absolute, should stay unchanged.

// Convert relative paths to absolute
c.ConvertPathsToAbsolute("/tmp/dvid-configs/myconfig.toml")

// Checks
if c.Server.WebClient != "/tmp/dvid-configs/dvid-distro/dvid-console" {
t.Errorf("WebClient not correctly converted to absolute path: %s", c.Server.WebClient)
}

if c.Logging.Logfile != "/tmp/dvid-configs/foobar.log" {
t.Errorf("Logfile not correctly converted to absolute path: %s", c.Logging.Logfile)
}

foo, _ := c.Store["foo"]
path, _ := foo["path"]
if path.(string) != "/tmp/dvid-configs/foo-storage-db" {
t.Errorf("[store.foo].path not correctly converted to absolute path: %s", path)
}

engine, _ := foo["engine"]
if engine.(string) != "basholeveldb" {
t.Errorf("[store.foo].engine should not have been touched: %s", path)
}

bar, _ := c.Store["bar"]
path, _ = bar["path"]
if path.(string) != "/tmp/bar-storage-db" {
t.Errorf("[store.bar].path was already absolute and should have been left unchanged: %s", path)
}
}

0 comments on commit db07124

Please sign in to comment.