Ok this is a second pass at writing out the xml we need to build groups from a 
comps file.  I still have to look at factory-managed-group and see if it can 
handle this.

usage right now... uncompress a comps file and use it.

> vi comps_groups.py 
> mkdir group-os
> cd group-os/
>  ../comps_groups.py 
> ../repodata/0da963383df1bcd1e3cd8d3403a32157b6ebb42a0790eab36896fa82bb4305e0-comps-f20.xml
>  


#!/usr/bin/python

from collections import namedtuple

from lxml import etree

# Example of groups.xml 
# groups xml is a list of all the groups to be built
'''
<?xml version='1.0' encoding='UTF-8'?>
<data>
  <items>
    <byDefault>1</byDefault>
    <checkPathConflicts>0</checkPathConflicts>
    <depCheck>1</depCheck>
    <filename>groupPackages.xml</filename>
    <name>group-packages</name>
  </items>
  <items>
    <byDefault>1</byDefault>
    <checkPathConflicts>1</checkPathConflicts>
    <depCheck>1</depCheck>
    <filename>groupStandard.xml</filename>
    <name>group-standard</name>
  </items>
</data>
'''

class GROUP(namedtuple('group', 'name filename bydefault checkpath depcheck')):
    __slots__ = ()

    def toxml(self):
        node = etree.Element('items')
        etree.SubElement(node, 'byDefault').text = self.bydefault
        etree.SubElement(node, 'depCheck').text = self.depcheck
        etree.SubElement(node, 'checkPathConflicts').text = self.checkpath
        etree.SubElement(node, 'filename').text = self.filename
        etree.SubElement(node, 'name').text = self.name
        return node

# Example of packages.xml
# Just one package from the bigger xml
'''
  <items>
    <flavor>1#x86:i486:i586:i686</flavor>
    <name>389-ds-base</name>
    <use>x86</use>
    
<version>/centos6.rpath.com@rpath:centos-6e/1394758678.670:1.2.11.15_32.el6_5-1-1</version>
  </items>
  <items>
    <flavor>1#x86_64</flavor>
    <name>389-ds-base</name>
    <use>x86_64</use>
    
<version>/centos6.rpath.com@rpath:centos-6e/1394758678.670:1.2.11.15_32.el6_5-1-1</version>
  </items>
'''

class PACKAGE(namedtuple('package', 'name flavor use version')):
    __slots__ = ()

    def toxml(self):  
        node = etree.Element('items')
        etree.SubElement(node, 'name').text = self.name
        etree.SubElement(node, 'flavor').text = self.flavor
        etree.SubElement(node, 'use').text = self.use
        etree.SubElement(node, 'version').text = self.version
        return node



class CompsReader(object):

    '''
    Creates a data structure from comps.xml that can 
    be used by factory-managed-group to create conary groups
    '''

    byDefault = {
        # True => "installed"
        'mandatory': True,
        'default': True,
        # False => "optional"
        'optional': False,
        'conditional': False,
    }

    flavorMap = { 
        # x86 Map
        '1#x86:i486:i586:i686' : 'x86',
        # x86_64 Map 
        '1#x86_64': 'x86_64' 
    }

    def __init__(self, compsfile=None):
        self.compsfile = compsfile

    def write_xml(self, data):
        for filename, xml in data.iteritems():
            with open(filename, 'w') as f:
                f.write(xml)        

    def getPackageMap(self, groups):
        pkgMap = {} # groupname: [(packagename, byDefault), ...]
        for group in groups:
            grpName = 'group-' + group.find('id').text
            pkgList = []
            for packagelist in group.findall('packagelist'):
                for pkg in packagelist.findall('packagereq'):
                    pkgList.append((pkg.text, 
self.byDefault.get(pkg.get('type'))))
            pkgMap[grpName] = pkgList
        return pkgMap

    def getGroupMap(self, environments, categories):
        grpMap = {} # groupname: [(trovename, byDefault), ...]
        for env in environments + categories:
            envName = 'group-' + env.find('id').text
            grpList = []
            for grouplist in env.findall('grouplist'):
                for grp in grouplist.findall('groupid'):
                    grpList.append(('group-' + grp.text, True))
            for optionlist in env.findall('optionlist'):
                for grp in optionlist.findall('groupid'):
                    grpList.append(('group-' + grp.text, False))
            grpMap[envName] = grpList
        return grpMap

    def createGroupsXml(self, pkgMap, grpMap):
        root = etree.Element('data')
        for grp in pkgMap.keys() + grpMap.keys():
            filename = grp + '.xml'
            group = GROUP(grp, filename, '1', '0', '1') 
            root.append(group.toxml())
        return etree.tostring(root, pretty_print=True, 
                        xml_declaration=True, encoding='UTF-8')

    def createPackageXml(self, pkgList):
        # FIXME
        # Mocked out. We are going to  do this different
        # Need to do a conary search for the actual version of the 
        # conary package. In mirrorball we should be able to look
        # this up in packageMaps without pinging the label for each 
        # package.
        version = '1'
     
        root = etree.Element('data')
        for pkg, bydefault in pkgList:
            for flavor in self.flavorMap:
                package = PACKAGE(pkg, flavor, self.flavorMap.get(flavor), 
version)  
                root.append(package.toxml())
        return etree.tostring(root, pretty_print=True, 
                        xml_declaration=True, encoding='UTF-8')

    def createAllXml(self, pkgMap, grpMap):
        data = {}
        data.setdefault('groups.xml', self.createGroupsXml(pkgMap, grpMap))
        for group, packages in pkgMap.iteritems():
            data.setdefault(group + '.xml', self.createPackageXml(packages))
        # FIXME
        # Not sure the factory can handle this format yet
        for group, groups in grpMap.iteritems():
            data.setdefault(group + '.xml', self.createPackageXml(groups))
        return data

            
    def read(self, fn):
        r = etree.parse(fn).getroot()
        groups = r.xpath('group')
        environments = r.xpath('environment')
        categories = r.xpath('category')
        # TODO Find a use for langpacks
        langpacks = r.find('langpacks')
        pkgMap = self.getPackageMap(groups)
        grpMap = self.getGroupMap(environments, categories)
        data = self.createAllXml(pkgMap, grpMap)
        return data
 
    def write(self, data):
        self.write_xml(data)

    def main(self, compsfile):
        data = self.read(compsfile)
        self.write(data)

