Fixed issue with overriding default config values via command line

This commit is contained in:
Torkel Ödegaard
2015-04-10 10:58:32 +02:00
parent 4c6d7630cd
commit 2020fedfdb
10 changed files with 257 additions and 57 deletions

View File

@ -115,7 +115,7 @@ func createPackage(packageType string, defaultPath string) {
configDir := "/etc/grafana"
configFilePath := "/etc/grafana/grafana.ini"
defaultFilePath := filepath.Join("/etc/", defaultPath, "grafana-server")
grafanaServerBinPath := "/usr/bin/" + serverBinaryName
grafanaServerBinPath := "/usr/sbin/" + serverBinaryName
initdScriptPath := "/etc/init.d/grafana-server"
systemdServiceFilePath := "/usr/lib/systemd/system/grafana-server.service"
@ -128,25 +128,25 @@ func createPackage(packageType string, defaultPath string) {
systemdFileSrc := filepath.Join(packageConfDir, "systemd/grafana-server.service")
// create directories
runError("mkdir", "-p", filepath.Join(packageRoot, homeDir))
runError("mkdir", "-p", filepath.Join(packageRoot, configDir))
runError("mkdir", "-p", filepath.Join(packageRoot, "/etc/init.d"))
runError("mkdir", "-p", filepath.Join(packageRoot, "/etc/", defaultPath))
runError("mkdir", "-p", filepath.Join(packageRoot, "/usr/lib/systemd/system"))
runError("mkdir", "-p", filepath.Join(packageRoot, "/usr/bin"))
runPrint("mkdir", "-p", filepath.Join(packageRoot, homeDir))
runPrint("mkdir", "-p", filepath.Join(packageRoot, configDir))
runPrint("mkdir", "-p", filepath.Join(packageRoot, "/etc/init.d"))
runPrint("mkdir", "-p", filepath.Join(packageRoot, "/etc/", defaultPath))
runPrint("mkdir", "-p", filepath.Join(packageRoot, "/usr/lib/systemd/system"))
runPrint("mkdir", "-p", filepath.Join(packageRoot, "/usr/sbin"))
// copy binary
runError("cp", "-p", filepath.Join(workingDir, "tmp/bin/"+serverBinaryName), grafanaServerBinPath)
runPrint("cp", "-p", filepath.Join(workingDir, "tmp/bin/"+serverBinaryName), filepath.Join(packageRoot, grafanaServerBinPath))
// copy init.d script
runError("cp", "-p", initdScriptSrc, filepath.Join(packageRoot, initdScriptPath))
runPrint("cp", "-p", initdScriptSrc, filepath.Join(packageRoot, initdScriptPath))
// copy environment var file
runError("cp", "-p", defaultFileSrc, filepath.Join(packageRoot, defaultFilePath))
runPrint("cp", "-p", defaultFileSrc, filepath.Join(packageRoot, defaultFilePath))
// copy systemd file
runPrint("cp", "-p", systemdFileSrc, filepath.Join(packageRoot, systemdServiceFilePath))
// copy release files
runError("cp", "-a", filepath.Join(workingDir, "tmp")+"/.", filepath.Join(packageRoot, homeDir))
runPrint("cp", "-a", filepath.Join(workingDir, "tmp")+"/.", filepath.Join(packageRoot, homeDir))
// copy sample ini file to /etc/opt/grafana
runError("cp", "conf/sample.ini", filepath.Join(packageRoot, configFilePath))
runPrint("cp", "conf/sample.ini", filepath.Join(packageRoot, configFilePath))
args := []string{
"-s", "dir",

View File

@ -96,10 +96,13 @@ google_analytics_ua_id =
[security]
# default admin user, created on startup
admin_user = admin
# default admin password, can be changed before first start of grafana, or in profile settings
admin_password = admin
# used for signing
secret_key = SW2YcwTIb9zpOOhoPsMm
# Auto-login remember days
login_remember_days = 7
cookie_username = grafana_user
@ -109,10 +112,13 @@ cookie_remember_name = grafana_remember
[users]
# disable user signup / registration
allow_sign_up = true
# Allow non admin users to create organizations
allow_org_create = true
# Set to true to automatically assign new users to the default organization (id 1)
auto_assign_org = true
# Default role new users will be automatically assigned (if disabled above is set to true)
auto_assign_org_role = Viewer
@ -120,8 +126,10 @@ auto_assign_org_role = Viewer
[auth.anonymous]
# enable anonymous access
enabled = false
# specify organization name that should be used for unauthenticated users
org_name = Main Org.
# specify role for unauthenticated users
org_role = Viewer
@ -152,8 +160,10 @@ token_url = https://accounts.google.com/o/oauth2/token
# Either "console", "file", default is "console"
# Use comma to separate multiple modes, e.g. "console, file"
mode = console, file
# Buffer length of channel, keep it as it is if you don't know what it is.
buffer_len = 10000
# Either "Trace", "Debug", "Info", "Warn", "Error", "Critical", default is "Trace"
level = Info
@ -164,15 +174,19 @@ level =
# For "file" mode only
[log.file]
level =
; This enables automated log rotate(switch of following options), default is true
# This enables automated log rotate(switch of following options), default is true
log_rotate = true
; Max line number of single file, default is 1000000
# Max line number of single file, default is 1000000
max_lines = 1000000
; Max size shift of single file, default is 28 means 1 << 28, 256MB
# Max size shift of single file, default is 28 means 1 << 28, 256MB
max_lines_shift = 28
; Segment log daily, default is true
# Segment log daily, default is true
daily_rotate = true
; Expired days of log file(delete after max days), default is 7
# Expired days of log file(delete after max days), default is 7
max_days = 7
#################################### AMPQ Event Publisher ##########################

View File

@ -1,7 +1,7 @@
##################### Grafana Configuration Example #####################
# Sample grafana config for deb & rpm packages
# You only need to specify overrides here
#
# Everything has defaults so you only need to uncomment things you want to
# change
; app_mode = production
@ -15,24 +15,182 @@
#
;logs = /var/log/grafana
#################################### Server ####################################
[server]
; protocol (http or https)
# Protocol (http or https)
;protocol = http
; the ip address to bind to, empty will bind to all interfaces
# The ip address to bind to, empty will bind to all interfaces
;http_addr =
; the http port to use
# The http port to use
;http_port = 3000
; The public facing domain name used to access grafana from a browser
# The public facing domain name used to access grafana from a browser
;domain = localhost
; the full public facing url
# The full public facing url
;root_url = %(protocol)s://%(domain)s:%(http_port)s/
# Log web requests
;router_logging = false
; the path relative home path where frontend assets are located
# the path relative working path
;static_root_path = public
; enable gzip
# enable gzip
;enable_gzip = false
; https certs & key file
# https certs & key file
;cert_file =
;cert_key =
#################################### Database ####################################
[database]
# Either "mysql", "postgres" or "sqlite3", it's your choice
;type = sqlite3
;host = 127.0.0.1:3306
;name = grafana
;user = root
;password =
# For "postgres" only, either "disable", "require" or "verify-full"
;ssl_mode = disable
# For "sqlite3" only, path relative to data_path setting
;path = grafana.db
#################################### Session ####################################
[session]
# Either "memory", "file", "redis", "mysql", default is "memory"
;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 addr, poolSize, password, e.g. `127.0.0.1:6379,100,grafana`
# mysql: go-sql-driver/mysql dsn config string, e.g. `user:password@tcp(127.0.0.1)/database_name`
;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
;session_life_time = 86400
#################################### Analytics ####################################
[analytics]
# Server reporting, sends usage counters to stats.grafana.org every 24 hours.
# No ip addresses are being tracked, only simple counters to track
# running instances, dashboard and error counts. It is very helpful to us.
# Change this option to false to disable reporting.
;reporting_enabled = true
# Google Analytics universal tracking code, only enabled if you specify an id here
;google_analytics_ua_id =
#################################### Security ####################################
[security]
# default admin user, created on startup
;admin_user = admin
# default admin password, can be changed before first start of grafana, or in profile settings
;admin_password = admin
# used for signing
;secret_key = SW2YcwTIb9zpOOhoPsMm
# Auto-login remember days
;login_remember_days = 7
;cookie_username = grafana_user
;cookie_remember_name = grafana_remember
#################################### Users ####################################
[users]
# disable user signup / registration
;allow_sign_up = true
# Allow non admin users to create organizations
;allow_org_create = true
# Set to true to automatically assign new users to the default organization (id 1)
;auto_assign_org = true
# Default role new users will be automatically assigned (if disabled above is set to true)
;auto_assign_org_role = Viewer
#################################### Anonymous Auth ##########################
[auth.anonymous]
# enable anonymous access
;enabled = false
# specify organization name that should be used for unauthenticated users
;org_name = Main Org.
# specify role for unauthenticated users
;org_role = Viewer
#################################### Github Auth ##########################
[auth.github]
;enabled = false
;client_id = some_id
;client_secret = some_secret
;scopes = user:email
;auth_url = https://github.com/login/oauth/authorize
;token_url = https://github.com/login/oauth/access_token
# Uncomment bellow to only allow specific email domains
; allowed_domains = mycompany.com othercompany.com
#################################### Google Auth ##########################
[auth.google]
;enabled = false
;client_id = some_client_id
;client_secret = some_client_secret
;scopes = https://www.googleapis.com/auth/userinfo.profile https://www.googleapis.com/auth/userinfo.email
;auth_url = https://accounts.google.com/o/oauth2/auth
;token_url = https://accounts.google.com/o/oauth2/token
# Uncomment bellow to only allow specific email domains
; allowed_domains = mycompany.com othercompany.com
#################################### Logging ##########################
[log]
# Either "console", "file", default is "console"
# Use comma to separate multiple modes, e.g. "console, file"
;mode = console, file
# Buffer length of channel, keep it as it is if you don't know what it is.
;buffer_len = 10000
# Either "Trace", "Debug", "Info", "Warn", "Error", "Critical", default is "Trace"
;level = Info
# For "console" mode only
[log.console]
;level =
# For "file" mode only
[log.file]
;level =
# This enables automated log rotate(switch of following options), default is true
;log_rotate = true
# Max line number of single file, default is 1000000
;max_lines = 1000000
# Max size shift of single file, default is 28 means 1 << 28, 256MB
;max_lines_shift = 28
# Segment log daily, default is true
;daily_rotate = true
# Expired days of log file(delete after max days), default is 7
;max_days = 7
#################################### AMPQ Event Publisher ##########################
[event_publisher]
;enabled = false
;rabbitmq_url = amqp://localhost/
;exchange = grafana_events

View File

@ -1,4 +1,6 @@
FROM debian:jessie
RUN apt-get update && apt-get install -y vim
ADD *.deb /tmp/

View File

@ -49,15 +49,15 @@ case "$1" in
if [ -x /bin/systemctl ] ; then
echo "### NOT starting on installation, please execute the following statements to configure elasticsearch to start automatically using systemd"
echo " sudo /bin/systemctl daemon-reload"
echo " sudo /bin/systemctl enable grafana.service"
echo "### You can start grafana by executing"
echo " sudo /bin/systemctl start grafana.service"
echo " sudo /bin/systemctl enable grafana-server.service"
echo "### You can start grafana-server by executing"
echo " sudo /bin/systemctl start grafana-server.service"
elif [ -x /usr/sbin/update-rc.d ] ; then
echo "### NOT starting grafana by default on bootup, please execute"
echo " sudo update-rc.d grafana defaults 95 10"
echo "### In order to start grafana, execute"
echo " sudo /etc/init.d/grafana start"
echo "### NOT starting grafana-server by default on bootup, please execute"
echo " sudo update-rc.d grafana-server defaults 95 10"
echo "### In order to start grafana-server, execute"
echo " sudo service grafana-server start"
fi
fi
;;

View File

@ -22,7 +22,19 @@
PATH=/bin:/usr/bin:/sbin:/usr/sbin
NAME=grafana-server
DESC="Grafana Server"
DEFAULT=/etc/default/grafana-server
DEFAULT=/etc/default/$NAME
GRAFANA_USER=grafana
GRAFANA_GROUP=grafana
GRAFANA_HOME=/usr/share/grafana
CONF_DIR=/etc/grafana
WORK_DIR=$GRAFANA_HOME
DATA_DIR=/var/lib/grafana
LOG_DIR=/var/log/grafana
CONF_FILE=$CONF_DIR/grafana.ini
MAX_OPEN_FILES=10000
PID_FILE=/var/run/$NAME.pid
DAEMON=/usr/sbin/$NAME
if [ `id -u` -ne 0 ]; then
echo "You need root privileges to run this script"
@ -35,23 +47,11 @@ if [ -r /etc/default/rcS ]; then
. /etc/default/rcS
fi
GRAFANA_USER=grafana
GRAFANA_GROUP=grafana
GRAFANA_HOME=/usr/share/grafana
CONF_DIR=/etc/grafana
WORK_DIR=$GRAFANA_HOME
DATA_DIR=/var/lib/grafana
LOG_DIR=/var/log/grafana
CONF_FILE=$CONF_DIR/grafana.ini
MAX_OPEN_FILES=10000
# overwrite settings from default file
if [ -f "$DEFAULT" ]; then
. "$DEFAULT"
fi
PID_FILE=/var/run/$NAME.pid
DAEMON=/usr/bin/grafana-server
DAEMON_OPTS="--pidfile=${PID_FILE} --config=${CONF_FILE} cfg:default.paths.data=${DATA_DIR} cfg:default.paths.logs=${LOG_DIR}"
# Check DAEMON exists

View File

@ -9,7 +9,7 @@ EnvironmentFile=/etc/default/grafana
User=grafana
Group=grafana
Type=simple
ExecStart=/usr/bin/grafana-server \
ExecStart=/usr/sbin/grafana-server \
--config=${CONF_FILE} \
cfg:default.paths.data=${LOG_DIR} \
cfg:default.paths.data=${DATA_DIR} \

View File

@ -225,6 +225,33 @@ func evalConfigValues() {
}
}
func loadSpecifedConfigFile(configFile string) {
userConfig, err := ini.Load(configFile)
if err != nil {
log.Fatal(3, "Failed to parse %v, %v", configFile, err)
}
for _, section := range userConfig.Sections() {
for _, key := range section.Keys() {
if key.Value() == "" {
continue
}
defaultSec, err := Cfg.GetSection(section.Name())
if err != nil {
log.Fatal(3, "Unknown config section %s defined in %s", section.Name(), configFile)
}
defaultKey, err := defaultSec.GetKey(key.Name())
if err != nil {
log.Fatal(3, "Unknown config key %s defined in section %s, in file", key.Name(), section.Name(), configFile)
}
defaultKey.SetValue(key.Value())
}
}
configFiles = append(configFiles, configFile)
}
func loadConfiguration(args *CommandLineArgs) {
var err error
@ -249,12 +276,7 @@ func loadConfiguration(args *CommandLineArgs) {
// load specified config file
if args.Config != "" {
err = Cfg.Append(args.Config)
if err != nil {
log.Fatal(3, "Failed to parse %v, %v", args.Config, err)
}
configFiles = append(configFiles, args.Config)
appliedCommandLineProperties = append(appliedCommandLineProperties, "config="+args.Config)
loadSpecifedConfigFile(args.Config)
}
// apply environment overrides

View File

@ -49,10 +49,13 @@ func TestLoadingSettings(t *testing.T) {
Convey("Should be able to override defaults via command line", func() {
NewConfigContext(&CommandLineArgs{
Args: []string{"cfg:default.paths.data=/tmp/data"},
Args: []string{
"cfg:default.server.domain=test2",
},
Config: filepath.Join(HomePath, "tests/config-files/override.ini"),
})
So(DataPath, ShouldEqual, "/tmp/data")
So(Domain, ShouldEqual, "test2")
})
Convey("Defaults can be overriden in specified config file", func() {

View File

@ -1,2 +1,3 @@
[paths]
data = /tmp/override