Skip to content

Commit efc31e0

Browse files
parthaaggainey
authored andcommitted
Fs exporter correctly handles hardlink
Fixed the fs exporter to handle the case where hardlink method was requested but pulp and export locations are in different partitions so can't share the same inode. Explicitly checks if its on a diff share/partition Also checks if FileExists for Symlinks to avoid FileExistsError fixes #1949 fixes #3187 Co-authored-by: Grant Gainey <ggainey@users.noreply.github.com> (cherry picked from commit b03d0ff)
1 parent 10663c4 commit efc31e0

File tree

3 files changed

+14
-0
lines changed

3 files changed

+14
-0
lines changed

CHANGES/1949.bugfix

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Fixed the fs exporter to handle the case where there are pre-existing files in the location that FileSystem attempts to export to you get a FileExistsError.

CHANGES/3187.bugfix

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Fixed the fs exporter to handle the case where hardlink method was requested but pulp and export locations are in different partitions so can't share the same inode.

pulpcore/app/tasks/export.py

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
import json
33
import logging
44
import os
5+
import os.path
56
import subprocess
67
import tarfile
78

@@ -66,16 +67,27 @@ def _export_to_file_system(path, relative_paths_to_artifacts, method=FS_EXPORT_M
6667
and method != FS_EXPORT_METHODS.WRITE
6768
):
6869
raise RuntimeError(_("Only write is supported for non-filesystem storage."))
70+
os.makedirs(path)
71+
export_not_on_same_filesystem = (
72+
settings.DEFAULT_FILE_STORAGE == "pulpcore.app.models.storage.FileSystem"
73+
and os.stat(settings.MEDIA_ROOT).st_dev != os.stat(path).st_dev
74+
)
75+
76+
if method == FS_EXPORT_METHODS.HARDLINK and export_not_on_same_filesystem:
77+
log.info(_("Hard link cannot be created, file will be copied."))
78+
method = FS_EXPORT_METHODS.WRITE
6979

7080
for relative_path, artifact in relative_paths_to_artifacts.items():
7181
dest = os.path.join(path, relative_path)
7282
os.makedirs(os.path.split(dest)[0], exist_ok=True)
7383

7484
if method == FS_EXPORT_METHODS.SYMLINK:
7585
src = os.path.join(settings.MEDIA_ROOT, artifact.file.name)
86+
os.path.lexists(dest) and os.unlink(dest)
7687
os.symlink(src, dest)
7788
elif method == FS_EXPORT_METHODS.HARDLINK:
7889
src = os.path.join(settings.MEDIA_ROOT, artifact.file.name)
90+
os.path.lexists(dest) and os.unlink(dest)
7991
os.link(src, dest)
8092
elif method == FS_EXPORT_METHODS.WRITE:
8193
with open(dest, "wb") as f, artifact.file as af:

0 commit comments

Comments
 (0)