Implement PORTAGE_BINHOST ssh:// protocol support by spawning ssh
authorZac Medico <zmedico@gentoo.org>
Sat, 25 Sep 2010 15:53:20 +0000 (08:53 -0700)
committerZac Medico <zmedico@gentoo.org>
Sat, 25 Sep 2010 15:53:20 +0000 (08:53 -0700)
and using it to stream the Packages file on stdout.

This assumes that you have ssh-agent running, for authentication.
For now, you won't be able to use this unless you define your own
FETCHCOMMAND_SSH and RESUMECOMMAND_SSH values. It's trivial to do
this if you create a helper script that calls rsync after
transforming the URI into the host:/path format that rsync uses.

pym/portage/dbapi/bintree.py

index d8c40d4efca09c4989a933d7e786754f3d79f08c..f2a7cded9e7e31725c653f0c6c4f78e3921d4d9e 100644 (file)
@@ -36,6 +36,7 @@ import codecs
 import errno
 import re
 import stat
+import subprocess
 import sys
 import textwrap
 from itertools import chain
@@ -756,11 +757,22 @@ class binarytree(object):
                                        raise
                        local_timestamp = pkgindex.header.get("TIMESTAMP", None)
                        rmt_idx = self._new_pkgindex()
+                       parsed_url = urlparse(base_url)
+                       proc = None
                        try:
                                # urlparse.urljoin() only works correctly with recognized
                                # protocols and requires the base url to have a trailing
                                # slash, so join manually...
-                               f = urllib_request_urlopen(base_url.rstrip("/") + "/Packages")
+                               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
+
                                f_dec = codecs.iterdecode(f,
                                        _encodings['repo.content'], errors='replace')
                                try:
@@ -786,6 +798,11 @@ class binarytree(object):
                                writemsg("!!! %s\n\n" % str(e))
                                del e
                                pkgindex = None
+                       if proc is not None:
+                               if proc.poll() is None:
+                                       proc.kill()
+                                       proc.wait()
+                               proc = None
                        if pkgindex is rmt_idx:
                                pkgindex.modified = False # don't update the header
                                try: