Remove remote repository-access-through-pyro support
Modern methods such as the rqlcontroller cube + the cwclientlib
library are the way forward.
Closes #2919309.
--- a/cwctl.py Mon Dec 01 11:52:58 2014 +0100
+++ b/cwctl.py Tue Mar 03 14:57:34 2015 +0100
@@ -1,4 +1,4 @@
-# copyright 2003-2013 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
+# copyright 2003-2014 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
# contact http://www.logilab.fr/ -- mailto:contact@logilab.fr
#
# This file is part of CubicWeb.
@@ -401,7 +401,7 @@
if 'type' in odict
and odict.get('level') <= self.config.config_level)
for section in sections:
- if section not in ('main', 'email', 'pyro', 'web'):
+ if section not in ('main', 'email', 'web'):
print '\n' + underline_title('%s options' % section)
config.input_config(section, self.config.config_level)
# write down configuration
@@ -900,9 +900,7 @@
('repo-uri',
{'short': 'H', 'type' : 'string', 'metavar': '<protocol>://<[host][:port]>',
'help': 'URI of the CubicWeb repository to connect to. URI can be \
-pyro://[host:port] the Pyro name server host; if the pyro nameserver is not set, \
-it will be detected by using a broadcast query, a ZMQ URL or \
-inmemory:// (default) use an in-memory repository. THIS OPTION IS DEPRECATED, \
+a ZMQ URL or inmemory:// (default) use an in-memory repository. THIS OPTION IS DEPRECATED, \
directly give URI as instance id instead',
'group': 'remote'
}),
@@ -953,7 +951,7 @@
if self.config.repo_uri:
warn('[3.16] --repo-uri option is deprecated, directly give the URI as instance id',
DeprecationWarning)
- if urlparse(self.config.repo_uri).scheme in ('pyro', 'inmemory'):
+ if urlparse(self.config.repo_uri).scheme == 'inmemory':
appuri = '%s/%s' % (self.config.repo_uri.rstrip('/'), appuri)
from cubicweb.utils import parse_repo_uri
--- a/dbapi.py Mon Dec 01 11:52:58 2014 +0100
+++ b/dbapi.py Tue Mar 03 14:57:34 2015 +0100
@@ -119,13 +119,7 @@
* a simple instance id for in-memory connection
* a uri like scheme://host:port/instanceid where scheme may be one of
- 'pyro', 'inmemory' or 'zmqpickle'
-
- * if scheme is 'pyro', <host:port> determine the name server address. If
- not specified (e.g. 'pyro:///instanceid'), it will be detected through a
- broadcast query. The instance id is the name of the instance in the name
- server and may be prefixed by a group (e.g.
- 'pyro:///:cubicweb.instanceid')
+ 'inmemory' or 'zmqpickle'
* if scheme is handled by ZMQ (eg 'tcp'), you should not specify an
instance id
@@ -137,8 +131,7 @@
:cnxprops:
a :class:`ConnectionProperties` instance, allowing to specify
- the connection method (eg in memory or pyro). A Pyro connection will be
- established if you don't specify that argument.
+ the connection method (eg in memory or zmq).
:setvreg:
flag telling if a registry should be initialized for the connection.
@@ -166,14 +159,6 @@
database = kwargs.pop('host')
elif cnxprops and cnxprops.cnxtype == 'inmemory':
database = 'inmemory://' + database
- else:
- host = kwargs.pop('host', None)
- if host is None:
- host = ''
- group = kwargs.pop('group', None)
- if group is None:
- group = 'cubicweb'
- database = 'pyro://%s/%s.%s' % (host, group, database)
puri = urlparse(database)
method = puri.scheme.lower()
if method == 'inmemory':
@@ -735,10 +720,6 @@
@check_not_closed
def cursor(self, req=None):
"""Return a new Cursor Object using the connection.
-
- On pyro connection, you should get cursor after calling if
- load_appobjects method if desired (which you should call if you intend
- to use ORM abilities).
"""
if req is None:
req = self.request()
--- a/debian/control Mon Dec 01 11:52:58 2014 +0100
+++ b/debian/control Tue Mar 03 14:57:34 2015 +0100
@@ -58,7 +58,6 @@
| python-pysqlite2,
python-passlib
Recommends:
- pyro (<< 4.0.0),
cubicweb-documentation (= ${source:Version})
Suggests:
python-zmq
@@ -109,7 +108,6 @@
cubicweb-ctl (= ${source:Version}),
python-twisted-web
Recommends:
- pyro (<< 4.0.0),
cubicweb-documentation (= ${source:Version})
Description: twisted-based web interface for the CubicWeb framework
CubicWeb is a semantic web application framework.
--- a/debian/cubicweb-ctl.cubicweb.init Mon Dec 01 11:52:58 2014 +0100
+++ b/debian/cubicweb-ctl.cubicweb.init Tue Mar 03 14:57:34 2015 +0100
@@ -4,16 +4,14 @@
# Provides: cubicweb
# Required-Start: $remote_fs $syslog $local_fs $network
# Required-Stop: $remote_fs $syslog $local_fs $network
-# Should-Start: postgresql pyro-nsd
-# Should-Stop: postgresql pyro-nsd
+# Should-Start: postgresql
+# Should-Stop: postgresql
# Default-Start: 2 3 4 5
# Default-Stop: 0 1 6
# Short-Description: Start cubicweb application at boot time
### END INIT INFO
# FIXME Seems to be inadequate here
-# FIXME If related to pyro, try instead:
-# export PYRO_STORAGE="/tmp"
cd /tmp
# FIXME Work-around about the following lintian error
--- a/devtools/__init__.py Mon Dec 01 11:52:58 2014 +0100
+++ b/devtools/__init__.py Tue Mar 03 14:57:34 2015 +0100
@@ -237,10 +237,6 @@
def available_languages(self, *args):
return self.cw_languages()
- def pyro_enabled(self):
- # but export PYRO_MULTITHREAD=0 or you get problems with sqlite and
- # threads
- return True
# XXX merge with BaseApptestConfiguration ?
class ApptestConfiguration(BaseApptestConfiguration):
--- a/devtools/httptest.py Mon Dec 01 11:52:58 2014 +0100
+++ b/devtools/httptest.py Tue Mar 03 14:57:34 2015 +0100
@@ -1,4 +1,4 @@
-# copyright 2003-2010 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
+# copyright 2003-2014 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
# contact http://www.logilab.fr/ -- mailto:contact@logilab.fr
#
# This file is part of CubicWeb.
@@ -78,8 +78,6 @@
self.global_set_option('port', port) # force rewrite here
return 'http://127.0.0.1:%d/' % self['port']
- def pyro_enabled(self):
- return False
class CubicWebServerTC(CubicWebTC):
--- a/doc/3.21.rst Mon Dec 01 11:52:58 2014 +0100
+++ b/doc/3.21.rst Tue Mar 03 14:57:34 2015 +0100
@@ -14,3 +14,7 @@
* the user_callback api has been removed; people should use plain
ajax functions instead
+
+* the Pyro remote repository access method has been entirely removed
+ (emerging alternatives such as rqlcontroller and cwclientlib should
+ be used instead)
--- a/doc/book/en/admin/config.rst Mon Dec 01 11:52:58 2014 +0100
+++ b/doc/book/en/admin/config.rst Tue Mar 03 14:57:34 2015 +0100
@@ -14,7 +14,6 @@
For advanced features, have a look to:
- - `Pyro configuration`_
- `Cubicweb resources configuration`_
.. _`configure the database`: DatabaseInstallation_
@@ -22,7 +21,6 @@
.. _`MySql configuration`: MySqlConfiguration_
.. _`SQLServer configuration`: SQLServerConfiguration_
.. _`SQLite configuration`: SQLiteConfiguration_
-.. _`Pyro configuration`: PyroConfiguration_
.. _`Cubicweb resources configuration`: RessourcesConfiguration_
@@ -229,29 +227,3 @@
SQLite is great for testing and to play with cubicweb but is not suited for
production environments.
-
-.. _PyroConfiguration:
-
-Pyro configuration
-------------------
-
-Pyro name server
-~~~~~~~~~~~~~~~~
-
-If you want to use Pyro to access your instance remotely, or to have multi-source
-or distributed configuration, it is required to have a Pyro name server running
-on your network. By default it is detected by a broadcast request, but you can
-specify a location in the instance's configuration file.
-
-To do so, you need to :
-
-* be sure to have installed it (see :ref:`InstallDependencies`)
-
-* launch the pyro name server with `pyro-nsd start` before starting cubicweb
-
-* under debian, edit the file :file:`/etc/default/pyro-nsd` so that the name
- server pyro will be launched automatically when the machine fire up
-
-Note that you can use the pyro server without a running pyro nameserver.
-Refer to `pyro-ns-host` server configuration option for details.
-
--- a/doc/book/en/admin/index.rst Mon Dec 01 11:52:58 2014 +0100
+++ b/doc/book/en/admin/index.rst Tue Mar 03 14:57:34 2015 +0100
@@ -22,7 +22,6 @@
site-config
multisources
ldap
- pyro
migration
additional-tips
rql-logs
--- a/doc/book/en/admin/instance-config.rst Mon Dec 01 11:52:58 2014 +0100
+++ b/doc/book/en/admin/instance-config.rst Tue Mar 03 14:57:34 2015 +0100
@@ -110,32 +110,6 @@
file where all requests RQL executed by the server are written
-Pyro configuration for the instance
------------------------------------
-Web server side:
-
-:`pyro.pyro-instance-id`:
- pyro identifier of RQL server (e.g. the instance name)
-
-RQL server side:
-
-:`main.pyro-server`:
- boolean to switch on/off pyro server-side
-
-:`pyro.pyro-host`:
- pyro host:port number. If no port is specified, it is assigned
- automatically.
-
-RQL and web servers side:
-
-:`pyro.pyro-ns-host`:
- hostname hosting pyro server name. If no value is
- specified, it is located by a request from broadcast
-
-:`pyro.pyro-ns-group`:
- pyro group in which to save the instance (will default to 'cubicweb')
-
-
Configuring e-mail
------------------
RQL and web server side:
--- a/doc/book/en/admin/migration.rst Mon Dec 01 11:52:58 2014 +0100
+++ b/doc/book/en/admin/migration.rst Tue Mar 03 14:57:34 2015 +0100
@@ -8,7 +8,7 @@
**Aim** : do the migration for N cubicweb instances hosted on a server to another with no downtime.
-**Prerequisites** : have an explicit definition of the database host (not default or localhost). In our case, the database is hosted on another host. You are not migrating your pyro server. You are not using multisource (more documentation on that soon).
+**Prerequisites** : have an explicit definition of the database host (not default or localhost). In our case, the database is hosted on another host.
**Steps** :
@@ -21,26 +21,18 @@
scp /etc/cubicweb.d/ newmachine:/etc/cubicweb.d/
scp /etc/apache2/sites-available/ newmachine:/etc/apache2/sites-available/
-3. *on new machine* : give new ids to pyro registration so the new instances can register ::
-
- cd /etc/cubicweb.d/ ; sed -i.bck 's/^pyro-instance-id=.*$/\02/' */all-in-one.conf
-
-4. *on new machine* : start your instances ::
+3. *on new machine* : start your instances ::
cubicweb start
-5. *on new machine* : enable sites and modules for apache and start it, test it using by modifying your /etc/host file.
+4. *on new machine* : enable sites and modules for apache and start it, test it using by modifying your /etc/host file.
-6. change dns entry from your oldmachine to newmachine
+5. change dns entry from your oldmachine to newmachine
-7. shutdown your *old machine* (if it doesn't host other services or your database)
+6. shutdown your *old machine* (if it doesn't host other services or your database)
-8. That's it.
+7. That's it.
**Possible enhancements** : use right from the start a pound server behind your apache, that way you can add backends and smoothily migrate by shuting down backends that pound will take into account.
-Migrate apache & cubicweb with pyro
------------------------------------
-FIXME TODO
-
--- a/doc/book/en/admin/pyro.rst Mon Dec 01 11:52:58 2014 +0100
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,62 +0,0 @@
-.. _UsingPyro:
-
-Working with a distributed client (using Pyro)
-==============================================
-
-In some circumstances, it is practical to split the repository and
-web-client parts of the application for load-balancing reasons. Or
-one wants to access the repository from independant scripts to consult
-or update the database.
-
-Prerequisites
--------------
-
-For this to work, several steps have to be taken in order.
-
-You must first ensure that the appropriate software is installed and
-running (see :ref:`ConfigEnv`)::
-
- pyro-nsd -x -p 6969
-
-Then you have to set appropriate options in your configuration. For
-instance::
-
- pyro-server=yes
- pyro-ns-host=localhost:6969
-
- pyro-instance-id=myinstancename
-
-Connect to the CubicWeb repository from a python script
--------------------------------------------------------
-
-Assuming pyro-nsd is running and your instance is configured with ``pyro-server=yes``,
-you will be able to use :mod:`cubicweb.dbapi` api to initiate the connection.
-
-.. note::
- Regardless of whether your instance is pyro activated or not, you can still
- achieve this by using cubicweb-ctl shell scripts in a simpler way, as by default
- it creates a repository 'in-memory' instead of connecting through pyro. That
- also means you've to be on the host where the instance is running.
-
-Finally, the client (for instance a python script) must connect specifically
-as in the following example code:
-
-.. sourcecode:: python
-
- from cubicweb import dbapi
-
- cnx = dbapi.connect(database='instance-id', user='admin', password='admin')
- cnx.load_appobjects()
- cur = cnx.cursor()
- for name in (u'Personal', u'Professional', u'Computers'):
- cur.execute('INSERT Tag T: T name %(n)s', {'n': name})
- cnx.commit()
-
-Calling :meth:`cubicweb.dbapi.load_appobjects`, will populate the
-cubicweb registries (see :ref:`VRegistryIntro`) with the application
-objects installed on the host where the script runs. You'll then be
-allowed to use the ORM goodies and custom entity methods and views. Of
-course this is optional, without it you can still get the repository
-data through the connection but in a roughly way: only RQL cursors
-will be available, e.g. you can't even build entity objects from the
-result set.
--- a/doc/features_list.rst Mon Dec 01 11:52:58 2014 +0100
+++ b/doc/features_list.rst Tue Mar 03 14:57:34 2015 +0100
@@ -45,7 +45,6 @@
| configuration - user / groups handling | 3 | 1 |
| configuration - site configuration | 3 | 1 |
| configuration - distributed configuration | 2 | 1 |
-| configuration - pyro | 2 | 2 |
+--------------------------------------------------------------------+----+----+
| multi-sources - capabilities | NA | 0 |
| multi-sources - configuration | 2 | 0 |
--- a/etwist/server.py Mon Dec 01 11:52:58 2014 +0100
+++ b/etwist/server.py Tue Mar 03 14:57:34 2015 +0100
@@ -65,14 +65,6 @@
# when we have an in-memory repository, clean unused sessions every XX
# seconds and properly shutdown the server
if config['repository-uri'] == 'inmemory://':
- if config.pyro_enabled():
- # if pyro is enabled, we have to register to the pyro name
- # server, create a pyro daemon, and create a task to handle pyro
- # requests
- self.appli.repo.warning('remote repository access through pyro is deprecated')
- self.pyro_daemon = self.appli.repo.pyro_register()
- self.pyro_listen_timeout = 0.02
- self.appli.repo.looping_task(1, self.pyro_loop_event)
if config.mode != 'test':
reactor.addSystemEventTrigger('before', 'shutdown',
self.shutdown_event)
@@ -93,13 +85,6 @@
"""
self.appli.repo.shutdown()
- def pyro_loop_event(self):
- """listen for pyro events"""
- try:
- self.pyro_daemon.handleRequests(self.pyro_listen_timeout)
- except select.error:
- return
-
def getChild(self, path, request):
"""Indicate which resource to use to process down the URL's path"""
return self
--- a/etwist/twconfig.py Mon Dec 01 11:52:58 2014 +0100
+++ b/etwist/twconfig.py Tue Mar 03 14:57:34 2015 +0100
@@ -1,4 +1,4 @@
-# copyright 2003-2010 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
+# copyright 2003-2014 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
# contact http://www.logilab.fr/ -- mailto:contact@logilab.fr
#
# This file is part of CubicWeb.
@@ -17,9 +17,6 @@
# with CubicWeb. If not, see <http://www.gnu.org/licenses/>.
"""twisted server configurations:
-* the "twisted" configuration to get a web instance running in a standalone
- twisted web server which talk to a repository server using Pyro
-
* the "all-in-one" configuration to get a web instance running in a twisted
web server integrating a repository server in the same process (only available
if the repository part of the software is installed
@@ -82,13 +79,6 @@
the repository rather than the user running the command',
'group': 'main', 'level': WebConfiguration.mode == 'system'
}),
- ('pyro-server',
- {'type' : 'yn',
- # pyro is only a recommends by default, so don't activate it here
- 'default': False,
- 'help': 'run a pyro server',
- 'group': 'main', 'level': 1,
- }),
('webserver-threadpool-size',
{'type': 'int',
'default': 4,
@@ -117,9 +107,6 @@
cubicweb_appobject_path = WebConfigurationBase.cubicweb_appobject_path | ServerConfiguration.cubicweb_appobject_path
cube_appobject_path = WebConfigurationBase.cube_appobject_path | ServerConfiguration.cube_appobject_path
- def pyro_enabled(self):
- """tell if pyro is activated for the in memory repository"""
- return self['pyro-server']
CONFIGURATIONS.append(AllInOneConfiguration)
--- a/repoapi.py Mon Dec 01 11:52:58 2014 +0100
+++ b/repoapi.py Tue Mar 03 14:57:34 2015 +0100
@@ -1,4 +1,4 @@
-# copyright 2013-2013 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
+# copyright 2013-2014 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
# contact http://www.logilab.fr/ -- mailto:contact@logilab.fr
#
# This file is part of CubicWeb.
@@ -41,7 +41,7 @@
loading the repository for a client, eg web server, configuration).
The returned repository may be an in-memory repository or a proxy object
- using a specific RPC method, depending on the given URI (pyro or zmq).
+ using a specific RPC method, depending on the given URI.
"""
if uri is None:
return _get_inmemory_repo(config, vreg)
@@ -52,25 +52,6 @@
# me may have been called with a dummy 'inmemory://' uri ...
return _get_inmemory_repo(config, vreg)
- if protocol == 'pyroloc': # direct connection to the instance
- from logilab.common.pyro_ext import get_proxy
- uri = uri.replace('pyroloc', 'PYRO')
- return get_proxy(uri)
-
- if protocol == 'pyro': # connection mediated through the pyro ns
- from logilab.common.pyro_ext import ns_get_proxy
- path = appid.strip('/')
- if not path:
- raise ConnectionError(
- "can't find instance name in %s (expected to be the path component)"
- % uri)
- if '.' in path:
- nsgroup, nsid = path.rsplit('.', 1)
- else:
- nsgroup = 'cubicweb'
- nsid = path
- return ns_get_proxy(nsid, defaultnsgroup=nsgroup, nshost=hostport)
-
if protocol.startswith('zmqpickle-'):
from cubicweb.zmqclient import ZMQRepositoryClient
return ZMQRepositoryClient(uri)
--- a/server/cwzmq.py Mon Dec 01 11:52:58 2014 +0100
+++ b/server/cwzmq.py Tue Mar 03 14:57:34 2015 +0100
@@ -19,6 +19,7 @@
import cPickle
import traceback
+from time import localtime, mktime
from threading import Thread
from logging import getLogger
@@ -27,7 +28,6 @@
import zmq.eventloop.zmqstream
from cubicweb import set_log_methods
-from cubicweb.server.server import QuitEvent, Finished
ctx = zmq.Context()
@@ -38,6 +38,51 @@
assert address.startswith('zmqpickle-'), 'bad protocol string %s' % address
return address.split('-', 1)[1] # chop the `zmqpickle-` prefix
+
+class Finished(Exception):
+ """raise to remove an event from the event loop"""
+
+class TimeEvent:
+ """base event"""
+ # timefunc = staticmethod(localtime)
+ timefunc = localtime
+
+ def __init__(self, absolute=None, period=None):
+ # local time tuple
+ if absolute is None:
+ absolute = self.timefunc()
+ self.absolute = absolute
+ # optional period in seconds
+ self.period = period
+
+ def is_ready(self):
+ """return true if the event is ready to be fired"""
+ now = self.timefunc()
+ if self.absolute <= now:
+ return True
+ return False
+
+ def fire(self, server):
+ """fire the event
+ must be overridden by concrete events
+ """
+ raise NotImplementedError()
+
+ def update(self):
+ """update the absolute date for the event or raise a finished exception
+ """
+ if self.period is None:
+ raise Finished
+ self.absolute = localtime(mktime(self.absolute) + self.period)
+
+
+class QuitEvent(TimeEvent):
+ """stop the server"""
+ def fire(self, server):
+ server.repo.shutdown()
+ server.quiting = True
+
+
class ZMQComm(object):
"""
A simple ZMQ-based notification bus.
--- a/server/repository.py Mon Dec 01 11:52:58 2014 +0100
+++ b/server/repository.py Tue Mar 03 14:57:34 2015 +0100
@@ -24,7 +24,6 @@
* brings these classes all together to provide a single access
point to a cubicweb instance.
* handles session management
-* provides method for pyro registration, to call if pyro is enabled
"""
__docformat__ = "restructuredtext en"
@@ -151,8 +150,6 @@
class Repository(object):
"""a repository provides access to a set of persistent storages for
entities and relations
-
- XXX protect pyro access
"""
def __init__(self, config, tasks_manager=None, vreg=None):
@@ -162,17 +159,11 @@
self.vreg = vreg
self._tasks_manager = tasks_manager
- self.pyro_registered = False
- self.pyro_uri = None
- # every pyro client is handled in its own thread; map these threads to
- # the session we opened for them so we can clean up when they go away
- self._pyro_sessions = {}
self.app_instances_bus = NullEventBus()
self.info('starting repository from %s', self.config.apphome)
# dictionary of opened sessions
self._sessions = {}
-
# list of functions to be called at regular interval
# list of running threads
self._running_threads = []
@@ -435,10 +426,6 @@
except Exception:
self.exception('error while closing %s' % cnxset)
continue
- if self.pyro_registered:
- if self._use_pyrons():
- pyro_unregister(self.config)
- self.pyro_uri = None
hits, misses = self.querier.cache_hit, self.querier.cache_miss
try:
self.info('rql st cache hit/miss: %s/%s (%s%% hits)', hits, misses,
@@ -662,12 +649,6 @@
# try to get a user object
user = self.authenticate_user(cnx, login, **kwargs)
session = Session(user, self, cnxprops)
- if threading.currentThread() in self._pyro_sessions:
- # assume no pyro client does one get_repository followed by
- # multiple repo.connect
- assert self._pyro_sessions[threading.currentThread()] == None
- self.debug('record session %s', session)
- self._pyro_sessions[threading.currentThread()] = session
user._cw = user.cw_rset.req = session
user.cw_clear_relation_cache()
self._sessions[session.sessionid] = session
@@ -697,10 +678,6 @@
try:
rset = self.querier.execute(session, rqlstring, args,
build_descr)
- # NOTE: the web front will (re)build it when needed
- # e.g in facets
- # Zeroed to avoid useless overhead with pyro
- rset._rqlst = None
return rset
except (ValidationError, Unauthorized, RQLSyntaxError):
raise
@@ -810,8 +787,6 @@
# done during `session_close` hooks
cnx.commit()
session.close()
- if threading.currentThread() in self._pyro_sessions:
- self._pyro_sessions[threading.currentThread()] = None
del self._sessions[sessionid]
self.info('closed session %s for user %s', sessionid, session.user.login)
@@ -1349,79 +1324,12 @@
eidfrom=subject, rtype=rtype, eidto=object)
- # pyro handling ###########################################################
-
- @property
- @cached
- def pyro_appid(self):
- from logilab.common import pyro_ext as pyro
- config = self.config
- appid = '%s.%s' % pyro.ns_group_and_id(
- config['pyro-instance-id'] or config.appid,
- config['pyro-ns-group'])
- # ensure config['pyro-instance-id'] is a full qualified pyro name
- config['pyro-instance-id'] = appid
- return appid
-
- def _use_pyrons(self):
- """return True if the pyro-ns-host is set to something else
- than NO_PYRONS, meaning we want to go through a pyro
- nameserver"""
- return self.config['pyro-ns-host'] != 'NO_PYRONS'
-
- def pyro_register(self, host=''):
- """register the repository as a pyro object"""
- from logilab.common import pyro_ext as pyro
- daemon = pyro.register_object(self, self.pyro_appid,
- daemonhost=self.config['pyro-host'],
- nshost=self.config['pyro-ns-host'],
- use_pyrons=self._use_pyrons())
- self.info('repository registered as a pyro object %s', self.pyro_appid)
- self.pyro_uri = pyro.get_object_uri(self.pyro_appid)
- self.info('pyro uri is: %s', self.pyro_uri)
- self.pyro_registered = True
- # register a looping task to regularly ensure we're still registered
- # into the pyro name server
- if self._use_pyrons():
- self.looping_task(60*10, self._ensure_pyro_ns)
- pyro_sessions = self._pyro_sessions
- # install hacky function to free cnxset
- def handleConnection(conn, tcpserver, sessions=pyro_sessions):
- sessions[threading.currentThread()] = None
- return tcpserver.getAdapter().__class__.handleConnection(tcpserver.getAdapter(), conn, tcpserver)
- daemon.getAdapter().handleConnection = handleConnection
- def removeConnection(conn, sessions=pyro_sessions):
- daemon.__class__.removeConnection(daemon, conn)
- session = sessions.pop(threading.currentThread(), None)
- if session is None:
- # client was not yet connected to the repo
- return
- if not session.closed:
- self.close(session.sessionid)
- daemon.removeConnection = removeConnection
- return daemon
-
- def _ensure_pyro_ns(self):
- if not self._use_pyrons():
- return
- from logilab.common import pyro_ext as pyro
- pyro.ns_reregister(self.pyro_appid, nshost=self.config['pyro-ns-host'])
- self.info('repository re-registered as a pyro object %s',
- self.pyro_appid)
# these are overridden by set_log_methods below
# only defining here to prevent pylint from complaining
info = warning = error = critical = exception = debug = lambda msg, *a, **kw: None
-
-def pyro_unregister(config):
- """unregister the repository from the pyro name server"""
- from logilab.common.pyro_ext import ns_unregister
- appid = config['pyro-instance-id'] or config.appid
- ns_unregister(appid, config['pyro-ns-group'], config['pyro-ns-host'])
-
-
from logging import getLogger
from cubicweb import set_log_methods
set_log_methods(Repository, getLogger('cubicweb.repository'))
--- a/server/server.py Mon Dec 01 11:52:58 2014 +0100
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,140 +0,0 @@
-# copyright 2003-2013 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
-# contact http://www.logilab.fr/ -- mailto:contact@logilab.fr
-#
-# This file is part of CubicWeb.
-#
-# CubicWeb is free software: you can redistribute it and/or modify it under the
-# terms of the GNU Lesser General Public License as published by the Free
-# Software Foundation, either version 2.1 of the License, or (at your option)
-# any later version.
-#
-# CubicWeb is distributed in the hope that it will be useful, but WITHOUT
-# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
-# FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
-# details.
-#
-# You should have received a copy of the GNU Lesser General Public License along
-# with CubicWeb. If not, see <http://www.gnu.org/licenses/>.
-"""Pyro RQL server"""
-
-__docformat__ = "restructuredtext en"
-
-import select
-from time import localtime, mktime
-
-from cubicweb.server.utils import TasksManager
-from cubicweb.server.repository import Repository
-
-class Finished(Exception):
- """raise to remove an event from the event loop"""
-
-class TimeEvent:
- """base event"""
- # timefunc = staticmethod(localtime)
- timefunc = localtime
-
- def __init__(self, absolute=None, period=None):
- # local time tuple
- if absolute is None:
- absolute = self.timefunc()
- self.absolute = absolute
- # optional period in seconds
- self.period = period
-
- def is_ready(self):
- """return true if the event is ready to be fired"""
- now = self.timefunc()
- if self.absolute <= now:
- return True
- return False
-
- def fire(self, server):
- """fire the event
- must be overridden by concrete events
- """
- raise NotImplementedError()
-
- def update(self):
- """update the absolute date for the event or raise a finished exception
- """
- if self.period is None:
- raise Finished
- self.absolute = localtime(mktime(self.absolute) + self.period)
-
-
-class QuitEvent(TimeEvent):
- """stop the server"""
- def fire(self, server):
- server.repo.shutdown()
- server.quiting = True
-
-
-class RepositoryServer(object):
-
- def __init__(self, config):
- """make the repository available as a PyRO object"""
- self.config = config
- self.repo = Repository(config, TasksManager())
- self.ns = None
- self.quiting = None
- # event queue
- self.events = []
-
- def add_event(self, event):
- """add an event to the loop"""
- self.info('adding event %s', event)
- self.events.append(event)
-
- def trigger_events(self):
- """trigger ready events"""
- for event in self.events[:]:
- if event.is_ready():
- self.info('starting event %s', event)
- event.fire(self)
- try:
- event.update()
- except Finished:
- self.events.remove(event)
-
- def run(self, req_timeout=5.0):
- """enter the service loop"""
- # start repository looping tasks
- self.repo.start_looping_tasks()
- while self.quiting is None:
- try:
- self.daemon.handleRequests(req_timeout)
- except select.error:
- continue
- finally:
- self.trigger_events()
-
- def quit(self):
- """stop the server"""
- self.add_event(QuitEvent())
-
- def connect(self, host='', port=0):
- """the connect method on the repository only register to pyro if
- necessary
- """
- self.daemon = self.repo.pyro_register(host)
-
- # server utilitities ######################################################
-
- def install_sig_handlers(self):
- """install signal handlers"""
- import signal
- self.info('installing signal handlers')
- signal.signal(signal.SIGINT, lambda x, y, s=self: s.quit())
- signal.signal(signal.SIGTERM, lambda x, y, s=self: s.quit())
-
-
- # these are overridden by set_log_methods below
- # only defining here to prevent pylint from complaining
- @classmethod
- def info(cls, msg, *a, **kw):
- pass
-
-from logging import getLogger
-from cubicweb import set_log_methods
-LOGGER = getLogger('cubicweb.reposerver')
-set_log_methods(RepositoryServer, LOGGER)
--- a/server/serverconfig.py Mon Dec 01 11:52:58 2014 +0100
+++ b/server/serverconfig.py Tue Mar 03 14:57:34 2015 +0100
@@ -1,4 +1,4 @@
-# copyright 2003-2013 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
+# copyright 2003-2014 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
# contact http://www.logilab.fr/ -- mailto:contact@logilab.fr
#
# This file is part of CubicWeb.
@@ -197,36 +197,6 @@
notified of every changes.',
'group': 'email', 'level': 2,
}),
- # pyro services config
- ('pyro-host',
- {'type' : 'string',
- 'default': None,
- 'help': 'Pyro server host, if not detectable correctly through \
-gethostname(). It may contains port information using <host>:<port> notation, \
-and if not set, it will be choosen randomly',
- 'group': 'pyro', 'level': 3,
- }),
- ('pyro-instance-id',
- {'type' : 'string',
- 'default': lgconfig.Method('default_instance_id'),
- 'help': 'identifier of the CubicWeb instance in the Pyro name server',
- 'group': 'pyro', 'level': 1,
- }),
- ('pyro-ns-host',
- {'type' : 'string',
- 'default': '',
- 'help': 'Pyro name server\'s host. If not set, will be detected by a \
-broadcast query. It may contains port information using <host>:<port> notation. \
-Use "NO_PYRONS" to create a Pyro server but not register to a pyro nameserver',
- 'group': 'pyro', 'level': 1,
- }),
- ('pyro-ns-group',
- {'type' : 'string',
- 'default': 'cubicweb',
- 'help': 'Pyro name server\'s group where the repository will be \
-registered.',
- 'group': 'pyro', 'level': 1,
- }),
# zmq services config
('zmq-repository-address',
{'type' : 'string',
@@ -350,10 +320,6 @@
stream.write('[%s]\n%s\n' % (section, generate_source_config(sconfig)))
restrict_perms_to_user(sourcesfile)
- def pyro_enabled(self):
- """pyro is always enabled in standalone repository configuration"""
- return True
-
def load_schema(self, expand_cubes=False, **kwargs):
from cubicweb.schema import CubicWebSchemaLoader
if expand_cubes:
--- a/server/serverctl.py Mon Dec 01 11:52:58 2014 +0100
+++ b/server/serverctl.py Tue Mar 03 14:57:34 2015 +0100
@@ -167,11 +167,6 @@
if not automatic:
print underline_title('Configuring the repository')
config.input_config('email', inputlevel)
- # ask for pyro configuration if pyro is activated and we're not
- # using a all-in-one config, in which case this is done by the web
- # side command handler
- if config.pyro_enabled() and config.name != 'all-in-one':
- config.input_config('pyro', inputlevel)
print '\n'+underline_title('Configuring the sources')
sourcesfile = config.sources_file()
# hack to make Method('default_instance_id') usable in db option defs
@@ -321,12 +316,7 @@
cfgname = 'repository'
def poststop(self):
- """if pyro is enabled, ensure the repository is correctly unregistered
- """
- if self.config.pyro_enabled():
- from cubicweb.server.repository import pyro_unregister
- pyro_unregister(self.config)
-
+ pass
# repository specific commands ################################################
@@ -689,7 +679,7 @@
class StartRepositoryCommand(Command):
"""Start a CubicWeb RQL server for a given instance.
- The server will be remotely accessible through pyro or ZMQ
+ The server will be remotely accessible through ZMQ
<instance>
the identifier of the instance to initialize.
@@ -709,23 +699,18 @@
('address',
{'short': 'a', 'type': 'string', 'metavar': '<protocol>://<host>:<port>',
'default': '',
- 'help': ('specify a ZMQ URI on which to bind, or use "pyro://"'
- 'to create a pyro-based repository'),
+ 'help': ('specify a ZMQ URI on which to bind'),
}),
)
def create_repo(self, config):
address = self['address']
if not address:
- address = config.get('zmq-repository-address') or 'pyro://'
- if address.startswith('pyro://'):
- from cubicweb.server.server import RepositoryServer
- return RepositoryServer(config), config['host']
- else:
- from cubicweb.server.utils import TasksManager
- from cubicweb.server.cwzmq import ZMQRepositoryServer
- repo = Repository(config, TasksManager())
- return ZMQRepositoryServer(repo), address
+ address = config.get('zmq-repository-address')
+ from cubicweb.server.utils import TasksManager
+ from cubicweb.server.cwzmq import ZMQRepositoryServer
+ repo = Repository(config, TasksManager())
+ return ZMQRepositoryServer(repo), address
def run(self, args):
from logilab.common.daemon import daemonize, setugid
--- a/server/test/unittest_repository.py Mon Dec 01 11:52:58 2014 +0100
+++ b/server/test/unittest_repository.py Tue Mar 03 14:57:34 2015 +0100
@@ -312,55 +312,6 @@
ownedby = schema.rschema('owned_by')
self.assertEqual(ownedby.objects('CWEType'), ('CWUser',))
- def test_pyro(self):
- import Pyro
- Pyro.config.PYRO_MULTITHREADED = 0
- done = []
- self.repo.config.global_set_option('pyro-ns-host', 'NO_PYRONS')
- daemon = self.repo.pyro_register()
- try:
- uri = self.repo.pyro_uri.replace('PYRO', 'pyroloc')
- # the client part has to be in the thread due to sqlite limitations
- t = threading.Thread(target=self._pyro_client, args=(uri, done))
- t.start()
- while not done:
- daemon.handleRequests(1.0)
- t.join(1)
- if t.isAlive():
- self.fail('something went wrong, thread still alive')
- finally:
- repository.pyro_unregister(self.repo.config)
- from logilab.common import pyro_ext
- pyro_ext._DAEMONS.clear()
-
-
- def _pyro_client(self, uri, done):
- cnx = connect(uri,
- u'admin', password='gingkow',
- initlog=False) # don't reset logging configuration
- try:
- cnx.load_appobjects(subpath=('entities',))
- # check we can get the schema
- schema = cnx.get_schema()
- self.assertTrue(cnx.vreg)
- self.assertTrue('etypes'in cnx.vreg)
- cu = cnx.cursor()
- rset = cu.execute('Any U,G WHERE U in_group G')
- user = iter(rset.entities()).next()
- self.assertTrue(user._cw)
- self.assertTrue(user._cw.vreg)
- from cubicweb.entities import authobjs
- self.assertIsInstance(user._cw.user, authobjs.CWUser)
- # make sure the tcp connection is closed properly; yes, it's disgusting.
- adapter = cnx._repo.adapter
- cnx.close()
- adapter.release()
- done.append(True)
- finally:
- # connect monkey patch some method by default, remove them
- multiple_connections_unfix()
-
-
def test_zmq(self):
try:
import zmq
--- a/server/test/unittest_tools.py Mon Dec 01 11:52:58 2014 +0100
+++ b/server/test/unittest_tools.py Tue Mar 03 14:57:34 2015 +0100
@@ -23,7 +23,6 @@
class ImportTC(TestCase):
def test(self):
# the minimal test: module is importable...
- import cubicweb.server.server
import cubicweb.server.checkintegrity
import cubicweb.server.serverctl
--- a/test/unittest_utils.py Mon Dec 01 11:52:58 2014 +0100
+++ b/test/unittest_utils.py Tue Mar 03 14:57:34 2015 +0100
@@ -58,10 +58,6 @@
parse_repo_uri('myapp'))
self.assertEqual(('inmemory', None, 'myapp'),
parse_repo_uri('inmemory://myapp'))
- self.assertEqual(('pyro', 'pyro-ns-host:pyro-ns-port', '/myapp'),
- parse_repo_uri('pyro://pyro-ns-host:pyro-ns-port/myapp'))
- self.assertEqual(('pyroloc', 'host:port', '/appkey'),
- parse_repo_uri('pyroloc://host:port/appkey'))
self.assertEqual(('zmqpickle-tcp', '127.0.0.1:666', ''),
parse_repo_uri('zmqpickle-tcp://127.0.0.1:666'))
with self.assertRaises(NotImplementedError):
--- a/transaction.py Mon Dec 01 11:52:58 2014 +0100
+++ b/transaction.py Tue Mar 03 14:57:34 2015 +0100
@@ -1,4 +1,4 @@
-# copyright 2003-2012 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
+# copyright 2003-2014 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
# contact http://www.logilab.fr/ -- mailto:contact@logilab.fr
#
# This file is part of CubicWeb.
@@ -15,13 +15,7 @@
#
# You should have received a copy of the GNU Lesser General Public License along
# with CubicWeb. If not, see <http://www.gnu.org/licenses/>.
-"""undoable transaction objects.
-
-
-This module is in the cubicweb package and not in cubicweb.server because those
-objects should be accessible to client through pyro, where the cubicweb.server
-package may not be installed.
-"""
+""" undoable transaction objects. """
__docformat__ = "restructuredtext en"
_ = unicode
--- a/utils.py Mon Dec 01 11:52:58 2014 +0100
+++ b/utils.py Tue Mar 03 14:57:34 2015 +0100
@@ -21,7 +21,6 @@
__docformat__ = "restructuredtext en"
-import sys
import decimal
import datetime
import random
@@ -608,7 +607,6 @@
""" transform a command line uri into a (protocol, hostport, appid), e.g:
<myapp> -> 'inmemory', None, '<myapp>'
inmemory://<myapp> -> 'inmemory', None, '<myapp>'
- pyro://[host][:port] -> 'pyro', 'host:port', None
zmqpickle://[host][:port] -> 'zmqpickle', 'host:port', None
"""
parseduri = urlparse(uri)
@@ -617,7 +615,7 @@
return ('inmemory', None, parseduri.path)
if scheme == 'inmemory':
return (scheme, None, parseduri.netloc)
- if scheme in ('pyro', 'pyroloc') or scheme.startswith('zmqpickle-'):
+ if scheme.startswith('zmqpickle-'):
return (scheme, parseduri.netloc, parseduri.path)
raise NotImplementedError('URI protocol not implemented for `%s`' % uri)
--- a/web/webctl.py Mon Dec 01 11:52:58 2014 +0100
+++ b/web/webctl.py Tue Mar 03 14:57:34 2015 +0100
@@ -46,9 +46,6 @@
if not automatic:
print '\n' + underline_title('Generic web configuration')
config = self.config
- if config['repository-uri'].startswith('pyro://') or config.pyro_enabled():
- print '\n' + underline_title('Pyro configuration')
- config.input_config('pyro', inputlevel)
config.input_config('web', inputlevel)
if ASK.confirm('Allow anonymous access ?', False):
config.global_set_option('anonymous-user', 'anon')
--- a/zmqclient.py Mon Dec 01 11:52:58 2014 +0100
+++ b/zmqclient.py Tue Mar 03 14:57:34 2015 +0100
@@ -1,4 +1,4 @@
-# copyright 2003-2012 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
+# copyright 2003-2014 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
# contact http://www.logilab.fr/ -- mailto:contact@logilab.fr
#
# This file is part of CubicWeb.
@@ -15,7 +15,7 @@
#
# You should have received a copy of the GNU Lesser General Public License along
# with CubicWeb. If not, see <http://www.gnu.org/licenses/>.
-"""Source to query another RQL repository using pyro"""
+"""Source to query another RQL repository using ZMQ"""
__docformat__ = "restructuredtext en"
_ = unicode