Skip to content

Commit

Permalink
Notify user when broken symlinks are encountered
Browse files Browse the repository at this point in the history
You will now see an error message shown as well as a non zero
RC:

  $ aws s3 sync anotherdir/ s3://jamesls-test-sync/
  [Errno 2] No such file or directory: '/private/tmp/symlnk/anotherdir/z-badsylmink'

  $ echo $?
  1

There is potential to add something like a ``--skip-bad-symlinks``
option, but the default behavior is to let the user know that we've hit
a bad symlink.  Fies #425 and #487.
  • Loading branch information
jamesls authored and EronHennessey committed Dec 20, 2013
1 parent cfc5ddb commit 3401072
Show file tree
Hide file tree
Showing 4 changed files with 27 additions and 4 deletions.
3 changes: 3 additions & 0 deletions CHANGELOG.rst
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,9 @@ Next Release (TBD)
is provided (`issue 501 <https://github.com/aws/aws-cli/issues/501>`__)
* Don't require key names for structures of single scalar values
(`issue 484 <https://github.com/aws/aws-cli/issues/484>`__)
* Fix issue with symlinks silently failing during ``s3 sync/cp``
(`issue 425 <https://github.com/aws/aws-cli/issues/425>`__
and `issue 487 <https://github.com/aws/aws-cli/issues/487>`__)


1.2.5
Expand Down
4 changes: 4 additions & 0 deletions awscli/customizations/s3/executer.py
Original file line number Diff line number Diff line change
Expand Up @@ -144,6 +144,7 @@ def __init__(self, result_queue, done, quiet, interrupt, timeout):
self._num_parts = 0
self._file_count = 0
self._lock = threading.Lock()
self._needs_newline = False

self._total_parts = 0
self._total_files = '...'
Expand Down Expand Up @@ -179,6 +180,8 @@ def run(self):
except Queue.Empty:
pass
if self._done.isSet():
if self._needs_newline:
sys.stdout.write('\n')
break

def _process_print_task(self, print_task):
Expand Down Expand Up @@ -226,4 +229,5 @@ def _process_print_task(self, print_task):
final_str += prog_str
if not self._quiet:
uni_print(final_str)
self._needs_newline = not final_str.endswith('\n')
sys.stdout.flush()
7 changes: 3 additions & 4 deletions awscli/customizations/s3/s3handler.py
Original file line number Diff line number Diff line change
Expand Up @@ -80,10 +80,9 @@ def call(self, files):
self.result_queue.join()

except Exception as e:
LOGGER.error('Exception caught during task execution: %s',
str(e))
# Log the traceback at DEBUG level.
LOGGER.debug(str(e), exc_info=True)
LOGGER.debug('Exception caught during task execution: %s',
str(e), exc_info=True)
self.result_queue.put({'message': str(e), 'error': True})
except KeyboardInterrupt:
self.interrupt.set()
self.result_queue.put({'message': "Cleaning up. Please wait...",
Expand Down
17 changes: 17 additions & 0 deletions tests/integration/customizations/s3/test_plugin.py
Original file line number Diff line number Diff line change
Expand Up @@ -362,6 +362,23 @@ def test_sync_with_delete_option_with_same_prefix(self):
self.assertEqual('', p.stdout)


class TestBadSymlinks(BaseS3CLICommand):
def test_bad_symlink_stops_sync_process(self):
bucket_name = self.create_bucket()
nested_dir = os.path.join(self.files.rootdir, 'realfiles')
os.mkdir(nested_dir)
full_path = self.files.create_file(os.path.join(nested_dir, 'foo.txt'),
contents='foo.txt contents')
symlink_dir = os.path.join(self.files.rootdir, 'symlinkdir')
os.mkdir(symlink_dir)
os.symlink(full_path, os.path.join(symlink_dir, 'a-goodsymlink'))
os.symlink('non-existent-file', os.path.join(symlink_dir, 'b-badsymlink'))
os.symlink(full_path, os.path.join(symlink_dir, 'c-goodsymlink'))
p = aws('s3 sync %s s3://%s/' % (symlink_dir, bucket_name))
self.assertEqual(p.rc, 1, p.stdout)
self.assertIn('[Errno 2] No such file or directory', p.stdout)


class TestUnicode(BaseS3CLICommand):
"""
The purpose of these tests are to ensure that the commands can handle
Expand Down

0 comments on commit 3401072

Please sign in to comment.