added core-manage tool for addons to add/remove/check services and models

(Boeing r1851)
This commit is contained in:
ahrenholz 2014-07-15 20:30:45 +00:00
parent e6ff3b4cce
commit 71927274cd
4 changed files with 241 additions and 1 deletions

210
daemon/sbin/core-manage Executable file
View 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()

View file

@ -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
View 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)

View file

@ -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