diff --git a/machines/stel-xps/default.nix b/machines/stel-xps/default.nix index d14fa59..f4cc5d2 100644 --- a/machines/stel-xps/default.nix +++ b/machines/stel-xps/default.nix @@ -67,6 +67,12 @@ }; }; + kbs.glpi-inventory = { + enable = true; + tag = "10002205"; + onCalendar = "*-*-* 12:12:12"; + }; + boot = { extraModulePackages = [config.boot.kernelPackages.v4l2loopback]; diff --git a/modules/glpi-inventory.nix b/modules/glpi-inventory.nix new file mode 100644 index 0000000..ce86e0d --- /dev/null +++ b/modules/glpi-inventory.nix @@ -0,0 +1,146 @@ +{ config, lib, pkgs, ... }: + +with lib; { + options.kbs.glpi-inventory = { + enable = mkEnableOption "enable the GLPI inventory service"; + + tag = mkOption { + description = + "tag used for associating the system to an organisational unit"; + example = "10002205"; # KBS group + type = types.str; + }; + + url = mkOption { + description = "URL for submission to the GLPI server"; + default = "https://glpi.tu-dresden.de/marketplace/glpiinventory/"; + type = types.str; + }; + + onCalendar = mkOption { + description = + "When to run the GLPI inventory. See systemd.time(7) for more information about the format."; + default = "daily"; + type = types.str; + }; + + scanHomedirs = mkOption { + description = "scan user homedirs for software"; + default = false; + type = types.bool; + }; + + scanProfiles = mkOption { + description = "scan user profiles for software"; + default = false; + type = types.bool; + }; + + noCategories = mkOption { + description = "categories to exclude from the inventory"; + default = [ + "environment" + "process" + "local_group" + "local_user" + "user" + "printer" + "usb" + ]; + type = types.listOf (types.enum [ + "accesslog" + "antivirus" + "battery" + "bios" + "controller" + "cpu" + "database" + "drive" + "environment" + "firewall" + "hardware" + "input" + "licenseinfo" + "local_group" + "local_user" + "lvm" + "memory" + "modem" + "monitor" + "network" + "os" + "port" + "printer" + "process" + "provider" + "psu" + "registry" + "remote_mgmt" + "rudder" + "slot" + "software" + "sound" + "storage" + "usb" + "user" + "video" + "virtualmachine" + ]); + }; + }; + + config = let + cfg = config.kbs.glpi-inventory; + noCategories = concatStringsSep "," cfg.noCategories; + inventoryArgs = concatStringsSep " " (concatLists [ + [ "--tag=${cfg.tag}" ] + (optional cfg.scanHomedirs "--scan-homedirs") + (optional cfg.scanProfiles "--scan-profiles") + (optional (noCategories != "") "--no-category=${noCategories}") + ]); + in mkIf cfg.enable { + systemd = { + services.glpi-submit-inventory = { + description = "Run the GLPI inventory and submit the results"; + + serviceConfig = { + CPUSchedulingPolicy = "idle"; + IOSchedulingClass = "idle"; + PrivateTmp = true; + DynamicUser = true; + + ExecStart = let + submitInventory = pkgs.writeShellScript "glpi-write-inventory" '' + ${pkgs.glpi-agent}/bin/glpi-inventory ${inventoryArgs} > /tmp/inventory.xml + ${pkgs.glpi-agent}/bin/glpi-injector --file /tmp/inventory.xml --url ${cfg.url} --no-compression + ''; + in "!${submitInventory}"; + }; + + requires = [ "network-online.target" ]; + }; + + timers.glpi-submit-inventory = { + description = "Run the GLPI inventory and submit the results"; + + timerConfig = { + Unit = "glpi-submit-inventory.service"; + OnCalendar = cfg.onCalendar; + Persistent = true; + }; + + wantedBy = [ "timers.target" ]; + }; + }; + + # make sure we don't accidentally submit inventories for VM builds. + virtualisation = let + glpiInventory = { + kbs.glpi-inventory.url = "http://localhost/glpiinventory"; + }; + in { + vmVariant = glpiInventory; + vmVariantWithBootLoader = glpiInventory; + }; + }; +} diff --git a/packages/glpi-agent/0001-Fix-test-for-UTC-timezone.patch b/packages/glpi-agent/0001-Fix-test-for-UTC-timezone.patch new file mode 100644 index 0000000..3c2ba14 --- /dev/null +++ b/packages/glpi-agent/0001-Fix-test-for-UTC-timezone.patch @@ -0,0 +1,25 @@ +From 09ca9a19176fa2590976efb9aaef28678eb8146c Mon Sep 17 00:00:00 2001 +From: Maximilian Marx +Date: Fri, 20 Oct 2023 16:26:28 +0200 +Subject: [PATCH 1/3] Fix test for UTC timezone + +--- + resources/linux/packaging/rpm | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/resources/linux/packaging/rpm b/resources/linux/packaging/rpm +index 1eabf8bec..abb30e52e 100644 +--- a/resources/linux/packaging/rpm ++++ b/resources/linux/packaging/rpm +@@ -4,7 +4,7 @@ gjs x86_64 1.32.0-1.mga2 1332868101 176167 Mageia.Org JavaScript bindings based + lib64nss3 x86_64 3.13.4-1.mga2 1334780473 3346040 Mageia.Org Network Security Services (NSS) Unspecified + ruby-term-ansicolor noarch 1.0.5-3.mga1 1311937930 7211 Mageia.Org Ruby library that colors strings using ANSI escape sequences Libraries + lib64tidy-devel x86_64 20090904-3.mga1 1325506366 1930155 Mageia.Org Headers for developing programs that will use tidy Unspecified +-xfsprogs x86_64 3.1.8-1.mga2 1332632724 3628382 Mageia.Org Utilities for managing the XFS filesystem System Environment/Base ++xfsprogs x86_64 3.1.8-1.mga2 1332636324 3628382 Mageia.Org Utilities for managing the XFS filesystem System Environment/Base + lib64swresample0 x86_64 0.10.2-2.mga2.tainted 1334217734 35016 Mageia.Org Shared library part of ffmpeg Unspecified + lib64pyglib2.0_0 x86_64 2.28.6-6.mga2 1329989131 18672 Mageia.Org Python Glib bindings shared library Unspecified + perl-Gtk2-ImageView x86_64 0.50.0-4.mga2 1333463926 153539 Mageia Perl bindings to the GtkImageView image viewer widget Development/Libraries +-- +2.40.1 + diff --git a/packages/glpi-agent/0002-Add-skip-for-software-inventory-test.patch b/packages/glpi-agent/0002-Add-skip-for-software-inventory-test.patch new file mode 100644 index 0000000..541a943 --- /dev/null +++ b/packages/glpi-agent/0002-Add-skip-for-software-inventory-test.patch @@ -0,0 +1,27 @@ +From 2a6a6cc1c0af556d625bee2eae907e916fef7a37 Mon Sep 17 00:00:00 2001 +From: Maximilian Marx +Date: Sat, 21 Oct 2023 17:50:15 +0200 +Subject: [PATCH 2/3] Add skip for software inventory test + +--- + t/apps/agent.t | 4 ++++ + 1 file changed, 4 insertions(+) + +diff --git a/t/apps/agent.t b/t/apps/agent.t +index 18563c6f9..28a5a0878 100755 +--- a/t/apps/agent.t ++++ b/t/apps/agent.t +@@ -84,6 +84,10 @@ SKIP: { + skip "No installed software seen on this system", 1 + if @hasSoftwareOutput == 0; + } ++ if (defined($ENV{GLPI_SKIP_SOFTWARE_INVENTORY_TEST})) { ++ skip "skipping software inventory test", 1 ++ if $ENV{GLPI_SKIP_SOFTWARE_INVENTORY_TEST}; ++ } + ok( + exists $content->{REQUEST}->{CONTENT}->{SOFTWARES}, + 'inventory has software' +-- +2.40.1 + diff --git a/packages/glpi-agent/0003-Do-not-run-the-GC-to-determine-what-is-in-the-nix-st.patch b/packages/glpi-agent/0003-Do-not-run-the-GC-to-determine-what-is-in-the-nix-st.patch new file mode 100644 index 0000000..7a01285 --- /dev/null +++ b/packages/glpi-agent/0003-Do-not-run-the-GC-to-determine-what-is-in-the-nix-st.patch @@ -0,0 +1,26 @@ +From c28c13ef9425671b6fbf33bb2e8415704359ce79 Mon Sep 17 00:00:00 2001 +From: Maximilian Marx +Date: Thu, 16 Nov 2023 13:06:32 +0100 +Subject: [PATCH 3/3] Do not run the GC to determine what is in the nix store + +Signed-off-by: Maximilian Marx +--- + lib/GLPI/Agent/Task/Inventory/Generic/Softwares/Nix.pm | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/lib/GLPI/Agent/Task/Inventory/Generic/Softwares/Nix.pm b/lib/GLPI/Agent/Task/Inventory/Generic/Softwares/Nix.pm +index fd4c947c2..141557d4e 100644 +--- a/lib/GLPI/Agent/Task/Inventory/Generic/Softwares/Nix.pm ++++ b/lib/GLPI/Agent/Task/Inventory/Generic/Softwares/Nix.pm +@@ -17,7 +17,7 @@ sub doInventory { + my $inventory = $params{inventory}; + my $logger = $params{logger}; + +- my $command = 'nix-store --gc --print-live'; ++ my $command = 'nix --experimental-features nix-command path-info -r /run/current-system'; + my $packages = _getPackagesList( + logger => $logger, command => $command + ); +-- +2.40.1 + diff --git a/packages/glpi-agent/default.nix b/packages/glpi-agent/default.nix new file mode 100644 index 0000000..6f5880b --- /dev/null +++ b/packages/glpi-agent/default.nix @@ -0,0 +1,137 @@ +{ + lib, + perlPackages, + nix, + dmidecode, + pciutils, + usbutils, + iproute2, + nettools, + fetchFromGitHub, + makeWrapper, + libredirect, + iana-etc, + xrandr, + xdpyinfo, + procps, + which, +}: +perlPackages.buildPerlPackage { + pname = "glpi-agent"; + version = "1.5"; + + src = fetchFromGitHub { + owner = "glpi-project"; + repo = "glpi-agent"; + rev = "1.5"; + sha256 = "l5ist5a07X4IG0OsYjqwMvhA5UN9/CxXrVcfhNTaBgc="; + }; + + patches = [ + ./0001-Fix-test-for-UTC-timezone.patch + ./0002-Add-skip-for-software-inventory-test.patch + ./0003-Do-not-run-the-GC-to-determine-what-is-in-the-nix-st.patch + ]; + + postPatch = '' + patchShebangs bin + + substituteInPlace "lib/GLPI/Agent/Tools/Linux.pm" \ + --replace /sbin/ip ${iproute2}/sbin/ip + substituteInPlace "lib/GLPI/Agent/Task/Inventory/Linux/Networks.pm" \ + --replace /sbin/ip ${iproute2}/sbin/ip + ''; + + buildTools = []; + nativeBuildInputs = [makeWrapper procps]; + buildInputs = with perlPackages; [ + CGI + CpanelJSONXS + DataStructureUtil + DataUUID + DateTime + FileCopyRecursive + HTTPDaemon + HTTPProxy + HTTPServerSimple + HTTPServerSimpleAuthen + IOCapture + IOSocketSSL + IPCRun + JSON + LWPProtocolHttps + ModuleInstall + NetSNMP + ParallelForkManager + TestCPANMeta + TestCompile + TestDeep + TestException + TestMockModule + TestMockObject + TestNoWarnings + XMLLibXML + ]; + propagatedBuildInputs = with perlPackages; [ + FileWhich + LWP + NetIP + TextTemplate + UNIVERSALrequire + XMLTreePP + ]; + + installPhase = '' + mkdir -p $out + + cp -r bin $out + cp -r lib $out + cp -r share $out + + for cur in $out/bin/*; do + if [ -x "$cur" ]; then + sed -e "s|./lib|$out/lib|" -i "$cur" + wrapProgram "$cur" --prefix PATH : ${ + lib.makeBinPath [ + nix + dmidecode + iproute2 + nettools + pciutils + procps + usbutils + xdpyinfo + xrandr + which + ] + } + fi + done + ''; + + preCheck = let + inherit (lib) concatStringsSep mapAttrsToList; + redirects = { + "/etc/protocols" = "${iana-etc}/etc/protocols"; + "/etc/services" = "${iana-etc}/etc/services"; + }; + REDIRECTS = + concatStringsSep ":" + (mapAttrsToList (from: to: "${from}=${to}") redirects); + in '' + export NIX_REDIRECTS="${REDIRECTS}" \ + LD_PRELOAD=${libredirect}/lib/libredirect.so \ + GLPI_SKIP_SOFTWARE_INVENTORY_TEST=1 + ''; + postCheck = '' + unset NIX_REDIRECTS LD_PRELOAD GLPI_SKIP_SOFTWARE_INVENTORY_TEST + ''; + + outputs = ["out"]; + + meta = { + homepage = "https://glpi-project.org/"; + description = "GLPI unified Agent for UNIX, Linux, Windows and MacOSX"; + license = lib.licenses.gpl2; + }; +}