Don't copy mode and attrs for existing dirs (e.g. /tmp), closes #6
This commit is contained in:
parent
ba9baa9362
commit
4f33d97386
@ -112,10 +112,10 @@ class ImageBuilder:
|
||||
unpack_http_archive(src, dst)
|
||||
else:
|
||||
src = os.path.join(self.builddir, src)
|
||||
if not os.path.isdir(src):
|
||||
shutil.copy2(src, dst)
|
||||
if os.path.isdir(src):
|
||||
copy_tree(src, dst)
|
||||
else:
|
||||
shutil.copytree(src, dst, symlinks=True, ignore_dangling_symlinks=True, dirs_exist_ok=True)
|
||||
shutil.copy2(src, dst)
|
||||
# Shift UID/GID of the files to the unprivileged range
|
||||
shift_uid(dst, os.stat(dst, follow_symlinks=False))
|
||||
|
||||
@ -141,6 +141,22 @@ def unpack_http_archive(src, dst):
|
||||
with tarfile.open(fileobj=tmp_archive) as tar:
|
||||
tar.extractall(dst, numeric_owner=True)
|
||||
|
||||
def copy_tree(src, dst):
|
||||
# Copy directory tree from host to container, leaving the existing modes and attributed unchanged,
|
||||
# which is crucial e.g. whenever anything is copied into /tmp
|
||||
# This function is a stripped and customized variant of shutil.copytree()
|
||||
for srcentry in os.scandir(src):
|
||||
dstname = os.path.join(dst, srcentry.name)
|
||||
is_new = not os.path.exists(dstname)
|
||||
if srcentry.is_dir():
|
||||
if is_new:
|
||||
os.mkdir(dstname)
|
||||
copy_tree(srcentry, dstname)
|
||||
else:
|
||||
shutil.copy2(srcentry, dstname)
|
||||
if is_new:
|
||||
shutil.copystat(srcentry, dstname, follow_symlinks=False)
|
||||
|
||||
def shift_uid(path, path_stat):
|
||||
# Shifts UID/GID of a file or a directory and its contents to the unprivileged range
|
||||
# The function parameters could arguably be more friendly, but os.scandir() already calls stat() on the entires,
|
||||
|
Loading…
Reference in New Issue
Block a user