summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--cnf/make.globals2
-rw-r--r--pym/portage/dbapi/bintree.py29
-rw-r--r--pym/portage/tests/util/test_getconfig.py1
3 files changed, 27 insertions, 5 deletions
diff --git a/cnf/make.globals b/cnf/make.globals
index d14d0519e..9ba10444b 100644
--- a/cnf/make.globals
+++ b/cnf/make.globals
@@ -46,6 +46,8 @@ RESUMECOMMAND_RSYNC="rsync -avP \"\${URI}\" \"\${DISTDIR}/\${FILE}\""
FETCHCOMMAND_SSH="bash -c \"x=\\\${2#ssh://} ; exec rsync -avP \\\"\\\${x%%/*}:/\\\${x#*/}\\\" \\\"\\\$1\\\"\" rsync \"\${DISTDIR}/\${FILE}\" \"\${URI}\""
RESUMECOMMAND_SSH=${FETCHCOMMAND_SSH}
+FETCHCOMMAND_SFTP="bash -c \"x=\\\${2#sftp://} ; exec sftp \\\"\\\${x%%/*}:/\\\${x#*/}\\\" \\\"\\\$1\\\"\" sftp \"\${DISTDIR}/\${FILE}\" \"\${URI}\""
+
# Default user options
FEATURES="assume-digests binpkg-logs distlocks fixpackages
fixlafiles news parallel-fetch protect-owned
diff --git a/pym/portage/dbapi/bintree.py b/pym/portage/dbapi/bintree.py
index f2a7cded9..aec89e016 100644
--- a/pym/portage/dbapi/bintree.py
+++ b/pym/portage/dbapi/bintree.py
@@ -38,6 +38,7 @@ import re
import stat
import subprocess
import sys
+import tempfile
import textwrap
from itertools import chain
try:
@@ -759,6 +760,7 @@ class binarytree(object):
rmt_idx = self._new_pkgindex()
parsed_url = urlparse(base_url)
proc = None
+ tmp_filename = None
try:
# urlparse.urljoin() only works correctly with recognized
# protocols and requires the base url to have a trailing
@@ -766,12 +768,24 @@ class binarytree(object):
try:
f = urllib_request_urlopen(base_url.rstrip("/") + "/Packages")
except IOError:
- if parsed_url.scheme != 'ssh':
- raise
path = parsed_url.path.rstrip("/") + "/Packages"
- proc = subprocess.Popen(['ssh', parsed_url.netloc, '--',
- 'cat', path], stdout=subprocess.PIPE)
- f = proc.stdout
+ if parsed_url.scheme == 'sftp':
+ # The sftp command complains about 'Illegal seek' if
+ # we try to make it write to /dev/stdout, so use a
+ # temp file instead.
+ fd, tmp_filename = tempfile.mkstemp()
+ os.close(fd)
+ proc = subprocess.Popen(['sftp',
+ parsed_url.netloc + ":" + path, tmp_filename])
+ if proc.wait() != os.EX_OK:
+ raise
+ f = open(tmp_filename, 'rb')
+ elif parsed_url.scheme == 'ssh':
+ proc = subprocess.Popen(['ssh', parsed_url.netloc, '--',
+ 'cat', path], stdout=subprocess.PIPE)
+ f = proc.stdout
+ else:
+ raise
f_dec = codecs.iterdecode(f,
_encodings['repo.content'], errors='replace')
@@ -803,6 +817,11 @@ class binarytree(object):
proc.kill()
proc.wait()
proc = None
+ if tmp_filename is not None:
+ try:
+ os.unlink(tmp_filename)
+ except OSError:
+ pass
if pkgindex is rmt_idx:
pkgindex.modified = False # don't update the header
try:
diff --git a/pym/portage/tests/util/test_getconfig.py b/pym/portage/tests/util/test_getconfig.py
index 5584db41e..b1d3e25cf 100644
--- a/pym/portage/tests/util/test_getconfig.py
+++ b/pym/portage/tests/util/test_getconfig.py
@@ -15,6 +15,7 @@ class GetConfigTestCase(TestCase):
_cases = {
'FETCHCOMMAND' : '/usr/bin/wget -t 5 -T 60 --passive-ftp -O "${DISTDIR}/${FILE}" "${URI}"',
'FETCHCOMMAND_RSYNC' : 'rsync -avP "${URI}" "${DISTDIR}/${FILE}"',
+ 'FETCHCOMMAND_SFTP' : 'bash -c "x=\\${2#sftp://} ; exec sftp \\"\\${x%%/*}:/\\${x#*/}\\" \\"\\$1\\"" sftp "${DISTDIR}/${FILE}" "${URI}"',
'FETCHCOMMAND_SSH' : 'bash -c "x=\\${2#ssh://} ; exec rsync -avP \\"\\${x%%/*}:/\\${x#*/}\\" \\"\\$1\\"" rsync "${DISTDIR}/${FILE}" "${URI}"',
'PORTAGE_ELOG_MAILSUBJECT' : '[portage] ebuild log for ${PACKAGE} on ${HOST}'
}