Exemplo n.º 1
0
class Hostname(namedtuple('Hostname', 'name'), BaseAddress):
    """A single hostname which is (probably) resolvable to an IP address."""
    __slots__ = ()

    def __str__(self):
        return self.name

    def resolve(self):
        from conary.lib import httputils
        results = httputils.IPCache.getMany(self.name)
        return [BaseIPAddress.parse(x) for x in results]

    def match(self, other):
        if isinstance(other, Hostname):
            return self.name.lower() == other.name.lower()
        elif isinstance(other, HostPort):
            return self.match(other.host)
        elif isinstance(other, BaseIPAddress):
            # Check the given IP against each possible resolve result for this
            # hostname.
            for ip in self.resolve():
                if ip.match(other):
                    return True
        return False

    def isPrecise(self):
        return True
Exemplo n.º 2
0
class ResponseArgs(compat.namedtuple('ResponseArgs',
        'isException result excName excArgs excKwargs')):

    @classmethod
    def newResult(cls, result):
        return cls(False, result, None, None, None)

    @classmethod
    def newException(cls, excName, excArgs=(), excKwargs=()):
        return cls(True, None,
                excName, tuple(excArgs), dict(excKwargs))

    def toWire(self, version):
        """Returns a 2-tuple (response, headers)"""
        if self.isException:
            if version < 60:
                assert not self.excKwargs
                result = (self.excName,) + tuple(self.excArgs)
            else:
                result = (self.excName, self.excArgs, self.excKwargs)
        else:
            result = self.result

        headers = {}
        if 60 <= version <= 70:
            # These versions suffer from an incredibly silly mistake where the
            # isException flag got passed through the X-Conary-UsedAnonymous
            # header.
            if self.isException:
                headers['X-Conary-Usedanonymous'] = '1'
            response = (result,)
        else:
            # Versions <= 59 and >= 71 make more sense.
            response = (self.isException, result)
        return response, headers

    @classmethod
    def fromWire(cls, version, response, headers):
        if 60 <= version <= 70:
            # See comment in toWire()
            isException = 'X-Conary-Usedanonymous' in headers
            result, = response
        else:
            isException, result = response

        if isException:
            if version < 60:
                excName = result[0]
                excArgs = result[1:]
                excKwargs = {}
            else:
                excName, excArgs, excKwargs = result
            result = None
        else:
            excName = excArgs = excKwargs = None

        return cls(isException, result, excName, excArgs, excKwargs)
Exemplo n.º 3
0
class FakeStat(
        namedtuple(
            'FakeStat', 'st_mode st_ino st_dev st_nlink st_uid '
            'st_gid st_size st_atime st_mtime st_ctime st_blksize st_blocks '
            'st_rdev linkto')):
    __slots__ = ()

    def __new__(cls, *args, **kwargs):
        out = [None] * len(cls._fields)
        names = set(cls._fields)
        for n, arg in enumerate(args):
            out[n] = arg
            names.remove(cls._fields[n])
        for key, arg in kwargs.items():
            out[cls._fields.index(key)] = arg
            names.remove(key)
        return tuple.__new__(cls, out)
Exemplo n.º 4
0
class HostPort(namedtuple('HostPort', 'host port'), Endpoint):
    """Pair (host, port) where host is an address and port is None or a
    port to match against."""
    __slots__ = ()

    def __new__(cls, host, port=None):
        if isinstance(host, basestring) and port is None:
            host, port = splitHostPort(host, rawPort=True)

        if port == '*':
            port = None
        elif port:
            port = int(port)

        if not isinstance(host, BaseAddress):
            if '*' in host:
                host = HostGlob(host)
            else:
                host = BaseAddress.parse(host)

        return tuple.__new__(cls, (host, port))

    def __str__(self):
        out = str(self.host)
        if ':' in out:
            out = '[%s]' % (out, )
        if self.port is not None:
            out += ':%s' % self.port
        return out

    def match(self, other):
        if self.port is not None:
            if isinstance(other, HostPort):
                if self.port != other.port:
                    # Port mismatch
                    return False
            else:
                # Not a HostPort, so port can't match
                return False
            # Test the host part next
            other = other.host

        return self.host.match(other)

    def isPrecise(self):
        return self.host.isPrecise()
