diff options
author | Michael DeHaan <mdehaan@redhat.com> | 2007-11-19 17:39:15 -0500 |
---|---|---|
committer | Michael DeHaan <mdehaan@redhat.com> | 2007-11-19 17:39:15 -0500 |
commit | 995bf878e03aabd8036498b641253a2c419e3c01 (patch) | |
tree | 38301f5c0300f721185b08a398be29a7f93eca85 | |
parent | 5883ca6b1b8fe371f98db68ac71982affed8b974 (diff) | |
download | third_party-cobbler-995bf878e03aabd8036498b641253a2c419e3c01.tar.gz third_party-cobbler-995bf878e03aabd8036498b641253a2c419e3c01.tar.xz third_party-cobbler-995bf878e03aabd8036498b641253a2c419e3c01.zip |
Further work on CLI modularization. All commands implemented now, except for old
school compatibility translation for list/report. All commands will then need
to be tested...
-rw-r--r-- | cobbler/action_reposync.py | 6 | ||||
-rw-r--r-- | cobbler/api.py | 4 | ||||
-rwxr-xr-x | cobbler/cobbler.py | 14 | ||||
-rw-r--r-- | cobbler/commands.py | 16 | ||||
-rw-r--r-- | cobbler/modules/cli_distro.py | 3 | ||||
-rw-r--r-- | cobbler/modules/cli_misc.py | 291 | ||||
-rw-r--r-- | cobbler/modules/cli_profile.py | 3 | ||||
-rw-r--r-- | cobbler/modules/cli_repo.py | 3 | ||||
-rw-r--r-- | cobbler/modules/cli_system.py | 3 |
9 files changed, 328 insertions, 15 deletions
diff --git a/cobbler/action_reposync.py b/cobbler/action_reposync.py index 1cbb6e2..e67317a 100644 --- a/cobbler/action_reposync.py +++ b/cobbler/action_reposync.py @@ -49,16 +49,16 @@ class RepoSync: # =================================================================== - def run(self, args=[], verbose=True): + def run(self, name=None, verbose=True): """ Syncs the current repo configuration file with the filesystem. """ self.verbose = verbose for repo in self.repos: - if args != [] and repo.name not in args: + if name is not None and repo.name != name: continue - elif args == [] and not repo.keep_updated: + elif name is None and not repo.keep_updated: print _("- %s is set to not be updated") % repo.name continue diff --git a/cobbler/api.py b/cobbler/api.py index cecaa74..1a26385 100644 --- a/cobbler/api.py +++ b/cobbler/api.py @@ -189,13 +189,13 @@ class BootAPI: sync = action_sync.BootSync(self._config) return sync.run() - def reposync(self, args=[]): + def reposync(self, name): """ Take the contents of /var/lib/cobbler/repos and update them -- or create the initial copy if no contents exist yet. """ reposync = action_reposync.RepoSync(self._config) - return reposync.run(args) + return reposync.run(name) def status(self,mode): statusifier = action_status.BootStatusReport(self._config, mode) diff --git a/cobbler/cobbler.py b/cobbler/cobbler.py index bbfed97..fb9b273 100755 --- a/cobbler/cobbler.py +++ b/cobbler/cobbler.py @@ -21,7 +21,7 @@ import os.path import traceback import optparse import commands -import cexceptions +from cexceptions import * from rhpl.translate import _, N_, textdomain, utf8 I18N_DOMAIN = "cobbler" @@ -52,13 +52,15 @@ def main(): try: # FIXME: redo locking code? return BootCLI().run(sys.argv) - except cexceptions.CX, exc: - if str(type(exc)).find("CX") != -1: - print str(exc)[1:-1] # remove framing air quotes + except CX, exc: + print str(exc)[1:-1] # remove framing air quotes + except Exception, exc2: + if str(type(exc2)).find("CX") == -1: + traceback.print_exc() else: - (t, val, tb) = sys.exc_info() - print tb.extract_tb().join("\n") + print str(exc2)[1:-1] # remove framing air quotes return 1 + return 1 if __name__ == "__main__": diff --git a/cobbler/commands.py b/cobbler/commands.py index 88d92b7..e5eb2de 100644 --- a/cobbler/commands.py +++ b/cobbler/commands.py @@ -17,6 +17,8 @@ from cexceptions import * from rhpl.translate import _, N_, textdomain, utf8 import sys +HELP_FORMAT = "%-25s%s" + #============================================================= class FunctionLoader: @@ -69,10 +71,16 @@ class FunctionLoader: Prints out all loaded functions. """ - print "usage:" - print "======" - for name in self.functions.keys(): - print "cobbler %s --help]" % name + print "commands:" + print "=========" + + names = self.functions.keys() + names.sort() + + for name in names: + help = self.functions[name].help_me() + if help != "": + print help #============================================================= diff --git a/cobbler/modules/cli_distro.py b/cobbler/modules/cli_distro.py index ff08e8c..860df90 100644 --- a/cobbler/modules/cli_distro.py +++ b/cobbler/modules/cli_distro.py @@ -26,6 +26,9 @@ import cexceptions class DistroFunction(commands.CobblerFunction): + def help_me(self): + return commands.HELP_FORMAT % ("cobbler distro", "<add|edit|copy|rename|delete> [ARGS|--help]") + def command_name(self): return "distro" diff --git a/cobbler/modules/cli_misc.py b/cobbler/modules/cli_misc.py new file mode 100644 index 0000000..eb66fb0 --- /dev/null +++ b/cobbler/modules/cli_misc.py @@ -0,0 +1,291 @@ +""" +Misc CLI functions. + +Copyright 2007, Red Hat, Inc +Michael DeHaan <mdehaan@redhat.com> + +This software may be freely redistributed under the terms of the GNU +general public license. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +""" + +import distutils.sysconfig +import sys + +plib = distutils.sysconfig.get_python_lib() +mod_path="%s/cobbler" % plib +sys.path.insert(0, mod_path) + +from rhpl.translate import _, N_, textdomain, utf8 +import commands +from cexceptions import * +HELP_FORMAT = commands.HELP_FORMAT + +# TO DO list +# cobbler check +# cobbler import (--name, --mirror, --available-as) +# cobbler reserialize +# cobbler --type=[profile|system|distro|repo] [--name=list] +# cobbler --type=[profile|system|distro|profile] [--name=report] +# cobbler status +# cobbler reposync --name=$name +# cobbler sync +# cobbler validateks +# elsewhere: repo auto-add + +######################################################## + +class CheckFunction(commands.CobblerFunction): + + def help_me(self): + return HELP_FORMAT % ("cobbler check","") + + def command_name(self): + return "check" + + def add_options(self, p, args): + pass + + def run(self): + status = self.api.check() + if len(status) == 0: + print _("No setup problems found") + print _("Manual review and editing of /var/lib/cobbler/settings is recommended to tailor cobbler to your particular configuration.") + print _("Good luck.") + return True + else: + print _("The following potential problems were detected:") + for i,x in enumerate(status): + print _("#%(number)d: %(problem)s") % { "number" : i, "problem" : x } + return False + +######################################################## + +class ImportFunction(commands.CobblerFunction): + + def help_me(self): + return HELP_FORMAT % ("cobbler import","[ARGS|--help]") + + def command_name(self): + return "import" + + def add_options(self, p, args): + p.add_option("--mirror", dest="mirror", help="local path or rsync location (REQUIRED)") + p.add_option("--name", dest="name", help="name, ex 'RHEL-5', (REQUIRED)") + p.add_option("--available-as", dest="available_as", help="do not mirror, use this as install tree") + + def run(self): + if not self.options.mirror: + raise CX(_("mirror is required")) + if not self.options.name: + raise CX(_("name is required")) + return self.api.import_tree( + self.options.mirror, + self.options.name, + network_root=self.options.available_as + ) + + +######################################################## + +class ReserializeFunction(commands.CobblerFunction): + + def help_me(self): + return "" # hide + + def command_name(self): + return "reserialize" + + def run(self): + return self.api.reserialize() + +######################################################## + +class ListFunction(commands.CobblerFunction): + + def help_me(self): + return HELP_FORMAT % ("cobbler list","[ARGS|--help]") + + def command_name(self): + return "list" + + def add_options(self, p, args): + p.add_option("--what", dest="what", default="all", help="all/distros/profiles/systems/repos") + + def run(self): + if self.options.what not in [ "all", "distros", "profiles", "systems", "repos" ]: + raise CX(_("invalid value for --what")) + if self.options.what in [ "all" ]: + self.__tree(self.api.distros(),0) + self.__tree(self.api.repos(),0) + if self.options.what in [ "distros"]: + self.__list(self.api.distros()) + if self.options.what in [ "profiles"]: + self.__list(self.api.profiles()) + if self.options.what in [ "systems" ]: + self.__list(self.api.systems()) + if self.options.what in [ "repos"]: + self.__list(self.api.repos()) + + def __list(self, collection): + names = [ x.name for x in collection] + names.sort() # sorted() is 2.4 only + for name in names: + str = _(" %(name)s") % { "name" : name } + print str + return True + + def __tree(self,collection,level): + for item in collection: + print _("%(indent)s%(type)s %(name)s") % { + "indent" : " " * level, + "type" : item.TYPE_NAME, + "name" : item.name + } + kids = item.get_children() + if kids is not None and len(kids) > 0: + self.__tree(kids,level+1) + +######################################################## + +class ReportFunction(commands.CobblerFunction): + + def help_me(self): + return HELP_FORMAT % ("cobbler report","[ARGS|--help]") + + def command_name(self): + return "report" + + def add_options(self, p, args): + p.add_option("--what", dest="what", default="all", help="distros/profiles/systems/repos (REQUIRED)") + p.add_option("--name", dest="name", help="report on just this object") + + def __list_names2(self, collection, name): + obj = collection.find(name=name) + if obj is not None: + print obj.printable() + return True + + def __sorter(self, a, b): + return cmp(a.name, b.name) + + def __print_sorted(self, collection): + collection = [x for x in collection] + collection.sort(self.__sorter) + for x in collection: + print x.printable() + return True + + def __list_names2(self, collection, name): + obj = collection.find(name=name) + if obj is not None: + print obj.printable() + return True + + def run(self): + if self.options.what not in [ "all", "distros", "profiles", "systems", "repos" ]: + raise CX(_("Invalid value for --what")) + + if self.options.what in [ "all", "distros" ]: + if self.options.name: + self.__list_names2(self.api.distros(),self.options.name) + else: + self.__print_sorted(self.api.distros()) + + if self.options.what in [ "all", "profiles" ]: + if self.options.name: + self.__list_names2(self.api.profiles(),self.options.name) + else: + self.__print_sorted(self.api.profiles()) + + if self.options.what in [ "all", "systems" ]: + if self.options.name: + self.__list_names2(self.api.systems(),self.options.name) + else: + self.__print_sorted(self.api.sytems()) + + if self.options.what in [ "all", "repos" ]: + if self.options.name: + self.__list_names2(self.api.repos(),self.options.name) + else: + self.__print_sorted(self.api.repos()) + return True + +## FIXME: add legacy command translator to keep things simple +## cobbler system report foo --> cobbler report --what=systems --name=foo +## cobbler system report --> cobbler report --what=systems +## ditto for "cobbler list" + +######################################################## + +class StatusFunction(commands.CobblerFunction): + + def help_me(self): + return HELP_FORMAT % ("cobbler status","[ARGS|--help]") + + def command_name(self): + return "status" + + def run(self): + return self.api.status("text") # no other output modes supported yet + +######################################################## + +class SyncFunction(commands.CobblerFunction): + + def help_me(self): + return HELP_FORMAT % ("cobbler sync","") + + def command_name(self): + return "sync" + +######################################################## + +class RepoSyncFunction(commands.CobblerFunction): + + def help_me(self): + return HELP_FORMAT % ("cobbler reposync","[ARGS|--help]") + + def command_name(self): + return "reposync" + + def add_options(self, p, args): + p.add_options("--only", dest="only", help="update only this repository name") + + def run(self): + return self.api.reposync(self.options.only) + +######################################################## + +class ValidateKsFunction(commands.CobblerFunction): + + def help_me(self): + return HELP_FORMAT % ("cobbler validateks","") + + def command_name(self): + return "validateks" + + def run(self): + return self.api.validateks() + +######################################################## +# MODULE HOOKS + +def register(): + """ + The mandatory cobbler module registration hook. + """ + return "cli" + +def cli_functions(api): + return [ + CheckFunction(api), ImportFunction(api), ReserializeFunction(api), + ListFunction(api), ReportFunction(api), StatusFunction(api), + SyncFunction(api), RepoSyncFunction(api), ValidateKsFunction(api) + ] + return [] + + diff --git a/cobbler/modules/cli_profile.py b/cobbler/modules/cli_profile.py index 8385986..a733534 100644 --- a/cobbler/modules/cli_profile.py +++ b/cobbler/modules/cli_profile.py @@ -26,6 +26,9 @@ import cexceptions class ProfileFunction(commands.CobblerFunction): + def help_me(self): + return commands.HELP_FORMAT % ("cobbler profile","<add|edit|copy|rename|delete> [ARGS|--help]") + def command_name(self): return "profile" diff --git a/cobbler/modules/cli_repo.py b/cobbler/modules/cli_repo.py index 09fa234..555b76a 100644 --- a/cobbler/modules/cli_repo.py +++ b/cobbler/modules/cli_repo.py @@ -26,6 +26,9 @@ import cexceptions class RepoFunction(commands.CobblerFunction): + def help_me(self): + return commands.HELP_FORMAT % ("cobbler repo","<add|edit|copy|rename|delete> [ARGS|--help]") + def command_name(self): return "repo" diff --git a/cobbler/modules/cli_system.py b/cobbler/modules/cli_system.py index bfc5c2f..65c0625 100644 --- a/cobbler/modules/cli_system.py +++ b/cobbler/modules/cli_system.py @@ -26,6 +26,9 @@ import cexceptions class SystemFunction(commands.CobblerFunction): + def help_me(self): + return commands.HELP_FORMAT % ("cobbler system","<add|edit|copy|rename|delete> [ARGS|--help]") + def command_name(self): return "system" |