Package flumotion :: Package admin :: Package command :: Module main
[hide private]

Source Code for Module flumotion.admin.command.main

  1  # -*- Mode: Python -*- 
  2  # vi:si:et:sw=4:sts=4:ts=4 
  3   
  4  # Flumotion - a streaming media server 
  5  # Copyright (C) 2004,2005,2006,2007,2008,2009 Fluendo, S.L. 
  6  # Copyright (C) 2010,2011 Flumotion Services, S.A. 
  7  # All rights reserved. 
  8  # 
  9  # This file may be distributed and/or modified under the terms of 
 10  # the GNU Lesser General Public License version 2.1 as published by 
 11  # the Free Software Foundation. 
 12  # This file is distributed without any warranty; without even the implied 
 13  # warranty of merchantability or fitness for a particular purpose. 
 14  # See "LICENSE.LGPL" in the source distribution for more information. 
 15  # 
 16  # Headers in this file shall remain intact. 
 17   
 18  """ 
 19  main for flumotion-command 
 20  """ 
 21   
 22  import sys 
 23   
 24  from twisted.internet import reactor, defer 
 25   
 26  from flumotion.common import errors, log 
 27  from flumotion.admin import connections, admin 
 28   
 29  from flumotion.monitor.nagios import util 
 30   
 31  from flumotion.admin.command import component, manager, worker, common 
 32   
 33  from flumotion.common.common import version 
 34   
 35  __version__ = "$Rev: 6562 $" 
 36   
 37  # Because we run a reactor and use deferreds, the flow is slightly different 
 38  # from the usual Command flow. 
 39   
 40  # Nagios will first create a loginDeferred instance variable, which will 
 41  # allow subcommands to hook into the connection and schedule callbacks. 
 42   
 43  # Nagios will then parse the command line, allowing all subcommands to 
 44  # hook into this step with their respective handleOptions/parse/do methods. 
 45   
 46  # Subcommands are expected to use the ok/warning/critical methods to report 
 47  # a message and set the exit state. 
 48   
 49  # The Nagios root command will take care of stopping the reactor and returning 
 50  # the exit value. 
 51   
 52   
53 -class Command(util.LogCommand):
54 usage = "%prog %command" 55 description = "Run commands on Flumotion manager." 56 57 loginDeferred = None # deferred that fires upon connection 58 medium = None # medium giving access over the connection 59 60 subCommandClasses = [component.Component, manager.Manager, worker.Worker] 61
62 - def addOptions(self):
63 self.parser.add_option('-v', '--version', 64 action="store_true", dest="version", 65 help="show version information") 66 default = "user:test@localhost:7531" 67 self.parser.add_option('-m', '--manager', 68 action="store", type="string", dest="manager", 69 help="the manager connection string, " \ 70 "in the form [username[:password]@]host:port " \ 71 "(defaults to %s)" % default, 72 default=default) 73 self.parser.add_option('-T', '--transport', 74 action="store", type="string", dest="transport", 75 help="transport protocol to use (tcp/ssl) [default ssl]", 76 default="ssl")
77
78 - def handleOptions(self, options):
79 self.debug('command: handleOptions') 80 if options.version: 81 print version("flumotion-admin-command") 82 return 0
83
84 - def parse(self, argv):
85 # instantiated here so our subcommands can chain to it 86 self.loginDeferred = defer.Deferred() 87 88 self.debug('parse: chain up') 89 # chain up to parent first 90 # all subcommands will have a chance to chain up to the deferred 91 ret = util.LogCommand.parse(self, argv) 92 93 if ret is None: 94 self.debug('parse returned None, help/usage printed') 95 return ret 96 97 if ret: 98 self.debug('parse returned %r' % ret) 99 return ret 100 101 if self.parser.help_printed or self.parser.usage_printed: 102 return 0 103 104 # now connect 105 self.debug('parse: connect') 106 self.connect(self.options) 107 108 # chain up an exit after our child commands have had the chance. 109 110 def cb(result): 111 self.debug('parse: cb: done') 112 reactor.callLater(0, reactor.stop)
113 114 def eb(failure): 115 self.debug('parse: eb: failure %s' % 116 log.getFailureMessage(failure)) 117 if failure.check(common.Exited): 118 sys.stderr.write(failure.value.msg + '\n') 119 reactor.exitStatus = failure.value.code 120 else: 121 sys.stderr.write(log.getFailureMessage(failure) + '\n') 122 reactor.exitStatus = 1 123 124 reactor.callLater(0, reactor.stop) 125 return
126 127 self.loginDeferred.addCallback(cb) 128 self.loginDeferred.addErrback(eb) 129 130 # now run the reactor 131 self.debug('parse: run the reactor') 132 self.run() 133 self.debug('parse: ran the reactor') 134 135 return reactor.exitStatus 136
137 - def run(self):
138 """ 139 Run the reactor. 140 141 Resets .exitStatus, and returns its value after running the reactor. 142 """ 143 # run the reactor 144 145 self.debug('running reactor') 146 # We cheat by putting the exit code in the reactor. 147 reactor.exitStatus = 0 148 reactor.run() 149 self.debug('ran reactor') 150 151 return reactor.exitStatus
152
153 - def connect(self, options):
154 connection = connections.parsePBConnectionInfoRecent(options.manager, 155 use_ssl=options.transport == 'ssl') 156 157 # platform-3/trunk compatibility stuff to guard against 158 # gratuitous changes 159 try: 160 # platform-3 161 self.medium = admin.AdminModel(connection.authenticator) 162 self.debug("code is platform-3") 163 except TypeError: 164 # trunk 165 self.medium = admin.AdminModel() 166 self.debug("code is trunk") 167 168 if hasattr(self.medium, 'connectToHost'): 169 # platform-3 170 d = self.medium.connectToHost(connection.host, 171 connection.port, not connection.use_ssl) 172 else: 173 d = self.medium.connectToManager(connection) 174 175 d.addCallback(self._connectedCb) 176 d.addErrback(self._connectedEb)
177
178 - def _connectedCb(self, result):
179 self.debug('Connected to manager.') 180 self.loginDeferred.callback(result)
181
182 - def _connectedEb(self, failure):
183 if failure.check(errors.ConnectionFailedError): 184 sys.stderr.write("Unable to connect to manager.\n") 185 if failure.check(errors.ConnectionRefusedError): 186 sys.stderr.write("Manager refused connection.\n") 187 self.loginDeferred.errback(failure)
188 189
190 -def main(args):
191 c = Command() 192 try: 193 ret = c.parse(args[1:]) 194 except common.Exited, e: 195 ret = e.code 196 if ret == 0: 197 sys.stdout.write(e.msg + '\n') 198 else: 199 sys.stderr.write(e.msg + '\n') 200 201 return ret
202