--- /dev/null
+#
+# AFS Server management toolkit: Command line help search
+# -*- coding: utf-8 -*-
+#
+
+__copyright__ = """
+Copyright (C) 2014 Red Hat, Inc. All Rights Reserved.
+Written by David Howells (dhowells@redhat.com)
+
+This program is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public Licence version 2 as
+published by the Free Software Foundation.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public Licence for more details.
+
+You should have received a copy of the GNU General Public Licence
+along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+"""
+
+from afs.exception import AFSException
+from afs.argparse import *
+from afs.lib.output import *
+
+help = "Search by help text"
+
+command_arguments = [
+ [ "topic", get_string, "rs", "<help string>" ],
+]
+
+description = r"""
+Search by help text
+"""
+
+def search_help(prog, cmdsetmod, commands, topic):
+ matches = dict()
+ for i in commands:
+ if i == "help":
+ command = __import__("afs.help", globals(), locals(), ['*'])
+ if topic in command.help.casefold():
+ matches["help"] = command.help
+ continue
+
+ if i == "apropos":
+ if topic in help.casefold():
+ matches["apropos"] = help
+ continue
+
+ command = cmdsetmod.get_command(i)
+ if hasattr(command, "help"):
+ if topic in command.help.casefold():
+ matches[i] = command.help
+ return matches
+
+###############################################################################
+#
+#
+#
+###############################################################################
+def main(params):
+ matches = search_help(params["_prog"], params["_cmdsetmod"], params["_commands"],
+ params["topic"].casefold())
+
+ if not matches:
+ output("Sorry, no commands found\n")
+ else:
+ for i in sorted(matches.keys()):
+ output(i, ": ", matches[i], "\n")
2 of the Licence, or (at your option) any later version.
"""
-from exception import AFSArgumentError
+from exception import AFSArgumentError, AFSHelpFlag
from afs.lib.output import set_verbosity
def get_cell(switch, params):
i = i + 1
if switch == "help":
- raise AFSArgumentError("Print help message")
+ raise AFSHelpFlag
if switch == "":
raise AFSArgumentError("Missing switch name")
from afs.lib.output import *
import kafs
-help = "Restarts a server process"
+help = "Restart a server process"
command_arguments = [
[ "server", get_bosserver, "rs", "<machine name>" ],
}
description = r"""
-Restarts a server process
+Restart a server process
"""
def main(params):
if vldb.volumeId[kafs.ROVOL] != 0:
outputf(" ROnly: {:<10d}", vldb.volumeId[kafs.ROVOL])
if vldb.volumeId[kafs.BACKVOL] != 0:
- outputf " Backup: {:<10d}", vldb.volumeId[kafs.BACKVOL])
+ outputf(" Backup: {:<10d}", vldb.volumeId[kafs.BACKVOL])
output("\n")
display_vldb_site_list(params, vldb, " ")
pass
class AFSArgumentError(AFSException):
- """Base class for all AFS Toolkit exceptions."""
+ """An argument parsing error was encountered"""
+ pass
+
+class AFSHelpFlag(AFSException):
+ """The -help flag was specified to a command."""
pass
+
--- /dev/null
+#
+# AFS Server management toolkit: Command line help
+# -*- coding: utf-8 -*-
+#
+
+__copyright__ = """
+Copyright (C) 2014 Red Hat, Inc. All Rights Reserved.
+Written by David Howells (dhowells@redhat.com)
+
+This program is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public Licence version 2 as
+published by the Free Software Foundation.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public Licence for more details.
+
+You should have received a copy of the GNU General Public Licence
+along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+"""
+
+from afs.exception import AFSException
+from afs.argparse import *
+from afs.lib.output import *
+
+help = "Get help on commandsw"
+
+command_arguments = [
+ [ "topic", get_strings, "om", "<help string>+" ],
+ [ "help", get_dummy, "fn" ],
+]
+
+description = r"""
+Display the server encryption keys from the KeyFile file
+"""
+
+###############################################################################
+#
+# Basic command list
+#
+###############################################################################
+def display_command_list(prog, cmdsetmod, commands):
+ output(prog, ": Commands are:\n")
+ for i in sorted(commands):
+ if i == "help":
+ desc = "Get help on commands"
+ elif i == "apropos":
+ desc = "Search by help text"
+ else:
+ command = cmdsetmod.get_command(i)
+ if hasattr(command, "alias"):
+ desc = "Alias for '" + command.alias + "'"
+ elif not hasattr(command, "help"):
+ desc = "** no help **"
+ else:
+ desc = command.help
+ outputf("{:<15s} {:s}\n", i, desc)
+
+###############################################################################
+#
+# Print a topic
+#
+###############################################################################
+def display_command_arguments(args):
+ for arg in args:
+ if arg[2] == "fn" or arg[2][0] == "o":
+ opt_o = "["
+ opt_c = "]"
+ else:
+ opt_o = ""
+ opt_c = ""
+ output(" ", opt_o, "-", arg[0])
+ if arg[2] != "fn":
+ output(" ", arg[3])
+ output(opt_c)
+ output(" [-help]")
+
+def display_aliases(prog, cmdsetmod, commands, topic):
+ aliases = []
+ for i in commands:
+ if i == "help" or i == "apropos":
+ continue
+ command = cmdsetmod.get_command(i)
+ if hasattr(command, "alias"):
+ if command.alias == topic:
+ aliases.append(i)
+ if aliases:
+ output("aliases: ", aliases[0])
+ if len(aliases) > 1:
+ for i in range(1, len(aliases)):
+ output(", ", aliases[i])
+ output("\n")
+
+def display_help_on_topics(prog, cmdsetmod, commands, topics):
+ for topic in topics:
+ if topic == "help":
+ output("bos help: ", help, "\n")
+ display_command_arguments(command_arguments)
+ continue
+
+ if topic == "apropos":
+ command = __import__("afs.apropos", globals(), locals(), ['*'])
+ output("bos apropos: ", command.help, "\n")
+ display_command_arguments(command.command_arguments)
+ continue
+
+ # See if the command is in the set
+ try:
+ found = False
+ for i in commands:
+ if i == topic:
+ found = topic
+ break
+ if i.startswith(topic):
+ if found:
+ raise RuntimeError("Ambiguous topic '" + topic + "'; use 'apropos' to list\n")
+ found = i
+ if not found:
+ raise RuntimeError("Unknown topic '" + topic + "'\n")
+ topic = found
+ except RuntimeError as e:
+ error(e)
+ set_exitcode(5)
+ continue
+
+ # Load the command module
+ command = cmdsetmod.get_command(topic)
+
+ # If it's an alias, then switch to the real module
+ if hasattr(command, "alias"):
+ alias = " (alias for " + command.alias + ")"
+ command = cmdsetmod.get_command(command.alias)
+ else:
+ alias = ""
+
+ output(prog, " ", topic, ": ", command.help, alias, "\n")
+ display_aliases(prog, cmdsetmod, commands, topic)
+ output("Usage: ", prog, " ", topic)
+ display_command_arguments(command.command_arguments)
+ output("\n")
+ desc = command.description
+ if desc[0] == "\n":
+ desc = desc[1:]
+ output(desc)
+
+###############################################################################
+#
+#
+#
+###############################################################################
+def main(params):
+ prog = params["_prog"]
+ cmdsetmod = params["_cmdsetmod"]
+ commands = params["_commands"]
+
+ if "help" in params:
+ display_help_on_topics(prog, cmdsetmod, commands, [ "help" ])
+ elif "topic" in params:
+ display_help_on_topics(prog, cmdsetmod, commands, params["topic"])
+ else:
+ display_command_list(prog, cmdsetmod, commands)
+
+###############################################################################
+#
+# Handle the -help flag being applied to a command
+#
+###############################################################################
+def helpflag(prog, cmdsetmod, topic, command):
+ output("Usage: ", prog, " ", topic)
+ display_command_arguments(command.command_arguments)
+ output("\n")
global exitcode
return exitcode
+def set_exitcode(n):
+ global exitcode
+ exitcode = n
+
def verbose(*args, **kwargs):
global verbosity
if verbosity:
import afs.commands
from afs.lib.output import *
-from exception import AFSArgumentError
-
-#
-# The commands map
-#
-class Commands(dict):
- """Commands class. It performs on-demand module loading
- """
- def canonical_cmd(self, key):
- """Return the canonical name for a possibly-shortened
- command name.
- """
- candidates = [cmd for cmd in self.keys() if cmd.startswith(key)]
-
- if not candidates:
- out.error('Unknown command: %s' % key,
- 'Try "%s help" for a list of supported commands' % prog)
- sys.exit(2)
-
- if len(candidates) > 1:
- out.error('Ambiguous command: %s' % key,
- 'Candidates are: %s' % ', '.join(candidates))
- sys.exit(2)
-
- return candidates[0]
-
- def __getitem__(self, key):
- cmd_mod = self.get(key) or self.get(self.canonical_cmd(key))
- return afs.commands.get_command(cmd_mod)
-
-#cmd_list = afs.commands.get_commands()
-#print(cmd_list);
-
-#commands = Commands((cmd, mod) for cmd, (mod, kind, help)
-# in cmd_list.iteritems())
-
-def print_help():
- print('usage: %s <command> [options]' % os.path.basename(sys.argv[0]))
- print()
- print('Generic commands:')
- print(' help print the detailed command usage')
- print(' version display version information')
- print(' copyright display copyright information')
- print()
- afs.commands.pretty_command_list(cmd_list, sys.stdout)
+from exception import AFSArgumentError, AFSHelpFlag
+###############################################################################
#
# The main function (command dispatcher)
#
+###############################################################################
def _main():
"""The main function
"""
# Import the command set
cmdsetmod = afs.commands.import_command_set(cmdset)
commands = cmdsetmod.get_command_list()
- #print("CMDS:", commands)
+ commands.append("help")
+ commands.append("apropos")
# See if the command is in the set
found = False
if i.startswith(cmd):
if found:
raise RuntimeError("Command '" + cmd + "' is ambiguous")
- found = cmd
+ found = i
if not found:
raise RuntimeError("Command '" + cmd + "' is unknown")
cmd = found
else:
sys.argv[0] += ' {:s}'.format(cmd)
- command = cmdsetmod.get_command(cmd)
-
- # If it's an alias, then switch to the real module
- if hasattr(command, "alias"):
- cmd = command.alias
+ if cmd == "help":
+ command = __import__("afs.help", globals(), locals(), ['*'])
+ elif cmd == "apropos":
+ command = __import__("afs.apropos", globals(), locals(), ['*'])
+ else:
command = cmdsetmod.get_command(cmd)
+ # If it's an alias, then switch to the real module
+ if hasattr(command, "alias"):
+ cmd = command.alias
+ command = cmdsetmod.get_command(cmd)
+
+ if hasattr(command, "cant_combine_arguments"):
+ cant_combine_arguments = command.cant_combine_arguments
+ else:
+ cant_combine_arguments = {}
if hasattr(command, "argument_size_limits"):
argument_size_limits = command.argument_size_limits
params = afs.argparse.parse_arguments(sys.argv[1:],
command.command_arguments,
argument_size_limits,
- command.cant_combine_arguments)
+ cant_combine_arguments)
except AFSArgumentError as e:
print(prog + ":", e, file=sys.stderr)
sys.exit(2)
+ except AFSHelpFlag:
+ helper = __import__("afs.help", globals(), locals(), ['*'])
+ helper.helpflag(prog, cmdsetmod, cmd, command)
+ sys.exit(0)
# Stick in the default cell if there isn't one
if "cell" not in params:
from afs.lib.cell import cell
params["cell"] = cell()
+ params["_prog"] = prog
+ params["_cmdsetmod"] = cmdsetmod
+ params["_commands"] = commands
+
# These modules are only used from this point onwards and do not
# need to be imported earlier
from afs.exception import AFSException