objectstore: add new skip_preserve_owner to Object.export()
This commit allows to exclude preserving ownership from an object export. This is required to fix the issue that on macOS the an podman based workflow cannot export objects with preserving ownerships. Originally this was a `no_preserve: Optional[List[str]] = None)` to be super flexible in what we pass to `cp` but then I felt like YAGNI - if we need more we can trivially change this (internal) API again :)
This commit is contained in:
parent
975057a0a9
commit
e35d841509
2 changed files with 42 additions and 11 deletions
|
|
@ -244,18 +244,20 @@ class Object:
|
|||
if self.mode != want:
|
||||
raise ValueError(f"Wrong object mode: {self.mode}, want {want}")
|
||||
|
||||
def export(self, to_directory: PathLike):
|
||||
def export(self, to_directory: PathLike, skip_preserve_owner=False):
|
||||
"""Copy object into an external directory"""
|
||||
subprocess.run(
|
||||
[
|
||||
"cp",
|
||||
"--reflink=auto",
|
||||
"-a",
|
||||
os.fspath(self.tree) + "/.",
|
||||
os.fspath(to_directory),
|
||||
],
|
||||
check=True,
|
||||
)
|
||||
cp_cmd = [
|
||||
"cp",
|
||||
"--reflink=auto",
|
||||
"-a",
|
||||
]
|
||||
if skip_preserve_owner:
|
||||
cp_cmd += ["--no-preserve=ownership"]
|
||||
cp_cmd += [
|
||||
os.fspath(self.tree) + "/.",
|
||||
os.fspath(to_directory),
|
||||
]
|
||||
subprocess.run(cp_cmd, check=True)
|
||||
|
||||
def __fspath__(self):
|
||||
return self.tree
|
||||
|
|
|
|||
|
|
@ -320,3 +320,32 @@ def test_store_server(tmp_path):
|
|||
|
||||
with pytest.raises(RuntimeError):
|
||||
_ = client.read_tree_at("42", tmp_path, "/nonexistent")
|
||||
|
||||
|
||||
@pytest.mark.skipif(os.getuid() != 0, reason="needs root")
|
||||
def test_object_export_preserves_ownership_by_default(tmp_path, object_store):
|
||||
tree = object_store.new("a")
|
||||
p = Path(tree, "A")
|
||||
p.touch()
|
||||
os.chown(os.fspath(p), 1000, 1000)
|
||||
tree.export(tmp_path)
|
||||
|
||||
expected_exported_path = Path(tmp_path, "A")
|
||||
assert expected_exported_path.exists()
|
||||
assert expected_exported_path.stat().st_uid == 1000
|
||||
assert expected_exported_path.stat().st_gid == 1000
|
||||
|
||||
|
||||
@pytest.mark.skipif(os.getuid() != 0, reason="needs root")
|
||||
def test_object_export_preserves_override(tmp_path, object_store):
|
||||
tree = object_store.new("a")
|
||||
p = Path(tree, "A")
|
||||
p.touch()
|
||||
os.chown(os.fspath(p), 1000, 1000)
|
||||
tree.export(tmp_path, skip_preserve_owner=True)
|
||||
|
||||
expected_exported_path = Path(tmp_path, "A")
|
||||
assert expected_exported_path.exists()
|
||||
assert expected_exported_path.stat().st_uid == 0
|
||||
assert expected_exported_path.stat().st_gid == 0
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue