From 2b34d93eb2c4d3f29fc4f4ebb1171f9207f70a43 Mon Sep 17 00:00:00 2001 From: Narayan Desai Date: Fri, 1 Dec 2006 20:47:09 +0000 Subject: Initial Gentoo support (from Michael Jinks) git-svn-id: https://svn.mcs.anl.gov/repos/bcfg/trunk/bcfg2@2561 ce84e21b-d406-0410-9b95-82705330c041 --- src/lib/Client/Tools/Portage.py | 68 ++++++++++++++++++++++++++++++++++++++++ src/lib/Client/Tools/RcUpdate.py | 58 ++++++++++++++++++++++++++++++++++ src/lib/Client/Tools/__init__.py | 4 +-- 3 files changed, 128 insertions(+), 2 deletions(-) create mode 100644 src/lib/Client/Tools/Portage.py create mode 100644 src/lib/Client/Tools/RcUpdate.py (limited to 'src') diff --git a/src/lib/Client/Tools/Portage.py b/src/lib/Client/Tools/Portage.py new file mode 100644 index 000000000..0edacda5f --- /dev/null +++ b/src/lib/Client/Tools/Portage.py @@ -0,0 +1,68 @@ +'''This is the bcfg2 support for the Gentoo Portage system, largely cribbed from the +APT one''' +__revision__ = '$Revision: $' + +import re +import Bcfg2.Client.Tools + +class Portage(Bcfg2.Client.Tools.PkgTool): + '''The Gentoo toolset implements package and service operations and inherits + the rest from Toolset.Toolset''' + __name__ = 'Portage' + __execs__ = ['/usr/bin/emerge', '/usr/bin/equery'] + __important__ = ["/etc/make.conf", "/etc/make.globals", \ + "/etc/make.profile/make.defaults", "/etc/make.profile/packages" ] + __handles__ = [('Package', 'ebuild')] + __req__ = {'Package': ['name', 'version']} + pkgtype = 'ebuild' + '''requires a working PORTAGE_BINHOST in make.conf''' + pkgtool = ('emerge --getbinpkgonly =%s', ('%s-%s', ['name', 'version'])) + + def __init__(self, logger, cfg, setup, states): + Bcfg2.Client.Tools.PkgTool.__init__(self, logger, cfg, setup, states) + self.cfg = cfg + if not self.setup['dryrun']: + self.cmd.run("emerge -q --sync") + self.installed = {} + self.RefreshPackages() + def RefreshPackages(self): + '''Refresh memory hashes of packages''' + cache = self.cmd.run("equery -q list") + self.installed = {} + for pkg in cache: + # there has got to be a better way... + name = re.split("-[0-9]", pkg)[0] + version = re.sub(name+"-", "", pkg) + self.installed[name] = version + + def VerifyPackage(self, entry, modlist): + '''Verify package for entry''' + if not entry.attrib.has_key('version'): + self.logger.info("Cannot verify unversioned package %s" % + (entry.attrib['name'])) + return False + if self.installed.has_key(entry.attrib['name']): + if self.installed[entry.attrib['name']] == entry.attrib['version']: + if not self.setup['quick'] and entry.get('verify', 'true') == 'true': + # mrj - there's probably a "python way" to avoid the grep...? + output = self.cmd.run("/usr/bin/equery check =%s | grep '!!!'" \ + % entry.get('name'))[1] + if [filename for filename in output if filename not in modlist]: + return False + return True + else: + entry.set('current_version', self.installed[entry.get('name')]) + return False + entry.set('current_exists', 'false') + return False + + def RemovePackages(self, packages): + '''Deal with extra configuration detected''' + if len(packages) > 0: + self.logger.info('Removing packages:') + self.logger.info(packages) + self.cmd.run("emerge --unmerge --quiet %s" % " ".join(packages)) + self.RefreshPackages() + self.extra = self.FindExtraPackages() + + diff --git a/src/lib/Client/Tools/RcUpdate.py b/src/lib/Client/Tools/RcUpdate.py new file mode 100644 index 000000000..7e2ea73be --- /dev/null +++ b/src/lib/Client/Tools/RcUpdate.py @@ -0,0 +1,58 @@ +'''This is rc-update support''' +__revision__ = '$Revision: $' + +import Bcfg2.Client.Tools, Bcfg2.Client.XML, commands, os + +class RcUpdate(Bcfg2.Client.Tools.SvcTool): + '''RcUpdate support for Bcfg2''' + __name__ = 'RcUpdate' + __execs__ = ['/sbin/rc-update', '/bin/rc-status'] + __handles__ = [('Service', 'rc-update')] + __req__ = {'Service': ['name', 'status']} + + def VerifyService(self, entry, _): + '''Verify Service status for entry. Assumes we run in the "default" runlevel.''' + # mrj - i think this should be: + # rc = self.cmd.run('/bin/rc-status | grep %s | grep started"' % entry.attrib['name']) + # ...but as i can't figure out a way to test that right now, i'll do the one + # that works in python's interactive interpreter. + rc = commands.getoutput('/bin/rc-status | grep %s | grep started' % \ + entry.get('name')) + status = len(rc) > 0 + + if not status: + # service is off + if entry.get('status') == 'on': + # we want it on, it's not + entry.set('current_status', 'off') + else: + # we want it off, it's not + entry.set('current_status', 'on') + return status + + def InstallService(self, entry): + '''Install Service entry''' + self.logger.info("Installing Service %s" % (entry.get('name'))) + try: + os.stat('/etc/init.d/%s' % entry.get('name')) + except OSError: + self.logger.debug("Init script for service %s does not exist" % entry.get('name')) + return False + + if entry.get('status') == 'off': + self.cmd.run("/etc/init.d/%s stop" % (entry.get('name'))) + cmdrc = self.cmd.run("/sbin/rc-update del %s default" % (entry.get('name'))) + else: + cmdrc = self.cmd.run("/sbin/rc-update add %s default" % entry.get('name'))[0] + return cmdrc == 0 + + def FindExtra(self): + '''Locate extra rc-update Services''' + allsrv = [line.split()[0] for line in \ + self.cmd.run("/bin/rc-status | grep started")[1]] + self.logger.debug('Found active services:') + self.logger.debug(allsrv) + specified = [srv.get('name') for srv in self.getSupportedEntries()] + return [Bcfg2.Client.XML.Element('Service', type='rc-update', name=name) \ + for name in allsrv if name not in specified] + diff --git a/src/lib/Client/Tools/__init__.py b/src/lib/Client/Tools/__init__.py index 078fcf818..a705234fa 100644 --- a/src/lib/Client/Tools/__init__.py +++ b/src/lib/Client/Tools/__init__.py @@ -1,8 +1,8 @@ '''This contains all Bcfg2 Tool modules''' __revision__ = '$Revision$' -__all__ = ["APT", "Blast", "Chkconfig", "DebInit", "Encap", "PostInstall", - "POSIX", "RPM", "SMF", "SYSV"] +__all__ = ["APT", "Blast", "Chkconfig", "DebInit", "Encap", "Portage", + "PostInstall", "POSIX", "RPM", "RcUpdate", "SMF", "SYSV"] import os, popen2, stat, sys, Bcfg2.Client.XML -- cgit v1.2.3-1-g7c22