summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorIzhar Firdaus <kagesenshi.87@gmail.com>2008-06-23 22:49:54 +0800
committerIzhar Firdaus <kagesenshi.87@gmail.com>2008-06-23 22:49:54 +0800
commit4e5b4a39c432395b62470176c84b96db44b8d34f (patch)
tree1edb2e4655375d7bdf030fcf699567bb047730a3
parent3155a3199cee1dfe727f6e05f06d585ccbdedd62 (diff)
downloadchitin-4e5b4a39c432395b62470176c84b96db44b8d34f.zip
chitin-4e5b4a39c432395b62470176c84b96db44b8d34f.tar.gz
chitin-4e5b4a39c432395b62470176c84b96db44b8d34f.tar.xz
- cleanup at chitin package
- created yum-plugin folder
-rw-r--r--chitin/parser.py237
-rw-r--r--chitin/utils.py74
-rw-r--r--yum-plugin/chitin.py311
3 files changed, 397 insertions, 225 deletions
diff --git a/chitin/parser.py b/chitin/parser.py
index 27e79cd..006d3a5 100644
--- a/chitin/parser.py
+++ b/chitin/parser.py
@@ -14,143 +14,40 @@
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#
-# Copyright Red Hat Inc. 2007, 2008
-#
-# Author: Izhar Firdaus <izhar@fedoraproject.com>
-# Examples:
-#
-# yum oci-install oneclickinstall-XML-metadata-file
-# yum oci-query details oneclickinstall-XML-metadata-file
-# yum oci-query repositories oneclickinstall-XML-metadata-file
-# yum oci-query packages oneclickinstall-XML-metadata-file
#
+# Parser library for One Click Install metadata XML
+#
+# @author Izhar Firdaus <izhar@fedoraproject.com>
from xml.etree.ElementTree import ElementTree,Element
-import re
-
-from yum.plugins import PluginYumExit,TYPE_CORE,TYPE_INTERACTIVE
-from yum import logginglevels
-import yum.i18n, tempfile
-_ = yum.i18n._
+import re, tempfile
+from chitin.utils import attrsfilter,get_child_value
ocins='http://opensuse.org/Standards/One_Click_Install'
-#distro='fedora'
-#release='9'
-
-## Use this for now
-distro='openSUSE'
-release='Factory'
-
-
-requires_api_version = '2.5'
-plugin_type = (TYPE_INTERACTIVE,)
-
-
-def attrsfilter(elements,keywords,operation='or'):
- """
- Function to filter elements by its attributes
-
- @param elements A list of elements to be filtered
- @param keywords A dictionary containing required tags and its values
- @param operation A string, either 'or' or 'and', for operation selection
-
- @return A list of filtered elements by attributes
- """
- retval = []
- if not keywords: return elements
- if operation == 'or':
- for element in elements:
- for key in keywords:
- if element.attrib.has_key(key):
- if element.attrib[key] == keywords[key]:
- retval.append(element)
- break
- elif operation == 'and':
- for element in elements:
- for key in keywords:
- if not element.attrib.has_key(key): break
- if element.attrib[key] != keywords[key]: break
- retval.append(element)
- return retval
-
-def get_element_tag(element):
- """
- Function to get the element tag without namespace
-
- @param element An element which will be extracted the tag name
-
- @return A string, containing the tag name without namespace
- """
- tag = re.match('{.*?}(.*)',element.tag)
- if tag:
- return tag.group(1)
- else:
- return tag
-
-def get_child_value(element,childname):
- """
- Function to get the value of an element's child element
-
- @param element An element to be queried
- @param childname A string, containing the tagname of the child
-
- @return A string containing child's text value if child is a leaf element,
- or a ElementTree element if child is a parent to 1 or more elements
- """
- for c in element.getchildren():
- if get_element_tag(c) == childname:
- if c.getchildren():
- return c
- else:
- return c.text
-
-
-def add_tmp_repo(base,name,repourls):
- """
- Function to add temporary repository
- @param base The YumBase object for the operation
- @param name The repository name
- @param repourls A list of urls for the repository
-
- @return None
- """
- tfo = tempfile.NamedTemporaryFile()
- repoid = name
- repoconfig = """
-[%s]
-name=%s
-failovermethod=priority
-baseurl=%s
-enabled=1
-""" % (name,name,'\n'.join(repourls))
- tfo.file.write(repoconfig)
- tfo.file.close()
- base.getReposFromConfigFile(tfo.name)
-
-class OCIMetapackage:
+class Metapackage:
"""
- Parser class for OCI Metapackage XML.
+ Parser class for Chitin Metapackage XML.
"""
- def __init__(self,element,distversion):
+ def __init__(self,xmlfile,distversion):
"""
- @param element ElementTree object which stores the XML file
+ @param xmlfile One Click Install XML file
@param distversion A string containing '$distro $release'
@return None
"""
- self.element = element
+ self.element = ElementTree(Element('metapackage'),open(xmlfile))
self.distversion = distversion
def getGroup(self):
"""
- Function to get Group element from OCI Metadata
+ Function to get Group element from Chitin Metadata
@return 'group' Element of the current distversion
"""
for group in self.element.getiterator('{%s}%s' % (ocins,'group')):
- if group.attrib['distversion'] == self.distversion:
+ if group.attrib['distversion'].lower() == self.distversion.lower():
return group
def getRepositories(self,*args,**kwargs):
@@ -199,113 +96,3 @@ class OCIMetapackage:
urls.sort(sorturl)
return [ url[0] for url in urls ]
-class OCIQuery:
- def __init__(self,distro,release):
- self.distro = distro
- self.release = release
-
- def getNames(self):
- return ['oci-query']
-
- def getUsage(self):
- return "[details|repositories|packages] [OCI file]"
-
- def getSummary(self):
- return "Query data from OneClickInstall metadata"
-
- def doCheck(self, base, basecmd, extcmds):
- pass
-
- def getRepos(self): # so we can act as a "conduit"
- return self.repos
-
- def show_pkg(self, msg, pkg, md, disp=None):
- print msg, pkg, md
-
- def show_pkg_exit(self):
- pass
-
- def doCommand(self, base, basecmd, extcmds):
- action = extcmds[0]
- param = extcmds[1:]
- metapackages = []
- for mp in param:
- et = ElementTree(Element('metapackage'),open(mp))
- metapackages.append(OCIMetapackage(et,'%s %s' % (self.distro,self.release)))
-
- if action == 'details':
- for oci in metapackages:
- print '======================='
- print 'Metadata'
- print '======================='
- for c in oci.getGroup().getchildren():
- tagname = get_element_tag(c)
- if tagname in ['name','summary','description']:
- print tagname,':',c.text
- if action == 'repositories':
- for oci in metapackages:
- print '========================'
- print 'Repositories'
- print '========================'
- for r in oci.getRepositories():
- print get_child_value(r,'name')
- print oci.getRepoURL(get_child_value(r,'name'))
- if action == 'packages':
- for oci in metapackages:
- print '========================'
- print 'Packages'
- print '========================'
- for p in oci.getProducts():
- print p.getchildren()[0].text
- print ''
- return 0, ['']
-
-class OCIInstall:
- def __init__(self,distro,release):
- self.distro = distro
- self.release = release
-
- def getNames(self):
- return ['oci-install']
-
- def getUsage(self):
- return "[OCI file]"
-
- def getSummary(self):
- return "Install packages from OneClickInstall metadata"
-
- def doCheck(self, base, basecmd, extcmds):
- pass
-
- def getRepos(self): # so we can act as a "conduit"
- return self.repos
-
- def show_pkg(self, msg, pkg, md, disp=None):
- print msg, pkg, md
-
- def show_pkg_exit(self):
- pass
-
- def doCommand(self, base, basecmd, extcmds):
- packages = []
- repositories = []
- for mp in extcmds:
- et = ElementTree(Element('metapackage'),open(mp))
- oci = OCIMetapackage(et,'%s %s' % (self.distro,self.release))
- for p in oci.getProducts():
- packages.append(get_child_value(p,'name'))
- for r in oci.getRepositories():
- repositories.append((get_child_value(r,'name'),oci.getRepoURL(get_child_value(r,'name'))))
- print packages
- print repositories
-
- base.verbose_logger.log(logginglevels.INFO_2,
- _("Setting up Install Process"))
- try:
- return base.installPkgs(packages)
- except yum.Errors.YumBaseError, e:
- return 1, [str(e)]
-
-def config_hook(conduit):
- conduit.registerCommand(OCIQuery(distro,release))
- conduit.registerCommand(OCIInstall(distro,release))
diff --git a/chitin/utils.py b/chitin/utils.py
new file mode 100644
index 0000000..b10bfc3
--- /dev/null
+++ b/chitin/utils.py
@@ -0,0 +1,74 @@
+#!/usr/bin/python
+
+# 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.
+
+def attrsfilter(elements,keywords,operation='or'):
+ """
+ Function to filter elements by its attributes
+
+ @param elements A list of elements to be filtered
+ @param keywords A dictionary containing required tags and its values
+ @param operation A string, either 'or' or 'and', for operation selection
+
+ @return A list of filtered elements by attributes
+ """
+ retval = []
+ if not keywords: return elements
+ if operation == 'or':
+ for element in elements:
+ for key in keywords:
+ if element.attrib.has_key(key):
+ if element.attrib[key] == keywords[key]:
+ retval.append(element)
+ break
+ elif operation == 'and':
+ for element in elements:
+ for key in keywords:
+ if not element.attrib.has_key(key): break
+ if element.attrib[key] != keywords[key]: break
+ retval.append(element)
+ return retval
+
+def get_element_tag(element):
+ """
+ Function to get the element tag without namespace
+
+ @param element An element which will be extracted the tag name
+
+ @return A string, containing the tag name without namespace
+ """
+ tag = re.match('{.*?}(.*)',element.tag)
+ if tag:
+ return tag.group(1)
+ else:
+ return tag
+
+def get_child_value(element,childname):
+ """
+ Function to get the value of an element's child element
+
+ @param element An element to be queried
+ @param childname A string, containing the tagname of the child
+
+ @return A string containing child's text value if child is a leaf element,
+ or a ElementTree element if child is a parent to 1 or more elements
+ """
+ for c in element.getchildren():
+ if get_element_tag(c) == childname:
+ if c.getchildren():
+ return c
+ else:
+ return c.text
+
diff --git a/yum-plugin/chitin.py b/yum-plugin/chitin.py
new file mode 100644
index 0000000..1653085
--- /dev/null
+++ b/yum-plugin/chitin.py
@@ -0,0 +1,311 @@
+#!/usr/bin/python
+
+# 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 Red Hat Inc. 2007, 2008
+#
+# Author: Izhar Firdaus <izhar@fedoraproject.com>
+# Examples:
+#
+# yum chitin-install oneclickinstall-XML-metadata-file
+# yum chitin-query details oneclickinstall-XML-metadata-file
+# yum chitin-query repositories oneclickinstall-XML-metadata-file
+# yum chitin-query packages oneclickinstall-XML-metadata-file
+#
+
+
+from xml.etree.ElementTree import ElementTree,Element
+import re
+
+from yum.plugins import PluginYumExit,TYPE_CORE,TYPE_INTERACTIVE
+from yum import logginglevels
+import yum.i18n, tempfile
+_ = yum.i18n._
+
+ocins='http://opensuse.org/Standards/One_Click_Install'
+#distro='fedora'
+#release='9'
+
+## Use this for now
+distro='openSUSE'
+release='Factory'
+
+
+requires_api_version = '2.5'
+plugin_type = (TYPE_INTERACTIVE,)
+
+
+def attrsfilter(elements,keywords,operation='or'):
+ """
+ Function to filter elements by its attributes
+
+ @param elements A list of elements to be filtered
+ @param keywords A dictionary containing required tags and its values
+ @param operation A string, either 'or' or 'and', for operation selection
+
+ @return A list of filtered elements by attributes
+ """
+ retval = []
+ if not keywords: return elements
+ if operation == 'or':
+ for element in elements:
+ for key in keywords:
+ if element.attrib.has_key(key):
+ if element.attrib[key] == keywords[key]:
+ retval.append(element)
+ break
+ elif operation == 'and':
+ for element in elements:
+ for key in keywords:
+ if not element.attrib.has_key(key): break
+ if element.attrib[key] != keywords[key]: break
+ retval.append(element)
+ return retval
+
+def get_element_tag(element):
+ """
+ Function to get the element tag without namespace
+
+ @param element An element which will be extracted the tag name
+
+ @return A string, containing the tag name without namespace
+ """
+ tag = re.match('{.*?}(.*)',element.tag)
+ if tag:
+ return tag.group(1)
+ else:
+ return tag
+
+def get_child_value(element,childname):
+ """
+ Function to get the value of an element's child element
+
+ @param element An element to be queried
+ @param childname A string, containing the tagname of the child
+
+ @return A string containing child's text value if child is a leaf element,
+ or a ElementTree element if child is a parent to 1 or more elements
+ """
+ for c in element.getchildren():
+ if get_element_tag(c) == childname:
+ if c.getchildren():
+ return c
+ else:
+ return c.text
+
+
+def add_tmp_repo(base,name,repourls):
+ """
+ Function to add temporary repository
+
+ @param base The YumBase object for the operation
+ @param name The repository name
+ @param repourls A list of urls for the repository
+
+ @return None
+ """
+ tfo = tempfile.NamedTemporaryFile()
+ repoid = name
+ repoconfig = """
+[%s]
+name=%s
+failovermethod=priority
+baseurl=%s
+enabled=1
+""" % (name,name,'\n'.join(repourls))
+ tfo.file.write(repoconfig)
+ tfo.file.close()
+ base.getReposFromConfigFile(tfo.name)
+
+class OCIMetapackage:
+ """
+ Parser class for OCI Metapackage XML.
+ """
+ def __init__(self,element,distversion):
+ """
+ @param element ElementTree object which stores the XML file
+ @param distversion A string containing '$distro $release'
+
+ @return None
+ """
+ self.element = element
+ self.distversion = distversion
+
+ def getGroup(self):
+ """
+ Function to get Group element from OCI Metadata
+
+ @return 'group' Element of the current distversion
+ """
+ for group in self.element.getiterator('{%s}%s' % (ocins,'group')):
+ if group.attrib['distversion'] == self.distversion:
+ return group
+
+ def getRepositories(self,*args,**kwargs):
+ """
+ Function to get 'repository' elements from the current distversion group
+
+ @kwargs Keyword arguments for filtering results
+
+ @return A list containing a filtered list of 'repository' Elements
+ """
+ repos = self.getGroup().getiterator('{%s}%s' % (ocins,'repository'))
+ return attrsfilter(repos,kwargs)
+
+ def getProducts(self,*args,**kwargs):
+ """
+ Function to get 'product' elements from the current distversion group
+
+ @kwargs Keyword arguments for filtering results
+
+ @return A list containing a filtered list of 'product' Elements
+ """
+ products = self.getGroup().getiterator('{%s}%s' % (ocins,'product'))
+ return attrsfilter(products,kwargs)
+
+ def getRepoURL(self,reponame):
+ """
+ Function to get 'url' values from current distversion group, and requested reponame
+
+ @param reponame The repository name
+
+ @return A list of URLs from the requested repository, sorted higher score first
+ """
+ repos = self.getRepositories()
+ urls = []
+ for r in repos:
+ if get_child_value(r,'name') == reponame:
+ for url in r.getiterator('{%s}%s' % (ocins,'url')):
+ priority = 0
+ if url.attrib.has_key('score'): priority = int(url.attrib['score'])
+ urls.append((url.text.strip(),priority))
+ def sorturl(x,y):
+ if x[1] <= y[1]:
+ return +1
+ else:
+ return -1
+ urls.sort(sorturl)
+ return [ url[0] for url in urls ]
+
+class OCIQuery:
+ def __init__(self,distro,release):
+ self.distro = distro
+ self.release = release
+
+ def getNames(self):
+ return ['oci-query']
+
+ def getUsage(self):
+ return "[details|repositories|packages] [OCI file]"
+
+ def getSummary(self):
+ return "Query data from OneClickInstall metadata"
+
+ def doCheck(self, base, basecmd, extcmds):
+ pass
+
+ def getRepos(self): # so we can act as a "conduit"
+ return self.repos
+
+ def show_pkg(self, msg, pkg, md, disp=None):
+ print msg, pkg, md
+
+ def show_pkg_exit(self):
+ pass
+
+ def doCommand(self, base, basecmd, extcmds):
+ action = extcmds[0]
+ param = extcmds[1:]
+ metapackages = []
+ for mp in param:
+ et = ElementTree(Element('metapackage'),open(mp))
+ metapackages.append(OCIMetapackage(et,'%s %s' % (self.distro,self.release)))
+
+ if action == 'details':
+ for oci in metapackages:
+ print '======================='
+ print 'Metadata'
+ print '======================='
+ for c in oci.getGroup().getchildren():
+ tagname = get_element_tag(c)
+ if tagname in ['name','summary','description']:
+ print tagname,':',c.text
+ if action == 'repositories':
+ for oci in metapackages:
+ print '========================'
+ print 'Repositories'
+ print '========================'
+ for r in oci.getRepositories():
+ print get_child_value(r,'name')
+ print oci.getRepoURL(get_child_value(r,'name'))
+ if action == 'packages':
+ for oci in metapackages:
+ print '========================'
+ print 'Packages'
+ print '========================'
+ for p in oci.getProducts():
+ print p.getchildren()[0].text
+ print ''
+ return 0, ['']
+
+class OCIInstall:
+ def __init__(self,distro,release):
+ self.distro = distro
+ self.release = release
+
+ def getNames(self):
+ return ['oci-install']
+
+ def getUsage(self):
+ return "[OCI file]"
+
+ def getSummary(self):
+ return "Install packages from OneClickInstall metadata"
+
+ def doCheck(self, base, basecmd, extcmds):
+ pass
+
+ def getRepos(self): # so we can act as a "conduit"
+ return self.repos
+
+ def show_pkg(self, msg, pkg, md, disp=None):
+ print msg, pkg, md
+
+ def show_pkg_exit(self):
+ pass
+
+ def doCommand(self, base, basecmd, extcmds):
+ packages = []
+ repositories = []
+ for mp in extcmds:
+ et = ElementTree(Element('metapackage'),open(mp))
+ oci = OCIMetapackage(et,'%s %s' % (self.distro,self.release))
+ for p in oci.getProducts():
+ packages.append(get_child_value(p,'name'))
+ for r in oci.getRepositories():
+ repositories.append((get_child_value(r,'name'),oci.getRepoURL(get_child_value(r,'name'))))
+ print packages
+ print repositories
+
+ base.verbose_logger.log(logginglevels.INFO_2,
+ _("Setting up Install Process"))
+ try:
+ return base.installPkgs(packages)
+ except yum.Errors.YumBaseError, e:
+ return 1, [str(e)]
+
+def config_hook(conduit):
+ conduit.registerCommand(OCIQuery(distro,release))
+ conduit.registerCommand(OCIInstall(distro,release))