Skip to content

Python 3 compatibility fixes and two new features#95

Open
xorpaul wants to merge 4 commits into
ceph:masterfrom
xorpaul:python3-compat-and-fixes
Open

Python 3 compatibility fixes and two new features#95
xorpaul wants to merge 4 commits into
ceph:masterfrom
xorpaul:python3-compat-and-fixes

Conversation

@xorpaul

@xorpaul xorpaul commented Jul 14, 2026

Copy link
Copy Markdown

Summary

  • Python 3 compatibility — fix #!/usr/bin/env python shebang and stderr bytes-decoding bugs across all ten scripts; without these fixes the plugins either crash with TypeError or silently print b'...' byte-string representations in Nagios output on Python 3.12+
  • check_ceph_osd rewrite — replace the broken IP-based ceph osd dump approach with ceph osd tree --format json; the old code failed on clusters with separate storage networks where the DNS name resolves to a management IP that never appears in the OSD dump
  • check_ceph_rgw: add --keyringradosgw-admin accepts --keyring like all other Ceph tools but the plugin had no way to pass it
  • check_ceph_mds: add --min-active — cephadm-managed clusters assign ephemeral random suffixes to MDS daemon names, making the existing --name mode unusable for stable Nagios checks; the new mode checks that a filesystem has at least N active daemons instead

Detailed changes

Python 3 compatibility (all scripts)

All scripts updated to #!/usr/bin/env python3.

subprocess.communicate() returns stderr as bytes in Python 3. Three scripts called .split('\n') directly on the bytes object, crashing with TypeError whenever Ceph writes to stderr:

Three more scripts printed err via %s / .format() without decoding, causing error messages to include the raw b'' wrapper:

All fixed with .decode('utf-8', errors='replace') before any string operation.

check_ceph_osd — switch from ceph osd dump to ceph osd tree --format json

The previous implementation resolved the host argument via DNS, then regex-searched the resulting IP in ceph osd dump text output. This fails on any cluster where the management/DNS IP differs from the storage-network IP the OSD daemons actually bind to — a common production setup.

The new implementation uses ceph osd tree --format json, which encodes the CRUSH host-to-OSD mapping directly. The host lookup tries the FQDN first, then the short hostname, so CRUSH bucket names (typically short, e.g. osd2) are matched correctly even when -H receives an FQDN like osd2.example.com.

Additional fixes in the same script:

  • Remove socket / DNS resolution code — no longer needed
  • Remove invalid escape sequences '\.', '\[', '\]' in src/check_ceph_osd that triggered SyntaxWarning in Python 3.12+
  • --osdid now matches the numeric OSD ID (e.g. --osdid 3) rather than requiring the osd.3 prefix

check_ceph_rgw — add --keyring

Add -k/--keyring with the same existence-check validation and command-line wiring used by all other plugins in the collection. Without this, users on hosts without a default keyring had no way to authenticate.

check_ceph_mds — add --min-active

With cephadm, MDS daemon names include ephemeral random IDs (format: <fs>.<host>.<random>, e.g. m01.mds2.fezsws). These change on every daemon restart, making the --name mode unsuitable for permanent Nagios service definitions.

The new -A/--min-active <N> mode checks that the given filesystem has at least N daemons in up:active state without a laggy flag. Behaviour:

  • Active count ≥ N, no laggy daemons → OK
  • Active count ≥ N, but some laggy → WARNING
  • Active count < N → CRITICAL

--name is unchanged and still works for environments with stable MDS names. Exactly one of --name or --min-active must be provided.

Testing

Verified against a Pacific/Quincy cluster with 12 CephFS filesystems, 96 OSDs across 4 hosts, and separate management / storage networks:

check_ceph_health  --id nagios --keyring /var/lib/nagios/ceph.client.nagios.keyring
→ HEALTH OK

check_ceph_osd     --id nagios --keyring /var/lib/nagios/ceph.client.nagios.keyring -H osd2.example.com
→ OSD OK / Up OSDs: osd.3 osd.8 … (24 OSDs)

check_ceph_mds     --id nagios --keyring /var/lib/nagios/ceph.client.nagios.keyring --filesystem m01 --min-active 5
→ MDS OK: FS 'm01' has 5 active MDS

xorpaul and others added 4 commits July 14, 2026 16:23
Update all scripts to use `#!/usr/bin/env python3`. In Python 3 `subprocess.communicate()` returns stderr as bytes, so any string operation on it (split, format, %s interpolation) either crashes with TypeError or silently prints the b'' representation. Decode stderr with `.decode('utf-8', errors='replace')` before use in all affected scripts.

Scripts with the crash-on-split bug (TypeError: a bytes-like object is required, not 'str'):
- check_ceph_df
- check_ceph_health
- check_ceph_osd_df

Scripts printing raw bytes repr in error messages:
- check_ceph_mgr
- check_ceph_mon

Shebang-only fix (no stderr usage):
- check_ceph_osd_db
- check_ceph_rgw_api

Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
The previous approach resolved the OSD host's DNS name to an IP and then regex-searched that IP in `ceph osd dump` output. This fails on clusters with separate storage networks where the DNS name resolves to a management IP that never appears in the OSD dump (the OSDs bind to storage network addresses instead).

Replace with `ceph osd tree --format json` which maps CRUSH host bucket names to OSD IDs directly — no IP matching needed. Host lookup tries the FQDN first, then the short hostname, so CRUSH bucket names (typically short) are matched correctly even when `-H` receives an FQDN.

Other improvements:
- Remove the socket/DNS resolution code and the invalid escape sequence workarounds (\. \[ \]) that triggered SyntaxWarning in Python 3.12+
- --osdid now matches against the numeric OSD ID rather than the full osd.N name
- OSD in/out status is read from the reweight field in the tree JSON

Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
radosgw-admin accepts --keyring like all other Ceph tools but the plugin had no way to pass it, forcing users to rely on a keyring in the default search path. Add -k/--keyring with the same validation and command-line wiring used by the other plugins in this collection.

Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
…emon count check

cephadm-managed clusters assign ephemeral random suffixes to MDS daemon names (e.g. m01.mds2.fezsws), so the existing --name mode cannot be used for stable Nagios service checks — the name changes every time a daemon restarts.

Add -A/--min-active <N>: instead of checking a specific named daemon, verify that the filesystem has at least N non-laggy daemons in up:active state. Warns if any daemon is laggy, crits if the active count falls below the threshold.

--name remains fully functional for environments with stable MDS names. Exactly one of --name or --min-active must be provided.

Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant