From a0c2fa6dd742a273d328238604594a78107581db Mon Sep 17 00:00:00 2001 From: Zac Medico Date: Sat, 25 Sep 2010 18:31:38 -0700 Subject: [PATCH] Add PORTAGE_BINHOST sftp protocol support. --- cnf/make.globals | 2 ++ pym/portage/dbapi/bintree.py | 29 ++++++++++++++++++++---- pym/portage/tests/util/test_getconfig.py | 1 + 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}' } -- 2.26.2