introduce wildcards for <instance>

This commit is contained in:
zolliker 2021-12-06 14:39:04 +01:00
parent bb3c72acc9
commit f411460c2c
5 changed files with 71 additions and 28 deletions

View File

@ -76,7 +76,7 @@ def run(group, arglist):
if pos >= SERVICE: if pos >= SERVICE:
unorder = True unorder = True
pos = SERVICE pos = SERVICE
elif arg in serv.info or arg == 'all': elif arg in serv.info or arg == 'all' or serv.wildcard(arg) is not None:
args['ins'] = arg args['ins'] = arg
if pos >= INS: if pos >= INS:
unorder = True unorder = True

47
base.py
View File

@ -202,6 +202,15 @@ class ServiceManager:
result.setdefault(ins, {}).setdefault(serv, []).append(p) result.setdefault(ins, {}).setdefault(serv, []).append(p)
return result return result
def wildcard(self, ins):
if ins is None or ins == 'all':
return list(self.info)
pat = re.sub(r'(\.|\*)', '.*', ins)
if pat == ins:
return None
pat = re.compile(pat)
return [k for k in self.info if pat.match(k)]
def check_running(self, ins, service): def check_running(self, ins, service):
self.get_info() self.get_info()
if ins not in self.info: if ins not in self.info:
@ -215,6 +224,9 @@ class ServiceManager:
def stop(self, ins, service=None): def stop(self, ins, service=None):
"""stop service (or all services) of instance <ins>""" """stop service (or all services) of instance <ins>"""
ins_list = self.wildcard(ins)
if ins_list is not None:
return ins_list
procs = self.get_procs() procs = self.get_procs()
done = False done = False
services = self.services if service is None else [service] services = self.services if service is None else [service]
@ -247,6 +259,9 @@ class ServiceManager:
def do_stop(self, ins, service=None, *args): def do_stop(self, ins, service=None, *args):
self.get_info() self.get_info()
ins_list = self.wildcard(ins)
if ins_list is not None:
return ins_list
if not self.stop(ins, service): if not self.stop(ins, service):
print('nothing to stop') print('nothing to stop')
@ -258,6 +273,9 @@ class ServiceManager:
return env.get('%s_ROOT' % gr, ''), env return env.get('%s_ROOT' % gr, ''), env
def do_start(self, ins, service=None, cfg='', restart=False, wait=False, logger=None): def do_start(self, ins, service=None, cfg='', restart=False, wait=False, logger=None):
ins_list = self.wildcard(ins)
if ins_list is not None:
return ins_list
if logger is None: if logger is None:
class logger: class logger:
@staticmethod @staticmethod
@ -349,10 +367,15 @@ class ServiceManager:
os.chdir(wd) os.chdir(wd)
def do_restart(self, ins, service=None, cfg=None, logger=None): def do_restart(self, ins, service=None, cfg=None, logger=None):
ins_list = self.wildcard(ins)
if ins_list is not None:
return ins_list
self.do_start(ins, service, cfg, True, logger=logger) self.do_start(ins, service, cfg, True, logger=logger)
def do_run(self, ins, service=None, cfg=None): def do_run(self, ins, service=None, cfg=None):
"""for tests: run and wait""" """for tests: run and wait"""
if self.wildcard(ins) is not None:
raise UsageError('no wildcards allowed with %s run' % self.group)
if not service: if not service:
try: try:
service, = self.services service, = self.services
@ -362,17 +385,22 @@ class ServiceManager:
def do_list(self, ins=None, *args): def do_list(self, ins=None, *args):
"""info about running services""" """info about running services"""
show_unused = ins == 'all'
if show_unused:
ins = None
instances = self.wildcard(ins)
if instances is None:
ins_set = {ins}
else:
ins_set = set(instances)
cfginfo = {} cfginfo = {}
procs = self.get_procs(self.all, cfginfo) procs = self.get_procs(self.all, cfginfo)
rows = [] rows = []
merged = OrderedDict() merged = OrderedDict()
show_unused = ins == 'all'
if show_unused:
ins = None
for group, sm in self.all.items(): for group, sm in self.all.items():
sm.get_info() sm.get_info()
for ins_i, info_dict in sm.info.items(): for ins_i, info_dict in sm.info.items():
if ins is not None and ins != ins_i: if ins_i not in ins_set:
continue continue
for serv, port in info_dict.items(): for serv, port in info_dict.items():
if ins_i not in merged: if ins_i not in merged:
@ -417,18 +445,25 @@ class ServiceManager:
if not callable(method): if not callable(method):
raise UsageError('%s is no valid action' % action) raise UsageError('%s is no valid action' % action)
try: try:
method(*args) ins_list = method(*args)
except TypeError as e: except TypeError as e:
errtxt = str(e) errtxt = str(e)
if 'do_%s(' % action in errtxt and 'argument' in errtxt: if 'do_%s(' % action in errtxt and 'argument' in errtxt:
raise UsageError(errtxt) raise UsageError(errtxt)
raise raise
# treat wildcards:
for ins in ins_list or ():
print('\n%s %s %s:' % (action, self.group, ins))
try:
method(ins, *args[1:])
except Exception as e:
print(str(e))
def do_help(self, *args): def do_help(self, *args):
if self.main_ins: if self.main_ins:
usage = self.USAGE.replace(' <instance>', '').replace(' [<instance>]', '') % '' usage = self.USAGE.replace(' <instance>', '').replace(' [<instance>]', '') % ''
else: else:
usage = self.USAGE % ('<instance> is one of %s' % ', '.join(self.info)) usage = self.USAGE % ('<instance> is one of %s' % ', '.join(self.info))
print(usage) print(usage)
def treat_args(self, argdict, unknown=(), extra=()): def treat_args(self, argdict, unknown=(), extra=()):

