Skip to content

BigFix client installer packaging issues to resolve (report upstream to BigFix) #39

Description

@jgstew

Important

This is an upstream BigFix issue, tracked here. The items below are
deficiencies in the official BigFix (BESAgent) client installer packages
(.deb / .rpm / .pkg) — they can only be fully fixed by the BigFix / HCL
team. This should be filed with BigFix directly (BigFix support / the
BigFix forum). This issue exists to document and track them from the
install_bigfix.sh
side, where each gap currently has to be worked around.

BigFix native client packaging improvements (deb / rpm / pkg)

Summary

install_bigfix.sh is a portable, single-command
installer for the BigFix (BESAgent) native client across Linux (deb/rpm/zypper),
macOS (pkg), and Solaris (pkg). Building and maintaining it surfaced several
gaps in the official client packages themselves. A large fraction of the
script's complexity exists only to work around them.

This issue collects those gaps with reproducible commands and real output. If
they were addressed upstream, installing the client would become dramatically
simpler — ideally just a package-manager install plus a documented config
drop-in, with no external helper script needed.

Each section lists: Problem → Evidence (commands + output) → How to make the
package better → What it removes from install_bigfix.sh.

Basis for these observations

  • Package version: BESAgent 11.0.6.137 (built 2026-03-30, Maintainer
    "HCL Technologies Limited").
  • Packages inspected (downloaded from software.bigfix.com/download/bes/110/):
    • BESAgent-11.0.6.137-rhe7.x86_64.rpm
    • BESAgent-11.0.6.137-ubuntu18.amd64.deb
    • BESAgent-11.0.6.137-raspbian10.armhf.deb
  • Cross-distro behavior verified with tests/test_install_bigfix_e2e.sh
    (Ubuntu, Debian, RHEL/UBI 7–9, Alma, Oracle, Fedora, Amazon Linux 2 & 2023,
    openSUSE Leap 42/15/16, plus armhf/ppc64le/i386).
  • Findings are specific to this version; please treat exact strings as such.

1. Packages do not declare their shared-library dependencies

Problem. The client links against shared libraries (notably libstdc++.so.6,
and libdbus-1.so.3 at runtime) that the packages do not declare as
dependencies. The install therefore "succeeds" while leaving the client unable
to run, and a dependency-resolving package manager has nothing to act on.

Evidence.

RPM declares no library dependencies at all — only a shell and rpmlib
capabilities:

$ rpm -qp --requires BESAgent-11.0.6.137-rhe7.x86_64.rpm
/bin/sh
/bin/sh
/bin/sh
/bin/sh
rpmlib(CompressedFileNames) <= 3.0.4-1
rpmlib(FileDigests) <= 4.6.0-1
rpmlib(PayloadFilesHavePrefix) <= 4.0-1
rpmlib(PayloadIsXz) <= 5.2-1

The DEB declares libc6 and nothing else — no libstdc++6, no libdbus-1-3:

$ dpkg-deb -f BESAgent-11.0.6.137-ubuntu18.amd64.deb Depends
libc6 (>= 2.0.105)

Consequence on a minimal/foreign-arch target (here the raspbian armhf client,
whose libstdc++6:armhf is never pulled in):

/opt/BESClient/bin/BESClient: error while loading shared libraries:
  libstdc++.so.6: cannot open shared object file: No such file or directory

Minimal container images are also commonly missing libdbus-1.so.3.

How to make the package better. Let the build compute dependencies from the
ELF automatically:

  • DEB: run dpkg-shlibdeps during packaging and substitute ${shlibs:Depends}
    into Depends:. (The package already declares libc6, so the tooling is
    clearly available — it just isn't capturing the C++ / dbus libraries.)
  • RPM: allow RPM's automatic find-requires to run (it derives
    libstdc++.so.6()(64bit) etc. from the binary), or add explicit Requires:
    for libstdc++6/libstdc++, dbus-libs/libdbus-1-3, and any other hard
    runtime libraries.

Once dependencies are declared, dnf/apt/zypper install them automatically.

Removes from install_bigfix.sh. The entire self-heal machinery in both
the rpm and deb branches: the ldd/readelf scans, on-demand
apt-file/binutils bootstrap, multiarch-triplet resolution, and the
dnf install "soname()(64bit)" loop. This is the single biggest simplification
available.

2. RPM starts only under systemd; no fallback for non-systemd hosts (Docker/CI)

