Skip to content

Commit 799ff53

Browse files
committed
fix: local mode deletion of temp files
1 parent fd7a335 commit 799ff53

File tree

2 files changed

+35
-1
lines changed

2 files changed

+35
-1
lines changed

src/sagemaker/local/utils.py

+17-1
Original file line numberDiff line numberDiff line change
@@ -14,14 +14,18 @@
1414
from __future__ import absolute_import
1515

1616
import os
17+
import logging
1718
import shutil
1819
import subprocess
20+
import errno
1921

2022
from distutils.dir_util import copy_tree
2123
from six.moves.urllib.parse import urlparse
2224

2325
from sagemaker import s3
2426

27+
logger = logging.getLogger(__name__)
28+
2529

2630
def copy_directory_structure(destination_directory, relative_path):
2731
"""Creates intermediate directory structure for relative_path.
@@ -75,7 +79,19 @@ def move_to_destination(source, destination, job_name, sagemaker_session):
7579
else:
7680
raise ValueError("Invalid destination URI, must be s3:// or file://, got: %s" % destination)
7781

78-
shutil.rmtree(source)
82+
try:
83+
shutil.rmtree(source)
84+
except OSError as exc:
85+
# on Linux, when docker writes to any mounted volume, it uses the container's user. In most
86+
# cases this is root. When the container exits and we try to delete them we can't because
87+
# root owns those files. We expect this to happen, so we handle EACCESS. Any other error
88+
# we will raise the exception up.
89+
if exc.errno == errno.EACCES:
90+
logger.warning("Failed to delete: %s Please remove it manually.", source)
91+
else:
92+
logger.error("Failed to delete: %s", source)
93+
raise
94+
7995
return final_uri
8096

8197

tests/unit/test_local_utils.py

+18
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
from __future__ import absolute_import
1414

1515
import os
16+
import errno
1617
import pytest
1718
from mock import patch, Mock
1819

@@ -92,3 +93,20 @@ def test_get_child_process_ids(m_subprocess):
9293
m_subprocess.Popen.return_value = process_mock
9394
sagemaker.local.utils.get_child_process_ids("pid")
9495
m_subprocess.Popen.assert_called_with(cmd, stdout=m_subprocess.PIPE, stderr=m_subprocess.PIPE)
96+
97+
98+
def raise_os_error(args):
99+
err = OSError()
100+
err.errno = errno.EACCES
101+
raise err
102+
103+
104+
@patch("shutil.rmtree", side_effect=raise_os_error)
105+
@patch("sagemaker.local.utils.recursive_copy")
106+
def test_move_to_destination_local_root_failure(recursive_copy, mock_rmtree):
107+
# This should not raise, in case root owns files, make sure it doesn't
108+
sagemaker.local.utils.move_to_destination("/tmp/data", "file:///target/dir/", "job", None)
109+
mock_rmtree.assert_called_once()
110+
recursive_copy.assert_called_with(
111+
"/tmp/data", os.path.abspath(os.path.join(os.sep, "target", "dir"))
112+
)

0 commit comments

Comments
 (0)