diff --git a/internal/logger.go b/internal/logger.go new file mode 100644 index 0000000..bf1a978 --- /dev/null +++ b/internal/logger.go @@ -0,0 +1,28 @@ +package internal + +import ( + "os" + + "gopkg.in/op/go-logging.v1" +) + +// InitLogger initilizes logging format and level +func InitLogger(verbose, debug, withSystemd bool) { + var fmtString string + if withSystemd { + fmtString = "\r[%{level:.6s}] %{message}" + } else { + fmtString = "\r%{color}[%{time:06-01-02 15:04:05}][%{level:.6s}]%{color:reset} %{message}" + } + format := logging.MustStringFormatter(fmtString) + logging.SetFormatter(format) + logging.SetBackend(logging.NewLogBackend(os.Stdout, "", 0)) + + if debug { + logging.SetLevel(logging.DEBUG, "tunasync") + } else if verbose { + logging.SetLevel(logging.INFO, "tunasync") + } else { + logging.SetLevel(logging.NOTICE, "tunasync") + } +} diff --git a/manager/common.go b/manager/common.go new file mode 100644 index 0000000..2c6d88a --- /dev/null +++ b/manager/common.go @@ -0,0 +1,7 @@ +package manager + +import ( + "gopkg.in/op/go-logging.v1" +) + +var logger = logging.MustGetLogger("tunasync") diff --git a/manager/config.go b/manager/config.go new file mode 100644 index 0000000..54d8568 --- /dev/null +++ b/manager/config.go @@ -0,0 +1,63 @@ +package manager + +import ( + "github.com/BurntSushi/toml" + "github.com/codegangsta/cli" +) + +// A Config is the top-level toml-serializaible config struct +type Config struct { + Debug bool `toml:"debug"` + Server ServerConfig `toml:"server"` + Files FileConfig `toml:"files"` +} + +// A ServerConfig represents the configuration for HTTP server +type ServerConfig struct { + Addr string `toml:"addr"` + Port int `toml:"port"` + SSLCert string `toml:"ssl_cert"` + SSLKey string `toml:"ssl_key"` +} + +// A FileConfig contains paths to special files +type FileConfig struct { + StatusFile string `toml:"status_file"` + DBFile string `toml:"db_file"` +} + +func loadConfig(cfgFile string, c *cli.Context) (*Config, error) { + + cfg := new(Config) + cfg.Server.Addr = "127.0.0.1" + cfg.Server.Port = 14242 + cfg.Debug = false + cfg.Files.StatusFile = "/var/lib/tunasync/tunasync.json" + cfg.Files.DBFile = "/var/lib/tunasync/tunasync.db" + + if cfgFile != "" { + if _, err := toml.DecodeFile(cfgFile, cfg); err != nil { + logger.Error(err.Error()) + return nil, err + } + } + + if c.String("addr") != "" { + cfg.Server.Addr = c.String("addr") + } + if c.Int("port") > 0 { + cfg.Server.Port = c.Int("port") + } + if c.String("cert") != "" && c.String("key") != "" { + cfg.Server.SSLCert = c.String("cert") + cfg.Server.SSLKey = c.String("key") + } + if c.String("status-file") != "" { + cfg.Files.StatusFile = c.String("status-file") + } + if c.String("db-file") != "" { + cfg.Files.DBFile = c.String("db-file") + } + + return cfg, nil +} diff --git a/manager/config_test.go b/manager/config_test.go new file mode 100644 index 0000000..4a81347 --- /dev/null +++ b/manager/config_test.go @@ -0,0 +1,141 @@ +package manager + +import ( + "fmt" + "io/ioutil" + "os" + "strings" + "testing" + + "github.com/BurntSushi/toml" + "github.com/codegangsta/cli" + . "github.com/smartystreets/goconvey/convey" +) + +func TestConfig(t *testing.T) { + var cfgBlob = ` + debug = true + [server] + addr = "0.0.0.0" + port = 5000 + + [files] + status_file = "/tmp/tunasync.json" + db_file = "/var/lib/tunasync/tunasync.db" + ` + + Convey("toml decoding should work", t, func() { + + var conf Config + _, err := toml.Decode(cfgBlob, &conf) + ShouldEqual(err, nil) + ShouldEqual(conf.Server.Addr, "0.0.0.0") + ShouldEqual(conf.Server.Port, 5000) + ShouldEqual(conf.Files.StatusFile, "/tmp/tunasync.json") + ShouldEqual(conf.Files.DBFile, "/var/lib/tunasync/tunasync.db") + }) + + Convey("load Config should work", t, func() { + Convey("create config file & cli context", func() { + tmpfile, err := ioutil.TempFile("", "tunasync") + So(err, ShouldEqual, nil) + defer os.Remove(tmpfile.Name()) + + err = ioutil.WriteFile(tmpfile.Name(), []byte(cfgBlob), 0644) + So(err, ShouldEqual, nil) + defer tmpfile.Close() + + app := cli.NewApp() + app.Flags = []cli.Flag{ + cli.StringFlag{ + Name: "config, c", + }, + cli.StringFlag{ + Name: "addr", + }, + cli.IntFlag{ + Name: "port", + }, + cli.StringFlag{ + Name: "cert", + }, + cli.StringFlag{ + Name: "key", + }, + cli.StringFlag{ + Name: "status-file", + }, + cli.StringFlag{ + Name: "db-file", + }, + } + Convey("when giving no config options", func() { + app.Action = func(c *cli.Context) { + cfgFile := c.String("config") + cfg, err := loadConfig(cfgFile, c) + So(err, ShouldEqual, nil) + So(cfg.Server.Addr, ShouldEqual, "127.0.0.1") + } + args := strings.Split("cmd", " ") + app.Run(args) + }) + Convey("when giving config options", func() { + app.Action = func(c *cli.Context) { + cfgFile := c.String("config") + So(cfgFile, ShouldEqual, tmpfile.Name()) + conf, err := loadConfig(cfgFile, c) + So(err, ShouldEqual, nil) + So(conf.Server.Addr, ShouldEqual, "0.0.0.0") + So(conf.Server.Port, ShouldEqual, 5000) + So(conf.Files.StatusFile, ShouldEqual, "/tmp/tunasync.json") + So(conf.Files.DBFile, ShouldEqual, "/var/lib/tunasync/tunasync.db") + + } + cmd := fmt.Sprintf("cmd -c %s", tmpfile.Name()) + args := strings.Split(cmd, " ") + app.Run(args) + }) + Convey("when giving cli options", func() { + app.Action = func(c *cli.Context) { + cfgFile := c.String("config") + So(cfgFile, ShouldEqual, "") + conf, err := loadConfig(cfgFile, c) + So(err, ShouldEqual, nil) + So(conf.Server.Addr, ShouldEqual, "0.0.0.0") + So(conf.Server.Port, ShouldEqual, 5001) + So(conf.Server.SSLCert, ShouldEqual, "/ssl.cert") + So(conf.Server.SSLKey, ShouldEqual, "/ssl.key") + So(conf.Files.StatusFile, ShouldEqual, "/tunasync.json") + So(conf.Files.DBFile, ShouldEqual, "/tunasync.db") + + } + args := strings.Split( + "cmd --addr=0.0.0.0 --port=5001 --cert=/ssl.cert --key /ssl.key --status-file=/tunasync.json --db-file=/tunasync.db", + " ", + ) + app.Run(args) + }) + Convey("when giving both config and cli options", func() { + app.Action = func(c *cli.Context) { + cfgFile := c.String("config") + So(cfgFile, ShouldEqual, tmpfile.Name()) + conf, err := loadConfig(cfgFile, c) + So(err, ShouldEqual, nil) + So(conf.Server.Addr, ShouldEqual, "0.0.0.0") + So(conf.Server.Port, ShouldEqual, 5000) + So(conf.Server.SSLCert, ShouldEqual, "/ssl.cert") + So(conf.Server.SSLKey, ShouldEqual, "/ssl.key") + So(conf.Files.StatusFile, ShouldEqual, "/tunasync.json") + So(conf.Files.DBFile, ShouldEqual, "/tunasync.db") + + } + cmd := fmt.Sprintf( + "cmd -c %s --cert=/ssl.cert --key /ssl.key --status-file=/tunasync.json --db-file=/tunasync.db", + tmpfile.Name(), + ) + args := strings.Split(cmd, " ") + app.Run(args) + }) + }) + }) +}