Commit 73a5e400 authored by Andrii Salnikov's avatar Andrii Salnikov
Browse files

Manual way for ARC services control when built from sources

parent 9d8efd2c
......@@ -6,6 +6,7 @@ logger = logging.getLogger('ARCCTL.Common')
try:
from arc import paths
ARC_LOCATION = paths.ARC_LOCATION
ARC_LIBEXEC_DIR = paths.ARC_LIBEXEC_DIR
ARC_DATA_DIR = paths.ARC_DATA_DIR
except ImportError:
......
......@@ -6,10 +6,27 @@ import os
class OSServiceManagement(object):
"""This class aimed to handle both Systemd and SysV cases"""
def __init__(self):
def __init__(self, scripts_path=None):
self.command_base = [] # placeholder to include command's prefix, like ssh to host
# self.command_base = ['ssh', 'arc6.grid.org.ua']
self.logger = logging.getLogger('ARCCTL.OSServiceManagement')
# scripts_path is defined - no OS service management, only scripts
if scripts_path is not None:
self.logger.debug('Direct startup scripts invocation is requested instead of OS service management')
self.sm = 'manual'
self.sm_ctl = {
'start': scripts_path + '{0} start',
'stop': scripts_path + '{0} stop',
'enable': 'true', # no enable/disable in manual mode
'disable': 'true'
}
self.sm_check = {
'enabled': 'false',
'installed': 'test -f ' + scripts_path + '{0}',
'active': scripts_path + '{0} status'
}
self.sm_version = ''
return
# detect systemctl
try:
systemctl_output = subprocess.Popen(self.command_base + ['systemctl', '--version'],
......@@ -25,9 +42,11 @@ class OSServiceManagement(object):
}
self.sm_check = {
'enabled': 'systemctl -q is-enabled {0}',
'installed': 'systemctl status {0}',
'active': 'systemctl -q is-active {0}'
}
self.sm_version = stdout[0].split('\n')[0]
self.logger.debug('Managing OS services using {0} version {1}', self.sm, self.sm_version)
return
except OSError:
pass
......@@ -46,9 +65,11 @@ class OSServiceManagement(object):
}
self.sm_check = {
'enabled': 'chkconfig {0}',
'installed': 'chkconfig --list {0}',
'active': 'service {0} status'
}
self.sm_version = stdout[0].split('\n')[0]
self.logger.debug('Managing OS services using {0} version {1}', self.sm, self.sm_version)
return
except OSError:
pass
......@@ -60,14 +81,20 @@ class OSServiceManagement(object):
action_str = self.sm_ctl[action]
command = self.command_base + action_str.format(service).split()
self.logger.info('Running the following command to %s service: %s', action, ' '.join(command))
return subprocess.call(command)
try:
return subprocess.call(command)
except OSError:
return 1
def __check_service(self, service, check):
__DEVNULL = open(os.devnull, 'w')
check_str = self.sm_check[check]
command = self.command_base + check_str.format(service).split()
self.logger.debug('Running the following command to check service is %s: %s', check, ' '.join(command))
return subprocess.call(command, stdout=__DEVNULL, stderr=subprocess.STDOUT) == 0
try:
self.logger.debug('Running the following command to check service is %s: %s', check, ' '.join(command))
return subprocess.call(command, stdout=__DEVNULL, stderr=subprocess.STDOUT) == 0
except OSError:
return False
def enable(self, service):
return self.__exec_service_cmd(service, 'enable')
......@@ -86,3 +113,6 @@ class OSServiceManagement(object):
def is_active(self, service):
return self.__check_service(service, 'active')
def is_installed(self, service):
return self.__check_service(service, 'installed')
......@@ -58,6 +58,19 @@ class ServicesControl(ComponentControl):
self.logger.info('Controlling ARC CE Services is not possible without arc.conf.')
sys.exit(1)
self.arcconfig = arcconfig
self.sm = None
self.pm = None
def __get_pm_sm(self):
if self.sm is None:
self.pm = OSPackageManagement()
# check arex package that contains arcctl
if self.pm.is_installed(self.__blocks_map['arex']['package']):
self.sm = OSServiceManagement()
else:
self.pm = None
self.sm = OSServiceManagement(ARC_LOCATION + '/etc/rc.d/init.d/')
return self.pm, self.sm
def __get_configured(self):
packages_needed = set()
......@@ -74,7 +87,10 @@ class ServicesControl(ComponentControl):
return packages_needed, services_all, services_needed
def __packages_install(self, packages_needed):
pm = OSPackageManagement()
pm, _ = self.__get_pm_sm()
if pm is None:
self.logger.info('ARC is installed from sources. Skipping OS packages management.')
return
install_list = []
for p in packages_needed:
if not pm.is_installed(p):
......@@ -118,7 +134,7 @@ class ServicesControl(ComponentControl):
self.__services_stop(services, sm)
def start_as_configured(self):
sm = OSServiceManagement()
pm, sm = self.__get_pm_sm()
packages_needed, services_all, services_needed = self.__get_configured()
# ensure packages are installed
self.__packages_install(packages_needed)
......@@ -128,7 +144,7 @@ class ServicesControl(ComponentControl):
self.__services_start(services_needed, sm)
def enable_as_configured(self, now=False):
sm = OSServiceManagement()
pm, sm = self.__get_pm_sm()
packages_needed, services_all, services_needed = self.__get_configured()
# ensure packages are installed
self.__packages_install(packages_needed)
......@@ -138,8 +154,7 @@ class ServicesControl(ComponentControl):
self.__services_enable(services_needed, sm, now)
def list_services(self, args):
pm = OSPackageManagement()
sm = OSServiceManagement()
pm, sm = self.__get_pm_sm()
services = {}
for s in self.__blocks_map.values():
sname = s['service']
......@@ -147,13 +162,18 @@ class ServicesControl(ComponentControl):
continue
if sname in services:
continue
installed = pm.is_installed(s['package'])
if pm is None:
installed = sm.is_installed(s['service'])
installed_str = 'Built from source' if installed else 'Not built'
else:
installed = pm.is_installed(s['package'])
installed_str = 'Installed' if installed else 'Not installed'
active = sm.is_active(s['service'])
enabled = sm.is_enabled(s['service'])
services[sname] = {
'name': sname,
'installed': installed,
'installed_str': 'Installed' if installed else 'Not installed',
'installed_str': installed_str,
'active': active,
'active_str': 'Running' if active else 'Stopped',
'enabled': enabled,
......@@ -170,28 +190,29 @@ class ServicesControl(ComponentControl):
print('{name:32} ({installed_str}, {enabled_str}, {active_str})'.format(**ss))
def control(self, args):
_, sm = self.__get_pm_sm()
if args.action == 'enable':
if args.as_configured:
self.enable_as_configured(args.now)
else:
self.__services_enable(args.service, OSServiceManagement(), args.now)
self.__services_enable(args.service, sm, args.now)
elif args.action == 'disable':
if args.as_configured:
services = self.get_all_services()
else:
services = args.service
self.__services_disable(services, OSServiceManagement(), args.now)
self.__services_disable(services, sm, args.now)
elif args.action == 'start':
if args.as_configured:
self.start_as_configured()
else:
self.__services_start(args.service, OSServiceManagement())
self.__services_start(args.service, sm)
elif args.action == 'stop':
if args.as_configured:
services = self.get_all_services()
else:
services = args.service
self.__services_stop(services, OSServiceManagement())
self.__services_stop(services, sm)
elif args.action == 'list':
self.list_services(args)
else:
......
Supports Markdown
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