Skip to content

Commit

Permalink
Add support for Python 3.2 / 3.3, drop 2.5
Browse files Browse the repository at this point in the history
  • Loading branch information
mnaberez committed Feb 2, 2014
1 parent aac248e commit 4a535b3
Show file tree
Hide file tree
Showing 21 changed files with 240 additions and 214 deletions.
2 changes: 2 additions & 0 deletions .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@ language: python
python:
- "2.6"
- "2.7"
- "3.2"
- "3.3"
# command to run tests
script:
- python setup.py test -q
4 changes: 4 additions & 0 deletions CHANGES.txt
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
Next Release
------------

- Dropped support for Python 2.5.

- Added support for Python 3.2 and 3.3.

- Removed ``setuptools`` from the ``install_requires`` list in ``setup.py``
because it caused installation issues on some systems.

Expand Down
12 changes: 6 additions & 6 deletions setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,12 +15,12 @@
import os
import sys

if sys.version_info[:2] < (2, 4) or sys.version_info[0] > 2:
msg = ("Superlance requires Python 2.4 or later but does not work on "
"any version of Python 3. You are using version %s. Please "
"install using a supported version." % sys.version)
sys.stderr.write(msg)
sys.exit(1)
py_version = sys.version_info[:2]

if py_version < (2, 6):
raise RuntimeError('On Python 2, superlance requires Python 2.6 or later')
elif (3, 0) < py_version < (3, 2):
raise RuntimeError('On Python 3, superlance requires Python 3.2 or later')

from setuptools import setup, find_packages

Expand Down
26 changes: 26 additions & 0 deletions superlance/compat.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
try:
import http.client as httplib
except ImportError:
import httplib

try:
from StringIO import StringIO
except ImportError:
from io import StringIO

try:
from sys import maxsize as maxint
except ImportError:
from sys import maxint

try:
import urllib.parse as urlparse
import urllib.parse as urllib
except ImportError:
import urlparse
import urllib

try:
import xmlrpc.client as xmlrpclib
except ImportError:
import xmlrpclib
7 changes: 3 additions & 4 deletions superlance/crashmail.py
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@
from supervisor import childutils

def usage():
print doc
print(doc)
sys.exit(255)

class CrashMail:
Expand Down Expand Up @@ -132,9 +132,8 @@ def mail(self, email, subject, msg):
body += 'Subject: %s\n' % subject
body += '\n'
body += msg
m = os.popen(self.sendmail, 'w')
m.write(body)
m.close()
with os.popen(self.sendmail, 'w') as m:
m.write(body)
self.stderr.write('Mailed:\n\n%s' % body)
self.mailed = body

Expand Down
55 changes: 26 additions & 29 deletions superlance/httpok.py
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@
the URL returns an unexpected result or times out. If this
process is part of a group, it can be specified using the
'group_name:process_name' syntax.
-a -- Restart any child of the supervisord under in the RUNNING state
if the URL returns an unexpected result or times out. Overrides
any -p parameters passed in the same httpok process
Expand Down Expand Up @@ -98,17 +98,17 @@
import socket
import sys
import time
import urlparse
import xmlrpclib
from superlance.compat import urlparse
from superlance.compat import xmlrpclib

from supervisor import childutils
from supervisor.states import ProcessStates
from supervisor.options import make_namespec

import timeoutconn
from superlance import timeoutconn

def usage():
print doc
print(doc)
sys.exit(255)

class HTTPOk:
Expand Down Expand Up @@ -178,12 +178,12 @@ def runforever(self, test=False):

try:
for will_retry in range(
self.timeout // (self.retry_time or 1) - 1 ,
self.timeout // (self.retry_time or 1) - 1 ,
-1, -1):
try:
conn.request('GET', path)
break
except socket.error, e:
except socket.error as e:
if e.errno == 111 and will_retry:
time.sleep(self.retry_time)
else:
Expand All @@ -195,10 +195,10 @@ def runforever(self, test=False):
msg = 'status contacting %s: %s %s' % (self.url,
res.status,
res.reason)
except Exception, why:
except Exception as e:
body = ''
status = None
msg = 'error contacting %s:\n\n %s' % (self.url, why)
msg = 'error contacting %s:\n\n %s' % (self.url, e)

if str(status) != str(self.status):
subject = 'httpok for %s: bad status returned' % self.url
Expand All @@ -222,12 +222,12 @@ def write(msg):

try:
specs = self.rpc.supervisor.getAllProcessInfo()
except Exception, why:
write('Exception retrieving process info %s, not acting' % why)
except Exception as e:
write('Exception retrieving process info %s, not acting' % e)
return

waiting = list(self.programs)

if self.any:
write('Restarting all running processes')
for spec in specs:
Expand Down Expand Up @@ -267,9 +267,8 @@ def mail(self, email, subject, msg):
body += 'Subject: %s\n' % subject
body += '\n'
body += msg
m = os.popen(self.sendmail, 'w')
m.write(body)
m.close()
with os.popen(self.sendmail, 'w') as m:
m.write(body)
self.stderr.write('Mailed:\n\n%s' % body)
self.mailed = body

Expand All @@ -278,27 +277,28 @@ def restart(self, spec, write):
if spec['state'] is ProcessStates.RUNNING:
if self.coredir and self.gcore:
corename = os.path.join(self.coredir, namespec)
m = os.popen(self.gcore + ' "%s" %s' % (corename, spec['pid']))
write('gcore output for %s:\n\n %s' % (namespec, m.read()))
m.close()
cmd = self.gcore + ' "%s" %s' % (corename, spec['pid'])
with os.popen(cmd) as m:
write('gcore output for %s:\n\n %s' % (
namespec, m.read()))
write('%s is in RUNNING state, restarting' % namespec)
try:
self.rpc.supervisor.stopProcess(namespec)
except xmlrpclib.Fault, what:
except xmlrpclib.Fault as e:
write('Failed to stop process %s: %s' % (
namespec, what))
namespec, e))

