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 aws#425 and aws#487.
  • Loading branch information
jamesls committed Nov 25, 2013
1 parent 632e2f8 commit afc6e37
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 @@ -12,6 +12,9 @@ Next Release (TBD)
(issue 494 <https://github.com/aws/aws-cli/issues/494>`__)
* Fix issue with ``--associate-public-ip-address`` when a ``--subnet-id``
is provided `(issue 501 <https://github.com/aws/aws-cli/issues/501>`__)
* 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 afc6e37

Please sign in to comment.