Changeset 5522

Show
Ignore:
Timestamp:
11/02/09 13:15:26 (3 weeks ago)
Author:
kisielk
Message:

Greatly sped up launchd client tool. Also made services reload correctly.

Files:
1 modified

Legend:

Unmodified
Added
Removed
  • trunk/bcfg2/src/lib/Client/Tools/launchd.py

    r5408 r5522  
    44import os 
    55import Bcfg2.Client.Tools 
     6import popen2 
     7 
     8'''Locate plist file that provides given reverse-fqdn name 
     9/Library/LaunchAgents          Per-user agents provided by the administrator. 
     10/Library/LaunchDaemons         System wide daemons provided by the administrator. 
     11/System/Library/LaunchAgents   Mac OS X Per-user agents. 
     12/System/Library/LaunchDaemons  Mac OS X System wide daemons.''' 
     13plistLocations = ["/Library/LaunchDaemons", "/System/Library/LaunchDaemons"] 
     14plistMapping = {} 
     15for directory in plistLocations: 
     16    for daemon in os.listdir(directory): 
     17        try: 
     18            if daemon.endswith(".plist"): 
     19                d = daemon[:-6] 
     20            else: 
     21                d = daemon 
     22            (stdout, _) = popen2.popen2('defaults read %s/%s Label' % (directory, d)) 
     23            label = stdout.read().strip() 
     24            plistMapping[label] = "%s/%s" % (directory, daemon) 
     25        except KeyError: #perhaps this could be more robust 
     26            pass 
    627 
    728class launchd(Bcfg2.Client.Tools.Tool): 
     
    1738    ''' 
    1839    def FindPlist(self, entry): 
    19         '''Locate plist file that provides given reverse-fqdn name 
    20         /Library/LaunchAgents          Per-user agents provided by the administrator. 
    21         /Library/LaunchDaemons         System wide daemons provided by the administrator. 
    22         /System/Library/LaunchAgents   Mac OS X Per-user agents. 
    23         /System/Library/LaunchDaemons  Mac OS X System wide daemons.''' 
    24         plistLocations = ["/Library/LaunchDaemons", "/System/Library/LaunchDaemons"] 
    25         plistMapping = {} 
    26         for directory in plistLocations: 
    27             for daemon in os.listdir(directory): 
    28                 try: 
    29                     if daemon.endswith(".plist"): 
    30                         d = daemon[:(len(daemon)-6)] 
    31                     else: 
    32                         d = daemon 
    33                     plistMapping[self.cmd.run( \ 
    34                         "defaults read %s/%s Label" % (directory, d))[1][0]] = \ 
    35                         "%s/%s"%(directory, daemon) 
    36                 except KeyError: #perhaps this could be more robust 
    37                     pass 
    38         try: 
    39             return plistMapping[entry.get('name')] 
    40         except KeyError: 
    41             return None 
     40        return plistMapping.get(entry.get('name'), None) 
    4241 
    4342    def os_version(self): 
     
    7877    def InstallService(self, entry): 
    7978        '''Enable or Disable launchd Item''' 
     79        name = entry.get('name') 
    8080        if entry.get('status') == 'on': 
     81            self.logger.error("Installing service %s" % name) 
    8182            cmdrc = self.cmd.run("/bin/launchctl load -w %s" % self.FindPlist(entry))[0] 
     83            cmdrc = self.cmd.run("/bin/launchctl start %s" % name) 
    8284        else: 
     85            self.logger.error("Uninstalling service %s" % name) 
     86            cmdrc = self.cmd.run("/bin/launchctl stop %s" % name) 
    8387            cmdrc = self.cmd.run("/bin/launchctl unload -w %s" % self.FindPlist(entry))[0] 
    84         return cmdrc == 0 
     88        return cmdrc[0] == 0 
    8589 
    8690    def Remove(self, svcs): 
     
    107111                self.logger.error("Insufficient information to restart service %s" % (entry.get('name'))) 
    108112            else: 
     113                name = entry.get('name') 
    109114                if entry.get('status') == 'on' and self.FindPlist(entry): 
    110                     self.logger.info("Reloading launchd  service %s" % (entry.get("name"))) 
     115                    self.logger.info("Reloading launchd  service %s" % name) 
    111116                    #stop? 
     117                    self.cmd.run("/bin/launchctl stop %s" % name) 
    112118                    self.cmd.run("/bin/launchctl unload -w %s" % (self.FindPlist(entry)))#what if it disappeared? how do we stop services that are currently running but the plist disappeared?! 
    113119                    self.cmd.run("/bin/launchctl load -w %s" % (self.FindPlist(entry))) 
     120                    self.cmd.run("/bin/launchctl start %s" % name) 
    114121                else: 
    115122                    #only if necessary.... 
     123                    self.cmd.run("/bin/launchctl stop %s" % name) 
    116124                    self.cmd.run("/bin/launchctl unload -w %s" % (self.FindPlist(entry))) 
    117125