Skip to content

Instantly share code, notes, and snippets.

@yoloseem
Created September 25, 2013 13:47
Show Gist options
  • Save yoloseem/6699845 to your computer and use it in GitHub Desktop.
Save yoloseem/6699845 to your computer and use it in GitHub Desktop.
supervisor control with fabric.
""" fabutils.py
~~~~~~~~~~~
"""
from __future__ import absolute_import, unicode_literals
import re
import time
from fabric.api import quiet, run, settings, sudo
from fabric.utils import abort, error, puts, warn
class supervisor(object):
"""supervisor utility for fabric. """
CONFIG = '/path/to/supervisor/config.cfg'
STARTING = 'STARTING'
RUNNING = 'RUNNING'
STOPPING = 'STOPPING'
STOPPED = 'STOPPED'
@classmethod
def ctl(cls, command):
with quiet():
out = run('supervisorctl -c {config} {command}'.format(
config=cls.CONFIG, command=command))
if 'error' in out:
error('supervisord seems that does not working now')
return out
@classmethod
def get_pid(cls):
with quiet():
pids = sudo("ps auxww | grep supervisor[d] | awk '{print $2}'")
pids = pids.strip()
if pids:
pids = re.split(r'\s+', pids)
else:
return None
return pids[0]
@classmethod
def is_running(cls, timeout=0):
def _determine():
pid = cls.get_pid()
if not pid:
return None
with quiet():
out = cls.ctl('status')
if 'error' in out:
return False
return int(pid)
if _determine():
return True
elif timeout > 0:
for trial in xrange(timeout):
puts('Waiting 1 second for retrying...')
time.sleep(1)
result = _determine()
if result is None:
return False
elif isinstance(result, int):
return True
return False
@classmethod
def start(cls):
puts('Starting supervisord daemon in backgroud...')
with quiet():
run('supervisord -c {config}'.format(config=cls.CONFIG))
@classmethod
def restart(cls, hup=True):
if cls.is_running():
puts('Running supervisord detected.')
if hup:
puts('Sending SIGHUP signal to supervisord process...')
with quiet():
run('kill -HUP {pid}'.format(pid=cls.get_pid()))
if cls.is_running(timeout=10):
return
puts('supervisord prcesss is not responding...')
else:
warn('Reloading via SIGHUP signal is recommended.')
cls.kill()
cls.start()
if not cls.is_running(timeout=10):
abort('supervisord is not working')
@classmethod
def kill(cls):
pid = cls.get_pid()
if pid:
puts('Killing supervisord process...')
with quiet():
run('kill -9 {pid}'.format(pid=cls.get_pid()))
@classmethod
def process_start(cls, program):
puts('Starting {0}...'.format(program))
with quiet():
out = cls.ctl('start {program}'.format(program=program))
if 'no such process' in out.lower():
error('{program} does not registred as supervisord program')
if 'ERROR' in out and 'already started' not in out:
error(out)
puts('{0}: started, woah!'.format(program))
@classmethod
def process_stop(cls, program):
puts('Stopping {0}...'.format(program))
with quiet():
out = cls.ctl('stop {program}'.format(program=program))
if 'no such process' in out.lower():
error('{program} does not registred as supervisord program')
if 'ERROR' in out and 'not running' not in out:
error('out')
puts('{0}: stopped.'.format(program))
@classmethod
def process_restart(cls, program):
puts('Restarting {0}...'.format(program))
with quiet():
out = cls.ctl('restart {program}'.format(program=program))
if 'no such process' in out.lower():
error('{program} does not registred as supervisord program')
puts('{0}: restarted, woah!'.format(program))
@classmethod
def process_status(cls, program):
with quiet():
out = cls.ctl('status {program}'.format(program=program))
if 'no such process' in out.lower():
error('{program} does not registred as supervisord program')
if cls.RUNNING in out:
return cls.RUNNING
elif cls.STOPPED in out:
return cls.STOPPED
elif cls.STARTING in out:
return cls.STARTING
@classmethod
def process_running(cls, program):
return bool(cls.process_status(program) != cls.STOPPED and
cls.process_status(program) != cls.STOPPING)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment