mirror of https://github.com/grafana/grafana
Server: Switch from separate server & cli to a unified grafana binary (#58286)
* avoid the need for a second bulky binary for grafana-cli * look for grafana-server in $PATH as well as same directory * implement unified "grafana" command * update dockerfiles, fix grafana-cli -v * update packaging to work with single binary - add wrapper scripts for grafana and grafana-server - update and sync package files - implement --sign flag of build package command - stop packaging scripts folder, they are not useful for end users - add support for --configOverrides in server command - remove unused nfpm.yaml config file * windows supportpull/59158/head
parent
824a562b03
commit
de99ce139c
@ -1,35 +0,0 @@ |
||||
name: "grafana" |
||||
arch: "${ARCH}" |
||||
platform: "linux" |
||||
version: "${VERSION}" |
||||
section: "default" |
||||
priority: "extra" |
||||
replaces: |
||||
- grafana |
||||
provides: |
||||
- grafana-server |
||||
- grafana-cli |
||||
depends: |
||||
- adduser |
||||
maintainer: "<contact@grafana.com>" |
||||
description: | |
||||
Grafana |
||||
vendor: "Grafana" |
||||
homepage: "https://grafana.com" |
||||
license: "Apache 2" |
||||
bindir: "/usr/sbin" |
||||
files: |
||||
"./bin/grafana-server": "/usr/sbin/grafana-server" |
||||
"./bin/grafana-cli": "/usr/sbin/grafana-cli" |
||||
config_files: |
||||
./packaging/deb/init.d/grafana-server: "/etc/init.d/grafana-server" |
||||
./packaging/deb/default/grafana-server: "/etc/default/grafana-server" |
||||
./packaging/deb/systemd/grafana-server.service: "/usr/lib/systemd/system/grafana-server.service" |
||||
overrides: |
||||
rpm: |
||||
scripts: |
||||
preinstall: ./scripts/preinstall.sh |
||||
postremove: ./scripts/postremove.sh |
||||
deb: |
||||
scripts: |
||||
postinstall: ./packaging/deb/control/postinst |
@ -0,0 +1,49 @@ |
||||
#! /usr/bin/env bash |
||||
|
||||
# Wrapper for the grafana binary |
||||
# This file serves as a wrapper for the grafana 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="${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" |
||||
|
||||
if [ ! -x $EXECUTABLE ]; then |
||||
echo "$EXECUTABLE 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} \ |
||||
--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}'" |
||||
|
||||
CMD="${1:-}" |
||||
shift |
||||
|
||||
# special handling to pass --pluginsDir to cli |
||||
# can remove once it fully supports cfg:default.paths.plugins |
||||
if [ "$CMD" = cli ]; then |
||||
OPTS="$OPTS \ |
||||
--pluginsDir=${PLUGINS_DIR}" |
||||
fi |
||||
|
||||
eval $EXECUTABLE "$CMD" "$OPTS" "$@" |
@ -0,0 +1,41 @@ |
||||
#! /usr/bin/env bash |
||||
|
||||
# Wrapper for the grafana binary |
||||
# This file serves as a wrapper for the grafana 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="${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" |
||||
|
||||
if [ ! -x $EXECUTABLE ]; then |
||||
echo "$EXECUTABLE 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} \ |
||||
--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}'" |
||||
|
||||
CMD=server |
||||
|
||||
eval $EXECUTABLE "$CMD" "$OPTS" "$@" |
@ -0,0 +1,68 @@ |
||||
package main |
||||
|
||||
import ( |
||||
"fmt" |
||||
"os" |
||||
|
||||
"github.com/fatih/color" |
||||
gcli "github.com/grafana/grafana/pkg/cmd/grafana-cli/commands" |
||||
gsrv "github.com/grafana/grafana/pkg/cmd/grafana-server/commands" |
||||
"github.com/urfave/cli/v2" |
||||
) |
||||
|
||||
// The following variables cannot be constants, since they can be overridden through the -X link flag
|
||||
var version = "9.2.0" |
||||
var commit = "NA" |
||||
var buildBranch = "main" |
||||
var buildstamp string |
||||
|
||||
func main() { |
||||
app := &cli.App{ |
||||
Name: "grafana", |
||||
Usage: "Grafana server and command line interface", |
||||
Authors: []*cli.Author{ |
||||
{ |
||||
Name: "Grafana Project", |
||||
Email: "hello@grafana.com", |
||||
}, |
||||
}, |
||||
Version: version, |
||||
Commands: []*cli.Command{ |
||||
gcli.CLICommand(version), |
||||
{ |
||||
Name: "server", |
||||
Usage: "server <server options>", |
||||
Action: func(context *cli.Context) error { |
||||
os.Exit(gsrv.RunServer(gsrv.ServerOptions{ |
||||
Version: version, |
||||
Commit: commit, |
||||
BuildBranch: buildBranch, |
||||
BuildStamp: buildstamp, |
||||
Args: context.Args().Slice(), |
||||
})) |
||||
return nil |
||||
}, |
||||
SkipFlagParsing: true, |
||||
}, |
||||
}, |
||||
CommandNotFound: cmdNotFound, |
||||
} |
||||
|
||||
if err := app.Run(os.Args); err != nil { |
||||
fmt.Printf("%s: %s %s\n", color.RedString("Error"), color.RedString("✗"), err) |
||||
os.Exit(1) |
||||
} |
||||
|
||||
os.Exit(0) |
||||
} |
||||
|
||||
func cmdNotFound(c *cli.Context, command string) { |
||||
fmt.Printf( |
||||
"%s: '%s' is not a %s command. See '%s --help'.\n", |
||||
c.App.Name, |
||||
command, |
||||
c.App.Name, |
||||
os.Args[0], |
||||
) |
||||
os.Exit(1) |
||||
} |
@ -0,0 +1,65 @@ |
||||
package cmd |
||||
|
||||
import ( |
||||
"errors" |
||||
"fmt" |
||||
"os" |
||||
"os/exec" |
||||
"path/filepath" |
||||
"runtime" |
||||
"syscall" |
||||
) |
||||
|
||||
func RunGrafanaCmd(subCmd string) int { |
||||
curr, err := os.Executable() |
||||
if err != nil { |
||||
fmt.Println("Error locating executable:", err) |
||||
return 1 |
||||
} |
||||
|
||||
executable := "grafana" |
||||
if runtime.GOOS == "windows" { |
||||
executable += ".exe" |
||||
} |
||||
|
||||
binary := filepath.Join(filepath.Dir(filepath.Clean(curr)), executable) |
||||
if _, err := os.Stat(binary); err != nil { |
||||
binary, err = exec.LookPath(executable) |
||||
if err != nil { |
||||
fmt.Printf("Error locating %s: %s\n", executable, err) |
||||
return 1 |
||||
} |
||||
} |
||||
|
||||
// windows doesn't support syscall.Exec so we just run the main binary as a command
|
||||
if runtime.GOOS == "windows" { |
||||
// bypassing gosec G204 because we need to build the command programmatically
|
||||
// nolint:gosec
|
||||
cmd := exec.Command(binary, append([]string{subCmd}, os.Args[1:]...)...) |
||||
cmd.Stdout = os.Stdout |
||||
cmd.Stderr = os.Stderr |
||||
cmd.Stdin = os.Stdin |
||||
cmd.Env = os.Environ() |
||||
err := cmd.Run() |
||||
if err == nil { |
||||
return 0 |
||||
} |
||||
var exitError *exec.ExitError |
||||
if errors.As(err, &exitError) { |
||||
return exitError.ExitCode() |
||||
} |
||||
return 1 |
||||
} |
||||
|
||||
args := append([]string{"grafana", subCmd}, os.Args[1:]...) |
||||
|
||||
// bypassing gosec G204 because we need to build the command programmatically
|
||||
// nolint:gosec
|
||||
execErr := syscall.Exec(binary, args, os.Environ()) |
||||
if execErr != nil { |
||||
fmt.Printf("Error running %s: %s\n", binary, execErr) |
||||
return 1 |
||||
} |
||||
|
||||
return 0 |
||||
} |
Loading…
Reference in new issue