if __name__ == '__main__':
    import sys
    from conary.lib import util
    sys.excepthook = util.genExcepthook()

    fn = sys.argv[1]

    comps_reader = CompsReader()
    data = comps_reader.read(fn)
    import epdb;epdb.st()
    comps_reader.write(data)



--

Brett C. Smith
[email protected]
Sr Software Developer
Platform Deployment Technologies
(919)531-6635  -- x16635

________________________________________
From: Foresight-devel <[email protected]> on 
behalf of Michael K. Johnson <[email protected]>
Sent: Wednesday, March 19, 2014 9:38 PM
To: Foresight Linux Development
Subject: [Foresight-devel] Re: making groups from comps

On Wed, Mar 19, 2014 at 09:16:24PM -0400, Michael K. Johnson wrote:
> I've been looking at comps. It has multiple things all of which
> we would represent via conary groups: groups, categories, and
> environments.
>
> I think langpacks might also show up as groups somehow but I'm a
> bit fuzzier on that.  Conary doesn't have a concept to directly
> map them into.

OK, included is my attempt to turn comps into data to drive building
Conary groups.  Try running it against comps and compare to the comps
to see what you think.


#!/usr/bin/python

import sys

from lxml import etree

fn = sys.argv[1]

r = etree.parse(fn).getroot()
groups = r.xpath('group')
environments = r.xpath('environment')
categories = r.xpath('category')
langpacks = r.find('langpacks')

pkgMap = {} # groupname: [(packagename, byDefault), ...]
grpMap = {} # groupname: [(trovename, byDefault), ...]

byDefault = {
    # True => "installed"
    'mandatory': True,
    'default': True,
    # False => "optional"
    'optional': False,
    'conditional': False,
}

for group in groups:
    grpName = 'group-' + group.find('id').text
    pkgList = []
    for packagelist in group.findall('packagelist'):
        for pkg in packagelist.findall('packagereq'):
            pkgList.append((pkg.text, byDefault[pkg.get('type')]))
    pkgMap[grpName] = pkgList

for env in environments + categories:
    envName = 'group-' + env.find('id').text
    grpList = []
    for grouplist in env.findall('grouplist'):
        for grp in grouplist.findall('groupid'):
            grpList.append(('group-' + grp.text, True))
    for optionlist in env.findall('optionlist'):
        for grp in optionlist.findall('groupid'):
            grpList.append(('group-' + grp.text, False))
    grpMap[envName] = grpList

import epdb;epdb.st()

_______________________________________________
Foresight-devel mailing list
[email protected]
https://lists.foresightlinux.org/mailman/listinfo/foresight-devel
_______________________________________________
Foresight-devel mailing list
[email protected]
https://lists.foresightlinux.org/mailman/listinfo/foresight-devel

Reply via email to