mirror of https://github.com/grafana/grafana.git
				
				
				
			Grafana-CLI: Wrapper for `grafana-cli` within RPM/DEB packages and config/homepath are now global flags (#17695)
* Feature: Introduce a grafana-cli wrapper When our users install the *nix packed version of grafana, tendency is to use the services and scripts installed as part of the package for grafana-server. These leverage the default configuration options by specifying the several default paths. This introduces a similar approach for the grafana-cli binary. We exposed it through a wrapper to ensure a proper configuration is in place. To enable that, we add the .real suffix to the original binary (grafana-cli.real) and then use a bash script named grafana-cli as the wrapper. * Make the config and homepath flags global * Introduce `configOverrides` as a global flag This flag allows us to pass configuration overrides as a string. The string follows the convention of configuration arguments separated by a space e.g. "cfg:default.paths.data=/dev/nullX cfg:default.paths.logs=/dev/nullX" Also, it is backwards compatible with similar the previous configuration method through tailing arguments. Tailing arguments take presedence over the configuration options string. * Only log configuration information in debug mode * Move the grafana-cli binary to $GRAFANA_HOME/bin As part of the package install process, we copy all the release files and directories into the grafana home directory. This includes the /bin folder from where we copied the binaries into their respective destinations. After that, the /bin folder gets deleted as we don't want to keep duplicates of the binaries around. As part of this commit, we moved the re-creation of /bin within grafana-home and the copy of the original binary (again) after the folder gets deleted.
This commit is contained in:
		
							parent
							
								
									e7e9d3619e
								
							
						
					
					
						commit
						2fb45eeec8
					
				
							
								
								
									
										29
									
								
								build.go
								
								
								
								
							
							
						
						
									
										29
									
								
								build.go
								
								
								
								
							| 
						 | 
				
			
			@ -43,7 +43,9 @@ var (
 | 
			
		|||
	workingDir            string
 | 
			
		||||
	includeBuildId        bool     = true
 | 
			
		||||
	buildId               string   = "0"
 | 
			
		||||
	binaries              []string = []string{"grafana-server", "grafana-cli"}
 | 
			
		||||
	serverBinary          string   = "grafana-server"
 | 
			
		||||
	cliBinary             string   = "grafana-cli"
 | 
			
		||||
	binaries              []string = []string{serverBinary, cliBinary}
 | 
			
		||||
	isDev                 bool     = false
 | 
			
		||||
	enterprise            bool     = false
 | 
			
		||||
	skipRpmGen            bool     = false
 | 
			
		||||
| 
						 | 
				
			
			@ -230,6 +232,7 @@ type linuxPackageOptions struct {
 | 
			
		|||
	packageType            string
 | 
			
		||||
	packageArch            string
 | 
			
		||||
	homeDir                string
 | 
			
		||||
	homeBinDir             string
 | 
			
		||||
	binPath                string
 | 
			
		||||
	serverBinPath          string
 | 
			
		||||
	cliBinPath             string
 | 
			
		||||
| 
						 | 
				
			
			@ -244,6 +247,7 @@ type linuxPackageOptions struct {
 | 
			
		|||
	initdScriptSrc      string
 | 
			
		||||
	defaultFileSrc      string
 | 
			
		||||
	systemdFileSrc      string
 | 
			
		||||
	cliBinaryWrapperSrc string
 | 
			
		||||
 | 
			
		||||
	depends []string
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -258,6 +262,7 @@ func createDebPackages() {
 | 
			
		|||
		packageType:            "deb",
 | 
			
		||||
		packageArch:            debPkgArch,
 | 
			
		||||
		homeDir:                "/usr/share/grafana",
 | 
			
		||||
		homeBinDir:             "/usr/share/grafana/bin",
 | 
			
		||||
		binPath:                "/usr/sbin",
 | 
			
		||||
		configDir:              "/etc/grafana",
 | 
			
		||||
		etcDefaultPath:         "/etc/default",
 | 
			
		||||
| 
						 | 
				
			
			@ -269,6 +274,7 @@ func createDebPackages() {
 | 
			
		|||
		initdScriptSrc:      "packaging/deb/init.d/grafana-server",
 | 
			
		||||
		defaultFileSrc:      "packaging/deb/default/grafana-server",
 | 
			
		||||
		systemdFileSrc:      "packaging/deb/systemd/grafana-server.service",
 | 
			
		||||
		cliBinaryWrapperSrc: "packaging/wrappers/grafana-cli",
 | 
			
		||||
 | 
			
		||||
		depends: []string{"adduser", "libfontconfig1"},
 | 
			
		||||
	})
 | 
			
		||||
| 
						 | 
				
			
			@ -286,6 +292,7 @@ func createRpmPackages() {
 | 
			
		|||
		packageType:            "rpm",
 | 
			
		||||
		packageArch:            rpmPkgArch,
 | 
			
		||||
		homeDir:                "/usr/share/grafana",
 | 
			
		||||
		homeBinDir:             "/usr/share/grafana/bin",
 | 
			
		||||
		binPath:                "/usr/sbin",
 | 
			
		||||
		configDir:              "/etc/grafana",
 | 
			
		||||
		etcDefaultPath:         "/etc/sysconfig",
 | 
			
		||||
| 
						 | 
				
			
			@ -297,6 +304,7 @@ func createRpmPackages() {
 | 
			
		|||
		initdScriptSrc:      "packaging/rpm/init.d/grafana-server",
 | 
			
		||||
		defaultFileSrc:      "packaging/rpm/sysconfig/grafana-server",
 | 
			
		||||
		systemdFileSrc:      "packaging/rpm/systemd/grafana-server.service",
 | 
			
		||||
		cliBinaryWrapperSrc: "packaging/wrappers/grafana-cli",
 | 
			
		||||
 | 
			
		||||
		depends: []string{"/sbin/service", "fontconfig", "freetype", "urw-fonts"},
 | 
			
		||||
	})
 | 
			
		||||
| 
						 | 
				
			
			@ -323,10 +331,12 @@ func createPackage(options linuxPackageOptions) {
 | 
			
		|||
	runPrint("mkdir", "-p", filepath.Join(packageRoot, "/usr/lib/systemd/system"))
 | 
			
		||||
	runPrint("mkdir", "-p", filepath.Join(packageRoot, "/usr/sbin"))
 | 
			
		||||
 | 
			
		||||
	// copy binary
 | 
			
		||||
	for _, binary := range binaries {
 | 
			
		||||
		runPrint("cp", "-p", filepath.Join(workingDir, "tmp/bin/"+binary), filepath.Join(packageRoot, "/usr/sbin/"+binary))
 | 
			
		||||
	}
 | 
			
		||||
	// copy grafana-cli wrapper
 | 
			
		||||
	runPrint("cp", "-p", options.cliBinaryWrapperSrc, filepath.Join(packageRoot, "/usr/sbin/"+cliBinary))
 | 
			
		||||
 | 
			
		||||
	// copy grafana-server binary
 | 
			
		||||
	runPrint("cp", "-p", filepath.Join(workingDir, "tmp/bin/"+serverBinary), filepath.Join(packageRoot, "/usr/sbin/"+serverBinary))
 | 
			
		||||
 | 
			
		||||
	// copy init.d script
 | 
			
		||||
	runPrint("cp", "-p", options.initdScriptSrc, filepath.Join(packageRoot, options.initdScriptFilePath))
 | 
			
		||||
	// copy environment var file
 | 
			
		||||
| 
						 | 
				
			
			@ -338,6 +348,13 @@ func createPackage(options linuxPackageOptions) {
 | 
			
		|||
	// remove bin path
 | 
			
		||||
	runPrint("rm", "-rf", filepath.Join(packageRoot, options.homeDir, "bin"))
 | 
			
		||||
 | 
			
		||||
	// create /bin within home
 | 
			
		||||
	runPrint("mkdir", "-p", filepath.Join(packageRoot, options.homeBinDir))
 | 
			
		||||
	// The grafana-cli binary is exposed through a wrapper to ensure a proper
 | 
			
		||||
	// configuration is in place. To enable that, we need to store the original
 | 
			
		||||
	// binary in a separate location to avoid conflicts.
 | 
			
		||||
	runPrint("cp", "-p", filepath.Join(workingDir, "tmp/bin/"+cliBinary), filepath.Join(packageRoot, options.homeBinDir, cliBinary))
 | 
			
		||||
 | 
			
		||||
	args := []string{
 | 
			
		||||
		"-s", "dir",
 | 
			
		||||
		"--description", "Grafana",
 | 
			
		||||
| 
						 | 
				
			
			@ -391,7 +408,7 @@ func createPackage(options linuxPackageOptions) {
 | 
			
		|||
		args = append(args, "--iteration", linuxPackageIteration)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// add dependenciesj
 | 
			
		||||
	// add dependencies
 | 
			
		||||
	for _, dep := range options.depends {
 | 
			
		||||
		args = append(args, "--depends", dep)
 | 
			
		||||
	}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -37,7 +37,7 @@ If running the command returns this error:
 | 
			
		|||
 | 
			
		||||
then there are two flags that can be used to set homepath and the config file path.
 | 
			
		||||
 | 
			
		||||
`grafana-cli admin reset-admin-password --homepath "/usr/share/grafana" newpass`
 | 
			
		||||
`grafana-cli --homepath "/usr/share/grafana" admin reset-admin-password newpass`
 | 
			
		||||
 | 
			
		||||
If you have not lost the admin password then it is better to set in the Grafana UI. If you need to set the password in a script then the [Grafana API](http://docs.grafana.org/http_api/user/#change-password) can be used. Here is an example using curl with basic auth:
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -0,0 +1,39 @@
 | 
			
		|||
#! /usr/bin/env bash
 | 
			
		||||
 | 
			
		||||
# Wrapper for the grafana-cli binary
 | 
			
		||||
# This file serves as a wrapper for the grafana-cli binary. It ensures we set
 | 
			
		||||
# the system-wide Grafana configuration that was bundled with the package as we
 | 
			
		||||
# use the binary.
 | 
			
		||||
 | 
			
		||||
DEFAULT=/etc/default/grafana
 | 
			
		||||
 | 
			
		||||
GRAFANA_HOME=/usr/share/grafana
 | 
			
		||||
CONF_DIR=/etc/grafana
 | 
			
		||||
DATA_DIR=/var/lib/grafana
 | 
			
		||||
PLUGINS_DIR=/var/lib/grafana/plugins
 | 
			
		||||
LOG_DIR=/var/log/grafana
 | 
			
		||||
 | 
			
		||||
CONF_FILE=$CONF_DIR/grafana.ini
 | 
			
		||||
PROVISIONING_CFG_DIR=$CONF_DIR/provisioning
 | 
			
		||||
 | 
			
		||||
EXECUTABLE=$GRAFANA_HOME/bin/grafana-cli
 | 
			
		||||
 | 
			
		||||
if [ ! -x $EXECUTABLE ]; then
 | 
			
		||||
 echo "Program not installed or not executable"
 | 
			
		||||
 exit 5
 | 
			
		||||
fi
 | 
			
		||||
 | 
			
		||||
# overwrite settings from default file
 | 
			
		||||
if [ -f "$DEFAULT" ]; then
 | 
			
		||||
  . "$DEFAULT"
 | 
			
		||||
fi
 | 
			
		||||
 | 
			
		||||
OPTS="--homepath=${GRAFANA_HOME} \
 | 
			
		||||
      --config=${CONF_FILE} \
 | 
			
		||||
      --pluginsDir=${PLUGINS_DIR} \
 | 
			
		||||
      --configOverrides='cfg:default.paths.provisioning=$PROVISIONING_CFG_DIR \
 | 
			
		||||
                        cfg:default.paths.data=${DATA_DIR} \
 | 
			
		||||
                        cfg:default.paths.logs=${LOG_DIR} \
 | 
			
		||||
                        cfg:default.paths.plugins=${PLUGINS_DIR}'"
 | 
			
		||||
 | 
			
		||||
eval $EXECUTABLE "$OPTS" "$@"
 | 
			
		||||
| 
						 | 
				
			
			@ -2,6 +2,7 @@ package commands
 | 
			
		|||
 | 
			
		||||
import (
 | 
			
		||||
	"os"
 | 
			
		||||
	"strings"
 | 
			
		||||
 | 
			
		||||
	"github.com/codegangsta/cli"
 | 
			
		||||
	"github.com/fatih/color"
 | 
			
		||||
| 
						 | 
				
			
			@ -16,16 +17,20 @@ import (
 | 
			
		|||
func runDbCommand(command func(commandLine utils.CommandLine, sqlStore *sqlstore.SqlStore) error) func(context *cli.Context) {
 | 
			
		||||
	return func(context *cli.Context) {
 | 
			
		||||
		cmd := &utils.ContextCommandLine{Context: context}
 | 
			
		||||
		debug := cmd.GlobalBool("debug")
 | 
			
		||||
 | 
			
		||||
		cfg := setting.NewCfg()
 | 
			
		||||
 | 
			
		||||
		configOptions := strings.Split(cmd.GlobalString("configOverrides"), " ")
 | 
			
		||||
		cfg.Load(&setting.CommandLineArgs{
 | 
			
		||||
			Config:   cmd.String("config"),
 | 
			
		||||
			HomePath: cmd.String("homepath"),
 | 
			
		||||
			Args:     context.Args(),
 | 
			
		||||
			Config:   cmd.ConfigFile(),
 | 
			
		||||
			HomePath: cmd.HomePath(),
 | 
			
		||||
			Args:     append(configOptions, cmd.Args()...), // tailing arguments have precedence over the options string
 | 
			
		||||
		})
 | 
			
		||||
 | 
			
		||||
		if debug {
 | 
			
		||||
			cfg.LogConfigSources()
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		engine := &sqlstore.SqlStore{}
 | 
			
		||||
		engine.Cfg = cfg
 | 
			
		||||
| 
						 | 
				
			
			@ -95,23 +100,11 @@ var pluginCommands = []cli.Command{
 | 
			
		|||
	},
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
var dbCommandFlags = []cli.Flag{
 | 
			
		||||
	cli.StringFlag{
 | 
			
		||||
		Name:  "homepath",
 | 
			
		||||
		Usage: "path to grafana install/home path, defaults to working directory",
 | 
			
		||||
	},
 | 
			
		||||
	cli.StringFlag{
 | 
			
		||||
		Name:  "config",
 | 
			
		||||
		Usage: "path to config file",
 | 
			
		||||
	},
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
var adminCommands = []cli.Command{
 | 
			
		||||
	{
 | 
			
		||||
		Name:   "reset-admin-password",
 | 
			
		||||
		Usage:  "reset-admin-password <new password>",
 | 
			
		||||
		Action: runDbCommand(resetPasswordCommand),
 | 
			
		||||
		Flags:  dbCommandFlags,
 | 
			
		||||
	},
 | 
			
		||||
	{
 | 
			
		||||
		Name:  "data-migration",
 | 
			
		||||
| 
						 | 
				
			
			@ -121,7 +114,6 @@ var adminCommands = []cli.Command{
 | 
			
		|||
				Name:   "encrypt-datasource-passwords",
 | 
			
		||||
				Usage:  "Migrates passwords from unsecured fields to secure_json_data field. Return ok unless there is an error. Safe to execute multiple times.",
 | 
			
		||||
				Action: runDbCommand(datamigrations.EncryptDatasourcePaswords),
 | 
			
		||||
				Flags:  dbCommandFlags,
 | 
			
		||||
			},
 | 
			
		||||
		},
 | 
			
		||||
	},
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -51,6 +51,18 @@ func main() {
 | 
			
		|||
			Name:  "debug, d",
 | 
			
		||||
			Usage: "enable debug logging",
 | 
			
		||||
		},
 | 
			
		||||
		cli.StringFlag{
 | 
			
		||||
			Name:  "configOverrides",
 | 
			
		||||
			Usage: "configuration options to override defaults as a string. e.g. cfg:default.paths.log=/dev/null",
 | 
			
		||||
		},
 | 
			
		||||
		cli.StringFlag{
 | 
			
		||||
			Name:  "homepath",
 | 
			
		||||
			Usage: "path to grafana install/home path, defaults to working directory",
 | 
			
		||||
		},
 | 
			
		||||
		cli.StringFlag{
 | 
			
		||||
			Name:  "config",
 | 
			
		||||
			Usage: "path to config file",
 | 
			
		||||
		},
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	app.Before = func(c *cli.Context) error {
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -38,6 +38,10 @@ func (c *ContextCommandLine) Application() *cli.App {
 | 
			
		|||
	return c.App
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (c *ContextCommandLine) HomePath() string { return c.GlobalString("homepath") }
 | 
			
		||||
 | 
			
		||||
func (c *ContextCommandLine) ConfigFile() string { return c.GlobalString("config") }
 | 
			
		||||
 | 
			
		||||
func (c *ContextCommandLine) PluginDirectory() string {
 | 
			
		||||
	return c.GlobalString("pluginsDir")
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -49,3 +53,7 @@ func (c *ContextCommandLine) RepoDirectory() string {
 | 
			
		|||
func (c *ContextCommandLine) PluginURL() string {
 | 
			
		||||
	return c.GlobalString("pluginUrl")
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (c *ContextCommandLine) OptionsString() string {
 | 
			
		||||
	return c.GlobalString("configOverrides")
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
		Reference in New Issue