Exemplo n.º 5
0
class NEVRA(namedtuple('NEVRA', 'name epoch version release arch')):
    _re = re.compile("^(.*)-([^-]*)-([^-]*)\.([^.]*)$")

    @classmethod
    def fromHeader(cls, header):
        args = []
        for tag in [NAME, EPOCH, VERSION, RELEASE, ARCH]:
            if tag in header.keys():
                args.append(header[tag])
            else:
                args.append(None)
        return cls(*args)

    @classmethod
    def parse(cls, filename):
        """
        Given an rpm filename like name-version-release.arch.rpm or
        name-epoch:version-release-arch.rpm (or the previous without .rpm), return
        (name, epoch, version, release, arch)
        """
        if filename.endswith('.rpm'):
            filename = filename[:-4]
        m = cls._re.match(filename)
        if not m:
            return None
        n, v, r, a = m.groups()
        if ':' not in v:
            return n, None, v, r, a
        e, v = v.split(':', 1)
        e = int(e)
        return cls(n, e, v, r, a)

    @classmethod
    def filename(cls, name, epoch, version, release, arch):
        if epoch is not None:
            version = "%s:%s" % (epoch, version)
        return "%s-%s-%s.%s.rpm" % (name, version, release, arch)

    def __str__(self):
        if self.epoch:
            epoch = '%s:' % self.epoch
        else:
            epoch = ''
        return '%s-%s%s-%s.%s' % (self.name, epoch, self.version, self.release,
                                  self.arch)
Exemplo n.º 6
0
class URL(namedtuple('URL', 'scheme userpass hostport path')):
    def __new__(cls, scheme, userpass=None, hostport=None, path=None):
        if userpass is None and hostport is None and path is None:
            return cls.parse(scheme)
        else:
            return tuple.__new__(cls, (scheme, userpass, hostport, path))

    @classmethod
    def parse(cls, url, defaultScheme='http'):
        if '://' not in url and defaultScheme:
            url = '%s://%s' % (defaultScheme, url)
        (
            scheme,
            username,
            password,
            host,
            port,
            path,
            query,
            fragment,
        ) = util.urlSplit(url)
        if not port and port != 0:
            if scheme[-1] == 's':
                port = 443
            else:
                port = 80
        hostport = networking.HostPort(host, port)
        path = urlparse.urlunsplit(('', '', path, query, fragment))
        return cls(scheme, (username, password), hostport, path)

    def unsplit(self):
        username, password = self.userpass
        host, port = self.hostport
        if (self.scheme == 'http' and port == 80) or (self.scheme == 'https'
                                                      and port == 443):
            port = None
        return util.urlUnsplit((self.scheme, username, password, str(host),
                                port, self.path, None, None))

    def __str__(self):
        rv = self.unsplit()
        if hasattr(rv, '__safe_str__'):
            rv = rv.__safe_str__()
        return rv
Exemplo n.º 7
0
class RequestArgs(compat.namedtuple('RequestArgs',
        'version args kwargs')):

    def toWire(self):
        if self.version < 51:
            assert not self.kwargs
            return (self.version,) + tuple(self.args)
        else:
            return (self.version, self.args, self.kwargs)

    @classmethod
    def fromWire(cls, argList):
        version = argList[0]
        if version < 51:
            args = argList[1:]
            kwargs = {}
        else:
            args, kwargs = argList[1:]
        return cls(version, tuple(args), dict(kwargs))
Exemplo n.º 8
0
class HostGlob(namedtuple('HostGlob', 'pattern'), BaseAddress):
    """A pattern (shell-style) that matches against hostnames."""
    __slots__ = ()

    def __str__(self):
        return self.pattern

    def match(self, other):
        if isinstance(other, Hostname):
            # Match against the literal hostname.
            return fnmatch.fnmatch(other.name.lower(), self.pattern.lower())
        elif isinstance(other, BaseIPAddress):
            # Match against the formatted IP address.
            if other.mask != other.bits:
                return False
            return fnmatch.fnmatch(other.format(False), self.pattern.lower())
        elif isinstance(other, HostPort):
            # Match against the host part.
            return self.match(other.host)
        return False
