summaryrefslogtreecommitdiffstats
path: root/cobbler
diff options
context:
space:
mode:
authorMichael DeHaan <mdehaan@mdehaan.rdu.redhat.com>2007-08-16 17:52:09 -0400
committerMichael DeHaan <mdehaan@mdehaan.rdu.redhat.com>2007-08-16 17:52:09 -0400
commita1935cbf878b1fe7743bc8b2bf66f7ba5c42cbe3 (patch)
treeca6782ebfc0dc6766532efeb03a3ec86ddcd9191 /cobbler
parent3b5617844e91d5d9febf391ca389230e3ba9d7cb (diff)
parentc34532d98aeae2e1401e3aff770782ab6871f19b (diff)
downloadthird_party-cobbler-a1935cbf878b1fe7743bc8b2bf66f7ba5c42cbe3.tar.gz
third_party-cobbler-a1935cbf878b1fe7743bc8b2bf66f7ba5c42cbe3.tar.xz
third_party-cobbler-a1935cbf878b1fe7743bc8b2bf66f7ba5c42cbe3.zip
Merge branch 'master' of ssh://git.fedoraproject.org/git/hosted/cobbler
Diffstat (limited to 'cobbler')
-rw-r--r--cobbler/action_enchant.py4
-rw-r--r--cobbler/action_import.py6
-rw-r--r--cobbler/action_litesync.py14
-rw-r--r--cobbler/action_reposync.py7
-rw-r--r--cobbler/action_status.py21
-rw-r--r--cobbler/action_sync.py8
-rwxr-xr-xcobbler/cobbler.py6
-rw-r--r--cobbler/cobblerd.py17
-rw-r--r--cobbler/collection.py74
-rw-r--r--cobbler/collection_distros.py2
-rw-r--r--cobbler/collection_profiles.py2
-rw-r--r--cobbler/collection_repos.py2
-rw-r--r--cobbler/collection_systems.py2
-rw-r--r--cobbler/item_distro.py2
-rw-r--r--cobbler/item_profile.py10
-rw-r--r--cobbler/item_system.py16
16 files changed, 126 insertions, 67 deletions
diff --git a/cobbler/action_enchant.py b/cobbler/action_enchant.py
index 3bf80f8..4a54ebe 100644
--- a/cobbler/action_enchant.py
+++ b/cobbler/action_enchant.py
@@ -40,9 +40,9 @@ class Enchant:
raise CX(_("enchant failed. no address specified"))
if system is None and profile is None:
raise CX(_("enchant failed. no profile specified"))
- if system is not None and self.config.systems().find(system) is None:
+ if system is not None and self.config.systems().find(name=system) is None:
raise CX(_("enchant failed. system not found"))
- if profile is not None and self.config.profiles().find(profile) is None:
+ if profile is not None and self.config.profiles().find(name=profile) is None:
raise CX(_("enchant failed. profile name not found"))
diff --git a/cobbler/action_import.py b/cobbler/action_import.py
index d1fd7ab..d05ea82 100644
--- a/cobbler/action_import.py
+++ b/cobbler/action_import.py
@@ -155,7 +155,7 @@ class Importer:
"""
for profile in self.profiles:
- distro = self.distros.find(profile.distro)
+ distro = self.distros.find(name=profile.distro)
if distro is None or not (distro in self.distros_added):
print _("- skipping distro %s since it wasn't imported this time") % profile.distro
continue
@@ -443,7 +443,7 @@ class Importer:
pxe_arch = self.get_pxe_arch(dirname)
name = self.get_proposed_name(dirname, pxe_arch)
- existing_distro = self.distros.find(name)
+ existing_distro = self.distros.find(name=name)
if existing_distro is not None:
print _("- modifying existing distro: %s") % name
@@ -460,7 +460,7 @@ class Importer:
self.distros.add(distro)
self.distros_added.append(distro)
- existing_profile = self.profiles.find(name)
+ existing_profile = self.profiles.find(name=name)
if existing_profile is None:
print _("- creating new profile: %s") % name
diff --git a/cobbler/action_litesync.py b/cobbler/action_litesync.py
index 21e6c62..2560d8d 100644
--- a/cobbler/action_litesync.py
+++ b/cobbler/action_litesync.py
@@ -53,7 +53,7 @@ class BootLiteSync:
def add_single_distro(self, name):
# get the distro record
- distro = self.distros.find(name)
+ distro = self.distros.find(name=name)
if distro is None:
raise CX(_("error in distro lookup: %s") % name)
# generate YAML file in distros/$name in webdir
@@ -73,7 +73,7 @@ class BootLiteSync:
def add_single_profile(self, name):
# get the profile object:
- profile = self.profiles.find(name)
+ profile = self.profiles.find(name=name)
if profile is None:
raise CX(_("error in profile lookup"))
# rebuild profile_list YAML file in webdir
@@ -93,7 +93,7 @@ class BootLiteSync:
def add_single_system(self, name):
# get the system object:
- system = self.systems.find(name)
+ system = self.systems.find(name=name)
if system is None:
raise CX(_("error in system lookup for %s") % name)
# rebuild system_list file in webdir
@@ -106,7 +106,7 @@ class BootLiteSync:
self.sync.validate_kickstart_for_specific_system(system)
def remove_single_system(self, name):
- system_record = self.systems.find(name)
+ system_record = self.systems.find(name=name)
# rebuild system_list file in webdir
self.sync.write_listings()
# delete system YAML file in systems/$name in webdir
@@ -118,11 +118,11 @@ class BootLiteSync:
# delete PXE Linux configuration file (which might be in one of two places)
itanic = False
- system_record = self.systems.find(name)
- profile = self.profiles.find(system_record.profile)
+ system_record = self.systems.find(name=name)
+ profile = self.profiles.find(name=system_record.profile)
# allow cobbler deletes to still work in the cobbler config is discombobulated
if profile is not None:
- distro = self.distros.find(profile.distro)
+ distro = self.distros.find(name=profile.distro)
if distro is not None and distro in [ "ia64", "IA64"]:
itanic = True
if not itanic:
diff --git a/cobbler/action_reposync.py b/cobbler/action_reposync.py
index 94c54a4..53cf4a3 100644
--- a/cobbler/action_reposync.py
+++ b/cobbler/action_reposync.py
@@ -129,10 +129,9 @@ class RepoSync:
if not os.path.exists(dest_path):
os.makedirs(dest_path)
- # if we only want certain RPMs, use yumdownloader (likely more than once)
- # FIXME: yumdownloader has a current bug where --resolve blows up
- # removing --resolve until I get the email from bugzilla saying it's fixed.
- cmd = "/usr/bin/yumdownloader -c %s --destdir=%s %s" %(temp_file, dest_path, " ".join(repo.rpm_list))
+ # older yumdownloader sometimes explodes on --resolvedeps
+ # if this happens to you, upgrade yum & yum-utils
+ cmd = "/usr/bin/yumdownloader --resolve -c %s --destdir=%s %s" %(temp_file, dest_path, " ".join(repo.rpm_list))
print _("- %s") % cmd
cmds.append(cmd)
else:
diff --git a/cobbler/action_status.py b/cobbler/action_status.py
index 158ee30..cc6ebd4 100644
--- a/cobbler/action_status.py
+++ b/cobbler/action_status.py
@@ -17,6 +17,7 @@ import os
import os.path
import glob
import time
+import api as cobbler_api
from rhpl.translate import _, N_, textdomain, utf8
@@ -99,6 +100,8 @@ class BootStatusReport:
tracking will be incomplete. This should be noted in the docs.
"""
+ api = cobbler_api.BootAPI()
+
apache_results = self.scan_apache_logfiles()
syslog_results = self.scan_syslog_logfiles()
ips = apache_results.keys()
@@ -112,9 +115,9 @@ class BootStatusReport:
last_recorded_time = 0
time_collisions = 0
- #header = ("Address", "State", "Started", "Last Request", "Seconds", "Log Entries")
+ #header = ("Name", "State", "Started", "Last Request", "Seconds", "Log Entries")
print "%-20s | %-15s | %-25s | %-25s | %-10s | %-6s" % (
- _("Address"),
+ _("Name"),
_("State"),
_("Last Request"),
_("Started"),
@@ -150,20 +153,22 @@ class BootStatusReport:
else:
entries[logtime] = "1"
+ obj = api.systems().find(ip_address=ip)
- self.generate_report(entries,ip)
-
+ if obj is not None:
+ self.generate_report(entries,obj.name)
+ else:
+ self.generate_report(entries,ip)
return True
#-----------------------------------------
- def generate_report(self,entries,ip):
+ def generate_report(self,entries,name):
"""
Given the information about transferred files and kickstart finish times, attempt
to produce a report that most describes the state of the system.
"""
-
# sort the access times
rtimes = entries.keys()
rtimes.sort()
@@ -175,7 +180,7 @@ class BootStatusReport:
fcount = 0
if len(rtimes) == 0:
- print _("%s: ?") % ip
+ print _("%s: ?") % name
return
# for each request time the machine has made
@@ -215,7 +220,7 @@ class BootStatusReport:
# print the status line for this IP address
print "%-20s | %-15s | %-25s | %-25s | %-10s | %-6s" % (
- ip,
+ name,
install_state,
display_start,
display_last,
diff --git a/cobbler/action_sync.py b/cobbler/action_sync.py
index 117f078..40419c8 100644
--- a/cobbler/action_sync.py
+++ b/cobbler/action_sync.py
@@ -373,7 +373,7 @@ class BootSync:
buf = ""
repos = profile.repos
for r in repos:
- repo = self.repos.find(r)
+ repo = self.repos.find(name=r)
if repo is None:
continue
http_url = "http://%s/cblr/repo_mirror/%s" % (self.settings.server, repo.name)
@@ -395,7 +395,7 @@ class BootSync:
repos = profile.repos
buf = ""
for r in repos:
- repo = self.repos.find(r)
+ repo = self.repos.find(name=r)
if repo is None:
continue
repo.local_filename = repo.local_filename.replace(".repo","")
@@ -592,7 +592,7 @@ class BootSync:
def make_pxe_menu(self):
# only do this if there is NOT a system named default.
- default = self.systems.find("default")
+ default = self.systems.find(name="default")
if default is not None:
return
@@ -680,7 +680,7 @@ class BootSync:
if system is not None and kickstart_path.startswith("/"):
# pxe_fn = utils.get_config_filename(system)
kickstart_path = "http://%s/cblr/kickstarts_sys/%s/ks.cfg" % (self.settings.server, system.name)
- elif kickstart_path.startswith("/") or kickstart_path.find("/cobbler/kickstarts/") != -1:
+ elif kickstart_path.startswith("/") or kickstart_path.find(name="/cobbler/kickstarts/") != -1:
kickstart_path = "http://%s/cblr/kickstarts/%s/ks.cfg" % (self.settings.server, profile.name)
if distro.breed is None or distro.breed == "redhat":
diff --git a/cobbler/cobbler.py b/cobbler/cobbler.py
index 13daabd..0f34eee 100755
--- a/cobbler/cobbler.py
+++ b/cobbler/cobbler.py
@@ -200,7 +200,7 @@ class BootCLI:
def __list_names2(self, collection, args):
for p in args:
- obj = collection.find(p)
+ obj = collection.find(name=p)
if obj is not None:
print obj.printable()
return True
@@ -269,7 +269,7 @@ class BootCLI:
control_fn(args,obj)
def __generic_edit(self,args,collection_fn,control_fn,exc_msg):
- obj = collection_fn().find(self.find_arg(args,"--name"))
+ 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'")
@@ -278,7 +278,7 @@ class BootCLI:
control_fn(args,obj)
def __generic_copy(self,args,collection_fn,control_fn,exc_msg):
- obj = collection_fn().find(self.find_arg(args,"--name"))
+ obj = collection_fn().find(name=self.find_arg(args,"--name"))
obj2 = self.find_arg(args,"--newname")
if obj is None:
raise CX(exc_msg)
diff --git a/cobbler/cobblerd.py b/cobbler/cobblerd.py
index 54294cb..1e2f32f 100644
--- a/cobbler/cobblerd.py
+++ b/cobbler/cobblerd.py
@@ -71,10 +71,11 @@ def do_syslog(bootapi, settings, port, logger):
while 1:
data, addr = s.recvfrom(buf)
(ip, port) = addr
- if not data:
+ system = bootapi.systems().find(ip_address = ip)
+ if not data and system:
break
else:
- logfile = open("/var/log/cobbler/syslog/%s" % ip, "a+")
+ logfile = open("/var/log/cobbler/syslog/%s" % system.name, "a+")
t = time.localtime()
# write numeric time
seconds = str(time.mktime(t))
@@ -118,7 +119,7 @@ class CobblerXMLRPCInterface:
# feature disabled!
return False
systems = self.api.systems()
- obj = systems.find(name)
+ obj = systems.find(name=name)
if obj == None:
# system not found!
return False
@@ -148,7 +149,7 @@ class CobblerXMLRPCInterface:
def __get_specific(self,collection,name):
self.api.clear()
self.api.deserialize()
- item = collection.find(name)
+ item = collection.find(name=name)
if item is None:
return self.fix_none({})
return self.fix_none(item.to_datastruct())
@@ -169,7 +170,7 @@ class CobblerXMLRPCInterface:
def get_distro_for_koan(self,name):
self.api.clear()
self.api.deserialize()
- obj = cobbler_api.distros().find(name)
+ obj = self.api.distros().find(name=name)
if obj is not None:
return self.fix_none(utils.blender(True, obj))
return self.fix_none({})
@@ -177,7 +178,7 @@ class CobblerXMLRPCInterface:
def get_profile_for_koan(self,name):
self.api.clear()
self.api.deserialize()
- obj = self.api.profiles().find(name)
+ obj = self.api.profiles().find(name=name)
if obj is not None:
return self.fix_none(utils.blender(True, obj))
return self.fix_none({})
@@ -185,7 +186,7 @@ class CobblerXMLRPCInterface:
def get_system_for_koan(self,name):
self.api.clear()
self.api.deserialize()
- obj = self.api.systems().find(name)
+ obj = self.api.systems().find(name=name)
if obj is not None:
return self.fix_none(utils.blender(True, obj))
return self.fix_none({})
@@ -193,7 +194,7 @@ class CobblerXMLRPCInterface:
def get_repo_for_koan(self,name):
self.api.clear()
self.api.deserialize()
- obj = self.api.repos().find(name)
+ obj = self.api.repos().find(name=name)
if obj is not None:
return self.fix_none(utils.blender(True, obj))
return self.fix_none({})
diff --git a/cobbler/collection.py b/cobbler/collection.py
index 0c743f4..16ad9ac 100644
--- a/cobbler/collection.py
+++ b/cobbler/collection.py
@@ -30,8 +30,8 @@ class Collection(serializable.Serializable):
def __init__(self,config):
"""
- Constructor.
- """
+ Constructor.
+ """
self.config = config
self.clear()
@@ -54,17 +54,71 @@ class Collection(serializable.Serializable):
"""
self.listing = {}
- def find(self,name):
+ def find(self, name=None, return_list=False, **kargs):
"""
- Return anything named 'name' in the collection, else return None if
- no objects can be found.
+ Return first object in the collection that maches all item='value'
+ pairs passed, else return None if no objects can be found.
"""
- n1 = name.lower()
- listing = self.listing
- if listing.has_key(n1):
- return self.listing[n1]
+
+ matches = []
+
+ # support the old style innovation without kwargs
+ if name is not None:
+ kargs["name"] = name
+
+ # no arguments is an error, so we don't return a false match
+ if len(kargs) == 0:
+ raise CX(_("calling find with no arguments"))
+
+ # performance: if the only key is name we can skip the whole loop
+ if len(kargs) == 1 and kargs.has_key("name") and not return_list:
+ return self.listing.get(kargs["name"].lower(), None)
+
+ argument_check_made = False
+
+ # for each item in the collection
+ for name in self.listing:
+
+ # used to flag that this particular object is not a match
+ failed = False
+ obj = self.listing[name]
+ objdata = self.listing[name].to_datastruct()
+
+ # make sure that the object being queried actually has
+ # the property being queried -- only need to be run once
+ # this will ensure the user gets no unexpected false
+ # positives
+
+ if not argument_check_made:
+ fields = objdata.keys()
+ for x in kargs.keys():
+ if not x in fields:
+ raise CX(_("queried object has no field: %s") % x)
+ argument_check_made = True
+
+ # now do the comparision...
+ # for each key in the object's data
+
+ for key in objdata.keys():
+
+ # if the key was specified as an arg to find
+ if kargs.has_key(key):
+
+ # reject if it doesn't match
+ if str(kargs[key]).lower() != str(objdata[key]).lower():
+ failed = True
+ continue
+
+ # if no matches failed, this is our item
+ if not failed:
+ matches.append(obj)
+
+ if not return_list:
+ if len(matches) == 0:
+ return None
+ return matches[0]
else:
- return None
+ return matches
def to_datastruct(self):
"""
diff --git a/cobbler/collection_distros.py b/cobbler/collection_distros.py
index 70029eb..9ab9e3c 100644
--- a/cobbler/collection_distros.py
+++ b/cobbler/collection_distros.py
@@ -51,7 +51,7 @@ class Distros(collection.Collection):
for v in self.config.profiles():
if v.distro == name:
raise CX(_("removal would orphan profile: %s") % v.name)
- if self.find(name):
+ if self.find(name=name):
if with_delete:
self._run_triggers(self.listing[name], "/var/lib/cobbler/triggers/delete/distro/pre/*")
lite_sync = action_litesync.BootLiteSync(self.config)
diff --git a/cobbler/collection_profiles.py b/cobbler/collection_profiles.py
index ac1798e..7331b08 100644
--- a/cobbler/collection_profiles.py
+++ b/cobbler/collection_profiles.py
@@ -49,7 +49,7 @@ class Profiles(collection.Collection):
for v in self.config.systems():
if v.profile == name:
raise CX(_("removal would orphan system: %s") % v.name)
- if self.find(name):
+ if self.find(name=name):
if with_delete:
self._run_triggers(self.listing[name], "/var/lib/cobbler/triggers/delete/profile/pre/*")
lite_sync = action_litesync.BootLiteSync(self.config)
diff --git a/cobbler/collection_repos.py b/cobbler/collection_repos.py
index 8ffa1bf..ed62d88 100644
--- a/cobbler/collection_repos.py
+++ b/cobbler/collection_repos.py
@@ -53,7 +53,7 @@ class Repos(collection.Collection):
# NOTE: with_delete isn't currently meaningful for repos
# but is left in for consistancy in the API. Unused.
name = name.lower()
- if self.find(name):
+ if self.find(name=name):
if with_delete:
self._run_triggers(self.listing[name], "/var/lib/cobbler/triggers/delete/repo/pre/*")
self._run_triggers(self.listing[name], "/var/lib/cobbler/triggers/delete/repo/post/*")
diff --git a/cobbler/collection_systems.py b/cobbler/collection_systems.py
index 5ffcea5..58f9e13 100644
--- a/cobbler/collection_systems.py
+++ b/cobbler/collection_systems.py
@@ -49,7 +49,7 @@ class Systems(collection.Collection):
Remove element named 'name' from the collection
"""
name = name.lower()
- if self.find(name):
+ if self.find(name=name):
if with_delete:
self._run_triggers(self.listing[name], "/var/lib/cobbler/triggers/delete/system/pre/*")
lite_sync = action_litesync.BootLiteSync(self.config)
diff --git a/cobbler/item_distro.py b/cobbler/item_distro.py
index 4bbf32f..4a97fcf 100644
--- a/cobbler/item_distro.py
+++ b/cobbler/item_distro.py
@@ -55,7 +55,7 @@ class Distro(item.Item):
if self.parent is None or self.parent == '':
return None
else:
- return self.config.distros().find(self.parent)
+ return self.config.distros().find(name=self.parent)
def from_datastruct(self,seed_data):
"""
diff --git a/cobbler/item_profile.py b/cobbler/item_profile.py
index c7c9814..4062826 100644
--- a/cobbler/item_profile.py
+++ b/cobbler/item_profile.py
@@ -91,7 +91,7 @@ class Profile(item.Item):
# check must be done in two places as set_parent could be called before/after
# set_name...
raise CX(_("self parentage is weird"))
- found = self.config.profiles().find(parent_name)
+ found = self.config.profiles().find(name=parent_name)
if found is None:
raise CX(_("profile %s not found, inheritance not possible") % parent_name)
self.parent = parent_name
@@ -102,7 +102,7 @@ class Profile(item.Item):
Sets the distro. This must be the name of an existing
Distro object in the Distros collection.
"""
- d = self.config.distros().find(distro_name)
+ d = self.config.distros().find(name=distro_name)
if d is not None:
self.distro = distro_name
self.depth = d.depth +1 # reset depth if previously a subprofile and now top-level
@@ -125,7 +125,7 @@ class Profile(item.Item):
except:
pass
for r in repolist:
- if not self.config.repos().find(r):
+ if not self.config.repos().find(name=r):
ok = False
break
if ok:
@@ -203,9 +203,9 @@ class Profile(item.Item):
Return object next highest up the tree.
"""
if self.parent is None or self.parent == '':
- result = self.config.distros().find(self.distro)
+ result = self.config.distros().find(name=self.distro)
else:
- result = self.config.profiles().find(self.parent)
+ result = self.config.profiles().find(name=self.parent)
return result
def is_valid(self):
diff --git a/cobbler/item_system.py b/cobbler/item_system.py
index cb7d02f..3575d79 100644
--- a/cobbler/item_system.py
+++ b/cobbler/item_system.py
@@ -93,9 +93,9 @@ class System(item.Item):
Return object next highest up the tree.
"""
if self.parent is None or self.parent == '':
- return self.config.profiles().find(self.profile)
+ return self.config.profiles().find(name=self.profile)
else:
- return self.config.systems().find(self.parent)
+ return self.config.systems().find(name=self.parent)
def set_name(self,name):
"""
@@ -180,10 +180,10 @@ class System(item.Item):
def set_profile(self,profile_name):
"""
- Set the system to use a certain named profile. The profile
- must have already been loaded into the Profiles collection.
- """
- p = self.config.profiles().find(profile_name)
+ Set the system to use a certain named profile. The profile
+ must have already been loaded into the Profiles collection.
+ """
+ p = self.config.profiles().find(name=profile_name)
if p is not None:
self.profile = profile_name
self.depth = p.depth + 1 # subprofiles have varying depths.
@@ -229,8 +229,8 @@ class System(item.Item):
def is_valid(self):
"""
- A system is valid when it contains a valid name and a profile.
- """
+ A system is valid when it contains a valid name and a profile.
+ """
# NOTE: this validation code does not support inheritable distros at this time.
# this is by design as inheritable systems don't make sense.
if self.name is None: