00001
00002
00003
00004
00005 '''rtshell
00006
00007 Copyright (C) 2009-2014
00008 Geoffrey Biggs
00009 RT-Synthesis Research Group
00010 Intelligent Systems Research Institute,
00011 National Institute of Advanced Industrial Science and Technology (AIST),
00012 Japan
00013 All rights reserved.
00014 Licensed under the Eclipse Public License -v 1.0 (EPL)
00015 http://www.opensource.org/licenses/eclipse-1.0.txt
00016
00017 Implementation of the command for controlling managers.
00018
00019 '''
00020
00021
00022 import rtctree
00023 import rtctree.exceptions
00024 import rtctree.path
00025 import rtctree.tree
00026 import CosNaming
00027 import omniORB
00028 import optparse
00029 import os
00030 import os.path
00031 import re
00032 import OpenRTM_aist
00033 import RTC
00034 import RTM
00035 import sys
00036 import traceback
00037
00038 import rtshell
00039 import rts_exceptions
00040 import path
00041
00042
00043 class DirectManager(object):
00044 def __init__(self, address):
00045 self._connect(self._fix_address(address))
00046
00047 def _connect(self, address):
00048 if rtctree.ORB_ARGS_ENV_VAR in os.environ:
00049 orb_args = os.environ[ORB_ARGS_ENV_VAR].split(';')
00050 else:
00051 orb_args = []
00052 self._orb = omniORB.CORBA.ORB_init(orb_args)
00053 try:
00054 self._obj = self._orb.string_to_object(address)
00055 except omniORB.CORBA.ORB.InvalidName:
00056 raise rts_exceptions.BadMgrAddressError
00057 try:
00058 self._mgr = self._obj._narrow(RTM.Manager)
00059 except omniORB.CORBA.TRANSIENT, e:
00060 if e.args[0] == omniORB.TRANSIENT_ConnectFailed:
00061 raise rts_exceptions.BadMgrAddressError
00062 else:
00063 raise
00064 if omniORB.CORBA.is_nil(self._mgr):
00065 raise rts_exceptions.FailedToNarrowError
00066
00067 def _fix_address(self, address):
00068 parts = address.split(':')
00069 if len(parts) == 3:
00070
00071 host, sep, id_ = parts[2].partition('/')
00072 if not id_:
00073
00074 id_ = 'manager'
00075 parts[2] = '{0}:2810/{1}'.format(host, id_)
00076 elif len(parts) == 4:
00077
00078 port, sep, id_ = parts[3].partition('/')
00079 if not id_:
00080
00081 id_ = 'manager'
00082 parts[3] = '{0}/{1}'.format(port, id_)
00083 else:
00084 raise rts_exceptions.BadMgrAddressError
00085 return ':'.join(parts)
00086
00087 def load_module(self, path, init_func):
00088 try:
00089 if self._mgr.load_module(path, init_func) != RTC.RTC_OK:
00090 raise rtctree.exceptions.FailedToLoadModuleError(path)
00091 except omniORB.CORBA.UNKNOWN, e:
00092 if e.args[0] == UNKNOWN_UserException:
00093 raise rtctree.exceptions.FailedToLoadModuleError(path,
00094 'CORBA User Exception')
00095 else:
00096 raise
00097
00098 def unload_module(self, path):
00099 if self._mgr.unload_module(path) != RTC.RTC_OK:
00100 raise rtctree.exceptions.FailedToUnloadModuleError(path)
00101
00102 def create_component(self, module_name):
00103 if not self._mgr.create_component(module_name):
00104 raise rtctree.exceptions.FailedToCreateComponentError(module_name)
00105
00106 def delete_component(self, instance_name):
00107 if not self._mgr.delete_component(instance_name) != RTC.RTC_OK:
00108 raise rtctree.exceptions.FailedToDeleteComponentError(instance_name)
00109
00110
00111 def get_manager(cmd_path, full_path, tree=None):
00112 path, port = rtctree.path.parse_path(full_path)
00113 if port:
00114 raise rts_exceptions.NotAManagerError(cmd_path)
00115
00116 if not path[-1]:
00117
00118 path = path[:-1]
00119
00120 if not tree:
00121 tree = rtctree.tree.RTCTree(paths=path, filter=[path])
00122
00123 object = tree.get_node(path)
00124 if not object:
00125 raise rts_exceptions.NoSuchObjectError(cmd_path)
00126 if object.is_zombie:
00127 raise rts_exceptions.ZombieObjectError(cmd_path)
00128 if not object.is_manager:
00129 raise rts_exceptions.NotAManagerError(cmd_path)
00130 return tree, object
00131
00132 def load_module(mgr, module_info):
00133 module_path, init_func = module_info
00134 mgr.load_module(module_path, init_func)
00135
00136
00137 def unload_module(mgr, module_path):
00138 mgr.unload_module(module_path)
00139
00140
00141 def create_component(mgr, module_name):
00142 mgr.create_component(module_name)
00143
00144
00145 def delete_component(mgr, instance_name):
00146 mgr.delete_component(instance_name)
00147
00148
00149 def main(argv=None, tree=None):
00150 def cmd_cb(option, opt, val, parser):
00151 if not hasattr(parser.values, 'cmds'):
00152 setattr(parser.values, 'cmds', [])
00153 if opt == '-l' or opt == '--load':
00154
00155 items = re.split(':([^/]+)', val)
00156 if len(items) != 3:
00157 raise optparse.OptionValueError('No initialisation function '
00158 'specified.')
00159 parser.values.cmds.append((load_module, items[0:2]))
00160 elif opt == '-c' or opt == '--create':
00161 parser.values.cmds.append((create_component, val))
00162 elif opt == '-d' or opt == '--delete':
00163 parser.values.cmds.append((delete_component, val))
00164 elif opt == '-u' or opt == '--unload':
00165 parser.values.cmds.append((unload_module, val))
00166
00167 usage = '''Usage: %prog [options] <path>
00168 Create and remove components with a manager.'''
00169 version = rtshell.RTSH_VERSION
00170 parser = optparse.OptionParser(usage=usage, version=version)
00171 parser.add_option('-c', '--create', action='callback', callback=cmd_cb,
00172 type='string', help='Create a new component instance from the '
00173 'specified loaded module. Properties of the new component an be '
00174 'specified after the module name prefixed with a question mark. '
00175 'e.g. ConsoleIn?instance_name=bleg&another_param=value')
00176 parser.add_option('-d', '--delete', action='callback', callback=cmd_cb,
00177 type='string', help='Shut down and delete the specified component '
00178 'instance.')
00179 parser.add_option('-l', '--load', action='callback', callback=cmd_cb,
00180 type='string', help='Load the module into the manager. An '
00181 'initialisation function must be specified after the module path '
00182 'separated by a ":".')
00183 parser.add_option('-u', '--unload', action='callback', callback=cmd_cb,
00184 type='string', help='Unload the module from the manager.')
00185 parser.add_option('-v', '--verbose', dest='verbose', action='store_true',
00186 default=False,
00187 help='Output verbose information. [Default: %default]')
00188
00189 if argv:
00190 sys.argv = [sys.argv[0]] + argv
00191 options, args = parser.parse_args()
00192
00193 if len(args) != 1:
00194 print >>sys.stderr, '{0}: No manager specified.'.format(
00195 os.path.basename(sys.argv[0]))
00196 return 1
00197
00198 try:
00199 if args[0].startswith('corbaloc::'):
00200
00201 mgr = DirectManager(args[0])
00202 else:
00203
00204 full_path = path.cmd_path_to_full_path(args[0])
00205 tree, mgr = get_manager(args[0], full_path, tree)
00206
00207 if not hasattr(options, 'cmds'):
00208 print >>sys.stderr, '{0}: No commands specified.'.format(
00209 os.path.basename(sys.argv[0]))
00210 return 1
00211
00212 for c in options.cmds:
00213 c[0](mgr, c[1])
00214 except Exception, e:
00215 if options.verbose:
00216 traceback.print_exc()
00217 print >>sys.stderr, '{0}: {1}'.format(os.path.basename(sys.argv[0]), e)
00218 return 1
00219 return 0
00220
00221
00222
00223