Loading nixos/modules/services/monitoring/grafana-image-renderer.nix +187 −95 Original line number Diff line number Diff line Loading @@ -2,108 +2,186 @@ lib, pkgs, config, utils, ... }: let cfg = config.services.grafana-image-renderer; format = pkgs.formats.json { }; configFile = format.generate "grafana-image-renderer-config.json" cfg.settings; format = { type = with lib.types; attrsOf ( attrsOf (oneOf [ str int bool (listOf (oneOf [ str int ])) ]) ); 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; server.addr = lib.mkOption { type = lib.types.str; default = "localhost:8081"; description = '' The TCP port to use for the rendering server. Listen address of the service. ''; }; logging.level = lib.mkOption { type = lib.types.enum [ "error" "warning" "info" "debug" ]; default = "info"; browser.path = lib.mkOption { type = lib.types.path; default = lib.getExe pkgs.chromium; defaultText = lib.literalExpression "lib.getExe pkgs.chromium"; description = '' The log-level of the {file}`grafana-image-renderer.service`-unit. Path to the executable of the chromium to use. ''; }; }; 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`. ''; }; }; }; }; default = { }; description = '' Configuration attributes for `grafana-image-renderer`. See <https://github.com/grafana/grafana-image-renderer/blob/ce1f81438e5f69c7fd7c73ce08bab624c4c92e25/default.json> for supported values. ''; }; }; Loading @@ -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; }; }; }; Loading pkgs/by-name/gr/grafana-image-renderer/package.jsondeleted 100644 → 0 +0 −109 Original line number Diff line number Diff line { "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" } } pkgs/by-name/gr/grafana-image-renderer/package.nix +8 −54 Original line number Diff line number Diff line { 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="; }; offlineCache = fetchYarnDeps { yarnLock = src + "/yarn.lock"; hash = "sha256-xZrIoQlPeyGTbFRUQ0M8Tc6YpzsC5IACW0bbZ+HnsOQ="; tag = "v${finalAttrs.version}"; hash = "sha256-oWJlb1mV1sNgN7EQ8L4msfnKps5oV60JgwZYpAJQaq4="; }; 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 vendorHash = "sha256-wA1XeLO2bYwq7HZOQ5UNcdqqJdEWRUxFoAQucXAj48k="; runHook postDist ''; subPackages = [ "." ]; meta = with lib; { homepage = "https://github.com/grafana/grafana-image-renderer"; Loading @@ -70,6 +25,5 @@ mkYarnPackage rec { mainProgram = "grafana-image-renderer"; license = licenses.asl20; maintainers = with maintainers; [ ma27 ]; platforms = platforms.all; }; } }) Loading
nixos/modules/services/monitoring/grafana-image-renderer.nix +187 −95 Original line number Diff line number Diff line Loading @@ -2,108 +2,186 @@ lib, pkgs, config, utils, ... }: let cfg = config.services.grafana-image-renderer; format = pkgs.formats.json { }; configFile = format.generate "grafana-image-renderer-config.json" cfg.settings; format = { type = with lib.types; attrsOf ( attrsOf (oneOf [ str int bool (listOf (oneOf [ str int ])) ]) ); 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; server.addr = lib.mkOption { type = lib.types.str; default = "localhost:8081"; description = '' The TCP port to use for the rendering server. Listen address of the service. ''; }; logging.level = lib.mkOption { type = lib.types.enum [ "error" "warning" "info" "debug" ]; default = "info"; browser.path = lib.mkOption { type = lib.types.path; default = lib.getExe pkgs.chromium; defaultText = lib.literalExpression "lib.getExe pkgs.chromium"; description = '' The log-level of the {file}`grafana-image-renderer.service`-unit. Path to the executable of the chromium to use. ''; }; }; 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`. ''; }; }; }; }; default = { }; description = '' Configuration attributes for `grafana-image-renderer`. See <https://github.com/grafana/grafana-image-renderer/blob/ce1f81438e5f69c7fd7c73ce08bab624c4c92e25/default.json> for supported values. ''; }; }; Loading @@ -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; }; }; }; Loading
pkgs/by-name/gr/grafana-image-renderer/package.jsondeleted 100644 → 0 +0 −109 Original line number Diff line number Diff line { "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" } }
pkgs/by-name/gr/grafana-image-renderer/package.nix +8 −54 Original line number Diff line number Diff line { 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="; }; offlineCache = fetchYarnDeps { yarnLock = src + "/yarn.lock"; hash = "sha256-xZrIoQlPeyGTbFRUQ0M8Tc6YpzsC5IACW0bbZ+HnsOQ="; tag = "v${finalAttrs.version}"; hash = "sha256-oWJlb1mV1sNgN7EQ8L4msfnKps5oV60JgwZYpAJQaq4="; }; 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 vendorHash = "sha256-wA1XeLO2bYwq7HZOQ5UNcdqqJdEWRUxFoAQucXAj48k="; runHook postDist ''; subPackages = [ "." ]; meta = with lib; { homepage = "https://github.com/grafana/grafana-image-renderer"; Loading @@ -70,6 +25,5 @@ mkYarnPackage rec { mainProgram = "grafana-image-renderer"; license = licenses.asl20; maintainers = with maintainers; [ ma27 ]; platforms = platforms.all; }; } })