Commit ebbfc529 by bergquist

datasource as cfg: support globbing

parent 0f136a94
# purge data source not listed in configuration.
# not recommended in HA setups if config can
# can differ between instances.
purge_other_datasources: false
# list of datasources to insert/update depending # list of datasources to insert/update depending
# whats available in the datbase # whats available in the datbase
datasources: datasources:
...@@ -42,9 +37,6 @@ datasources: ...@@ -42,9 +37,6 @@ datasources:
# # <bool> allow users to edit datasources from the UI. # # <bool> allow users to edit datasources from the UI.
# editable: true # editable: true
delete_datasources:
# - name: Prometheus # - name: Graphite
# type: prometheus # org_id: 1
# access: proxy
# url: http://localhost:9090
...@@ -12,17 +12,17 @@ instance_name = ${HOSTNAME} ...@@ -12,17 +12,17 @@ instance_name = ${HOSTNAME}
#################################### Paths ############################### #################################### Paths ###############################
[paths] [paths]
# Path to where grafana can store temp files, sessions, and the sqlite3 db (if that is used) # Path to where grafana can store temp files, sessions, and the sqlite3 db (if that is used)
#
data = data data = data
#
# Directory where grafana can store logs # Directory where grafana can store logs
#
logs = data/log logs = data/log
#
# Directory where grafana will automatically scan and look for plugins # Directory where grafana will automatically scan and look for plugins
#
plugins = data/plugins plugins = data/plugins
# Config files containing datasources that will be configured at startup
datasources = conf/datasources
#################################### Server ############################## #################################### Server ##############################
[server] [server]
# Protocol (http, https, socket) # Protocol (http, https, socket)
......
...@@ -12,18 +12,17 @@ ...@@ -12,18 +12,17 @@
#################################### Paths #################################### #################################### Paths ####################################
[paths] [paths]
# Path to where grafana can store temp files, sessions, and the sqlite3 db (if that is used) # Path to where grafana can store temp files, sessions, and the sqlite3 db (if that is used)
#
;data = /var/lib/grafana ;data = /var/lib/grafana
#
# Directory where grafana can store logs # Directory where grafana can store logs
#
;logs = /var/log/grafana ;logs = /var/log/grafana
#
# Directory where grafana will automatically scan and look for plugins # Directory where grafana will automatically scan and look for plugins
#
;plugins = /var/lib/grafana/plugins ;plugins = /var/lib/grafana/plugins
# # Config files containing datasources that will be configured at startup
;datasources = conf/datasources
#################################### Server #################################### #################################### Server ####################################
[server] [server]
# Protocol (http, https, socket) # Protocol (http, https, socket)
......
...@@ -66,7 +66,8 @@ func (g *GrafanaServerImpl) Start() { ...@@ -66,7 +66,8 @@ func (g *GrafanaServerImpl) Start() {
social.NewOAuthService() social.NewOAuthService()
plugins.Init() plugins.Init()
if err := provisioning.StartUp(setting.HomePath); err != nil { //if err := provisioning.StartUp(setting.HomePath); err != nil {
if err := provisioning.StartUp(setting.DatasourcesPath); err != nil {
logger.Error("Failed to provision Grafana from config", "error", err) logger.Error("Failed to provision Grafana from config", "error", err)
g.Shutdown(1, "Startup failed") g.Shutdown(1, "Startup failed")
return return
......
...@@ -146,11 +146,15 @@ type UpdateDataSourceCommand struct { ...@@ -146,11 +146,15 @@ type UpdateDataSourceCommand struct {
type DeleteDataSourceByIdCommand struct { type DeleteDataSourceByIdCommand struct {
Id int64 Id int64
OrgId int64 OrgId int64
DeletedDatasourcesCount int64
} }
type DeleteDataSourceByNameCommand struct { type DeleteDataSourceByNameCommand struct {
Name string Name string
OrgId int64 OrgId int64
DeletedDatasourcesCount int64
} }
// --------------------- // ---------------------
......
...@@ -4,6 +4,7 @@ import ( ...@@ -4,6 +4,7 @@ import (
"errors" "errors"
"io/ioutil" "io/ioutil"
"path/filepath" "path/filepath"
"strings"
"github.com/grafana/grafana/pkg/bus" "github.com/grafana/grafana/pkg/bus"
...@@ -17,67 +18,36 @@ var ( ...@@ -17,67 +18,36 @@ var (
ErrInvalidConfigToManyDefault = errors.New("datasource.yaml config is invalid. Only one datasource can be marked as default") ErrInvalidConfigToManyDefault = errors.New("datasource.yaml config is invalid. Only one datasource can be marked as default")
) )
func Apply(configPath string) error { func Provision(configDirectory string) error {
dc := NewDatasourceConfiguration() dc := newDatasourceProvisioner(log.New("provisioning.datasources"))
return dc.applyChanges(configPath) return dc.applyChanges(configDirectory)
} }
type DatasourceConfigurator struct { type DatasourceProvisioner struct {
log log.Logger log log.Logger
cfgProvider configProvider cfgProvider configReader
} }
func NewDatasourceConfiguration() DatasourceConfigurator { func newDatasourceProvisioner(log log.Logger) DatasourceProvisioner {
return newDatasourceConfiguration(log.New("setting.datasource")) return DatasourceProvisioner{
}
func newDatasourceConfiguration(log log.Logger) DatasourceConfigurator {
return DatasourceConfigurator{
log: log, log: log,
cfgProvider: configProvider{}, cfgProvider: configReader{},
} }
} }
func (dc *DatasourceConfigurator) applyChanges(configPath string) error { func (dc *DatasourceProvisioner) apply(cfg *DatasourcesAsConfig) error {
cfg, err := dc.cfgProvider.readConfig(configPath) if err := dc.deleteDatasources(cfg.DeleteDatasources); err != nil {
if err != nil {
return err
}
defaultCount := 0
for i := range cfg.Datasources {
if cfg.Datasources[i].OrgId == 0 {
cfg.Datasources[i].OrgId = 1
}
if cfg.Datasources[i].IsDefault {
defaultCount++
if defaultCount > 1 {
return ErrInvalidConfigToManyDefault
}
}
}
cmd := &models.GetAllDataSourcesQuery{}
if err = bus.Dispatch(cmd); err != nil {
return err
}
allDatasources := cmd.Result
if err := dc.deleteDatasourcesNotInConfiguration(cfg, allDatasources); err != nil {
return err return err
} }
for _, ds := range cfg.Datasources { for _, ds := range cfg.Datasources {
var dbDatasource *models.DataSource cmd := &models.GetDataSourceByNameQuery{OrgId: ds.OrgId, Name: ds.Name}
for _, ddd := range allDatasources { err := bus.Dispatch(cmd)
if ddd.Name == ds.Name && ddd.OrgId == ds.OrgId { if err != nil && err != models.ErrDataSourceNotFound {
dbDatasource = ddd return err
break
}
} }
if dbDatasource == nil { if err == models.ErrDataSourceNotFound {
dc.log.Info("inserting datasource from configuration ", "name", ds.Name) dc.log.Info("inserting datasource from configuration ", "name", ds.Name)
insertCmd := createInsertCommand(ds) insertCmd := createInsertCommand(ds)
if err := bus.Dispatch(insertCmd); err != nil { if err := bus.Dispatch(insertCmd); err != nil {
...@@ -85,7 +55,7 @@ func (dc *DatasourceConfigurator) applyChanges(configPath string) error { ...@@ -85,7 +55,7 @@ func (dc *DatasourceConfigurator) applyChanges(configPath string) error {
} }
} else { } else {
dc.log.Debug("updating datasource from configuration", "name", ds.Name) dc.log.Debug("updating datasource from configuration", "name", ds.Name)
updateCmd := createUpdateCommand(ds, dbDatasource.Id) updateCmd := createUpdateCommand(ds, cmd.Result.Id)
if err := bus.Dispatch(updateCmd); err != nil { if err := bus.Dispatch(updateCmd); err != nil {
return err return err
} }
...@@ -95,44 +65,83 @@ func (dc *DatasourceConfigurator) applyChanges(configPath string) error { ...@@ -95,44 +65,83 @@ func (dc *DatasourceConfigurator) applyChanges(configPath string) error {
return nil return nil
} }
func (dc *DatasourceConfigurator) deleteDatasourcesNotInConfiguration(cfg *DatasourcesAsConfig, allDatasources []*models.DataSource) error { func (dc *DatasourceProvisioner) applyChanges(configPath string) error {
if cfg.PurgeOtherDatasources { configs, err := dc.cfgProvider.readConfig(configPath)
for _, dbDS := range allDatasources { if err != nil {
delete := true return err
for _, cfgDS := range cfg.Datasources { }
if dbDS.Name == cfgDS.Name && dbDS.OrgId == cfgDS.OrgId {
delete = false
}
}
if delete { for _, cfg := range configs {
dc.log.Info("deleting datasource from configuration", "name", dbDS.Name) if err := dc.apply(cfg); err != nil {
cmd := &models.DeleteDataSourceByIdCommand{Id: dbDS.Id, OrgId: dbDS.OrgId} return err
if err := bus.Dispatch(cmd); err != nil {
return err
}
}
} }
} }
return nil return nil
} }
type configProvider struct{} func (dc *DatasourceProvisioner) deleteDatasources(dsToDelete []*DeleteDatasourceConfig) error {
for _, ds := range dsToDelete {
cmd := &models.DeleteDataSourceByNameCommand{OrgId: ds.OrgId, Name: ds.Name}
if err := bus.Dispatch(cmd); err != nil {
return err
}
if cmd.DeletedDatasourcesCount > 0 {
dc.log.Info("deleted datasource based on configuration", "name", ds.Name)
}
}
return nil
}
func (configProvider) readConfig(path string) (*DatasourcesAsConfig, error) { type configReader struct{}
filename, _ := filepath.Abs(path)
yamlFile, err := ioutil.ReadFile(filename)
func (configReader) readConfig(path string) ([]*DatasourcesAsConfig, error) {
files, err := ioutil.ReadDir(path)
if err != nil { if err != nil {
return nil, err return nil, err
} }
var datasources *DatasourcesAsConfig var datasources []*DatasourcesAsConfig
for _, file := range files {
if strings.HasSuffix(file.Name(), ".yaml") || strings.HasSuffix(file.Name(), ".yml") {
filename, _ := filepath.Abs(filepath.Join(path, file.Name()))
yamlFile, err := ioutil.ReadFile(filename)
err = yaml.Unmarshal(yamlFile, &datasources) if err != nil {
if err != nil { return nil, err
return nil, err }
var datasource *DatasourcesAsConfig
err = yaml.Unmarshal(yamlFile, &datasource)
if err != nil {
return nil, err
}
datasources = append(datasources, datasource)
}
}
defaultCount := 0
for _, cfg := range datasources {
for _, ds := range cfg.Datasources {
if ds.OrgId == 0 {
ds.OrgId = 1
}
if ds.IsDefault {
defaultCount++
if defaultCount > 1 {
return nil, ErrInvalidConfigToManyDefault
}
}
}
for _, ds := range cfg.DeleteDatasources {
if ds.OrgId == 0 {
ds.OrgId = 1
}
}
} }
return datasources, nil return datasources, nil
......
...@@ -13,10 +13,11 @@ import ( ...@@ -13,10 +13,11 @@ import (
var ( var (
logger log.Logger = log.New("fake.logger") logger log.Logger = log.New("fake.logger")
oneDatasourcesConfig string = "" oneDatasourcesConfig string = ""
twoDatasourcesConfig string = "./test-configs/two-datasources.yaml" twoDatasourcesConfig string = "./test-configs/two-datasources"
twoDatasourcesConfigPurgeOthers string = "./test-configs/two-datasources-purge-others.yaml" twoDatasourcesConfigPurgeOthers string = "./test-configs/insert-two-delete-two"
doubleDatasourcesConfig string = "./test-configs/double-default-datasources.yaml" doubleDatasourcesConfig string = "./test-configs/double-default"
allProperties string = "./test-configs/all-properties.yaml" allProperties string = "./test-configs/all-properties"
brokenYaml string = "./test-configs/broken-yaml"
fakeRepo *fakeRepository fakeRepo *fakeRepository
) )
...@@ -33,7 +34,7 @@ func TestDatasourceAsConfig(t *testing.T) { ...@@ -33,7 +34,7 @@ func TestDatasourceAsConfig(t *testing.T) {
Convey("One configured datasource", func() { Convey("One configured datasource", func() {
Convey("no datasource in database", func() { Convey("no datasource in database", func() {
dc := newDatasourceConfiguration(logger) dc := newDatasourceProvisioner(logger)
err := dc.applyChanges(twoDatasourcesConfig) err := dc.applyChanges(twoDatasourcesConfig)
if err != nil { if err != nil {
t.Fatalf("applyChanges return an error %v", err) t.Fatalf("applyChanges return an error %v", err)
...@@ -50,7 +51,7 @@ func TestDatasourceAsConfig(t *testing.T) { ...@@ -50,7 +51,7 @@ func TestDatasourceAsConfig(t *testing.T) {
} }
Convey("should update one datasource", func() { Convey("should update one datasource", func() {
dc := newDatasourceConfiguration(logger) dc := newDatasourceProvisioner(logger)
err := dc.applyChanges(twoDatasourcesConfig) err := dc.applyChanges(twoDatasourcesConfig)
if err != nil { if err != nil {
t.Fatalf("applyChanges return an error %v", err) t.Fatalf("applyChanges return an error %v", err)
...@@ -63,7 +64,7 @@ func TestDatasourceAsConfig(t *testing.T) { ...@@ -63,7 +64,7 @@ func TestDatasourceAsConfig(t *testing.T) {
}) })
Convey("Two datasources with is_default", func() { Convey("Two datasources with is_default", func() {
dc := newDatasourceConfiguration(logger) dc := newDatasourceProvisioner(logger)
err := dc.applyChanges(doubleDatasourcesConfig) err := dc.applyChanges(doubleDatasourcesConfig)
Convey("should raise error", func() { Convey("should raise error", func() {
So(err, ShouldEqual, ErrInvalidConfigToManyDefault) So(err, ShouldEqual, ErrInvalidConfigToManyDefault)
...@@ -79,7 +80,7 @@ func TestDatasourceAsConfig(t *testing.T) { ...@@ -79,7 +80,7 @@ func TestDatasourceAsConfig(t *testing.T) {
} }
Convey("should have two new datasources", func() { Convey("should have two new datasources", func() {
dc := newDatasourceConfiguration(logger) dc := newDatasourceProvisioner(logger)
err := dc.applyChanges(twoDatasourcesConfigPurgeOthers) err := dc.applyChanges(twoDatasourcesConfigPurgeOthers)
if err != nil { if err != nil {
t.Fatalf("applyChanges return an error %v", err) t.Fatalf("applyChanges return an error %v", err)
...@@ -100,7 +101,7 @@ func TestDatasourceAsConfig(t *testing.T) { ...@@ -100,7 +101,7 @@ func TestDatasourceAsConfig(t *testing.T) {
} }
Convey("should have two new datasources", func() { Convey("should have two new datasources", func() {
dc := newDatasourceConfiguration(logger) dc := newDatasourceProvisioner(logger)
err := dc.applyChanges(twoDatasourcesConfig) err := dc.applyChanges(twoDatasourcesConfig)
if err != nil { if err != nil {
t.Fatalf("applyChanges return an error %v", err) t.Fatalf("applyChanges return an error %v", err)
...@@ -113,16 +114,22 @@ func TestDatasourceAsConfig(t *testing.T) { ...@@ -113,16 +114,22 @@ func TestDatasourceAsConfig(t *testing.T) {
}) })
}) })
Convey("can read all properties", func() { Convey("broken yaml should return error", func() {
_, err := configReader{}.readConfig(brokenYaml)
So(err, ShouldNotBeNil)
})
cfgProvifer := configProvider{} Convey("can read all properties", func() {
cfgProvifer := configReader{}
cfg, err := cfgProvifer.readConfig(allProperties) cfg, err := cfgProvifer.readConfig(allProperties)
if err != nil { if err != nil {
t.Fatalf("readConfig return an error %v", err) t.Fatalf("readConfig return an error %v", err)
} }
So(cfg.PurgeOtherDatasources, ShouldBeTrue) So(len(cfg), ShouldEqual, 2)
ds := cfg.Datasources[0]
dsCfg := cfg[0]
ds := dsCfg.Datasources[0]
So(ds.Name, ShouldEqual, "name") So(ds.Name, ShouldEqual, "name")
So(ds.Type, ShouldEqual, "type") So(ds.Type, ShouldEqual, "type")
...@@ -138,19 +145,22 @@ func TestDatasourceAsConfig(t *testing.T) { ...@@ -138,19 +145,22 @@ func TestDatasourceAsConfig(t *testing.T) {
So(ds.WithCredentials, ShouldBeTrue) So(ds.WithCredentials, ShouldBeTrue)
So(ds.IsDefault, ShouldBeTrue) So(ds.IsDefault, ShouldBeTrue)
So(ds.Editable, ShouldBeTrue) So(ds.Editable, ShouldBeTrue)
dstwo := cfg[1].Datasources[0]
So(dstwo.Name, ShouldEqual, "name2")
}) })
}) })
} }
type fakeRepository struct { type fakeRepository struct {
inserted []*models.AddDataSourceCommand inserted []*models.AddDataSourceCommand
deleted []*models.DeleteDataSourceByIdCommand deleted []*models.DeleteDataSourceByNameCommand
updated []*models.UpdateDataSourceCommand updated []*models.UpdateDataSourceCommand
loadAll []*models.DataSource loadAll []*models.DataSource
} }
func mockDelete(cmd *models.DeleteDataSourceByIdCommand) error { func mockDelete(cmd *models.DeleteDataSourceByNameCommand) error {
fakeRepo.deleted = append(fakeRepo.deleted, cmd) fakeRepo.deleted = append(fakeRepo.deleted, cmd)
return nil return nil
} }
......
purge_other_datasources: true
datasources:
- name: name2
type: type2
access: proxy
org_id: 2
url: url2
#sfxzgnsxzcvnbzcvn
cvbn
cvbn
c
vbn
cvbncvbn
\ No newline at end of file
purge_other_datasources: false
datasources: datasources:
- name: Graphite - name: Graphite
type: graphite type: graphite
access: proxy access: proxy
url: http://localhost:8080 url: http://localhost:8080
is_default: true is_default: true
- name: Prometheus
type: prometheus
access: proxy
url: http://localhost:9090
is_default: true
purge_other_datasources: false
datasources: datasources:
- name: Graphite - name: Graphite
type: graphite type: graphite
access: proxy access: proxy
url: http://localhost:8080 url: http://localhost:8080
- name: Prometheus is_default: true
type: prometheus
access: proxy
url: http://localhost:9090
datasources:
- name: Prometheus
type: prometheus
access: proxy
url: http://localhost:9090
delete_datasources:
- name: old-graphite
datasources:
- name: Graphite
type: graphite
access: proxy
url: http://localhost:8080
delete_datasources:
- name: old-graphite3
...@@ -4,8 +4,13 @@ import "github.com/grafana/grafana/pkg/models" ...@@ -4,8 +4,13 @@ import "github.com/grafana/grafana/pkg/models"
import "github.com/grafana/grafana/pkg/components/simplejson" import "github.com/grafana/grafana/pkg/components/simplejson"
type DatasourcesAsConfig struct { type DatasourcesAsConfig struct {
PurgeOtherDatasources bool `json:"purge_other_datasources" yaml:"purge_other_datasources"` Datasources []*DataSourceFromConfig `json:"datasources" yaml:"datasources"`
Datasources []DataSourceFromConfig `json:"datasources" yaml:"datasources"` DeleteDatasources []*DeleteDatasourceConfig `json:"delete_datasources" yaml:"delete_datasources"`
}
type DeleteDatasourceConfig struct {
OrgId int64 `json:"org_id" yaml:"org_id"`
Name string `json:"name" yaml:"name"`
} }
type DataSourceFromConfig struct { type DataSourceFromConfig struct {
...@@ -29,7 +34,7 @@ type DataSourceFromConfig struct { ...@@ -29,7 +34,7 @@ type DataSourceFromConfig struct {
Editable bool `json:"editable" yaml:"editable"` Editable bool `json:"editable" yaml:"editable"`
} }
func createInsertCommand(ds DataSourceFromConfig) *models.AddDataSourceCommand { func createInsertCommand(ds *DataSourceFromConfig) *models.AddDataSourceCommand {
jsonData, err := simplejson.NewJson([]byte(ds.JsonData)) jsonData, err := simplejson.NewJson([]byte(ds.JsonData))
if err != nil { if err != nil {
jsonData = simplejson.New() jsonData = simplejson.New()
...@@ -55,7 +60,7 @@ func createInsertCommand(ds DataSourceFromConfig) *models.AddDataSourceCommand { ...@@ -55,7 +60,7 @@ func createInsertCommand(ds DataSourceFromConfig) *models.AddDataSourceCommand {
} }
} }
func createUpdateCommand(ds DataSourceFromConfig, id int64) *models.UpdateDataSourceCommand { func createUpdateCommand(ds *DataSourceFromConfig, id int64) *models.UpdateDataSourceCommand {
jsonData, err := simplejson.NewJson([]byte(ds.JsonData)) jsonData, err := simplejson.NewJson([]byte(ds.JsonData))
if err != nil { if err != nil {
jsonData = simplejson.New() jsonData = simplejson.New()
......
package provisioning package provisioning
import ( import (
"path/filepath"
"github.com/grafana/grafana/pkg/log" "github.com/grafana/grafana/pkg/log"
"github.com/grafana/grafana/pkg/services/provisioning/datasources" "github.com/grafana/grafana/pkg/services/provisioning/datasources"
) )
...@@ -11,6 +9,6 @@ var ( ...@@ -11,6 +9,6 @@ var (
logger log.Logger = log.New("services.provisioning") logger log.Logger = log.New("services.provisioning")
) )
func StartUp(homePath string) error { func StartUp(datasourcePath string) error {
return datasources.Apply(filepath.Join(homePath, "conf/datasources.yaml")) return datasources.Provision(datasourcePath)
} }
...@@ -65,7 +65,9 @@ func GetAllDataSources(query *m.GetAllDataSourcesQuery) error { ...@@ -65,7 +65,9 @@ func GetAllDataSources(query *m.GetAllDataSourcesQuery) error {
func DeleteDataSourceById(cmd *m.DeleteDataSourceByIdCommand) error { func DeleteDataSourceById(cmd *m.DeleteDataSourceByIdCommand) error {
return inTransaction(func(sess *DBSession) error { return inTransaction(func(sess *DBSession) error {
var rawSql = "DELETE FROM data_source WHERE id=? and org_id=?" var rawSql = "DELETE FROM data_source WHERE id=? and org_id=?"
_, err := sess.Exec(rawSql, cmd.Id, cmd.OrgId) result, err := sess.Exec(rawSql, cmd.Id, cmd.OrgId)
affected, _ := result.RowsAffected()
cmd.DeletedDatasourcesCount = affected
return err return err
}) })
} }
...@@ -73,7 +75,9 @@ func DeleteDataSourceById(cmd *m.DeleteDataSourceByIdCommand) error { ...@@ -73,7 +75,9 @@ func DeleteDataSourceById(cmd *m.DeleteDataSourceByIdCommand) error {
func DeleteDataSourceByName(cmd *m.DeleteDataSourceByNameCommand) error { func DeleteDataSourceByName(cmd *m.DeleteDataSourceByNameCommand) error {
return inTransaction(func(sess *DBSession) error { return inTransaction(func(sess *DBSession) error {
var rawSql = "DELETE FROM data_source WHERE name=? and org_id=?" var rawSql = "DELETE FROM data_source WHERE name=? and org_id=?"
_, err := sess.Exec(rawSql, cmd.Name, cmd.OrgId) result, err := sess.Exec(rawSql, cmd.Name, cmd.OrgId)
affected, _ := result.RowsAffected()
cmd.DeletedDatasourcesCount = affected
return err return err
}) })
} }
......
...@@ -50,11 +50,12 @@ var ( ...@@ -50,11 +50,12 @@ var (
BuildStamp int64 BuildStamp int64
// Paths // Paths
LogsPath string LogsPath string
HomePath string HomePath string
DataPath string DataPath string
PluginsPath string PluginsPath string
CustomInitPath = "conf/custom.ini" DatasourcesPath string
CustomInitPath = "conf/custom.ini"
// Log settings. // Log settings.
LogModes []string LogModes []string
...@@ -470,6 +471,7 @@ func NewConfigContext(args *CommandLineArgs) error { ...@@ -470,6 +471,7 @@ func NewConfigContext(args *CommandLineArgs) error {
Env = Cfg.Section("").Key("app_mode").MustString("development") Env = Cfg.Section("").Key("app_mode").MustString("development")
InstanceName = Cfg.Section("").Key("instance_name").MustString("unknown_instance_name") InstanceName = Cfg.Section("").Key("instance_name").MustString("unknown_instance_name")
PluginsPath = makeAbsolute(Cfg.Section("paths").Key("plugins").String(), HomePath) PluginsPath = makeAbsolute(Cfg.Section("paths").Key("plugins").String(), HomePath)
DatasourcesPath = makeAbsolute(Cfg.Section("paths").Key("datasources").String(), HomePath)
server := Cfg.Section("server") server := Cfg.Section("server")
AppUrl, AppSubUrl = parseAppUrlAndSubUrl(server) AppUrl, AppSubUrl = parseAppUrlAndSubUrl(server)
...@@ -661,5 +663,6 @@ func LogConfigurationInfo() { ...@@ -661,5 +663,6 @@ func LogConfigurationInfo() {
logger.Info("Path Data", "path", DataPath) logger.Info("Path Data", "path", DataPath)
logger.Info("Path Logs", "path", LogsPath) logger.Info("Path Logs", "path", LogsPath)
logger.Info("Path Plugins", "path", PluginsPath) logger.Info("Path Plugins", "path", PluginsPath)
logger.Info("Path Datasources", "path", DatasourcesPath)
logger.Info("App mode " + Env) logger.Info("App mode " + Env)
} }
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment