Commit 24bab1da authored by Marco Mariani's avatar Marco Mariani

cli refactoring: supervisord, supervisorctl

parent 4a067ef9
...@@ -56,19 +56,19 @@ setup(name=name, ...@@ -56,19 +56,19 @@ setup(name=name,
entry_points={ entry_points={
'console_scripts': [ 'console_scripts': [
# One entry point to control them all # One entry point to control them all
'slapos = slapos.cli_legacy.entry:main',
'slapos-watchdog = slapos.grid.watchdog:main', 'slapos-watchdog = slapos.grid.watchdog:main',
'slapproxy = slapos.proxy:main', 'slapproxy = slapos.proxy:main',
'slapproxy-query = slapos.proxy.query:main', 'slapproxy-query = slapos.proxy.query:main',
# Deprecated entry points # Deprecated entry points
'slapos = slapos.cli_legacy.entry:main',
'slapconsole = slapos.cli_legacy.console:console', 'slapconsole = slapos.cli_legacy.console:console',
'slapformat = slapos.cli_legacy.format:main', 'slapformat = slapos.cli_legacy.format:main',
'slapgrid = slapos.grid.slapgrid:run', 'slapgrid = slapos.grid.slapgrid:run',
'slapgrid-sr = slapos.grid.slapgrid:runSoftwareRelease', 'slapgrid-sr = slapos.grid.slapgrid:runSoftwareRelease',
'slapgrid-cp = slapos.grid.slapgrid:runComputerPartition', 'slapgrid-cp = slapos.grid.slapgrid:runComputerPartition',
'slapgrid-ur = slapos.grid.slapgrid:runUsageReport', 'slapgrid-ur = slapos.grid.slapgrid:runUsageReport',
'slapgrid-supervisorctl = slapos.grid.svcbackend:supervisorctl', 'slapgrid-supervisorctl = slapos.cli_legacy.svcbackend:supervisorctl',
'slapgrid-supervisord = slapos.grid.svcbackend:supervisord', 'slapgrid-supervisord = slapos.cli_legacy.svcbackend:supervisord',
'bang = slapos.cli_legacy.bang:main', 'bang = slapos.cli_legacy.bang:main',
'slap2 = slapos.cli.entry:main', 'slap2 = slapos.cli.entry:main',
], ],
...@@ -77,6 +77,12 @@ setup(name=name, ...@@ -77,6 +77,12 @@ setup(name=name,
'node bang = slapos.cli.bang:BangCommand', 'node bang = slapos.cli.bang:BangCommand',
'node format = slapos.cli.format:FormatCommand', 'node format = slapos.cli.format:FormatCommand',
'node register = slapos.cli.register:RegisterCommand', 'node register = slapos.cli.register:RegisterCommand',
'node supervisord = slapos.cli.supervisord:SupervisordCommand',
'node supervisorctl = slapos.cli.supervisorctl:SupervisorctlCommand',
'node status = slapos.cli.supervisorctl:SupervisorctlStatusCommand',
'node start = slapos.cli.supervisorctl:SupervisorctlStartCommand',
'node stop = slapos.cli.supervisorctl:SupervisorctlStopCommand',
'node restart = slapos.cli.supervisorctl:SupervisorctlRestartCommand',
'console = slapos.cli.console:ConsoleCommand', 'console = slapos.cli.console:ConsoleCommand',
'supply = slapos.cli.supply:SupplyCommand', 'supply = slapos.cli.supply:SupplyCommand',
'remove = slapos.cli.remove:RemoveCommand', 'remove = slapos.cli.remove:RemoveCommand',
......
...@@ -44,6 +44,7 @@ class RequestCommand(ClientConfigCommand): ...@@ -44,6 +44,7 @@ class RequestCommand(ClientConfigCommand):
action='store_true', action='store_true',
help='Ask for a slave instance') help='Ask for a slave instance')
# XXX maybe find a better name? we already have a global --cfg option
ap.add_argument('--configuration', ap.add_argument('--configuration',
nargs='+', nargs='+',
help="Give your configuration 'option1=value1 option2=value2'") help="Give your configuration 'option1=value1 option2=value2'")
......
# -*- coding: utf-8 -*-
import argparse
import logging
import os
from slapos.cli.config import ConfigCommand
from slapos.grid.svcbackend import launchSupervisord
import supervisor.supervisorctl
class SupervisorctlCommand(ConfigCommand):
log = logging.getLogger(__name__)
def get_parser(self, prog_name):
parser = super(SupervisorctlCommand, self).get_parser(prog_name)
parser.add_argument('supervisor_args',
nargs=argparse.REMAINDER,
help='parameters passed to supervisorctl')
return parser
def take_action(self, args):
config = self.fetch_config(args)
instance_root = config.get('slapos', 'instance_root')
configuration_file = os.path.join(instance_root, 'etc', 'supervisord.conf')
launchSupervisord(socket=os.path.join(instance_root, 'supervisord.socket'),
configuration_file=configuration_file,
logger=self.log)
supervisor.supervisorctl.main(args=['-c', configuration_file] + args.supervisor_args)
class SupervisorctlAliasCommand(SupervisorctlCommand):
def take_action(self, args):
args.supervisor_args = [self.alias] + args.supervisor_args
super(SupervisorctlAliasCommand, self).take_action(args)
class SupervisorctlStatusCommand(SupervisorctlAliasCommand):
"""alias for 'node supervisorctl status'"""
alias = 'status'
class SupervisorctlStartCommand(SupervisorctlAliasCommand):
"""alias for 'node supervisorctl start'"""
alias = 'start'
class SupervisorctlStopCommand(SupervisorctlAliasCommand):
"""alias for 'node supervisorctl stop'"""
alias = 'stop'
class SupervisorctlRestartCommand(SupervisorctlAliasCommand):
"""alias for 'node supervisorctl restart'"""
alias = 'restart'
# -*- coding: utf-8 -*-
import argparse
import logging
import os
from slapos.cli.config import ConfigCommand
from slapos.grid.svcbackend import launchSupervisord
class SupervisordCommand(ConfigCommand):
log = logging.getLogger(__name__)
def take_action(self, args):
config = self.fetch_config(args)
instance_root = config.get('slapos', 'instance_root')
launchSupervisord(socket=os.path.join(instance_root, 'supervisord.socket'),
configuration_file=os.path.join(instance_root, 'etc', 'supervisord.conf'),
logger=self.log)
...@@ -41,8 +41,8 @@ from slapos.cli_legacy.cache import cache_lookup ...@@ -41,8 +41,8 @@ from slapos.cli_legacy.cache import cache_lookup
from slapos.grid.slapgrid import runComputerPartition as instance from slapos.grid.slapgrid import runComputerPartition as instance
from slapos.grid.slapgrid import runSoftwareRelease as software from slapos.grid.slapgrid import runSoftwareRelease as software
from slapos.grid.slapgrid import runUsageReport as report from slapos.grid.slapgrid import runUsageReport as report
from slapos.grid.svcbackend import supervisord from slapos.cli_legacy.svcbackend import supervisord
from slapos.grid.svcbackend import supervisorctl from slapos.cli_legacy.svcbackend import supervisorctl
from slapos.cli_legacy.register import main as register from slapos.cli_legacy.register import main as register
from slapos.version import version from slapos.version import version
......
# -*- coding: utf-8 -*-
# vim: set et sts=2:
##############################################################################
#
# Copyright (c) 2010, 2011, 2012 Vifib SARL and Contributors.
# All Rights Reserved.
#
# WARNING: This program as such is intended to be used by professional
# programmers who take the whole responsibility of assessing all potential
# consequences resulting from its eventual inadequacies and bugs
# End users who are looking for a ready-to-use solution with commercial
# guarantees and support are strongly advised to contract a Free Software
# Service Company
#
# This program is Free Software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; either version 3
# of the License, or (at your option) any later version.
#
# This program 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 General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#
##############################################################################
import logging
import os
from optparse import OptionParser
import ConfigParser
from slapos.grid.svcbackend import launchSupervisord
logger = logging.getLogger('SVCBackend')
logger.setLevel(logging.INFO)
handler = logging.StreamHandler()
logger.addHandler(handler)
def getOptionDict(*argument_tuple):
usage = """
Typical usage:
* %prog CONFIGURATION_FILE [arguments passed to supervisor]
""".strip()
parser = OptionParser(usage=usage)
# Parses arguments
if argument_tuple:
(argument_option_instance, argument_list) = parser.parse_args(list(argument_tuple))
else:
# No arguments given to entry point : we parse sys.argv.
(argument_option_instance, argument_list) = parser.parse_args()
if not argument_list:
parser.error("Configuration file is obligatory. Consult documentation by calling with -h.")
configuration_file = argument_list[0]
if not os.path.exists(configuration_file):
parser.error("Could not read configuration file : %s" % configuration_file)
slapgrid_configuration = ConfigParser.SafeConfigParser()
slapgrid_configuration.read(configuration_file)
# Merges the two dictionnaries
option_dict = dict(slapgrid_configuration.items("slapos"))
# Supervisord configuration location
option_dict.setdefault('supervisord_configuration_path',
os.path.join(option_dict['instance_root'], 'etc', 'supervisord.conf'))
# Supervisord socket
option_dict.setdefault('supervisord_socket',
os.path.join(option_dict['instance_root'], 'supervisord.socket'))
return option_dict, argument_list[1:]
def supervisorctl(*argument_tuple):
option_dict, args = getOptionDict(*argument_tuple)
import supervisor.supervisorctl
launchSupervisord(socket=option_dict['supervisord_socket'],
configuration_file=option_dict['supervisord_configuration_path'],
logger=logger)
supervisor.supervisorctl.main(args=['-c', option_dict['supervisord_configuration_path']] + args)
def supervisord(*argument_tuple):
option_dict, _ = getOptionDict(*argument_tuple)
launchSupervisord(socket=option_dict['supervisord_socket'],
configuration_file=option_dict['supervisord_configuration_path'],
logger=logger)
...@@ -28,18 +28,17 @@ ...@@ -28,18 +28,17 @@
# #
############################################################################## ##############################################################################
from supervisor import xmlrpc
import time import time
from utils import SlapPopen
import logging import logging
import os import os
import sys import sys
import xmlrpclib import xmlrpclib
from optparse import OptionParser
import ConfigParser
import socket as socketlib import socket as socketlib
import subprocess import subprocess
from supervisor import xmlrpc
from slapos.grid.utils import SlapPopen
def getSupervisorRPC(socket): def getSupervisorRPC(socket):
supervisor_transport = xmlrpc.SupervisorTransport('', '', supervisor_transport = xmlrpc.SupervisorTransport('', '',
...@@ -48,21 +47,25 @@ def getSupervisorRPC(socket): ...@@ -48,21 +47,25 @@ def getSupervisorRPC(socket):
supervisor_transport) supervisor_transport)
return getattr(server_proxy, 'supervisor') return getattr(server_proxy, 'supervisor')
class dummylogger(object):
def info(self, *args):
print args
debug = info
def launchSupervisord(socket, configuration_file): def launchSupervisord(socket, configuration_file, logger):
logger = logging.getLogger('SVCBackend') #logger = dummylogger()
supervisor = getSupervisorRPC(socket)
if os.path.exists(socket): if os.path.exists(socket):
trynum = 1 trynum = 1
while trynum < 6: while trynum < 6:
try: try:
supervisor = getSupervisorRPC(socket)
status = supervisor.getState() status = supervisor.getState()
except xmlrpclib.Fault as e: except xmlrpclib.Fault as e:
if e.faultCode == 6 and e.faultString == 'SHUTDOWN_STATE': if e.faultCode == 6 and e.faultString == 'SHUTDOWN_STATE':
logger.info('Supervisor in shutdown procedure, will check again later.') logger.info('Supervisor in shutdown procedure, will check again later.')
trynum += 1 trynum += 1
time.sleep(2 * trynum) time.sleep(2 * trynum)
except Exception: except Exception as e:
# In case if there is problem with connection, assume that supervisord # In case if there is problem with connection, assume that supervisord
# is not running and try to run it # is not running and try to run it
break break
...@@ -91,84 +94,32 @@ def launchSupervisord(socket, configuration_file): ...@@ -91,84 +94,32 @@ def launchSupervisord(socket, configuration_file):
executable=sys.executable, executable=sys.executable,
stdout=subprocess.PIPE, stdout=subprocess.PIPE,
stderr=subprocess.STDOUT) stderr=subprocess.STDOUT)
result = supervisord_popen.communicate()[0]
if supervisord_popen.returncode == 0:
logger.info('Supervisord command invoked with: %s' % result)
try:
default_timeout = socketlib.getdefaulttimeout()
current_timeout = 1
trynum = 1
while trynum < 6:
try:
socketlib.setdefaulttimeout(current_timeout)
status = supervisor.getState()
if status['statename'] == 'RUNNING' and status['statecode'] == 1:
return
logger.warning('Wrong status name %(statename)r and code '
'%(statecode)r, trying again' % status)
trynum += 1
except Exception:
current_timeout = 5 * trynum
trynum += 1
else:
logger.info('Supervisord started correctly in try %s.' % trynum)
return
logger.warning('Issue while checking supervisord.')
finally:
socketlib.setdefaulttimeout(default_timeout)
else:
log_message = 'Supervisord unknown problem: %s' % result
logger.warning(log_message)
def getOptionDict(*argument_tuple):
usage = """
Typical usage:
* %prog CONFIGURATION_FILE [arguments passed to supervisor]
""".strip()
parser = OptionParser(usage=usage)
# Parses arguments
if argument_tuple:
(argument_option_instance, argument_list) = parser.parse_args(list(argument_tuple))
else:
# No arguments given to entry point : we parse sys.argv.
(argument_option_instance, argument_list) = parser.parse_args()
if not argument_list: result = supervisord_popen.communicate()[0]
parser.error("Configuration file is obligatory. Consult documentation by " if supervisord_popen.returncode:
"calling with -h.") logger.warning('Supervisord unknown problem: %s' % result)
configuration_file = argument_list[0] return
if not os.path.exists(configuration_file):
parser.error("Could not read configuration file : %s" % configuration_file)
slapgrid_configuration = ConfigParser.SafeConfigParser()
slapgrid_configuration.read(configuration_file)
# Merges the two dictionnaries
option_dict = dict(slapgrid_configuration.items("slapos"))
# Supervisord configuration location
option_dict.setdefault('supervisord_configuration_path',
os.path.join(option_dict['instance_root'], 'etc', 'supervisord.conf'))
# Supervisord socket
option_dict.setdefault('supervisord_socket',
os.path.join(option_dict['instance_root'], 'supervisord.socket'))
return option_dict, argument_list[1:]
def supervisorctl(*argument_tuple):
option_dict, args = getOptionDict(*argument_tuple)
import supervisor.supervisorctl
launchSupervisord(option_dict['supervisord_socket'],
option_dict['supervisord_configuration_path'])
supervisor.supervisorctl.main(args=['-c',
option_dict['supervisord_configuration_path']] + args)
def supervisord(*argument_tuple):
option_dict, _ = getOptionDict(*argument_tuple)
launchSupervisord(option_dict['supervisord_socket'],
option_dict['supervisord_configuration_path'])
try:
default_timeout = socketlib.getdefaulttimeout()
current_timeout = 1
trynum = 1
while trynum < 6:
try:
socketlib.setdefaulttimeout(current_timeout)
supervisor = getSupervisorRPC(socket)
status = supervisor.getState()
if status['statename'] == 'RUNNING' and status['statecode'] == 1:
return
logger.warning('Wrong status name %(statename)r and code '
'%(statecode)r, trying again' % status)
trynum += 1
except Exception as e:
current_timeout = 5 * trynum
trynum += 1
else:
logger.info('Supervisord started correctly in try %s.' % trynum)
return
logger.warning('Issue while checking supervisord.')
finally:
socketlib.setdefaulttimeout(default_timeout)
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment