diff --git a/build.go b/build.go index 4ee59928d67..6d9ce40a2c0 100644 --- a/build.go +++ b/build.go @@ -73,7 +73,7 @@ func main() { case "package": //verifyGitRepoIsClean() - grunt("release", "--pkgVer="+version) + //grunt("release", "--pkgVer="+version) createRpmAndDeb() case "latest": @@ -114,32 +114,39 @@ func readVersionFromPackageJson() { func createRpmAndDeb() { 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) - runError("mkdir", "-p", versionFolder) + runError("mkdir", "-p", packageInstallRoot) 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 configFile := filepath.Join(configDir, "grafana.ini") 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{ "-s", "dir", "--description", "Grafana", "-C", packageRoot, "--vendor", "Grafana", + "--depends", "adduser", "--url", "http://grafana.org", "--license", "Apache 2.0", "--maintainer", "contact@grafana.org", "--config-files", filepath.Join(configRoot, "grafana.ini"), - "--after-install", postInstallScriptPath.Name(), + "--after-install", afterInstallScript, "--name", "grafana", "--version", version, "-p", "./dist", @@ -153,37 +160,6 @@ func createRpmAndDeb() { 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() { rs, err := runError("git", "ls-files", "--modified") if err != nil { diff --git a/conf/defaults.ini b/conf/defaults.ini index 182af44ac5f..d9f84196fde 100644 --- a/conf/defaults.ini +++ b/conf/defaults.ini @@ -1,6 +1,14 @@ app_name = Grafana 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] ; protocol (http or https) protocol = http @@ -39,18 +47,18 @@ user = root password = ; For "postgres" only, either "disable", "require" or "verify-full" ssl_mode = disable -; For "sqlite3" only -path = data/grafana.db +; For "sqlite3" only, path relative to data_dir setting +path = grafana.db [session] ; Either "memory", "file", "redis", "mysql", default is "memory" provider = file ; Provider config options ; 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` ; 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 cookie_name = grafana_sess ; 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 [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" ; 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_len = 10000 ; Either "Trace", "Debug", "Info", "Warn", "Error", "Critical", default is "Trace" diff --git a/conf/sample.ini b/conf/sample.ini index bc312fdfc49..8ab6628014b 100644 --- a/conf/sample.ini +++ b/conf/sample.ini @@ -5,6 +5,11 @@ 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] ; protocol (http or https) protocol = http @@ -42,18 +47,18 @@ user = root password = ; For "postgres" only, either "disable", "require" or "verify-full" ssl_mode = disable -; For "sqlite3" only -path = /opt/grafana/data/grafana.db +; For "sqlite3" only, path is relative to data_dir +path = grafana.db [session] ; Either "memory", "file", "redis", "mysql", default is "memory" provider = file ; Provider config options ; 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` ; 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 cookie_name = grafana_sess ; 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" level = Info 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 = diff --git a/docker/debtest/Dockerfile b/docker/debtest/Dockerfile index 0d32380194c..30c5f3d08c9 100644 --- a/docker/debtest/Dockerfile +++ b/docker/debtest/Dockerfile @@ -1,4 +1,4 @@ -FROM debian +FROM debian:jessie ADD *.deb /tmp/ diff --git a/main.go b/main.go index 3b25b73039d..2ce47f97ded 100644 --- a/main.go +++ b/main.go @@ -45,6 +45,14 @@ func main() { Name: "config", 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{ Name: "pidfile", Usage: "path to pidfile", diff --git a/packaging/deb/control/postinst b/packaging/deb/control/postinst new file mode 100755 index 00000000000..c52a5b384bd --- /dev/null +++ b/packaging/deb/control/postinst @@ -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 diff --git a/packaging/deb/default/grafana b/packaging/deb/default/grafana new file mode 100644 index 00000000000..06de8b5a946 --- /dev/null +++ b/packaging/deb/default/grafana @@ -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 diff --git a/packaging/deb/init.d/grafana b/packaging/deb/init.d/grafana new file mode 100755 index 00000000000..c0ca534fbc8 --- /dev/null +++ b/packaging/deb/init.d/grafana @@ -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 diff --git a/packaging/deb/systemd/grafana.service b/packaging/deb/systemd/grafana.service new file mode 100644 index 00000000000..5635939f0f0 --- /dev/null +++ b/packaging/deb/systemd/grafana.service @@ -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 diff --git a/pkg/cmd/common.go b/pkg/cmd/common.go index 3caa8350700..c5882484f92 100644 --- a/pkg/cmd/common.go +++ b/pkg/cmd/common.go @@ -10,12 +10,22 @@ import ( ) 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("Version: %v, Commit: %v, Build date: %v", setting.BuildVersion, setting.BuildCommit, time.Unix(setting.BuildStamp, 0)) 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.EnsureAdminUser() } diff --git a/pkg/services/sqlstore/sqlstore.go b/pkg/services/sqlstore/sqlstore.go index 609a4d9fb9e..40e54a827e5 100644 --- a/pkg/services/sqlstore/sqlstore.go +++ b/pkg/services/sqlstore/sqlstore.go @@ -4,6 +4,7 @@ import ( "fmt" "os" "path" + "path/filepath" "strings" "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", DbCfg.User, DbCfg.Pwd, host, port, DbCfg.Name, DbCfg.SslMode) case "sqlite3": + if !filepath.IsAbs(DbCfg.Path) { + DbCfg.Path = filepath.Join(setting.DataPath, DbCfg.Path) + } os.MkdirAll(path.Dir(DbCfg.Path), os.ModePerm) cnnstr = "file:" + DbCfg.Path + "?cache=shared&mode=rwc&_loc=Local" default: diff --git a/pkg/setting/setting.go b/pkg/setting/setting.go index 107a0147385..5a6f788385f 100644 --- a/pkg/setting/setting.go +++ b/pkg/setting/setting.go @@ -83,12 +83,10 @@ var ( SessionOptions session.Options // Global setting objects. - WorkDir string + DataPath string + WorkPath string Cfg *ini.File ConfRootPath string - CustomPath string // Custom directory path. - ProdMode bool - RunUser string IsWindows bool // PhantomJs Rendering @@ -101,14 +99,20 @@ var ( GoogleAnalyticsId string ) +type CommandLineArgs struct { + DefaultDataPath string + DefaultLogPath string + Config string +} + func init() { IsWindows = runtime.GOOS == "windows" log.NewLogger(0, "console", `{"level": 0}`) - WorkDir, _ = filepath.Abs(".") + WorkPath, _ = filepath.Abs(".") } func findConfigFiles(customConfigFile string) { - ConfRootPath = path.Join(WorkDir, "conf") + ConfRootPath = path.Join(WorkPath, "conf") configFiles = make([]string, 0) configFile := path.Join(ConfRootPath, "defaults.ini") @@ -171,8 +175,8 @@ func loadEnvVariableOverrides() { } } -func NewConfigContext(config string) { - findConfigFiles(config) +func NewConfigContext(args *CommandLineArgs) { + findConfigFiles(args.Config) var err error @@ -190,7 +194,19 @@ func NewConfigContext(config string) { } 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") 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") 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) EnableGzip = server.Key("enable_gzip").MustBool(false) @@ -234,8 +250,8 @@ func NewConfigContext(config string) { AnonymousOrgRole = Cfg.Section("auth.anonymous").Key("org_role").String() // PhantomJS rendering - ImagesDir = "data/png" - PhantomDir = "vendor/phantomjs" + ImagesDir = filepath.Join(DataPath, "png") + PhantomDir = filepath.Join(WorkPath, "vendor/phantomjs") analytics := Cfg.Section("analytics") ReportingEnabled = analytics.Key("reporting_enabled").MustBool(true) @@ -257,6 +273,9 @@ func readSessionConfig() { SessionOptions.IDLength = 16 if SessionOptions.Provider == "file" { + if !filepath.IsAbs(SessionOptions.ProviderConfig) { + SessionOptions.ProviderConfig = filepath.Join(DataPath, SessionOptions.ProviderConfig) + } os.MkdirAll(path.Dir(SessionOptions.ProviderConfig), os.ModePerm) } @@ -274,10 +293,18 @@ var logLevels = map[string]string{ "Critical": "5", } -func initLogging() { +func initLogging(args *CommandLineArgs) { // Get and check log mode. 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)) for i, mode := range LogModes { mode = strings.TrimSpace(mode) diff --git a/scripts/init.sh b/scripts/init.sh deleted file mode 100644 index 778107f8a73..00000000000 --- a/scripts/init.sh +++ /dev/null @@ -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 diff --git a/tasks/build_task.js b/tasks/build_task.js index 64f87522515..7a3627afd92 100644 --- a/tasks/build_task.js +++ b/tasks/build_task.js @@ -57,7 +57,7 @@ module.exports = function(grunt) { expand: true, src: ['grafana'], options: { mode: true}, - dest: '<%= tempDir %>' + dest: '<%= tempDir %>/bin/' }); grunt.config('copy.backend_files', { expand: true,