diff options
Diffstat (limited to 'cobbler/cobbler.py')
-rwxr-xr-x | cobbler/cobbler.py | 782 |
1 files changed, 23 insertions, 759 deletions
diff --git a/cobbler/cobbler.py b/cobbler/cobbler.py index 99a1935..bbfed97 100755 --- a/cobbler/cobbler.py +++ b/cobbler/cobbler.py @@ -19,748 +19,28 @@ import api import os import os.path import traceback - -from cexceptions import * +import optparse +import commands +import cexceptions from rhpl.translate import _, N_, textdomain, utf8 I18N_DOMAIN = "cobbler" -LOCKING_ENABLED = True -LOCKFILE="/var/lib/cobbler/lock" - -USAGE = _("see 'man cobbler' for instructions") +#################################################### class BootCLI: - - def __init__(self,args): - """ - Build the command line parser and API instances, etc. - """ + def __init__(self): textdomain(I18N_DOMAIN) - self.args = args self.api = api.BootAPI() - self.commands = {} - self.commands['distro'] = { - 'add' : self.distro_add, - 'edit' : self.distro_edit, - 'copy' : self.distro_copy, - 'rename' : self.distro_rename, - 'delete' : self.distro_remove, - 'remove' : self.distro_remove, - 'list' : self.distro_list, - 'report' : self.distro_report - } - self.commands['profile'] = { - 'add' : self.profile_add, - 'edit' : self.profile_edit, - 'copy' : self.profile_copy, - 'rename' : self.profile_rename, - 'delete' : self.profile_remove, - 'remove' : self.profile_remove, - 'list' : self.profile_list, - 'report' : self.profile_report - } - self.commands['system'] = { - 'add' : self.system_add, - 'edit' : self.system_edit, - 'rename' : self.system_rename, - 'copy' : self.system_copy, - 'delete' : self.system_remove, - 'remove' : self.system_remove, - 'list' : self.system_list, - 'report' : self.system_report - } - self.commands['repo'] = { - 'auto-add' : self.repo_auto_add, - 'add' : self.repo_add, - 'edit' : self.repo_edit, - 'rename' : self.repo_rename, - 'copy' : self.repo_copy, - 'delete' : self.repo_remove, - 'remove' : self.repo_remove, - 'list' : self.repo_list, - 'report' : self.repo_report, - 'sync' : self.reposync - } - self.commands['toplevel'] = { - '-v' : self.version, - '--version' : self.version, - 'check' : self.check, - 'validateks' : self.validateks, - 'list' : self.list, - 'report' : self.report, - 'distros' : self.distro, - 'distro' : self.distro, - 'profiles' : self.profile, - 'profile' : self.profile, - 'systems' : self.system, - 'system' : self.system, - 'repos' : self.repo, - 'repo' : self.repo, - 'sync' : self.sync, - 'reposync' : self.reposync, - 'import' : self.import_tree, - 'status' : self.status, - 'reserialize' : self.reserialize, - 'help' : self.usage, - '--help' : self.usage, - '/?' : self.usage - } - - def run(self): - """ - Run the command line and return system exit code - """ - # deserialization is implicit with API construction - # self.api.deserialize() - self.relay_args(self.args[1:], self.commands['toplevel']) - - def usage(self,args): - """ - Print out abbreviated help if user gives bad syntax - """ - print USAGE - - - ########################################################### - # REPORTING FUNCTIONS - - def distro_report(self,args): - if len(args) > 0: - return self.__list_names2(self.api.distros(), args) - else: - return self.__print_sorted(self.api.distros()) - - def system_report(self,args): - if len(args) > 0: - return self.__list_names2(self.api.systems(), args) - else: - return self.__print_sorted(self.api.systems()) - - def profile_report(self,args): - if len(args) > 0: - return self.__list_names2(self.api.profiles(), args) - else: - return self.__print_sorted(self.api.profiles()) - - def repo_report(self,args): - if len(args) > 0: - return self.__list_names2(self.api.repos(), args) - else: - return self.__print_sorted(self.api.repos()) - - def report(self,args): - - args.append("") # filler - match = False - for a in args: - if a == '--distros' or len(args) == 1: - self.distro_report([]) - match = True - if a == '--repos' or len(args) == 1: - self.repo_report([]) - match = True - if a == '--profiles' or len(args) == 1: - self.profile_report([]) - match = True - if a == '--systems' or len(args) == 1: - self.system_report([]) - match = True - if not match and a is not None and a != "": - raise CX(_("cobbler does not understand '%(command)s'") % { "command" : a }) - match = False - - ############################################# - # LISTING FUNCTIONS - - def list(self,args): - self.__tree(self.api.distros(),0) - self.__tree(self.api.repos(),0) - - 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) - - def __list_names(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 __list_names2(self, collection, args): - for p in args: - obj = collection.find(name=p) - if obj is not None: - print obj.printable() - return True - - def system_list(self, args): - if len(args) > 0: - self.__list_names2(self.api.systems(), args) - else: - return self.__list_names(self.api.systems()) - - def distro_list(self, args): - if len(args) > 0: - return self.__list_names2(self.api.distros(),args) - else: - return self.__list_names(self.api.distros()) - - def profile_list(self, args): - if len(args) > 0: - return self.__list_names2(self.api.profiles(),args) - else: - return self.__list_names(self.api.profiles()) - - def repo_list(self, args): - if len(args) > 0: - return self.__list_names2(self.api.repos(),args) - else: - return self.__list_names(self.api.repos()) - - ############################################################### - # UTILITY FUNCTIONS - - def find_arg(self,haystack,needle): - for arg in haystack: - arg2 = arg.replace('"','') - if arg2.startswith(needle): - tokens = arg2.split("=") - if len(tokens) >= 1: - return "".join(tokens[1:]) - return None - - def replace_names(self,haystack,newname): - args2 = [] - for arg in haystack: - if arg.startswith("--name"): - args2.append("--name=%s" % newname) - else: - args2.append(arg) - return args2 - - - 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 - - ###################################################################### - # BASIC FRAMEWORK - - def __generic_add(self,args,new_fn,control_fn,does_inherit): - obj = new_fn(is_subobject=does_inherit) - control_fn(args,obj) - - def __generic_edit(self,args,collection_fn,control_fn,exc_msg): - obj = collection_fn().find(name=self.find_arg(args,"--name")) - name2 = self.find_arg(args,"--newname") - if name2 is not None: - raise CX("objects cannot be renamed with the edit command, use 'rename'") - if obj is None: - raise CX(exc_msg) - control_fn(args,obj) - - def __generic_copy(self,args,collection_fn,control_fn,exc_msg): - obj = collection_fn().find(name=self.find_arg(args,"--name")) - obj2 = self.find_arg(args,"--newname") - if obj is None: - raise CX(exc_msg) - args = self.replace_names(args, obj2) - obj3 = obj.make_clone() - obj3.set_name(obj2) - control_fn(args,obj3) - - def __generic_rename(self,args,collection_fn,control_fn,exc_msg): - objname = self.find_arg(args,"--name") - if objname is None: - raise CX(_("at least one required parameter is missing. See 'man cobbler'.")) - objname2 = self.find_arg(args,"--newname") - if objname2 is None: - raise CX(_("at least one required parameter is missing. See 'man cobbler'.")) - self.__generic_copy(args,collection_fn,control_fn,exc_msg) - if objname != objname2: - collection_fn().remove(objname, with_delete=True) - - # new cobbler does not require explicit serialize calls - # self.api.serialize() - - def __generic_remove(self,args,alias1,alias2,collection_fn): - commands = { - "--%s" % alias1 : lambda(a): collection_fn().remove(a, with_delete=True), - "--%s" % alias2 : lambda(a): collection_fn().remove(a, with_delete=True) - } - on_ok = lambda: True - return self.apply_args(args,commands,on_ok) - - #################################################################### - # REMOVAL FUNCTIONS - - def distro_remove(self,args): - return self.__generic_remove(args,"distro","name",self.api.distros) - - def profile_remove(self,args): - return self.__generic_remove(args,"profile","name",self.api.profiles) - - def system_remove(self,args): - return self.__generic_remove(args,"system","name",self.api.systems) - - def repo_remove(self,args): - return self.__generic_remove(args,"repo","name",self.api.repos) - - #################################################################### - # COPY FUNCTIONS - - def distro_copy(self,args): - exc = _("distribution does not exist") - self.__generic_copy(args,self.api.distros,self.__distro_control,exc) - - def profile_copy(self,args): - exc = _("profile does not exist") - self.__generic_copy(args,self.api.profiles,self.__profile_control,exc) - - def system_copy(self,args): - exc = _("system does not exist") - self.__generic_copy(args,self.api.systems,self.__system_control,exc) - - def repo_copy(self,args): - exc = _("repository does not exist") - self.__generic_copy(args,self.api.repos,self.__repo_control,exc) - - ##################################################################### - # RENAME FUNCTIONS - - def distro_rename(self,args): - exc = _("distribution does not exist") - self.__generic_rename(args,self.api.distros,self.__distro_control,exc) - - def profile_rename(self,args): - exc = _("profile does not exist") - self.__generic_rename(args,self.api.profiles,self.__profile_control,exc) - - def system_rename(self,args): - exc = _("system does not exist") - self.__generic_rename(args,self.api.systems,self.__system_control,exc) - - def repo_rename(self,args): - exc = _("repository does not exist") - self.__generic_rename(args,self.api.repos,self.__repo_control,exc) - - ##################################################################### - # EDIT FUNCTIONS - - def distro_edit(self,args): - exc = _("distribution does not exist") - self.__generic_edit(args,self.api.distros,self.__distro_control,exc) - - def profile_edit(self,args): - exc = _("profile does not exist") - self.__generic_edit(args,self.api.profiles,self.__profile_control,exc) - - def system_edit(self,args): - exc = _("system does not exist") - self.__generic_edit(args,self.api.systems,self.__system_control,exc) - - def repo_edit(self,args): - exc = _("repository does not exist") - self.__generic_edit(args,self.api.repos,self.__repo_control,exc) - - ##################################################################### - # ADD FUNCTIONS - - def __prescan_for_inheritance_args(self,args): - """ - Normally we just feed all the arguments through to the functions - in question, but here, we need to send a special flag to the foo_add - functions if we are creating a subobject, because that needs to affect - what function calls we make. So, this checks to see if the user - is creating a subobject by looking for --inherit in the arguments list, - before we actually parse the --inherit arg. Complicated :) - """ - for x in args: - try: - key, value = x.split("=",1) - value = value.replace('"','').replace("'",'') - if key == "--inherit": - return True - except: - pass - return False - - def distro_add(self,args): - does_inherit = self.__prescan_for_inheritance_args(args) - self.__generic_add(args,self.api.new_distro,self.__distro_control,does_inherit) - - def profile_add(self,args): - does_inherit = self.__prescan_for_inheritance_args(args) - self.__generic_add(args,self.api.new_profile,self.__profile_control,does_inherit) - - def system_add(self,args): - does_inherit = self.__prescan_for_inheritance_args(args) - self.__generic_add(args,self.api.new_system,self.__system_control,does_inherit) - - def repo_auto_add(self, args): - self.api.auto_add_repos() - - def repo_add(self,args): - does_inherit = self.__prescan_for_inheritance_args(args) - self.__generic_add(args,self.api.new_repo,self.__repo_control,does_inherit) - - - ############################################################### - # CONTROL IMPLEMENTATIONS - - def __profile_control(self,args,profile,newname=None): - """ - Create/Edit a profile: 'cobbler profile edit --name='foo' ... - """ - commands = { - '--name' : lambda(a) : profile.set_name(a), - '--inherit' : lambda(a) : profile.set_parent(a), - '--newname' : lambda(a) : True, - '--profile' : lambda(a) : profile.set_name(a), - '--distro' : lambda(a) : profile.set_distro(a), - '--kickstart' : lambda(a) : profile.set_kickstart(a), - '--kick-start' : lambda(a) : profile.set_kickstart(a), - '--answers' : lambda(a) : profile.set_kickstart(a), - '--kopts' : lambda(a) : profile.set_kernel_options(a), - '--virt-file-size' : lambda(a) : profile.set_virt_file_size(a), - '--virt-ram' : lambda(a) : profile.set_virt_ram(a), - '--virt-bridge' : lambda(a) : profile.set_virt_bridge(a), - '--virt-cpus' : lambda(a) : profile.set_virt_cpus(a), - '--ksmeta' : lambda(a) : profile.set_ksmeta(a), - '--repos' : lambda(a) : profile.set_repos(a), - '--virt-path' : lambda(a) : profile.set_virt_path(a), - '--virt-type' : lambda(a) : profile.set_virt_type(a), - '--dhcp-tag' : lambda(a) : profile.set_dhcp_tag(a), - '--server-override' : lambda(a) : profile.set_server(a) - } - def on_ok(): - if newname is not None: - profile.set_name(newname) - self.api.profiles().add(profile, with_copy=True) - return self.apply_args(args,commands,on_ok) - - def __repo_control(self,args,repo,newname=None): - """ - Create/edit a repo: 'cobbler repo add --name='foo' ... - """ - commands = { - '--name' : lambda(a): repo.set_name(a), - '--newname' : lambda(a): True, - '--mirror-name' : lambda(a): repo.set_name(a), - '--mirror' : lambda(a): repo.set_mirror(a), - '--keep-updated' : lambda(a): repo.set_keep_updated(a), - '--rpm-list' : lambda(a): repo.set_rpm_list(a), - '--createrepo-flags' : lambda(a): repo.set_createrepo_flags(a), - '--arch' : lambda(a): repo.set_arch(a) - } - def on_ok(): - if newname is not None: - repo.set_name(newname) - self.api.repos().add(repo, with_copy=True) - return self.apply_args(args,commands,on_ok) - - def __distro_control(self,args,distro): - """ - Create/Edit a distro: 'cobbler distro edit --name='foo' ... - """ - commands = { - '--name' : lambda(a) : distro.set_name(a), - '--newname' : lambda(a) : True, - '--distro' : lambda(a) : distro.set_name(a), - '--kernel' : lambda(a) : distro.set_kernel(a), - '--initrd' : lambda(a) : distro.set_initrd(a), - '--kopts' : lambda(a) : distro.set_kernel_options(a), - '--arch' : lambda(a) : distro.set_arch(a), - '--ksmeta' : lambda(a) : distro.set_ksmeta(a), - '--breed' : lambda(a) : distro.set_breed(a) - } - def on_ok(): - self.api.distros().add(distro, with_copy=True) - return self.apply_args(args,commands,on_ok) - - def __system_control(self,args,sys): - """ - Create/Edit a system: 'cobbler system edit --name='foo' ... - """ - - # This copy/paste is heinous evil, please forgive me. - # there was a loop here but the python optimizers seemed to do wierd - # things with the lambda handling. To be resolved when this - # command line gets refactored to use optparse. - - commands = { - '--name' : lambda(a) : sys.set_name(a), - '--newname' : lambda(a) : True, - '--system' : lambda(a) : sys.set_name(a), - '--profile' : lambda(a) : sys.set_profile(a), - '--kopts' : lambda(a) : sys.set_kernel_options(a), - '--ksmeta' : lambda(a) : sys.set_ksmeta(a), - '--hostname' : lambda(a) : sys.set_hostname(a,"intf0"), - '--hostname0' : lambda(a) : sys.set_hostname(a,"intf0"), - '--hostname1' : lambda(a) : sys.set_hostname(a,"intf1"), - '--hostname2' : lambda(a) : sys.set_hostname(a,"intf2"), - '--hostname3' : lambda(a) : sys.set_hostname(a,"intf3"), - '--hostname4' : lambda(a) : sys.set_hostname(a,"intf4"), - '--hostname5' : lambda(a) : sys.set_hostname(a,"intf5"), - '--hostname6' : lambda(a) : sys.set_hostname(a,"intf6"), - '--hostname7' : lambda(a) : sys.set_hostname(a,"intf7"), - '--ip' : lambda(a) : sys.set_ip_address(a,"intf0"), - '--ip0' : lambda(a) : sys.set_ip_address(a,"intf0"), - '--ip1' : lambda(a) : sys.set_ip_address(a,"intf1"), - '--ip2' : lambda(a) : sys.set_ip_address(a,"intf2"), - '--ip3' : lambda(a) : sys.set_ip_address(a,"intf3"), - '--ip4' : lambda(a) : sys.set_ip_address(a,"intf4"), - '--ip5' : lambda(a) : sys.set_ip_address(a,"intf5"), - '--ip6' : lambda(a) : sys.set_ip_address(a,"intf6"), - '--ip7' : lambda(a) : sys.set_ip_address(a,"intf7"), - '--mac' : lambda(a) : sys.set_mac_address(a,"intf0"), - '--mac0' : lambda(a) : sys.set_mac_address(a,"intf0"), - '--mac1' : lambda(a) : sys.set_mac_address(a,"intf1"), - '--mac2' : lambda(a) : sys.set_mac_address(a,"intf2"), - '--mac3' : lambda(a) : sys.set_mac_address(a,"intf3"), - '--mac4' : lambda(a) : sys.set_mac_address(a,"intf4"), - '--mac5' : lambda(a) : sys.set_mac_address(a,"intf5"), - '--mac6' : lambda(a) : sys.set_mac_address(a,"intf6"), - '--mac7' : lambda(a) : sys.set_mac_address(a,"intf7"), - '--gateway' : lambda(a) : sys.set_gateway(a,"intf0"), - '--gateway0' : lambda(a) : sys.set_gateway(a,"intf0"), - '--gateway1' : lambda(a) : sys.set_gateway(a,"intf1"), - '--gateway2' : lambda(a) : sys.set_gateway(a,"intf2"), - '--gateway3' : lambda(a) : sys.set_gateway(a,"intf3"), - '--gateway4' : lambda(a) : sys.set_gateway(a,"intf4"), - '--gateway5' : lambda(a) : sys.set_gateway(a,"intf5"), - '--gateway6' : lambda(a) : sys.set_gateway(a,"intf6"), - '--gateway7' : lambda(a) : sys.set_gateway(a,"intf7"), - '--subnet' : lambda(a) : sys.set_subnet(a,"intf0"), - '--subnet0' : lambda(a) : sys.set_subnet(a,"intf1"), - '--subnet1' : lambda(a) : sys.set_subnet(a,"intf2"), - '--subnet2' : lambda(a) : sys.set_subnet(a,"intf3"), - '--subnet3' : lambda(a) : sys.set_subnet(a,"intf4"), - '--subnet4' : lambda(a) : sys.set_subnet(a,"intf5"), - '--subnet5' : lambda(a) : sys.set_subnet(a,"intf6"), - '--subnet6' : lambda(a) : sys.set_subnet(a,"intf7"), - '--subnet7' : lambda(a) : sys.set_subnet(a,"intf8"), - '--virt-bridge' : lambda(a) : sys.set_virt_bridge(a,"intf0"), - '--virt-bridge0' : lambda(a) : sys.set_virt_bridge(a,"intf0"), - '--virt-bridge1' : lambda(a) : sys.set_virt_bridge(a,"intf1"), - '--virt-bridge2' : lambda(a) : sys.set_virt_bridge(a,"intf2"), - '--virt-bridge3' : lambda(a) : sys.set_virt_bridge(a,"intf3"), - '--virt-bridge4' : lambda(a) : sys.set_virt_bridge(a,"intf4"), - '--virt-bridge5' : lambda(a) : sys.set_virt_bridge(a,"intf5"), - '--virt-bridge6' : lambda(a) : sys.set_virt_bridge(a,"intf6"), - '--virt-bridge7' : lambda(a) : sys.set_virt_bridge(a,"intf7"), - '--dhcp-tag' : lambda(a) : sys.set_dhcp_tag(a,"intf0"), - '--dhcp-tag0' : lambda(a) : sys.set_dhcp_tag(a,"intf0"), - '--dhcp-tag1' : lambda(a) : sys.set_dhcp_tag(a,"intf1"), - '--dhcp-tag2' : lambda(a) : sys.set_dhcp_tag(a,"intf2"), - '--dhcp-tag3' : lambda(a) : sys.set_dhcp_tag(a,"intf3"), - '--dhcp-tag4' : lambda(a) : sys.set_dhcp_tag(a,"intf4"), - '--dhcp-tag5' : lambda(a) : sys.set_dhcp_tag(a,"intf5"), - '--dhcp-tag6' : lambda(a) : sys.set_dhcp_tag(a,"intf6"), - '--dhcp-tag7' : lambda(a) : sys.set_dhcp_tag(a,"intf7"), - '--kickstart' : lambda(a) : sys.set_kickstart(a), - '--netboot-enabled' : lambda(a) : sys.set_netboot_enabled(a), - '--virt-path' : lambda(a) : sys.set_virt_path(a), - '--virt-type' : lambda(a) : sys.set_virt_type(a), - '--server-override' : lambda(a) : sys.set_server(a) - } - - def on_ok(): - self.api.systems().add(sys, with_copy=True) - return self.apply_args(args,commands,on_ok) - - ################################################################################### - # PARSING FUNCTIONS - - def apply_args(self,args,input_routines,on_ok): - """ - Custom CLI handling, instead of getopt/optparse. - Parses arguments of the form --foo=bar. - 'on_ok' is a callable that is run if all arguments are parsed - successfully. 'input_routines' is a dispatch table of routines - that parse the arguments. See distro_edit for an example. - """ - if len(args) == 0: - raise CX(_("this command requires arguments")) - for x in args: - try: - key, value = x.split("=",1) - value = value.replace('"','').replace("'",'') - except: - raise CX(_("Cobbler was expecting an equal sign in argument '%(argument)s'") % { "argument" : x }) - if input_routines.has_key(key): - input_routines[key](value) - else: - raise CX(_("this command doesn't take an option called '%(argument)s'") % { "argument" : key }) - on_ok() - - # new cobbler does not require explicit serialize calls - # self.api.serialize() - - def relay_args(self, args, commands): - """ - Lookup command args[0] in the dispatch table and - feed it the remaining args[1:-1] as arguments. - """ - if args is None or len(args) == 0: - print USAGE - return True - if args[0] in commands: - commands[args[0]](args[1:]) - else: - raise CX(_("Cobbler does not understand '%(command)s'") % { "command" : args[0] }) - return True - - ################################################ - # GENERAL FUNCTIONS - - def reserialize(self, args): - """ - This command is intentionally not documented in the manpage. - Basically it loads the cobbler config and then reserialize's it's internal state. - It can be used for testing config format upgrades and other development related things. - It has very little purpose in the real world. - """ - self.api.serialize() - return True - - def sync(self, args): - """ - Sync the config file with the system config: 'cobbler sync' - """ - self.api.sync() - return True - - def reposync(self, args): - """ - Sync the repo-specific portions of the config with the filesystem. - 'cobbler reposync'. Intended to be run on cron. - """ - self.api.reposync(args) - return True - - def validateks(self,args): - """ - Scan rendered kickstarts for potential errors, before actual install - """ - return self.api.validateks() - - def version(self,args): - print self.api.version() - return True - - def check(self,args): - """ - Check system for network boot decency/prereqs: 'cobbler check' - """ - 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 - - def status(self,args): - """ - Show the kickstart status for logged kickstart activity. - 'cobbler status [--mode=text|somethingelse]' - """ - self.mode = "text" - if args is None or len(args) == 0: - return self.api.status(self.mode) - def set_mode(a): - if a.lower in [ "text" ]: - self.mode = a - return True - else: - return False - commands = { - '--mode' : set_mode - } - def go_status(): - return self.api.status(self.mode) - return self.apply_args(args, commands, go_status) - - def import_tree(self,args): - """ - Import a directory tree and auto-create distros & profiles. - 'cobbler - """ - self.temp_mirror = None - self.temp_mirror_name = None - self.temp_network_root = None - def set_mirror_name(a): - self.temp_mirror_name = a - def set_mirror(a): - self.temp_mirror = a - def set_network_root(a): - self.temp_network_root = a - def go_import(): - return self.api.import_tree( - self.temp_mirror, - self.temp_mirror_name, - network_root=self.temp_network_root - ) - commands = { - '--path' : lambda(a): set_mirror(a), - '--mirror' : lambda(a): set_mirror(a), - '--mirror-name' : lambda(a): set_mirror_name(a), - '--name' : lambda(a): set_mirror_name(a), - '--available-as' : lambda(a): set_network_root(a) - } - on_ok = lambda: go_import() - return self.apply_args(args,commands,on_ok) - - - ######################################################### - # TOPLEVEL MAPPINGS - - def distro(self,args): - """ - Handles any of the 'cobbler distro' subcommands - """ - return self.relay_args(args, self.commands['distro']) - - def profile(self,args): - """ - Handles any of the 'cobbler profile' subcommands - """ - return self.relay_args(args, self.commands['profile']) - - def system(self,args): - """ - Handles any of the 'cobbler system' subcommands - """ - return self.relay_args(args, self.commands['system']) - - def repo(self,args): - """ - Handles any of the 'cobbler repo' subcommands - """ - return self.relay_args(args, self.commands['repo']) + self.loader = commands.FunctionLoader() + climods = self.api.get_modules_in_category("cli") + for mod in climods: + for fn in mod.cli_functions(self.api): + self.loader.add_func(fn) + + def run(self,args): + return self.loader.run(args) #################################################### @@ -769,33 +49,17 @@ def main(): CLI entry point """ exitcode = 0 - lock_hit = False try: - if LOCKING_ENABLED: - if os.path.exists(LOCKFILE): - lock_hit = True - raise CX(_("Locked. If cobbler is currently running, wait for termination, otherwise remove /var/lib/cobbler/lock")) - try: - lockfile = open(LOCKFILE,"w+") - except: - raise CX(_("Cobbler could not create the lockfile %(lockfile)s. Are you root?") % { "lockfile" : LOCKFILE }) - lockfile.close() - BootCLI(sys.argv).run() - except CobblerException, exc: - print str(exc)[1:-1] # remove framing air quotes - exitcode = 1 - except KeyboardInterrupt: - print _("interrupted.") - exitcode = 1 - except Exception, other: - traceback.print_exc() - exitcode = 1 - if LOCKING_ENABLED and not lock_hit: - try: - os.remove(LOCKFILE) - except: - pass - return exitcode + # 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 + else: + (t, val, tb) = sys.exc_info() + print tb.extract_tb().join("\n") + return 1 + if __name__ == "__main__": sys.exit(main()) |