Commit db584b3d by Oleg Gaidarenko Committed by GitHub

Chore: remove session storage references (#16445)

* Chore: remove session storage references

* Small refactoring of the settings module

* Update docs - remove references for the session storage

* Update config files (sample and default configs)

* Add tests for warning during the config load on defined storage cache

* Remove all references to session storage

* Remove macaron session dependency

* Remove leftovers

* Fix: address review comments

* Fix: remove old deps

* Fix: add skipStaticRootValidation = true to tests

* Fix: improve the docs and warning message

As per discussion in here - https://github.com/grafana/grafana/pull/16445/files#r273026255

* Chore: make linter happy

Fixes #16148
Ref #16114
parent f175046b
This diff is collapsed. Click to expand it.
...@@ -117,37 +117,6 @@ type = database ...@@ -117,37 +117,6 @@ type = database
# memcache: 127.0.0.1:11211 # memcache: 127.0.0.1:11211
connstr = connstr =
#################################### Session #############################
[session]
# Either "memory", "file", "redis", "mysql", "postgres", "memcache", default is "file"
provider = file
# Provider config options
# memory: not have any config yet
# file: session dir path, is relative to grafana data_path
# redis: config like redis server e.g. `addr=127.0.0.1:6379,pool_size=100,db=grafana`
# postgres: user=a password=b host=localhost port=5432 dbname=c sslmode=disable
# mysql: go-sql-driver/mysql dsn config string, examples:
# `user:password@tcp(127.0.0.1:3306)/database_name`
# `user:password@unix(/var/run/mysqld/mysqld.sock)/database_name`
# memcache: 127.0.0.1:11211
provider_config = sessions
# Session cookie name
cookie_name = grafana_sess
# If you use session in https only, default is false
cookie_secure = false
# Session life time, default is 86400 (means 86400 seconds or 24 hours)
session_life_time = 86400
gc_interval_time = 86400
# Connection Max Lifetime default is 14400 (means 14400 seconds or 4 hours)
conn_max_lifetime = 14400
#################################### Data proxy ########################### #################################### Data proxy ###########################
[dataproxy] [dataproxy]
......
...@@ -113,28 +113,6 @@ log_queries = ...@@ -113,28 +113,6 @@ log_queries =
# memcache: 127.0.0.1:11211 # memcache: 127.0.0.1:11211
;connstr = ;connstr =
#################################### Session ####################################
[session]
# Either "memory", "file", "redis", "mysql", "postgres", default is "file"
;provider = file
# Provider config options
# memory: not have any config yet
# file: session dir path, is relative to grafana data_path
# redis: config like redis server e.g. `addr=127.0.0.1:6379,pool_size=100,db=grafana`
# mysql: go-sql-driver/mysql dsn config string, e.g. `user:password@tcp(127.0.0.1:3306)/database_name`
# postgres: user=a password=b host=localhost port=5432 dbname=c sslmode=disable
;provider_config = sessions
# Session cookie name
;cookie_name = grafana_sess
# If you use session in https only, default is false
;cookie_secure = false
# Session life time, default is 86400 (means 86400 seconds or 24 hours)
;session_life_time = 86400
#################################### Data proxy ########################### #################################### Data proxy ###########################
[dataproxy] [dataproxy]
......
...@@ -383,39 +383,6 @@ below. ...@@ -383,39 +383,6 @@ below.
- [LDAP Authentication]({{< relref "auth/ldap.md" >}}) (auth.ldap) - [LDAP Authentication]({{< relref "auth/ldap.md" >}}) (auth.ldap)
- [Auth Proxy]({{< relref "auth/auth-proxy.md" >}}) (auth.proxy) - [Auth Proxy]({{< relref "auth/auth-proxy.md" >}}) (auth.proxy)
## [session]
### provider
Valid values are `memory`, `file`, `mysql`, `postgres`, `memcache` or `redis`. Default is `file`.
### provider_config
This option should be configured differently depending on what type of
session provider you have configured.
- **file:** session file path, e.g. `data/sessions`
- **mysql:** go-sql-driver/mysql dsn config string, e.g. `user:password@tcp(127.0.0.1:3306)/database_name`
- **postgres:** ex: `user=a password=b host=localhost port=5432 dbname=c sslmode=verify-full`
- **memcache:** ex: `127.0.0.1:11211`
- **redis:** ex: `addr=127.0.0.1:6379,pool_size=100,prefix=grafana`. For unix socket, use for example: `network=unix,addr=/var/run/redis/redis.sock,pool_size=100,db=grafana`
Postgres valid `sslmode` are `disable`, `require`, `verify-ca`, and `verify-full` (default).
### cookie_name
The name of the Grafana session cookie.
### cookie_secure
Set to true if you host Grafana behind HTTPS only. Defaults to `false`.
### session_life_time
How long sessions lasts in seconds. Defaults to `86400` (24 hours).
<hr />
## [dataproxy] ## [dataproxy]
### logging ### logging
...@@ -677,3 +644,40 @@ is false. This settings was introduced in Grafana v6.0. ...@@ -677,3 +644,40 @@ is false. This settings was introduced in Grafana v6.0.
Set to true if you want to test alpha plugins that are not yet ready for general usage. Set to true if you want to test alpha plugins that are not yet ready for general usage.
<hr />
# Removed options
Please note that these options have been removed.
## [session]
**Removed starting from Grafana v6.2. Please use [remote_cache](#remote-cache) option instead.**
### provider
Valid values are `memory`, `file`, `mysql`, `postgres`, `memcache` or `redis`. Default is `file`.
### provider_config
This option should be configured differently depending on what type of
session provider you have configured.
- **file:** session file path, e.g. `data/sessions`
- **mysql:** go-sql-driver/mysql dsn config string, e.g. `user:password@tcp(127.0.0.1:3306)/database_name`
- **postgres:** ex: `user=a password=b host=localhost port=5432 dbname=c sslmode=verify-full`
- **memcache:** ex: `127.0.0.1:11211`
- **redis:** ex: `addr=127.0.0.1:6379,pool_size=100,prefix=grafana`. For unix socket, use for example: `network=unix,addr=/var/run/redis/redis.sock,pool_size=100,db=grafana`
Postgres valid `sslmode` are `disable`, `require`, `verify-ca`, and `verify-full` (default).
### cookie_name
The name of the Grafana session cookie.
### cookie_secure
Set to true if you host Grafana behind HTTPS only. Defaults to `false`.
### session_life_time
How long sessions lasts in seconds. Defaults to `86400` (24 hours).
...@@ -9,12 +9,10 @@ import ( ...@@ -9,12 +9,10 @@ import (
"testing" "testing"
"time" "time"
msession "github.com/go-macaron/session"
"github.com/grafana/grafana/pkg/bus" "github.com/grafana/grafana/pkg/bus"
"github.com/grafana/grafana/pkg/infra/remotecache" "github.com/grafana/grafana/pkg/infra/remotecache"
m "github.com/grafana/grafana/pkg/models" m "github.com/grafana/grafana/pkg/models"
"github.com/grafana/grafana/pkg/services/auth" "github.com/grafana/grafana/pkg/services/auth"
"github.com/grafana/grafana/pkg/services/session"
"github.com/grafana/grafana/pkg/setting" "github.com/grafana/grafana/pkg/setting"
"github.com/grafana/grafana/pkg/util" "github.com/grafana/grafana/pkg/util"
. "github.com/smartystreets/goconvey/convey" . "github.com/smartystreets/goconvey/convey"
...@@ -423,9 +421,6 @@ func middlewareScenario(t *testing.T, desc string, fn scenarioFunc) { ...@@ -423,9 +421,6 @@ func middlewareScenario(t *testing.T, desc string, fn scenarioFunc) {
sc.remoteCacheService = remotecache.NewFakeStore(t) sc.remoteCacheService = remotecache.NewFakeStore(t)
sc.m.Use(GetContextHandler(sc.userAuthTokenService, sc.remoteCacheService)) sc.m.Use(GetContextHandler(sc.userAuthTokenService, sc.remoteCacheService))
// mock out gc goroutine
session.StartSessionGC = func() {}
setting.SessionOptions = msession.Options{}
sc.m.Use(OrgRedirect()) sc.m.Use(OrgRedirect())
sc.m.Use(AddDefaultResponseHeaders()) sc.m.Use(AddDefaultResponseHeaders())
......
...@@ -4,7 +4,6 @@ import ( ...@@ -4,7 +4,6 @@ import (
"strings" "strings"
"github.com/grafana/grafana/pkg/log" "github.com/grafana/grafana/pkg/log"
"github.com/grafana/grafana/pkg/services/session"
"github.com/grafana/grafana/pkg/setting" "github.com/grafana/grafana/pkg/setting"
"github.com/prometheus/client_golang/prometheus" "github.com/prometheus/client_golang/prometheus"
"gopkg.in/macaron.v1" "gopkg.in/macaron.v1"
...@@ -15,9 +14,6 @@ type ReqContext struct { ...@@ -15,9 +14,6 @@ type ReqContext struct {
*SignedInUser *SignedInUser
UserToken *UserToken UserToken *UserToken
// This should only be used by the auth_proxy
Session session.SessionStore
IsSignedIn bool IsSignedIn bool
IsRenderCall bool IsRenderCall bool
AllowAnonymous bool AllowAnonymous bool
......
// Copyright 2013 Beego Authors
// Copyright 2014 The Macaron Authors
//
// Licensed under the Apache License, Version 2.0 (the "License"): you may
// not use this file except in compliance with the License. You may obtain
// a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
// License for the specific language governing permissions and limitations
// under the License.
package session
import (
"database/sql"
"fmt"
"log"
"sync"
"time"
_ "github.com/go-sql-driver/mysql"
"github.com/go-macaron/session"
)
// MysqlStore represents a mysql session store implementation.
type MysqlStore struct {
c *sql.DB
sid string
lock sync.RWMutex
data map[interface{}]interface{}
expiry int64
dirty bool
}
// NewMysqlStore creates and returns a mysql session store.
func NewMysqlStore(c *sql.DB, sid string, kv map[interface{}]interface{}, expiry int64) *MysqlStore {
return &MysqlStore{
c: c,
sid: sid,
data: kv,
expiry: expiry,
dirty: false,
}
}
// Set sets value to given key in session.
func (s *MysqlStore) Set(key, val interface{}) error {
s.lock.Lock()
defer s.lock.Unlock()
s.data[key] = val
s.dirty = true
return nil
}
// Get gets value by given key in session.
func (s *MysqlStore) Get(key interface{}) interface{} {
s.lock.RLock()
defer s.lock.RUnlock()
return s.data[key]
}
// Delete delete a key from session.
func (s *MysqlStore) Delete(key interface{}) error {
s.lock.Lock()
defer s.lock.Unlock()
delete(s.data, key)
s.dirty = true
return nil
}
// ID returns current session ID.
func (s *MysqlStore) ID() string {
return s.sid
}
// Release releases resource and save data to provider.
func (s *MysqlStore) Release() error {
newExpiry := time.Now().Unix()
if !s.dirty && (s.expiry+60) >= newExpiry {
return nil
}
data, err := session.EncodeGob(s.data)
if err != nil {
return err
}
_, err = s.c.Exec("UPDATE session SET data=?, expiry=? WHERE `key`=?",
data, newExpiry, s.sid)
s.dirty = false
s.expiry = newExpiry
return err
}
// Flush deletes all session data.
func (s *MysqlStore) Flush() error {
s.lock.Lock()
defer s.lock.Unlock()
s.data = make(map[interface{}]interface{})
s.dirty = true
return nil
}
// MysqlProvider represents a mysql session provider implementation.
type MysqlProvider struct {
c *sql.DB
expire int64
}
// Init initializes mysql session provider.
// connStr: username:password@protocol(address)/dbname?param=value
func (p *MysqlProvider) Init(expire int64, connStr string) (err error) {
p.expire = expire
p.c, err = sql.Open("mysql", connStr)
p.c.SetConnMaxLifetime(time.Second * time.Duration(sessionConnMaxLifetime))
if err != nil {
return err
}
return p.c.Ping()
}
// Read returns raw session store by session ID.
func (p *MysqlProvider) Read(sid string) (session.RawStore, error) {
expiry := time.Now().Unix()
var data []byte
err := p.c.QueryRow("SELECT data,expiry FROM session WHERE `key`=?", sid).Scan(&data, &expiry)
if err == sql.ErrNoRows {
_, err = p.c.Exec("INSERT INTO session(`key`,data,expiry) VALUES(?,?,?)",
sid, "", expiry)
}
if err != nil {
return nil, err
}
var kv map[interface{}]interface{}
if len(data) == 0 {
kv = make(map[interface{}]interface{})
} else {
kv, err = session.DecodeGob(data)
if err != nil {
return nil, err
}
}
return NewMysqlStore(p.c, sid, kv, expiry), nil
}
// Exist returns true if session with given ID exists.
func (p *MysqlProvider) Exist(sid string) bool {
exists, err := p.queryExists(sid)
if err != nil {
exists, err = p.queryExists(sid)
}
if err != nil {
log.Printf("session/mysql: error checking if session exists: %v", err)
return false
}
return exists
}
func (p *MysqlProvider) queryExists(sid string) (bool, error) {
var data []byte
err := p.c.QueryRow("SELECT data FROM session WHERE `key`=?", sid).Scan(&data)
if err != nil && err != sql.ErrNoRows {
return false, err
}
return err != sql.ErrNoRows, nil
}
// Destory deletes a session by session ID.
func (p *MysqlProvider) Destory(sid string) error {
_, err := p.c.Exec("DELETE FROM session WHERE `key`=?", sid)
return err
}
// Regenerate regenerates a session store from old session ID to new one.
func (p *MysqlProvider) Regenerate(oldsid, sid string) (_ session.RawStore, err error) {
if p.Exist(sid) {
return nil, fmt.Errorf("new sid '%s' already exists", sid)
}
if !p.Exist(oldsid) {
if _, err = p.c.Exec("INSERT INTO session(`key`,data,expiry) VALUES(?,?,?)",
oldsid, "", time.Now().Unix()); err != nil {
return nil, err
}
}
if _, err = p.c.Exec("UPDATE session SET `key`=? WHERE `key`=?", sid, oldsid); err != nil {
return nil, err
}
return p.Read(sid)
}
// Count counts and returns number of sessions.
func (p *MysqlProvider) Count() (total int) {
if err := p.c.QueryRow("SELECT COUNT(*) AS NUM FROM session").Scan(&total); err != nil {
panic("session/mysql: error counting records: " + err.Error())
}
return total
}
// GC calls GC to clean expired sessions.
func (p *MysqlProvider) GC() {
var err error
if _, err = p.c.Exec("DELETE FROM session WHERE expiry + ? <= UNIX_TIMESTAMP(NOW())", p.expire); err != nil {
_, err = p.c.Exec("DELETE FROM session WHERE expiry + ? <= UNIX_TIMESTAMP(NOW())", p.expire)
}
if err != nil {
log.Printf("session/mysql: error garbage collecting: %v", err)
}
}
func init() {
session.Register("mysql", &MysqlProvider{})
}
package session
import (
"math/rand"
"time"
ms "github.com/go-macaron/session"
_ "github.com/go-macaron/session/memcache"
_ "github.com/go-macaron/session/postgres"
_ "github.com/go-macaron/session/redis"
"github.com/grafana/grafana/pkg/log"
"gopkg.in/macaron.v1"
)
const (
SESS_KEY_USERID = "uid"
SESS_KEY_LASTLDAPSYNC = "last_ldap_sync"
)
var sessionManager *ms.Manager
var sessionOptions *ms.Options
var StartSessionGC func() = func() {}
var GetSessionCount func() int
var sessionLogger = log.New("session")
var sessionConnMaxLifetime int64
func init() {
StartSessionGC = func() {
sessionManager.GC()
sessionLogger.Debug("Session GC")
time.AfterFunc(time.Duration(sessionOptions.Gclifetime)*time.Second, StartSessionGC)
}
GetSessionCount = func() int {
return sessionManager.Count()
}
}
func Init(options *ms.Options, connMaxLifetime int64) {
var err error
sessionOptions = prepareOptions(options)
sessionConnMaxLifetime = connMaxLifetime
sessionManager, err = ms.NewManager(options.Provider, *options)
if err != nil {
panic(err)
}
// start GC threads after some random seconds
rndSeconds := 10 + rand.Int63n(180)
time.AfterFunc(time.Duration(rndSeconds)*time.Second, StartSessionGC)
}
func prepareOptions(opt *ms.Options) *ms.Options {
if len(opt.Provider) == 0 {
opt.Provider = "memory"
}
if len(opt.ProviderConfig) == 0 {
opt.ProviderConfig = "data/sessions"
}
if len(opt.CookieName) == 0 {
opt.CookieName = "grafana_sess"
}
if len(opt.CookiePath) == 0 {
opt.CookiePath = "/"
}
if opt.Gclifetime == 0 {
opt.Gclifetime = 3600
}
if opt.Maxlifetime == 0 {
opt.Maxlifetime = opt.Gclifetime
}
if opt.IDLength == 0 {
opt.IDLength = 16
}
return opt
}
func GetSession() SessionStore {
return &SessionWrapper{manager: sessionManager}
}
type SessionStore interface {
// Set sets value to given key in session.
Set(interface{}, interface{}) error
// Get gets value by given key in session.
Get(interface{}) interface{}
// Delete deletes a key from session.
Delete(interface{}) interface{}
// ID returns current session ID.
ID() string
// Release releases session resource and save data to provider.
Release() error
// Destory deletes a session.
Destory(*macaron.Context) error
// init
Start(*macaron.Context) error
// RegenerateId regenerates the session id
RegenerateId(*macaron.Context) error
}
type SessionWrapper struct {
session ms.RawStore
manager *ms.Manager
}
func (s *SessionWrapper) Start(c *macaron.Context) error {
// See https://github.com/grafana/grafana/issues/11155 for details on why
// a recover and retry is needed
defer func() error {
if err := recover(); err != nil {
var retryErr error
s.session, retryErr = s.manager.Start(c)
return retryErr
}
return nil
}()
var err error
s.session, err = s.manager.Start(c)
return err
}
func (s *SessionWrapper) RegenerateId(c *macaron.Context) error {
var err error
s.session, err = s.manager.RegenerateId(c)
return err
}
func (s *SessionWrapper) Set(k interface{}, v interface{}) error {
if s.session != nil {
return s.session.Set(k, v)
}
return nil
}
func (s *SessionWrapper) Get(k interface{}) interface{} {
if s.session != nil {
return s.session.Get(k)
}
return nil
}
func (s *SessionWrapper) Delete(k interface{}) interface{} {
if s.session != nil {
return s.session.Delete(k)
}
return nil
}
func (s *SessionWrapper) ID() string {
if s.session != nil {
return s.session.ID()
}
return ""
}
func (s *SessionWrapper) Release() error {
if s.session != nil {
return s.session.Release()
}
return nil
}
func (s *SessionWrapper) Destory(c *macaron.Context) error {
if s.session != nil {
if err := s.manager.Destory(c); err != nil {
return err
}
s.session = nil
}
return nil
}
...@@ -17,9 +17,10 @@ import ( ...@@ -17,9 +17,10 @@ import (
"time" "time"
"github.com/go-macaron/session" "github.com/go-macaron/session"
ini "gopkg.in/ini.v1"
"github.com/grafana/grafana/pkg/log" "github.com/grafana/grafana/pkg/log"
"github.com/grafana/grafana/pkg/util" "github.com/grafana/grafana/pkg/util"
ini "gopkg.in/ini.v1"
) )
type Scheme string type Scheme string
...@@ -183,9 +184,6 @@ var ( ...@@ -183,9 +184,6 @@ var (
// Explore UI // Explore UI
ExploreEnabled bool ExploreEnabled bool
// logger
logger log.Logger
// Grafana.NET URL // Grafana.NET URL
GrafanaComUrl string GrafanaComUrl string
...@@ -199,7 +197,8 @@ var ( ...@@ -199,7 +197,8 @@ var (
// TODO move all global vars to this struct // TODO move all global vars to this struct
type Cfg struct { type Cfg struct {
Raw *ini.File Raw *ini.File
Logger log.Logger
// HTTP Server Settings // HTTP Server Settings
AppUrl string AppUrl string
...@@ -258,7 +257,6 @@ type CommandLineArgs struct { ...@@ -258,7 +257,6 @@ type CommandLineArgs struct {
func init() { func init() {
IsWindows = runtime.GOOS == "windows" IsWindows = runtime.GOOS == "windows"
logger = log.New("settings")
} }
func parseAppUrlAndSubUrl(section *ini.Section) (string, string) { func parseAppUrlAndSubUrl(section *ini.Section) (string, string) {
...@@ -535,24 +533,25 @@ func setHomePath(args *CommandLineArgs) { ...@@ -535,24 +533,25 @@ func setHomePath(args *CommandLineArgs) {
var skipStaticRootValidation = false var skipStaticRootValidation = false
func validateStaticRootPath() error { func NewCfg() *Cfg {
return &Cfg{
Logger: log.New("settings"),
Raw: ini.Empty(),
}
}
func (cfg *Cfg) validateStaticRootPath() error {
if skipStaticRootValidation { if skipStaticRootValidation {
return nil return nil
} }
if _, err := os.Stat(path.Join(StaticRootPath, "build")); err != nil { if _, err := os.Stat(path.Join(StaticRootPath, "build")); err != nil {
logger.Error("Failed to detect generated javascript files in public/build") cfg.Logger.Error("Failed to detect generated javascript files in public/build")
} }
return nil return nil
} }
func NewCfg() *Cfg {
return &Cfg{
Raw: ini.Empty(),
}
}
func (cfg *Cfg) Load(args *CommandLineArgs) error { func (cfg *Cfg) Load(args *CommandLineArgs) error {
setHomePath(args) setHomePath(args)
...@@ -600,7 +599,7 @@ func (cfg *Cfg) Load(args *CommandLineArgs) error { ...@@ -600,7 +599,7 @@ func (cfg *Cfg) Load(args *CommandLineArgs) error {
EnforceDomain = server.Key("enforce_domain").MustBool(false) EnforceDomain = server.Key("enforce_domain").MustBool(false)
StaticRootPath = makeAbsolute(server.Key("static_root_path").String(), HomePath) StaticRootPath = makeAbsolute(server.Key("static_root_path").String(), HomePath)
if err := validateStaticRootPath(); err != nil { if err := cfg.validateStaticRootPath(); err != nil {
return err return err
} }
...@@ -813,27 +812,13 @@ type RemoteCacheOptions struct { ...@@ -813,27 +812,13 @@ type RemoteCacheOptions struct {
} }
func (cfg *Cfg) readSessionConfig() { func (cfg *Cfg) readSessionConfig() {
sec := cfg.Raw.Section("session") sec, _ := cfg.Raw.GetSection("session")
SessionOptions = session.Options{}
SessionOptions.Provider = sec.Key("provider").In("memory", []string{"memory", "file", "redis", "mysql", "postgres", "memcache"})
SessionOptions.ProviderConfig = strings.Trim(sec.Key("provider_config").String(), "\" ")
SessionOptions.CookieName = sec.Key("cookie_name").MustString("grafana_sess")
SessionOptions.CookiePath = AppSubUrl
SessionOptions.Secure = sec.Key("cookie_secure").MustBool()
SessionOptions.Gclifetime = cfg.Raw.Section("session").Key("gc_interval_time").MustInt64(86400)
SessionOptions.Maxlifetime = cfg.Raw.Section("session").Key("session_life_time").MustInt64(86400)
SessionOptions.IDLength = 16
if SessionOptions.Provider == "file" {
SessionOptions.ProviderConfig = makeAbsolute(SessionOptions.ProviderConfig, cfg.DataPath)
os.MkdirAll(path.Dir(SessionOptions.ProviderConfig), os.ModePerm)
}
if SessionOptions.CookiePath == "" { if sec != nil {
SessionOptions.CookiePath = "/" cfg.Logger.Warn(
"[Removed] Session setting was removed in v6.2, use remote_cache option instead",
)
} }
SessionConnMaxLifetime = cfg.Raw.Section("session").Key("conn_max_lifetime").MustInt64(14400)
} }
func (cfg *Cfg) initLogging(file *ini.File) { func (cfg *Cfg) initLogging(file *ini.File) {
...@@ -851,26 +836,26 @@ func (cfg *Cfg) LogConfigSources() { ...@@ -851,26 +836,26 @@ func (cfg *Cfg) LogConfigSources() {
var text bytes.Buffer var text bytes.Buffer
for _, file := range configFiles { for _, file := range configFiles {
logger.Info("Config loaded from", "file", file) cfg.Logger.Info("Config loaded from", "file", file)
} }
if len(appliedCommandLineProperties) > 0 { if len(appliedCommandLineProperties) > 0 {
for _, prop := range appliedCommandLineProperties { for _, prop := range appliedCommandLineProperties {
logger.Info("Config overridden from command line", "arg", prop) cfg.Logger.Info("Config overridden from command line", "arg", prop)
} }
} }
if len(appliedEnvOverrides) > 0 { if len(appliedEnvOverrides) > 0 {
text.WriteString("\tEnvironment variables used:\n") text.WriteString("\tEnvironment variables used:\n")
for _, prop := range appliedEnvOverrides { for _, prop := range appliedEnvOverrides {
logger.Info("Config overridden from Environment variable", "var", prop) cfg.Logger.Info("Config overridden from Environment variable", "var", prop)
} }
} }
logger.Info("Path Home", "path", HomePath) cfg.Logger.Info("Path Home", "path", HomePath)
logger.Info("Path Data", "path", cfg.DataPath) cfg.Logger.Info("Path Data", "path", cfg.DataPath)
logger.Info("Path Logs", "path", cfg.LogsPath) cfg.Logger.Info("Path Logs", "path", cfg.LogsPath)
logger.Info("Path Plugins", "path", PluginsPath) cfg.Logger.Info("Path Plugins", "path", PluginsPath)
logger.Info("Path Provisioning", "path", cfg.ProvisioningPath) cfg.Logger.Info("Path Provisioning", "path", cfg.ProvisioningPath)
logger.Info("App mode " + Env) cfg.Logger.Info("App mode " + Env)
} }
package setting
import (
"path/filepath"
"testing"
"github.com/grafana/grafana/pkg/log"
. "github.com/smartystreets/goconvey/convey"
)
type testLogger struct {
log.Logger
warnCalled bool
warnMessage string
}
func (stub *testLogger) Warn(testMessage string, ctx ...interface{}) {
stub.warnCalled = true
stub.warnMessage = testMessage
}
func TestSessionSettings(t *testing.T) {
Convey("session config", t, func() {
skipStaticRootValidation = true
Convey("Reading session should log error ", func() {
var (
cfg = NewCfg()
homePath = "../../"
)
stub := &testLogger{}
cfg.Logger = stub
cfg.Load(&CommandLineArgs{
HomePath: homePath,
Config: filepath.Join(homePath, "pkg/setting/testdata/session.ini"),
})
So(stub.warnCalled, ShouldEqual, true)
So(len(stub.warnMessage), ShouldBeGreaterThan, 0)
})
})
}
...@@ -188,6 +188,5 @@ func TestLoadingSettings(t *testing.T) { ...@@ -188,6 +188,5 @@ func TestLoadingSettings(t *testing.T) {
So(cfg.RendererCallbackUrl, ShouldEqual, "http://myserver/renderer/") So(cfg.RendererCallbackUrl, ShouldEqual, "http://myserver/renderer/")
}) })
}) })
} }
[session]
provider = file
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