summaryrefslogtreecommitdiffstats
path: root/src/lib/Server/Generators/Pkgmgr.py
blob: 63e65970dd3a40ab6d2a1dffe121ea53003e5d43 (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
'''This module implements a package management scheme for all images'''
__revision__ = '$Revision$'

from re import compile as regcompile

from Bcfg2.Server.Generator import Generator, DirectoryBacked, XMLFileBacked

class PackageEntry(XMLFileBacked):
    '''PackageEntry is a set of packages and locations for a single image'''
    __identifier__ = 'image'
    rpm = regcompile('^(?P<name>[\w\+\d\.]+(-[\w\+\d\.]+)*)-(?P<version>[\w\d\.]+-([\w\d\.]+))\.(?P<arch>\w+)\.rpm$')

    def Index(self):
        '''Build internal data structures'''
        XMLFileBacked.Index(self)
        self.packages = {}
        for location in self.entries:
            for pkg in location.getchildren():
                if pkg.attrib.has_key("file"):
                    mdata = self.rpm.match(pkg.get('file'))
                    if not mdata:
                        print "failed to rpm match %s" % (pkg.get('file'))
                        continue
                    pkgname = mdata.group('name')
                    self.packages[pkgname] = mdata.groupdict()
                    self.packages[pkgname]['file'] = pkg.attrib['file']
                    self.packages[pkgname]['uri'] = location.attrib['uri']
                    self.packages[pkgname]['type'] = 'rpm'
                else:
                    self.packages[pkg.get('name')] = pkg.attrib

class PackageDir(DirectoryBacked):
    '''A directory of package files'''
    __child__ = PackageEntry

class Pkgmgr(Generator):
    '''This is a generator that handles package assignments'''
    __name__ = 'Pkgmgr'
    __version__ = '$Id$'
    __author__ = 'bcfg-dev@mcs.anl.gov'

    def __init__(self, core, datastore):
        Generator.__init__(self, core, datastore)
        self.pkgdir = PackageDir(self.data, self.core.fam)

    def FindHandler(self, entry):
        '''Non static mechanism of determining entry provisioning'''
        if entry.tag != 'Package':
            raise KeyError, (entry.tag, entry.get('name'))
        return self.LocatePackage

    def LocatePackage(self, entry, metadata):
        '''Locates a package entry for particular metadata'''
        pkgname = entry.get('name')
        pkglist = self.pkgdir["%s.xml" % (metadata.image)]
        if pkglist.packages.has_key(pkgname):
            pkg = pkglist.packages[pkgname]
            if pkg.get('type', None) == 'rpm':
                entry.attrib.update({'url':"%s/%s" % (pkg['uri'], pkg['file']), 'version':pkg['version']})
            else:
                entry.attrib.update(pkg)
        else:
            raise KeyError, ("Package", pkgname)