def findYumPackagesInLabel(yumrepos, upstreamlabel, downstreamlabel):

    # given a yumrepo object, check if the packages exist upstream or downstream

    NEVRA = namedtuple('NEVRA', 'name epoch version release arch')
    dlabel = versions.Label(downstreamlabel)
    ulabel = versions.Label(upstreamlabel)

    print "DEBUG: matching packages to local troves in label %s " % dlabel
    for trvSpec, nevra in _getNevras(NEVRA, dlabel):

        # ('CSCOsars:rpm', VFS('/celmb1.cisco.com@c:celmb1-trunk-devel/1.0.1_0-1-1'), Flavor('is: x86_64'))
        # trvSpec[0] = 'CSCOsars:rpm'
        # trvSpec[1] = VFS('/celmb1.cisco.com@c:celmb1-trunk-devel/1.0.1_0-1-1')
        # trvSpec[2] = Flavor('is: x86_64')


        for pkg in yumrepos.latestpackages:
            trovespec = ""
            #print "\t%s" % pkg.name

            # Why is nevra.epcoh = None ?

            if ((pkg.name == nevra.name) and
               (pkg.version == nevra.version) and
               (pkg.release == nevra.release) and
               (pkg.arch == nevra.arch)):

               trovespec = str(nevra.name) + "=" + str(trvSpec[1]) + "[" + str(trvSpec[2]) + "]"
               pkg.downstream = True
               pkg.localtrove = trovespec

               print "MATCH: %s %s" %(pkg.url, trovespec)
               #epdb.st()


    print "DEBUG: matching packages to upstream troves in label %s " % ulabel
    for trvSpec, nevra in _getNevras(NEVRA, ulabel):

        # ('CSCOsars:rpm', VFS('/celmb1.cisco.com@c:celmb1-trunk-devel/1.0.1_0-1-1'), Flavor('is: x86_64'))
        # trvSpec[0] = 'CSCOsars:rpm'
        # trvSpec[1] = VFS('/celmb1.cisco.com@c:celmb1-trunk-devel/1.0.1_0-1-1')
        # trvSpec[2] = Flavor('is: x86_64')

        #epdb.st()
        for pkg in yumrepos.latestpackages:
            trovespec = ""
            #print "\t%s" % pkg.name

            # Why is nevra.epcoh = None ?

            if ((pkg.name == nevra.name) and
               (pkg.version == nevra.version) and
               (pkg.release == nevra.release) and
               (pkg.arch == nevra.arch)):

               trovespec = str(nevra.name) + "=" + str(trvSpec[1]) + "[" + str(trvSpec[2]) + "]"
               pkg.upstream = True
               pkg.upstreamtrove = trovespec

               print "MATCH: %s %s" %(pkg.url, trovespec)
               #epdb.st()
    #import epdb; epdb.st()
    return yumrepos
