stages(tar): expose new transform option to tar stage
This commit adds a new `transform` option to the tar stages that maps directly to the `--transform=` comamndline argument of tar(1). This allows to transform the names while files/dirs are added to a tarfile. This is useful for the `gcp` pipeline for bootc-image-builder where we want to create a gcp tar file that expects the disk image filename in the tar to be exactly `disk.raw`. Note that tar allows only a single `--transform` and we leave it to the user to construct `sed` expressions if multiple renames are required.
This commit is contained in:
parent
68b6481f54
commit
6cc0e584ba
3 changed files with 54 additions and 0 deletions
|
|
@ -33,6 +33,10 @@ def main(inputs, output_dir, options):
|
||||||
if options.get("sparse", False):
|
if options.get("sparse", False):
|
||||||
extra_args += ["--sparse"]
|
extra_args += ["--sparse"]
|
||||||
|
|
||||||
|
transform = options.get("transform")
|
||||||
|
if transform:
|
||||||
|
extra_args += ["--transform", transform]
|
||||||
|
|
||||||
# Set up the tar command.
|
# Set up the tar command.
|
||||||
tar_cmd = [
|
tar_cmd = [
|
||||||
"tar",
|
"tar",
|
||||||
|
|
|
||||||
|
|
@ -98,6 +98,10 @@
|
||||||
"description": "Make archive files sparse",
|
"description": "Make archive files sparse",
|
||||||
"type": "boolean",
|
"type": "boolean",
|
||||||
"default": false
|
"default": false
|
||||||
|
},
|
||||||
|
"transform": {
|
||||||
|
"type": "string",
|
||||||
|
"description": "Used to transform filenames and directly passed to --transform"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
|
||||||
|
|
@ -19,11 +19,16 @@ STAGE_NAME = "org.osbuild.tar"
|
||||||
"root-node": "include",
|
"root-node": "include",
|
||||||
"paths": ["file1"]
|
"paths": ["file1"]
|
||||||
}, "{'filename': 'out.tar', 'root-node': 'include', 'paths': ['file1']} is not valid under any of the given schemas"),
|
}, "{'filename': 'out.tar', 'root-node': 'include', 'paths': ['file1']} is not valid under any of the given schemas"),
|
||||||
|
({
|
||||||
|
"filename": "foo",
|
||||||
|
"transform": ["transform-cannot-be-passed-multiple-times"],
|
||||||
|
}, " is not of type 'string'"),
|
||||||
# good
|
# good
|
||||||
({"filename": "out.tar", "root-node": "include"}, ""),
|
({"filename": "out.tar", "root-node": "include"}, ""),
|
||||||
({"filename": "out.tar", "paths": ["file1"]}, ""),
|
({"filename": "out.tar", "paths": ["file1"]}, ""),
|
||||||
({"filename": "out.tar", "sparse": True}, ""),
|
({"filename": "out.tar", "sparse": True}, ""),
|
||||||
({"filename": "out.tar"}, ""),
|
({"filename": "out.tar"}, ""),
|
||||||
|
({"filename": "out.tar", "transform": "s/foo/bar"}, ""),
|
||||||
])
|
])
|
||||||
def test_schema_validation_tar(stage_schema, test_data, expected_err):
|
def test_schema_validation_tar(stage_schema, test_data, expected_err):
|
||||||
test_input = {
|
test_input = {
|
||||||
|
|
@ -99,3 +104,44 @@ def test_tar_paths(tmp_path, stage_module, fake_inputs):
|
||||||
assert os.path.exists(tar_path)
|
assert os.path.exists(tar_path)
|
||||||
output = subprocess.check_output(["tar", "-tf", tar_path], encoding="utf-8").split("\n")
|
output = subprocess.check_output(["tar", "-tf", tar_path], encoding="utf-8").split("\n")
|
||||||
assert ["file2", "file1", "file1", "file2", ""] == output
|
assert ["file2", "file1", "file1", "file2", ""] == output
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.skipif(not has_executable("tar"), reason="no tar executable")
|
||||||
|
@pytest.mark.parametrize("transform,expected_tar_output", [
|
||||||
|
# unrelated transform
|
||||||
|
("s/foo/bar/", ["file1", "file2", ""]),
|
||||||
|
# one file
|
||||||
|
("s/^file1$/foo99/", ["foo99", "file2", ""]),
|
||||||
|
# one file
|
||||||
|
("s/file1/foo99/;s/file2/bar11/", ["foo99", "bar11", ""]),
|
||||||
|
])
|
||||||
|
def test_tar_transform(tmp_path, stage_module, fake_inputs, transform, expected_tar_output):
|
||||||
|
options = {
|
||||||
|
"filename": "out.tar",
|
||||||
|
"paths": [
|
||||||
|
"file1",
|
||||||
|
"file2",
|
||||||
|
],
|
||||||
|
"transform": transform,
|
||||||
|
}
|
||||||
|
stage_module.main(fake_inputs, tmp_path, options)
|
||||||
|
|
||||||
|
tar_path = os.path.join(tmp_path, "out.tar")
|
||||||
|
assert os.path.exists(tar_path)
|
||||||
|
output = subprocess.check_output(["tar", "-tf", tar_path], encoding="utf-8").split("\n")
|
||||||
|
assert output == expected_tar_output
|
||||||
|
|
||||||
|
|
||||||
|
def test_tar_transform_no_sh(tmp_path, stage_module, fake_inputs):
|
||||||
|
options = {
|
||||||
|
"filename": "out.tar",
|
||||||
|
"paths": [
|
||||||
|
"file1",
|
||||||
|
],
|
||||||
|
# GNU sed allows to run shell commands with "/e"
|
||||||
|
# ensure here we donot allow this
|
||||||
|
"transform": "s/file1/date/e",
|
||||||
|
}
|
||||||
|
with pytest.raises(subprocess.CalledProcessError) as ex:
|
||||||
|
stage_module.main(fake_inputs, tmp_path, options)
|
||||||
|
assert "exit status 2" in str(ex.value)
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue