summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--cobbler/config.py14
-rw-r--r--cobbler/item_distro.py5
-rw-r--r--cobbler/item_profile.py12
-rw-r--r--cobbler/item_repo.py7
-rw-r--r--cobbler/item_system.py13
-rw-r--r--cobbler/serializer.py16
6 files changed, 52 insertions, 15 deletions
diff --git a/cobbler/config.py b/cobbler/config.py
index cd19d00..08bd770 100644
--- a/cobbler/config.py
+++ b/cobbler/config.py
@@ -59,10 +59,16 @@ class Config:
self._settings = settings.Settings() # not a true collection
self._repos = repos.Repos(weakref.proxy(self))
self._classes = [
+ self._settings,
+ self._distros,
+ self._profiles,
+ self._systems,
+ self._repos
+ ]
+ self._graph_classes = [
self._distros,
self._profiles,
self._systems,
- self._settings,
self._repos
]
self.file_check()
@@ -157,8 +163,10 @@ class Config:
"""
Load the object hierachy from disk, using the filenames referenced in each object.
"""
- for x in self._classes:
- if not serializer.deserialize(x):
+ if not serializer.deserialize(self._settings,topological=False):
+ return False
+ for x in self._graph_classes:
+ if not serializer.deserialize(x,topological=True):
return False
return True
diff --git a/cobbler/item_distro.py b/cobbler/item_distro.py
index b6a5bea..8fa7682 100644
--- a/cobbler/item_distro.py
+++ b/cobbler/item_distro.py
@@ -38,6 +38,7 @@ class Distro(item.Item):
self.arch = ('x86', '<<inherit>>')[is_subobject]
self.breed = ('redhat', '<<inherit>>')[is_subobject]
self.source_repos = ([], '<<inherit>>')[is_subobject]
+ self.depth = 0
def make_clone(self):
ds = self.to_datastruct()
@@ -69,6 +70,7 @@ class Distro(item.Item):
self.arch = self.load_item(seed_data,'arch','x86')
self.breed = self.load_item(seed_data,'breed','redhat')
self.source_repos = self.load_item(seed_data,'source_repos',[])
+ self.depth = self.load_item(seed_data,'depth',0)
# backwards compatibility -- convert string entries to dicts for storage
if type(self.kernel_options) != dict:
@@ -161,7 +163,8 @@ class Distro(item.Item):
'arch' : self.arch,
'breed' : self.breed,
'source_repos' : self.source_repos,
- 'parent' : self.parent
+ 'parent' : self.parent,
+ 'depth' : self.depth
}
def printable(self):
diff --git a/cobbler/item_profile.py b/cobbler/item_profile.py
index 79a7dcb..606c6f9 100644
--- a/cobbler/item_profile.py
+++ b/cobbler/item_profile.py
@@ -40,6 +40,7 @@ class Profile(item.Item):
self.virt_file_size = (5, '<<inherit>>')[is_subobject]
self.virt_ram = (512, '<<inherit>>')[is_subobject]
self.repos = ("", '<<inherit>>')[is_subobject]
+ self.depth = 1
def from_datastruct(self,seed_data):
"""
@@ -53,7 +54,8 @@ class Profile(item.Item):
self.kernel_options = self.load_item(seed_data,'kernel_options')
self.ks_meta = self.load_item(seed_data,'ks_meta')
self.repos = self.load_item(seed_data,'repos', [])
-
+ self.depth = self.load_item(seed_data,'depth', 1)
+
# backwards compatibility
if type(self.repos) != list:
self.set_repos(self.repos)
@@ -89,14 +91,17 @@ class Profile(item.Item):
if found is None:
raise CX(_("profile %s not found, inheritance not possible") % parent_name)
self.parent = parent_name
+ self.depth = found.depth + 1
def set_distro(self,distro_name):
"""
Sets the distro. This must be the name of an existing
Distro object in the Distros collection.
"""
- if self.config.distros().find(distro_name):
+ d = self.config.distros().find(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
return True
raise CX(_("distribution not found"))
@@ -217,7 +222,8 @@ class Profile(item.Item):
'virt_ram' : self.virt_ram,
'ks_meta' : self.ks_meta,
'repos' : self.repos,
- 'parent' : self.parent
+ 'parent' : self.parent,
+ 'depth' : self.depth
}
def printable(self):
diff --git a/cobbler/item_repo.py b/cobbler/item_repo.py
index c9846b1..19b2e3f 100644
--- a/cobbler/item_repo.py
+++ b/cobbler/item_repo.py
@@ -35,7 +35,8 @@ class Repo(item.Item):
self.local_filename = ("", '<<inherit>>')[is_subobject]
self.rpm_list = ("", '<<inherit>>')[is_subobject]
self.createrepo_flags = ("-c cache", '<<inherit>>')[is_subobject]
-
+ self.depth = 2 # arbitrary, as not really apart of the graph
+
def from_datastruct(self,seed_data):
self.parent = self.load_item(seed_data, 'parent')
self.name = self.load_item(seed_data, 'name')
@@ -44,6 +45,7 @@ class Repo(item.Item):
self.local_filename = self.load_item(seed_data, 'local_filename')
self.rpm_list = self.load_item(seed_data, 'rpm_list')
self.createrepo_flags = self.load_item(seed_data, 'createrepo_flags', '-c cache')
+ self.depth = self.load_item(seed_data, 'depth', 2)
return self
def set_name(self,name):
@@ -130,7 +132,8 @@ class Repo(item.Item):
'local_filename' : self.local_filename,
'rpm_list' : self.rpm_list,
'createrepo_flags' : self.createrepo_flags,
- 'parent' : self.parent
+ 'parent' : self.parent,
+ 'depth' : self.depth
}
def printable(self):
diff --git a/cobbler/item_system.py b/cobbler/item_system.py
index c2e8243..0152411 100644
--- a/cobbler/item_system.py
+++ b/cobbler/item_system.py
@@ -29,8 +29,6 @@ class System(item.Item):
return cloned
def clear(self,is_subobject=False):
- # names of cobbler repo definitions
-
self.name = None
self.profile = (None, '<<inherit>>')[is_subobject]
self.kernel_options = ({}, '<<inherit>>')[is_subobject]
@@ -39,6 +37,7 @@ class System(item.Item):
self.mac_address = ("", '<<inherit>>')[is_subobject]
self.netboot_enabled = (1, '<<inherit>>')[is_subobject]
self.hostname = ("", '<<inheirt>>')[is_subobject]
+ self.depth = 2
def from_datastruct(self,seed_data):
@@ -47,7 +46,8 @@ class System(item.Item):
self.profile = self.load_item(seed_data, 'profile')
self.kernel_options = self.load_item(seed_data, 'kernel_options')
self.ks_meta = self.load_item(seed_data, 'ks_meta')
-
+ self.depth = self.load_item(seed_data, 'depth')
+
# backwards compat, load --ip-address from two possible sources.
# the old --pxe-address was a bit of a misnomer, new value is --ip-address
@@ -175,8 +175,10 @@ class System(item.Item):
Set the system to use a certain named profile. The profile
must have already been loaded into the Profiles collection.
"""
- if self.config.profiles().find(profile_name):
+ p = self.config.profiles().find(profile_name)
+ if p is not None:
self.profile = profile_name
+ self.depth = p.depth + 1 # subprofiles have varying depths.
return True
raise CX(_("invalid profile name"))
@@ -223,7 +225,8 @@ class System(item.Item):
'netboot_enabled' : self.netboot_enabled,
'hostname' : self.hostname,
'mac_address' : self.mac_address,
- 'parent' : self.parent
+ 'parent' : self.parent,
+ 'depth' : self.depth
}
def printable(self):
diff --git a/cobbler/serializer.py b/cobbler/serializer.py
index 38a182d..39cb982 100644
--- a/cobbler/serializer.py
+++ b/cobbler/serializer.py
@@ -49,7 +49,7 @@ def serialize(obj):
fd.close()
return True
-def deserialize(obj):
+def deserialize(obj,topological=False):
"""
Populate an existing object with the contents of datastruct.
Object must "implement" Serializable. Returns True assuming
@@ -69,7 +69,21 @@ def deserialize(obj):
data = fd.read()
datastruct = yaml.load(data).next() # first record
fd.close()
+
+ if topological:
+ # in order to build the graph links from the flat list, sort by the
+ # depth of items in the graph. If an object doesn't have a depth, sort it as
+ # if the depth were 0. It will be assigned a proper depth at serialization
+ # time. This is a bit cleaner implementation wise than a topological sort,
+ # though that would make a shiny upgrade.
+ datastruct.sort(cmp=__depth_cmp)
obj.from_datastruct(datastruct)
return True
+def __depth_cmp(item1, item2):
+ if not item1.has_key("depth"):
+ return 1
+ if not item2.has_key("depth"):
+ return -1
+ return cmp(item1["depth"],item2["depth"])