diff options
-rw-r--r-- | etc/bash-complete-sunhpc (renamed from sbin/sunhpc-completion-backup) | 10 | ||||
-rw-r--r-- | lib/sunhpc/commands/build/initializes/__init__.py | 10 | ||||
-rw-r--r-- | lib/sunhpc/commands/report/completion/__init__.py | 8 | ||||
-rw-r--r-- | lib/sunhpc/core/app.py | 358 | ||||
-rw-r--r-- | lib/sunhpc/invoke.py | 2 | ||||
-rwxr-xr-x | sbin/check-port | 46 |
6 files changed, 420 insertions, 14 deletions
diff --git a/sbin/sunhpc-completion-backup b/etc/bash-complete-sunhpc index 8eb4f1e..fb272fe 100644 --- a/sbin/sunhpc-completion-backup +++ b/etc/bash-complete-sunhpc @@ -1,4 +1,7 @@ # sunhpc(1) completion +# +# /etc/bash_completion.d/sunhpc +# _sunhpc_array_delete_at() { @@ -40,8 +43,11 @@ _sunhpc() return 0 fi - local IFS=$'\n' - COMPREPLY=( $( compgen -W '$output' -- $cur ) ) + #local IFS=$'\n' + COMPREPLY=( $( compgen -W '$output' -- ${cur} ) ) + + # do not append a space to words that end with = + [[ $COMPREPLY == *= ]] && compopt -o nospace } && complete -F _sunhpc sunhpc diff --git a/lib/sunhpc/commands/build/initializes/__init__.py b/lib/sunhpc/commands/build/initializes/__init__.py index acc87f7..2a93015 100644 --- a/lib/sunhpc/commands/build/initializes/__init__.py +++ b/lib/sunhpc/commands/build/initializes/__init__.py @@ -466,12 +466,12 @@ class Command(command): Networks = ''' CREATE TABLE Networks ( ID integer NOT NULL primary key autoincrement, - Node integer(11) default NULL, - MAC varchar(64) default NULL, - IP varchar(32) default NULL, + Node integer(11) default NULL, + MAC varchar(64) default NULL, + IP varchar(32) default NULL, Name varchar(128) default NULL, - Device varchar(32) default NULL, - Subnet integer(11) default NULL, + Device varchar(32) default NULL, + Subnet integer(11) default NULL, Foreign key(subnet) references subnets(id) on delete cascade on update restrict, Foreign key(node) references nodes(id) on delete cascade on update restrict )''' diff --git a/lib/sunhpc/commands/report/completion/__init__.py b/lib/sunhpc/commands/report/completion/__init__.py index aa75f40..b908d5b 100644 --- a/lib/sunhpc/commands/report/completion/__init__.py +++ b/lib/sunhpc/commands/report/completion/__init__.py @@ -67,7 +67,6 @@ class Command(sunhpc.commands.report.command): if o.MustBeRoot and not self.isRootUser(): sys.exit(0) - results = [] for arg in o.usage().split(): tmp = arg.split('=', 1) @@ -77,14 +76,9 @@ class Command(sunhpc.commands.report.command): tmpstr = arg.replace('[', '') tmpstr = tmpstr.replace(']', '') tmpstr = tmpstr.split('=')[0] + '=' - results.append(tmpstr) - #print (' '.join(results)) - - #print ('--add-interface= --set-net=') - print ('--envs= prefix=') - + print (' '.join(results)) RollName = "base" diff --git a/lib/sunhpc/core/app.py b/lib/sunhpc/core/app.py new file mode 100644 index 0000000..2bc627b --- /dev/null +++ b/lib/sunhpc/core/app.py @@ -0,0 +1,358 @@ +# +# Time for an initial checkin. Datastructure and general layout of the +# code is correct. Still need comparison code for File and RPM objects. +# + +import os +import sys +import types +import sunhpc +import getopt +import sunhpc.invoke +import xml +from xml.sax import saxutils +from xml.sax import handler +from xml.sax import make_parser +from xml.sax._exceptions import SAXParseException + +class Application: + + def __init__(self, argv=None): + + # Applets (code in the kickstart graph) doesn't pass sys.argv + # so pick it up anyway to keep everything working. + + if not argv: + argv = sys.argv + + self.args = [] + self.caller_args = argv[1:] + self.usage_command = os.path.basename(argv[0]) + self.usage_name = 'Application' + self.usage_version = 0 + self.rcfileHandler = RCFileHandler + self.rcfileList = [] + self.rcForce = [] + + self.projectName = 'sunhpc' + self.projectVersionName = 'base' + self.projectVersionMajor = sunhpc.version_major + self.projectVersionMinor = sunhpc.version_minor + self.projectVersionMicro = sunhpc.version_micro + + + self.getopt = sunhpc.core.utils.Struct() + self.getopt.s = [ 'h' ] + self.getopt.l = [ 'help', + 'list-rcfiles', + 'list-project-info', + 'rcfile=' + ] + + # Unset our local + try: + os.environ["LANG"] + except KeyError: + pass + + def run(self): + sys.exit(-1) + + def projectInfo(self): + return [ self.projectName, + self.projectVersionName, + int(self.projectVersionMajor), + int(self.projectVersionMinor), + int(self.projectVersionMicro) ] + + def getArgs(self): + return self.args + + def setArgs(self, argslist): + self.args = argslist + + + def parseArgs(self, rcbase=None): + """Parses the command line arguments and all the relevant + resource-control (RC) files for this application. The usage_command + (generally argv[0]) will determine which the name of our rcfile, + unless overrided with the rcbase argument.""" + + # Save any existing options + args = self.getArgs() + + # First pass to get rcfiles specified on the cmd line + self.setArgs(self.caller_args) + self.parseCommandLine(rcfile=1) + + # Parse Resource Control files + self.setArgs([]) + if not rcbase: + rcbase = self.usage_command + self.parseRC(rcbase) + + for rc in self.rcForce: + self.parseRCFile(rc, rcbase) + + # Command line options always win + self.setArgs(args + self.args + self.caller_args) + self.parseCommandLine() + + + def parseRC(self, rcbase, section=None): + rcfile = rcbase + 'rc' + + if not section: + section = rcbase + + # Where we look for resource-control files. First in + # the default 'etc' location, then HOME, finally in this dir. + # We use data from all three, such that later rc files take + # precedence. + + dirList = [ os.path.join(os.sep,'opt', self.projectName, 'etc') ] + if 'HOME' in os.environ: + dirList.append(os.environ['HOME']) + dirList.append('.') + + # Look for both hidden and visible rc files. + for dir in dirList: + self.parseRCFile(os.path.join(dir, '.' + rcfile), section) + self.parseRCFile(os.path.join(dir, rcfile), section) + + def parseRCFile(self, filename, section): + if os.path.isfile(filename) and filename not in self.rcfileList: + self.rcfileList.append(filename) + file = open(filename, 'r') + parser = make_parser() + handler = self.rcfileHandler(self) + if section: + handler.setSection(section) + parser.setContentHandler(handler) + try: + parser.parse(file) + except SAXParseException as msg: + print (filename, "XML parse exception: ", msg) + file.close() + + def parseCommandLine(self, rcfile=0): + """Calls getopt to parse the command line flags. In + rcfile mode we just get --rcfile options.""" + + short = '' + for e in self.getopt.s: + if isinstance(e, tuple): + short = short + e[0] + else: + short = short + e + + long = [] + for e in self.getopt.l: + if isinstance(e, tuple): + long.append(e[0]) + else: + long.append(e) + + try: + opts, args = getopt.getopt(self.args, short, long) + except getopt.GetoptError as msg: + sys.stderr.write("error - %s\n" % msg) + self.usage() + sys.exit(1) + + for c in opts: + if rcfile: + if c[0] != "--rcfile": + continue + self.parseArg(c) + + if not rcfile: + self.args = args + + def parseArg(self, c): + if c[0] in ('-h', '--help'): + self.help() + sys.exit(0) + elif c[0] == '--list-rcfiles': + print (self.rcfileList) + sys.exit(0) + elif c[0] == '--list-project-info': + print (self.projectInfo()) + sys.exit(0) + elif c[0] == '--rcfile': + self.rcForce.append(c[1]) + else: + return 0 + return 1 + + def usage(self): + + if 'COLUMNS' in os.environ: + cols = os.environ['COLUMNS'] + else: + cols = 80 + + usagelist = [ 'Usage: ', self.usage_command, ' ' ] + + # Build string of argument-free short options. + s = '[-' + for e in self.getopt.s: + if len(e) == 1: + s = s + e + s = s + ']' + if len(s) == 3: + s = '' + usagelist.append(s) + + # Add the argument short options to the above string + for e in self.getopt.s: + if isinstance(e, tuple): + v = e[0] + h = e[1] + else: + v = e + h = 'arg' + if len(v) != 1: + usagelist.append(' [-' + v[:-1] + ' ' + h + ']') + + # Add argument-free long options + for e in self.getopt.l: + if isinstance(e, tuple): + v = e[0] + else: + v = e + if v[len(v)-1] != '=': + usagelist.append(' [--' + v + ']') + + # Add argument long options + for e in self.getopt.l: + if isinstance(e, tuple): + v = e[0] + h = e[1] + else: + v = e + h = 'arg' + if v[len(v)-1] == '=': + usagelist.append(' [--' + v[:-1] + ' ' + h + ']') + + usagelist.append(self.usageTail()) + + # Print the usage, word wrapped to the correct screen size. + print (self.usage_name, '- version', self.usage_version) + l = 0 + s = '' + for e in usagelist: + if l + len(e) <= cols: + s = s + e + l = l + len(e) + else: + print (s) + l = len(e) + s = e + if s: + print (s) + + def help(self): + self.usage() + + def usageTail(self): + return '' + + def getArch(self): + return sunhpc.core.utils.getNativeArch() + +class RCFileHandler(sunhpc.core.utils.ParseXML): + + def __init__(self, application): + sunhpc.core.utils.ParseXML.__init__(self, application) + self.foundSection = 0 + self.section = self.app.usage_command + + def setSection(self, section): + self.section = section + + def startElement(self, name, attrs): + # + # need to convert all the attributes to ascii strings. + # starting in python 2, the xml parser puts the attributes in + # unicode which causes problems with sunhpc apps classes, specifically + # those that append path names found in the attributes to the sys.path + # + newattrs = {} + for (aname, avalue) in attrs.items(): + newattrs[aname] = str(attrs[aname]) + + if self.foundSection: + sunhpc.core.utils.ParseXML.startElement(self, name, newattrs) + elif name == self.section: + self.startElementSection(name, newattrs) + + def endElement(self, name): + if self.foundSection and name == self.foundSection: + self.endElementSection(name) + if self.foundSection: + sunhpc.core.utils.ParseXML.endElement(self, name) + + def getOptions(self): + return self.options + + + # <section parent="base"> + + def startElementSection(self, name, attrs): + parent = attrs.get('parent') + if parent: + self.app.parseRC(parent, parent) + self.foundSection = 1 + + def endElementSection(self, name, attrs): + self.foundSection = 0 + + # <usage> + + def startElement_usage(self, name, attrs): + usageName = attrs.get('name') + usageVersion = attrs.get('version') + + if usageName: + self.app.usage_name = usageName + if usageVersion: + self.app.usage_version = usageVersion + + # <option> + + def startElement_option(self, name, attrs): + argName = attrs.get('name') + # Will return None if value is not present. + argValue = attrs.get('value') + + list = self.app.getArgs() + + if len(argName) > 1: + flag = '--' + argName + + # We differentiate between empty values and + # no value at all. + if argValue is not None: + list.append('%s=%s' % (flag, argValue)) + else: + list.append(flag) + else: + flag = '-' + argName + if argValue: + list.append('%s %s' % (flag, argValue)) + else: + list.append(flag) + + self.app.setArgs(list) + + + # <project> + + def startElement_project(self, name, attrs): + self.app.projectName = attrs.get('name') + self.app.projectVersionName = attrs.get('versionName') + self.app.projectVersionMajor = attrs.get('versionMajor') + self.app.projectVersionMinor = attrs.get('versionMinor') + self.app.projectVersionMicro = attrs.get('versionMicro') + diff --git a/lib/sunhpc/invoke.py b/lib/sunhpc/invoke.py index 44bdb63..c02fe71 100644 --- a/lib/sunhpc/invoke.py +++ b/lib/sunhpc/invoke.py @@ -2,9 +2,11 @@ import sunhpc import sunhpc.core import sunhpc.core.ip +import sunhpc.core.app import sunhpc.core.sql import sunhpc.core.dist import sunhpc.core.files import sunhpc.core.build +import sunhpc.core.utils import sunhpc.core.security import sunhpc.core.partition diff --git a/sbin/check-port b/sbin/check-port new file mode 100755 index 0000000..34564a9 --- /dev/null +++ b/sbin/check-port @@ -0,0 +1,46 @@ +#!/opt/sunpy3/bin/python3 + +import os +import sys +import socket +import sunhpc.invoke + +class App(sunhpc.core.app.Application): + + def __init__(self, argv): + sunhpc.core.app.Application.__init__(self,argv) + + self.usage_name = 'Check Port' + self.usage_version = '4.2' + self.node_name = 'localhost' + self.port_num = 5901 + + nodehelp = '(nodename default=%s)' % self.node_name + porthelp = '(port number default=%d)' % (self.port_num) + self.getopt.l.extend([ ('node=',nodehelp),('port=',porthelp) ]) + self.getopt.s.extend([('n:',nodehelp),('p:',porthelp)]) + + def parseArg(self, c): + sunhpc.core.app.Application.parseArg(self,c) + + key, val = c + if key in ('--port'): + self.port_num = int(val) + elif key in ('--node'): + self.node_name = val + + def run(self): + s = socket.socket(socket.AF_INET,socket.SOCK_STREAM) + try: + s.connect((self.node_name,self.port_num)) + except: + print ('Port(%s) is closed' % self.port_num) + sys.exit(1) + + print ('Port(%s) is open' % self.port_num) + s.close() + sys.exit(0) + +app = App(sys.argv) +app.parseArgs() +app.run() |