feat: execute durable archive transfers
This commit is contained in:
@@ -387,6 +387,50 @@ def materialize_transfer(
|
||||
return result_manifest
|
||||
|
||||
|
||||
def cleanup_transfer(job_directory: Path) -> bool:
|
||||
"""Remove only manifest-declared files and known job metadata."""
|
||||
|
||||
try:
|
||||
published = load_published_transfer(job_directory)
|
||||
except FileNotFoundError:
|
||||
return False
|
||||
paths = [
|
||||
job_directory / _relative_path(entry.payload_relative_path)
|
||||
for entry in published.manifest.files
|
||||
]
|
||||
paths.extend(
|
||||
job_directory / _relative_path(artifact.payload_relative_path)
|
||||
for artifact in published.manifest.artifacts
|
||||
)
|
||||
paths.extend((published.ready_path, published.manifest_path))
|
||||
directories: set[Path] = set()
|
||||
for path in paths:
|
||||
try:
|
||||
metadata = path.lstat()
|
||||
except FileNotFoundError:
|
||||
continue
|
||||
if not stat.S_ISREG(metadata.st_mode):
|
||||
raise TransferIntegrityError(
|
||||
"job-owned cleanup path is not a regular file"
|
||||
)
|
||||
path.unlink()
|
||||
parent = path.parent
|
||||
while parent != job_directory.parent:
|
||||
directories.add(parent)
|
||||
if parent == job_directory:
|
||||
break
|
||||
parent = parent.parent
|
||||
for directory in sorted(
|
||||
directories, key=lambda item: len(item.parts), reverse=True
|
||||
):
|
||||
try:
|
||||
directory.rmdir()
|
||||
except OSError as exc:
|
||||
if exc.errno not in {errno.ENOTEMPTY, errno.ENOENT}:
|
||||
raise
|
||||
return True
|
||||
|
||||
|
||||
def canonical_message_json(message: object) -> bytes:
|
||||
value = json_format.MessageToDict(
|
||||
message,
|
||||
|
||||
Reference in New Issue
Block a user