Exemplo n.º 10
0
    def checkLabelsAPI(self, locallabel, upstreamlabel):
        NEVRA = namedtuple('NEVRA', 'name epoch version release arch')
        dlabel = versions.Label(locallabel)
        ulabel = versions.Label(upstreamlabel)

        print "DEBUG: matching packages to local troves"
        for trvSpec, nevra in self._getNevras(NEVRA, dlabel):

            # ('CSCOsars:rpm', VFS('/celmb1.cisco.com@c:celmb1-trunk-devel/1.0.1_0-1-1'), Flavor('is: x86_64'))
            # trvSpec[0] = 'CSCOsars:rpm'
            # trvSpec[1] = VFS('/celmb1.cisco.com@c:celmb1-trunk-devel/1.0.1_0-1-1')
            # trvSpec[2] = Flavor('is: x86_64')

            #print "\t\t%s" % trvSpec
            #print "%s" % nevra.name

            for pkg in self.latestpackages:
                trovespec = ""
                #print "\t%s" % pkg.name

                # Why is nevra.epcoh = None ?

                if ((pkg.name == nevra.name) and (pkg.version == nevra.version)
                        and (pkg.release == nevra.release)
                        and (pkg.arch == nevra.arch)):

                    trovespec = str(nevra.name) + "=" + str(
                        trvSpec[1]) + "[" + str(trvSpec[2]) + "]"
                    pkg.localtrove = trovespec

                    print "MATCH: %s %s" % (pkg.url, trovespec)
                    #epdb.st()

        print "DEBUG: matching packages to upstream troves"
        for trvSpec, nevra in self._getNevras(NEVRA, ulabel):

            # ('CSCOsars:rpm', VFS('/celmb1.cisco.com@c:celmb1-trunk-devel/1.0.1_0-1-1'), Flavor('is: x86_64'))
            # trvSpec[0] = 'CSCOsars:rpm'
            # trvSpec[1] = VFS('/celmb1.cisco.com@c:celmb1-trunk-devel/1.0.1_0-1-1')
            # trvSpec[2] = Flavor('is: x86_64')

            #print "\t\t%s" % trvSpec
            #print "%s" % nevra.name

            #self.latestpackages.sort()

            #epdb.st()
            for pkg in self.latestpackages:
                trovespec = ""
                #print "\t%s" % pkg.name

                # Why is nevra.epcoh = None ?

                if ((pkg.name == nevra.name) and (pkg.version == nevra.version)
                        and (pkg.release == nevra.release)
                        and (pkg.arch == nevra.arch)):

                    trovespec = str(nevra.name) + "=" + str(
                        trvSpec[1]) + "[" + str(trvSpec[2]) + "]"
                    pkg.upstreamtrove = trovespec

                    print "MATCH: %s %s" % (pkg.url, trovespec)
Exemplo n.º 11
0
# See the License for the specific language governing permissions and
# limitations under the License.
#

# NOTE -- this is (currently) a copy of the module in rpath-tools
# at some point in the future this should be moved into a common
# lib.

import urllib2
import urlparse

from lxml import etree as ET

from conary.lib.compat import namedtuple

ApiFinderResult = namedtuple('ApiFinderResult', ['version', 'url'])


