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