try:
self.rpc.supervisor.startProcess(namespec)
except xmlrpclib.Fault, what:
except xmlrpclib.Fault as e:
write('Failed to start process %s: %s' % (
namespec, what))
namespec, e))
else:
write('%s restarted' % namespec)

else:
write('%s not in RUNNING state, NOT restarting' % namespec)


def main(argv=sys.argv):
import getopt
Expand Down Expand Up @@ -382,8 +382,8 @@ def main(argv=sys.argv):

try:
rpc = childutils.getRPCInterface(os.environ)
except KeyError, why:
if why[0] != 'SUPERVISOR_SERVER_URL':
except KeyError as e:
if e.args[0] != 'SUPERVISOR_SERVER_URL':
raise
sys.stderr.write('httpok must be run as a supervisor event '
'listener\n')
Expand All @@ -396,6 +396,3 @@ def main(argv=sys.argv):

if __name__ == '__main__':
main()



43 changes: 21 additions & 22 deletions superlance/memmon.py
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@
-u -- optionally specify the minimum uptime in seconds for the process.
if the process uptime is longer than this value, no email is sent
(useful to only be notified if processes are restarted too often/early)
seconds can be specified as plain integer values or a suffix-multiplied integer
(e.g. 1m). Valid suffixes are m (minute), h (hour) and d (day).
Expand All @@ -79,17 +79,18 @@
import os
import sys
import time
import xmlrpclib
from superlance.compat import xmlrpclib

from supervisor import childutils
from supervisor.datatypes import byte_size, SuffixMultiplier

def usage():
print doc
print(doc)
sys.exit(255)

def shell(cmd):
return os.popen(cmd).read()
with os.popen(cmd) as f:
return f.read()

class Memmon:
def __init__(self, programs, groups, any, sendmail, email, email_uptime_limit, name, rpc):
Expand Down Expand Up @@ -122,15 +123,17 @@ def runforever(self, test=False):

status = []
if self.programs:
keys = sorted(self.programs.keys())
status.append(
'Checking programs %s' % ', '.join(
[ '%s=%s' % x for x in self.programs.items() ] )
[ '%s=%s' % (k, self.programs[k]) for k in keys ] )
)

if self.groups:
keys = sorted(self.groups.keys())
status.append(
'Checking groups %s' % ', '.join(
[ '%s=%s' % x for x in self.groups.items() ] )
[ '%s=%s' % (k, self.groups[k]) for k in keys ] )
)
if self.any is not None:
status.append('Checking any=%s' % self.any)
Expand Down Expand Up @@ -193,9 +196,9 @@ def restart(self, name, rss):
memmonId = self.memmonName and " [%s]" % self.memmonName or ""
try:
self.rpc.supervisor.stopProcess(name)
except xmlrpclib.Fault, what:
except xmlrpclib.Fault as e:
msg = ('Failed to stop process %s (RSS %s), exiting: %s' %
(name, rss, what))
(name, rss, e))
self.stderr.write(str(msg))
if self.email:
subject = 'memmon%s: failed to stop process %s, exiting' % (memmonId, name)
Expand All @@ -204,9 +207,9 @@ def restart(self, name, rss):

try:
self.rpc.supervisor.startProcess(name)
except xmlrpclib.Fault, what:
except xmlrpclib.Fault as e:
msg = ('Failed to start process %s after stopping it, '
'exiting: %s' % (name, what))
'exiting: %s' % (name, e))
self.stderr.write(str(msg))
if self.email:
subject = 'memmon%s: failed to start process %s, exiting' % (memmonId, name)
Expand All @@ -228,16 +231,15 @@ def mail(self, email, subject, msg):
body += 'Subject: %s\n' % subject
body += '\n'
body += msg
m = os.popen(self.sendmail, 'w')
m.write(body)
m.close()
with os.popen(self.sendmail, 'w') as m:
m.write(body)
self.mailed = body

def parse_namesize(option, value):
try:
name, size = value.split('=')
except ValueError:
print 'Unparseable value %r for %r' % (value, option)
print('Unparseable value %r for %r' % (value, option))
usage()
size = parse_size(option, size)
return name, size
Expand All @@ -246,7 +248,7 @@ def parse_size(option, value):
try:
size = byte_size(value)
except:
print 'Unparseable byte_size in %r for %r' % (value, option)
print('Unparseable byte_size in %r for %r' % (value, option))
usage()

return size
Expand All @@ -261,10 +263,10 @@ def parse_seconds(option, value):
try:
seconds = seconds_size(value)
except:
print 'Unparseable value for time in %r for %s' % (value, option)
print('Unparseable value for time in %r for %s' % (value, option))
usage()
return seconds

def main():
import getopt
short_args="hp:g:a:s:m:n:u:"
Expand All @@ -284,7 +286,7 @@ def main():
try:
opts, args=getopt.getopt(arguments, short_args, long_args)
except:
print __doc__
print(__doc__)
sys.exit(2)

programs = {}
Expand Down Expand Up @@ -320,7 +322,7 @@ def main():

if option in ('-u', '--uptime'):
uptime = parse_seconds(option, value)

if option in ('-n', '--name'):
name = value

Expand All @@ -330,6 +332,3 @@ def main():

if __name__ == '__main__':
main()



Loading

0 comments on commit 4a535b3

Please sign in to comment.