#!/usr/bin/python -tt # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU Library General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. #Copyright 2003 Duke University # Seth Vidal skvidal at phy.duke.edu import rpm import libxml2 import os import sys import getopt def printError(stuff): print >> sys.stderr, stuff def doCommandLine(options): """parses the command line options, returns a dict of the necessary data""" config = {} config['uservisible'] = 'true' config['type'] = 'mandatory' config['groupreq'] = [] config['complete'] = 0 try: gopts, cmds = getopt.getopt(options, 'hg:cv:i:t:', ['help', 'groupreq=']) except getopt.error, e: printError('Options Error: %s' % e) usage() try: for o, a in gopts: if o == '-g': config['groupname'] = a elif o == '-i': config['groupid'] = a elif o == '-v': if a not in ['true', 'false']: usage() config['uservisible'] = a elif o == '-c': config['complete'] = 1 elif o == '-t': if a not in ['optional', 'mandatory', 'default']: usage() config['type'] = a elif o == '--groupreq': config['groupreq'].append(a) elif o in ['--help' , '-h']: usage() except ValueError, e: printError('Options Error: %s' % e) usage() config['packages'] = cmds return config def usage(): printError(""" Usage: yumgengroups.py [options] -g [groupname] -i [groupid] Options: -c output the complete file - not just the group section -v [true or false] - is the group visible to the user or hidden -t type of packages(mandatory, default or optional) defaults to mandatory --groupreq [groupname] - a group you want included in the group as a requirement you may list this option more than one to include multiple groups. -h, --help this screen """) sys.exit(1) def returnHdr(ts, package): """hand back the rpm header - if the pkg is fubar handback None""" try: fdno = os.open(package, os.O_RDONLY) except OSError, e: printError('Error: %s open error %s' % (package, e)) hdr = None return hdr ts.setVSFlags(~(rpm.RPMVSF_NOMD5|rpm.RPMVSF_NEEDPAYLOAD)) try: hdr = ts.hdrFromFdno(fdno) except rpm.error, e: printError('Error: %s rpm open error %s' % (package, e)) hdr = None if type(hdr) != rpm.hdr: hdr = None ts.setVSFlags(0) os.close(fdno) return hdr def main(args): """ main loop""" config = doCommandLine(args) # sanity checks errors = [] if not config.has_key('groupname'): errors.append('Error: Must define a groupname: -g required') if not config.has_key('groupid'): errors.append('Error: Must define a groupid: -i required') if len(config['packages']) == 0: errors.append('Error: No packages specified') if len(errors) > 0: for error in errors: print >> sys.stderr, error usage() # setup the transaction Set ts = rpm.TransactionSet() # give me a list of pkgs that have been finished pkgsincluded = [] for pkg in config['packages']: hdr = returnHdr(ts, pkg) if hdr is None: printError('Warning: bad or nonexistent package %s' % pkg) pass else: name = hdr['name'] if name not in pkgsincluded: pkgsincluded.append(name) else: printError('Warning: ignoring duplicate package %s'% name) del hdr del ts # get the base doc and root tag doc = libxml2.newDoc("1.0") dtd = doc.newDtd("comps" ,"-//Red Hat, Inc.//DTD Comps info//EN","comps.dtd") doc.addChild(dtd) root = doc.newChild(None, "comps", None) group = root.newChild(None, 'group', None) group.newChild(None, 'id', config['groupid']) group.newChild(None, 'uservisible', config['uservisible']) group.newChild(None, 'name', config['groupname']) # do the groupreqs grplist = group.newChild(None, 'grouplist', None) for req in config['groupreq']: grplist.newChild(None, 'groupreq', req) # and the packages pkglist = group.newChild(None, 'packagelist', None) for pkg in pkgsincluded: pkgnode = pkglist.newChild(None, 'packagereq', pkg) pkgnode.newProp("type", config['type']) if config['complete']: print doc.serialize(None, 1) else: print group.serialize(None, 1) sys.exit() if __name__ == '__main__': main(sys.argv[1:])