added core-manage tool for addons to add/remove/check services and models
(Boeing r1851)
This commit is contained in:
parent
e6ff3b4cce
commit
71927274cd
4 changed files with 241 additions and 1 deletions
210
daemon/sbin/core-manage
Executable file
210
daemon/sbin/core-manage
Executable file
|
@ -0,0 +1,210 @@
|
||||||
|
#!/usr/bin/env python
|
||||||
|
#
|
||||||
|
# CORE
|
||||||
|
# Copyright (c)2014 the Boeing Company.
|
||||||
|
# See the LICENSE file included in this distribution.
|
||||||
|
#
|
||||||
|
# author: Jeff Ahrenholz <jeffrey.m.ahrenholz@boeing.com>
|
||||||
|
#
|
||||||
|
'''
|
||||||
|
core-manage: Helper tool to add, remove, or check for services and models in
|
||||||
|
a CORE installation.
|
||||||
|
'''
|
||||||
|
|
||||||
|
import os
|
||||||
|
import sys
|
||||||
|
import ast
|
||||||
|
import optparse
|
||||||
|
|
||||||
|
from core import pycore
|
||||||
|
from core.constants import CORE_CONF_DIR
|
||||||
|
|
||||||
|
# core-manage add emane_model RfPipeNew
|
||||||
|
# core-manage add service MyService
|
||||||
|
|
||||||
|
class FileUpdater(object):
|
||||||
|
''' Helper class for changing configuration files.
|
||||||
|
'''
|
||||||
|
actions = ("add", "remove", "check")
|
||||||
|
targets = ("service", "model")
|
||||||
|
|
||||||
|
def __init__(self, action, target, data, verbose=False):
|
||||||
|
'''
|
||||||
|
'''
|
||||||
|
self.action = action
|
||||||
|
self.target = target
|
||||||
|
self.data = data
|
||||||
|
self.verbose = verbose
|
||||||
|
self.search, self.filename = self.get_filename(target)
|
||||||
|
|
||||||
|
def process(self):
|
||||||
|
''' Invoke update_file() using a helper method depending on target.
|
||||||
|
'''
|
||||||
|
if self.verbose:
|
||||||
|
txt = "Updating"
|
||||||
|
if self.action == "check":
|
||||||
|
txt = "Checking"
|
||||||
|
sys.stdout.write("%s file: '%s'\n" % (txt, self.filename))
|
||||||
|
|
||||||
|
if self.target == "service":
|
||||||
|
r = self.update_file(fn=self.update_services)
|
||||||
|
elif self.target == "model":
|
||||||
|
r = self.update_file(fn=self.update_emane_models)
|
||||||
|
|
||||||
|
if self.verbose:
|
||||||
|
txt = ""
|
||||||
|
if not r:
|
||||||
|
txt = "NOT "
|
||||||
|
if self.action == "check":
|
||||||
|
sys.stdout.write("String %sfound.\n" % txt)
|
||||||
|
else:
|
||||||
|
sys.stdout.write("File %supdated.\n" % txt)
|
||||||
|
|
||||||
|
return r
|
||||||
|
|
||||||
|
def update_services(self, line):
|
||||||
|
''' Modify the __init__.py file having this format:
|
||||||
|
__all__ = ["quagga", "nrl", "xorp", "bird", ]
|
||||||
|
Returns True or False when "check" is the action, a modified line
|
||||||
|
otherwise.
|
||||||
|
'''
|
||||||
|
line = line.strip('\n')
|
||||||
|
key, valstr = line.split('= ')
|
||||||
|
vals = ast.literal_eval(valstr)
|
||||||
|
r = self.update_keyvals(key, vals)
|
||||||
|
if self.action == "check":
|
||||||
|
return r
|
||||||
|
valstr = '%s' % r
|
||||||
|
return '= '.join([key, valstr]) + '\n'
|
||||||
|
|
||||||
|
|
||||||
|
def update_emane_models(self, line):
|
||||||
|
''' Modify the core.conf file having this format:
|
||||||
|
emane_models = RfPipe, Ieee80211abg, CommEffect, Bypass
|
||||||
|
Returns True or False when "check" is the action, a modified line
|
||||||
|
otherwise.
|
||||||
|
'''
|
||||||
|
line = line.strip('\n')
|
||||||
|
key, valstr = line.split('= ')
|
||||||
|
vals = valstr.split(', ')
|
||||||
|
r = self.update_keyvals(key, vals)
|
||||||
|
if self.action == "check":
|
||||||
|
return r
|
||||||
|
valstr = ', '.join(r)
|
||||||
|
return '= '.join([key, valstr]) + '\n'
|
||||||
|
|
||||||
|
def update_keyvals(self, key, vals):
|
||||||
|
''' Perform self.action on (key, vals).
|
||||||
|
Returns True or False when "check" is the action, a modified line
|
||||||
|
otherwise.
|
||||||
|
'''
|
||||||
|
if self.action == "check":
|
||||||
|
if self.data in vals:
|
||||||
|
return True
|
||||||
|
else:
|
||||||
|
return False
|
||||||
|
elif self.action == "add":
|
||||||
|
if self.data not in vals:
|
||||||
|
vals.append(self.data)
|
||||||
|
elif self.action == "remove":
|
||||||
|
try:
|
||||||
|
vals.remove(self.data)
|
||||||
|
except ValueError:
|
||||||
|
pass
|
||||||
|
return vals
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def get_filename(target):
|
||||||
|
''' Return search string and filename based on target.
|
||||||
|
'''
|
||||||
|
if target == "service":
|
||||||
|
pypath = os.path.dirname(pycore.__file__)
|
||||||
|
filename = os.path.join(pypath, "services", "__init__.py")
|
||||||
|
search = "__all__ ="
|
||||||
|
elif target == "model":
|
||||||
|
filename = os.path.join(CORE_CONF_DIR, "core.conf")
|
||||||
|
search = "emane_models ="
|
||||||
|
else:
|
||||||
|
raise ValueError, "unknown target"
|
||||||
|
if not os.path.exists(filename):
|
||||||
|
raise ValueError, "file '%s' does not exist" % filename
|
||||||
|
return search, filename
|
||||||
|
|
||||||
|
def update_file(self, fn=None):
|
||||||
|
''' Open a file and search for self.search, invoking the supplied
|
||||||
|
function on the matching line. Write file changes if necessary.
|
||||||
|
Returns True if the file has changed (or action is "check" and the
|
||||||
|
search string is found), False otherwise.
|
||||||
|
'''
|
||||||
|
changed = False
|
||||||
|
output = "" # this accumulates output, assumes input is small
|
||||||
|
with open(self.filename, "r") as f:
|
||||||
|
for line in f:
|
||||||
|
if line[:len(self.search)] == self.search:
|
||||||
|
r = fn(line) # line may be modified by fn() here
|
||||||
|
if self.action == "check":
|
||||||
|
return r
|
||||||
|
else:
|
||||||
|
if line != r:
|
||||||
|
changed = True
|
||||||
|
line = r
|
||||||
|
output += line
|
||||||
|
if changed:
|
||||||
|
with open(self.filename, "w") as f:
|
||||||
|
f.write(output)
|
||||||
|
|
||||||
|
return changed
|
||||||
|
|
||||||
|
|
||||||
|
def main():
|
||||||
|
usagestr = "usage: %prog [-h] [options] <action> <target> <string>\n"
|
||||||
|
usagestr += "\nHelper tool to add, remove, or check for "
|
||||||
|
usagestr += "services and models in a CORE\ninstallation.\n"
|
||||||
|
usagestr += "\nExamples:\n %prog add service newrouting"
|
||||||
|
usagestr += "\n %prog -v check model RfPipe\n"
|
||||||
|
usagestr += "\nArguments:\n <action> should be one of: %s" % \
|
||||||
|
', '.join(FileUpdater.actions)
|
||||||
|
usagestr += "\n <target> should be one of: %s" % \
|
||||||
|
', '.join(FileUpdater.targets)
|
||||||
|
usagestr += "\n <string> is the text to %s" % \
|
||||||
|
', '.join(FileUpdater.actions)
|
||||||
|
parser = optparse.OptionParser(usage = usagestr)
|
||||||
|
parser.set_defaults(verbose = False,)
|
||||||
|
|
||||||
|
parser.add_option("-v", "--verbose", dest = "verbose", action="store_true",
|
||||||
|
help = "be verbose when performing action")
|
||||||
|
|
||||||
|
def usage(msg = None, err = 0):
|
||||||
|
sys.stdout.write("\n")
|
||||||
|
if msg:
|
||||||
|
sys.stdout.write(msg + "\n\n")
|
||||||
|
parser.print_help()
|
||||||
|
sys.exit(err)
|
||||||
|
|
||||||
|
(options, args) = parser.parse_args()
|
||||||
|
|
||||||
|
if len(args) != 3:
|
||||||
|
usage("Missing required arguments!", 1)
|
||||||
|
|
||||||
|
action = args[0]
|
||||||
|
if action not in FileUpdater.actions:
|
||||||
|
usage("invalid action '%s'" % action, 1)
|
||||||
|
|
||||||
|
target = args[1]
|
||||||
|
if target not in FileUpdater.targets:
|
||||||
|
usage("invalid target '%s'" % target, 1)
|
||||||
|
|
||||||
|
data = args[2]
|
||||||
|
|
||||||
|
try:
|
||||||
|
up = FileUpdater(action, target, data, verbose=options.verbose)
|
||||||
|
r = up.process()
|
||||||
|
except Exception, e:
|
||||||
|
sys.stderr.write("Exception: %s\n" % e)
|
||||||
|
sys.exit(1)
|
||||||
|
if not r:
|
||||||
|
sys.exit(1)
|
||||||
|
sys.exit(0)
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
main()
|
|
@ -12,7 +12,7 @@ if WANT_GUI
|
||||||
endif
|
endif
|
||||||
if WANT_DAEMON
|
if WANT_DAEMON
|
||||||
DAEMON_MANS = vnoded.1 vcmd.1 netns.1 core-daemon.1 coresendmsg.1 \
|
DAEMON_MANS = vnoded.1 vcmd.1 netns.1 core-daemon.1 coresendmsg.1 \
|
||||||
core-cleanup.1 core-xen-cleanup.1
|
core-cleanup.1 core-xen-cleanup.1 core-manage.1
|
||||||
endif
|
endif
|
||||||
man_MANS = $(GUI_MANS) $(DAEMON_MANS)
|
man_MANS = $(GUI_MANS) $(DAEMON_MANS)
|
||||||
|
|
||||||
|
@ -26,6 +26,7 @@ generate-mans:
|
||||||
$(HELP2MAN) --version-string=$(CORE_VERSION) --no-info --source CORE $(top_srcdir)/daemon/sbin/coresendmsg -o coresendmsg.1.new
|
$(HELP2MAN) --version-string=$(CORE_VERSION) --no-info --source CORE $(top_srcdir)/daemon/sbin/coresendmsg -o coresendmsg.1.new
|
||||||
$(HELP2MAN) --version-string=$(CORE_VERSION) --no-info --source CORE $(top_srcdir)/daemon/sbin/core-cleanup -o core-cleanup.1.new
|
$(HELP2MAN) --version-string=$(CORE_VERSION) --no-info --source CORE $(top_srcdir)/daemon/sbin/core-cleanup -o core-cleanup.1.new
|
||||||
$(HELP2MAN) --version-string=$(CORE_VERSION) --no-info --source CORE $(top_srcdir)/daemon/sbin/core-xen-cleanup -o core-xen-cleanup.1.new
|
$(HELP2MAN) --version-string=$(CORE_VERSION) --no-info --source CORE $(top_srcdir)/daemon/sbin/core-xen-cleanup -o core-xen-cleanup.1.new
|
||||||
|
$(HELP2MAN) --version-string=$(CORE_VERSION) --no-info --source CORE $(top_srcdir)/daemon/sbin/core-manage -o core-manage.1.new
|
||||||
|
|
||||||
.PHONY: diff
|
.PHONY: diff
|
||||||
diff:
|
diff:
|
||||||
|
|
28
doc/man/core-manage.1
Normal file
28
doc/man/core-manage.1
Normal file
|
@ -0,0 +1,28 @@
|
||||||
|
.\" DO NOT MODIFY THIS FILE! It was generated by help2man 1.40.4.
|
||||||
|
.TH CORE-MANAGE "1" "July 2014" "CORE" "User Commands"
|
||||||
|
.SH NAME
|
||||||
|
core-manage \- helper tool to add, remove, or check for services and models in a CORE installation.
|
||||||
|
.SH SYNOPSIS
|
||||||
|
.B core-manage
|
||||||
|
[\fI-h\fR] [\fIoptions\fR] \fI<action> <target> <string>\fR
|
||||||
|
.SH DESCRIPTION
|
||||||
|
.TP
|
||||||
|
<action> should be one of: add, remove, check
|
||||||
|
.TP
|
||||||
|
<target> should be one of: service, model
|
||||||
|
.TP
|
||||||
|
<string> is the text to add, remove, check
|
||||||
|
.SH OPTIONS
|
||||||
|
.TP
|
||||||
|
\fB\-h\fR, \fB\-\-help\fR
|
||||||
|
show this help message and exit
|
||||||
|
.TP
|
||||||
|
\fB\-v\fR, \fB\-\-verbose\fR
|
||||||
|
be verbose when performing action
|
||||||
|
.SH EXAMPLES
|
||||||
|
.TP
|
||||||
|
core\-manage add service newrouting
|
||||||
|
.TP
|
||||||
|
core\-manage \fB\-v\fR check model RfPipe
|
||||||
|
.SH "SEE ALSO"
|
||||||
|
.BR core-daemon(1)
|
|
@ -338,6 +338,7 @@ sed -i 's/emane_realtime = True/emane_realtime = False/' /etc/core/core.conf
|
||||||
%{python_sitelib}/core/xen/xen.py*
|
%{python_sitelib}/core/xen/xen.py*
|
||||||
%{_sbindir}/core-cleanup
|
%{_sbindir}/core-cleanup
|
||||||
%{_sbindir}/core-daemon
|
%{_sbindir}/core-daemon
|
||||||
|
%{_sbindir}/core-manage
|
||||||
%{_sbindir}/coresendmsg
|
%{_sbindir}/coresendmsg
|
||||||
%{_sbindir}/core-xen-cleanup
|
%{_sbindir}/core-xen-cleanup
|
||||||
%{_sbindir}/netns
|
%{_sbindir}/netns
|
||||||
|
|
Loading…
Reference in a new issue