mirror of
https://github.com/grafana/grafana.git
synced 2025-09-28 05:13:50 +08:00
Worked on new deb & rpm packaging and init.d scripts
This commit is contained in:
54
build.go
54
build.go
@ -73,7 +73,7 @@ func main() {
|
|||||||
|
|
||||||
case "package":
|
case "package":
|
||||||
//verifyGitRepoIsClean()
|
//verifyGitRepoIsClean()
|
||||||
grunt("release", "--pkgVer="+version)
|
//grunt("release", "--pkgVer="+version)
|
||||||
createRpmAndDeb()
|
createRpmAndDeb()
|
||||||
|
|
||||||
case "latest":
|
case "latest":
|
||||||
@ -114,32 +114,39 @@ func readVersionFromPackageJson() {
|
|||||||
|
|
||||||
func createRpmAndDeb() {
|
func createRpmAndDeb() {
|
||||||
packageRoot, _ := ioutil.TempDir("", "grafana-linux-pack")
|
packageRoot, _ := ioutil.TempDir("", "grafana-linux-pack")
|
||||||
postInstallScriptPath, _ := ioutil.TempFile("", "postinstall")
|
afterInstallScript, _ := filepath.Abs("./packaging/deb/control/postinst")
|
||||||
|
initdscript, _ := filepath.Abs("./packaging/deb/init.d/grafana")
|
||||||
|
defaultScript, _ := filepath.Abs("./packaging/deb/default/grafana")
|
||||||
|
|
||||||
versionFolder := filepath.Join(packageRoot, installRoot, "versions", version)
|
packageInstallRoot := filepath.Join(packageRoot, installRoot)
|
||||||
configDir := filepath.Join(packageRoot, configRoot)
|
configDir := filepath.Join(packageRoot, configRoot)
|
||||||
|
|
||||||
runError("mkdir", "-p", versionFolder)
|
runError("mkdir", "-p", packageInstallRoot)
|
||||||
runError("mkdir", "-p", configDir)
|
runError("mkdir", "-p", configDir)
|
||||||
|
runError("mkdir", "-p", filepath.Join(packageRoot, "/etc/init.d"))
|
||||||
|
runError("mkdir", "-p", filepath.Join(packageRoot, "/etc/default"))
|
||||||
|
|
||||||
// copy sample ini file to /etc/opt/grafana
|
// copy sample ini file to /etc/opt/grafana
|
||||||
configFile := filepath.Join(configDir, "grafana.ini")
|
configFile := filepath.Join(configDir, "grafana.ini")
|
||||||
runError("cp", "conf/sample.ini", configFile)
|
runError("cp", "conf/sample.ini", configFile)
|
||||||
// copy release files
|
|
||||||
runError("cp", "-a", filepath.Join(workingDir, "tmp")+"/.", versionFolder)
|
|
||||||
|
|
||||||
GeneratePostInstallScript(postInstallScriptPath.Name())
|
// copy init.d script
|
||||||
|
runError("cp", "-p", initdscript, filepath.Join(packageRoot, "/etc/init.d/grafana"))
|
||||||
|
runError("cp", "-p", defaultScript, filepath.Join(packageRoot, "/etc/default/grafana"))
|
||||||
|
// copy release files
|
||||||
|
runError("cp", "-a", filepath.Join(workingDir, "tmp")+"/.", packageInstallRoot)
|
||||||
|
|
||||||
args := []string{
|
args := []string{
|
||||||
"-s", "dir",
|
"-s", "dir",
|
||||||
"--description", "Grafana",
|
"--description", "Grafana",
|
||||||
"-C", packageRoot,
|
"-C", packageRoot,
|
||||||
"--vendor", "Grafana",
|
"--vendor", "Grafana",
|
||||||
|
"--depends", "adduser",
|
||||||
"--url", "http://grafana.org",
|
"--url", "http://grafana.org",
|
||||||
"--license", "Apache 2.0",
|
"--license", "Apache 2.0",
|
||||||
"--maintainer", "contact@grafana.org",
|
"--maintainer", "contact@grafana.org",
|
||||||
"--config-files", filepath.Join(configRoot, "grafana.ini"),
|
"--config-files", filepath.Join(configRoot, "grafana.ini"),
|
||||||
"--after-install", postInstallScriptPath.Name(),
|
"--after-install", afterInstallScript,
|
||||||
"--name", "grafana",
|
"--name", "grafana",
|
||||||
"--version", version,
|
"--version", version,
|
||||||
"-p", "./dist",
|
"-p", "./dist",
|
||||||
@ -153,37 +160,6 @@ func createRpmAndDeb() {
|
|||||||
runPrint("fpm", append([]string{"-t", "rpm"}, args...)...)
|
runPrint("fpm", append([]string{"-t", "rpm"}, args...)...)
|
||||||
}
|
}
|
||||||
|
|
||||||
func GeneratePostInstallScript(path string) {
|
|
||||||
content := `
|
|
||||||
rm -f $INSTALL_ROOT_DIR/current
|
|
||||||
ln -s $INSTALL_ROOT_DIR/versions/$VERSION/ $INSTALL_ROOT_DIR/current
|
|
||||||
|
|
||||||
if [ ! -L /etc/init.d/grafana ]; then
|
|
||||||
ln -sfn $INSTALL_ROOT_DIR/current/scripts/init.sh /etc/init.d/grafana
|
|
||||||
fi
|
|
||||||
|
|
||||||
chmod +x /etc/init.d/grafana
|
|
||||||
if which update-rc.d > /dev/null 2>&1 ; then
|
|
||||||
update-rc.d -f grafana remove
|
|
||||||
update-rc.d grafana defaults
|
|
||||||
else
|
|
||||||
chkconfig --add grafana
|
|
||||||
fi
|
|
||||||
|
|
||||||
if ! id grafana >/dev/null 2>&1; then
|
|
||||||
useradd --system -U -M grafana
|
|
||||||
fi
|
|
||||||
chown -R -L grafana:grafana $INSTALL_ROOT_DIR
|
|
||||||
chmod -R a+rX $INSTALL_ROOT_DIR
|
|
||||||
mkdir -p $GRAFANA_LOG_DIR
|
|
||||||
chown -R -L grafana:grafana $GRAFANA_LOG_DIR
|
|
||||||
`
|
|
||||||
content = strings.Replace(content, "$INSTALL_ROOT_DIR", installRoot, -1)
|
|
||||||
content = strings.Replace(content, "$VERSION", version, -1)
|
|
||||||
content = strings.Replace(content, "$GRAFANA_LOG_DIR", grafanaLogDir, -1)
|
|
||||||
ioutil.WriteFile(path, []byte(content), 0644)
|
|
||||||
}
|
|
||||||
|
|
||||||
func verifyGitRepoIsClean() {
|
func verifyGitRepoIsClean() {
|
||||||
rs, err := runError("git", "ls-files", "--modified")
|
rs, err := runError("git", "ls-files", "--modified")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -1,6 +1,14 @@
|
|||||||
app_name = Grafana
|
app_name = Grafana
|
||||||
app_mode = production
|
app_mode = production
|
||||||
|
|
||||||
|
; data_path
|
||||||
|
; where rendered png images are temporarily stored
|
||||||
|
; file based sessions are stored here (if file based session is configured below)
|
||||||
|
; the database is stored here if sqlite3 database is used
|
||||||
|
; can be overriden from command line --data-path
|
||||||
|
; defaults to `data` path relative to working directory
|
||||||
|
data_path =
|
||||||
|
|
||||||
[server]
|
[server]
|
||||||
; protocol (http or https)
|
; protocol (http or https)
|
||||||
protocol = http
|
protocol = http
|
||||||
@ -39,18 +47,18 @@ user = root
|
|||||||
password =
|
password =
|
||||||
; For "postgres" only, either "disable", "require" or "verify-full"
|
; For "postgres" only, either "disable", "require" or "verify-full"
|
||||||
ssl_mode = disable
|
ssl_mode = disable
|
||||||
; For "sqlite3" only
|
; For "sqlite3" only, path relative to data_dir setting
|
||||||
path = data/grafana.db
|
path = grafana.db
|
||||||
|
|
||||||
[session]
|
[session]
|
||||||
; Either "memory", "file", "redis", "mysql", default is "memory"
|
; Either "memory", "file", "redis", "mysql", default is "memory"
|
||||||
provider = file
|
provider = file
|
||||||
; Provider config options
|
; Provider config options
|
||||||
; memory: not have any config yet
|
; memory: not have any config yet
|
||||||
; file: session file path, e.g. `data/sessions`
|
; file: session dir path, is relative to grafana data_dir
|
||||||
; redis: config like redis server addr, poolSize, password, e.g. `127.0.0.1:6379,100,grafana`
|
; 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`
|
; mysql: go-sql-driver/mysql dsn config string, e.g. `user:password@tcp(127.0.0.1)/database_name`
|
||||||
provider_config = data/sessions
|
provider_config = sessions
|
||||||
; Session cookie name
|
; Session cookie name
|
||||||
cookie_name = grafana_sess
|
cookie_name = grafana_sess
|
||||||
; If you use session in https only, default is false
|
; If you use session in https only, default is false
|
||||||
@ -109,10 +117,14 @@ token_url = https://accounts.google.com/o/oauth2/token
|
|||||||
; allowed_domains = mycompany.com othercompany.com
|
; allowed_domains = mycompany.com othercompany.com
|
||||||
|
|
||||||
[log]
|
[log]
|
||||||
root_path = data/log
|
; root_path
|
||||||
|
; for deb or rpm package installs this is specified via command line
|
||||||
|
; change it in /etc/default/grafana, it defaults to /var/log/grafana
|
||||||
|
; for non package installs (running manually) defaults to `log` dir under data_dir
|
||||||
|
root_path =
|
||||||
; Either "console", "file", default is "console"
|
; Either "console", "file", default is "console"
|
||||||
; Use comma to separate multiple modes, e.g. "console, file"
|
; Use comma to separate multiple modes, e.g. "console, file"
|
||||||
mode = console
|
mode = console, file
|
||||||
; Buffer length of channel, keep it as it is if you don't know what it is.
|
; Buffer length of channel, keep it as it is if you don't know what it is.
|
||||||
buffer_len = 10000
|
buffer_len = 10000
|
||||||
; Either "Trace", "Debug", "Info", "Warn", "Error", "Critical", default is "Trace"
|
; Either "Trace", "Debug", "Info", "Warn", "Error", "Critical", default is "Trace"
|
||||||
|
@ -5,6 +5,11 @@
|
|||||||
|
|
||||||
app_mode = production
|
app_mode = production
|
||||||
|
|
||||||
|
; data_path (used for sqlite3 db (if that is used), temp png images, and sessions (if file based sessions are used)
|
||||||
|
; this option is passed via command line args, override this option in /etc/default/grafana
|
||||||
|
; defaults to /opt/grafana/data
|
||||||
|
data_path =
|
||||||
|
|
||||||
[server]
|
[server]
|
||||||
; protocol (http or https)
|
; protocol (http or https)
|
||||||
protocol = http
|
protocol = http
|
||||||
@ -42,18 +47,18 @@ user = root
|
|||||||
password =
|
password =
|
||||||
; For "postgres" only, either "disable", "require" or "verify-full"
|
; For "postgres" only, either "disable", "require" or "verify-full"
|
||||||
ssl_mode = disable
|
ssl_mode = disable
|
||||||
; For "sqlite3" only
|
; For "sqlite3" only, path is relative to data_dir
|
||||||
path = /opt/grafana/data/grafana.db
|
path = grafana.db
|
||||||
|
|
||||||
[session]
|
[session]
|
||||||
; Either "memory", "file", "redis", "mysql", default is "memory"
|
; Either "memory", "file", "redis", "mysql", default is "memory"
|
||||||
provider = file
|
provider = file
|
||||||
; Provider config options
|
; Provider config options
|
||||||
; memory: not have any config yet
|
; memory: not have any config yet
|
||||||
; file: session file path, e.g. `data/sessions`
|
; file: session file path, e.g. `sessions`, relative to data_dir
|
||||||
; redis: config like redis server addr, poolSize, password, e.g. `127.0.0.1:6379,100,grafana`
|
; 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`
|
; mysql: go-sql-driver/mysql dsn config string, e.g. `user:password@tcp(127.0.0.1)/database_name`
|
||||||
provider_config = /opt/grafana/data/sessions
|
provider_config = sessions
|
||||||
; Session cookie name
|
; Session cookie name
|
||||||
cookie_name = grafana_sess
|
cookie_name = grafana_sess
|
||||||
; If you use session in https only, default is false
|
; If you use session in https only, default is false
|
||||||
@ -95,5 +100,8 @@ org_role = Viewer
|
|||||||
; Either "Trace", "Debug", "Info", "Warn", "Error", "Critical", default is "Trace"
|
; Either "Trace", "Debug", "Info", "Warn", "Error", "Critical", default is "Trace"
|
||||||
level = Info
|
level = Info
|
||||||
mode = console, file
|
mode = console, file
|
||||||
root_path = /var/log/grafana
|
; root_path, this option is passed via command line args,
|
||||||
|
; override this option in /etc/default/grafana
|
||||||
|
; defaults to /var/log/grafana/
|
||||||
|
root_path =
|
||||||
|
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
FROM debian
|
FROM debian:jessie
|
||||||
|
|
||||||
ADD *.deb /tmp/
|
ADD *.deb /tmp/
|
||||||
|
|
||||||
|
8
main.go
8
main.go
@ -45,6 +45,14 @@ func main() {
|
|||||||
Name: "config",
|
Name: "config",
|
||||||
Usage: "path to grafana.ini config file",
|
Usage: "path to grafana.ini config file",
|
||||||
},
|
},
|
||||||
|
cli.StringFlag{
|
||||||
|
Name: "default-data-path",
|
||||||
|
Usage: "change default path to where grafana can store data",
|
||||||
|
},
|
||||||
|
cli.StringFlag{
|
||||||
|
Name: "default-log-path",
|
||||||
|
Usage: "change default path to where grafana can log files",
|
||||||
|
},
|
||||||
cli.StringFlag{
|
cli.StringFlag{
|
||||||
Name: "pidfile",
|
Name: "pidfile",
|
||||||
Usage: "path to pidfile",
|
Usage: "path to pidfile",
|
||||||
|
64
packaging/deb/control/postinst
Executable file
64
packaging/deb/control/postinst
Executable file
@ -0,0 +1,64 @@
|
|||||||
|
#!/bin/sh
|
||||||
|
|
||||||
|
set -e
|
||||||
|
|
||||||
|
[ -f /etc/default/grafana ] && . /etc/default/grafana
|
||||||
|
|
||||||
|
startGrafana() {
|
||||||
|
if [ -x /bin/systemctl ] ; then
|
||||||
|
/bin/systemctl daemon-reload
|
||||||
|
/bin/systemctl start grafana.service
|
||||||
|
elif [ -x "/etc/init.d/grafana" ]; then
|
||||||
|
if [ -x "`which invoke-rc.d 2>/dev/null`" ]; then
|
||||||
|
invoke-rc.d grafana start || true
|
||||||
|
else
|
||||||
|
/etc/init.d/grafana start || true
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
case "$1" in
|
||||||
|
configure)
|
||||||
|
[ -z "$GRAFANA_USER" ] && GRAFANA_USER="grafana"
|
||||||
|
[ -z "$GRAFANA_GROUP" ] && GRAFANA_GROUP="grafana"
|
||||||
|
if ! getent group "$GRAFANA_GROUP" > /dev/null 2>&1 ; then
|
||||||
|
addgroup --system "$GRAFANA_GROUP" --quiet
|
||||||
|
fi
|
||||||
|
if ! id $GRAFANA_USER > /dev/null 2>&1 ; then
|
||||||
|
adduser --system --home /usr/share/grafana --no-create-home \
|
||||||
|
--ingroup "$GRAFANA_GROUP" --disabled-password --shell /bin/false \
|
||||||
|
"$GRAFANA_USER"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Set user permissions on /var/log/grafana, /opt/grafana/data
|
||||||
|
mkdir -p /var/log/grafana /opt/grafana/data
|
||||||
|
chown -R $GRAFANA_USER:$GRAFANA_GROUP /var/log/grafana /opt/grafana/data
|
||||||
|
chmod 755 /var/log/grafana /opt/grafana/data
|
||||||
|
|
||||||
|
# configuration files should not be modifiable by elasticsearch user, as this can be a security issue
|
||||||
|
chown -Rh root:root /etc/grafana/*
|
||||||
|
chmod 755 /etc/grafana
|
||||||
|
find /etc/grafana -type f -exec chmod 644 {} ';'
|
||||||
|
find /etc/grafana -type d -exec chmod 755 {} ';'
|
||||||
|
|
||||||
|
# if $2 is set, this is an upgrade
|
||||||
|
if ( [ -n $2 ] && [ "$RESTART_ON_UPGRADE" = "true" ] ) ; then
|
||||||
|
startGrafana
|
||||||
|
# this is a fresh installation
|
||||||
|
elif [ -z $2 ] ; then
|
||||||
|
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"
|
||||||
|
|
||||||
|
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"
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
;;
|
||||||
|
esac
|
15
packaging/deb/default/grafana
Normal file
15
packaging/deb/default/grafana
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
|
||||||
|
#GRAFANA_USER=grafana
|
||||||
|
|
||||||
|
#GRAFANA_GROUP=grafana
|
||||||
|
|
||||||
|
#LOG_DIR=/var/log/grafana
|
||||||
|
|
||||||
|
#GRAFANA_HOME=/opt/grafana
|
||||||
|
#DATA_DIR=/opt/data/grafana
|
||||||
|
#WORK_DIR=/opt/grafana
|
||||||
|
|
||||||
|
#CONF_DIR=/etc/grafana
|
||||||
|
#CONF_FILE=/etc/grafana/grafana.ini
|
||||||
|
|
||||||
|
#RESTART_ON_UPGRADE=true
|
140
packaging/deb/init.d/grafana
Executable file
140
packaging/deb/init.d/grafana
Executable file
@ -0,0 +1,140 @@
|
|||||||
|
#! /usr/bin/env bash
|
||||||
|
|
||||||
|
# chkconfig: 2345 80 05
|
||||||
|
# description: Grafana web server & backend
|
||||||
|
# processname: grafana
|
||||||
|
# config: /etc/grafana/grafana.ini
|
||||||
|
# pidfile: /var/run/grafana.pid
|
||||||
|
|
||||||
|
### BEGIN INIT INFO
|
||||||
|
# Provides: grafana
|
||||||
|
# Required-Start: $all
|
||||||
|
# Required-Stop: $remote_fs $syslog
|
||||||
|
# Default-Start: 2 3 4 5
|
||||||
|
# Default-Stop: 0 1 6
|
||||||
|
# Short-Description: Start grafana at boot time
|
||||||
|
### END INIT INFO
|
||||||
|
|
||||||
|
# tested on
|
||||||
|
# 1. New lsb that define start-stop-daemon
|
||||||
|
# 3. Centos with initscripts package installed
|
||||||
|
|
||||||
|
PATH=/bin:/usr/bin:/sbin:/usr/sbin
|
||||||
|
NAME=grafana
|
||||||
|
DESC="Grafana Server"
|
||||||
|
DEFAULT=/etc/default/$NAME
|
||||||
|
|
||||||
|
if [ `id -u` -ne 0 ]; then
|
||||||
|
echo "You need root privileges to run this script"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
. /lib/lsb/init-functions
|
||||||
|
|
||||||
|
if [ -r /etc/default/rcS ]; then
|
||||||
|
. /etc/default/rcS
|
||||||
|
fi
|
||||||
|
|
||||||
|
GRAFANA_USER=grafana
|
||||||
|
GRAFANA_GROUP=grafana
|
||||||
|
GRAFANA_HOME=/opt/$NAME
|
||||||
|
CONF_DIR=/etc/$NAME
|
||||||
|
WORK_DIR=$GRAFANA_HOME
|
||||||
|
DATA_DIR=$GRAFANA_HOME/data
|
||||||
|
LOG_DIR=/var/log/$NAME
|
||||||
|
CONF_FILE=$CONF_DIR/grafana.ini
|
||||||
|
MAX_OPEN_FILES=65535
|
||||||
|
|
||||||
|
# overwrite settings from default file
|
||||||
|
if [ -f "$DEFAULT" ]; then
|
||||||
|
. "$DEFAULT"
|
||||||
|
fi
|
||||||
|
|
||||||
|
PID_FILE=/var/run/$NAME.pid
|
||||||
|
DAEMON=$GRAFANA_HOME/bin/grafana
|
||||||
|
DAEMON_OPTS="--pidfile=${PID_FILE} --config=${CONF_FILE} --default-data-path=${DATA_DIR} --default-log-path=${LOG_DIR} web"
|
||||||
|
|
||||||
|
# Check DAEMON exists
|
||||||
|
test -x $DAEMON || exit 0
|
||||||
|
|
||||||
|
case "$1" in
|
||||||
|
start)
|
||||||
|
|
||||||
|
log_daemon_msg "Starting $DESC"
|
||||||
|
|
||||||
|
pid=`pidofproc -p $PID_FILE grafana`
|
||||||
|
if [ -n "$pid" ] ; then
|
||||||
|
log_begin_msg "Already running."
|
||||||
|
log_end_msg 0
|
||||||
|
exit 0
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Prepare environment
|
||||||
|
mkdir -p "$LOG_DIR" "$DATA_DIR" "$WORK_DIR" && chown "$GRAFANA_USER":"$GRAFANA_GROUP" "$LOG_DIR" "$DATA_DIR" "$WORK_DIR"
|
||||||
|
touch "$PID_FILE" && chown "$GRAFANA_USER":"$GRAFANA_GROUP" "$PID_FILE"
|
||||||
|
|
||||||
|
if [ -n "$MAX_OPEN_FILES" ]; then
|
||||||
|
ulimit -n $MAX_OPEN_FILES
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Start Daemon
|
||||||
|
start-stop-daemon --start -b --chdir "$WORK_DIR" --user "$GRAFANA_USER" -c "$GRAFANA_USER" --pidfile "$PID_FILE" --exec $DAEMON -- $DAEMON_OPTS
|
||||||
|
return=$?
|
||||||
|
if [ $return -eq 0 ]
|
||||||
|
then
|
||||||
|
sleep 1
|
||||||
|
|
||||||
|
# check if pid file has been written two
|
||||||
|
if ! [[ -s $PID_FILE ]]; then
|
||||||
|
log_end_msg 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
i=0
|
||||||
|
timeout=10
|
||||||
|
# Wait for the process to be properly started before exiting
|
||||||
|
until { cat "$PID_FILE" | xargs kill -0; } >/dev/null 2>&1
|
||||||
|
do
|
||||||
|
sleep 1
|
||||||
|
i=$(($i + 1))
|
||||||
|
[ $i -gt $timeout ] && log_end_msg 1
|
||||||
|
done
|
||||||
|
fi
|
||||||
|
log_end_msg $return
|
||||||
|
;;
|
||||||
|
stop)
|
||||||
|
log_daemon_msg "Stopping $DESC"
|
||||||
|
|
||||||
|
if [ -f "$PID_FILE" ]; then
|
||||||
|
start-stop-daemon --stop --pidfile "$PID_FILE" \
|
||||||
|
--user "$GRAFANA_USER" \
|
||||||
|
--retry=TERM/20/KILL/5 >/dev/null
|
||||||
|
if [ $? -eq 1 ]; then
|
||||||
|
log_progress_msg "$DESC is not running but pid file exists, cleaning up"
|
||||||
|
elif [ $? -eq 3 ]; then
|
||||||
|
PID="`cat $PID_FILE`"
|
||||||
|
log_failure_msg "Failed to stop $DESC (pid $PID)"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
rm -f "$PID_FILE"
|
||||||
|
else
|
||||||
|
log_progress_msg "(not running)"
|
||||||
|
fi
|
||||||
|
log_end_msg 0
|
||||||
|
;;
|
||||||
|
status)
|
||||||
|
status_of_proc -p $PID_FILE grafana grafana && exit 0 || exit $?
|
||||||
|
;;
|
||||||
|
restart|force-reload)
|
||||||
|
if [ -f "$PID_FILE" ]; then
|
||||||
|
$0 stop
|
||||||
|
sleep 1
|
||||||
|
fi
|
||||||
|
$0 start
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
log_success_msg "Usage: $0 {start|stop|restart|force-reload|status}"
|
||||||
|
exit 1
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
|
||||||
|
exit 0
|
26
packaging/deb/systemd/grafana.service
Normal file
26
packaging/deb/systemd/grafana.service
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
[Unit]
|
||||||
|
Description=Starts and stops a single grafana instance on this system
|
||||||
|
Documentation=http://docs.grafana.org
|
||||||
|
Wants=network-online.target
|
||||||
|
After=network-online.target
|
||||||
|
|
||||||
|
[Service]
|
||||||
|
EnvironmentFile=/etc/default/elasticsearch
|
||||||
|
User=elasticsearch
|
||||||
|
Group=elasticsearch
|
||||||
|
ExecStart=/usr/share/elasticsearch/bin/elasticsearch \
|
||||||
|
-Des.default.config=$CONF_FILE \
|
||||||
|
-Des.default.path.home=$ES_HOME \
|
||||||
|
-Des.default.path.logs=$LOG_DIR \
|
||||||
|
-Des.default.path.data=$DATA_DIR \
|
||||||
|
-Des.default.path.work=$WORK_DIR \
|
||||||
|
-Des.default.path.conf=$CONF_DIR
|
||||||
|
# See MAX_OPEN_FILES in sysconfig
|
||||||
|
LimitNOFILE=65535
|
||||||
|
# See MAX_LOCKED_MEMORY in sysconfig, use "infinity" when MAX_LOCKED_MEMORY=unlimited and using bootstrap.mlockall: true
|
||||||
|
#LimitMEMLOCK=infinity
|
||||||
|
# Shutdown delay in seconds, before process is tried to be killed with KILL (if configured)
|
||||||
|
TimeoutStopSec=20
|
||||||
|
|
||||||
|
[Install]
|
||||||
|
WantedBy=multi-user.target
|
@ -10,12 +10,22 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
func initRuntime(c *cli.Context) {
|
func initRuntime(c *cli.Context) {
|
||||||
setting.NewConfigContext(c.GlobalString("config"))
|
var args = &setting.CommandLineArgs{
|
||||||
|
Config: c.GlobalString("config"),
|
||||||
|
DefaultDataPath: c.GlobalString("default-data-path"),
|
||||||
|
DefaultLogPath: c.GlobalString("default-log-path"),
|
||||||
|
}
|
||||||
|
|
||||||
|
setting.NewConfigContext(args)
|
||||||
|
|
||||||
log.Info("Starting Grafana")
|
log.Info("Starting Grafana")
|
||||||
log.Info("Version: %v, Commit: %v, Build date: %v", setting.BuildVersion, setting.BuildCommit, time.Unix(setting.BuildStamp, 0))
|
log.Info("Version: %v, Commit: %v, Build date: %v", setting.BuildVersion, setting.BuildCommit, time.Unix(setting.BuildStamp, 0))
|
||||||
setting.LogLoadedConfigFiles()
|
setting.LogLoadedConfigFiles()
|
||||||
|
|
||||||
|
log.Info("Working Path: %s", setting.WorkPath)
|
||||||
|
log.Info("Data Path: %s", setting.DataPath)
|
||||||
|
log.Info("Log Path: %s", setting.LogRootPath)
|
||||||
|
|
||||||
sqlstore.NewEngine()
|
sqlstore.NewEngine()
|
||||||
sqlstore.EnsureAdminUser()
|
sqlstore.EnsureAdminUser()
|
||||||
}
|
}
|
||||||
|
@ -4,6 +4,7 @@ import (
|
|||||||
"fmt"
|
"fmt"
|
||||||
"os"
|
"os"
|
||||||
"path"
|
"path"
|
||||||
|
"path/filepath"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"github.com/grafana/grafana/pkg/bus"
|
"github.com/grafana/grafana/pkg/bus"
|
||||||
@ -126,6 +127,9 @@ func getEngine() (*xorm.Engine, error) {
|
|||||||
cnnstr = fmt.Sprintf("user=%s password=%s host=%s port=%s dbname=%s sslmode=%s",
|
cnnstr = fmt.Sprintf("user=%s password=%s host=%s port=%s dbname=%s sslmode=%s",
|
||||||
DbCfg.User, DbCfg.Pwd, host, port, DbCfg.Name, DbCfg.SslMode)
|
DbCfg.User, DbCfg.Pwd, host, port, DbCfg.Name, DbCfg.SslMode)
|
||||||
case "sqlite3":
|
case "sqlite3":
|
||||||
|
if !filepath.IsAbs(DbCfg.Path) {
|
||||||
|
DbCfg.Path = filepath.Join(setting.DataPath, DbCfg.Path)
|
||||||
|
}
|
||||||
os.MkdirAll(path.Dir(DbCfg.Path), os.ModePerm)
|
os.MkdirAll(path.Dir(DbCfg.Path), os.ModePerm)
|
||||||
cnnstr = "file:" + DbCfg.Path + "?cache=shared&mode=rwc&_loc=Local"
|
cnnstr = "file:" + DbCfg.Path + "?cache=shared&mode=rwc&_loc=Local"
|
||||||
default:
|
default:
|
||||||
|
@ -83,12 +83,10 @@ var (
|
|||||||
SessionOptions session.Options
|
SessionOptions session.Options
|
||||||
|
|
||||||
// Global setting objects.
|
// Global setting objects.
|
||||||
WorkDir string
|
DataPath string
|
||||||
|
WorkPath string
|
||||||
Cfg *ini.File
|
Cfg *ini.File
|
||||||
ConfRootPath string
|
ConfRootPath string
|
||||||
CustomPath string // Custom directory path.
|
|
||||||
ProdMode bool
|
|
||||||
RunUser string
|
|
||||||
IsWindows bool
|
IsWindows bool
|
||||||
|
|
||||||
// PhantomJs Rendering
|
// PhantomJs Rendering
|
||||||
@ -101,14 +99,20 @@ var (
|
|||||||
GoogleAnalyticsId string
|
GoogleAnalyticsId string
|
||||||
)
|
)
|
||||||
|
|
||||||
|
type CommandLineArgs struct {
|
||||||
|
DefaultDataPath string
|
||||||
|
DefaultLogPath string
|
||||||
|
Config string
|
||||||
|
}
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
IsWindows = runtime.GOOS == "windows"
|
IsWindows = runtime.GOOS == "windows"
|
||||||
log.NewLogger(0, "console", `{"level": 0}`)
|
log.NewLogger(0, "console", `{"level": 0}`)
|
||||||
WorkDir, _ = filepath.Abs(".")
|
WorkPath, _ = filepath.Abs(".")
|
||||||
}
|
}
|
||||||
|
|
||||||
func findConfigFiles(customConfigFile string) {
|
func findConfigFiles(customConfigFile string) {
|
||||||
ConfRootPath = path.Join(WorkDir, "conf")
|
ConfRootPath = path.Join(WorkPath, "conf")
|
||||||
configFiles = make([]string, 0)
|
configFiles = make([]string, 0)
|
||||||
|
|
||||||
configFile := path.Join(ConfRootPath, "defaults.ini")
|
configFile := path.Join(ConfRootPath, "defaults.ini")
|
||||||
@ -171,8 +175,8 @@ func loadEnvVariableOverrides() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewConfigContext(config string) {
|
func NewConfigContext(args *CommandLineArgs) {
|
||||||
findConfigFiles(config)
|
findConfigFiles(args.Config)
|
||||||
|
|
||||||
var err error
|
var err error
|
||||||
|
|
||||||
@ -190,7 +194,19 @@ func NewConfigContext(config string) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
loadEnvVariableOverrides()
|
loadEnvVariableOverrides()
|
||||||
initLogging()
|
|
||||||
|
DataPath = Cfg.Section("").Key("data_path").String()
|
||||||
|
// if no data path in config, use command line, otherwise default to
|
||||||
|
// data folder relative to working dir
|
||||||
|
if DataPath == "" {
|
||||||
|
if args.DefaultDataPath != "" {
|
||||||
|
DataPath = args.DefaultDataPath
|
||||||
|
} else {
|
||||||
|
DataPath = filepath.Join(WorkPath, "data")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
initLogging(args)
|
||||||
|
|
||||||
AppName = Cfg.Section("").Key("app_name").MustString("Grafana")
|
AppName = Cfg.Section("").Key("app_name").MustString("Grafana")
|
||||||
Env = Cfg.Section("").Key("app_mode").MustString("development")
|
Env = Cfg.Section("").Key("app_mode").MustString("development")
|
||||||
@ -209,7 +225,7 @@ func NewConfigContext(config string) {
|
|||||||
HttpAddr = server.Key("http_addr").MustString("0.0.0.0")
|
HttpAddr = server.Key("http_addr").MustString("0.0.0.0")
|
||||||
HttpPort = server.Key("http_port").MustString("3000")
|
HttpPort = server.Key("http_port").MustString("3000")
|
||||||
|
|
||||||
StaticRootPath = server.Key("static_root_path").MustString(path.Join(WorkDir, "webapp"))
|
StaticRootPath = server.Key("static_root_path").MustString(path.Join(WorkPath, "public"))
|
||||||
RouterLogging = server.Key("router_logging").MustBool(false)
|
RouterLogging = server.Key("router_logging").MustBool(false)
|
||||||
EnableGzip = server.Key("enable_gzip").MustBool(false)
|
EnableGzip = server.Key("enable_gzip").MustBool(false)
|
||||||
|
|
||||||
@ -234,8 +250,8 @@ func NewConfigContext(config string) {
|
|||||||
AnonymousOrgRole = Cfg.Section("auth.anonymous").Key("org_role").String()
|
AnonymousOrgRole = Cfg.Section("auth.anonymous").Key("org_role").String()
|
||||||
|
|
||||||
// PhantomJS rendering
|
// PhantomJS rendering
|
||||||
ImagesDir = "data/png"
|
ImagesDir = filepath.Join(DataPath, "png")
|
||||||
PhantomDir = "vendor/phantomjs"
|
PhantomDir = filepath.Join(WorkPath, "vendor/phantomjs")
|
||||||
|
|
||||||
analytics := Cfg.Section("analytics")
|
analytics := Cfg.Section("analytics")
|
||||||
ReportingEnabled = analytics.Key("reporting_enabled").MustBool(true)
|
ReportingEnabled = analytics.Key("reporting_enabled").MustBool(true)
|
||||||
@ -257,6 +273,9 @@ func readSessionConfig() {
|
|||||||
SessionOptions.IDLength = 16
|
SessionOptions.IDLength = 16
|
||||||
|
|
||||||
if SessionOptions.Provider == "file" {
|
if SessionOptions.Provider == "file" {
|
||||||
|
if !filepath.IsAbs(SessionOptions.ProviderConfig) {
|
||||||
|
SessionOptions.ProviderConfig = filepath.Join(DataPath, SessionOptions.ProviderConfig)
|
||||||
|
}
|
||||||
os.MkdirAll(path.Dir(SessionOptions.ProviderConfig), os.ModePerm)
|
os.MkdirAll(path.Dir(SessionOptions.ProviderConfig), os.ModePerm)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -274,10 +293,18 @@ var logLevels = map[string]string{
|
|||||||
"Critical": "5",
|
"Critical": "5",
|
||||||
}
|
}
|
||||||
|
|
||||||
func initLogging() {
|
func initLogging(args *CommandLineArgs) {
|
||||||
// Get and check log mode.
|
// Get and check log mode.
|
||||||
LogModes = strings.Split(Cfg.Section("log").Key("mode").MustString("console"), ",")
|
LogModes = strings.Split(Cfg.Section("log").Key("mode").MustString("console"), ",")
|
||||||
LogRootPath = Cfg.Section("log").Key("root_path").MustString(path.Join(WorkDir, "/data/log"))
|
LogRootPath = Cfg.Section("log").Key("root_path").String()
|
||||||
|
if LogRootPath == "" {
|
||||||
|
if args.DefaultLogPath != "" {
|
||||||
|
LogRootPath = args.DefaultLogPath
|
||||||
|
} else {
|
||||||
|
LogRootPath = filepath.Join(DataPath, "log")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
LogConfigs = make([]string, len(LogModes))
|
LogConfigs = make([]string, len(LogModes))
|
||||||
for i, mode := range LogModes {
|
for i, mode := range LogModes {
|
||||||
mode = strings.TrimSpace(mode)
|
mode = strings.TrimSpace(mode)
|
||||||
|
174
scripts/init.sh
174
scripts/init.sh
@ -1,174 +0,0 @@
|
|||||||
#! /usr/bin/env bash
|
|
||||||
|
|
||||||
# chkconfig: 2345 80 05
|
|
||||||
# description: Grafana web server & backend
|
|
||||||
# processname: grafana
|
|
||||||
# config: /etc/grafana/grafana.ini
|
|
||||||
# pidfile: /var/run/grafana.pid
|
|
||||||
|
|
||||||
### BEGIN INIT INFO
|
|
||||||
# Provides: grafana
|
|
||||||
# Required-Start: $all
|
|
||||||
# Required-Stop: $remote_fs $syslog
|
|
||||||
# Default-Start: 2 3 4 5
|
|
||||||
# Default-Stop: 0 1 6
|
|
||||||
# Short-Description: Start grafana at boot time
|
|
||||||
### END INIT INFO
|
|
||||||
|
|
||||||
# tested on
|
|
||||||
# 1. New lsb that define start-stop-daemon
|
|
||||||
# 3. Centos with initscripts package installed
|
|
||||||
|
|
||||||
if [ -r /lib/lsb/init-functions ]; then
|
|
||||||
source /lib/lsb/init-functions
|
|
||||||
fi
|
|
||||||
|
|
||||||
DAEMON_NAME="grafana"
|
|
||||||
DAEMON_USER="grafana"
|
|
||||||
DAEMON_PATH="/opt/grafana/current/grafana"
|
|
||||||
DAEMON_OPTS="--config=/etc/grafana/grafana.ini web"
|
|
||||||
DAEMON_PWD="/opt/grafana/current"
|
|
||||||
DAEMON_PID="/var/run/${DAEMON_NAME}.pid"
|
|
||||||
DAEMON_NICE=0
|
|
||||||
DAEMON_LOG='/var/log/grafana/grafana.log'
|
|
||||||
|
|
||||||
# If the daemon is not there, then exit.
|
|
||||||
[ -x $DAEMON_PATH ] || exit 5
|
|
||||||
|
|
||||||
if [ "x$STDOUT" == "x" ]; then
|
|
||||||
STDOUT=/tmp/grafana.log
|
|
||||||
fi
|
|
||||||
|
|
||||||
function pidofproc() {
|
|
||||||
if [ $# -ne 3 ]; then
|
|
||||||
echo "Expected three arguments, e.g. $0 -p pidfile daemon-name"
|
|
||||||
fi
|
|
||||||
|
|
||||||
pid=`pgrep -f $3`
|
|
||||||
local pidfile=`cat $2`
|
|
||||||
|
|
||||||
if [ "x$pidfile" == "x" ]; then
|
|
||||||
return 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
if [ "x$pid" != "x" -a "$pidfile" == "$pid" ]; then
|
|
||||||
return 0
|
|
||||||
fi
|
|
||||||
|
|
||||||
return 1
|
|
||||||
}
|
|
||||||
|
|
||||||
function killproc() {
|
|
||||||
if [ $# -ne 3 ]; then
|
|
||||||
echo "Expected three arguments, e.g. $0 -p pidfile signal"
|
|
||||||
fi
|
|
||||||
|
|
||||||
pid=`cat $2`
|
|
||||||
|
|
||||||
kill -s $3 $pid
|
|
||||||
}
|
|
||||||
|
|
||||||
function log_failure_msg() {
|
|
||||||
echo "$@" "[ FAILED ]"
|
|
||||||
}
|
|
||||||
|
|
||||||
function log_success_msg() {
|
|
||||||
echo "$@" "[ OK ]"
|
|
||||||
}
|
|
||||||
|
|
||||||
do_start() {
|
|
||||||
cd $DAEMON_PWD
|
|
||||||
|
|
||||||
# Checked the PID file exists and check the actual status of process
|
|
||||||
if [ -e $DAEMON_PID ]; then
|
|
||||||
pidofproc -p $DAEMON_PID $DAEMON_PATH > /dev/null 2>&1 && status="0" || status="$?"
|
|
||||||
# If the status is SUCCESS then don't need to start again.
|
|
||||||
if [ "x$status" = "x0" ]; then
|
|
||||||
log_failure_msg "$DAEMON_NAME process is running"
|
|
||||||
exit 1 # Exit
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
# Start the daemon.
|
|
||||||
log_success_msg "Starting the process" "$DAEMON_NAME"
|
|
||||||
|
|
||||||
# Start the daemon with the help of start-stop-daemon
|
|
||||||
# Log the message appropriately
|
|
||||||
if which start-stop-daemon > /dev/null 2>&1; then
|
|
||||||
start-stop-daemon \
|
|
||||||
--start --quiet --oknodo --background \
|
|
||||||
--nicelevel $DAEMON_NICE \
|
|
||||||
--chdir "${DAEMON_PWD}" \
|
|
||||||
--pidfile "${DAEMON_PID}" --make-pidfile \
|
|
||||||
--chuid "${DAEMON_USER}" \
|
|
||||||
--exec "${DAEMON_PATH}" -- $DAEMON_OPTS
|
|
||||||
result=$?
|
|
||||||
else
|
|
||||||
touch ${DAEMON_PID}
|
|
||||||
chown $DAEMON_USER "${DAEMON_PID}"
|
|
||||||
#daemon --user $DAEMON_USER --pidfile $DAEMON_PID nohup $DAEMON_PATH $DAEMON_OPTS
|
|
||||||
su -s /bin/sh -c "nohup ${DAEMON_PATH} --pidfile=${DAEMON_PID} ${DAEMON_OPTS} >> $STDOUT 3>&1 &" $DAEMON_USER
|
|
||||||
fi
|
|
||||||
|
|
||||||
log_success_msg "$DAEMON_NAME process was started"
|
|
||||||
}
|
|
||||||
|
|
||||||
do_stop() {
|
|
||||||
local result
|
|
||||||
|
|
||||||
pidofproc -p "${DAEMON_PID}" "${DAEMON_PATH}" > /dev/null
|
|
||||||
if [ $? -ne 0 ]; then
|
|
||||||
log_failure_msg "${DAEMON_NAME} is not started"
|
|
||||||
result=0
|
|
||||||
else
|
|
||||||
log_success_msg "Stopping ${DAEMON_NAME}"
|
|
||||||
killproc -p "${DAEMON_PID}" SIGTERM
|
|
||||||
result=$?
|
|
||||||
if [ $result = 0 ]; then
|
|
||||||
log_success_msg "Stopped ${DAEMON_NAME}"
|
|
||||||
rm "${DAEMON_PID}"
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
|
|
||||||
return $result
|
|
||||||
}
|
|
||||||
|
|
||||||
do_restart() {
|
|
||||||
local result
|
|
||||||
do_stop
|
|
||||||
result=$?
|
|
||||||
sleep 2
|
|
||||||
if [ $result = 0 ]; then
|
|
||||||
do_start
|
|
||||||
result=$?
|
|
||||||
fi
|
|
||||||
return $result
|
|
||||||
}
|
|
||||||
|
|
||||||
do_status() {
|
|
||||||
if [ -e $DEAMON_PID ]; then
|
|
||||||
pidofproc -p "${DAEMON_PID}" "${DAEMON_PATH}" > /dev/null
|
|
||||||
if [ $? -ne 0 ]; then
|
|
||||||
log_failure_msg "$DAEMON_NAME Process is not running"
|
|
||||||
exit 1
|
|
||||||
else
|
|
||||||
log_success_msg "$DAEMON_NAME Process is running"
|
|
||||||
exit 0
|
|
||||||
fi
|
|
||||||
else
|
|
||||||
log_failure_msg "$DAEMON_NAME Process is not running"
|
|
||||||
exit 3
|
|
||||||
fi
|
|
||||||
}
|
|
||||||
|
|
||||||
do_usage() {
|
|
||||||
echo $"Usage: $0 {start | stop | restart | status}"
|
|
||||||
exit 1
|
|
||||||
}
|
|
||||||
|
|
||||||
case "$1" in
|
|
||||||
start) do_start; exit $? ;;
|
|
||||||
stop) do_stop; exit $? ;;
|
|
||||||
restart) do_restart; exit $? ;;
|
|
||||||
status) do_status; exit $? ;;
|
|
||||||
*) do_usage; exit 1 ;;
|
|
||||||
esac
|
|
@ -57,7 +57,7 @@ module.exports = function(grunt) {
|
|||||||
expand: true,
|
expand: true,
|
||||||
src: ['grafana'],
|
src: ['grafana'],
|
||||||
options: { mode: true},
|
options: { mode: true},
|
||||||
dest: '<%= tempDir %>'
|
dest: '<%= tempDir %>/bin/'
|
||||||
});
|
});
|
||||||
grunt.config('copy.backend_files', {
|
grunt.config('copy.backend_files', {
|
||||||
expand: true,
|
expand: true,
|
||||||
|
Reference in New Issue
Block a user