--- a/common/migration.py Fri Oct 16 14:15:44 2009 +0200
+++ b/common/migration.py Fri Oct 16 14:37:11 2009 +0200
@@ -92,7 +92,9 @@
def __init__(self, config, interactive=True, verbosity=1):
self.config = config
- self.config.init_log(logthreshold=logging.ERROR, debug=True)
+ if config:
+ # no config on shell to a remote instance
+ self.config.init_log(logthreshold=logging.ERROR, debug=True)
# 0: no confirmation, 1: only main commands confirmed, 2 ask for everything
self.verbosity = verbosity
self.need_wrap = True
--- a/cwctl.py Fri Oct 16 14:15:44 2009 +0200
+++ b/cwctl.py Fri Oct 16 14:37:11 2009 +0200
@@ -685,10 +685,16 @@
class ShellCommand(Command):
- """Run an interactive migration shell. This is a python shell with
- enhanced migration commands predefined in the namespace. An additional
- argument may be given corresponding to a file containing commands to
- execute in batch mode.
+ """Run an interactive migration shell on an instance. This is a python shell
+ with enhanced migration commands predefined in the namespace. An additional
+ argument may be given corresponding to a file containing commands to execute
+ in batch mode.
+
+ By default it will connect to a local instance using an in memory
+ connection, unless -P option is specified, in which case you will be
+ connected through pyro. In the later case, you won't have access to
+ repository internals (session, etc...) so most migration commands won't be
+ available.
<instance>
the identifier of the instance to connect.
@@ -698,46 +704,72 @@
options = (
('system-only',
{'short': 'S', 'action' : 'store_true',
- 'default': False,
'help': 'only connect to the system source when the instance is '
'using multiple sources. You can\'t use this option and the '
- '--ext-sources option at the same time.'}),
+ '--ext-sources option at the same time.',
+ 'group': 'local'
+ }),
('ext-sources',
{'short': 'E', 'type' : 'csv', 'metavar': '<sources>',
- 'default': None,
'help': "For multisources instances, specify to which sources the \
repository should connect to for upgrading. When unspecified or 'all' given, \
will connect to all defined sources. If 'migration' is given, appropriate \
sources for migration will be automatically selected.",
+ 'group': 'local'
}),
('force',
{'short': 'f', 'action' : 'store_true',
- 'default' : False,
- 'help': 'don\'t check instance is up to date.'}
- ),
+ 'help': 'don\'t check instance is up to date.',
+ 'group': 'local'
+ }),
+
+ ('pyro',
+ {'short': 'P', 'action' : 'store_true',
+ 'help': 'connect to a running instance through Pyro.',
+ 'group': 'remote',
+ }),
+ ('pyro-ns-host',
+ {'short': 'H', 'type' : 'string', 'metavar': '<host[:port]>',
+ 'help': 'Pyro name server host. If not set, will be detected by '
+ 'using a broadcast query.',
+ 'group': 'remote'
+ }),
)
def run(self, args):
appid = pop_arg(args, 99, msg="No instance specified !")
- config = cwcfg.config_for(appid)
- if self.config.ext_sources:
- assert not self.config.system_only
- sources = self.config.ext_sources
- elif self.config.system_only:
- sources = ('system',)
+ if self.config.pyro:
+ from cubicweb.dbapi import connect
+ from cubicweb.server.utils import manager_userpasswd
+ from cubicweb.server.migractions import ServerMigrationHelper
+ login, pwd = manager_userpasswd(msg=None)
+ cnx = connect(appid, login=login, password=pwd,
+ host=self.config.pyro_ns_host, mulcnx=False)
+ repo = cnx._repo
+ mih = ServerMigrationHelper(None, repo=repo, cnx=cnx,
+ # hack so it don't try to load fs schema
+ schema=1)
else:
- sources = ('all',)
- config.set_sources_mode(sources)
- config.repairing = self.config.force
- mih = config.migration_handler()
+ config = cwcfg.config_for(appid)
+ if self.config.ext_sources:
+ assert not self.config.system_only
+ sources = self.config.ext_sources
+ elif self.config.system_only:
+ sources = ('system',)
+ else:
+ sources = ('all',)
+ config.set_sources_mode(sources)
+ config.repairing = self.config.force
+ mih = config.migration_handler()
if args:
for arg in args:
mih.process_script(arg)
else:
mih.interactive_shell()
- mih.shutdown()
+ if not self.config.pyro:
+ mih.shutdown()
class RecompileInstanceCatalogsCommand(InstanceCommand):
--- a/server/migractions.py Fri Oct 16 14:15:44 2009 +0200
+++ b/server/migractions.py Fri Oct 16 14:37:11 2009 +0200
@@ -54,6 +54,7 @@
def __init__(self, config, schema, interactive=True,
repo=None, cnx=None, verbosity=1, connect=True):
MigrationHelper.__init__(self, config, interactive, verbosity)
+ # no config on shell to a remote instance
if not interactive:
assert cnx
assert repo
@@ -61,7 +62,8 @@
assert repo
self._cnx = cnx
self.repo = repo
- self.session.data['rebuild-infered'] = False
+ if config is not None:
+ self.session.data['rebuild-infered'] = False
elif connect:
self.repo_connect()
if not schema:
@@ -233,7 +235,10 @@
@property
def session(self):
- return self.repo._get_session(self.cnx.sessionid)
+ if self.config is not None:
+ return self.repo._get_session(self.cnx.sessionid)
+ # no access to session on remote instance
+ return None
def commit(self):
if hasattr(self, '_cnx'):
@@ -268,8 +273,7 @@
@cached
def group_mapping(self):
"""cached group mapping"""
- self.session.set_pool()
- return ss.group_mapping(self.session)
+ return ss.group_mapping(self._cw)
def exec_event_script(self, event, cubepath=None, funcname=None,
*args, **kwargs):
@@ -981,7 +985,6 @@
:rtype: `Workflow`
"""
- self.session.set_pool() # ensure pool is set
wf = self.cmd_create_entity('Workflow', name=unicode(name),
**kwargs)
if not isinstance(wfof, (list, tuple)):
@@ -1001,7 +1004,6 @@
# XXX remove once cmd_add_[state|transition] are removed
def _get_or_create_wf(self, etypes):
- self.session.set_pool() # ensure pool is set
if not isinstance(etypes, (list, tuple)):
etypes = (etypes,)
rset = self.rqlexec('Workflow X WHERE X workflow_of ET, ET name %(et)s',
@@ -1041,16 +1043,14 @@
"""set or add (if `reset` is False) groups and conditions for a
transition
"""
- self.session.set_pool() # ensure pool is set
- tr = self.session.entity_from_eid(treid)
+ tr = self._cw.entity_from_eid(treid)
tr.set_transition_permissions(requiredgroups, conditions, reset)
if commit:
self.commit()
@deprecated('[3.5] use entity.fire_transition("transition") or entity.change_state("state")')
def cmd_set_state(self, eid, statename, commit=False):
- self.session.set_pool() # ensure pool is set
- self.session.entity_from_eid(eid).change_state(statename)
+ self._cw.entity_from_eid(eid).change_state(statename)
if commit:
self.commit()
@@ -1074,11 +1074,18 @@
# other data migration commands ###########################################
+ @property
+ def _cw(self):
+ session = self.session
+ if session is not None:
+ session.set_pool()
+ return session
+ return self.cnx.request()
+
def cmd_create_entity(self, etype, *args, **kwargs):
"""add a new entity of the given type"""
commit = kwargs.pop('commit', False)
- self.session.set_pool()
- entity = self.session.create_entity(etype, *args, **kwargs)
+ entity = self._cw.create_entity(etype, *args, **kwargs)
if commit:
self.commit()
return entity
@@ -1114,7 +1121,6 @@
if not isinstance(rql, (tuple, list)):
rql = ( (rql, kwargs), )
res = None
- self.session.set_pool()
for rql, kwargs in rql:
if kwargs:
msg = '%s (%s)' % (rql, kwargs)
@@ -1122,7 +1128,7 @@
msg = rql
if not ask_confirm or self.confirm('execute rql: %s ?' % msg):
try:
- res = self.session.execute(rql, kwargs, cachekey)
+ res = self._cw.execute(rql, kwargs, cachekey)
except Exception, ex:
if self.confirm('error: %s\nabort?' % ex):
raise
@@ -1211,9 +1217,8 @@
if self.ask_confirm:
if not self._h.confirm('execute rql: %s ?' % msg):
raise StopIteration
- self._h.session.set_pool()
try:
- rset = self._h.session.execute(rql, kwargs)
+ rset = self._h._cw.execute(rql, kwargs)
except Exception, ex:
if self._h.confirm('error: %s\nabort?' % ex):
raise