class ApiFinder(object):
    '''
    Determines an rBuilder service location in a API version agnostic
    way.   Example: 

    results = ApiFinder('dhcp244.eng.rpath.com').url('inventory')
    results.version
    results.url

    The latest version matching the constraints will always be returned.

    minVersion and maxVersion can be set to exclude using a future
    version or a "too old" version. 
Exemplo n.º 12
0
    _intFormat = '>B'


class ShortStream(_NumericStream):
    _intFormat = '>h'


class IntStream(_NumericStream):
    _intFormat = '>i'


class LongLongStream(_NumericStream):
    _intFormat = '>Q'


_tagInfo = namedtuple('_tagInfo', 'tag sizeType type name')


class StreamSet(_BaseStream):
    streamDict = None
    ignoreUnknown = FAIL_UNKNOWN

    def __init__(self, data=None, offset=0):
        self._unknownTags = []
        for tag in self._getTags():
            setattr(self, tag.name, tag.type())
        if data is not None:
            self.thaw(data[offset:])

    @classmethod
    def _getTags(cls):
Exemplo n.º 13
0
    _intFormat = '>B'


class ShortStream(_NumericStream):
    _intFormat = '>h'


class IntStream(_NumericStream):
    _intFormat = '>i'


class LongLongStream(_NumericStream):
    _intFormat = '>Q'


_tagInfo = namedtuple('_tagInfo', 'tag sizeType type name')


class StreamSet(_BaseStream):
    streamDict = None
    ignoreUnknown = FAIL_UNKNOWN

    def __init__(self, data=None, offset=0):
        self._unknownTags = []
        for tag in self._getTags():
            setattr(self, tag.name, tag.type())
        if data is not None:
            self.thaw(data[offset:])

    @classmethod
    def _getTags(cls):
Exemplo n.º 14
0
class BaseIPAddress(namedtuple('BaseIPAddress', 'address mask'), BaseAddress):
    """Base class for IPv4 and IPv6 addresses."""
    __slots__ = ()

    bits = None
    family = None

    def __new__(cls, address, mask=None):
        if isinstance(address, basestring):
            ret = cls.parse(address)
            if mask is None:
                return ret
            elif 0 <= mask <= cls.bits:
                return ret._replace(mask=mask)
            else:
                raise ValueError("Invalid address mask %d" % mask)
        else:
            if mask is None:
                mask = 128
            elif not (0 <= mask <= cls.bits):
                raise ValueError("Invalid address mask %d" % mask)
            return tuple.__new__(cls, (address, mask))

    def __repr__(self):
        return '%s(%r)' % (type(self).__name__, self.format())

    def __str__(self):
        return self.format()

    @classmethod
    def _parse_direct(cls, val):
        if cls is BaseIPAddress:
            # Called as BaseIPAddress, so try to figure out what it is
            if ':' in val:
                return IPv6Address._parse_direct(val)
            else:
                return IPv4Address._parse_direct(val)

        if '/' in val:
            address, mask = val.split('/')
            mask = int(mask)
            if not (0 <= mask <= cls.bits):
                raise ValueError("Invalid address mask %d" % mask)
        else:
            address, mask = val, cls.bits
        return cls._parse_value(address, mask)

    @classmethod
    def _parse_value(cls, address, mask):
        try:
            addr_bin = socket.inet_pton(cls.family, address)
        except socket.error, err:
            raise ValueError("Invalid IP address %r: %s" %
                             (address, err.args[0]))

        val = 0
        for i in range(0, cls.bits, 32):
            val <<= 32
            val |= struct.unpack('>I', addr_bin[:4])[0]
            addr_bin = addr_bin[4:]

        return cls(val, mask)
Exemplo n.º 15
0
class URL(namedtuple('URL', 'scheme userpass hostport path')):
    def __new__(cls, scheme, userpass=None, hostport=None, path=None):
        if userpass is None and hostport is None and path is None:
            return cls.parse(scheme)
        else:
            return tuple.__new__(cls, (scheme, userpass, hostport, path))

    @classmethod
    def parse(cls, url, defaultScheme='http'):
        if '://' not in url and defaultScheme:
            url = '%s://%s' % (defaultScheme, url)
        (
            scheme,
            username,
            password,
            host,
            port,
            path,
            query,
            fragment,
        ) = util.urlSplit(url)
        if not port and port != 0:
            if scheme[-1] == 's':
                port = 443
            else:
                port = 80
        hostport = networking.HostPort(host, port)
        path = urlparse.urlunsplit(('', '', path, query, fragment))
        return cls(scheme, (username, password), hostport, path)

    def unsplit(self):
        username, password = self.userpass
        host, port = self.hostport
        if port in (80, 443):
            port = None
        return util.urlUnsplit((self.scheme, username, password, str(host),
                                port, self.path, None, None))

    def join(self, suffix):
        """
        Evaluate a possibly relative URL C{suffix} against the current URL and
        return the new absolute URL.
        """
        if '://' in suffix:
            # Fully qualified URL
            return URL.parse(suffix)
        elif suffix.startswith('//'):
            # Relative to scheme
            return URL.parse(self.scheme + ':' + suffix)
        elif suffix.startswith('/'):
            # Relative to host
            return self._replace(path=suffix)
        # Fully relative
        path = self.path or ''
        path = path.split('?')[0]
        path = path.split('/')
        # Strip leading slash(es)
        if path and path[0] == '':
            path.pop(0)
        # Strip trailing basename
        if path and path[-1]:
            path.pop()
        for elem in suffix.split('/'):
            if elem == '..':
                if path:
                    path.pop()
            elif elem == '.':
                pass
            else:
                path.append(elem)
        if not path or path[0] != '':
            path.insert(0, '')
        path = '/'.join(path)
        return self._replace(path=path)

    def __str__(self):
        rv = self.unsplit()
        if hasattr(rv, '__safe_str__'):
            rv = rv.__safe_str__()
        return rv
Exemplo n.º 16
0
# limitations under the License.
#


# NOTE -- this is (currently) a copy of the module in rpath-tools
# at some point in the future this should be moved into a common
# lib.

import urllib2
import urlparse

from lxml import etree as ET

from conary.lib.compat import namedtuple

ApiFinderResult = namedtuple('ApiFinderResult', ['version', 'url'])

class ApiFinder(object):
    '''
    Determines an rBuilder service location in a API version agnostic
    way.   Example: 

    results = ApiFinder('dhcp244.eng.rpath.com').url('inventory')
    results.version
    results.url

    The latest version matching the constraints will always be returned.

    minVersion and maxVersion can be set to exclude using a future
    version or a "too old" version. 
