Include held (dpkg selection-state hold) but installed packages in system.sw.packages.get on Debian systems

XMLWordPrintable

    • Type: New Feature Request
    • Resolution: Unresolved
    • Priority: Medium
    • None
    • Affects Version/s: 7.0.26
    • Component/s: Agent2 (G)
    • None

      Problem

      On Debian-based (dpkg) systems, the Zabbix agent's built-in software inventory
      items silently omit packages whose dpkg selection state is hold. A package
      pinned with apt-mark hold remains installed and running, yet its version
      cannot be collected through any built-in item. This produces version drift and
      inventory blind spots for exactly the packages an operator has most deliberately
      frozen.

      Current behavior (root cause)

      The filtering is identical across both agents (Zabbix agent / C and Zabbix
      agent 2 / Go), in two separate code paths, and is consistent across release
      branches.

      Zabbix agent (C)src/libs/zbxsysinfo/linux/software.c

      • system.sw.packages runs dpkg --get-selections. Parser dpkg_list
        (named dpkg_parser in 6.0) accepts a line only when the selection state is
        exactly install (strcmp(tmp, "install")). Lines with state hold are
        dropped.
      • system.sw.packages.get runs
        LC_ALL=C dpkg-query -W -f='${Status},${Package},${Version},${Architecture},${Installed-Size}\n'.
        Parser dpkg_details accepts a package only when the status is exactly
        install ok installed (strcmp(status, "install ok installed")). A held
        package reports hold ok installed and is excluded.

      Zabbix agent 2 (Go)src/go/plugins/system/sw/sw_linux.go

      • dpkgList: split[len(split)-1] != "install" – same selection-state filter.
      • dpkgDetails: split[0] != "install ok installed" – same status filter.

      Verified on release/6.0, release/7.0 and master for the C agent, and
      on release/7.0 and master for agent 2.

      Note: the dpkg-query command used by .get already captures ${Status},
      whose first token is the selection state (e.g. hold). The information needed
      to report held packages is therefore already fetched – it is discarded at the
      parser stage. No additional command or query is required.

      Steps to reproduce

      1. Pick an installed package and hold it: apt-mark hold <package>
      2. Query the item in agent test mode:
        zabbix_agentd -t system.sw.packages.get
        # or, for agent 2:
        zabbix_agent2 -t system.sw.packages.get
        
      3. Observe: the held package is absent from the JSON output, while
        dpkg -l <package> still lists it as installed (state hi).

      Expected behavior

      Version information for held-but-installed packages should be collectible through
      a built-in agent item, without resorting to system.run or UserParameter.

      Proposed solution (backward-compatible)

      The proposal is intentionally scoped to system.sw.packages.get (the structured
      JSON item). The legacy flat system.sw.packages is documented above only for
      completeness; it has no structured field to carry state and is not the target.

      Two additive changes, neither altering existing default output:

      1. Expose a per-package selection field in the JSON (suggested name selection:
        install / hold / deinstall / ...), sourced from the ${Status}
        token already captured, or from ${db:Status-Want}. selection is suggested
        over status to avoid collision with dpkg's own "status" token (installed /
        config-files / ...).
      2. Include held (and, if desired, other non-install) packages only when
        explicitly requested via a new opt-in parameter/flag. Default behavior stays
        exactly as today.

      Rationale for opt-in rather than default inclusion: adding held packages
      unconditionally would change current output (new entries appear), which can break
      users who diff or count the returned package set. Gating inclusion behind an
      explicit flag preserves backward compatibility for every existing user.

      Exact implementation (field name, flag syntax) is left to the Zabbix team;
      several reasonable approaches exist.

      Use case

      apt-mark hold is a standard mechanism to prevent automatic upgrade or
      replacement of a package from distribution repositories when a different source of
      truth manages it. Such packages are installed and in production, so their versions
      are precisely what an operator wants under monitoring – for example, to alert
      when a held package drifts from an approved baseline version across a fleet.
      Because these are the packages most deliberately frozen, the current blind spot
      affects the highest-value inventory targets.

      system.run and UserParameter are not viable in many environments (remote/
      flexible keys disabled for security posture, plus the maintenance and
      attack-surface cost of custom scripts at scale), which is why a built-in solution
      is needed.

      Affected versions

      Behavior verified on release/6.0, release/7.0 and master.

      Backward compatibility

      The default output of both system.sw.packages and system.sw.packages.get
      must remain unchanged. All new behavior – inclusion of held/non-install packages
      and any new JSON field – must be opt-in only.

            Assignee:
            Zabbix Integration Team
            Reporter:
            mehmet akbaş
            Votes:
            0 Vote for this issue
            Watchers:
            2 Start watching this issue

              Created:
              Updated: