diff options
| author | Michael DeHaan <mdehaan@redhat.com> | 2009-07-15 15:42:20 -0400 |
|---|---|---|
| committer | Michael DeHaan <mdehaan@redhat.com> | 2009-07-15 15:42:20 -0400 |
| commit | ce864ebf6330a98929442103da938b90b35fb8ea (patch) | |
| tree | 62e6d0fba73a13f1a11ffc0f200792f74b0f0e26 | |
| parent | 8cf89470e2fd1a86e540adf2482e4a9f906db028 (diff) | |
| parent | 8580b3943e1c47e3737ed08ffb3202649ccac458 (diff) | |
| download | cobbler-ce864ebf6330a98929442103da938b90b35fb8ea.tar.gz cobbler-ce864ebf6330a98929442103da938b90b35fb8ea.tar.xz cobbler-ce864ebf6330a98929442103da938b90b35fb8ea.zip | |
Merge branch 'master' of ssh://git.fedorahosted.org/git/cobbler
Conflicts:
web/cobbler_web/views.py
31 files changed, 162 insertions, 197 deletions
diff --git a/cobbler.spec b/cobbler.spec index 19b2d061..eb09692d 100644 --- a/cobbler.spec +++ b/cobbler.spec @@ -231,7 +231,6 @@ test "x$RPM_BUILD_ROOT" != "x" && rm -rf $RPM_BUILD_ROOT %dir /var/lib/cobbler/config/systems.d/ %dir /var/lib/cobbler/config/repos.d/ %dir /var/lib/cobbler/config/images.d/ -%dir /var/lib/cobbler/config/networks.d/ %dir /var/lib/cobbler/kickstarts/ %dir /var/lib/cobbler/backup/ %dir /var/lib/cobbler/triggers diff --git a/cobbler/action_litesync.py b/cobbler/action_litesync.py index 5afe74e5..5ce978b2 100644 --- a/cobbler/action_litesync.py +++ b/cobbler/action_litesync.py @@ -47,7 +47,6 @@ class BootLiteSync: self.images = config.images() self.settings = config.settings() self.repos = config.repos() - self.networks = config.networks() if logger is None: logger = clogger.Logger() self.logger = logger @@ -180,8 +179,3 @@ class BootLiteSync: else: utils.rmfile(os.path.join(bootloc, filename)) - # not sure sure I actually need anything special to litesync networks - def add_single_network(self, name): - pass - def remote_single_network(self, name): - pass diff --git a/cobbler/action_sync.py b/cobbler/action_sync.py index d706093c..b4ed9ba8 100644 --- a/cobbler/action_sync.py +++ b/cobbler/action_sync.py @@ -136,8 +136,8 @@ class BootSync: if self.verbose: self.logger.info("running post-sync triggers") - utils.run_triggers(self.api, None, "/var/lib/cobbler/triggers/sync/post/*") - utils.run_triggers(self.api, None, "/var/lib/cobbler/triggers/change/*") + utils.run_triggers(self.api, None, "/var/lib/cobbler/triggers/sync/post/*", logger=self.logger) + utils.run_triggers(self.api, None, "/var/lib/cobbler/triggers/change/*", logger=self.logger) return True diff --git a/cobbler/api.py b/cobbler/api.py index b995e8f6..9f029fa6 100644 --- a/cobbler/api.py +++ b/cobbler/api.py @@ -61,7 +61,6 @@ import item_profile import item_system import item_repo import item_image -import item_network ERROR = 100 INFO = 10 @@ -274,12 +273,6 @@ class BootAPI: """ return self.get_items("image") - def networks(self): - """ - Return the current list of networks - """ - return self.get_items("network") - def settings(self): """ Return the application configuration @@ -316,9 +309,6 @@ class BootAPI: def copy_image(self, ref, newname): return self.copy_item("image", ref, newname, logger=None) - def copy_network(self, ref, newname): - return self.copy_item("network", ref, newname, logger=None) - # ========================================================================== def remove_item(self, what, ref, recursive=False, delete=True, with_triggers=True, logger=None): @@ -342,9 +332,6 @@ class BootAPI: def remove_image(self, ref, recursive=False, delete=True, with_triggers=True): return self.remove_item(self, "image", ref, recursive=recursive, delete=delete, with_triggers=with_triggers, logger=logger) - def remove_network(self, ref, recursive=False, delete=True, with_triggers=True): - return self.remove_item(self, "distro", ref, recursive=recursive, delete=delete, with_triggers=with_triggers, logger=logger) - # ========================================================================== def rename_item(self, what, ref, newname, logger=None): @@ -366,9 +353,6 @@ class BootAPI: def rename_image(self, ref, newname, logger=None): return self.rename_item("image", ref, newname, logger=logger) - def rename_network(self, ref, newname, logger=None): - return self.rename_item("network", ref, newname, logger=logger) - # ========================================================================== # FIXME: add a new_item method @@ -393,10 +377,6 @@ class BootAPI: self.log("new_image",[is_subobject]) return self._config.new_image(is_subobject=is_subobject) - def new_network(self,is_subobject=False): - self.log("new_network",[is_subobject]) - return self._config.new_network(is_subobject=is_subobject) - # ========================================================================== def add_item(self, what, ref, check_for_duplicate_names=False, save=True,logger=None): @@ -418,9 +398,6 @@ class BootAPI: def add_image(self, ref, check_for_duplicate_names=False,save=True, logger=None): return self.add_item("image", ref, check_for_duplicate_names=check_for_duplicate_names, save=save,logger=logger) - def add_network(self, ref, check_for_duplicate_names=False,save=True, logger=None): - return self.add_item("network", ref, check_for_duplicate_names=check_for_duplicate_names, save=save,logger=logger) - # ========================================================================== # FIXME: find_items should take all the arguments the other find @@ -455,9 +432,6 @@ class BootAPI: def find_image(self, name=None, return_list=False, no_errors=False, **kargs): return self._config.images().find(name=name, return_list=return_list, no_errors=no_errors, **kargs) - def find_network(self, name=None, return_list=False, no_errors=False, **kargs): - return self._config.networks().find(name=name, return_list=return_list, no_errors=no_errors, **kargs) - # ========================================================================== def __since(self,mtime,collector,collapse=False): @@ -493,9 +467,6 @@ class BootAPI: def get_images_since(self,mtime,collapse=False): return self.__since(mtime,self.images,collapse=collapse) - def get_networks_since(self,mtime,collapse=False): - return self.__since(mtime,self.networks,collapse=collapse) - # ========================================================================== def dump_vars(self, obj, format=False): diff --git a/cobbler/collection.py b/cobbler/collection.py index ee38065e..2b801ce9 100644 --- a/cobbler/collection.py +++ b/cobbler/collection.py @@ -35,7 +35,6 @@ import item_profile import item_distro import item_repo import item_image -import item_network from utils import _ class Collection(serializable.Serializable): @@ -270,7 +269,7 @@ class Collection(serializable.Serializable): if save: # failure of a pre trigger will prevent the object from being added if with_triggers: - self._run_triggers(self.api, ref,"/var/lib/cobbler/triggers/add/%s/pre/*" % self.collection_type()) + utils.run_triggers(self.api, ref,"/var/lib/cobbler/triggers/add/%s/pre/*" % self.collection_type(), [], logger) self.listing[ref.name.lower()] = ref # save just this item if possible, if not, save @@ -286,8 +285,6 @@ class Collection(serializable.Serializable): self.lite_sync.add_single_distro(ref.name) elif isinstance(ref, item_image.Image): self.lite_sync.add_single_image(ref.name) - elif isinstance(ref, item_network.Network): - self.lite_sync.add_single_network(ref.name) elif isinstance(ref, item_repo.Repo): pass else: @@ -298,8 +295,8 @@ class Collection(serializable.Serializable): # save the tree, so if neccessary, scripts can examine it. if with_triggers: - self._run_triggers(self.api, ref, "/var/lib/cobbler/triggers/change/*") - self._run_triggers(self.api, ref,"/var/lib/cobbler/triggers/add/%s/post/*" % self.collection_type()) + utils.run_triggers(self.api, ref, "/var/lib/cobbler/triggers/change/*", [], logger) + utils.run_triggers(self.api, ref,"/var/lib/cobbler/triggers/add/%s/post/*" % self.collection_type(), [], logger) # update children cache in parent object @@ -309,9 +306,6 @@ class Collection(serializable.Serializable): return True - def _run_triggers(self,api_handle,ref,globber): - return utils.run_triggers(api_handle,ref,globber) - def __duplication_checks(self,ref,check_for_duplicate_names,check_for_duplicate_netinfo): """ Prevents adding objects with the same name. @@ -332,8 +326,6 @@ class Collection(serializable.Serializable): match = self.api.find_repo(ref.name) elif isinstance(ref, item_image.Image): match = self.api.find_image(ref.name) - elif isinstance(ref, item_network.Network): - match = self.api.find_network(ref.name) else: raise CX("internal error, unknown object type") diff --git a/cobbler/collection_distros.py b/cobbler/collection_distros.py index 540eb81c..da3794fd 100644 --- a/cobbler/collection_distros.py +++ b/cobbler/collection_distros.py @@ -64,7 +64,7 @@ class Distros(collection.Collection): if with_delete: if with_triggers: - self._run_triggers(self.config.api, obj, "/var/lib/cobbler/triggers/delete/distro/pre/*") + utils.run_triggers(self.config.api, obj, "/var/lib/cobbler/triggers/delete/distro/pre/*", [], logger) if with_sync: lite_sync = action_litesync.BootLiteSync(self.config, logger=logger) lite_sync.remove_single_distro(name) @@ -75,8 +75,8 @@ class Distros(collection.Collection): if with_delete: self.log_func("deleted distro %s" % name) if with_triggers: - self._run_triggers(self.config.api, obj, "/var/lib/cobbler/triggers/delete/distro/post/*") - self._run_triggers(self.config.api, obj, "/var/lib/cobbler/triggers/change/*") + utils.run_triggers(self.config.api, obj, "/var/lib/cobbler/triggers/delete/distro/post/*", [], logger) + utils.run_triggers(self.config.api, obj, "/var/lib/cobbler/triggers/change/*", [], logger) # look through all mirrored directories and find if any directory is holding diff --git a/cobbler/collection_images.py b/cobbler/collection_images.py index 9f5d0e2e..b2774c00 100644 --- a/cobbler/collection_images.py +++ b/cobbler/collection_images.py @@ -60,7 +60,7 @@ class Images(collection.Collection): if with_delete: if with_triggers: - self._run_triggers(self.config.api, obj, "/var/lib/cobbler/triggers/delete/image/pre/*") + utils.run_triggers(self.config.api, obj, "/var/lib/cobbler/triggers/delete/image/pre/*", [], logger) if with_sync: lite_sync = action_litesync.BootLiteSync(self.config, logger=logger) lite_sync.remove_single_image(name) @@ -71,8 +71,8 @@ class Images(collection.Collection): if with_delete: self.log_func("deleted repo %s" % name) if with_triggers: - self._run_triggers(self.config.api, obj, "/var/lib/cobbler/triggers/delete/image/post/*") - self._run_triggers(self.config.api, obj, "/var/lib/cobbler/triggers/change/*") + utils.run_triggers(self.config.api, obj, "/var/lib/cobbler/triggers/delete/image/post/*", [], logger) + utils.run_triggers(self.config.api, obj, "/var/lib/cobbler/triggers/change/*", [], logger) return True diff --git a/cobbler/collection_profiles.py b/cobbler/collection_profiles.py index 42527a86..755eab8a 100644 --- a/cobbler/collection_profiles.py +++ b/cobbler/collection_profiles.py @@ -67,7 +67,7 @@ class Profiles(collection.Collection): if with_delete: if with_triggers: - self._run_triggers(self.config.api, obj, "/var/lib/cobbler/triggers/delete/profile/pre/*") + utils.run_triggers(self.config.api, obj, "/var/lib/cobbler/triggers/delete/profile/pre/*", [], logger) if with_sync: lite_sync = action_litesync.BootLiteSync(self.config, logger=logger) lite_sync.remove_single_profile(name) @@ -76,8 +76,8 @@ class Profiles(collection.Collection): if with_delete: self.log_func("deleted profile %s" % name) if with_triggers: - self._run_triggers(self.config.api, obj, "/var/lib/cobbler/triggers/delete/profile/post/*") - self._run_triggers(self.config.api, obj, "/var/lib/cobbler/triggers/change/*") + utils.run_triggers(self.config.api, obj, "/var/lib/cobbler/triggers/delete/profile/post/*", [], logger) + utils.run_triggers(self.config.api, obj, "/var/lib/cobbler/triggers/change/*", [], logger) return True diff --git a/cobbler/collection_repos.py b/cobbler/collection_repos.py index a6d21e28..10215843 100644 --- a/cobbler/collection_repos.py +++ b/cobbler/collection_repos.py @@ -56,7 +56,7 @@ class Repos(collection.Collection): if obj is not None: if with_delete: if with_triggers: - self._run_triggers(self.config.api, obj, "/var/lib/cobbler/triggers/delete/repo/pre/*") + utils.run_triggers(self.config.api, obj, "/var/lib/cobbler/triggers/delete/repo/pre/*", [], logger) del self.listing[name] self.config.serialize_delete(self, obj) @@ -64,8 +64,8 @@ class Repos(collection.Collection): if with_delete: self.log_func("deleted repo %s" % name) if with_triggers: - self._run_triggers(self.config.api, obj, "/var/lib/cobbler/triggers/delete/repo/post/*") - self._run_triggers(self.config.api, obj, "/var/lib/cobbler/triggers/change/*") + utils.run_triggers(self.config.api, obj, "/var/lib/cobbler/triggers/delete/repo/post/*", [], logger) + utils.run_triggers(self.config.api, obj, "/var/lib/cobbler/triggers/change/*", [], logger) path = "/var/www/cobbler/repo_mirror/%s" % obj.name diff --git a/cobbler/collection_systems.py b/cobbler/collection_systems.py index 45d0fb79..19e99900 100644 --- a/cobbler/collection_systems.py +++ b/cobbler/collection_systems.py @@ -52,7 +52,7 @@ class Systems(collection.Collection): if with_delete: if with_triggers: - self._run_triggers(self.config.api, obj, "/var/lib/cobbler/triggers/delete/system/pre/*") + utils.run_triggers(self.config.api, obj, "/var/lib/cobbler/triggers/delete/system/pre/*", [], logger) if with_sync: lite_sync = action_litesync.BootLiteSync(self.config, logger=logger) lite_sync.remove_single_system(name) @@ -61,8 +61,8 @@ class Systems(collection.Collection): if with_delete: self.log_func("deleted system %s" % name) if with_triggers: - self._run_triggers(self.config.api, obj, "/var/lib/cobbler/triggers/delete/system/post/*") - self._run_triggers(self.config.api, obj, "/var/lib/cobbler/triggers/change/*") + utils.run_triggers(self.config.api, obj, "/var/lib/cobbler/triggers/delete/system/post/*", [], logger) + utils.run_triggers(self.config.api, obj, "/var/lib/cobbler/triggers/change/*", [], logger) return True diff --git a/cobbler/config.py b/cobbler/config.py index 5ec211a9..df4a589e 100644 --- a/cobbler/config.py +++ b/cobbler/config.py @@ -32,14 +32,12 @@ import item_profile as profile import item_system as system import item_repo as repo import item_image as image -import item_network as network import collection_distros as distros import collection_profiles as profiles import collection_systems as systems import collection_repos as repos import collection_images as images -import collection_networks as networks import modules.serializer_yaml as serializer_yaml import settings @@ -78,7 +76,6 @@ class Config: self._profiles = profiles.Profiles(weakref.proxy(self)) self._systems = systems.Systems(weakref.proxy(self)) self._images = images.Images(weakref.proxy(self)) - self._networks = networks.Networks(weakref.proxy(self)) self._settings = settings.Settings() # not a true collection def generate_uid(self): @@ -130,12 +127,6 @@ class Config: """ return self._images - def networks(self): - """ - Return the definitive copy of the Networks collection - """ - return self._networks - def new_distro(self,is_subobject=False): """ Create a new distro object with a backreference to this object @@ -166,12 +157,6 @@ class Config: """ return image.Image(weakref.proxy(self),is_subobject=is_subobject) - def new_network(self,is_subobject=False): - """ - Create a new network object... - """ - return network.Network(weakref.proxy(self),is_subobject=is_subobject) - def clear(self): """ Forget about all loaded configuration data @@ -182,7 +167,6 @@ class Config: self._profiles.clear(), self._images.clear() self._systems.clear(), - self._networks.clear(), return True def serialize(self): @@ -194,7 +178,6 @@ class Config: serializer.serialize(self._profiles) serializer.serialize(self._images) serializer.serialize(self._systems) - serializer.serialize(self._networks) return True def serialize_item(self,collection,item): @@ -224,7 +207,6 @@ class Config: serializer.deserialize(self._profiles) serializer.deserialize(self._images) serializer.deserialize(self._systems) - serializer.deserialize(self._networks) return True def deserialize_raw(self,collection_type): @@ -250,8 +232,6 @@ class Config: result=self._repos elif collection_type == "image": result=self._images - elif collection_type == "network": - result=self._networks else: raise CX("internal error, collection name %s not supported" % collection_type) return result diff --git a/cobbler/field_info.py b/cobbler/field_info.py index ee58cb04..e18a5b3a 100644 --- a/cobbler/field_info.py +++ b/cobbler/field_info.py @@ -22,7 +22,8 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA """ -# FIXME: presumably incomplete. +# fields that display as a text area in the web app +# note: not the same as a text field, this is the big one. USES_TEXTAREA = [ "comment", @@ -30,14 +31,17 @@ USES_TEXTAREA = [ "template_files" ] +# fields that use a multi select in the web app + USES_MULTI_SELECT = [ "repos" ] +# fields that use a select in the web app + USES_SELECT = [ "profile", "distro", - "network", "image", "virt_type", "arch", @@ -47,6 +51,8 @@ USES_SELECT = [ "os_version", ] +# fields that should use the checkbox in the web app + USES_CHECKBOX = [ "enable_menu", "*netboot_enabled", @@ -55,9 +61,14 @@ USES_CHECKBOX = [ ] # select killed the radio button +# we should not make anything use a radio button, we hate radio buttons. + USES_RADIO = [ ] +# this is the map of what color to color code each field type. +# it may also be used to expand/collapse certain web elements as a set. + CSS_MAPPINGS = { "virt_ram" : "virtedit", "virt_disk" : "virtedit", @@ -96,14 +107,16 @@ CSS_MAPPINGS = { "*bonding_master" : "netedit", "*dns_name" : "netedit", "*static_routes" : "netedit", - "*network" : "netedit", "*subnet" : "netedit", "hostname" : "netedit", "gateway" : "netedit", "name_servers" : "netedit", "name_servers_search" : "netedit" } - + +# Certain legacy fields need to have different CLI options than the direct translation of their +# name in the FIELDS data structure. We should not add any more of these under any conditions. + ALTERNATE_OPTIONS = { "ks_meta" : "--ksmeta", "kernel_options" : "--kopts", diff --git a/cobbler/item_distro.py b/cobbler/item_distro.py index e19cdefa..8b5a1f32 100644 --- a/cobbler/item_distro.py +++ b/cobbler/item_distro.py @@ -33,7 +33,64 @@ from cexceptions import * from utils import _ import codes -# name | default | subobject default | tooltip | editable? +# the fields has controls what data elements are part of each object. To add a new field, just add a new +# entry to the list following some conventions to be described later. You must also add a method called +# set_$fieldname. Do not write a method called get_$fieldname, that will not be called. +# +# name | default | subobject default | hidden | tooltip | editable? | values ? +# +# name -- what the filed should be called. For the command line, underscores will be replaced with +# a hyphen programatically, so use underscores to seperate things that are seperate words +# +# default value -- when a new object is created, what is the default value for this field? +# +# subobject default -- this applies ONLY to subprofiles, and is most always set to <<inherit>>. If this +# is not item_profile.py it does not matter. +# +# display name -- how the field shows up in the web application and the "cobbler report" command +# +# editable -- should the field be editable in the CLI and web app? Almost always yes unless +# it is an internalism. Fields that are not editable are "hidden" +# +# tooltip -- the caption to be shown in the web app or in "commandname --help" in the CLI +# +# values -- for fields that have a limited set of valid options and those options are always fixed +# (such as architecture type), the list of valid options goes in this field. This should +# almost always be a constant from codes.py +# +# you will also notice some names start with "*" ... this denotes that the fields belong to +# interfaces, and only item_system.py should have these. Each system may have multiple interfaces. +# +# the order in which the fields are listed (for all non-hidden fields) are the order they will +# appear in the web application (top to bottom). The command line sorts fields alphabetically. +# +# field_info.py also contains a set of "Groups" that describe what other fields are associated with +# what other fields. This affects color coding and other display hints. If you add a field +# please edit field_info.py carefully to match. +# +# additional: see field_info.py for some display hints. By default in the web app all fields +# are text fields unless field_info.py lists the field in one of those hashes. +# +# hidden fields should not be added without just cause, explanations about these are: +# +# ctime, mtime -- times the object was modified, used internally by cobbler for API purposes +# uid -- also used for some external API purposes +# source_repos -- an artifiact of import, this is too complicated to explain on IRC so we just hide it +# for RHEL split repos, this is a list of each of them in the install tree, used to generate +# repo lines in the kickstart to allow installation of x>=RHEL5. Otherwise unimportant. +# depth -- used for "cobbler list" to print the tree, makes it easier to load objects from disk also +# tree_build_time -- loaded from import, this is not useful to many folks so we just hide it. Avail over API. +# +# so to add new fields +# (A) understand the above +# (B) add a field below +# (C) add a set_fieldname method +# (D) you do not need to modify the CLI or webapp +# +# in general the set_field_name method should raise exceptions on invalid fields, always. There are adtl +# validation fields in is_valid to check to see that two seperate fields do not conflict, but in general +# design issues that require this should be avoided forever more, and there are few exceptions. Cobbler +# must operate as normal with the default value for all fields and not choke on the default values. FIELDS = [ [ "name","",0,"Name",True,"Ex: Fedora-11-i386",0], diff --git a/cobbler/item_image.py b/cobbler/item_image.py index f520b443..ff4939ae 100644 --- a/cobbler/item_image.py +++ b/cobbler/item_image.py @@ -28,6 +28,8 @@ from cexceptions import * import codes from utils import _ +# this datastructure is described in great detail in item_distro.py -- read the comments there. + FIELDS = [ ['name','',0,"Name",True,"",0], ['arch','i386',0,"Architecture",True,"",["i386","x86_64","ia64","s390","ppc"]], diff --git a/cobbler/item_profile.py b/cobbler/item_profile.py index ebe1cb70..911b1753 100644 --- a/cobbler/item_profile.py +++ b/cobbler/item_profile.py @@ -27,6 +27,8 @@ from cexceptions import * from utils import _ +# this datastructure is described in great detail in item_distro.py -- read the comments there. + FIELDS = [ ["name","",None,"Name",True,"Ex: F10-i386-webserver",0], ["uid","","","",False,"",0], diff --git a/cobbler/item_repo.py b/cobbler/item_repo.py index 68d8d598..62b1463f 100644 --- a/cobbler/item_repo.py +++ b/cobbler/item_repo.py @@ -27,6 +27,8 @@ from utils import _ import time import codes +# this datastructure is described in great detail in item_distro.py -- read the comments there. + FIELDS = [ ["arch","",0,"Arch",True,"ex: i386, x86_64",['i386','x86_64','ia64','ppc','s390']], ["breed","",0,"Breed",True,"",codes.VALID_OS_BREEDS], diff --git a/cobbler/item_system.py b/cobbler/item_system.py index 992696ff..f9787592 100644 --- a/cobbler/item_system.py +++ b/cobbler/item_system.py @@ -26,6 +26,8 @@ import time from cexceptions import * from utils import _ +# this datastructure is described in great detail in item_distro.py -- read the comments there. + FIELDS = [ ["name","",0,"Name",True,"Ex: vanhalen.example.org",0], ["uid","",0,"",False,"",0], @@ -66,7 +68,6 @@ FIELDS = [ ["redhat_management_server","<<inherit>>",0,"Red Hat Management Server",True,"Address of Satellite or Spacewalk Server",0], ["network_widget_a","",0,"Add Interface",True,"",0], # not a real field, a marker for the web app ["network_widget_b","",0,"Edit Interface",True,"",0], # not a real field, a marker for the web app - ["*network","",0,"Network",True,"Parent network object for this interface",0], ["*mac_address","",0,"MAC Address",True,"",0], ["*ip_address","",0,"IP Address",True,"",0], ["*bonding","na",0,"Bonding Mode",True,"",["na","master","slave"]], @@ -125,7 +126,6 @@ class System(item.Item): "bonding_opts" : "", "dns_name" : "", "static_routes" : [], - "network" : "", } return self.interfaces[name] @@ -214,11 +214,6 @@ class System(item.Item): if intf["ip_address"] != "": return intf["ip_address"].strip() - elif intf.get("network","") != "": - net = self.config.networks().find(name=intf["network"]) - if net == None: - raise CX(_("Network %s does not exist" % network)) - return net.get_assigned_address(self.name, interface) else: return "" @@ -268,43 +263,6 @@ class System(item.Item): intf["static"] = utils.input_boolean(truthiness) return True - def set_network(self,network,interface): - """ - Add an interface to a network object. If network is empty, - clear the network. - """ - - # the following is to make the absense a network clearer for the webapp - # FIXME: testing needed - if network == "<<None>>": - network = "" - - intf = self.__get_interface(interface) - - if network == intf['network']: - # setting the existing network is no-op - return - - if intf['network'] != '': - # we are currently subscribed to a network, so to join - # a different one we need to leave this one first. - net = self.config.networks().find(name=intf['network']) - if net == None: - raise CX(_("Network %s does not exist" % network)) - net.unsubscribe_system(self.name, interface) - intf['network'] = '' - - if network != '': # Join - net = self.config.networks().find(name=network) - if net == None: - raise CX(_("Network %s does not exist" % network)) - net.subscribe_system(self.name, interface, intf['ip_address']) - intf['network'] = network - - # FIXME figure out why the network collection doesn't - # serialize itself out to disk without this - # self.config.serialize() - def set_ip_address(self,address,interface): """ Assign a IP or hostname in DHCP when this MAC boots. diff --git a/cobbler/modules/install_post_log.py b/cobbler/modules/install_post_log.py index 02c0b55e..6140801c 100644 --- a/cobbler/modules/install_post_log.py +++ b/cobbler/modules/install_post_log.py @@ -17,7 +17,9 @@ def register(): # the return of this method indicates the trigger type return "/var/lib/cobbler/triggers/install/post/*" -def run(api, args): +def run(api, args, logger): + # FIXME: make everything use the logger, no prints, use util.subprocess_call, etc + objtype = args[0] # "system" or "profile" name = args[1] # name of system or profile ip = args[2] # ip or "?" diff --git a/cobbler/modules/install_post_report.py b/cobbler/modules/install_post_report.py index b42753b4..3a41343f 100755 --- a/cobbler/modules/install_post_report.py +++ b/cobbler/modules/install_post_report.py @@ -29,7 +29,8 @@ def register(): # the return of this method indicates the trigger type return "/var/lib/cobbler/triggers/install/post/*" -def run(api, args): +def run(api, args, logger): + # FIXME: make everything use the logger settings = api.settings() diff --git a/cobbler/modules/install_pre_clear_anamon_logs.py b/cobbler/modules/install_pre_clear_anamon_logs.py index 381759aa..eb149501 100755 --- a/cobbler/modules/install_pre_clear_anamon_logs.py +++ b/cobbler/modules/install_pre_clear_anamon_logs.py @@ -19,7 +19,8 @@ def register(): # the return of this method indicates the trigger type return "/var/lib/cobbler/triggers/install/pre/*" -def run(api, args): +def run(api, args, logger): + # FIXME: use the logger if len(args) < 3: raise CX("invalid invocation") diff --git a/cobbler/modules/install_pre_log.py b/cobbler/modules/install_pre_log.py index 4469a514..1218fd78 100644 --- a/cobbler/modules/install_pre_log.py +++ b/cobbler/modules/install_pre_log.py @@ -17,11 +17,13 @@ def register(): # the return of this method indicates the trigger type return "/var/lib/cobbler/triggers/install/pre/*" -def run(api, args): +def run(api, args, logger): objtype = args[0] # "system" or "profile" name = args[1] # name of system or profile ip = args[2] # ip or "?" + # FIXME: use the logger + fd = open("/var/log/cobbler/install.log","a+") fd.write("%s\t%s\t%s\tstart\t%s\n" % (objtype,name,ip,time.time())) fd.close() diff --git a/cobbler/modules/scm_track.py b/cobbler/modules/scm_track.py index 92a12c04..1892aae7 100644 --- a/cobbler/modules/scm_track.py +++ b/cobbler/modules/scm_track.py @@ -23,7 +23,7 @@ def scall(args): op.communicate() -def run(api,args): +def run(api,args,logger): settings = api.settings() diff --git a/cobbler/modules/sync_post_restart_services.py b/cobbler/modules/sync_post_restart_services.py index a81caf2c..1d7aa80e 100644 --- a/cobbler/modules/sync_post_restart_services.py +++ b/cobbler/modules/sync_post_restart_services.py @@ -18,7 +18,7 @@ def register(): # the return of this method indicates the trigger type return "/var/lib/cobbler/triggers/sync/post/*" -def run(api,args): +def run(api,args,logger): settings = api.settings() @@ -42,28 +42,28 @@ def run(api,args): if manage_dhcp != "0": if which_dhcp_module == "manage_isc": if not omapi_enabled in [ "1", "true", "yes", "y" ] and restart_dhcp: - rc = utils.os_system("%s -t -q" % dhcpd_bin) + rc = utils.subprocess_call(logger, "%s -t -q" % dhcpd_bin, shell=True) if rc != 0: - print "%s -t failed" % dhcpd_bin + logger.error("%s -t failed" % dhcpd_bin) return 1 - rc = utils.os_system("%s %s restart" % (restart_bin, dhcpd_init)) + rc = utils.subprocess_call(logger,"%s %s restart" % (restart_bin, dhcpd_init), shell=True) elif which_dhcp_module == "manage_dnsmasq": if restart_dhcp: - rc = utils.os_system("/sbin/service dnsmasq restart") + rc = utils.subprocess_call(logger, "/sbin/service dnsmasq restart") has_restarted_dnsmasq = True else: - print "- error: unknown DHCP engine: %s" % which_dhcp_module + logger.error("unknown DHCP engine: %s" % which_dhcp_module) rc = 411 if manage_dns != "0" and restart_dns != "0": if which_dns_module == "manage_bind": - rc = utils.os_system("/sbin/service named restart") + rc = utils.subprocess_call(logger, "/sbin/service named restart", shell=True) elif which_dns_module == "manage_dnsmasq" and not has_restarted_dnsmasq: - rc = utils.os_system("/sbin/service dnsmasq restart") + rc = utils.subprocess_call(logger, "/sbin/service dnsmasq restart", shell=True) elif which_dns_module == "manage_dnsmasq" and has_restarted_dnsmasq: rc = 0 else: - print "- error: unknown DNS engine: %s" % which_dns_module + logger.error("unknown DNS engine: %s" % which_dns_module) rc = 412 return rc diff --git a/cobbler/remote.py b/cobbler/remote.py index 76235185..875724a4 100644 --- a/cobbler/remote.py +++ b/cobbler/remote.py @@ -46,7 +46,6 @@ import item_profile import item_system import item_repo import item_image -import item_network import clogger import utils #from utils import * # BAD! @@ -238,7 +237,7 @@ class CobblerXMLRPCInterface: id = self.__start_task(RepoSyncThread, "Reposync", [repos, tries]) return id - def background_power_system(self, object_id,power=None,token=None): + def background_power_system(self, system_names, power=None,token=None): # FIXME: needs testing class PowerThread(CobblerThread): def _run(self): @@ -246,14 +245,17 @@ class CobblerXMLRPCInterface: power = self.args[1] token = self.args[2] try: - self.remote.power_system(object_id,power,token,logger=self.logger) + for x in system_names: + self.logger.debug("performing power actions for system %s" % x) + object_id = self.remote.get_system_handle(x,token) + self.remote.power_system(object_id,power,token,logger=self.logger) self.remote._set_task_state(self.event_id,EVENT_COMPLETE) except: utils.log_exc(self.logger) self.remote._set_task_state(self.event_id,EVENT_FAILED) self.check_access(token, "power") - id = self.__start_task(PowerThread, "Power management", [object_id,power,token]) + id = self.__start_task(PowerThread, "Power management (%s)" % power, [system_names,power,token]) return id def get_events(self, for_user=""): @@ -515,8 +517,6 @@ class CobblerXMLRPCInterface: return self.get_item("repo",name,flatten=flatten) def get_image(self,name,flatten=False,token=None,**rest): return self.get_item("image",name,flatten=flatten) - def get_network(self,name,flatten=False,token=None,**rest): - return self.get_item("network",name,flatten=flatten) def get_items(self, what): """ @@ -538,8 +538,6 @@ class CobblerXMLRPCInterface: return self.get_items("repo") def get_images(self,page=None,results_per_page=None,token=None,**rest): return self.get_items("image") - def get_networks(self,page=None,results_per_page=None,token=None,**rest): - return self.get_items("network") def find_items(self, what, criteria=None,sort_field=None,expand=True): """ @@ -567,8 +565,6 @@ class CobblerXMLRPCInterface: return self.find_items("repo",criteria,expand=expand) def find_image(self,criteria={},expand=False,token=None,**rest): return self.find_items("image",criteria,expand=expand) - def find_network(self,criteria={},expand=False,token=None,**rest): - return self.find_items("network",criteria,expand=expand) def find_items_paged(self, what, criteria=None, sort_field=None, page=None, items_per_page=None, token=None): """ @@ -621,8 +617,6 @@ class CobblerXMLRPCInterface: return self.get_item_handle("repo",name,token) def get_image_handle(self,name,token): return self.get_item_handle("image",name,token) - def get_network_handle(self,name,token): - return self.get_item_handle("network",name,token) def remove_item(self,what,name,token,recursive=True): """ @@ -643,8 +637,6 @@ class CobblerXMLRPCInterface: return self.remove_item("repo",name,token,recursive) def remove_image(self,name,token,recursive=1): return self.remove_item("image",name,token,recursive) - def remove_network(self,name,token,recursive=1): - return self.remove_item("network",name,token,recursive) def copy_item(self,what,object_id,newname,token=None): """ @@ -665,8 +657,6 @@ class CobblerXMLRPCInterface: return self.copy_item("repo",object_id,newname,token) def copy_image(self,object_id,newname,token=None): return self.copy_item("image",object_id,newname,token) - def copy_network(self,object_id,newname,token=None): - return self.copy_item("network",object_id,newname,token) def rename_item(self,what,object_id,newname,token=None): """ @@ -686,8 +676,6 @@ class CobblerXMLRPCInterface: return self.rename_item("repo",object_id,newname,token) def rename_image(self,object_id,newname,token=None): return self.rename_item("image",object_id,newname,token) - def rename_network(self,object_id,newname,token=None): - return self.rename_item("network",object_id,newname,token) def new_item(self,what,token): """ @@ -695,7 +683,7 @@ class CobblerXMLRPCInterface: handle that can be used with modify_* methods and then finally save_* methods. The handle only exists in memory until saved. "what" specifies the type of object: - distro, profile, system, repo, image, or network + distro, profile, system, repo, or image """ self._log("new_item(%s)"%what,token=token) self.check_access(token,"new_%s"%what) @@ -709,8 +697,6 @@ class CobblerXMLRPCInterface: d = item_repo.Repo(self.api._config) elif what == "image": d = item_image.Image(self.api._config) - elif what == "network": - d = item_network.Network(self.api._config) else: raise CX("internal error, collection name is %s" % what) key = "___NEW___%s::%s" % (what,self.__get_random(25)) @@ -727,8 +713,6 @@ class CobblerXMLRPCInterface: return self.new_item("repo",token) def new_image(self,token): return self.new_item("image",token) - def new_network(self,token): - return self.new_item("network",token) def modify_item(self,what,object_id,attribute,arg,token): """ @@ -754,8 +738,6 @@ class CobblerXMLRPCInterface: return self.modify_item("image",object_id,attribute,arg,token) def modify_repo(self,object_id,attribute,arg,token): return self.modify_item("repo",object_id,attribute,arg,token) - def modify_network(self,object_id,attribute,arg,token): - return self.modify_item("network",object_id,attribute,arg,token) def save_item(self,what,object_id,token,editmode="bypass"): """ @@ -780,8 +762,6 @@ class CobblerXMLRPCInterface: return self.save_item("image",object_id,token,editmode=editmode) def save_repo(self,object_id,token,editmode="bypass"): return self.save_item("repo",object_id,token,editmode=editmode) - def save_network(self,object_id,token,editmode="bypass"): - return self.save_item("network",object_id,token,editmode=editmode) def get_kickstart_templates(self,token=None,**rest): """ @@ -1155,12 +1135,6 @@ class CobblerXMLRPCInterface: data = self.api.get_images_since(mtime, collapse=True) return self.xmlrpc_hacks(data) - def get_networks_since(self,mtime): - """ - See documentation for get_distros_since - """ - data = self.api.get_networks_since(mtime, collapse=True) - def get_repos_compatible_with_profile(self,profile=None,token=None,**rest): """ Get repos that can be used with a given profile name @@ -1612,18 +1586,20 @@ class CobblerXMLRPCInterface: return True - def power_system(self,object_id,power=None,token=None): + def power_system(self,object_id,power=None,token=None,logger=None): """ + Internal implementation used by background_power, do not call + directly if possible. Allows poweron/poweroff/reboot of a system specified by object_id. """ obj = self.__get_object(object_id) self.check_access(token, "power_system", obj) if power=="on": - rc=self.api.power_on(obj) + rc=self.api.power_on(obj, user=None, password=None, logger=logger) elif power=="off": - rc=self.api.power_off(obj) + rc=self.api.power_off(obj, user=None, password=None, logger=logger) elif power=="reboot": - rc=self.api.reboot(obj) + rc=self.api.reboot(obj, user=None, password=None, logger=logger) else: raise CX("invalid power mode '%s', expected on/off/reboot" % power) return rc diff --git a/cobbler/utils.py b/cobbler/utils.py index 9769f82b..f406cacd 100644 --- a/cobbler/utils.py +++ b/cobbler/utils.py @@ -725,7 +725,7 @@ def hash_to_string(hash): buffer = buffer + str(key) + "=" + str(value) + " " return buffer -def run_triggers(api,ref,globber,additional=[]): +def run_triggers(api,ref,globber,additional=[],logger=None): """ Runs all the trigger scripts in a given directory. ref can be a cobbler object, if not None, the name will be passed @@ -745,7 +745,7 @@ def run_triggers(api,ref,globber,additional=[]): arglist.append(ref.name) for x in additional: arglist.append(x) - rc = m.run(api, arglist) + rc = m.run(api, arglist, logger) if rc != 0: raise CX("cobbler trigger failed: %s" % m.__name__) @@ -765,7 +765,7 @@ def run_triggers(api,ref,globber,additional=[]): arglist.append(ref.name) for x in additional: arglist.append(x) - rc = sub_process.call(arglist, shell=False) # close_fds=True) + rc = subprocess_call(logger, arglist, shell=False) # close_fds=True) except: if logger is not None: logger.warning("failed to execute trigger: %s" % file) diff --git a/cobbler/collection_networks.py b/obsolete/collection_networks.py index 47a64667..b75f28c2 100644 --- a/cobbler/collection_networks.py +++ b/obsolete/collection_networks.py @@ -56,7 +56,7 @@ class Networks(collection.Collection): if obj is not None: if with_delete: if with_triggers: - self._run_triggers(self.config.api, obj, "/var/lib/cobbler/triggers/delete/network/pre/*") + utils.run_triggers(self.config.api, obj, "/var/lib/cobbler/triggers/delete/network/pre/*", [], logger) del self.listing[name] self.config.serialize_delete(self, obj) @@ -64,7 +64,8 @@ class Networks(collection.Collection): if with_delete: self.log_func("deleted network %s" % name) if with_triggers: - self._run_triggers(self.config.api, obj, "/var/lib/cobbler/triggers/delete/network/post/*") + utils.run_triggers(self.config.api, obj, "/var/lib/cobbler/triggers/delete/network/post/*", [], logger) + utils.run_triggers(self.config.api, obj, "/var/lib/cobbler/triggers/change/*", [], logger) return True raise CX(_("cannot delete an object that does not exist: %s") % name) diff --git a/cobbler/item_network.py b/obsolete/item_network.py index 26ad93f2..26ad93f2 100644 --- a/cobbler/item_network.py +++ b/obsolete/item_network.py @@ -227,7 +227,6 @@ if __name__ == "__main__": (dbpath + "/systems.d", []), (dbpath + "/repos.d", []), (dbpath + "/images.d", []), - (dbpath + "/networks.d", []), # sample kickstart files (kickpath, ['kickstarts/legacy.ks']), diff --git a/web/cobbler_web/templates/error_page.tmpl b/web/cobbler_web/templates/error_page.tmpl index 2b7b1533..aa0b0466 100644 --- a/web/cobbler_web/templates/error_page.tmpl +++ b/web/cobbler_web/templates/error_page.tmpl @@ -4,7 +4,7 @@ <h1 style="color: red;">Error</h1> -An error has occurred. You may find more information in /var/log/cobbler/cobblerd.log +An error has occurred. You may find more information in /var/log/cobbler/cobbled.log on the server should this error not be self explanatory. <p color="blue">{{ message }}</p> diff --git a/web/cobbler_web/templates/generic_list.tmpl b/web/cobbler_web/templates/generic_list.tmpl index 64974468..3e35d63e 100644 --- a/web/cobbler_web/templates/generic_list.tmpl +++ b/web/cobbler_web/templates/generic_list.tmpl @@ -74,6 +74,10 @@ function action_multi(otype, action, param) { if ((action == "netboot") && (param == "disable")) { value = confirm("Confirm: Really disable all checked systems for PXE reinstallation?") } + if ((action == "reposync")) { + value = "reposync" + } + if (value) { document.myform.action = "/cobbler_web/" + otype + "/multi/" + action + "/" + param document.myform.submit() @@ -156,6 +160,15 @@ function action_multi(otype, action, param) { <input type="button" onClick="javascript:action_multi('system','netboot','disable')" value="Disable Netboot"/> {% endifequal %} +{% ifequal what "repo" %} + <br/> + Batch actions: + <br/> + <br/> + <input type="button" onClick="javascript:action_multi('profile','reposync','go')" value="Sync Repos"/> + +{% endifequal %} + {% else %} There are no objects of this type yet. {% endif %} diff --git a/web/cobbler_web/views.py b/web/cobbler_web/views.py index fa5b00cd..5950246b 100644 --- a/web/cobbler_web/views.py +++ b/web/cobbler_web/views.py @@ -439,16 +439,16 @@ def generic_domulti(request, what, multi_mode=None, multi_arg=None): remote.modify_system(obj_id, "profile", profile, token) remote.save_system(obj_id, token, "edit") elif what == "system" and multi_mode == "power": + # FIXME: power should not loop, but send the list of all systems + # in one set. power = multi_arg if power is None: return error_page(request,"Cannot modify systems without specifying power option") - for obj_name in names: - obj_id = remote.get_system_handle(obj_name, token) - remote.background_power_system(obj_id, power, token) - elif what == "repo" and multi_mode == "reposync": - pass + remote.background_power_system(names, power, token) + elif what == "profile" and multi_mode == "reposync": + remote.background_reposync(names,3,token) else: - return error_page(request,"Unknown multiple operation on %ss: %s" % (what,str(multi_mode))) + return error_page(request,"Unknown batch operation on %ss: %s" % (what,str(multi_mode))) # FIXME: "operation complete" would make a lot more sense here than a redirect return HttpResponseRedirect("/cobbler_web/%s/list"%what) |
