367
367
cur_coalesced = cur_coalesced_stack.next()
369
def put(self, relpath, f, mode=None):
369
def put_file(self, relpath, f, mode=None):
371
Copy the file-like or string object into the location.
371
Copy the file-like object into the location.
373
373
:param relpath: Location to put the contents, relative to base.
374
:param f: File-like or string object.
374
:param f: File-like object.
375
375
:param mode: The final mode for the file
377
377
final_path = self._remote_path(relpath)
389
389
self._pump(f, fout)
390
390
except (IOError, paramiko.SSHException), e:
391
391
self._translate_io_exception(e, tmp_abspath)
392
# XXX: This doesn't truly help like we would like it to.
393
# The problem is that openssh strips sticky bits. So while we
394
# can properly set group write permission, we lose the group
395
# sticky bit. So it is probably best to stop chmodding, and
396
# just tell users that they need to set the umask correctly.
397
# The attr.st_mode = mode, in _sftp_open_exclusive
398
# will handle when the user wants the final mode to be more
399
# restrictive. And then we avoid a round trip. Unless
400
# paramiko decides to expose an async chmod()
402
# This is designed to chmod() right before we close.
403
# Because we set_pipelined() earlier, theoretically we might
404
# avoid the round trip for fout.close()
392
405
if mode is not None:
393
406
self._sftp.chmod(tmp_abspath, mode)
412
425
# raise the original with its traceback if we can.
428
def _put_non_atomic_helper(self, relpath, writer, mode=None,
429
create_parent_dir=False,
431
abspath = self._remote_path(relpath)
433
# TODO: jam 20060816 paramiko doesn't publicly expose a way to
434
# set the file mode at create time. If it does, use it.
435
# But for now, we just chmod later anyway.
437
def _open_and_write_file():
438
"""Try to open the target file, raise error on failure"""
442
fout = self._sftp.file(abspath, mode='wb')
443
fout.set_pipelined(True)
445
except (paramiko.SSHException, IOError), e:
446
self._translate_io_exception(e, abspath,
449
# This is designed to chmod() right before we close.
450
# Because we set_pipelined() earlier, theoretically we might
451
# avoid the round trip for fout.close()
453
self._sftp.chmod(abspath, mode)
458
if not create_parent_dir:
459
_open_and_write_file()
462
# Try error handling to create the parent directory if we need to
464
_open_and_write_file()
466
# Try to create the parent directory, and then go back to
468
parent_dir = os.path.dirname(abspath)
469
self._mkdir(parent_dir, dir_mode)
470
_open_and_write_file()
472
def put_file_non_atomic(self, relpath, f, mode=None,
473
create_parent_dir=False,
475
"""Copy the file-like object into the target location.
477
This function is not strictly safe to use. It is only meant to
478
be used when you already know that the target does not exist.
479
It is not safe, because it will open and truncate the remote
480
file. So there may be a time when the file has invalid contents.
482
:param relpath: The remote location to put the contents.
483
:param f: File-like object.
484
:param mode: Possible access permissions for new file.
485
None means do not set remote permissions.
486
:param create_parent_dir: If we cannot create the target file because
487
the parent directory does not exist, go ahead and
488
create it, and then try again.
492
self._put_non_atomic_helper(relpath, writer, mode=mode,
493
create_parent_dir=create_parent_dir,
496
def put_bytes_non_atomic(self, relpath, bytes, mode=None,
497
create_parent_dir=False,
501
self._put_non_atomic_helper(relpath, writer, mode=mode,
502
create_parent_dir=create_parent_dir,
415
505
def iter_files_recursive(self):
416
506
"""Walk the relative paths of all files in this transport."""
417
507
queue = list(self.list_dir('.'))
517
def _mkdir(self, abspath, mode=None):
523
self._sftp.mkdir(abspath, local_mode)
525
self._sftp.chmod(abspath, mode=mode)
526
except (paramiko.SSHException, IOError), e:
527
self._translate_io_exception(e, abspath, ': unable to mkdir',
528
failure_exc=FileExists)
427
530
def mkdir(self, relpath, mode=None):
428
531
"""Create a directory at the given path."""
429
path = self._remote_path(relpath)
431
# In the paramiko documentation, it says that passing a mode flag
432
# will filtered against the server umask.
433
# StubSFTPServer does not do this, which would be nice, because it is
434
# what we really want :)
435
# However, real servers do use umask, so we really should do it that way
436
self._sftp.mkdir(path)
438
self._sftp.chmod(path, mode=mode)
439
except (paramiko.SSHException, IOError), e:
440
self._translate_io_exception(e, path, ': unable to mkdir',
441
failure_exc=FileExists)
532
self._mkdir(self._remote_path(relpath), mode=mode)
443
534
def _translate_io_exception(self, e, path, more_info='',
444
535
failure_exc=PathError):
457
548
# paramiko seems to generate detailless errors.
458
549
self._translate_error(e, path, raise_generic=False)
459
if hasattr(e, 'args'):
550
if getattr(e, 'args', None) is not None:
460
551
if (e.args == ('No such file or directory',) or
461
552
e.args == ('No such file',)):
462
553
raise NoSuchFile(path, str(e) + more_info)
466
557
if (e.args == ('Failure',)):
467
558
raise failure_exc(path, str(e) + more_info)
468
559
mutter('Raising exception with args %s', e.args)
469
if hasattr(e, 'errno'):
560
if getattr(e, 'errno', None) is not None:
470
561
mutter('Raising exception with errno %s', e.errno)
473
def append(self, relpath, f, mode=None):
564
def append_file(self, relpath, f, mode=None):
475
566
Append the text in the file-like object into the final
641
732
:param abspath: The remote absolute path where the file should be opened
642
733
:param mode: The mode permissions bits for the new file
735
# TODO: jam 20060816 Paramiko >= 1.6.2 (probably earlier) supports
736
# using the 'x' flag to indicate SFTP_FLAG_EXCL.
737
# However, there is no way to set the permission mode at open
738
# time using the sftp_client.file() functionality.
644
739
path = self._sftp._adjust_cwd(abspath)
645
740
# mutter('sftp abspath %s => %s', abspath, path)
646
741
attr = SFTPAttributes()