diff options
-rw-r--r-- | cobbler/config.py | 14 | ||||
-rw-r--r-- | cobbler/item_distro.py | 5 | ||||
-rw-r--r-- | cobbler/item_profile.py | 12 | ||||
-rw-r--r-- | cobbler/item_repo.py | 7 | ||||
-rw-r--r-- | cobbler/item_system.py | 13 | ||||
-rw-r--r-- | cobbler/serializer.py | 16 |
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"]) |