sftp method no longer uses temporary file name during upload
Affects | Status | Importance | Assigned to | Milestone | |
---|---|---|---|---|---|
dput (Ubuntu) |
Fix Released
|
Low
|
Unassigned |
Bug Description
In previous versions of dput, the sftp method would use a temporary file name while uploading. For example:
linux-headers-
In bionic with package version 1.0.1ubuntu1, it no longer does this.
I have a remote script that it triggered by a file system watcher that looks for the creation of a new .changes file. Since the file is created with this line:
with sftp_client.
the initial file is empty and as a result, my script sent me this message from reprepro:
Unexpected empty file 'raspberrypi-
There have been errors!
This script was working with previous versions of dput.
Changed in dput (Ubuntu): | |
importance: | Undecided → Low |
summary: |
- regression: sftp method no longer uses temporary file name during upload + sftp method no longer uses temporary file name during upload |
It looks like this can be fixed by copying (parts of) the _put() method from bzrlib
def _put(self, abspath, f, mode=None):
os.getpid( ), random. randint( 0,0x7FFFFFFF) ) open_exclusive( tmp_abspath, mode=mode)
fout. set_pipelined( True)
length = self._pump(f, fout) SSHException) , e:
self. _translate_ io_exception( e, tmp_abspath) exclusive
"""Helper function so both put() and copy_abspaths can reuse the code"""
tmp_abspath = '%s.tmp.%.9f.%d.%d' % (abspath, time.time(),
fout = self._sftp_
closed = False
try:
try:
except (IOError, paramiko.
# XXX: This doesn't truly help like we would like it to.
# The problem is that openssh strips sticky bits. So while we
# can properly set group write permission, we lose the group
# sticky bit. So it is probably best to stop chmodding, and
# just tell users that they need to set the umask correctly.
# The attr.st_mode = mode, in _sftp_open_
# will handle when the user wants the final mode to be more
# restrictive. And then we avoid a round trip. Unless
# paramiko decides to expose an async chmod()
# This is designed to chmod() right before we close.
self. _get_sftp( ).chmod( tmp_abspath, mode)
fout. close()
self. _rename_ and_overwrite( tmp_abspath, abspath)
mutter( traceback. format_ exc())
fout. close()
self. _get_sftp( ).remove( tmp_abspath)
raise e
# Because we set_pipelined() earlier, theoretically we might
# avoid the round trip for fout.close()
if mode is not None:
closed = True
return length
except Exception, e:
# If we fail, try to clean up the temporary file
# before we throw the exception
# but don't let another exception mess things up
# Write out the traceback, because otherwise
# the catch and throw destroys it
import traceback
try:
if not closed:
except:
# raise the saved except
# raise the original with its traceback if we can.
raise