summaryrefslogtreecommitdiffstats
path: root/src/lib/Bcfg2/Server/Plugins/Packages/Pkgng.py
blob: 5248ad896e2f597346b5d7227a63406c8bb7b1b7 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
""" pkgng backend for :mod:`Bcfg2.Server.Plugins.Packages` """

import tarfile

try:
    import json
    # py2.4 json library is structured differently
    json.loads  # pylint: disable=W0104
except (ImportError, AttributeError):
    import simplejson as json

from Bcfg2.Server.Plugins.Packages.Collection import Collection
from Bcfg2.Server.Plugins.Packages.Source import Source


class PkgngCollection(Collection):
    """ Handle collections of pkgng sources.  This is a no-op object
    that simply inherits from
    :class:`Bcfg2.Server.Plugins.Packages.Collection.Collection`,
    overrides nothing, and defers all operations to :class:`PacSource`
    """

    def __init__(self, metadata, sources, cachepath, basepath, debug=False):
        # we define an __init__ that just calls the parent __init__,
        # so that we can set the docstring on __init__ to something
        # different from the parent __init__ -- namely, the parent
        # __init__ docstring, minus everything after ``.. -----``,
        # which we use to delineate the actual docs from the
        # .. autoattribute hacks we have to do to get private
        # attributes included in sphinx 1.0 """
        Collection.__init__(self, metadata, sources, cachepath, basepath,
                            debug=debug)
    __init__.__doc__ = Collection.__init__.__doc__.split(".. -----")[0]


class PkgngSource(Source):
    """ Handle pkgng sources """

    #: PkgngSource sets the ``type`` on Package entries to "pkgng"
    ptype = 'pkgng'

    #: The "packagesite" files of pkgng repositories are compressed
    #: with "xz"
    default_compression = 'xz'

    def _get_extension(self):
        extension = super(PkgngSource, self)._get_extension()
        if extension == '':
            return 'tar'
        return 't%s' % extension

    @property
    def urls(self):
        """ A list of URLs to the base metadata file for each
        repository described by this source. """
        fname = self.build_filename("packagesite")
        if not self.rawurl:
            rv = []
            for part in self.components:
                for arch in self.arches:
                    rv.append("%s/freebsd:%s:%s/%s/%s" %
                              (self.url, self.version, arch, part, fname))
            return rv
        else:
            return ["%s/%s" % (self.rawurl, fname)]

    def read_files(self):
        bdeps = dict()
        self.pkgnames = set()
        for fname in self.files:
            if not self.rawurl:
                abi = [x
                       for x in fname.split('@')
                       if x.startswith('freebsd:')][0][8:]
                barch = ':'.join(abi.split(':')[1:])
            else:
                # RawURL entries assume that they only have one <Arch></Arch>
                # element and that it is the architecture of the source.
                barch = self.arches[0]
            if barch not in bdeps:
                bdeps[barch] = dict()
            try:
                reader = self.open_file(fname)
                tar = tarfile.open(fileobj=reader)
                packagesite = tar.extractfile('packagesite.yaml')
            except (IOError, tarfile.TarError):
                self.logger.error("Packages: Failed to read file %s" % fname)
                raise
            for line in packagesite.readlines():
                pkg = json.loads(unicode(line, errors='ignore'))
                pkgname = pkg['name']
                self.pkgnames.add(pkgname)
                if 'deps' in pkg:
                    bdeps[barch][pkgname] = pkg['deps'].keys()
        self.process_files(bdeps, dict())
    read_files.__doc__ = Source.read_files.__doc__