diff options
-rw-r--r-- | cobbler/action_check.py (renamed from cobbler/check.py) | 8 | ||||
-rw-r--r-- | cobbler/action_sync.py (renamed from cobbler/sync.py) | 20 | ||||
-rw-r--r-- | cobbler/api.py | 37 | ||||
-rwxr-xr-x | cobbler/cobbler | 5 | ||||
-rwxr-xr-x | cobbler/cobbler.py | 5 | ||||
-rw-r--r-- | cobbler/collection.py | 41 | ||||
-rw-r--r-- | cobbler/collection_distros.py | 4 | ||||
-rw-r--r-- | cobbler/collection_profiles.py | 19 | ||||
-rw-r--r-- | cobbler/collection_systems.py | 15 | ||||
-rw-r--r-- | cobbler/config.py | 3 | ||||
-rw-r--r-- | cobbler/item.py | 8 | ||||
-rw-r--r-- | cobbler/item_distro.py | 8 | ||||
-rw-r--r-- | cobbler/item_profile.py | 7 | ||||
-rw-r--r-- | cobbler/item_system.py | 7 | ||||
-rw-r--r-- | cobbler/msg.py | 6 | ||||
-rw-r--r-- | cobbler/serializable.py | 16 | ||||
-rw-r--r-- | cobbler/settings.py | 11 | ||||
-rw-r--r-- | cobbler/utils.py | 22 |
18 files changed, 155 insertions, 87 deletions
diff --git a/cobbler/check.py b/cobbler/action_check.py index fd3291f..cb02f69 100644 --- a/cobbler/check.py +++ b/cobbler/action_check.py @@ -1,6 +1,8 @@ -# Classes for validating whether asystem is configured for network booting -# -# Michael DeHaan <mdehaan@redhat.com> +""" +Classes for validating whether asystem is configured for network booting + +Michael DeHaan <mdehaan@redhat.com> +""" import os import sys diff --git a/cobbler/sync.py b/cobbler/action_sync.py index 9e51718..7e0d35e 100644 --- a/cobbler/sync.py +++ b/cobbler/action_sync.py @@ -1,6 +1,8 @@ -# Code to vivify a configuration into a real TFTP/DHCP configuration. -# -# Michael DeHaan <mdehaan@redhat.com> +""" +Code to vivify a configuration into a real TFTP/DHCP configuration. + +Michael DeHaan <mdehaan@redhat.com> +""" import config @@ -11,6 +13,8 @@ import re import shutil import syck import weakref + +import utils from msg import * """ @@ -22,10 +26,10 @@ class BootSync: def __init__(self,config): self.verbose = True self.config = config - self.distros = config.distros - self.profiles = config.profiles - self.systems = config.systems - self.settings = config.settings + self.distros = config.distros() + self.profiles = config.profiles() + self.systems = config.systems() + self.settings = config.settings() def sync(self,dry_run=False,verbose=True): @@ -275,7 +279,7 @@ class BootSync: Create system information for xen-net-install """ fd = self.open_file(filename,"w+") - self.tee(fd,yaml.dump(system.to_datastruct())) + self.tee(fd,syck.dump(system.to_datastruct())) self.close_file(fd) def tee(self,fd,text): diff --git a/cobbler/api.py b/cobbler/api.py index 318dc51..4cae53d 100644 --- a/cobbler/api.py +++ b/cobbler/api.py @@ -1,6 +1,6 @@ """ -python API module for BootConf -see source for bootconf.py for a good API reference +python API module for Cobbler +see source for cobbler.py, or pydoc, for example usage. Michael DeHaan <mdehaan@redhat.com> """ @@ -11,8 +11,8 @@ import traceback import config import utils -import sync -import check +import action_sync +import action_check _config = config.Config() @@ -23,7 +23,6 @@ class BootAPI: """ Constructor... """ - self.debug = 1 # FIXME: deserializer/serializer error # handling probably not up to par yet self.deserialize() @@ -33,7 +32,7 @@ class BootAPI: """ Forget about current list of profiles, distros, and systems """ - if self.debug: + if utils.app_debug: print "BootAPI::clear" _config.clear() @@ -42,7 +41,7 @@ class BootAPI: """ Return the current list of systems """ - if self.debug: + if utils.app_debug: print "BootAPI::systems" return _config.systems() @@ -51,7 +50,7 @@ class BootAPI: """ Return the current list of profiles """ - if self.debug: + if utils.app_debug: print "BootAPI::profiles" return _config.profiles() @@ -60,7 +59,7 @@ class BootAPI: """ Return the current list of distributions """ - if self.debug: + if utils.app_debug: print "BootAPI::distros" return _config.distros() @@ -69,7 +68,7 @@ class BootAPI: """ Return a blank, unconfigured system, unattached to a collection """ - if self.debug: + if utils.app_debug: print "BootAPI::new_system" return _config.new_system() @@ -78,7 +77,7 @@ class BootAPI: """ Create a blank, unconfigured distro, unattached to a collection. """ - if self.debug: + if utils.app_debug: print "BootAPI::new_distro" return _config.new_distro() @@ -87,7 +86,7 @@ class BootAPI: """ Create a blank, unconfigured profile, unattached to a collection """ - if self.debug: + if utils.app_debug: print "BootAPI::new_profile" return _config.new_profile() @@ -100,9 +99,9 @@ class BootAPI: for human admins, who may, for instance, forget to properly set up their TFTP servers for PXE, etc. """ - if self.debug: + if utils.app_debug: print "BootAPI::check" - return check.BootCheck(_config).run() + return action_check.BootCheck(_config).run() def sync(self,dry_run=True): @@ -112,17 +111,17 @@ class BootAPI: /tftpboot. Any operations done in the API that have not been saved with serialize() will NOT be synchronized with this command. """ - if self.debug: + if utils.app_debug: print "BootAPI::sync" # config.deserialize(); # neccessary? - return sync.BootSync(_config).sync(dry_run) + return action_sync.BootSync(_config).sync(dry_run) def serialize(self): """ Save the config file(s) to disk. """ - if self.debug: + if utils.app_debug: print "BootAPI::serialize" _config.serialize() @@ -130,12 +129,12 @@ class BootAPI: """ Load the current configuration from config file(s) """ - if self.debug: + if utils.app_debug: print "BootAPI::deserialize" _config.deserialize() def last_error(self): - if self.debug: + if utils.app_debug: print "BootAPI::last_error" return utils.last_error() diff --git a/cobbler/cobbler b/cobbler/cobbler index f62e10f..d69b50b 100755 --- a/cobbler/cobbler +++ b/cobbler/cobbler @@ -1,5 +1,10 @@ #!/usr/bin/python +""" +Wrapper for cobbler +Michael DeHaan <mdehaan@redhat.com> +""" + import sys import cobbler sys.exit(cobbler.main()) diff --git a/cobbler/cobbler.py b/cobbler/cobbler.py index f170aee..9ea56f1 100755 --- a/cobbler/cobbler.py +++ b/cobbler/cobbler.py @@ -1,9 +1,8 @@ -#!/usr/bin/env python -# Michael DeHaan <mdehaan@redhat.com> - """ Command line interface for cobbler, a network provisioning configuration library. Consult 'man cobbler' for general info. + +Michael DeHaan <mdehaan@redhat.com> """ import os diff --git a/cobbler/collection.py b/cobbler/collection.py index c02d10c..3d44510 100644 --- a/cobbler/collection.py +++ b/cobbler/collection.py @@ -1,29 +1,30 @@ +""" +Base class for any serializable list of things... + +Michael DeHaan <mdehaan@redhat.com> +""" + import serializable import utils import msg -""" -Base class for any serializable lists of things... -""" class Collection(serializable.Serializable): - def factory_produce(self): - raise exceptions.NotImplementedError - - def filename(self): - raise exceptions.NotImplementedError - def __init__(self,config): """ Constructor. """ self.config = config - self.debug = 1 self.clear() + def factory_produce(self): + raise exceptions.NotImplementedError + + def filename(self): + raise exceptions.NotImplementedError def clear(self): - if self.debug: + if utils.app_debug: print "Collection::clear" self.listing = {} @@ -32,7 +33,7 @@ class Collection(serializable.Serializable): Return anything named 'name' in the collection, else return None if no objects can be found. """ - if self.debug: + if utils.app_debug: print "Collection::find(%s)" % name if name in self.listing.keys(): return self.listing[name] @@ -43,20 +44,20 @@ class Collection(serializable.Serializable): """ Serialize the collection """ - if self.debug: + if utils.app_debug: print "Collection::to_datastruct" datastruct = [x.to_datastruct() for x in self.listing.values()] return datastruct def from_datastruct(self,datastruct): - if self.debug: + if utils.app_debug: print "Collection::from_datastruct(%s)" % datastruct if datastruct is None: print "DEBUG: from_datastruct -> None, skipping" return print "DEBUG: from_datastruct: %s" % datastruct - for x in datastruct: - item = self.factory_produce(self.config) + for seed_data in datastruct: + item = self.factory_produce(self.config,seed_data) self.add(item) def add(self,ref): @@ -66,7 +67,7 @@ class Collection(serializable.Serializable): object specified by ref deems itself invalid (and therefore won't be added to the collection). """ - if self.debug: + if utils.app_debug: print "Collection::add(%s)" % ref if ref is None or not ref.is_valid(): if utils.last_error() is None or utils.last_error() == "": @@ -82,7 +83,7 @@ class Collection(serializable.Serializable): for reading by humans or parsing from scripts. Actually scripts would be better off reading the YAML in the config files directly. """ - if self.debug: + if utils.app_debug: print "Collection::printable" values = map(lambda(a): a.printable(), sorted(self.listing.values())) if len(values) > 0: @@ -94,7 +95,7 @@ class Collection(serializable.Serializable): """ Iterator for the collection. Allows list comprehensions, etc """ - if self.debug: + if utils.app_debug: print "Collection::__iter__" for a in self.listing.values(): yield a @@ -103,7 +104,7 @@ class Collection(serializable.Serializable): """ Returns size of the collection """ - if self.debug: + if utils.app_debug: print "Collection::__len__" return len(self.listing.values()) diff --git a/cobbler/collection_distros.py b/cobbler/collection_distros.py index 03a1557..e700727 100644 --- a/cobbler/collection_distros.py +++ b/cobbler/collection_distros.py @@ -10,8 +10,8 @@ and initrd files """ class Distros(collection.Collection): - def factory_produce(self,config): - return distro.Distro(config) + def factory_produce(self,config,seed_data): + return distro.Distro(config).from_datastruct(seed_data) def filename(self): return "/var/lib/cobbler/distros" diff --git a/cobbler/collection_profiles.py b/cobbler/collection_profiles.py index b691822..a5b1996 100644 --- a/cobbler/collection_profiles.py +++ b/cobbler/collection_profiles.py @@ -1,19 +1,22 @@ -import profile -import utils -import collection - -#-------------------------------------------- - """ A profile represents a distro paired with a kickstart file. For instance, FC5 with a kickstart file specifying OpenOffice might represent a 'desktop' profile. For Xen, there are many additional options, with client-side defaults (not kept here). + +Michael DeHaan <mdehaan@redhat.com> """ + +import item_profile as profile +import utils +import collection + +#-------------------------------------------- + class Profiles(collection.Collection): - def factory_produce(self,config): - return profile.Profile(config) + def factory_produce(self,config,seed_data): + return profile.Profile(config).from_datastruct(seed_data) def filename(self): return "/var/lib/cobbler/profiles" diff --git a/cobbler/collection_systems.py b/cobbler/collection_systems.py index d353bbc..abcf417 100644 --- a/cobbler/collection_systems.py +++ b/cobbler/collection_systems.py @@ -1,17 +1,20 @@ +""" +Systems are hostnames/MACs/IP names and the associated profile +they belong to. + +Michael DeHaan <mdehaan@redhat.com> +""" + import item_system as system import utils import collection #-------------------------------------------- -""" -Systems are hostnames/MACs/IP names and the associated profile -they belong to. -""" class Systems(collection.Collection): - def factory_produce(self,config): - return system.System(config) + def factory_produce(self,config,seed_data): + return system.System(config).from_datastruct(seed_data) def filename(self): return "/var/lib/cobbler/systems" diff --git a/cobbler/config.py b/cobbler/config.py index bb2e454..470b57c 100644 --- a/cobbler/config.py +++ b/cobbler/config.py @@ -1,6 +1,9 @@ """ Config.py is a repository of the Cobbler object model + +Michael DeHaan <mdehaan@redhat.com> """ + import os import weakref diff --git a/cobbler/item.py b/cobbler/item.py index a881b40..c2944e6 100644 --- a/cobbler/item.py +++ b/cobbler/item.py @@ -1,9 +1,11 @@ - -import serializable - """ An Item is a serializable thing that can appear in a Collection + +Michael DeHaan <mdehaan@redhat.com> """ + +import serializable + class Item(serializable.Serializable): """ diff --git a/cobbler/item_distro.py b/cobbler/item_distro.py index efbead9..312cd8d 100644 --- a/cobbler/item_distro.py +++ b/cobbler/item_distro.py @@ -1,3 +1,10 @@ +""" +A cobbler distribution + +Michael DeHaan <mdehaan@redhat.com> +""" + + import utils import item import weakref @@ -20,6 +27,7 @@ class Distro(item.Item): self.kernel = seed_data['kernel'] self.initrd = seed_data['initrd'] self.kernel_options = seed_data['kernel_options'] + return self def set_kernel(self,kernel): """ diff --git a/cobbler/item_profile.py b/cobbler/item_profile.py index 1f32c35..f84f241 100644 --- a/cobbler/item_profile.py +++ b/cobbler/item_profile.py @@ -1,3 +1,9 @@ +""" +A Cobbler Profile. + +Michael DeHaan <mdehaan@redhat.com> +""" + import utils import item from msg import * @@ -31,6 +37,7 @@ class Profile(item.Item): self.xen_file_size = seed_data['xen_file_size'] self.xen_mac = seed_data['xen_mac'] self.xen_paravirt = seed_data['xen_paravirt'] + return self def set_distro(self,distro_name): """ diff --git a/cobbler/item_system.py b/cobbler/item_system.py index ef2985c..22ea4b3 100644 --- a/cobbler/item_system.py +++ b/cobbler/item_system.py @@ -1,3 +1,9 @@ +""" +A Cobbler System. + +Michael DeHaan <mdehaan@redhat.com> +""" + import utils import item @@ -16,6 +22,7 @@ class System(item.Item): self.name = seed_data['name'] self.profile = seed_data['profile'] self.kernel_options = seed_data['kernel_options'] + return self def set_name(self,name): """ diff --git a/cobbler/msg.py b/cobbler/msg.py index ac7ffa1..ceaa0e5 100644 --- a/cobbler/msg.py +++ b/cobbler/msg.py @@ -1,9 +1,9 @@ -# Messages used by cobbler. -# Michael DeHaan <mdehaan@redhat.com> - """ +Messages used by cobbler. This module encapsulates strings so they can be reused and potentially translated. + +Michael DeHaan <mdehaan@redhat.com> """ msg_table = { diff --git a/cobbler/serializable.py b/cobbler/serializable.py index 7daa81a..0a23283 100644 --- a/cobbler/serializable.py +++ b/cobbler/serializable.py @@ -1,13 +1,27 @@ -import exceptions +""" +Serializable interface, for documentation purposes + +Michael DeHaan <mdehaan@redhat.com> +""" class Serializable: def filename(self): + """ + Return the full path to the config file this object uses. + """ return None def from_datastruct(self,datastruct): + """ + Return an object constructed with data from datastruct + """ raise exceptions.NotImplementedError def to_datastruct(self): + """ + Return hash/array/scalar reprentation of self. + This function must be the inverse of from_datastruct. + """ raise exceptions.NotImplementedError diff --git a/cobbler/settings.py b/cobbler/settings.py index 99ebd7d..bbdf3e9 100644 --- a/cobbler/settings.py +++ b/cobbler/settings.py @@ -1,9 +1,12 @@ -import serializable - """ Cobbler app-wide settings + +Michael DeHaan <mdehaan@redhat.com> """ +import serializable +import utils + class Settings(serializable.Serializable): def filename(self): @@ -34,8 +37,12 @@ class Settings(serializable.Serializable): print "DEBUG: not loading empty structure" return self._attributes = datastruct + return self + # could use getatr, but I'd rather not. def __getattr__(self,name): + if utils.app_debug: + print "Settings::__getattr__(self,%s)" % name if self._attributes.has_key(name): return self._attributes[name] else: diff --git a/cobbler/utils.py b/cobbler/utils.py index f6ab675..90354c6 100644 --- a/cobbler/utils.py +++ b/cobbler/utils.py @@ -1,6 +1,8 @@ -# Misc heavy lifting functions for cobbler -# -# Michael DeHaan <mdehaan@redhat.com> +""" +Misc heavy lifting functions for cobbler + +Michael DeHaan <mdehaan@redhat.com> +""" import os import re @@ -10,8 +12,10 @@ import subprocess import msg -re_kernel = re.compile(r'vmlinuz-(\d+)\.(\d+)\.(\d+)-(.*)') -re_initrd = re.compile(r'initrd-(\d+)\.(\d+)\.(\d+)-(.*).img') +app_debug = True # essentially an app level global, but the only one + +_re_kernel = re.compile(r'vmlinuz-(\d+)\.(\d+)\.(\d+)-(.*)') +_re_initrd = re.compile(r'initrd-(\d+)\.(\d+)\.(\d+)-(.*).img') _last_error = "" def last_error(): @@ -119,12 +123,12 @@ def find_kernel(path): """ if os.path.isfile(path): filename = os.path.basename(path) - if re_kernel.match(filename): + if _re_kernel.match(filename): return path elif filename == "vmlinuz": return path elif os.path.isdir(path): - return find_highest_files(path,"vmlinuz",re_kernel) + return find_highest_files(path,"vmlinuz",_re_kernel) return None @@ -136,12 +140,12 @@ def find_initrd(path): # FUTURE: try to match kernel/initrd pairs? if os.path.isfile(path): filename = os.path.basename(path) - if re_initrd.match(filename): + if _re_initrd.match(filename): return path if filename == "initrd.img" or filename == "initrd": return path elif os.path.isdir(path): - return find_highest_files(path,"initrd.img",re_initrd) + return find_highest_files(path,"initrd.img",_re_initrd) return None |