PluginManager: Remove some global state (#31081)

* PluginManager: Remove global state

Signed-off-by: Arve Knudsen <arve.knudsen@gmail.com>
This commit is contained in:
Arve Knudsen
2021-02-10 13:31:47 +01:00
committed by GitHub
parent cff6f5fec3
commit b99127be82
8 changed files with 79 additions and 106 deletions

View File

@ -224,8 +224,8 @@ func (hs *HTTPServer) getFrontendSettingsMap(c *models.ReqContext) (map[string]i
"commit": commit, "commit": commit,
"buildstamp": buildstamp, "buildstamp": buildstamp,
"edition": hs.License.Edition(), "edition": hs.License.Edition(),
"latestVersion": plugins.GrafanaLatestVersion, "latestVersion": hs.PluginManager.GrafanaLatestVersion,
"hasUpdate": plugins.GrafanaHasUpdate, "hasUpdate": hs.PluginManager.GrafanaHasUpdate,
"env": setting.Env, "env": setting.Env,
"isEnterprise": hs.License.HasValidLicense(), "isEnterprise": hs.License.HasValidLicense(),
}, },

View File

@ -11,6 +11,7 @@ import (
"github.com/stretchr/testify/require" "github.com/stretchr/testify/require"
"github.com/grafana/grafana/pkg/plugins"
"github.com/grafana/grafana/pkg/services/rendering" "github.com/grafana/grafana/pkg/services/rendering"
"github.com/grafana/grafana/pkg/services/licensing" "github.com/grafana/grafana/pkg/services/licensing"
@ -47,8 +48,9 @@ func setupTestEnvironment(t *testing.T, cfg *setting.Cfg) (*macaron.Macaron, *HT
hs := &HTTPServer{ hs := &HTTPServer{
Cfg: cfg, Cfg: cfg,
Bus: bus.GetBus(), Bus: bus.GetBus(),
License: &licensing.OSSLicensingService{}, License: &licensing.OSSLicensingService{Cfg: cfg},
RenderService: r, RenderService: r,
PluginManager: &plugins.PluginManager{Cfg: cfg},
} }
m := macaron.New() m := macaron.New()
@ -74,13 +76,17 @@ func TestHTTPServer_GetFrontendSettings_hideVersionAnonyomus(t *testing.T) {
} }
cfg := setting.NewCfg() cfg := setting.NewCfg()
cfg.Env = "testing"
cfg.BuildVersion = "7.8.9"
cfg.BuildCommit = "01234567"
m, hs := setupTestEnvironment(t, cfg) m, hs := setupTestEnvironment(t, cfg)
req := httptest.NewRequest(http.MethodGet, "/api/frontend/settings", nil) req := httptest.NewRequest(http.MethodGet, "/api/frontend/settings", nil)
setting.BuildVersion = "7.8.9" // TODO: Remove
setting.BuildCommit = "01234567" setting.BuildVersion = cfg.BuildVersion
setting.Env = "testing" setting.BuildCommit = cfg.BuildCommit
setting.Env = cfg.Env
tests := []struct { tests := []struct {
desc string desc string

View File

@ -408,8 +408,8 @@ func (hs *HTTPServer) setIndexViewData(c *models.ReqContext) (*dtos.IndexViewDat
GoogleTagManagerId: setting.GoogleTagManagerId, GoogleTagManagerId: setting.GoogleTagManagerId,
BuildVersion: setting.BuildVersion, BuildVersion: setting.BuildVersion,
BuildCommit: setting.BuildCommit, BuildCommit: setting.BuildCommit,
NewGrafanaVersion: plugins.GrafanaLatestVersion, NewGrafanaVersion: hs.PluginManager.GrafanaLatestVersion,
NewGrafanaVersionExists: plugins.GrafanaHasUpdate, NewGrafanaVersionExists: hs.PluginManager.GrafanaHasUpdate,
AppName: setting.ApplicationName, AppName: setting.ApplicationName,
AppNameBodyClass: getAppNameBodyClass(hs.License.HasValidLicense()), AppNameBodyClass: getAppNameBodyClass(hs.License.HasValidLicense()),
FavIcon: "public/img/fav32.png", FavIcon: "public/img/fav32.png",

View File

@ -368,7 +368,7 @@ func (hs *HTTPServer) getCachedPluginSettings(pluginID string, user *models.Sign
} }
func (hs *HTTPServer) GetPluginErrorsList(c *models.ReqContext) response.Response { func (hs *HTTPServer) GetPluginErrorsList(c *models.ReqContext) response.Response {
return response.JSON(200, plugins.ScanningErrors()) return response.JSON(200, hs.PluginManager.ScanningErrors())
} }
func translatePluginRequestErrorToAPIError(err error) response.Response { func translatePluginRequestErrorToAPIError(err error) response.Response {

View File

@ -32,11 +32,7 @@ var (
PluginTypes map[string]interface{} PluginTypes map[string]interface{}
Renderer *RendererPlugin Renderer *RendererPlugin
GrafanaLatestVersion string plog log.Logger
GrafanaHasUpdate bool
plog log.Logger
pluginScanningErrors map[string]*PluginError
) )
type unsignedPluginConditionFunc = func(plugin *PluginBase) bool type unsignedPluginConditionFunc = func(plugin *PluginBase) bool
@ -61,6 +57,9 @@ type PluginManager struct {
// AllowUnsignedPluginsCondition changes the policy for allowing unsigned plugins. Signature validation only runs when plugins are starting // AllowUnsignedPluginsCondition changes the policy for allowing unsigned plugins. Signature validation only runs when plugins are starting
// and running plugins will not be terminated if they violate the new policy. // and running plugins will not be terminated if they violate the new policy.
AllowUnsignedPluginsCondition unsignedPluginConditionFunc AllowUnsignedPluginsCondition unsignedPluginConditionFunc
GrafanaLatestVersion string
GrafanaHasUpdate bool
pluginScanningErrors map[string]PluginError
} }
func init() { func init() {
@ -82,11 +81,11 @@ func (pm *PluginManager) Init() error {
"app": AppPlugin{}, "app": AppPlugin{},
"renderer": RendererPlugin{}, "renderer": RendererPlugin{},
} }
pluginScanningErrors = map[string]*PluginError{} pm.pluginScanningErrors = map[string]PluginError{}
pm.log.Info("Starting plugin search") pm.log.Info("Starting plugin search")
plugDir := filepath.Join(setting.StaticRootPath, "app/plugins") plugDir := filepath.Join(pm.Cfg.StaticRootPath, "app/plugins")
pm.log.Debug("Scanning core plugin directory", "dir", plugDir) pm.log.Debug("Scanning core plugin directory", "dir", plugDir)
if err := pm.scan(plugDir, false); err != nil { if err := pm.scan(plugDir, false); err != nil {
return errutil.Wrapf(err, "failed to scan core plugin directory '%s'", plugDir) return errutil.Wrapf(err, "failed to scan core plugin directory '%s'", plugDir)
@ -105,21 +104,21 @@ func (pm *PluginManager) Init() error {
} }
// check if plugins dir exists // check if plugins dir exists
exists, err = fs.Exists(setting.PluginsPath) exists, err = fs.Exists(pm.Cfg.PluginsPath)
if err != nil { if err != nil {
return err return err
} }
if !exists { if !exists {
if err = os.MkdirAll(setting.PluginsPath, os.ModePerm); err != nil { if err = os.MkdirAll(pm.Cfg.PluginsPath, os.ModePerm); err != nil {
pm.log.Error("failed to create external plugins directory", "dir", setting.PluginsPath, "error", err) pm.log.Error("failed to create external plugins directory", "dir", pm.Cfg.PluginsPath, "error", err)
} else { } else {
pm.log.Info("External plugins directory created", "directory", setting.PluginsPath) pm.log.Info("External plugins directory created", "directory", pm.Cfg.PluginsPath)
} }
} else { } else {
pm.log.Debug("Scanning external plugins directory", "dir", setting.PluginsPath) pm.log.Debug("Scanning external plugins directory", "dir", pm.Cfg.PluginsPath)
if err := pm.scan(setting.PluginsPath, true); err != nil { if err := pm.scan(pm.Cfg.PluginsPath, true); err != nil {
return errutil.Wrapf(err, "failed to scan external plugins directory '%s'", return errutil.Wrapf(err, "failed to scan external plugins directory '%s'",
setting.PluginsPath) pm.Cfg.PluginsPath)
} }
} }
@ -241,7 +240,7 @@ func (pm *PluginManager) scan(pluginDir string, requireSigned bool) error {
if signingError != nil { if signingError != nil {
pm.log.Debug("Failed to validate plugin signature. Will skip loading", "id", plugin.Id, pm.log.Debug("Failed to validate plugin signature. Will skip loading", "id", plugin.Id,
"signature", plugin.Signature, "status", signingError.ErrorCode) "signature", plugin.Signature, "status", signingError.ErrorCode)
pluginScanningErrors[plugin.Id] = signingError pm.pluginScanningErrors[plugin.Id] = *signingError
continue continue
} }
@ -255,7 +254,7 @@ func (pm *PluginManager) scan(pluginDir string, requireSigned bool) error {
jsonFPath := filepath.Join(plugin.PluginDir, "plugin.json") jsonFPath := filepath.Join(plugin.PluginDir, "plugin.json")
// External plugins need a module.js file for SystemJS to load // External plugins need a module.js file for SystemJS to load
if !strings.HasPrefix(jsonFPath, setting.StaticRootPath) && !scanner.IsBackendOnlyPlugin(plugin.Type) { if !strings.HasPrefix(jsonFPath, pm.Cfg.StaticRootPath) && !scanner.IsBackendOnlyPlugin(plugin.Type) {
module := filepath.Join(plugin.PluginDir, "module.js") module := filepath.Join(plugin.PluginDir, "module.js")
exists, err := fs.Exists(module) exists, err := fs.Exists(module)
if err != nil { if err != nil {
@ -460,7 +459,7 @@ func (s *PluginScanner) allowUnsigned(plugin *PluginBase) bool {
return s.allowUnsignedPluginsCondition(plugin) return s.allowUnsignedPluginsCondition(plugin)
} }
if setting.Env == setting.Dev { if s.cfg.Env == setting.Dev {
return true return true
} }
@ -473,9 +472,10 @@ func (s *PluginScanner) allowUnsigned(plugin *PluginBase) bool {
return false return false
} }
func ScanningErrors() []PluginError { // ScanningErrors returns plugin scanning errors encountered.
func (pm *PluginManager) ScanningErrors() []PluginError {
scanningErrs := make([]PluginError, 0) scanningErrs := make([]PluginError, 0)
for id, e := range pluginScanningErrors { for id, e := range pm.pluginScanningErrors {
scanningErrs = append(scanningErrs, PluginError{ scanningErrs = append(scanningErrs, PluginError{
ErrorCode: e.ErrorCode, ErrorCode: e.ErrorCode,
PluginID: id, PluginID: id,

View File

@ -17,6 +17,9 @@ import (
) )
func TestPluginManager_Init(t *testing.T) { func TestPluginManager_Init(t *testing.T) {
staticRootPath, err := filepath.Abs("../../public/")
require.NoError(t, err)
origRootPath := setting.StaticRootPath origRootPath := setting.StaticRootPath
origRaw := setting.Raw origRaw := setting.Raw
origEnv := setting.Env origEnv := setting.Env
@ -25,16 +28,16 @@ func TestPluginManager_Init(t *testing.T) {
setting.Raw = origRaw setting.Raw = origRaw
setting.Env = origEnv setting.Env = origEnv
}) })
setting.StaticRootPath = staticRootPath
var err error
setting.StaticRootPath, err = filepath.Abs("../../public/")
require.NoError(t, err)
setting.Raw = ini.Empty() setting.Raw = ini.Empty()
setting.Env = setting.Prod setting.Env = setting.Prod
t.Run("Base case", func(t *testing.T) { t.Run("Base case", func(t *testing.T) {
pm := &PluginManager{ pm := &PluginManager{
Cfg: &setting.Cfg{ Cfg: &setting.Cfg{
Raw: ini.Empty(),
Env: setting.Prod,
StaticRootPath: staticRootPath,
PluginSettings: setting.PluginSettings{ PluginSettings: setting.PluginSettings{
"nginx-app": map[string]string{ "nginx-app": map[string]string{
"path": "testdata/test-app", "path": "testdata/test-app",
@ -55,14 +58,8 @@ func TestPluginManager_Init(t *testing.T) {
}) })
t.Run("With external back-end plugin lacking signature", func(t *testing.T) { t.Run("With external back-end plugin lacking signature", func(t *testing.T) {
origPluginsPath := setting.PluginsPath
t.Cleanup(func() {
setting.PluginsPath = origPluginsPath
})
setting.PluginsPath = "testdata/unsigned"
pm := &PluginManager{ pm := &PluginManager{
Cfg: &setting.Cfg{}, Cfg: &setting.Cfg{PluginsPath: "testdata/unsigned"},
} }
err := pm.Init() err := pm.Init()
require.NoError(t, err) require.NoError(t, err)
@ -71,14 +68,9 @@ func TestPluginManager_Init(t *testing.T) {
}) })
t.Run("With external unsigned back-end plugin and configuration disabling signature check of this plugin", func(t *testing.T) { t.Run("With external unsigned back-end plugin and configuration disabling signature check of this plugin", func(t *testing.T) {
origPluginsPath := setting.PluginsPath
t.Cleanup(func() {
setting.PluginsPath = origPluginsPath
})
setting.PluginsPath = "testdata/unsigned"
pm := &PluginManager{ pm := &PluginManager{
Cfg: &setting.Cfg{ Cfg: &setting.Cfg{
PluginsPath: "testdata/unsigned",
PluginsAllowUnsigned: []string{"test"}, PluginsAllowUnsigned: []string{"test"},
}, },
BackendPluginManager: &fakeBackendPluginManager{}, BackendPluginManager: &fakeBackendPluginManager{},
@ -90,14 +82,10 @@ func TestPluginManager_Init(t *testing.T) {
}) })
t.Run("With external back-end plugin with invalid v1 signature", func(t *testing.T) { t.Run("With external back-end plugin with invalid v1 signature", func(t *testing.T) {
origPluginsPath := setting.PluginsPath
t.Cleanup(func() {
setting.PluginsPath = origPluginsPath
})
setting.PluginsPath = "testdata/invalid-v1-signature"
pm := &PluginManager{ pm := &PluginManager{
Cfg: &setting.Cfg{}, Cfg: &setting.Cfg{
PluginsPath: "testdata/invalid-v1-signature",
},
} }
err := pm.Init() err := pm.Init()
require.NoError(t, err) require.NoError(t, err)
@ -106,15 +94,11 @@ func TestPluginManager_Init(t *testing.T) {
}) })
t.Run("With external back-end plugin lacking files listed in manifest", func(t *testing.T) { t.Run("With external back-end plugin lacking files listed in manifest", func(t *testing.T) {
origPluginsPath := setting.PluginsPath
t.Cleanup(func() {
setting.PluginsPath = origPluginsPath
})
setting.PluginsPath = "testdata/lacking-files"
fm := &fakeBackendPluginManager{} fm := &fakeBackendPluginManager{}
pm := &PluginManager{ pm := &PluginManager{
Cfg: &setting.Cfg{}, Cfg: &setting.Cfg{
PluginsPath: "testdata/lacking-files",
},
BackendPluginManager: fm, BackendPluginManager: fm,
} }
err := pm.Init() err := pm.Init()
@ -124,15 +108,11 @@ func TestPluginManager_Init(t *testing.T) {
}) })
t.Run("Transform plugins should be ignored when expressions feature is off", func(t *testing.T) { t.Run("Transform plugins should be ignored when expressions feature is off", func(t *testing.T) {
origPluginsPath := setting.PluginsPath
t.Cleanup(func() {
setting.PluginsPath = origPluginsPath
})
setting.PluginsPath = "testdata/behind-feature-flag"
fm := fakeBackendPluginManager{} fm := fakeBackendPluginManager{}
pm := &PluginManager{ pm := &PluginManager{
Cfg: &setting.Cfg{}, Cfg: &setting.Cfg{
PluginsPath: "testdata/behind-feature-flag",
},
BackendPluginManager: &fm, BackendPluginManager: &fm,
} }
err := pm.Init() err := pm.Init()
@ -143,14 +123,10 @@ func TestPluginManager_Init(t *testing.T) {
}) })
t.Run("With nested plugin duplicating parent", func(t *testing.T) { t.Run("With nested plugin duplicating parent", func(t *testing.T) {
origPluginsPath := setting.PluginsPath
t.Cleanup(func() {
setting.PluginsPath = origPluginsPath
})
setting.PluginsPath = "testdata/duplicate-plugins"
pm := &PluginManager{ pm := &PluginManager{
Cfg: &setting.Cfg{}, Cfg: &setting.Cfg{
PluginsPath: "testdata/duplicate-plugins",
},
} }
err := pm.Init() err := pm.Init()
require.NoError(t, err) require.NoError(t, err)
@ -160,14 +136,10 @@ func TestPluginManager_Init(t *testing.T) {
}) })
t.Run("With external back-end plugin with valid v2 signature", func(t *testing.T) { t.Run("With external back-end plugin with valid v2 signature", func(t *testing.T) {
origPluginsPath := setting.PluginsPath
t.Cleanup(func() {
setting.PluginsPath = origPluginsPath
})
setting.PluginsPath = "testdata/valid-v2-signature"
pm := &PluginManager{ pm := &PluginManager{
Cfg: &setting.Cfg{}, Cfg: &setting.Cfg{
PluginsPath: "testdata/valid-v2-signature",
},
BackendPluginManager: &fakeBackendPluginManager{}, BackendPluginManager: &fakeBackendPluginManager{},
} }
err := pm.Init() err := pm.Init()
@ -188,16 +160,15 @@ func TestPluginManager_Init(t *testing.T) {
t.Run("With back-end plugin with invalid v2 private signature (mismatched root URL)", func(t *testing.T) { t.Run("With back-end plugin with invalid v2 private signature (mismatched root URL)", func(t *testing.T) {
origAppURL := setting.AppUrl origAppURL := setting.AppUrl
origPluginsPath := setting.PluginsPath
t.Cleanup(func() { t.Cleanup(func() {
setting.AppUrl = origAppURL setting.AppUrl = origAppURL
setting.PluginsPath = origPluginsPath
}) })
setting.AppUrl = "http://localhost:1234" setting.AppUrl = "http://localhost:1234"
setting.PluginsPath = "testdata/valid-v2-pvt-signature"
pm := &PluginManager{ pm := &PluginManager{
Cfg: &setting.Cfg{}, Cfg: &setting.Cfg{
PluginsPath: "testdata/valid-v2-pvt-signature",
},
} }
err := pm.Init() err := pm.Init()
require.NoError(t, err) require.NoError(t, err)
@ -208,16 +179,15 @@ func TestPluginManager_Init(t *testing.T) {
t.Run("With back-end plugin with valid v2 private signature", func(t *testing.T) { t.Run("With back-end plugin with valid v2 private signature", func(t *testing.T) {
origAppURL := setting.AppUrl origAppURL := setting.AppUrl
origPluginsPath := setting.PluginsPath
t.Cleanup(func() { t.Cleanup(func() {
setting.AppUrl = origAppURL setting.AppUrl = origAppURL
setting.PluginsPath = origPluginsPath
}) })
setting.AppUrl = "http://localhost:3000/" setting.AppUrl = "http://localhost:3000/"
setting.PluginsPath = "testdata/valid-v2-pvt-signature"
pm := &PluginManager{ pm := &PluginManager{
Cfg: &setting.Cfg{}, Cfg: &setting.Cfg{
PluginsPath: "testdata/valid-v2-pvt-signature",
},
BackendPluginManager: &fakeBackendPluginManager{}, BackendPluginManager: &fakeBackendPluginManager{},
} }
err := pm.Init() err := pm.Init()
@ -238,16 +208,15 @@ func TestPluginManager_Init(t *testing.T) {
t.Run("With back-end plugin with modified v2 signature (missing file from plugin dir)", func(t *testing.T) { t.Run("With back-end plugin with modified v2 signature (missing file from plugin dir)", func(t *testing.T) {
origAppURL := setting.AppUrl origAppURL := setting.AppUrl
origPluginsPath := setting.PluginsPath
t.Cleanup(func() { t.Cleanup(func() {
setting.AppUrl = origAppURL setting.AppUrl = origAppURL
setting.PluginsPath = origPluginsPath
}) })
setting.AppUrl = "http://localhost:3000/" setting.AppUrl = "http://localhost:3000/"
setting.PluginsPath = "testdata/invalid-v2-signature"
pm := &PluginManager{ pm := &PluginManager{
Cfg: &setting.Cfg{}, Cfg: &setting.Cfg{
PluginsPath: "testdata/invalid-v2-signature",
},
BackendPluginManager: &fakeBackendPluginManager{}, BackendPluginManager: &fakeBackendPluginManager{},
} }
err := pm.Init() err := pm.Init()
@ -258,16 +227,15 @@ func TestPluginManager_Init(t *testing.T) {
t.Run("With back-end plugin with modified v2 signature (unaccounted file in plugin dir)", func(t *testing.T) { t.Run("With back-end plugin with modified v2 signature (unaccounted file in plugin dir)", func(t *testing.T) {
origAppURL := setting.AppUrl origAppURL := setting.AppUrl
origPluginsPath := setting.PluginsPath
t.Cleanup(func() { t.Cleanup(func() {
setting.AppUrl = origAppURL setting.AppUrl = origAppURL
setting.PluginsPath = origPluginsPath
}) })
setting.AppUrl = "http://localhost:3000/" setting.AppUrl = "http://localhost:3000/"
setting.PluginsPath = "testdata/invalid-v2-signature-2"
pm := &PluginManager{ pm := &PluginManager{
Cfg: &setting.Cfg{}, Cfg: &setting.Cfg{
PluginsPath: "testdata/invalid-v2-signature-2",
},
BackendPluginManager: &fakeBackendPluginManager{}, BackendPluginManager: &fakeBackendPluginManager{},
} }
err := pm.Init() err := pm.Init()

View File

@ -112,17 +112,16 @@ func (pm *PluginManager) checkForUpdates() {
} }
if strings.Contains(setting.BuildVersion, "-") { if strings.Contains(setting.BuildVersion, "-") {
GrafanaLatestVersion = githubLatest.Testing pm.GrafanaLatestVersion = githubLatest.Testing
GrafanaHasUpdate = !strings.HasPrefix(setting.BuildVersion, githubLatest.Testing) pm.GrafanaHasUpdate = !strings.HasPrefix(setting.BuildVersion, githubLatest.Testing)
} else { } else {
GrafanaLatestVersion = githubLatest.Stable pm.GrafanaLatestVersion = githubLatest.Stable
GrafanaHasUpdate = githubLatest.Stable != setting.BuildVersion pm.GrafanaHasUpdate = githubLatest.Stable != setting.BuildVersion
} }
currVersion, err1 := version.NewVersion(setting.BuildVersion) currVersion, err1 := version.NewVersion(setting.BuildVersion)
latestVersion, err2 := version.NewVersion(GrafanaLatestVersion) latestVersion, err2 := version.NewVersion(pm.GrafanaLatestVersion)
if err1 == nil && err2 == nil { if err1 == nil && err2 == nil {
GrafanaHasUpdate = currVersion.LessThan(latestVersion) pm.GrafanaHasUpdate = currVersion.LessThan(latestVersion)
} }
} }

View File

@ -67,7 +67,6 @@ var (
// Paths // Paths
HomePath string HomePath string
PluginsPath string
CustomInitPath = "conf/custom.ini" CustomInitPath = "conf/custom.ini"
// HTTP server options // HTTP server options
@ -215,6 +214,7 @@ type Cfg struct {
ProvisioningPath string ProvisioningPath string
DataPath string DataPath string
LogsPath string LogsPath string
PluginsPath string
BundledPluginsPath string BundledPluginsPath string
// SMTP email settings // SMTP email settings
@ -765,7 +765,7 @@ func (cfg *Cfg) Load(args *CommandLineArgs) error {
cfg.Env = Env cfg.Env = Env
InstanceName = valueAsString(iniFile.Section(""), "instance_name", "unknown_instance_name") InstanceName = valueAsString(iniFile.Section(""), "instance_name", "unknown_instance_name")
plugins := valueAsString(iniFile.Section("paths"), "plugins", "") plugins := valueAsString(iniFile.Section("paths"), "plugins", "")
PluginsPath = makeAbsolute(plugins, HomePath) cfg.PluginsPath = makeAbsolute(plugins, HomePath)
cfg.BundledPluginsPath = makeAbsolute("plugins-bundled", HomePath) cfg.BundledPluginsPath = makeAbsolute("plugins-bundled", HomePath)
provisioning := valueAsString(iniFile.Section("paths"), "provisioning", "") provisioning := valueAsString(iniFile.Section("paths"), "provisioning", "")
cfg.ProvisioningPath = makeAbsolute(provisioning, HomePath) cfg.ProvisioningPath = makeAbsolute(provisioning, HomePath)
@ -969,7 +969,7 @@ func (cfg *Cfg) LogConfigSources() {
cfg.Logger.Info("Path Home", "path", HomePath) cfg.Logger.Info("Path Home", "path", HomePath)
cfg.Logger.Info("Path Data", "path", cfg.DataPath) cfg.Logger.Info("Path Data", "path", cfg.DataPath)
cfg.Logger.Info("Path Logs", "path", cfg.LogsPath) cfg.Logger.Info("Path Logs", "path", cfg.LogsPath)
cfg.Logger.Info("Path Plugins", "path", PluginsPath) cfg.Logger.Info("Path Plugins", "path", cfg.PluginsPath)
cfg.Logger.Info("Path Provisioning", "path", cfg.ProvisioningPath) cfg.Logger.Info("Path Provisioning", "path", cfg.ProvisioningPath)
cfg.Logger.Info("App mode " + cfg.Env) cfg.Logger.Info("App mode " + cfg.Env)
} }