OMD[cmk]:~$ omd backup /tmp/cmk-backup.10.06.2026bis.tar.gz
Traceback (most recent call last):
File “/omd/sites/cmk/bin/omd”, line 54, in
omdlib.main.main()
~~~~~~~~~~~~~~~~^^
File “/omd/versions/2.5.0p5.community/lib/python3/omdlib/main.py”, line 3343, in main
_run_command(command, site, global_opts, args, options)
~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File “/omd/versions/2.5.0p5.community/lib/python3/omdlib/main.py”, line 3305, in _run_command
omdlib.backup.main_backup(object(), site, global_opts, args, command_options)
~~~~~~~~~~~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File “/omd/versions/2.5.0p5.community/lib/python3/omdlib/backup.py”, line 116, in main_backup
returncode = main_site_backup(backup_args)
File “/omd/versions/2.5.0p5.community/lib/python3/omdlib/backup.py”, line 126, in main_site_backup
_try_backup_site_to_tarfile(tar, BackupExclusions.from_args(args), site, args.verbose)
~~~~~~~~~~~~~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File “/omd/versions/2.5.0p5.community/lib/python3/omdlib/backup.py”, line 60, in _try_backup_site_to_tarfile
_backup_site_to_tarfile(
~~~~~~~~~~~~~~~~~~~~~~~^
site.name,
^^^^^^^^^^
…<4 lines>…
verbose,
^^^^^^^^
)
^
File “/omd/versions/2.5.0p5.community/lib/python3/omdlib/backup.py”, line 173, in _backup_site_to_tarfile
_tar_add(
~~~~~~~~^
rrd_socket,
^^^^^^^^^^^
…<4 lines>…
verbose=verbose,
^^^^^^^^^^^^^^^^
)
^
File “/omd/versions/2.5.0p5.community/lib/python3/omdlib/backup.py”, line 400, in _tar_add
_tar_add( # recursive call
~~~~~~~~^^^^^^^^^^^^^^^^^^^
rrd_socket,
^^^^^^^^^^^
…<4 lines>…
verbose=verbose,
^^^^^^^^^^^^^^^^
)
^
File “/omd/versions/2.5.0p5.community/lib/python3/omdlib/backup.py”, line 400, in _tar_add
_tar_add( # recursive call
~~~~~~~~^^^^^^^^^^^^^^^^^^^
rrd_socket,
^^^^^^^^^^^
…<4 lines>…
verbose=verbose,
^^^^^^^^^^^^^^^^
)
^
File “/omd/versions/2.5.0p5.community/lib/python3/omdlib/backup.py”, line 371, in _tar_add
if not predicate(tarinfo):
~~~~~~~~~^^^^^^^^^
File “/omd/versions/2.5.0p5.community/lib/python3/omdlib/backup.py”, line 155, in accepted_files
return not any(
~~~^
fnmatch.fnmatch(tarinfo.name[len(site_name) + 1 :], glob_pattern)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
for glob_pattern in excludes
^^^^^^^^^^^^^^^^^^^^^^^^^^^^
)
^
File “/omd/versions/2.5.0p5.community/lib/python3/omdlib/backup.py”, line 156, in
fnmatch.fnmatch(tarinfo.name[len(site_name) + 1 :], glob_pattern)
^^^^^^^^^^^^
AttributeError: ‘NoneType’ object has no attribute ‘name’
Same root cause here, different trigger and the regression is easy to pinpoint.
Diffed omdlib/backup.py between v2.4.0 and v2.5.0p6:
tarinfo = tar.gettarinfo(name, arcname)
-
if tarinfo is None or not predicate(tarinfo): # 2.4.0
-
if not predicate(tarinfo): # 2.5.0p6
return
The tarinfo is None guard was dropped between 2.4 and 2.5 — likely a casualty of
the refactor that introduced BackupExclusions as a dataclass and renamed
tar_add → _tar_add.
tarfile.gettarinfo() returns None for file types tarfile can’t represent —
most importantly Unix sockets (S_ISSOCK). Without the guard, predicate(None)
explodes in accepted_files at tarinfo.name[...].
In our case the trigger were stale OpenSSH ControlMaster sockets in
~/.ssh/control-* (the site fetches agents over SSH and the ControlPath points
at the site home). 2.4 silently skipped them, 2.5 crashes the whole backup.
WATO exposes no custom-exclude field in the backup job, only the
rrds/agents/logs toggles, so we can’t work around this from the UI. We resorted to hotpatching by doing
sed -i 's| if not predicate(tarinfo):| if tarinfo is None or not predicate(tarinfo):|' /omd/versions/2.5.0p6.pro/lib/python3/omdlib/backup.py
Looks like a clear regression, could the Checkmk team please look at this?
Restoring the tarinfo is None or part should be enough.