Exemplo n.º 17
0
class MockResponse(namedtuple('MockResponse', 'status reason')):
    msg = read = None
    version = 11

    def getheader(self, name, default=None):
        return None
Exemplo n.º 18
0
        padded = ((rta_len + 3) / 4) * 4
        attrs[rta_type] = rta_data
        data = data[padded:]
    return attrs


## linux/if.h

IFF_UP                  = 0x001
IFF_LOOPBACK            = 0x008


## linux/if_link.h

STRUCT_IFINFOMSG = 'BxHiII'
IfInfoMsg = namedtuple('IfInfoMsg', 'family type index flags change attrs')

(IFLA_UNSPEC, IFLA_ADDRESS, IFLA_BROADCAST, IFLA_IFNAME, IFLA_MTU, IFLA_LINK,
        IFLA_QDISC, IFLA_STATS, IFLA_COST, IFLA_PRIORITY, IFLA_MASTER,
        IFLA_WIRELESS, IFLA_PROTINFO, IFLA_TXQLEN, IFLA_MAP, IFLA_WEIGHT,
        IFLA_OPERSTATE, IFLA_LINKMODE, IFLA_LINKINFO, IFLA_NET_NS_PID,
        IFLA_IFALIAS, IFLA_NUM_VF, IFLA_VFINFO_LIST, IFLA_STATS64,
        IFLA_VF_PORTS, IFLA_PORT_SELF,) = range(26)


def ifinfomsg_unpack(data):
    """Unpack struct ifinfomsg and its attributes."""
    size = struct.calcsize(STRUCT_IFINFOMSG)
    family, type, index, flags, change = struct.unpack(STRUCT_IFINFOMSG,
            data[:size])
    attrs = rtattr_unpack(data[size:])
    def checkLabelsAPI(self, locallabel, upstreamlabel):
        NEVRA = namedtuple('NEVRA', 'name epoch version release arch')
        dlabel = versions.Label(locallabel)
        ulabel = versions.Label(upstreamlabel)
          
        print "DEBUG: matching packages to local troves" 
        for trvSpec, nevra in self._getNevras(NEVRA, dlabel):

            # ('CSCOsars:rpm', VFS('/celmb1.cisco.com@c:celmb1-trunk-devel/1.0.1_0-1-1'), Flavor('is: x86_64'))
            # trvSpec[0] = 'CSCOsars:rpm'
            # trvSpec[1] = VFS('/celmb1.cisco.com@c:celmb1-trunk-devel/1.0.1_0-1-1')
            # trvSpec[2] = Flavor('is: x86_64')

            #print "\t\t%s" % trvSpec 
            #print "%s" % nevra.name 

            for pkg in self.latestpackages:
                trovespec = ""
                #print "\t%s" % pkg.name

                # Why is nevra.epcoh = None ?

                if ((pkg.name == nevra.name) and
                   (pkg.version == nevra.version) and 
                   (pkg.release == nevra.release) and
                   (pkg.arch == nevra.arch)):
                   
                   trovespec = str(nevra.name) + "=" + str(trvSpec[1]) + "[" + str(trvSpec[2]) + "]"  
                   pkg.localtrove = trovespec

                   print "MATCH: %s %s" %(pkg.url, trovespec)
                   #epdb.st()

        print "DEBUG: matching packages to upstream troves" 
        for trvSpec, nevra in self._getNevras(NEVRA, ulabel):

            # ('CSCOsars:rpm', VFS('/celmb1.cisco.com@c:celmb1-trunk-devel/1.0.1_0-1-1'), Flavor('is: x86_64'))
            # trvSpec[0] = 'CSCOsars:rpm'
            # trvSpec[1] = VFS('/celmb1.cisco.com@c:celmb1-trunk-devel/1.0.1_0-1-1')
            # trvSpec[2] = Flavor('is: x86_64')

            #print "\t\t%s" % trvSpec 
            #print "%s" % nevra.name 

            #self.latestpackages.sort()

            #epdb.st()
            for pkg in self.latestpackages:
                trovespec = ""
                #print "\t%s" % pkg.name

                # Why is nevra.epcoh = None ?

                if ((pkg.name == nevra.name) and
                   (pkg.version == nevra.version) and 
                   (pkg.release == nevra.release) and
                   (pkg.arch == nevra.arch)):
                   
                   trovespec = str(nevra.name) + "=" + str(trvSpec[1]) + "[" + str(trvSpec[2]) + "]"  
                   pkg.upstreamtrove = trovespec

                   print "MATCH: %s %s" %(pkg.url, trovespec)
def findYumPackagesInLabel(yumrepos, upstreamlabel, downstreamlabel):

    # given a yumrepo object, check if the packages exist upstream or downstream

    NEVRA = namedtuple('NEVRA', 'name epoch version release arch')
    dlabel = versions.Label(downstreamlabel)
    ulabel = versions.Label(upstreamlabel)

    print "DEBUG: matching packages to local troves in label %s " % dlabel
    for trvSpec, nevra in _getNevras(NEVRA, dlabel):

        # ('CSCOsars:rpm', VFS('/celmb1.cisco.com@c:celmb1-trunk-devel/1.0.1_0-1-1'), Flavor('is: x86_64'))
        # trvSpec[0] = 'CSCOsars:rpm'
        # trvSpec[1] = VFS('/celmb1.cisco.com@c:celmb1-trunk-devel/1.0.1_0-1-1')
        # trvSpec[2] = Flavor('is: x86_64')

        for pkg in yumrepos.latestpackages:
            trovespec = ""
            #print "\t%s" % pkg.name

            # Why is nevra.epcoh = None ?

            if ((pkg.name == nevra.name) and (pkg.version == nevra.version)
                    and (pkg.release == nevra.release)
                    and (pkg.arch == nevra.arch)):

                trovespec = str(nevra.name) + "=" + str(
                    trvSpec[1]) + "[" + str(trvSpec[2]) + "]"
                pkg.downstream = True
                pkg.localtrove = trovespec

                print "MATCH: %s %s" % (pkg.url, trovespec)
                #epdb.st()

    print "DEBUG: matching packages to upstream troves in label %s " % ulabel
    for trvSpec, nevra in _getNevras(NEVRA, ulabel):

        # ('CSCOsars:rpm', VFS('/celmb1.cisco.com@c:celmb1-trunk-devel/1.0.1_0-1-1'), Flavor('is: x86_64'))
        # trvSpec[0] = 'CSCOsars:rpm'
        # trvSpec[1] = VFS('/celmb1.cisco.com@c:celmb1-trunk-devel/1.0.1_0-1-1')
        # trvSpec[2] = Flavor('is: x86_64')

        #epdb.st()
        for pkg in yumrepos.latestpackages:
            trovespec = ""
            #print "\t%s" % pkg.name

            # Why is nevra.epcoh = None ?

            if ((pkg.name == nevra.name) and (pkg.version == nevra.version)
                    and (pkg.release == nevra.release)
                    and (pkg.arch == nevra.arch)):

                trovespec = str(nevra.name) + "=" + str(
                    trvSpec[1]) + "[" + str(trvSpec[2]) + "]"
                pkg.upstream = True
                pkg.upstreamtrove = trovespec

                print "MATCH: %s %s" % (pkg.url, trovespec)
                #epdb.st()
    #import epdb; epdb.st()
    return yumrepos