Permalink
Browse files

Big reorganization:

- Move all packages into "src" directory.

- Use setuptools rather than distutils for setup.py

- Add configuration knob for specifying rpc interface namespaces.
  • Loading branch information...
1 parent cf1e15b commit dbc77205e48dedc54448b111511eaa2900fe39ed @mcdonc mcdonc committed Aug 1, 2007
Showing with 93 additions and 61 deletions.
  1. +3 −0 sample.conf
  2. +13 −26 setup.py
  3. +1 −1 src/supervisor/__init__.py
  4. +14 −1 src/supervisor/http.py
  5. +31 −1 src/supervisor/options.py
  6. +23 −22 src/supervisor/tests.py
  7. +8 −10 src/supervisor/xmlrpc.py
View
3 sample.conf
@@ -23,6 +23,9 @@ minprocs=200 ; (min. avail process descriptors;default 200)
;environment=KEY=value ; (key value pairs to add to environment)
;strip_ansi=false ; (strip ansi escape codes from stdout; def. false)
+[rpcinterface:supervisor]
+supervisor.rpcinterface_factory = supervisor.xmlrpc:make_main_rpcinterface
+
[supervisorctl]
serverurl=unix:///tmp/supervisor.sock ; use a unix:// URL for a unix socket
;serverurl=http://127.0.0.1:9001 ; use an http:// url to specify an inet socket
View
39 setup.py
@@ -1,8 +1,10 @@
__revision__ = '$Id$'
+import os
import sys
import string
+
version, extra = string.split(sys.version, ' ', 1)
maj, minor = string.split(version, '.', 1)
@@ -11,8 +13,8 @@
"install it using version %s. Please install with a "
"supported version" % version)
-from distutils.core import setup
-
+from setuptools import setup, find_packages
+here = os.path.abspath(os.path.normpath(os.path.dirname(__file__)))
DESC = """\
Supervisor is a client/server system that allows its users to
@@ -29,13 +31,11 @@
'Topic :: System :: Systems Administration',
]
-from options import VERSION
-
dist = setup(
name = 'supervisor',
- version = VERSION,
- license = 'ZPL/BSD (see LICENSES.txt)',
- url = 'http://www.plope.com/software',
+ version = '2.3b1',
+ license = 'ZPL 2.0/BSD (see LICENSES.txt)',
+ url = 'http://www.plope.com/software/supervisor2',
description = "A system for controlling process state under UNIX",
long_description= DESC,
platform = 'UNIX',
@@ -44,23 +44,10 @@
author_email = "chrism@plope.com",
maintainer = "Chris McDonough",
maintainer_email = "chrism@plope.com",
- scripts=['supervisord', 'supervisorctl'],
- packages = ['supervisor', 'supervisor.medusa', 'supervisor.meld3',
- 'supervisor.meld3.elementtree'],
- package_dir = {'supervisor':'.'},
- # package_data doesn't work under 2.3
- package_data= {'supervisor':['ui/*.gif', 'ui/*.css', 'ui/*.html']},
+ package_dir = {'':'src'},
+ packages = find_packages(os.path.join(here, 'src')),
+ scripts=['src/supervisor/supervisord', 'src/supervisor/supervisorctl'],
+ include_package_data = True,
+ zip_safe = False,
+ namespace_packages = ['supervisor'],
)
-
-if __name__ == '__main__':
- # if pre-2.4 distutils was a joke, i suspect nobody laughed
- if minor[0] <= '3':
- if 'install' in sys.argv:
- from distutils import dir_util
- import os
- pkg_dir = dist.command_obj['install'].install_purelib
- for dirname in ['ui']:
- dir_util.copy_tree(
- os.path.join(dirname),
- os.path.join(pkg_dir, 'supervisor', dirname)
- )
View
2 src/supervisor/__init__.py
@@ -1 +1 @@
-# poof.
+__import__('pkg_resources').declare_namespace(__name__)
View
15 src/supervisor/http.py
@@ -748,8 +748,21 @@ def log(self, msg):
raise ValueError('Cannot determine socket type %r' % family)
from xmlrpc import supervisor_xmlrpc_handler
+ from xmlrpc import SystemNamespaceRPCInterface
from web import supervisor_ui_handler
- xmlrpchandler = supervisor_xmlrpc_handler(supervisord)
+ rpcfactories = options.configroot.supervisord.rpcinterface_factories
+
+ subinterfaces = []
+ for name, factory, d in rpcfactories:
+ try:
+ inst = factory(supervisord, **d)
+ except:
+ import traceback; traceback.print_exc()
+ raise ValueError('Could not make %s rpc interface' % name)
+ subinterfaces.append((name, inst))
+
+ subinterfaces.append(('system', SystemNamespaceRPCInterface(subinterfaces)))
+ xmlrpchandler = supervisor_xmlrpc_handler(supervisord, subinterfaces)
tailhandler = logtail_handler(supervisord)
maintailhandler = mainlogtail_handler(supervisord)
here = os.path.abspath(os.path.dirname(__file__))
View
32 src/supervisor/options.py
@@ -17,11 +17,12 @@
import grp
import resource
import stat
+import pkg_resources
from fcntl import fcntl
from fcntl import F_SETFL, F_GETFL
-VERSION = '2.2b1'
+VERSION = '2.3b1'
class FileHandler(logging.StreamHandler):
"""File handler which supports reopening of logs.
@@ -674,6 +675,7 @@ def read_config(self, fp):
section.environment = datatypes.dict_of_key_value_pairs(environment)
section.programs = self.programs_from_config(config)
+ section.rpcinterface_factories = self.rpcinterfaces_from_config(config)
return section
def programs_from_config(self, config):
@@ -749,6 +751,34 @@ def programs_from_config(self, config):
programs.sort() # asc by priority
return programs
+ def import_spec(self, spec):
+ return pkg_resources.EntryPoint.parse("x="+spec).load(False)
+
+ def rpcinterfaces_from_config(self, config):
+ factories = []
+ factory_key = 'supervisor.rpcinterface_factory'
+
+ for section in config.sections():
+ if not section.startswith('rpcinterface:'):
+ continue
+ options = config.options(section)
+ name = section.split(':', 1)[1]
+ realoptions = []
+ factory_spec = config.saneget(section, factory_key, None)
+ if factory_spec is None:
+ raise ValueError('section [%s] does not specify a %s' %
+ (section, factory_key))
+ try:
+ factory = self.import_spec(factory_spec)
+ except ImportError:
+ raise ValueError('%s cannot be resolved within [%s]' % (
+ factory_spec, section))
+ items = config.items(section)
+ items.remove((factory_key, factory_spec))
+ factories.append((name, factory, dict(items)))
+
+ return factories
+
def daemonize(self):
# To daemonize, we need to become the leader of our own session
# (process) group. If we do not, signals sent to our
View
45 src/supervisor/tests.py
@@ -347,31 +347,27 @@ def _assertRPCError(self, code, callable, *args, **kw):
class MainXMLRPCInterfaceTests(TestBase):
def _getTargetClass(self):
- return xmlrpc.RPCInterface
+ return xmlrpc.RootRPCInterface
def _makeOne(self, *args, **kw):
return self._getTargetClass()(*args, **kw)
def test_ctor(self):
- supervisord = DummySupervisor()
- interface = self._makeOne(supervisord)
- self.assertEqual(interface.supervisor.supervisord, supervisord)
- self.failUnless(interface.system)
+ interface = self._makeOne([('supervisor', None)])
+ self.assertEqual(interface.supervisor, None)
def test_traverse(self):
- supervisord = DummySupervisor()
- interface = self._makeOne(supervisord)
+ dummy = DummyRPCInterface()
+ interface = self._makeOne([('dummy', dummy)])
from xmlrpc import traverse
self._assertRPCError(xmlrpc.Faults.UNKNOWN_METHOD,
traverse, interface, 'notthere.hello', [])
self._assertRPCError(xmlrpc.Faults.UNKNOWN_METHOD,
traverse, interface, 'supervisor._readFile', [])
self._assertRPCError(xmlrpc.Faults.INCORRECT_PARAMETERS,
traverse, interface,
- 'supervisor.getIdentification', [1])
- self.assertEqual(
- traverse(interface, 'supervisor.getIdentification', []),
- 'supervisor')
+ 'dummy.hello', [1])
+ self.assertEqual(traverse(interface, 'dummy.hello', []), 'Hello!')
def makeExecutable(file, substitutions=None):
if substitutions is None:
@@ -1860,20 +1856,21 @@ def _getTargetClass(self):
from xmlrpc import supervisor_xmlrpc_handler
return supervisor_xmlrpc_handler
- def _makeOne(self, supervisord):
- return self._getTargetClass()(supervisord)
+ def _makeOne(self, supervisord, subinterfaces):
+ return self._getTargetClass()(supervisord, subinterfaces)
def test_ctor(self):
supervisor = DummySupervisor()
- handler = self._makeOne(supervisor)
+ subinterfaces = [('supervisor', DummySupervisorRPCNamespace())]
+ handler = self._makeOne(supervisor, subinterfaces)
self.assertEqual(handler.supervisord, supervisor)
- from xmlrpc import RPCInterface
- self.assertEqual(handler.rpcinterface.__class__, RPCInterface)
+ from xmlrpc import RootRPCInterface
+ self.assertEqual(handler.rpcinterface.__class__, RootRPCInterface)
def test_continue_request_nosuchmethod(self):
supervisor = DummySupervisor()
- handler = self._makeOne(supervisor)
- handler.rpcinterface = DummyRPCServer()
+ subinterfaces = [('supervisor', DummySupervisorRPCNamespace())]
+ handler = self._makeOne(supervisor, subinterfaces)
import xmlrpclib
data = xmlrpclib.dumps(('a', 'b'), 'supervisor.noSuchMethod')
request = DummyRequest('/what/ever', None, None, None)
@@ -1891,8 +1888,8 @@ def test_continue_request_nosuchmethod(self):
def test_continue_request_methodsuccess(self):
supervisor = DummySupervisor()
- handler = self._makeOne(supervisor)
- handler.rpcinterface = DummyRPCServer()
+ subinterfaces = [('supervisor', DummySupervisorRPCNamespace())]
+ handler = self._makeOne(supervisor, subinterfaces)
import xmlrpclib
data = xmlrpclib.dumps((), 'supervisor.getProtocolVersion')
request = DummyRequest('/what/ever', None, None, None)
@@ -1913,8 +1910,8 @@ def test_continue_request_methodsuccess(self):
def test_continue_request_500(self):
supervisor = DummySupervisor()
- handler = self._makeOne(supervisor)
- handler.rpcinterface = DummyRPCServer()
+ subinterfaces = [('supervisor', DummySupervisorRPCNamespace())]
+ handler = self._makeOne(supervisor, subinterfaces)
import xmlrpclib
data = xmlrpclib.dumps((), 'supervisor.raiseError')
request = DummyRequest('/what/ever', None, None, None)
@@ -3161,6 +3158,10 @@ def __setitem__(self, header, value):
def done(self):
self._done = True
+
+class DummyRPCInterface:
+ def hello(self):
+ return 'Hello!'
def test_suite():
suite = unittest.TestSuite()
View
18 src/supervisor/xmlrpc.py
@@ -875,17 +875,14 @@ class AttrDict(dict):
def __getattr__(self, name):
return self[name]
-class RPCInterface:
- def __init__(self, supervisord):
- self.supervisord = supervisord
- self.supervisor = SupervisorNamespaceRPCInterface(supervisord)
- self.system = SystemNamespaceRPCInterface(
- [('supervisor', self.supervisor)]
- )
+class RootRPCInterface:
+ def __init__(self, subinterfaces):
+ for name, rpcinterface in subinterfaces:
+ setattr(self, name, rpcinterface)
class supervisor_xmlrpc_handler(xmlrpc_handler):
- def __init__(self, supervisord):
- self.rpcinterface = RPCInterface(supervisord)
+ def __init__(self, supervisord, subinterfaces):
+ self.rpcinterface = RootRPCInterface(subinterfaces)
self.supervisord = supervisord
def continue_request (self, data, request):
@@ -958,4 +955,5 @@ def traverse(ob, method, params):
except TypeError:
raise RPCError(Faults.INCORRECT_PARAMETERS)
-
+def make_main_rpcinterface(supervisord):
+ return SupervisorNamespaceRPCInterface(supervisord)

0 comments on commit dbc7720

Please sign in to comment.