diff options
author | Rob Austein <sra@hactrn.net> | 2012-03-01 03:16:34 +0000 |
---|---|---|
committer | Rob Austein <sra@hactrn.net> | 2012-03-01 03:16:34 +0000 |
commit | 209270fdb7641c3e28b47a144bdb2d785ab30a9c (patch) | |
tree | 62089f57f0fa920a23c211c01c07eb56ecdcd3e7 /rcynic | |
parent | 7609726054549996b49c13102080b6fae110751e (diff) |
Work around atomic-rename problem using OpenSSH-specific extension.
svn path=/trunk/; revision=4381
Diffstat (limited to 'rcynic')
-rw-r--r-- | rcynic/rpki-torrent.py | 35 |
1 files changed, 14 insertions, 21 deletions
diff --git a/rcynic/rpki-torrent.py b/rcynic/rpki-torrent.py index 0e52622f..9c2057d3 100644 --- a/rcynic/rpki-torrent.py +++ b/rcynic/rpki-torrent.py @@ -102,6 +102,18 @@ def main(): def generator_main(): import paramiko + class SFTPClient(paramiko.SFTPClient): + """ + Subclass paramiko's SFTPClient class to add support for OpenSSH's + atomic-rename extension. + """ + + def atomic_rename(self, oldpath, newpath): + oldpath = self._adjust_cwd(oldpath) + newpath = self._adjust_cwd(newpath) + self._log(paramiko.common.DEBUG, 'atomic_rename(%r, %r)' % (oldpath, newpath)) + self._request(paramiko.sftp.CMD_EXTENDED, "posix-rename@openssh.com", oldpath, newpath) + z = ZipFile(url = cfg.generate_url, dir = cfg.zip_dir) client = TransmissionClient() @@ -146,7 +158,7 @@ def generator_main(): username = cfg.sftp_user, hostkey = paramiko.util.load_host_keys(cfg.sftp_hostkey_file)[cfg.sftp_host]["ssh-rsa"], pkey = paramiko.RSAKey.from_private_key_file(cfg.sftp_private_key_file)) - sftp = paramiko.SFTPClient.from_transport(ssh) + sftp = SFTPClient.from_transport(ssh) zip_filename = os.path.join("data", z.filename) zip_tempname = zip_filename + ".new" @@ -174,26 +186,7 @@ def generator_main(): syslog.syslog("Closing %s and renaming to %s" % (zip_tempname, zip_filename)) z.close() f.close() - - # Feh, atomic rename isn't part of the non-standard, well, it sort - # of is part of the last version of the non-standard before the IETF - # SECSH WG abandoned the specification, but paramiko doesn't support - # it, and my lame attempts to patch it in didn't work, perhaps - # because OpenSSH doesn't really support it either, they have their - # own extension instead. - # - # But we're here to get a job done, so for now just live with a - # brief race condition. Feh. - - zip_oldname = zip_filename + ".old" - - try: - sftp.remove(zip_oldname) - except IOError: - pass - - sftp.rename(zip_filename, zip_oldname) - sftp.rename(zip_tempname, zip_filename) + sftp.atomic_rename(zip_tempname, zip_filename) syslog.syslog("Closing upload connection") sftp.close() |