From 903a4fcb4ac2275b149e87db518a0a15b694121f Mon Sep 17 00:00:00 2001 From: Joey Hagedorn Date: Wed, 3 Jan 2007 19:06:45 +0000 Subject: Preliminiary launchd support implementation for Install function. git-svn-id: https://svn.mcs.anl.gov/repos/bcfg/trunk/bcfg2@2618 ce84e21b-d406-0410-9b95-82705330c041 --- src/lib/Client/Tools/launchd.py | 48 +++++++++++++++++++++++++++++++---------- 1 file changed, 37 insertions(+), 11 deletions(-) diff --git a/src/lib/Client/Tools/launchd.py b/src/lib/Client/Tools/launchd.py index 2957c8869..001d42ea4 100644 --- a/src/lib/Client/Tools/launchd.py +++ b/src/lib/Client/Tools/launchd.py @@ -9,13 +9,33 @@ class LaunchD(Bcfg2.Client.Tools.Tool): __handles__ = [('Service', 'launchd')] __execs__ = ['/bin/launchctl', '/usr/bin/defaults'] __name__ = 'LaunchD' - __req__ = {'Service':['name', 'status', 'plist']} + __req__ = {'Service':['name', 'status']} #currently requires the path to the plist to load/unload, and Name is acually a reverse-fqdn (or the label) - + def FindPlist(self, entry): + '''Locate plist file that provides given reverse-fqdn name''' + '''/Library/LaunchAgents Per-user agents provided by the administrator. + /Library/LaunchDaemons System wide daemons provided by the administrator. + /System/Library/LaunchAgents Mac OS X Per-user agents. + /System/Library/LaunchDaemons Mac OS X System wide daemons.''' + plistLocations = ["/Library/LaunchDaemons","/System/Library/LaunchDaemons"] + plistMapping = [] + for directory in plistLocations: + for daemon in os.listdir(directory): + try: + plistMapping.append(dict(zip(self.cmd.run("defaults read %s/%s"%\ + (directory,daemon.rsplit('.')[0]))[1], + "%s/%s"%(directory,daemon)))) + except KeyError: + pass + try: + return plistMapping[entry.get('name')] + except KeyError: + return None + + def VerifyService(self, entry, _): '''Verify Launchd Service Entry''' - try: services = self.cmd.run("/bin/launchctl list") except IndexError:#happens when no services are running (should be never) @@ -27,19 +47,25 @@ class LaunchD(Bcfg2.Client.Tools.Tool): return entry.get('status') == 'off' try: #Perhaps add the "-w" flag to load and unload to modify the file itself! - self.cmd.run("/bin/launchtl load %s" % entry.get('plist')) + self.cmd.run("/bin/launchctl load %s" % self.FindPlist(entry)) except IndexError: return "on" return "off" def InstallService(self, entry): - '''Install SMF Service Entry''' - pass + '''Enable or Disable LaunchD Item''' + if entry.get('status') == 'on': + cmdrc = self.cmd.run("/bin/launchctl load -w %s" % self.FindPlist(entry))[0] + else: + cmdrc = self.cmd.run("/bin/launchctl unload -w %s" % self.FindPlist(entry))[0] + return cmdrc == 0 def Remove(self, svcs): - '''Remove Extra SMF entries''' + '''Remove Extra LaunchD entries''' pass + + def FindExtra(self): '''Find Extra LaunchD Services''' @@ -55,14 +81,14 @@ class LaunchD(Bcfg2.Client.Tools.Tool): if not self.canInstall(entry): self.logger.error("Insufficient information to restart service %s" % (entry.get('name'))) else: - if entry.get('status') == 'on': + if entry.get('status') == 'on' and self.FindPlist(entry): #may need to start/stop as well! self.logger.info("Reloading LaunchD service %s" % (entry.get("name"))) #stop? - self.cmd.run("/bin/launchctl unload %s" % (entry.get("plist")))#what if it disappeared? how do we stop services that are currently running but the plist disappeared?! - self.cmd.run("/bin/launchctl load %s" % (entry.get("plist"))) + self.cmd.run("/bin/launchctl unload %s" % (self.FindPlist(entry)))#what if it disappeared? how do we stop services that are currently running but the plist disappeared?! + self.cmd.run("/bin/launchctl load %s" % (self.FindPlist(entry))) #start? else: #may need to stop as well! - self.cmd.run("/bin/launchctl unload %s" % (entry.get("plist"))) + self.cmd.run("/bin/launchctl unload %s" % (self.FindPlist(entry))) -- cgit v1.2.3-1-g7c22