Remove remote repository-access-through-pyro support
authorAurelien Campeas <aurelien.campeas@logilab.fr>
Tue, 03 Mar 2015 14:57:34 +0100
changeset 10235 684215aca046
parent 10232 cda1bdc3652e
child 10236 ef3059a692cb
Remove remote repository-access-through-pyro support Modern methods such as the rqlcontroller cube + the cwclientlib library are the way forward. Closes #2919309.
cwctl.py
dbapi.py
debian/control
debian/cubicweb-ctl.cubicweb.init
devtools/__init__.py
devtools/httptest.py
doc/3.21.rst
doc/book/en/admin/config.rst
doc/book/en/admin/index.rst
doc/book/en/admin/instance-config.rst
doc/book/en/admin/migration.rst
doc/book/en/admin/pyro.rst
doc/features_list.rst
etwist/server.py
etwist/twconfig.py
repoapi.py
server/cwzmq.py
server/repository.py
server/server.py
server/serverconfig.py
server/serverctl.py
server/test/unittest_repository.py
server/test/unittest_tools.py
test/unittest_utils.py
transaction.py
utils.py
web/webctl.py
zmqclient.py
--- 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