385
385
cur_coalesced = cur_coalesced_stack.next()
387
def put(self, relpath, f, mode=None):
387
def put_file(self, relpath, f, mode=None):
389
Copy the file-like or string object into the location.
389
Copy the file-like object into the location.
391
391
:param relpath: Location to put the contents, relative to base.
392
:param f: File-like or string object.
392
:param f: File-like object.
393
393
:param mode: The final mode for the file
395
395
final_path = self._remote_path(relpath)
407
407
self._pump(f, fout)
408
408
except (IOError, paramiko.SSHException), e:
409
409
self._translate_io_exception(e, tmp_abspath)
410
# XXX: This doesn't truly help like we would like it to.
411
# The problem is that openssh strips sticky bits. So while we
412
# can properly set group write permission, we lose the group
413
# sticky bit. So it is probably best to stop chmodding, and
414
# just tell users that they need to set the umask correctly.
415
# The attr.st_mode = mode, in _sftp_open_exclusive
416
# will handle when the user wants the final mode to be more
417
# restrictive. And then we avoid a round trip. Unless
418
# paramiko decides to expose an async chmod()
420
# This is designed to chmod() right before we close.
421
# Because we set_pipelined() earlier, theoretically we might
422
# avoid the round trip for fout.close()
410
423
if mode is not None:
411
424
self._sftp.chmod(tmp_abspath, mode)
430
443
# raise the original with its traceback if we can.
446
def _put_non_atomic_helper(self, relpath, writer, mode=None,
447
create_parent_dir=False,
449
abspath = self._remote_path(relpath)
451
# TODO: jam 20060816 paramiko doesn't publicly expose a way to
452
# set the file mode at create time. If it does, use it.
453
# But for now, we just chmod later anyway.
455
def _open_and_write_file():
456
"""Try to open the target file, raise error on failure"""
460
fout = self._sftp.file(abspath, mode='wb')
461
fout.set_pipelined(True)
463
except (paramiko.SSHException, IOError), e:
464
self._translate_io_exception(e, abspath,
467
# This is designed to chmod() right before we close.
468
# Because we set_pipelined() earlier, theoretically we might
469
# avoid the round trip for fout.close()
471
self._sftp.chmod(abspath, mode)
476
if not create_parent_dir:
477
_open_and_write_file()
480
# Try error handling to create the parent directory if we need to
482
_open_and_write_file()
484
# Try to create the parent directory, and then go back to
486
parent_dir = os.path.dirname(abspath)
487
self._mkdir(parent_dir, dir_mode)
488
_open_and_write_file()
490
def put_file_non_atomic(self, relpath, f, mode=None,
491
create_parent_dir=False,
493
"""Copy the file-like object into the target location.
495
This function is not strictly safe to use. It is only meant to
496
be used when you already know that the target does not exist.
497
It is not safe, because it will open and truncate the remote
498
file. So there may be a time when the file has invalid contents.
500
:param relpath: The remote location to put the contents.
501
:param f: File-like object.
502
:param mode: Possible access permissions for new file.
503
None means do not set remote permissions.
504
:param create_parent_dir: If we cannot create the target file because
505
the parent directory does not exist, go ahead and
506
create it, and then try again.
510
self._put_non_atomic_helper(relpath, writer, mode=mode,
511
create_parent_dir=create_parent_dir,
514
def put_bytes_non_atomic(self, relpath, bytes, mode=None,
515
create_parent_dir=False,
519
self._put_non_atomic_helper(relpath, writer, mode=mode,
520
create_parent_dir=create_parent_dir,
433
523
def iter_files_recursive(self):
434
524
"""Walk the relative paths of all files in this transport."""
435
525
queue = list(self.list_dir('.'))
535
def _mkdir(self, abspath, mode=None):
541
self._sftp.mkdir(abspath, local_mode)
543
self._sftp.chmod(abspath, mode=mode)
544
except (paramiko.SSHException, IOError), e:
545
self._translate_io_exception(e, abspath, ': unable to mkdir',
546
failure_exc=FileExists)
445
548
def mkdir(self, relpath, mode=None):
446
549
"""Create a directory at the given path."""
447
path = self._remote_path(relpath)
449
# In the paramiko documentation, it says that passing a mode flag
450
# will filtered against the server umask.
451
# StubSFTPServer does not do this, which would be nice, because it is
452
# what we really want :)
453
# However, real servers do use umask, so we really should do it that way
454
self._sftp.mkdir(path)
456
self._sftp.chmod(path, mode=mode)
457
except (paramiko.SSHException, IOError), e:
458
self._translate_io_exception(e, path, ': unable to mkdir',
459
failure_exc=FileExists)
550
self._mkdir(self._remote_path(relpath), mode=mode)
461
552
def _translate_io_exception(self, e, path, more_info='',
462
553
failure_exc=PathError):
475
566
# paramiko seems to generate detailless errors.
476
567
self._translate_error(e, path, raise_generic=False)
477
if hasattr(e, 'args'):
568
if getattr(e, 'args', None) is not None:
478
569
if (e.args == ('No such file or directory',) or
479
570
e.args == ('No such file',)):
480
571
raise NoSuchFile(path, str(e) + more_info)
484
575
if (e.args == ('Failure',)):
485
576
raise failure_exc(path, str(e) + more_info)
486
577
mutter('Raising exception with args %s', e.args)
487
if hasattr(e, 'errno'):
578
if getattr(e, 'errno', None) is not None:
488
579
mutter('Raising exception with errno %s', e.errno)
491
def append(self, relpath, f, mode=None):
582
def append_file(self, relpath, f, mode=None):
493
584
Append the text in the file-like object into the final
660
751
:param abspath: The remote absolute path where the file should be opened
661
752
:param mode: The mode permissions bits for the new file
754
# TODO: jam 20060816 Paramiko >= 1.6.2 (probably earlier) supports
755
# using the 'x' flag to indicate SFTP_FLAG_EXCL.
756
# However, there is no way to set the permission mode at open
757
# time using the sftp_client.file() functionality.
663
758
path = self._sftp._adjust_cwd(abspath)
664
759
# mutter('sftp abspath %s => %s', abspath, path)
665
760
attr = SFTPAttributes()