Skip to content

Commit 678bc53

Browse files
praiskupxsuchy
authored andcommitted
Fix certificate copying
The problem with default shutil.copytree() is that it doesn't "update" existing directories. So I was wrong in adf58f0, we can't pre-create the dest-directory. More, the certificate directory is being updated over and over with subsequent calls, and we want to keep updating the dest directory. For this to work correctly, we need to use 'shutil.copytree(dirs_exist_ok=True)' which is though not in Python 3.6. Therefore we try the 'shutil.copytree' first (works for Python standard library 3.7+), and we fallback to the deprecated 'distutils' copy_tree() method to stay compatible with Python 3.6. Partly-reverts: adf58f0 Fixes: #1094
1 parent 875a732 commit 678bc53

File tree

2 files changed

+29
-2
lines changed

2 files changed

+29
-2
lines changed

mock/py/mockbuild/file_util.py

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,10 +3,21 @@
33
import errno
44
import os
55
import os.path
6+
import shutil
67
import stat
78
import subprocess
89
import time
910

11+
# TODO: Remove with copy_or_update_tree() removal
12+
try:
13+
deprecated_copy_tree = None
14+
deprecated_copy_tree_error = None
15+
# pylint: disable=deprecated-module
16+
from distutils.dir_util import copy_tree as deprecated_copy_tree # type: ignore
17+
from distutils.errors import DistutilsFileError as deprecated_copy_tree_error # type: ignore
18+
except ImportError:
19+
pass
20+
1021
from . import exception
1122
from .trace_decorator import getLog, traceLog
1223

@@ -114,3 +125,20 @@ def find_non_nfs_dir():
114125
if not get_fs_type(d).startswith('nfs'):
115126
return d
116127
raise exception.Error('Cannot find non-NFS directory in: %s' % dirs)
128+
129+
130+
def copy_or_update_tree(src, dest):
131+
"""
132+
Copy directory src into the dest directory. This method won't be needed
133+
when we stop supporting Python 3.6 (RHEL 8) where shutil.copytree doesn't
134+
support the dirs_exist_ok= option.
135+
"""
136+
try:
137+
shutil.copytree(src, dest, dirs_exist_ok=True)
138+
except TypeError: # no dirs_exist_ok= support!
139+
try:
140+
# RHEL 8 only
141+
deprecated_copy_tree(src, dest)
142+
except deprecated_copy_tree_error as err:
143+
# Caller(s) expect us to raise OSError.
144+
raise OSError("Can't copy using distutils's copy_tree()") from err

mock/py/mockbuild/package_manager.py

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -341,9 +341,8 @@ def copy_certs(self):
341341
cert_paths = ["/etc/pki/ca-trust", "/usr/share/pki/ca-trust-source"]
342342
for cert_path in cert_paths:
343343
pki_dir = self.buildroot.make_chroot_path(cert_path)
344-
file_util.mkdirIfAbsent(pki_dir)
345344
try:
346-
shutil.copytree(cert_path, pki_dir)
345+
file_util.copy_or_update_tree(cert_path, pki_dir)
347346
except OSError as err:
348347
warning = "Couldn't copy %s certs from host: %s"
349348
self.buildroot.root_log.debug(warning, cert_path, str(err))

0 commit comments

Comments
 (0)