stages/tar: add --numeric-owner option

The numeric-owner option omits the inclusion of user and group names in
the archive metadata.  This is often desirable since name and group
mappings can change the ownership of files during extraction.

The test uses the tarfile module to check that the uname and gname
attributes in the tar archive itself are empty, which is the intended
effect of enabling numeric-owner [1].

RHEL-102854

[1] https://www.gnu.org/software/tar//manual/html_section/Attributes.html
This commit is contained in:
Achilleas Koutsou 2025-07-11 17:07:04 +02:00 committed by Simon de Vlieger
parent 77701f6f1d
commit e31084e520
3 changed files with 29 additions and 0 deletions

View file

@ -37,6 +37,9 @@ def main(inputs, output_dir, options):
if transform:
extra_args += ["--transform", transform]
if options.get("numeric-owner", False):
extra_args += ["--numeric-owner"]
compression = options.get("compression", "auto")
if compression == "auto":

View file

@ -113,6 +113,10 @@
"transform": {
"type": "string",
"description": "Used to transform filenames and directly passed to --transform"
},
"numeric-owner": {
"type": "boolean",
"description": "Always use numbers for user/group names"
}
}
},

View file

@ -3,6 +3,7 @@
import os.path
import re
import subprocess
import tarfile
import pytest
@ -190,3 +191,24 @@ def test_tar_compress(tmp_path, stage_module, fake_inputs, filename, compression
assert os.path.exists(tar_path)
output = subprocess.check_output(["file", tar_path], encoding="utf-8")
assert expected in output.lower()
@pytest.mark.skipif(not has_executable("tar"), reason="no tar executable")
@pytest.mark.parametrize("numeric_owner", [True, False,])
def test_tar_numeric_owner(tmp_path, stage_module, fake_inputs, numeric_owner):
options = {
"filename": "out.tar",
"numeric-owner": numeric_owner,
}
stage_module.main(fake_inputs, tmp_path, options)
tar_path = os.path.join(tmp_path, "out.tar")
assert os.path.exists(tar_path)
# read the tar archive directly instead of relying on parsing the human-readable verbose output
with tarfile.open(tar_path, mode="r") as archive:
for item in archive.getmembers():
# when enabling numeric-owner, the uname and gname fields are empty
info = item.get_info()
assert (info["uname"] == "") == numeric_owner
assert (info["gname"] == "") == numeric_owner