From 9ce350cdccb51c5245a0823e9290d301c3e6e5f3 Mon Sep 17 00:00:00 2001 From: Jan Tojnar Date: Sun, 4 Oct 2020 00:36:47 +0200 Subject: [PATCH 1/4] blackfire: init at 1.44.0 --- .../tools/misc/blackfire/default.nix | 52 +++++++++++++++++++ pkgs/top-level/all-packages.nix | 2 + 2 files changed, 54 insertions(+) create mode 100644 pkgs/development/tools/misc/blackfire/default.nix diff --git a/pkgs/development/tools/misc/blackfire/default.nix b/pkgs/development/tools/misc/blackfire/default.nix new file mode 100644 index 00000000000..08496d9f520 --- /dev/null +++ b/pkgs/development/tools/misc/blackfire/default.nix @@ -0,0 +1,52 @@ +{ stdenv +, lib +, fetchurl +, dpkg +, autoPatchelfHook +, writeShellScript +, curl +, jq +, common-updater-scripts +}: + +stdenv.mkDerivation rec { + pname = "blackfire-agent"; + version = "1.44.1"; + + src = fetchurl { + url = "https://packages.blackfire.io/debian/pool/any/main/b/blackfire-php/blackfire-agent_${version}_amd64.deb"; + sha256 = "1p00flipm5x6r36gblfrfrd14byipilybrhfzv8rzpahz2b7r5hb"; + }; + + nativeBuildInputs = [ + dpkg + autoPatchelfHook + ]; + + dontUnpack = true; + + installPhase = '' + runHook preInstall + + dpkg-deb -x $src $out + mv $out/usr/* $out + rmdir $out/usr + + runHook postInstall + ''; + + passthru = { + updateScript = writeShellScript "update-${pname}" '' + export PATH="${lib.makeBinPath [ curl jq common-updater-scripts ]}" + update-source-version "$UPDATE_NIX_ATTR_PATH" "$(curl https://blackfire.io/api/v1/releases | jq .agent --raw-output)" + ''; + }; + + meta = with lib; { + description = "Blackfire Profiler agent and client"; + homepage = "https://blackfire.io/"; + license = licenses.unfree; + maintainers = with maintainers; [ jtojnar ]; + platforms = [ "x86_64-linux" ]; + }; +} diff --git a/pkgs/top-level/all-packages.nix b/pkgs/top-level/all-packages.nix index 1d198778dce..1c7b541fbc8 100644 --- a/pkgs/top-level/all-packages.nix +++ b/pkgs/top-level/all-packages.nix @@ -10674,6 +10674,8 @@ in black = with python3Packages; toPythonApplication black; + blackfire = callPackage ../development/tools/misc/blackfire { }; + black-macchiato = with python3Packages; toPythonApplication black-macchiato; blackmagic = callPackage ../development/tools/misc/blackmagic { }; From a07508c1d34138df95c6c81ac0e4aedb42914dc3 Mon Sep 17 00:00:00 2001 From: Jan Tojnar Date: Sun, 4 Oct 2020 13:00:23 +0200 Subject: [PATCH 2/4] php: declare ZTS support Binary extensions like Blackfire need to know whether PHP was compiled with ZTS support to work properly. --- pkgs/development/interpreters/php/default.nix | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/pkgs/development/interpreters/php/default.nix b/pkgs/development/interpreters/php/default.nix index a2e546b8261..8286de744ed 100644 --- a/pkgs/development/interpreters/php/default.nix +++ b/pkgs/development/interpreters/php/default.nix @@ -106,7 +106,7 @@ let name = "php-with-extensions-${version}"; inherit (php) version; nativeBuildInputs = [ makeWrapper ]; - passthru = { + passthru = php.passthru // { buildEnv = mkBuildEnv allArgs allExtensionFunctions; withExtensions = mkWithExtensions allArgs allExtensionFunctions; phpIni = "${phpWithExtensions}/lib/php.ini"; @@ -259,6 +259,7 @@ let passthru = { buildEnv = mkBuildEnv {} []; withExtensions = mkWithExtensions {} []; + inherit ztsSupport; }; meta = with stdenv.lib; { From 956a43990e33719d2110a99ccd659230b6411eba Mon Sep 17 00:00:00 2001 From: Jan Tojnar Date: Sun, 4 Oct 2020 12:59:52 +0200 Subject: [PATCH 3/4] phpExtensions.blackfire: init at 1.40.0 --- .../tools/misc/blackfire/php-probe.nix | 63 +++++++++++++++++++ pkgs/top-level/php-packages.nix | 2 + 2 files changed, 65 insertions(+) create mode 100644 pkgs/development/tools/misc/blackfire/php-probe.nix diff --git a/pkgs/development/tools/misc/blackfire/php-probe.nix b/pkgs/development/tools/misc/blackfire/php-probe.nix new file mode 100644 index 00000000000..5de2a05349a --- /dev/null +++ b/pkgs/development/tools/misc/blackfire/php-probe.nix @@ -0,0 +1,63 @@ +{ stdenv +, lib +, fetchurl +, dpkg +, autoPatchelfHook +, php +, writeShellScript +, curl +, jq +, common-updater-scripts +}: + +let + soFile = { + "7.3" = "blackfire-20180731"; + "7.4" = "blackfire-20190902"; + }.${lib.versions.majorMinor php.version} or (throw "Unsupported PHP version."); +in stdenv.mkDerivation rec { + pname = "php-blackfire"; + version = "1.41.0"; + + src = fetchurl { + url = "https://packages.blackfire.io/debian/pool/any/main/b/blackfire-php/blackfire-php_${version}_amd64.deb"; + sha256 = "0vbl48bccswk9ygb4sshn24cl33fk0xg8d1bcg7ihvdc45any9ww"; + }; + + nativeBuildInputs = [ + dpkg + autoPatchelfHook + ]; + + unpackPhase = '' + runHook preUnpack + + dpkg-deb -x $src pkg + sourceRoot=pkg + + runHook postUnpack + ''; + + installPhase = '' + runHook preInstall + + install -D usr/lib/blackfire-php/amd64/${soFile}${lib.optionalString php.ztsSupport "-zts"}.so $out/lib/php/extensions/blackfire.so + + runHook postInstall + ''; + + passthru = { + updateScript = writeShellScript "update-${pname}" '' + export PATH="${lib.makeBinPath [ curl jq common-updater-scripts ]}" + update-source-version "$UPDATE_NIX_ATTR_PATH" "$(curl https://blackfire.io/api/v1/releases | jq .probe.php --raw-output)" + ''; + }; + + meta = with lib; { + description = "Blackfire Profiler PHP module"; + homepage = "https://blackfire.io/"; + license = licenses.unfree; + maintainers = with maintainers; [ jtojnar ]; + platforms = [ "x86_64-linux" ]; + }; +} diff --git a/pkgs/top-level/php-packages.nix b/pkgs/top-level/php-packages.nix index 8f052ee87b8..1e915f93851 100644 --- a/pkgs/top-level/php-packages.nix +++ b/pkgs/top-level/php-packages.nix @@ -399,6 +399,8 @@ in meta.maintainers = lib.teams.php.members; }; + blackfire = pkgs.callPackage ../development/tools/misc/blackfire/php-probe.nix { inherit php; }; + couchbase = buildPecl rec { version = "2.6.1"; pname = "couchbase"; From 991a67d45368c331be13ba9414ec9e626c801577 Mon Sep 17 00:00:00 2001 From: Jan Tojnar Date: Sun, 4 Oct 2020 01:49:09 +0200 Subject: [PATCH 4/4] nixos/blackfire: init --- nixos/modules/module-list.nix | 1 + .../services/development/blackfire.nix | 65 +++++++++++++++++++ .../services/development/blackfire.xml | 45 +++++++++++++ 3 files changed, 111 insertions(+) create mode 100644 nixos/modules/services/development/blackfire.nix create mode 100644 nixos/modules/services/development/blackfire.xml diff --git a/nixos/modules/module-list.nix b/nixos/modules/module-list.nix index 76263a32138..77f8d27d859 100644 --- a/nixos/modules/module-list.nix +++ b/nixos/modules/module-list.nix @@ -331,6 +331,7 @@ ./services/desktops/tumbler.nix ./services/desktops/zeitgeist.nix ./services/development/bloop.nix + ./services/development/blackfire.nix ./services/development/hoogle.nix ./services/development/jupyter/default.nix ./services/development/jupyterhub/default.nix diff --git a/nixos/modules/services/development/blackfire.nix b/nixos/modules/services/development/blackfire.nix new file mode 100644 index 00000000000..6fd948cce38 --- /dev/null +++ b/nixos/modules/services/development/blackfire.nix @@ -0,0 +1,65 @@ +{ config, lib, pkgs, ... }: + +let + cfg = config.services.blackfire-agent; + + agentConfigFile = lib.generators.toINI {} { + blackfire = cfg.settings; + }; + + agentSock = "blackfire/agent.sock"; +in { + meta = { + maintainers = pkgs.blackfire.meta.maintainers; + doc = ./blackfire.xml; + }; + + options = { + services.blackfire-agent = { + enable = lib.mkEnableOption "Blackfire profiler agent"; + settings = lib.mkOption { + description = '' + See https://blackfire.io/docs/configuration/agent + ''; + type = lib.types.submodule { + freeformType = with lib.types; attrsOf str; + + options = { + server-id = lib.mkOption { + type = lib.types.str; + description = '' + Sets the server id used to authenticate with Blackfire + + You can find your personal server-id at https://blackfire.io/my/settings/credentials + ''; + }; + + server-token = lib.mkOption { + type = lib.types.str; + description = '' + Sets the server token used to authenticate with Blackfire + + You can find your personal server-token at https://blackfire.io/my/settings/credentials + ''; + }; + }; + }; + }; + }; + }; + + config = lib.mkIf cfg.enable { + environment.etc."blackfire/agent".text = agentConfigFile; + + services.blackfire-agent.settings.socket = "unix:///run/${agentSock}"; + + systemd.services.blackfire-agent = { + description = "Blackfire agent"; + + serviceConfig = { + ExecStart = "${pkgs.blackfire}/bin/blackfire-agent"; + RuntimeDirectory = "blackfire"; + }; + }; + }; +} diff --git a/nixos/modules/services/development/blackfire.xml b/nixos/modules/services/development/blackfire.xml new file mode 100644 index 00000000000..ad4af35788d --- /dev/null +++ b/nixos/modules/services/development/blackfire.xml @@ -0,0 +1,45 @@ + + Blackfire profiler + + Source: + modules/services/development/blackfire.nix + + + Upstream documentation: + + + + Blackfire is a proprietary tool for profiling applications. There are several languages supported by the product but currently only PHP support is packaged in Nixpkgs. The back-end consists of a module that is loaded into the language runtime (called probe) and a service (agent) that the probe connects to and that sends the profiles to the server. + + + To use it, you will need to enable the agent and the probe on your server. The exact method will depend on the way you use PHP but here is an example of NixOS configuration for PHP-FPM: +let + php = pkgs.php.withExtensions ({ enabled, all }: enabled ++ (with all; [ + blackfire + ])); +in { + # Enable the probe extension for PHP-FPM. + services.phpfpm = { + phpPackage = php; + }; + + # Enable and configure the agent. + services.blackfire-agent = { + enable = true; + settings = { + # You will need to get credentials at https://blackfire.io/my/settings/credentials + # You can also use other options described in https://blackfire.io/docs/configuration/agent + server-id = "XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX"; + server-token = "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"; + }; + }; + + # Make the agent run on start-up. + # Alternately, you can start it manually with `systemctl start blackfire-agent`. + systemd.services.blackfire-agent.wantedBy = [ "phpfpm-foo.service" ]; +} + + + On your developer machine, you will also want to install the client (see blackfire package) or the browser extension to actually trigger the profiling. + +