Problem. The RPM ships only a systemd unit and its scriptlets are
systemd-centric, so on any host where systemd is not PID 1 (containers, image
builds, WSL, chroots) the client is installed but never started — and the
scriptlets emit errors. The DEB does not have this problem because it also
ships a SysV init.d script.

Evidence.

RPM ships only the systemd unit:

$ rpm -qlp BESAgent-11.0.6.137-rhe7.x86_64.rpm | grep -Ei 'init.d|systemd|\.service'
/usr/lib/systemd/system/besclient.service

…and its preinstall scriptlet drives the service through systemctl:

$ rpm -qp --scripts BESAgent-11.0.6.137-rhe7.x86_64.rpm | sed -n '1,20p'
preinstall scriptlet (using /bin/sh):
...
stop_old_client_pre() {
    prog=BESClient
    if [ -f /usr/lib/systemd/system/besclient.service ]; then
        /bin/systemctl stop besclient &>/dev/null
    ...

By contrast the DEB ships both an init.d script and a systemd unit:

$ dpkg-deb -c BESAgent-11.0.6.137-ubuntu18.amd64.deb | grep -Ei 'init.d|systemd|\.service'
-rwxr-xr-x  ./etc/init.d/besclient
-rw-rw-r--  ./lib/systemd/system/besclient.service.d/restart.conf

Observed failures when starting the rpm-installed client in containers:

System has not been booted with systemd as init system (PID 1). Can't operate.
Failed to connect to bus: Host is down
systemctl: command not found          # e.g. Fedora/Amazon/openSUSE minimal images

How to make the package better.

  • Ship a portable SysV init.d script in the RPM too (the DEB already does),
    so non-systemd hosts have a working start path.
  • Make post-install/scriptlets degrade gracefully: detect whether systemd is
    actually running (e.g. systemctl is-system-running/PID-1 check) and skip the
    systemctl calls instead of erroring when it isn't.
  • Optionally provide a documented foreground/daemon entrypoint for containers
    (the bigfix/bfdocker approach), so
    container images have a supported way to run the client.

Removes from install_bigfix.sh. The direct-launch fallback that starts
/opt/BESClient/bin/BESClient by hand when no init manager is usable.

3. Multi-architecture install requires manual dpkg --add-architecture

Problem. Installing the armhf .deb on a 64-bit host requires the operator
to enable the foreign architecture first; the package does not, and its control
metadata carries no Multi-Arch: field.

Evidence. The installer must run this before apt-get install for the
Raspberry Pi OS / Raspbian armhf client:

dpkg --add-architecture armhf
apt-get update

The control file is single-arch with no multiarch hint:

$ dpkg-deb -f BESAgent-11.0.6.137-raspbian10.armhf.deb | grep -Ei 'Architecture|Multi-Arch'
Architecture: armhf

Without the architecture enabled, the install is refused outright — this is
not just a library-resolution problem. dpkg rejects a foreign-arch archive at
archive-processing time, before it unpacks anything:

$ dpkg --print-foreign-architectures        # armhf NOT enabled -> empty
$ dpkg -i coreutils_9.1-1_armhf.deb          # any armhf .deb, on an arm64/amd64 host
dpkg: error processing archive coreutils_9.1-1_armhf.deb (--install):
 package architecture (armhf) does not match system (arm64)
Errors were encountered while processing:
 coreutils_9.1-1_armhf.deb
# rc=1

Important: because that rejection happens before any maintainer script
runs, dpkg --add-architecture cannot be moved into the package's preinst
— dpkg will not run the preinst of a package it has already refused. Enabling the
architecture is necessarily a system/dpkg-level step performed before the
install, by the operator or deploying tool. (dpkg -i --force-architecture can
override the check, but it is an operator flag the package cannot carry, and
armhf still has to be enabled for apt to fetch the multiarch library
dependencies — so it does not actually help.)

How to make the package better (in priority order).

  1. The real fix — publish a native 64-bit ARM (arm64/aarch64) .deb so
    64-bit ARM hosts install the client for their own architecture and never need
    multiarch at all. Native aarch64 RPMs already exist
    (e.g. BESAgent-11.0.6.137-al2.aarch64.rpm), so an aarch64 .deb would round
    out the set. This removes the problem entirely rather than working around it.
  2. Until then, document clearly that dpkg --add-architecture <arch> +
    apt-get update is a required prerequisite the operator/tool must run first —
    and that it cannot be packaged into a maintainer script (see above).
  3. Add appropriate Multi-Arch: control metadata so apt can reason about the
    package on multiarch systems.

Removes from install_bigfix.sh. The dpkg --add-architecture + apt-get update step and the armhf special-casing.

4. No supported drop-in for client configuration (besclient.config)

Problem. There is no documented, supported way to seed client settings at
install time on Linux/Solaris. Installers must generate the client's internal
registry-style besclient.config themselves. (This was a primary motivation for
install_bigfix.sh in the first place.)

Evidence. The DEB ships maintainer scripts but no settings drop-in
mechanism — nothing consumes a clientsettings.cfg:

$ dpkg-deb --control BESAgent-11.0.6.137-ubuntu18.amd64.deb ./ctrl && ls -1 ./ctrl
conffiles
control
postinst
postrm
prerm

So the installer has to synthesize /var/opt/BESClient/besclient.config in the
client's own format, e.g.:

[Software\BigFix\EnterpriseClient]
EnterpriseClientFolder = /opt/BESClient

[Software\BigFix\EnterpriseClient\GlobalOptions]
StoragePath = /var/opt/BESClient
LibPath = /opt/BESClient/BESLib

[Software\BigFix\EnterpriseClient\Settings\Client\_BESClient_Comm_CommandPollEnable]
value = 1
... one stanza per setting ...

This is brittle (it required Solaris oawk-portability workarounds in the
generator) and forces every deployment tool to know an undocumented internal
format.

How to make the package better. Adopt the model the Windows installer and
macOS .pkg already use: on first start, read a masthead/actionsite.afxm
and a plain clientsettings.cfg from a documented staging path, and have
the client self-initialize besclient.config from them. A simple, documented
key=value clientsettings.cfg contract (no registry-style stanzas) would let any
deployment tool configure the client without reverse-engineering the format.

Removes from install_bigfix.sh. The entire awk besclient.config
generator and its cross-platform portability workarounds.

5. Bring deb/rpm/Solaris up to the macOS .pkg behavior (the overall goal)

Problem. Behavior that "just works" on macOS is absent on Linux/Solaris,
which is the root reason a wrapper script is needed at all.

Evidence / contrast. On macOS the .pkg reads the masthead from the staging
folder, writes its own configuration, and starts the service itself — the
wrapper does almost nothing platform-specific there. On Linux/Solaris the wrapper
must place the masthead, generate besclient.config, install missing libraries,
and start the service by hand (and Solaris pkgadd still needs an interactive
echo y).

How to make the package better. Converge the deb/rpm/Solaris packages on the
macOS model:

This is the north-star. With #1, #2, and #4 in place, a correct cross-distro
install collapses to roughly:

# install (deps resolved by the package manager)
dnf install ./BESAgent-<ver>.rpm      # or apt-get install ./...deb / zypper install

# configure: drop the masthead + a plain clientsettings.cfg in the documented
# location; the client self-initializes and starts on first run

At that point install_bigfix.sh could drop the majority of its logic:
per-distro filename mapping, the ldd/readelf/apt-file library self-heal,
the manual dpkg --add-architecture, the besclient.config generator, and the
manual service-start fallback.


Appendix — reproduce the package-metadata checks

Run in a debian:12 container (it has dpkg-deb, and rpm + binutils are one
apt-get install away), or adapt for an RPM distro:

apt-get update -qq && apt-get install -y -qq curl rpm binutils
base=https://software.bigfix.com/download/bes/110
curl -fsSO $base/BESAgent-11.0.6.137-rhe7.x86_64.rpm
curl -fsSO $base/BESAgent-11.0.6.137-ubuntu18.amd64.deb

# 1. declared dependencies
rpm -qp --requires BESAgent-11.0.6.137-rhe7.x86_64.rpm     # -> no library sonames
dpkg-deb -f BESAgent-11.0.6.137-ubuntu18.amd64.deb Depends # -> libc6 only

# 2. service integration
rpm  -qlp BESAgent-11.0.6.137-rhe7.x86_64.rpm     | grep -Ei 'init.d|systemd|service'  # systemd unit only
dpkg-deb -c BESAgent-11.0.6.137-ubuntu18.amd64.deb | grep -Ei 'init.d|systemd|service'  # init.d + systemd

# 4. configuration drop-in
dpkg-deb --control BESAgent-11.0.6.137-ubuntu18.amd64.deb ./ctrl && ls ./ctrl  # no settings mechanism

Cross-distro install/runtime behavior: tests/test_install_bigfix_e2e.sh in this
repo.

Metadata

Metadata

Assignees

No one assigned

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions