summaryrefslogtreecommitdiffstats
path: root/cobbler
diff options
context:
space:
mode:
authorJames Cammarata <jimi@sngx.net>2009-02-13 06:52:58 -0600
committerJames Cammarata <jimi@sngx.net>2009-02-13 06:52:58 -0600
commit3a2a20078789d26263823b2271d3c4ac8ab7f053 (patch)
tree06a13cec50ab8db2740c1e10d532ac88c4b0d23a /cobbler
parenta389783b113ada0e3e33e8eb22e3b5a4b74db71e (diff)
parent77924d6840743b8eeefbd269fa860d836e73ff0b (diff)
downloadcobbler-3a2a20078789d26263823b2271d3c4ac8ab7f053.tar.gz
cobbler-3a2a20078789d26263823b2271d3c4ac8ab7f053.tar.xz
cobbler-3a2a20078789d26263823b2271d3c4ac8ab7f053.zip
Merge branch 'devel' of git://git.fedorahosted.org/cobbler into standalone
Diffstat (limited to 'cobbler')
-rw-r--r--cobbler/action_buildiso.py21
-rw-r--r--cobbler/action_import.py10
-rw-r--r--cobbler/action_litesync.py2
-rw-r--r--cobbler/action_sync.py4
-rw-r--r--cobbler/api.py12
-rw-r--r--cobbler/cobblerd.py1
-rw-r--r--cobbler/collection.py8
-rw-r--r--cobbler/collection_distros.py4
-rw-r--r--cobbler/collection_images.py4
-rw-r--r--cobbler/collection_profiles.py4
-rw-r--r--cobbler/collection_repos.py4
-rw-r--r--cobbler/collection_systems.py4
-rw-r--r--cobbler/item.py2
-rw-r--r--cobbler/item_profile.py13
-rw-r--r--cobbler/item_system.py12
-rw-r--r--cobbler/module_loader.py4
-rw-r--r--cobbler/modules/cli_distro.py2
-rw-r--r--cobbler/modules/cli_image.py2
-rw-r--r--cobbler/modules/cli_misc.py2
-rw-r--r--cobbler/modules/cli_profile.py5
-rw-r--r--cobbler/modules/cli_repo.py2
-rw-r--r--cobbler/modules/cli_report.py2
-rw-r--r--cobbler/modules/cli_system.py5
-rw-r--r--cobbler/modules/install_post_log.py29
-rwxr-xr-xcobbler/modules/install_post_report.py101
-rwxr-xr-xcobbler/modules/install_pre_clear_anamon_logs.py51
-rw-r--r--cobbler/modules/install_pre_log.py29
-rw-r--r--cobbler/modules/manage_bind.py16
-rw-r--r--cobbler/modules/sync_post_restart_services.py70
-rw-r--r--cobbler/pxegen.py17
-rw-r--r--cobbler/remote.py10
-rw-r--r--cobbler/settings.py10
-rw-r--r--cobbler/templar.py9
-rw-r--r--cobbler/utils.py23
-rw-r--r--cobbler/webui/CobblerWeb.py6
35 files changed, 443 insertions, 57 deletions
diff --git a/cobbler/action_buildiso.py b/cobbler/action_buildiso.py
index 65dd4c35..9a72fb23 100644
--- a/cobbler/action_buildiso.py
+++ b/cobbler/action_buildiso.py
@@ -131,7 +131,13 @@ class BuildIso:
cfg.write(HEADER) # fixme, use template
print _("- generating profile list...")
- for profile in self.api.profiles():
+ #sort the profiles
+ profile_list = [profile for profile in self.profiles]
+ def sort_name(a,b):
+ return cmp(a.name,b.name)
+ profile_list.sort(sort_name)
+
+ for profile in profile_list:
use_this = True
if profiles is not None:
which_profiles = profiles.split(",")
@@ -171,7 +177,13 @@ class BuildIso:
cfg.write("\nMENU SEPARATOR\n")
- for system in self.api.systems():
+ #sort the systems
+ system_list = [system for system in self.systems]
+ def sort_name(a,b):
+ return cmp(a.name,b.name)
+ system_list.sort(sort_name)
+
+ for system in system_list:
use_this = False
if systems is not None:
which_systems = systems.split(",")
@@ -215,7 +227,10 @@ class BuildIso:
append_line = append_line + " netmask=%s" % data["subnet_" + primary_interface]
if data.has_key("gateway") and data["gateway"] != "":
- append_line = append_line + " gateway=%s\n" % data["gateway"]
+ append_line = append_line + " gateway=%s" % data["gateway"]
+
+ if data.has_key("name_servers") and data["name_servers"]:
+ append_line = append_line + " dns=%s\n" % ",".join(data["name_servers"])
length=len(append_line)
if length > 254:
diff --git a/cobbler/action_import.py b/cobbler/action_import.py
index 24738cb0..19b2f9ae 100644
--- a/cobbler/action_import.py
+++ b/cobbler/action_import.py
@@ -987,8 +987,11 @@ class RedHatImporter ( BaseImporter ) :
data = glob.glob(os.path.join(self.get_pkgdir(), "*release-*"))
data2 = []
for x in data:
- if x.find("generic") == -1:
- data2.append(x)
+ b = os.path.basename(x)
+ if b.find("fedora") != -1 or \
+ b.find("redhat") != -1 or \
+ b.find("centos") != -1:
+ data2.append(x)
return data2
# ================================================================
@@ -1100,13 +1103,14 @@ class RedHatImporter ( BaseImporter ) :
# OS_VERSION next
# OS_VERSION.MINOR next
# ARCH/default.ks next
- # default.ks finally.
+ # FLAVOR.ks next
kickstarts = [
"%s/%s/%s.%i.ks" % (kickbase,arch,os_version,int(minor)),
"%s/%s/%s.ks" % (kickbase,arch,os_version),
"%s/%s.%i.ks" % (kickbase,os_version,int(minor)),
"%s/%s.ks" % (kickbase,os_version),
"%s/%s/default.ks" % (kickbase,arch),
+ "%s/%s.ks" % (kickbase,flavor),
]
for kickstart in kickstarts:
if os.path.exists(kickstart):
diff --git a/cobbler/action_litesync.py b/cobbler/action_litesync.py
index 5dcd1a71..7773455e 100644
--- a/cobbler/action_litesync.py
+++ b/cobbler/action_litesync.py
@@ -101,7 +101,7 @@ class BootLiteSync:
# get the profile object:
profile = self.profiles.find(name=name)
if profile is None:
- raise CX(_("error in profile lookup"))
+ raise CX(_("error in profile lookup for %s" % name))
# rebuild the yum configuration files for any attached repos
# generate any templates listed in the distro
self.sync.pxegen.write_templates(profile)
diff --git a/cobbler/action_sync.py b/cobbler/action_sync.py
index 4ebe027e..78f3c3d5 100644
--- a/cobbler/action_sync.py
+++ b/cobbler/action_sync.py
@@ -85,7 +85,7 @@ class BootSync:
print "- running pre-sync triggers"
# run pre-triggers...
- utils.run_triggers(None, "/var/lib/cobbler/triggers/sync/pre/*")
+ utils.run_triggers(self.api, None, "/var/lib/cobbler/triggers/sync/pre/*")
# (paranoid) in case the pre-trigger modified any objects...
@@ -141,7 +141,7 @@ class BootSync:
# run post-triggers
if self.verbose:
print "- running post-sync triggers"
- utils.run_triggers(None, "/var/lib/cobbler/triggers/sync/post/*")
+ utils.run_triggers(self.api, None, "/var/lib/cobbler/triggers/sync/post/*")
return True
def clean_trees(self):
diff --git a/cobbler/api.py b/cobbler/api.py
index bbaca45a..934ed953 100644
--- a/cobbler/api.py
+++ b/cobbler/api.py
@@ -265,14 +265,10 @@ class BootAPI:
def update(self):
"""
- This can be called when you expect a cobbler object
- to have changed outside of your API call. It does not
- have to be called before read operations but should be
- called before write operations depending on the last
- modification time. For the local API it is not needed.
- """
- self.clear()
- self.deserialize()
+ This can be called is no longer used by cobbler.
+ And is here to just avoid breaking older scripts.
+ """
+ return True
def copy_distro(self, ref, newname):
self.log("copy_distro",[ref.name, newname])
diff --git a/cobbler/cobblerd.py b/cobbler/cobblerd.py
index 77512611..8abe8329 100644
--- a/cobbler/cobblerd.py
+++ b/cobbler/cobblerd.py
@@ -112,6 +112,7 @@ def do_xmlrpc_rw(bootapi,settings,port):
while True:
try:
+ print "SERVING!"
server.serve_forever()
except IOError:
# interrupted? try to serve again
diff --git a/cobbler/collection.py b/cobbler/collection.py
index 3249555f..d6df28ad 100644
--- a/cobbler/collection.py
+++ b/cobbler/collection.py
@@ -258,7 +258,7 @@ class Collection(serializable.Serializable):
self.log_func("saving %s %s" % (self.collection_type(), ref.name))
# failure of a pre trigger will prevent the object from being added
if with_triggers:
- self._run_triggers(ref,"/var/lib/cobbler/triggers/add/%s/pre/*" % self.collection_type())
+ self._run_triggers(self.api, ref,"/var/lib/cobbler/triggers/add/%s/pre/*" % self.collection_type())
self.listing[ref.name.lower()] = ref
# save just this item if possible, if not, save
@@ -284,7 +284,7 @@ class Collection(serializable.Serializable):
# save the tree, so if neccessary, scripts can examine it.
if with_triggers:
- self._run_triggers(ref,"/var/lib/cobbler/triggers/add/%s/post/*" % self.collection_type())
+ self._run_triggers(self.api, ref,"/var/lib/cobbler/triggers/add/%s/post/*" % self.collection_type())
# update children cache in parent object
@@ -298,8 +298,8 @@ class Collection(serializable.Serializable):
return True
- def _run_triggers(self,ref,globber):
- return utils.run_triggers(ref,globber)
+ 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):
"""
diff --git a/cobbler/collection_distros.py b/cobbler/collection_distros.py
index d032768f..ae75f407 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(obj, "/var/lib/cobbler/triggers/delete/distro/pre/*")
+ self._run_triggers(self.config.api, obj, "/var/lib/cobbler/triggers/delete/distro/pre/*")
if with_sync:
lite_sync = action_litesync.BootLiteSync(self.config)
lite_sync.remove_single_profile(name)
@@ -75,7 +75,7 @@ class Distros(collection.Collection):
if with_delete:
self.log_func("deleted distro %s" % name)
if with_triggers:
- self._run_triggers(obj, "/var/lib/cobbler/triggers/delete/distro/post/*")
+ self._run_triggers(self.config.api, obj, "/var/lib/cobbler/triggers/delete/distro/post/*")
# look through all mirrored directories and find if any directory is holding
# this particular distribution's kernel and initrd
diff --git a/cobbler/collection_images.py b/cobbler/collection_images.py
index b7466e59..64e9df01 100644
--- a/cobbler/collection_images.py
+++ b/cobbler/collection_images.py
@@ -43,7 +43,7 @@ class Images(collection.Collection):
if obj is not None:
if with_delete:
if with_triggers:
- self._run_triggers(obj, "/var/lib/cobbler/triggers/delete/image/pre/*")
+ self._run_triggers(self.config.api, obj, "/var/lib/cobbler/triggers/delete/image/pre/*")
if with_sync:
lite_sync = action_litesync.BootLiteSync(self.config)
lite_sync.remove_single_image(name)
@@ -54,7 +54,7 @@ class Images(collection.Collection):
if with_delete:
self.log_func("deleted repo %s" % name)
if with_triggers:
- self._run_triggers(obj, "/var/lib/cobbler/triggers/delete/image/post/*")
+ self._run_triggers(self.config.api, obj, "/var/lib/cobbler/triggers/delete/image/post/*")
return True
if with_delete and not self.api.is_cobblerd:
diff --git a/cobbler/collection_profiles.py b/cobbler/collection_profiles.py
index 57f23d43..bb27dea4 100644
--- a/cobbler/collection_profiles.py
+++ b/cobbler/collection_profiles.py
@@ -64,7 +64,7 @@ class Profiles(collection.Collection):
if with_delete:
if with_triggers:
- self._run_triggers(obj, "/var/lib/cobbler/triggers/delete/profile/pre/*")
+ self._run_triggers(self.config.api, obj, "/var/lib/cobbler/triggers/delete/profile/pre/*")
if with_sync:
lite_sync = action_litesync.BootLiteSync(self.config)
lite_sync.remove_single_profile(name)
@@ -73,7 +73,7 @@ class Profiles(collection.Collection):
if with_delete:
self.log_func("deleted profile %s" % name)
if with_triggers:
- self._run_triggers(obj, "/var/lib/cobbler/triggers/delete/profile/post/*")
+ self._run_triggers(self.config.api, obj, "/var/lib/cobbler/triggers/delete/profile/post/*")
if with_delete and not self.api.is_cobblerd:
self.api._internal_cache_update("profile", name, remove=True)
diff --git a/cobbler/collection_repos.py b/cobbler/collection_repos.py
index 976c61e3..3b2c1c20 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(obj, "/var/lib/cobbler/triggers/delete/repo/pre/*")
+ self._run_triggers(self.config.api, obj, "/var/lib/cobbler/triggers/delete/repo/pre/*")
del self.listing[name]
self.config.serialize_delete(self, obj)
@@ -64,7 +64,7 @@ class Repos(collection.Collection):
if with_delete:
self.log_func("deleted repo %s" % name)
if with_triggers:
- self._run_triggers(obj, "/var/lib/cobbler/triggers/delete/repo/post/*")
+ self._run_triggers(self.config.api, obj, "/var/lib/cobbler/triggers/delete/repo/post/*")
path = "/var/www/cobbler/repo_mirror/%s" % obj.name
if os.path.exists(path):
diff --git a/cobbler/collection_systems.py b/cobbler/collection_systems.py
index 0c0b2b31..5a628248 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(obj, "/var/lib/cobbler/triggers/delete/system/pre/*")
+ self._run_triggers(self.config.api, obj, "/var/lib/cobbler/triggers/delete/system/pre/*")
if with_sync:
lite_sync = action_litesync.BootLiteSync(self.config)
lite_sync.remove_single_system(name)
@@ -61,7 +61,7 @@ class Systems(collection.Collection):
if with_delete:
self.log_func("deleted system %s" % name)
if with_triggers:
- self._run_triggers(obj, "/var/lib/cobbler/triggers/delete/system/post/*")
+ self._run_triggers(self.config.api, obj, "/var/lib/cobbler/triggers/delete/system/post/*")
if with_delete and not self.api.is_cobblerd:
self.api._internal_cache_update("system", name, remove=True)
diff --git a/cobbler/item.py b/cobbler/item.py
index a4ecea5b..fbb1d9d5 100644
--- a/cobbler/item.py
+++ b/cobbler/item.py
@@ -138,7 +138,7 @@ class Item(serializable.Serializable):
like authz_ownership, which ships with Cobbler but is off by default. Consult the Wiki
docs for more info on CustomizableAuthorization.
"""
- owners = utils.input_string_or_list(data)
+ owners = utils.input_string_or_list(data, delim=" ")
self.owners = owners
return True
diff --git a/cobbler/item_profile.py b/cobbler/item_profile.py
index d30eb52a..eafdfa14 100644
--- a/cobbler/item_profile.py
+++ b/cobbler/item_profile.py
@@ -69,6 +69,7 @@ class Profile(item.Item):
self.ctime = 0
self.mtime = 0
self.name_servers = (self.settings.default_name_servers, '<<inherit>>')[is_subobject]
+ self.name_servers_search = (self.settings.default_name_servers_search, '<<inherit>>')[is_subobject]
self.redhat_management_key = "<<inherit>>"
def from_datastruct(self,seed_data):
@@ -95,6 +96,7 @@ class Profile(item.Item):
self.ctime = self.load_item(seed_data,'ctime',0)
self.mtime = self.load_item(seed_data,'mtime',0)
self.name_servers = self.load_item(seed_data,'name_servers',[])
+ self.name_servers_search = self.load_item(seed_data,'name_servers_search',[])
self.redhat_management_key = self.load_item(seed_data,'redhat_management_key', '<<inherit>>')
# backwards compatibility
@@ -180,10 +182,16 @@ class Profile(item.Item):
return utils.set_redhat_management_key(self,key)
def set_name_servers(self,data):
- data = utils.input_string_or_list(data)
+ # FIXME: move to utils since shared with system
+ data = utils.input_string_or_list(data, delim=" ")
self.name_servers = data
return True
+ def set_name_servers_search(self,data):
+ data = utils.input_string_or_list(data, delim=" ")
+ self.name_servers_search = data
+ return True
+
def set_enable_menu(self,enable_menu):
"""
Sets whether or not the profile will be listed in the default
@@ -304,6 +312,7 @@ class Profile(item.Item):
'ctime' : self.ctime,
'mtime' : self.mtime,
'name_servers' : self.name_servers,
+ 'name_servers_search' : self.name_servers_search,
'uid' : self.uid,
'random_id' : self.random_id,
'redhat_management_key' : self.redhat_management_key
@@ -328,6 +337,7 @@ class Profile(item.Item):
buf = buf + _("mgmt classes : %s\n") % self.mgmt_classes
buf = buf + _("modified : %s\n") % time.ctime(self.mtime)
buf = buf + _("name servers : %s\n") % self.name_servers
+ buf = buf + _("name servers search : %s\n") % self.name_servers_search
buf = buf + _("owners : %s\n") % self.owners
buf = buf + _("post kernel options : %s\n") % self.kernel_options_post
buf = buf + _("redhat mgmt key : %s\n") % self.redhat_management_key
@@ -379,6 +389,7 @@ class Profile(item.Item):
'mgmt_classes' : self.set_mgmt_classes,
'comment' : self.set_comment,
'name_servers' : self.set_name_servers,
+ 'name_servers_search' : self.set_name_servers_search,
'redhat_management_key' : self.set_redhat_management_key
}
diff --git a/cobbler/item_system.py b/cobbler/item_system.py
index 91a7f62b..4445f5ec 100644
--- a/cobbler/item_system.py
+++ b/cobbler/item_system.py
@@ -74,6 +74,7 @@ class System(item.Item):
self.hostname = ""
self.gateway = ""
self.name_servers = ""
+ self.name_servers_search = ""
self.bonding = ""
self.bonding_master = ""
self.bonding_opts = ""
@@ -175,6 +176,7 @@ class System(item.Item):
self.hostname = self.load_item(seed_data, 'hostname', __hostname)
self.name_servers = self.load_item(seed_data, 'name_servers', '<<inherit>>')
+ self.name_servers_search = self.load_item(seed_data, 'name_servers_search', '<<inherit>>')
self.redhat_management_key = self.load_item(seed_data, 'redhat_management_key', '<<inherit>>')
# virt specific
@@ -444,10 +446,15 @@ class System(item.Item):
return True
def set_name_servers(self,data):
- data = utils.input_string_or_list(data)
+ data = utils.input_string_or_list(data, delim=" ")
self.name_servers = data
return True
+ def set_name_servers_search(self,data):
+ data = utils.input_string_or_list(data, delim=" ")
+ self.name_servers_search = data
+ return True
+
def set_subnet(self,subnet,interface):
intf = self.__get_interface(interface)
intf["subnet"] = subnet
@@ -662,6 +669,7 @@ class System(item.Item):
'hostname' : self.hostname,
'gateway' : self.gateway,
'name_servers' : self.name_servers,
+ 'name_servers_search' : self.name_servers_search,
'redhat_management_key' : self.redhat_management_key
}
@@ -681,6 +689,7 @@ class System(item.Item):
buf = buf + _("modified : %s\n") % time.ctime(self.mtime)
buf = buf + _("name servers : %s\n") % self.name_servers
+ buf = buf + _("name servers search : %s\n") % self.name_servers_search
buf = buf + _("netboot enabled? : %s\n") % self.netboot_enabled
buf = buf + _("owners : %s\n") % self.owners
buf = buf + _("server : %s\n") % self.server
@@ -787,6 +796,7 @@ class System(item.Item):
'hostname' : self.set_hostname,
'gateway' : self.set_gateway,
'name_servers' : self.set_name_servers,
+ 'name_servers_search' : self.set_name_servers_search,
'redhat_management_key' : self.set_redhat_management_key
}
diff --git a/cobbler/module_loader.py b/cobbler/module_loader.py
index a7be1f68..f50e4bf4 100644
--- a/cobbler/module_loader.py
+++ b/cobbler/module_loader.py
@@ -82,7 +82,7 @@ def load_modules(module_path=mod_path, blacklist=None):
def get_module_by_name(name):
return MODULE_CACHE.get(name, None)
-def get_module_from_file(category,field,fallback_module_name=None):
+def get_module_from_file(category,field,fallback_module_name=None,just_name=False):
try:
value = cp.get(category,field)
@@ -91,6 +91,8 @@ def get_module_from_file(category,field,fallback_module_name=None):
value = fallback_module_name
else:
raise CX(_("Cannot find config file setting for: %s") % field)
+ if just_name:
+ return value
rc = MODULE_CACHE.get(value, None)
if rc is None:
raise CX(_("Failed to load module for %s/%s") % (category,field))
diff --git a/cobbler/modules/cli_distro.py b/cobbler/modules/cli_distro.py
index 0c1425b1..2472f918 100644
--- a/cobbler/modules/cli_distro.py
+++ b/cobbler/modules/cli_distro.py
@@ -28,7 +28,7 @@ mod_path="%s/cobbler" % plib
sys.path.insert(0, mod_path)
from utils import _
-import commands
+import cobbler.commands as commands
import cexceptions
diff --git a/cobbler/modules/cli_image.py b/cobbler/modules/cli_image.py
index b6b96ff4..8725ca35 100644
--- a/cobbler/modules/cli_image.py
+++ b/cobbler/modules/cli_image.py
@@ -20,7 +20,7 @@ mod_path="%s/cobbler" % plib
sys.path.insert(0, mod_path)
from utils import _
-import commands
+import cobbler.commands as commands
import cexceptions
diff --git a/cobbler/modules/cli_misc.py b/cobbler/modules/cli_misc.py
index 5855a0a1..7174cdaf 100644
--- a/cobbler/modules/cli_misc.py
+++ b/cobbler/modules/cli_misc.py
@@ -21,7 +21,7 @@ mod_path="%s/cobbler" % plib
sys.path.insert(0, mod_path)
from utils import _
-import commands
+import cobbler.commands as commands
from cexceptions import *
HELP_FORMAT = commands.HELP_FORMAT
diff --git a/cobbler/modules/cli_profile.py b/cobbler/modules/cli_profile.py
index 03efb7bf..f5933938 100644
--- a/cobbler/modules/cli_profile.py
+++ b/cobbler/modules/cli_profile.py
@@ -28,7 +28,7 @@ mod_path="%s/cobbler" % plib
sys.path.insert(0, mod_path)
from utils import _
-import commands
+import cobbler.commands as commands
import cexceptions
@@ -72,6 +72,7 @@ class ProfileFunction(commands.CobblerFunction):
if not self.matches_args(args,["dumpvars","remove","report","getks","list"]):
p.add_option("--name-servers", dest="name_servers", help="name servers for static setups")
+ p.add_option("--name-servers-search", dest="name_servers_search", help="name servers search path for static setups")
if "copy" in args or "rename" in args:
p.add_option("--newname", dest="newname")
@@ -158,6 +159,8 @@ class ProfileFunction(commands.CobblerFunction):
obj.set_template_files(self.options.template_files,self.options.inplace)
if self.options.name_servers is not None:
obj.set_name_servers(self.options.name_servers)
+ if self.options.name_servers_search is not None:
+ obj.set_name_servers_search(self.options.name_servers_search)
if self.options.redhat_management_key is not None:
obj.set_redhat_management_key(self.options.redhat_management_key)
diff --git a/cobbler/modules/cli_repo.py b/cobbler/modules/cli_repo.py
index a8483dcb..0bcb0dba 100644
--- a/cobbler/modules/cli_repo.py
+++ b/cobbler/modules/cli_repo.py
@@ -28,7 +28,7 @@ mod_path="%s/cobbler" % plib
sys.path.insert(0, mod_path)
from utils import _
-import commands
+import cobbler.commands as commands
import cexceptions
diff --git a/cobbler/modules/cli_report.py b/cobbler/modules/cli_report.py
index 82060dda..4bec4b5d 100644
--- a/cobbler/modules/cli_report.py
+++ b/cobbler/modules/cli_report.py
@@ -20,7 +20,7 @@ mod_path="%s/cobbler" % plib
sys.path.insert(0, mod_path)
from utils import _, get_random_mac
-import commands
+import cobbler.commands as commands
from cexceptions import *
HELP_FORMAT = commands.HELP_FORMAT
diff --git a/cobbler/modules/cli_system.py b/cobbler/modules/cli_system.py
index 0c6499d7..12f81a79 100644
--- a/cobbler/modules/cli_system.py
+++ b/cobbler/modules/cli_system.py
@@ -28,7 +28,7 @@ mod_path="%s/cobbler" % plib
sys.path.insert(0, mod_path)
from utils import _, get_random_mac
-import commands
+import cobbler.commands as commands
from cexceptions import *
@@ -73,6 +73,7 @@ class SystemFunction(commands.CobblerFunction):
p.add_option("--mac", dest="mac", help="ex: 'AA:BB:CC:DD:EE:FF', (RECOMMENDED)")
p.add_option("--mgmt-classes", dest="mgmt_classes", help="list of config management classes (for Puppet, etc)")
p.add_option("--name-servers", dest="name_servers", help="name servers for static setups")
+ p.add_option("--name-servers-search", dest="name_servers_search", help="name servers search path for static setups")
p.add_option("--redhat-management-key", dest="redhat_management_key", help="authentication token for RHN/Spacewalk/Satellite")
p.add_option("--static-routes", dest="static_routes", help="sets static routes (see manpage)")
p.add_option("--template-files", dest="template_files",help="specify files to be generated from templates during a sync")
@@ -245,6 +246,8 @@ class SystemFunction(commands.CobblerFunction):
obj.set_template_files(self.options.template_files,self.options.inplace)
if self.options.name_servers is not None:
obj.set_name_servers(self.options.name_servers)
+ if self.options.name_servers_search is not None:
+ obj.set_name_servers_search(self.options.name_servers_search)
if self.options.redhat_management_key is not None:
obj.set_redhat_management_key(self.options.redhat_management_key)
diff --git a/cobbler/modules/install_post_log.py b/cobbler/modules/install_post_log.py
new file mode 100644
index 00000000..02c0b55e
--- /dev/null
+++ b/cobbler/modules/install_post_log.py
@@ -0,0 +1,29 @@
+import distutils.sysconfig
+import sys
+import os
+from utils import _
+import traceback
+import cexceptions
+import os
+import sys
+import time
+
+plib = distutils.sysconfig.get_python_lib()
+mod_path="%s/cobbler" % plib
+sys.path.insert(0, mod_path)
+
+def register():
+ # this pure python trigger acts as if it were a legacy shell-trigger, but is much faster.
+ # the return of this method indicates the trigger type
+ return "/var/lib/cobbler/triggers/install/post/*"
+
+def run(api, args):
+ objtype = args[0] # "system" or "profile"
+ name = args[1] # name of system or profile
+ ip = args[2] # ip or "?"
+
+ fd = open("/var/log/cobbler/install.log","a+")
+ fd.write("%s\t%s\t%s\tstop\t%s\n" % (objtype,name,ip,time.time()))
+ fd.close()
+
+ return 0
diff --git a/cobbler/modules/install_post_report.py b/cobbler/modules/install_post_report.py
new file mode 100755
index 00000000..b42753b4
--- /dev/null
+++ b/cobbler/modules/install_post_report.py
@@ -0,0 +1,101 @@
+# (c) 2008-2009
+# Jeff Schroeder <jeffschroeder@computer.org>
+# Michael DeHaan <mdehaan@redhat.com>
+#
+# License: GPLv2+
+
+# Post install trigger for cobbler to
+# send out a pretty email report that
+# contains target information.
+
+import distutils.sysconfig
+import sys
+import os
+import traceback
+
+plib = distutils.sysconfig.get_python_lib()
+mod_path="%s/cobbler" % plib
+sys.path.insert(0, mod_path)
+
+from utils import _
+import smtplib
+import sys
+import cobbler.templar as templar
+from cobbler.cexceptions import CX
+import utils
+
+def register():
+ # this pure python trigger acts as if it were a legacy shell-trigger, but is much faster.
+ # the return of this method indicates the trigger type
+ return "/var/lib/cobbler/triggers/install/post/*"
+
+def run(api, args):
+
+ settings = api.settings()
+
+ # go no further if this feature is turned off
+ if not str(settings.build_reporting_enabled).lower() in [ "1", "yes", "y", "true"]:
+ print "not enabled"
+ return 0
+
+ objtype = args[0] # "target" or "profile"
+ name = args[1] # name of target or profile
+ boot_ip = args[2] # ip or "?"
+
+ if objtype == "system":
+ target = api.find_system(name)
+ else:
+ target = api.find_profile(name)
+
+ # collapse the object down to a rendered datastructure
+ target = utils.blender(api, False, target)
+
+ if target == {}:
+ raise CX("failure looking up target")
+
+ to_addr = settings.build_reporting_email
+ if to_addr == "":
+ return 0
+
+ # add the ability to specify an MTA for servers that don't run their own
+ smtp_server = settings.build_reporting_smtp_server
+ if smtp_server == "":
+ smtp_server = "localhost"
+
+ # use a custom from address or fall back to a reasonable default
+ from_addr = settings.build_reporting_sender
+ if from_addr == "":
+ from_addr = "cobbler@%s" % settings.server
+
+ subject = settings.build_reporting_subject
+ if subject == "":
+ subject = '[Cobbler] install complete '
+
+ to_addr = ", ".join(to_addr)
+ metadata = {
+ "from_addr" : from_addr,
+ "to_addr" : to_addr,
+ "subject" : subject,
+ "boot_ip" : boot_ip
+ }
+ metadata.update(target)
+
+ input_template = open("/etc/cobbler/reporting/build_report_email.template")
+ input_data = input_template.read()
+ input_template.close()
+
+ message = templar.Templar().render(input_data, metadata, None)
+ # for debug, call
+ # print message
+
+ # Send the mail
+ # FIXME: on error, return non-zero
+ server_handle = smtplib.SMTP(smtp_server)
+ server_handle.sendmail(from_addr, to_addr, message)
+ server_handle.quit()
+
+ return 0
+
+
+
+
diff --git a/cobbler/modules/install_pre_clear_anamon_logs.py b/cobbler/modules/install_pre_clear_anamon_logs.py
new file mode 100755
index 00000000..381759aa
--- /dev/null
+++ b/cobbler/modules/install_pre_clear_anamon_logs.py
@@ -0,0 +1,51 @@
+import distutils.sysconfig
+import sys
+import os
+from utils import _
+import traceback
+import cexceptions
+
+plib = distutils.sysconfig.get_python_lib()
+mod_path="%s/cobbler" % plib
+sys.path.insert(0, mod_path)
+
+import os
+import glob
+import sys
+
+
+def register():
+ # this pure python trigger acts as if it were a legacy shell-trigger, but is much faster.
+ # the return of this method indicates the trigger type
+ return "/var/lib/cobbler/triggers/install/pre/*"
+
+def run(api, args):
+
+ if len(args) < 3:
+ raise CX("invalid invocation")
+
+ objtype = args[0] # "system" or "profile"
+ name = args[1] # name of system or profile
+ ip = args[2] # ip or "?"
+
+ settings = api.settings()
+ anamon_enabled = str(settings.anamon_enabled)
+
+ # Remove any files matched with the given glob pattern
+ def unlink_files(globex):
+ for f in glob.glob(globex):
+ if os.path.isfile(f):
+ try:
+ os.unlink(f)
+ except OSError, e:
+ pass
+
+ if str(anamon_enabled) in [ "true", "1", "y", "yes"]:
+ dirname = "/var/log/cobbler/anamon/%s" % name
+ if os.path.isdir(dirname):
+ unlink_files(os.path.join(dirname, "*"))
+
+ # TODO - log somewhere that we cleared a systems anamon logs
+ return 0
+
+
diff --git a/cobbler/modules/install_pre_log.py b/cobbler/modules/install_pre_log.py
new file mode 100644
index 00000000..4469a514
--- /dev/null
+++ b/cobbler/modules/install_pre_log.py
@@ -0,0 +1,29 @@
+import distutils.sysconfig
+import sys
+import os
+from utils import _
+import traceback
+import cexceptions
+import os
+import sys
+import time
+
+plib = distutils.sysconfig.get_python_lib()
+mod_path="%s/cobbler" % plib
+sys.path.insert(0, mod_path)
+
+def register():
+ # this pure python trigger acts as if it were a legacy shell-trigger, but is much faster.
+ # the return of this method indicates the trigger type
+ return "/var/lib/cobbler/triggers/install/pre/*"
+
+def run(api, args):
+ objtype = args[0] # "system" or "profile"
+ name = args[1] # name of system or profile
+ ip = args[2] # ip or "?"
+
+ 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()
+
+ return 0
diff --git a/cobbler/modules/manage_bind.py b/cobbler/modules/manage_bind.py
index 5acbf208..657a9a77 100644
--- a/cobbler/modules/manage_bind.py
+++ b/cobbler/modules/manage_bind.py
@@ -81,7 +81,13 @@ class BindManager:
in them
"""
zones = {}
- for zone in self.settings.manage_forward_zones:
+ forward_zones = self.settings.manage_forward_zones
+ if type(forward_zones) != type([]):
+ # gracefully handle when user inputs only a single zone
+ # as a string instead of a list with only a single item
+ forward_zones = [forward_zones]
+
+ for zone in forward_zones:
zones[zone] = {}
for system in self.systems:
@@ -125,7 +131,13 @@ class BindManager:
in them
"""
zones = {}
- for zone in self.settings.manage_reverse_zones:
+ reverse_zones = self.settings.manage_reverse_zones
+ if type(reverse_zones) != type([]):
+ # gracefully handle when user inputs only a single zone
+ # as a string instead of a list with only a single item
+ reverse_zones = [reverse_zones]
+
+ for zone in reverse_zones:
zones[zone] = {}
for sys in self.systems:
diff --git a/cobbler/modules/sync_post_restart_services.py b/cobbler/modules/sync_post_restart_services.py
new file mode 100644
index 00000000..fa9699b9
--- /dev/null
+++ b/cobbler/modules/sync_post_restart_services.py
@@ -0,0 +1,70 @@
+import distutils.sysconfig
+import sys
+import os
+from utils import _
+import traceback
+import cexceptions
+import os
+import sys
+import xmlrpclib
+import cobbler.module_loader as module_loader
+
+plib = distutils.sysconfig.get_python_lib()
+mod_path="%s/cobbler" % plib
+sys.path.insert(0, mod_path)
+
+def register():
+ # this pure python trigger acts as if it were a legacy shell-trigger, but is much faster.
+ # the return of this method indicates the trigger type
+ return "/var/lib/cobbler/triggers/sync/post/*"
+
+def run(api,args):
+
+ settings = api.settings()
+
+ manage_dhcp = str(settings.manage_dhcp).lower()
+ manage_dns = str(settings.manage_dns).lower()
+ manage_xinetd = str(settings.manage_xinetd).lower()
+ restart_dhcp = str(settings.restart_dhcp).lower()
+ restart_dns = str(settings.restart_dns).lower()
+ restart_xinetd = str(settings.restart_xinetd).lower()
+ omapi_enabled = str(settings.omapi_enabled).lower()
+ omapi_port = str(settings.omapi_port).lower()
+
+ which_dhcp_module = module_loader.get_module_from_file("dhcp","module",just_name=True).strip()
+ which_dns_module = module_loader.get_module_from_file("dns","module",just_name=True).strip()
+
+ # special handling as we don't want to restart it twice
+ has_restarted_dnsmasq = False
+
+ rc = 0
+ if manage_dhcp != "0":
+ if which_dhcp_module == "manage_isc":
+ if not omapi_enabled in [ "1", "true", "yes", "y" ] and restart_dhcp:
+ rc = os.system("/usr/sbin/dhcpd -t")
+ if rc != 0:
+ print "/usr/sbin/dhcpd -t failed"
+ return 1
+ rc = os.system("/sbin/service dhcpd restart")
+ elif which_dhcp_module == "manage_dnsmasq":
+ if restart_dhcp:
+ rc = os.system("/sbin/service dnsmasq restart")
+ has_restarted_dnsmasq = True
+ else:
+ print "- 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 = os.system("/sbin/service named restart")
+ elif which_dns_module == "manage_dnsmasq" and not has_restarted_dnsmasq:
+ rc = os.ssytem("/sbin/service dnsmasq restart")
+ else:
+ print "- error: unknown DNS engine: %s" % which_dns_module
+ rc = 412
+
+ if manage_xinetd != "0" and restart_xinetd != "0":
+ rc = os.system("/sbin/service xinetd restart")
+
+ return rc
+
diff --git a/cobbler/pxegen.py b/cobbler/pxegen.py
index bbe27ec8..633e5359 100644
--- a/cobbler/pxegen.py
+++ b/cobbler/pxegen.py
@@ -579,6 +579,23 @@ class PXEGen:
listfile.write("%s\n" % profile.name)
f2 = os.path.join(self.bootloc, "s390x", "p_%s" % profile.name)
self.write_pxe_file(f2,None,profile,distro,distro.arch)
+ cf = "%s_conf" % f2
+ pf = "%s_parm" % f2
+ template_cf = open("/etc/cobbler/pxe/s390x_conf.template")
+ template_pf = open("/etc/cobbler/pxe/s390x_parm.template")
+ blended = utils.blender(self.api, True, profile)
+ self.templar.render(template_cf, blended, cf)
+ # FIXME: profiles also need this data!
+ kickstart_path = "http://%s/cblr/svc/op/ks/profile/%s" % (blended["http_server"], profile.name)
+ meta2 = {}
+ meta2["kickstart_expanded"] = "ks=%s" % kickstart_path
+ ## FIXME: this may not work right for kernel options with
+ ## a space in them though there are not many of those.
+ meta2["kernel_options"] = "\n".join(blended["kernel_options"].split(" "))
+ meta2["confname"] = "p_%s_conf" % profile.name
+ self.templar.render(template_pf, meta2, pf)
+
+
listfile.close()
def make_actual_pxe_menu(self):
diff --git a/cobbler/remote.py b/cobbler/remote.py
index a36ade31..f7f90e9c 100644
--- a/cobbler/remote.py
+++ b/cobbler/remote.py
@@ -303,7 +303,11 @@ class CobblerXMLRPCInterface:
Return the contents of /etc/cobbler/settings, which is a hash.
"""
self._log("get_settings",token=token)
- return self.__get_all("settings")
+ results = self.api.settings()
+ self._log("got settings")
+ data = results.to_datastruct()
+ self._log("my settings are: %s" % data)
+ return self.xmlrpc_hacks(results)
def get_repo_config_for_profile(self,profile_name,**rest):
"""
@@ -526,7 +530,7 @@ class CobblerXMLRPCInterface:
# time if reinstalling all of a cluster all at once.
# we can do that at "cobbler check" time.
- utils.run_triggers(None, "/var/lib/cobbler/triggers/install/%s/*" % mode, additional=[objtype,name,ip])
+ utils.run_triggers(self.api, None, "/var/lib/cobbler/triggers/install/%s/*" % mode, additional=[objtype,name,ip])
return True
@@ -1900,6 +1904,7 @@ def test_xmlrpc_rw():
server.modify_profile(pid, "mgmt-classes", "one two three", token)
server.modify_profile(pid, "comment", "...", token)
server.modify_profile(pid, "name_servers", ["one","two"], token)
+ server.modify_profile(pid, "name_servers_search", ["one","two"], token)
server.modify_profile(pid, "redhat_management_key", "BETA", token)
server.save_profile(pid, token)
@@ -1918,6 +1923,7 @@ def test_xmlrpc_rw():
server.modify_system(sid, 'virt-path', "/opt/images", token)
server.modify_system(sid, 'virt-type', 'qemu', token)
server.modify_system(sid, 'name_servers', 'one two three four', token)
+ server.modify_system(sid, 'name_servers_search', 'one two three four', token)
server.modify_system(sid, 'modify-interface', {
"macaddress-eth0" : "AA:BB:CC:EE:EE:EE",
"ipaddress-eth0" : "192.168.10.50",
diff --git a/cobbler/settings.py b/cobbler/settings.py
index e87536c7..816efff3 100644
--- a/cobbler/settings.py
+++ b/cobbler/settings.py
@@ -30,14 +30,21 @@ TESTMODE = False
# we need.
DEFAULTS = {
+ "anamon_enabled" : 0,
"allow_duplicate_hostnames" : 0,
"allow_duplicate_macs" : 0,
"allow_duplicate_ips" : 0,
"bind_bin" : "/usr/sbin/named",
+ "build_reporting_enabled" : 0,
+ "build_reporting_to_address" : "",
+ "build_reporting_sender" : "",
+ "build_reporting_subject" : "",
+ "build_reporting_smtp_server" : "localhost",
"cheetah_import_whitelist" : [ "re", "random", "time" ],
"cobbler_master" : '',
"default_kickstart" : "/var/lib/cobbler/kickstarts/default.ks",
"default_name_servers" : '',
+ "default_name_servers_search" : '',
"default_password_crypted" : "\$1\$mF86/UHC\$WvcIcX2t6crBz2onWxyac.",
"default_virt_bridge" : "xenbr0",
"default_virt_type" : "auto",
@@ -103,8 +110,7 @@ DEFAULTS = {
"xmlrpc_port" : 25151,
"yum_post_install_mirror" : 1,
"yumdownloader_flags" : "--resolve",
- "yumreposync_flags" : "-l",
- "anamon_enabled" : 0,
+ "yumreposync_flags" : "-l"
}
diff --git a/cobbler/templar.py b/cobbler/templar.py
index 5cdd4959..f2e4b7f1 100644
--- a/cobbler/templar.py
+++ b/cobbler/templar.py
@@ -32,13 +32,14 @@ import utils
class Templar:
- def __init__(self,config):
+ def __init__(self,config=None):
"""
Constructor
"""
- self.config = config
- self.api = config.api
- self.settings = config.settings()
+ if config is not None:
+ self.config = config
+ self.api = config.api
+ self.settings = config.settings()
def check_for_invalid_imports(self,data):
"""
diff --git a/cobbler/utils.py b/cobbler/utils.py
index a4101cff..6ddde053 100644
--- a/cobbler/utils.py
+++ b/cobbler/utils.py
@@ -75,8 +75,6 @@ def _(foo):
MODULE_CACHE = {}
-# import api # factor out
-
_re_kernel = re.compile(r'vmlinuz(.*)')
_re_initrd = re.compile(r'initrd(.*).img')
@@ -660,15 +658,34 @@ def hash_to_string(hash):
buffer = buffer + str(key) + "=" + str(value) + " "
return buffer
-def run_triggers(ref,globber,additional=[]):
+def run_triggers(api,ref,globber,additional=[]):
"""
Runs all the trigger scripts in a given directory.
ref can be a cobbler object, if not None, the name will be passed
to the script. If ref is None, the script will be called with
no argumenets. Globber is a wildcard expression indicating which
triggers to run. Example: "/var/lib/cobbler/triggers/blah/*"
+
+ As of Cobbler 1.5.X, this also runs cobbler modules that match the globbing paths.
"""
+ # Python triggers first, before shell
+
+ modules = api.get_modules_in_category(globber)
+ print "DEBUG: trigger modules matching %s are %s" % (globber, [m.__name__ for m in modules])
+ for m in modules:
+ arglist = []
+ if ref:
+ arglist.append(ref.name)
+ for x in additional:
+ arglist.append(x)
+ rc = m.run(api, arglist)
+ if rc != 0:
+ raise CX("cobbler trigger failed: %s" % m.__name__)
+
+ # now do the old shell triggers, which are usually going to be slower, but are easier to write
+ # and support any language
+
triggers = glob.glob(globber)
triggers.sort()
for file in triggers:
diff --git a/cobbler/webui/CobblerWeb.py b/cobbler/webui/CobblerWeb.py
index f29a9496..72f3659a 100644
--- a/cobbler/webui/CobblerWeb.py
+++ b/cobbler/webui/CobblerWeb.py
@@ -512,7 +512,7 @@ class CobblerWeb(object):
def system_save(self,name=None,comment=None,editmode="edit",profile=None,
kopts=None, koptspost=None, ksmeta=None, owners=None, server_override=None, netboot='n',
virtpath=None,virtram=None,virttype=None,virtcpus=None,virtfilesize=None,
- name_servers=None,
+ name_servers=None,name_servers_search=None,
power_type=None, power_user=None, power_pass=None, power_id=None, power_address=None,
gateway=None,hostname=None,redhatmanagementkey=None,delete1=None, delete2=None, **args):
@@ -565,6 +565,7 @@ class CobblerWeb(object):
self.remote.modify_system(system, 'power_id', power_id, self.token)
self.remote.modify_system(system, 'power_address', power_address, self.token)
self.remote.modify_system(system, 'name_servers', name_servers, self.token)
+ self.remote.modify_system(system, 'name_servers_search', name_servers_search, self.token)
self.remote.modify_system(system, 'gateway', gateway, self.token)
self.remote.modify_system(system, 'hostname', hostname, self.token)
self.remote.modify_system(system, 'redhat_management_key', redhatmanagementkey, self.token)
@@ -678,7 +679,7 @@ class CobblerWeb(object):
ksmeta=None,owners=None,enablemenu=None,virtfilesize=None,virtram=None,virttype=None,
virtpath=None,repos=None,dhcptag=None,delete1=False,delete2=False,
parent=None,virtcpus=None,virtbridge=None,subprofile=None,server_override=None,
- name_servers=None,redhatmanagementkey=None,recursive=False,**args):
+ name_servers=None,name_servers_search=None,redhatmanagementkey=None,recursive=False,**args):
if not self.__xmlrpc_setup():
return self.xmlrpc_auth_failure()
@@ -745,6 +746,7 @@ class CobblerWeb(object):
self.remote.modify_profile(profile, 'server', server_override, self.token)
self.remote.modify_profile(profile, 'comment', comment, self.token)
self.remote.modify_profile(profile, 'name_servers', name_servers, self.token)
+ self.remote.modify_profile(profile, 'name_servers_search', name_servers_search, self.token)
self.remote.modify_profile(profile, 'redhat_management_key', redhatmanagementkey, self.token)
if repos is None: