summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSol Jerome <sol.jerome@gmail.com>2010-10-28 09:48:31 -0500
committerSol Jerome <sol.jerome@gmail.com>2010-10-28 09:48:31 -0500
commitb9d71aacc622bd285460cbe7d86b7a538c80880d (patch)
tree116ecd6a2d6d86153494095d407f7ad483501afb
parent4be21b7fbb93c3552713ab9914114fbe0068b93d (diff)
parente560e2c7f384bdd5ca675465b85cc5a6c911f747 (diff)
downloadbcfg2-b9d71aacc622bd285460cbe7d86b7a538c80880d.tar.gz
bcfg2-b9d71aacc622bd285460cbe7d86b7a538c80880d.tar.bz2
bcfg2-b9d71aacc622bd285460cbe7d86b7a538c80880d.zip
Merge branch 'asaf-master'
-rw-r--r--src/lib/Client/Tools/Pacman.py86
-rw-r--r--src/lib/Server/Plugins/Packages.py112
2 files changed, 198 insertions, 0 deletions
diff --git a/src/lib/Client/Tools/Pacman.py b/src/lib/Client/Tools/Pacman.py
new file mode 100644
index 000000000..a9edc4d65
--- /dev/null
+++ b/src/lib/Client/Tools/Pacman.py
@@ -0,0 +1,86 @@
+"""This is the bcfg2 support for pacman"""
+
+import Bcfg2.Client.Tools
+import Bcfg2.Options
+import Bcfg2.Client.Tools
+
+class Pacman(Bcfg2.Client.Tools.PkgTool):
+ '''Archlinux package support'''
+ name = 'Pacman'
+ __execs__ = ["/usr/bin/pacman"]
+ __handles__ = [('Package', 'pacman')]
+ __req__ = {'Package': ['name', 'version']}
+ pkgtype = 'pacman'
+ pkgtool = ("/usr/bin/pacman --needed --noconfirm --noprogressbar")
+
+ def __init__(self, logger, setup, config):
+ Bcfg2.Client.Tools.PkgTool.__init__(self, logger, setup, config)
+ self.installed = {}
+ self.RefreshPackages()
+
+ def RefreshPackages(self):
+ '''Refresh memory hashes of packages'''
+ pkgcache = self.cmd.run("/usr/bin/pacman -Q")[1]
+ self.installed = {}
+ for pkg in pkgcache:
+ pkgname = pkg.split(' ')[0].strip()
+ version = pkg.split(' ')[1].strip()
+ #self.logger.info(" pkgname: %s, version: %s" % (pkgname, version))
+ self.installed[pkgname] = version
+
+ def VerifyPackage(self, entry, modlist):
+ '''Verify Package status for entry'''
+
+ print "VerifyPackage : " + entry.get('name')+ " : " + entry.get('version')
+
+ if not 'version' in entry.attrib:
+ self.logger.info("Cannot verify unversioned package %s" %
+ (entry.attrib['name']))
+ return False
+
+ if entry.attrib['name'] in self.installed:
+ if entry.attrib['version'] == 'auto':
+ return True
+ elif self.installed[entry.attrib['name']] == entry.attrib['version']:
+ #if not self.setup['quick'] and \
+ # entry.get('verify', 'true') == 'true':
+ #FIXME: We should be able to check this once
+ # http://trac.macports.org/ticket/15709 is implemented
+ return True
+ else:
+ entry.set('current_version', self.installed[entry.get('name')])
+ self.logger.info("attribname: %s" % (entry.attrib['name']))
+ self.logger.info("attribname: %s" % (entry.attrib['name']))
+ return False
+ entry.set('current_exists', 'false')
+ self.logger.info("attribname: %s" % (entry.attrib['name']))
+ return False
+
+ def RemovePackages(self, packages):
+ '''Remove extra packages'''
+ names = [pkg.get('name') for pkg in packages]
+ self.logger.info("Removing packages: %s" % " ".join(names))
+ self.cmd.run("%s --noconfirm --noprogressbar -R %s" % \
+ (self.pkgtool, " ".join(names)))
+ self.RefreshPackages()
+ self.extra = self.FindExtraPackages()
+
+ def Install(self, packages, states):
+ '''
+ Pacman Install
+ '''
+ pkgline = ""
+ for pkg in packages:
+ pkgline += " " + pkg.get('name')
+
+ print "packages : " + pkgline
+
+ try:
+ self.logger.debug('Running Pacman.Install()')
+ print "running : %s -S %s" % (self.pkgtool, pkgline)
+ s = self.cmd.run("%s -S %s" % (self.pkgtool, pkgline))
+ print "pacman : " + str(s)
+ except Exception as ex:
+ print "error in cmd.run ", ex
+
+ self.logger.debug('Running Pacman.Install()')
diff --git a/src/lib/Server/Plugins/Packages.py b/src/lib/Server/Plugins/Packages.py
index b83b7444f..194330723 100644
--- a/src/lib/Server/Plugins/Packages.py
+++ b/src/lib/Server/Plugins/Packages.py
@@ -1,6 +1,7 @@
import cPickle
import copy
import gzip
+import tarfile
import glob
import logging
import lxml.etree
@@ -467,6 +468,114 @@ class APTSource(Source):
pkg not in self.blacklist and \
(len(self.whitelist) == 0 or pkg in self.whitelist)
+class PACSource(Source):
+ basegroups = ['arch', 'parabola']
+ ptype = 'pacman'
+
+ def __init__(self, basepath, url, version, arches, components, groups,
+ rawurl, blacklist, whitelist, recommended):
+ Source.__init__(self, basepath, url, version, arches, components, groups,
+ rawurl, blacklist, whitelist, recommended)
+ self.pkgnames = set()
+
+ self.url_map = [{'rawurl': self.rawurl, 'url': self.url, 'version': self.version, \
+ 'components': self.components, 'arches': self.arches, 'groups': self.groups}]
+
+ def save_state(self):
+ cache = file(self.cachefile, 'wb')
+ cPickle.dump((self.pkgnames, self.deps, self.provides),
+ cache, 2)
+ cache.close()
+
+ def load_state(self):
+ data = file(self.cachefile)
+ self.pkgnames, self.deps, self.provides = cPickle.load(data)
+
+ def filter_unknown(self, unknown):
+ filtered = set([u for u in unknown if u.startswith('choice')])
+ unknown.difference_update(filtered)
+
+ def get_urls(self):
+ if not self.rawurl:
+ return ["%s/%s/os/%s/%s.db.tar.gz" % \
+ (self.url, part, arch, part) for part in self.components \
+ for arch in self.arches]
+ else:
+ raise Exception("PACSource : RAWUrl not supported (yet)")
+ urls = property(get_urls)
+
+
+ def read_files(self):
+ bdeps = dict()
+ bprov = dict()
+
+ if self.recommended:
+ depfnames = ['Depends', 'Pre-Depends', 'Recommends']
+ else:
+ depfnames = ['Depends', 'Pre-Depends']
+
+ for fname in self.files:
+ if not self.rawurl:
+ barch = [x for x in fname.split('@') if x in self.arches][0]
+ else:
+ # RawURL entries assume that they only have one <Arch></Arch>
+ # element and that it is the architecture of the source.
+ barch = self.arches[0]
+
+ if barch not in bdeps:
+ bdeps[barch] = dict()
+ bprov[barch] = dict()
+ try:
+ print "try to read : " + fname
+ tar = tarfile.open(fname, "r")
+ reader = gzip.GzipFile(fname)
+ except:
+ print("Failed to read file %s" % fname)
+ raise
+
+ for tarinfo in tar:
+ if tarinfo.isdir():
+ self.pkgnames.add(tarinfo.name.rsplit("-",2)[0])
+ print "added : " + tarinfo.name.rsplit("-",2)[0]
+ tar.close()
+
+ self.deps['global'] = dict()
+ self.provides['global'] = dict()
+ for barch in bdeps:
+ self.deps[barch] = dict()
+ self.provides[barch] = dict()
+ for pkgname in self.pkgnames:
+ pset = set()
+ for barch in bdeps:
+ if pkgname not in bdeps[barch]:
+ bdeps[barch][pkgname] = []
+ pset.add(tuple(bdeps[barch][pkgname]))
+ if len(pset) == 1:
+ self.deps['global'][pkgname] = pset.pop()
+ else:
+ for barch in bdeps:
+ self.deps[barch][pkgname] = bdeps[barch][pkgname]
+ provided = set()
+ for bprovided in bprov.values():
+ provided.update(set(bprovided))
+ for prov in provided:
+ prset = set()
+ for barch in bprov:
+ if prov not in bprov[barch]:
+ continue
+ prset.add(tuple(bprov[barch].get(prov, ())))
+ if len(prset) == 1:
+ self.provides['global'][prov] = prset.pop()
+ else:
+ for barch in bprov:
+ self.provides[barch][prov] = bprov[barch].get(prov, ())
+ self.save_state()
+
+ def is_package(self, _, pkg):
+ return pkg in self.pkgnames and \
+ pkg not in self.blacklist and \
+ (len(self.whitelist) == 0 or pkg in self.whitelist)
+
class Packages(Bcfg2.Server.Plugin.Plugin,
Bcfg2.Server.Plugin.StructureValidator,
Bcfg2.Server.Plugin.Generator,
@@ -742,6 +851,9 @@ class Packages(Bcfg2.Server.Plugin.Plugin,
self.sources.append(APTSource(self.cachepath, **source_from_xml(s)))
for s in xdata.findall('.//YUMSource'):
self.sources.append(YUMSource(self.cachepath, **source_from_xml(s)))
+ for s in xdata.findall('.//PACSource'):
+ self.sources.append(PACSource(self.cachepath, **source_from_xml(s)))
+
cachefiles = []
for source in self.sources:
cachefiles.append(source.cachefile)