Skip to content

Commit

Permalink
Big reorganization:
Browse files Browse the repository at this point in the history
- 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
mcdonc committed Aug 1, 2007
1 parent cf1e15b commit dbc7720
Show file tree
Hide file tree
Showing 7 changed files with 93 additions and 61 deletions.
3 changes: 3 additions & 0 deletions sample.conf
Expand Up @@ -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
Expand Down
39 changes: 13 additions & 26 deletions 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)

Expand All @@ -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
Expand All @@ -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',
Expand All @@ -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)
)
2 changes: 1 addition & 1 deletion src/supervisor/__init__.py
@@ -1 +1 @@
# poof.
__import__('pkg_resources').declare_namespace(__name__)
15 changes: 14 additions & 1 deletion src/supervisor/http.py
Expand Up @@ -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__))
Expand Down
32 changes: 31 additions & 1 deletion src/supervisor/options.py
Expand Up @@ -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.
Expand Down Expand Up @@ -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):
Expand Down Expand Up @@ -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
Expand Down
45 changes: 23 additions & 22 deletions src/supervisor/tests.py
Expand Up @@ -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:
Expand Down Expand Up @@ -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)
Expand All @@ -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)
Expand All @@ -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)
Expand Down Expand Up @@ -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()
Expand Down
18 changes: 8 additions & 10 deletions src/supervisor/xmlrpc.py
Expand Up @@ -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):
Expand Down Expand Up @@ -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.