grafana-image-renderer: 4.0.14 -> 5.0.10 (#461983)
This commit is contained in:
@@ -2,97 +2,178 @@
|
||||
lib,
|
||||
pkgs,
|
||||
config,
|
||||
utils,
|
||||
...
|
||||
}:
|
||||
let
|
||||
cfg = config.services.grafana-image-renderer;
|
||||
|
||||
format = pkgs.formats.json { };
|
||||
format = {
|
||||
type =
|
||||
with lib.types;
|
||||
attrsOf (
|
||||
attrsOf (oneOf [
|
||||
str
|
||||
int
|
||||
bool
|
||||
(listOf (oneOf [
|
||||
str
|
||||
int
|
||||
]))
|
||||
])
|
||||
);
|
||||
|
||||
configFile = format.generate "grafana-image-renderer-config.json" cfg.settings;
|
||||
generate = lib.flip lib.pipe [
|
||||
# Remove legacy option prefixes that only exist for backwards-compat
|
||||
(lib.flip builtins.removeAttrs [
|
||||
"service"
|
||||
"rendering"
|
||||
"assertions"
|
||||
"warnings"
|
||||
])
|
||||
|
||||
# Normalize CLI args from a nested attr-set to `section.option = value`
|
||||
(lib.concatMapAttrs (block: lib.mapAttrs' (option: lib.nameValuePair "${block}.${option}")))
|
||||
|
||||
# Turn attr-set into a list of arguments, denormalize list options.
|
||||
(lib.mapAttrsToList (
|
||||
option: value:
|
||||
if lib.isBool value then
|
||||
lib.optional value "--${option}"
|
||||
else if lib.isList value then
|
||||
map (v: [
|
||||
"--${option}"
|
||||
v
|
||||
]) value
|
||||
else
|
||||
[
|
||||
"--${option}"
|
||||
(toString value)
|
||||
]
|
||||
))
|
||||
lib.flatten
|
||||
|
||||
# Turn into a string
|
||||
utils.escapeSystemdExecArgs
|
||||
];
|
||||
};
|
||||
in
|
||||
{
|
||||
imports = [
|
||||
(lib.mkChangedOptionModule
|
||||
[
|
||||
"services"
|
||||
"grafana-image-renderer"
|
||||
"chromium"
|
||||
]
|
||||
[
|
||||
"services"
|
||||
"grafana-image-renderer"
|
||||
"settings"
|
||||
"browser"
|
||||
"path"
|
||||
]
|
||||
(config: lib.getExe config.services.grafana-image-renderer.chromium)
|
||||
)
|
||||
(lib.mkRemovedOptionModule
|
||||
[
|
||||
"services"
|
||||
"grafana-image-renderer"
|
||||
"verbose"
|
||||
]
|
||||
''
|
||||
Use `services.grafana-image-renderer.settings.log.level = "debug"` instead.
|
||||
''
|
||||
)
|
||||
];
|
||||
|
||||
options.services.grafana-image-renderer = {
|
||||
enable = lib.mkEnableOption "grafana-image-renderer";
|
||||
|
||||
chromium = lib.mkOption {
|
||||
type = lib.types.package;
|
||||
description = ''
|
||||
The chromium to use for image rendering.
|
||||
'';
|
||||
};
|
||||
|
||||
verbose = lib.mkEnableOption "verbosity for the service";
|
||||
|
||||
provisionGrafana = lib.mkEnableOption "Grafana configuration for grafana-image-renderer";
|
||||
|
||||
settings = lib.mkOption {
|
||||
type = lib.types.submodule {
|
||||
freeformType = format.type;
|
||||
imports = [
|
||||
../../misc/assertions.nix
|
||||
(lib.mkRenamedOptionModule
|
||||
[
|
||||
"rendering"
|
||||
"width"
|
||||
]
|
||||
[
|
||||
"browser"
|
||||
"min-width"
|
||||
]
|
||||
)
|
||||
(lib.mkRenamedOptionModule
|
||||
[
|
||||
"rendering"
|
||||
"height"
|
||||
]
|
||||
[
|
||||
"browser"
|
||||
"min-height"
|
||||
]
|
||||
)
|
||||
(lib.mkRenamedOptionModule
|
||||
[
|
||||
"rendering"
|
||||
"args"
|
||||
]
|
||||
[
|
||||
|
||||
"browser"
|
||||
"flag"
|
||||
]
|
||||
)
|
||||
(lib.mkChangedOptionModule
|
||||
[
|
||||
"service"
|
||||
"port"
|
||||
]
|
||||
[
|
||||
"server"
|
||||
"addr"
|
||||
]
|
||||
(config: "0.0.0.0:${toString config.service.port}")
|
||||
)
|
||||
(lib.mkRemovedOptionModule
|
||||
[
|
||||
"rendering"
|
||||
"mode"
|
||||
]
|
||||
''
|
||||
This option is obsolete.
|
||||
''
|
||||
)
|
||||
(lib.mkRenamedOptionModule
|
||||
[
|
||||
"service"
|
||||
"logging"
|
||||
]
|
||||
[
|
||||
"log"
|
||||
]
|
||||
)
|
||||
];
|
||||
|
||||
options = {
|
||||
service = {
|
||||
port = lib.mkOption {
|
||||
type = lib.types.port;
|
||||
default = 8081;
|
||||
description = ''
|
||||
The TCP port to use for the rendering server.
|
||||
'';
|
||||
};
|
||||
logging.level = lib.mkOption {
|
||||
type = lib.types.enum [
|
||||
"error"
|
||||
"warning"
|
||||
"info"
|
||||
"debug"
|
||||
];
|
||||
default = "info";
|
||||
description = ''
|
||||
The log-level of the {file}`grafana-image-renderer.service`-unit.
|
||||
'';
|
||||
};
|
||||
server.addr = lib.mkOption {
|
||||
type = lib.types.str;
|
||||
default = "localhost:8081";
|
||||
description = ''
|
||||
Listen address of the service.
|
||||
'';
|
||||
};
|
||||
rendering = {
|
||||
width = lib.mkOption {
|
||||
default = 1000;
|
||||
type = lib.types.ints.positive;
|
||||
description = ''
|
||||
Width of the PNG used to display the alerting graph.
|
||||
'';
|
||||
};
|
||||
height = lib.mkOption {
|
||||
default = 500;
|
||||
type = lib.types.ints.positive;
|
||||
description = ''
|
||||
Height of the PNG used to display the alerting graph.
|
||||
'';
|
||||
};
|
||||
mode = lib.mkOption {
|
||||
default = "default";
|
||||
type = lib.types.enum [
|
||||
"default"
|
||||
"reusable"
|
||||
"clustered"
|
||||
];
|
||||
description = ''
|
||||
Rendering mode of `grafana-image-renderer`:
|
||||
|
||||
- `default:` Creates on browser-instance
|
||||
per rendering request.
|
||||
- `reusable:` One browser instance
|
||||
will be started and reused for each rendering request.
|
||||
- `clustered:` allows to precisely
|
||||
configure how many browser-instances are supposed to be used. The values
|
||||
for that mode can be declared in `rendering.clustering`.
|
||||
'';
|
||||
};
|
||||
args = lib.mkOption {
|
||||
type = lib.types.listOf lib.types.str;
|
||||
default = [ "--no-sandbox" ];
|
||||
description = ''
|
||||
List of CLI flags passed to `chromium`.
|
||||
'';
|
||||
};
|
||||
browser.path = lib.mkOption {
|
||||
type = lib.types.path;
|
||||
default = lib.getExe pkgs.chromium;
|
||||
defaultText = lib.literalExpression "lib.getExe pkgs.chromium";
|
||||
description = ''
|
||||
Path to the executable of the chromium to use.
|
||||
'';
|
||||
};
|
||||
};
|
||||
};
|
||||
@@ -101,9 +182,6 @@ in
|
||||
|
||||
description = ''
|
||||
Configuration attributes for `grafana-image-renderer`.
|
||||
|
||||
See <https://github.com/grafana/grafana-image-renderer/blob/ce1f81438e5f69c7fd7c73ce08bab624c4c92e25/default.json>
|
||||
for supported values.
|
||||
'';
|
||||
};
|
||||
};
|
||||
@@ -120,39 +198,53 @@ in
|
||||
];
|
||||
|
||||
services.grafana.settings.rendering = lib.mkIf cfg.provisionGrafana {
|
||||
server_url = "http://localhost:${toString cfg.settings.service.port}/render";
|
||||
server_url = "http://${toString cfg.settings.server.addr}/render";
|
||||
callback_url = "http://${config.services.grafana.settings.server.http_addr}:${toString config.services.grafana.settings.server.http_port}";
|
||||
};
|
||||
|
||||
services.grafana-image-renderer.chromium = lib.mkDefault pkgs.chromium;
|
||||
|
||||
services.grafana-image-renderer.settings = {
|
||||
rendering = lib.mapAttrs (lib.const lib.mkDefault) {
|
||||
chromeBin = "${cfg.chromium}/bin/chromium";
|
||||
verboseLogging = cfg.verbose;
|
||||
timezone = config.time.timeZone;
|
||||
};
|
||||
|
||||
service = {
|
||||
logging.level = lib.mkIf cfg.verbose (lib.mkDefault "debug");
|
||||
metrics.enabled = lib.mkDefault false;
|
||||
};
|
||||
browser.timezone = lib.mkIf (config.time.timeZone != null) (lib.mkDefault config.time.timeZone);
|
||||
};
|
||||
|
||||
systemd.services.grafana-image-renderer = {
|
||||
wantedBy = [ "multi-user.target" ];
|
||||
after = [ "network.target" ];
|
||||
wants = [ "network-online.target" ];
|
||||
after = [ "network-online.target" ];
|
||||
description = "Grafana backend plugin that handles rendering of panels & dashboards to PNGs using headless browser (Chromium/Chrome)";
|
||||
|
||||
environment = {
|
||||
PUPPETEER_SKIP_CHROMIUM_DOWNLOAD = "true";
|
||||
};
|
||||
|
||||
serviceConfig = {
|
||||
DynamicUser = true;
|
||||
PrivateTmp = true;
|
||||
ExecStart = "${pkgs.grafana-image-renderer}/bin/grafana-image-renderer server --config=${configFile}";
|
||||
ExecStart = "${lib.getExe pkgs.grafana-image-renderer} server ${format.generate cfg.settings}";
|
||||
Restart = "always";
|
||||
AmbientCapabilities = "";
|
||||
CapabilityBoundingSet = "";
|
||||
LockPersonality = true;
|
||||
MountAPIVFS = true;
|
||||
NoNewPrivileges = true;
|
||||
PrivateDevices = true;
|
||||
PrivateMounts = true;
|
||||
PrivateUsers = true;
|
||||
ProtectClock = true;
|
||||
ProtectControlGroups = "strict";
|
||||
ProtectHome = true;
|
||||
ProtectHostname = true;
|
||||
ProtectKernelLogs = true;
|
||||
ProtectKernelModules = true;
|
||||
ProtectKernelTunables = true;
|
||||
ProtectProc = "invisible";
|
||||
ProtectSystem = "full";
|
||||
RemoveIPC = true;
|
||||
RestrictAddressFamilies = [
|
||||
"AF_UNIX"
|
||||
"AF_INET"
|
||||
"AF_INET6"
|
||||
];
|
||||
RestrictNamespaces = true;
|
||||
RestrictRealtime = true;
|
||||
RestrictSUIDSGID = true;
|
||||
SystemCallArchitectures = "native";
|
||||
UMask = 27;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
@@ -1,109 +0,0 @@
|
||||
{
|
||||
"name": "renderer",
|
||||
"version": "1.0.0",
|
||||
"author": "Grafana Labs",
|
||||
"license": "Apache-2.0",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/grafana/grafana-image-renderer.git"
|
||||
},
|
||||
"scripts": {
|
||||
"eslint": "eslint .",
|
||||
"typecheck": "tsc --noEmit",
|
||||
"prettier:check": "prettier --list-different \"**/*.ts\"",
|
||||
"prettier:write": "prettier --list-different \"**/*.ts\" --write",
|
||||
"precommit": "npm run eslint & npm run typecheck",
|
||||
"watch": "tsc-watch --onSuccess \"node build/app.js server --config=dev.json\"",
|
||||
"watch:debug": "tsc-watch --onSuccess \"cross-env DEBUG=puppeteer-cluster:* node build/app.js server --config=dev.json\"",
|
||||
"build": "tsc",
|
||||
"start": "node build/app.js server --config=dev.json",
|
||||
"create-gcom-plugin-json": "ts-node scripts/createGcomPluginJson.ts ./scripts/tmp",
|
||||
"push-to-gcom": "sh ./scripts/push-to-gcom.sh",
|
||||
"test-update": "cross-env UPDATE_GOLDEN=true jest",
|
||||
"test": "sh ./scripts/run_tests.sh",
|
||||
"test-ci": "jest",
|
||||
"test-diff": "cross-env SAVE_DIFF=true jest"
|
||||
},
|
||||
"dependencies": {
|
||||
"@grpc/grpc-js": "^1.8.22",
|
||||
"@grpc/proto-loader": "^0.7.2",
|
||||
"@hapi/boom": "^10.0.0",
|
||||
"@opentelemetry/api": "^1.9.0",
|
||||
"@opentelemetry/auto-instrumentations-node": "^0.49.0",
|
||||
"@opentelemetry/exporter-trace-otlp-http": "^0.52.1",
|
||||
"@opentelemetry/resources": "^1.25.1",
|
||||
"@opentelemetry/sdk-node": "^0.52.1",
|
||||
"@opentelemetry/semantic-conventions": "^1.25.1",
|
||||
"@puppeteer/browsers": "^2.3.1",
|
||||
"chokidar": "^3.5.2",
|
||||
"dompurify": "^3.2.4",
|
||||
"express": "^4.21.1",
|
||||
"express-prom-bundle": "^6.5.0",
|
||||
"ioredis": "^5.6.1",
|
||||
"jimp": "^0.22.12",
|
||||
"jsdom": "20.0.0",
|
||||
"lodash": "^4.17.21",
|
||||
"minimist": "^1.2.6",
|
||||
"morgan": "^1.9.0",
|
||||
"multer": "^2.0.2",
|
||||
"on-finished": "^2.3.0",
|
||||
"poolpeteer": "^0.24.0",
|
||||
"prom-client": "^14.1.0",
|
||||
"puppeteer": "^22.8.2",
|
||||
"puppeteer-cluster": "^0.24.0",
|
||||
"rate-limiter-flexible": "^7.0.0",
|
||||
"tar-fs": "^3.0.9",
|
||||
"unique-filename": "^2.0.1",
|
||||
"winston": "^3.8.2"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@eslint/js": "^9.31.0",
|
||||
"@grafana/eslint-config": "^8.1.0",
|
||||
"@grafana/sign-plugin": "^3.1.3",
|
||||
"@stylistic/eslint-plugin-ts": "^4.4.1",
|
||||
"@types/content-disposition": "^0.5.9",
|
||||
"@types/express": "^4.17.14",
|
||||
"@types/jest": "^29.5.12",
|
||||
"@types/jsdom": "20.0.0",
|
||||
"@types/lodash": "^4.17.20",
|
||||
"@types/minimist": "^1.2.5",
|
||||
"@types/morgan": "^1.9.10",
|
||||
"@types/multer": "^1.4.7",
|
||||
"@types/node": "^20.17.27",
|
||||
"@types/pixelmatch": "^5.2.6",
|
||||
"@types/supertest": "^2.0.15",
|
||||
"@typescript-eslint/eslint-plugin": "^8.37.0",
|
||||
"@typescript-eslint/parser": "^8.37.0",
|
||||
"@yao-pkg/pkg": "^6.3.0",
|
||||
"axios": "1.8.2",
|
||||
"cross-env": "7.0.3",
|
||||
"eslint": "^9.31.0",
|
||||
"eslint-config-prettier": "^10.1.5",
|
||||
"eslint-plugin-jsdoc": "^51.4.1",
|
||||
"eslint-plugin-react": "^7.37.5",
|
||||
"eslint-plugin-react-hooks": "^5.2.0",
|
||||
"fast-png": "^6.2.0",
|
||||
"jest": "^29.7.0",
|
||||
"jsonwebtoken": "^9.0.2",
|
||||
"lint-staged": "13.0.3",
|
||||
"prettier": "2.7.1",
|
||||
"supertest": "^7.0.0",
|
||||
"ts-jest": "^29.1.1",
|
||||
"ts-node": "10.9.1",
|
||||
"tsc-watch": "5.0.3",
|
||||
"typescript": "^5.8.3",
|
||||
"typescript-eslint": "^8.37.0"
|
||||
},
|
||||
"lint-staged": {
|
||||
"*.ts": [
|
||||
"prettier --write"
|
||||
]
|
||||
},
|
||||
"pkg": {
|
||||
"assets": "proto/*"
|
||||
},
|
||||
"bin": "build/app.js",
|
||||
"engines": {
|
||||
"node": ">= 22"
|
||||
}
|
||||
}
|
||||
@@ -1,68 +1,23 @@
|
||||
{
|
||||
lib,
|
||||
mkYarnPackage,
|
||||
buildGoModule,
|
||||
fetchFromGitHub,
|
||||
fetchYarnDeps,
|
||||
nodejs,
|
||||
runtimeShell,
|
||||
}:
|
||||
|
||||
# Notes for the upgrade:
|
||||
# * Download the tarball of the new version to use.
|
||||
# * Replace new `package.json` here.
|
||||
# * Update `version`+`hash` and rebuild.
|
||||
|
||||
mkYarnPackage rec {
|
||||
buildGoModule (finalAttrs: {
|
||||
pname = "grafana-image-renderer";
|
||||
version = "4.0.14";
|
||||
version = "5.0.10";
|
||||
|
||||
src = fetchFromGitHub {
|
||||
owner = "grafana";
|
||||
repo = "grafana-image-renderer";
|
||||
rev = "v${version}";
|
||||
hash = "sha256-CoQTOzQ7h31B3U0yvJYsgC3uaSyjNNLpD+8uMN+naiQ=";
|
||||
tag = "v${finalAttrs.version}";
|
||||
hash = "sha256-oWJlb1mV1sNgN7EQ8L4msfnKps5oV60JgwZYpAJQaq4=";
|
||||
};
|
||||
|
||||
offlineCache = fetchYarnDeps {
|
||||
yarnLock = src + "/yarn.lock";
|
||||
hash = "sha256-xZrIoQlPeyGTbFRUQ0M8Tc6YpzsC5IACW0bbZ+HnsOQ=";
|
||||
};
|
||||
vendorHash = "sha256-wA1XeLO2bYwq7HZOQ5UNcdqqJdEWRUxFoAQucXAj48k=";
|
||||
|
||||
packageJSON = ./package.json;
|
||||
|
||||
buildPhase = ''
|
||||
runHook preBuild
|
||||
|
||||
pushd deps/renderer
|
||||
yarn run build
|
||||
popd
|
||||
|
||||
runHook postBuild
|
||||
'';
|
||||
|
||||
dontInstall = true;
|
||||
|
||||
distPhase = ''
|
||||
runHook preDist
|
||||
|
||||
shopt -s extglob
|
||||
|
||||
pushd deps/renderer
|
||||
install_path="$out/libexec/grafana-image-renderer"
|
||||
mkdir -p $install_path
|
||||
cp -R ../../node_modules $install_path
|
||||
cp -R ./!(node_modules) $install_path
|
||||
popd
|
||||
|
||||
mkdir -p $out/bin
|
||||
cat >$out/bin/grafana-image-renderer <<EOF
|
||||
#! ${runtimeShell}
|
||||
${nodejs}/bin/node $install_path/build/app.js \$@
|
||||
EOF
|
||||
chmod +x $out/bin/grafana-image-renderer
|
||||
|
||||
runHook postDist
|
||||
'';
|
||||
subPackages = [ "." ];
|
||||
|
||||
meta = with lib; {
|
||||
homepage = "https://github.com/grafana/grafana-image-renderer";
|
||||
@@ -70,6 +25,5 @@ mkYarnPackage rec {
|
||||
mainProgram = "grafana-image-renderer";
|
||||
license = licenses.asl20;
|
||||
maintainers = with maintainers; [ ma27 ];
|
||||
platforms = platforms.all;
|
||||
};
|
||||
}
|
||||
})
|
||||
|
||||
Reference in New Issue
Block a user