diff --git a/mlflow/projects/docker.py b/mlflow/projects/docker.py index 19411a106f9fc..43e0a6e8254c9 100644 --- a/mlflow/projects/docker.py +++ b/mlflow/projects/docker.py @@ -99,6 +99,25 @@ def _get_docker_image_uri(repository_uri, work_dir): return repository_uri + version_string +def onerror(func, path, exc_info): + """ + Error handler for ``shutil.rmtree``. + + If the error is due to an access error (read only file) + it attempts to add write permission and then retries. + + If the error is for another reason it re-raises the error. + + Usage : ``shutil.rmtree(path, onerror=onerror)`` + """ + import stat + if not os.access(path, os.W_OK): + # Is the error an access error ? + os.chmod(path, stat.S_IWUSR) + func(path) + else: + raise + def _create_docker_build_ctx(work_dir, dockerfile_contents): """ Creates build context tarfile containing Dockerfile and project code, returning path to tarfile @@ -114,7 +133,7 @@ def _create_docker_build_ctx(work_dir, dockerfile_contents): output_filename=result_path, source_dir=dst_path, archive_name=_PROJECT_TAR_ARCHIVE_NAME ) finally: - shutil.rmtree(directory) + shutil.rmtree(directory, onerror=onerror) return result_path