View File

@ -34,14 +34,15 @@ class FrappyManager(ServiceManager):
USAGE = """ USAGE = """
Usage: Usage:
frappy list [<instance>] frappy list [<instance>] *
frappy start <instance> <service> <cfgfiles> frappy start <instance> <service> <cfgfiles>
frappy restart <instance> [<service>] [<cfgfiles>] frappy restart <instance> [<service>] [<cfgfiles>] *
frappy stop <instance> [<service>] frappy stop <instance> [<service>] *
frappy listcfg <instance> [<service>] # list available cfg files frappy listcfg <instance> [<service>] # list available cfg files
<service> is one of main, stick, addons <service> is one of main, stick, addons
%s %s
* wildcards allowed, using '.' to replace 0 or more arbitrary characters in <instance>
""" """
def config_dirs(self, ins, service): def config_dirs(self, ins, service):
@ -70,6 +71,8 @@ class FrappyManager(ServiceManager):
return start_dir, env return start_dir, env
def do_start(self, ins, service=None, cfg='', restart=False, wait=False, logger=None): def do_start(self, ins, service=None, cfg='', restart=False, wait=False, logger=None):
if self.wildcard(ins) is not None:
raise UsageError('no wildcards allowed with %s start' % self.group)
if cfg and not service and len(self.services) != 1: if cfg and not service and len(self.services) != 1:
raise UsageError('need service to start (one of %s)' % ', '.join(self.services)) raise UsageError('need service to start (one of %s)' % ', '.join(self.services))
super().do_start(ins, service, cfg, restart, wait, logger) super().do_start(ins, service, cfg, restart, wait, logger)

View File

@ -26,7 +26,7 @@ import shutil
from glob import glob from glob import glob
from os.path import join, abspath, dirname, basename, expanduser, exists, islink from os.path import join, abspath, dirname, basename, expanduser, exists, islink
from configparser import ConfigParser from configparser import ConfigParser
from servicemanager.base import ServiceManager from servicemanager.base import ServiceManager, UsageError
ENV_KEYS = { ENV_KEYS = {
@ -56,16 +56,16 @@ class NicosManager(ServiceManager):
nicos gui <instance> nicos gui <instance>
nicos <instance> (the same as above) nicos <instance> (the same as above)
nicos list [<instance>] nicos list [<instance>] *
nicos start <instance> [<service>] nicos start <instance> [<service>] *
nicos restart <instance> [<service>] nicos restart <instance> [<service>] *
nicos stop <instance> [<service>] nicos stop <instance> [<service>] *
nicos create <instance> <nr> nicos create <instance> <nr> *
nicos create all
nicos link <instance> (create links to nicos data and scripts) nicos link <instance> (create links to nicos data and scripts)
<service> is one of main, stick, addons <service> is one of main, stick, addons
%s %s
* wildcards allowed, using '.' to replace 0 or more arbitrary characters in <instance>
to be done after the experiment: to be done after the experiment:
nicos copy (copy data and scripts from link) nicos copy (copy data and scripts from link)
@ -87,12 +87,14 @@ class NicosManager(ServiceManager):
env['NICOS_PACKAGE'] = basename(dirname(instdir[0])) env['NICOS_PACKAGE'] = basename(dirname(instdir[0]))
def do_create(self, ins, *args): def do_create(self, ins, *args):
self.get_info() if ins == 'check':
if ins == 'all' or ins == 'check': ins_list = self.wildcard(None)
inslist = list(self.info)
else: else:
inslist = [ins] ins_list = self.wildcard(ins)
for ins_i in inslist: if ins_list is None:
ins_list = [ins]
self.get_info()
for ins_i in ins_list:
env = self.env[ins_i] env = self.env[ins_i]
base = join(env['NICOS_ROOT'], env['NICOS_PACKAGE'], ins) base = join(env['NICOS_ROOT'], env['NICOS_PACKAGE'], ins)
nicos_conf = join(base, 'nicos.conf') nicos_conf = join(base, 'nicos.conf')
@ -238,6 +240,8 @@ class NicosManager(ServiceManager):
return start_dir, env return start_dir, env
def prepare_client(self, ins): def prepare_client(self, ins):
if self.wildcard(ins):
raise UsageError('wildcards not allowed')
self.check_running(ins, 'daemon') self.check_running(ins, 'daemon')
env = self.prepare_start(ins, 'daemon')[1] env = self.prepare_start(ins, 'daemon')[1]
os.environ.update(env) os.environ.update(env)

View File

@ -52,15 +52,16 @@ class SeaManager(ServiceManager):
Usage: Usage:
sea gui <instance> sea gui <instance>
sea <instance> # the same as sea gui <instance> sea <instance> # the same as sea gui <instance>
sea cli <instance> # the same as old seacmd sea cli <instance> # the same as old seacmd
sea start <instance> [<service>] # the same as old 'monit start sea' sea start <instance> [<service>] * # the same as old 'monit start sea'
sea restart <instance> [<service>] sea restart <instance> [<service>] *
sea stop <instance> [<service>] sea stop <instance> [<service>] *
sea list [<instance>] sea list [<instance>] *
<service> is one of sea, graph <service> is one of sea, graph
%s %s
* wildcards allowed, using '.' to replace 0 or more arbitrary characters in <instance>
""" """
def do_cli(self, ins): def do_cli(self, ins):