summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--CHANGELOG3
-rw-r--r--Makefile7
-rw-r--r--cobbler.spec10
-rw-r--r--cobbler/action_import.py16
-rw-r--r--cobbler/api.py7
-rw-r--r--cobbler/cexceptions.py2
-rw-r--r--cobbler/collection.py6
-rw-r--r--cobbler/collection_distros.py18
-rw-r--r--cobbler/collection_profiles.py18
-rw-r--r--cobbler/collection_repos.py21
-rw-r--r--cobbler/collection_systems.py25
-rw-r--r--cobbler/config.py21
-rw-r--r--cobbler/modules/serializer_shelve.py66
-rw-r--r--cobbler/modules/serializer_yaml.py30
-rw-r--r--cobbler/remote.py53
-rw-r--r--cobbler/serializer.py6
-rw-r--r--cobbler/settings.py9
-rw-r--r--config/rsync.exclude4
-rw-r--r--tests/tests.py10
19 files changed, 176 insertions, 156 deletions
diff --git a/CHANGELOG b/CHANGELOG
index 6c33699..6f70817 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -7,6 +7,9 @@ Cobbler CHANGELOG
- Add --virt-cpus to profile editing
- Fix bug where WUI (XMLRPC) auth wasn't supported on EL4
- Add --virt-bridge to profile editing and NICs
+- Added serializer_shelve for added performance/persistance over YAML
+- Backup state and migrate structures upon RPM upgrade
+- Added some more unsupported distros to the rsync.exclude file
* Fri Sep 28 2007 - 0.6.2
- cobbler repo auto-add to discover yum repos automatically
diff --git a/Makefile b/Makefile
index 11dc5ce..4004fbe 100644
--- a/Makefile
+++ b/Makefile
@@ -17,8 +17,13 @@ manpage:
pod2html ./docs/cobbler.pod > ./docs/cobbler.html
test:
+ -mkdir -p /tmp/cobbler_test_bak
+ -cp /var/lib/cobbler/distros* /tmp/cobbler_test_bak
+ -cp /var/lib/cobbler/profiles* /tmp/cobbler_test_bak
+ -cp /var/lib/cobbler/systems* /tmp/cobbler_test_bak
+ -cp /var/lib/cobbler/repos* /tmp/cobbler_test_bak
python tests/tests.py
- -rm -rf /tmp/_cobbler-*
+ -cp /tmp/cobbler_test_bak/* /var/lib/cobbler
test2:
python tests/multi.py
diff --git a/cobbler.spec b/cobbler.spec
index fcfc229..85adb99 100644
--- a/cobbler.spec
+++ b/cobbler.spec
@@ -53,7 +53,13 @@ test "x$RPM_BUILD_ROOT" != "x" && rm -rf $RPM_BUILD_ROOT
%{__python} setup.py install --optimize=1 --root=$RPM_BUILD_ROOT
%post
+cp /var/lib/cobbler/distros* /var/lib/cobbler/backup
+cp /var/lib/cobbler/profiles* /var/lib/cobbler/backup
+cp /var/lib/cobbler/systems* /var/lib/cobbler/backup
+cp /var/lib/cobbler/repos* /var/lib/cobbler/backup
+/usr/bin/cobbler reserialize
/sbin/chkconfig --add cobblerd
+/sbin/service cobblerd restart
%preun
@@ -141,6 +147,7 @@ test "x$RPM_BUILD_ROOT" != "x" && rm -rf $RPM_BUILD_ROOT
%defattr(755,root,root)
%dir /var/lib/cobbler
%dir /var/lib/cobbler/kickstarts/
+%dir /var/lib/cobbler/backup/
%dir /var/lib/cobbler/triggers/add/distro/pre
%dir /var/lib/cobbler/triggers/add/distro/post
%dir /var/lib/cobbler/triggers/add/profile/pre
@@ -176,9 +183,10 @@ test "x$RPM_BUILD_ROOT" != "x" && rm -rf $RPM_BUILD_ROOT
%changelog
-* Mon Oct 08 2007 Michael DeHaan <mdehaan@redhat.com> - 0.6.3-1
+* Wed Oct 16 2007 Michael DeHaan <mdehaan@redhat.com> - 0.6.3-1
- Upstream changes (see CHANGELOG)
- now packaging javascript file(s) seperately for WUI
+- backup state files on upgrade
* Fri Sep 28 2007 Michael DeHaan <mdehaan@redhat.com> - 0.6.2-2
- Upstream changes (see CHANGELOG)
diff --git a/cobbler/action_import.py b/cobbler/action_import.py
index 01e9396..d2ccb64 100644
--- a/cobbler/action_import.py
+++ b/cobbler/action_import.py
@@ -347,12 +347,22 @@ class Importer:
def repo_scanner(self,distro,dirname,fnames):
+ matches = {}
print "- processing: %s" % dirname
for x in fnames:
if x == "base" or x == "repodata":
- print "- need to process repo/comps: %s" % dirname
- self.process_comps_file(dirname, distro)
- continue
+ # only run the repo scanner on directories that contain a comps.xml
+ gloob1 = glob.glob("%s/%s/comps*.xml" % (dirname,x))
+ if len(gloob1) >= 1 or len(gloob2) >= 1:
+ if matches.has_key(dirname):
+ print _("- looks like we've already scanned here: %s") % dirname
+ continue
+ print _("- need to process repo/comps: %s") % dirname
+ self.process_comps_file(dirname, distro)
+ matches[dirname] = 1
+ else:
+ print _("- directory %s is missing comps.xml, skipping") % dirname
+ continue
# ----------------------------------------------------------------------
diff --git a/cobbler/api.py b/cobbler/api.py
index 955c41d..2a51c1a 100644
--- a/cobbler/api.py
+++ b/cobbler/api.py
@@ -226,8 +226,11 @@ class BootAPI:
"""
return self._config.deserialize()
- ## FIXME: would be nice to have functions to just deserialize
- ## certain collections for efficiency in WUI calls.
+ def deserialize_raw(self,collection_name):
+ """
+ Get the collection back just as raw data.
+ """
+ return self._config.deserialize_raw(collection_name)
if __name__ == "__main__":
api = BootAPI()
diff --git a/cobbler/cexceptions.py b/cobbler/cexceptions.py
index bed420e..a78f7f2 100644
--- a/cobbler/cexceptions.py
+++ b/cobbler/cexceptions.py
@@ -14,6 +14,8 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
import exceptions
+TEST_MODE = False
+
class CobblerException(exceptions.Exception):
def __init__(self, value, *args):
diff --git a/cobbler/collection.py b/cobbler/collection.py
index de7ae72..4117bd9 100644
--- a/cobbler/collection.py
+++ b/cobbler/collection.py
@@ -43,12 +43,6 @@ class Collection(serializable.Serializable):
"""
raise exceptions.NotImplementedError
- def filename(self):
- """
- Must override in subclass. See Serializable
- """
- raise exceptions.NotImplementedError
-
def clear(self):
"""
Forget about objects in the collection.
diff --git a/cobbler/collection_distros.py b/cobbler/collection_distros.py
index 00e543d..5f54881 100644
--- a/cobbler/collection_distros.py
+++ b/cobbler/collection_distros.py
@@ -20,8 +20,6 @@ from cexceptions import *
import action_litesync
from rhpl.translate import _, N_, textdomain, utf8
-TESTMODE = False
-
class Distros(collection.Collection):
def collection_type(self):
@@ -33,16 +31,7 @@ class Distros(collection.Collection):
"""
return distro.Distro(config).from_datastruct(seed_data)
- def filename(self):
- """
- Config file for distro serialization
- """
- if TESTMODE:
- return "/var/lib/cobbler/test/distros"
- else:
- return "/var/lib/cobbler/distros"
-
- def remove(self,name,with_delete=False):
+ def remove(self,name,with_delete=True):
"""
Remove element named 'name' from the collection
"""
@@ -51,11 +40,14 @@ class Distros(collection.Collection):
for v in self.config.profiles():
if v.distro.lower() == name:
raise CX(_("removal would orphan profile: %s") % v.name)
- if self.find(name=name):
+ obj = self.find(name=name)
+ if obj is not None:
if with_delete:
self._run_triggers(self.listing[name], "/var/lib/cobbler/triggers/delete/distro/pre/*")
lite_sync = action_litesync.BootLiteSync(self.config)
lite_sync.remove_single_profile(name)
+ self.config.serialize_delete(self, obj)
+ if with_delete:
self._run_triggers(self.listing[name], "/var/lib/cobbler/triggers/delete/distro/post/*")
del self.listing[name]
return True
diff --git a/cobbler/collection_profiles.py b/cobbler/collection_profiles.py
index b11762f..7e71ec1 100644
--- a/cobbler/collection_profiles.py
+++ b/cobbler/collection_profiles.py
@@ -22,9 +22,6 @@ from cexceptions import *
import action_litesync
from rhpl.translate import _, N_, textdomain, utf8
-
-TESTMODE = False
-
#--------------------------------------------
class Profiles(collection.Collection):
@@ -35,12 +32,6 @@ class Profiles(collection.Collection):
def factory_produce(self,config,seed_data):
return profile.Profile(config).from_datastruct(seed_data)
- def filename(self):
- if TESTMODE:
- return "/var/lib/cobbler/test/profiles"
- else:
- return "/var/lib/cobbler/profiles"
-
def remove(self,name,with_delete=True):
"""
Remove element named 'name' from the collection
@@ -49,12 +40,15 @@ class Profiles(collection.Collection):
for v in self.config.systems():
if v.profile.lower() == name:
raise CX(_("removal would orphan system: %s") % v.name)
- if self.find(name=name):
+ obj = self.find(name=name)
+ if obj is not None:
if with_delete:
- self._run_triggers(self.listing[name], "/var/lib/cobbler/triggers/delete/profile/pre/*")
+ self._run_triggers(obj, "/var/lib/cobbler/triggers/delete/profile/pre/*")
lite_sync = action_litesync.BootLiteSync(self.config)
lite_sync.remove_single_profile(name)
- self._run_triggers(self.listing[name], "/var/lib/cobbler/triggers/delete/profile/post/*")
+ self.config.serialize_delete(self, obj)
+ if with_delete:
+ self._run_triggers(obj, "/var/lib/cobbler/triggers/delete/profile/post/*")
del self.listing[name]
return True
raise CX(_("cannot delete an object that does not exist"))
diff --git a/cobbler/collection_repos.py b/cobbler/collection_repos.py
index ed62d88..d1ec55d 100644
--- a/cobbler/collection_repos.py
+++ b/cobbler/collection_repos.py
@@ -36,16 +36,7 @@ class Repos(collection.Collection):
"""
return repo.Repo(config).from_datastruct(seed_data)
- def filename(self):
- """
- Return a filename for System serialization
- """
- if TESTMODE:
- return "/var/lib/cobbler/test/repos"
- else:
- return "/var/lib/cobbler/repos"
-
- def remove(self,name,with_delete=False):
+ def remove(self,name,with_delete=True):
"""
Remove element named 'name' from the collection
"""
@@ -53,10 +44,14 @@ 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=name):
+ obj = self.find(name=name)
+ if obj is not None:
+ if with_delete:
+ self._run_triggers(obj, "/var/lib/cobbler/triggers/delete/repo/pre/*")
+ # FIMXE: clean up repo config files?
+ self.config.serialize_delete(self, obj)
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/*")
+ self._run_triggers(obj, "/var/lib/cobbler/triggers/delete/repo/post/*")
del self.listing[name]
return True
raise CX(_("cannot delete an object that does not exist"))
diff --git a/cobbler/collection_systems.py b/cobbler/collection_systems.py
index 58f9e13..2582dfb 100644
--- a/cobbler/collection_systems.py
+++ b/cobbler/collection_systems.py
@@ -20,8 +20,6 @@ from cexceptions import *
import action_litesync
from rhpl.translate import _, N_, textdomain, utf8
-TESTMODE = False
-
#--------------------------------------------
class Systems(collection.Collection):
@@ -35,27 +33,24 @@ class Systems(collection.Collection):
"""
return system.System(config).from_datastruct(seed_data)
- def filename(self):
- """
- Return a filename for System serialization
- """
- if TESTMODE:
- return "/var/lib/cobbler/test/systems"
- else:
- return "/var/lib/cobbler/systems"
-
- def remove(self,name,with_delete=False):
+ def remove(self,name,with_delete=True):
"""
Remove element named 'name' from the collection
"""
name = name.lower()
- if self.find(name=name):
+ obj = self.find(name=name)
+
+ if obj is not None:
+
if with_delete:
- self._run_triggers(self.listing[name], "/var/lib/cobbler/triggers/delete/system/pre/*")
+ self._run_triggers(obj, "/var/lib/cobbler/triggers/delete/system/pre/*")
lite_sync = action_litesync.BootLiteSync(self.config)
lite_sync.remove_single_system(name)
- self._run_triggers(self.listing[name], "/var/lib/cobbler/triggers/delete/system/post/*")
+ self.config.serialize_delete(self, obj)
+ if with_delete:
+ self._run_triggers(obj, "/var/lib/cobbler/triggers/delete/system/post/*")
del self.listing[name]
+
return True
raise CX(_("cannot delete an object that does not exist"))
diff --git a/cobbler/config.py b/cobbler/config.py
index 658c8ce..258b241 100644
--- a/cobbler/config.py
+++ b/cobbler/config.py
@@ -73,8 +73,6 @@ class Config:
self._systems
]
- self.file_check()
-
def __cmp(self,a,b):
return cmp(a.name,b.name)
@@ -140,19 +138,6 @@ class Config:
x.clear()
return True
- def file_check(self):
- """
- Serialize any files that do not yet exist. This is useful for bringing the
- app up to a working state on first run or if files are deleted. See api.py
- FIXME: will require some tweaks when serializer modes aren't all file based
- """
- for x in self._serialize_graph_classes:
- if not os.path.exists(x.filename()):
- if not serializer.serialize(x):
- return False
- return True
-
-
def serialize(self):
"""
Save the object hierarchy to disk, using the filenames referenced in each object.
@@ -185,5 +170,11 @@ class Config:
return False
return True
+ def deserialize_raw(self,collection_type):
+ """
+ Get object data from disk, not objects.
+ """
+ return serializer.deserialize_raw(collection_type)
+
diff --git a/cobbler/modules/serializer_shelve.py b/cobbler/modules/serializer_shelve.py
index f7a5c65..07b05cb 100644
--- a/cobbler/modules/serializer_shelve.py
+++ b/cobbler/modules/serializer_shelve.py
@@ -16,31 +16,49 @@ along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
"""
+## FIXME: serializer needs a close() call
+## FIXME: investigate locking
+
import distutils.sysconfig
import os
import sys
import glob
import traceback
from rhpl.translate import _, N_, textdomain, utf8
-from cexceptions import *
import os
import shelve
+import time
+#import gdbm # FIXME: check if available in EL4?
+import bsddb
-# FIXME: this is only needed for loading other modules, right?
-# plib = distutils.sysconfig.get_python_lib()
-# mod_path="%s/cobbler" % plib
-# sys.path.insert(0, mod_path)
+plib = distutils.sysconfig.get_python_lib()
+mod_path="%s/cobbler" % plib
+sys.path.insert(0, mod_path)
+import cexceptions
+import utils
-import gdbm # FIXME: check if available in EL4?
+DATABASES = {}
-def open_db(obj):
+def open_db(collection_type):
+ if DATABASES.has_key(collection_type):
+ return DATABASES[collection_type]
+ ending = collection_type
+ if not ending.endswith("s"):
+ ending = ending + "s"
while 1:
try:
- filename = obj.filename() + ".gdbm"
- internal_db = gdbm.open(filename, 'c', 0644)
- return shelve.BsdDbShelf(internal_db)
- except gdbm.error:
+ filename = "/var/lib/cobbler/%s.gdbm" % ending
+
+ internal_db = bsddb.btopen( filename, 'c', 0644 )
+
+
+ #internal_db = gdbm.open(filename, 'c', 0644)
+ database = shelve.BsdDbShelf(internal_db)
+ DATABASES[collection_type] = database
+ return database
+ except:
+ traceback.print_exc()
print "- can't access %s right now, waiting..." % filename
time.sleep(1)
continue
@@ -60,27 +78,37 @@ def serialize(obj):
# FIXME: this needs to understand deletes
# FIXME: create partial serializer and don't use this
- fd = open_db(obj)
+ fd = open_db(obj.collection_type())
for entry in obj:
fd[entry.name] = entry.to_datastruct()
- fd.sync()
+ # fd.sync()
return True
def serialize_item(obj, item):
- fd = open_db(obj)
+ fd = open_db(obj.collection_type())
fd[item.name] = item.to_datastruct()
- fd.sync()
+ # fd.sync()
return True
# NOTE: not heavily tested
def serialize_delete(obj, item):
- fd = open_db(obj)
+ fd = open_db(obj.collection_type())
if fd.has_key(item.name):
+ print "DEBUG: deleting: %s" % item.name
del fd[item.name]
- fd.sync()
+ # fd.sync()
return True
+def deserialize_raw(collection_type):
+ fd = open_db(collection_type)
+ datastruct = []
+ # FIXME: see if we can call items() directly
+ for (key,value) in fd.iteritems():
+ datastruct.append(value)
+ # fd.close()
+ return datastruct
+
def deserialize(obj,topological=False):
"""
Populate an existing object with the contents of datastruct.
@@ -88,13 +116,13 @@ def deserialize(obj,topological=False):
files could be read and contained decent YAML. Otherwise returns
False.
"""
- fd = open_db(obj)
+ fd = open_db(obj.collection_type())
datastruct = []
for (key,value) in fd.iteritems():
datastruct.append(value)
- fd.close()
+ # fd.close()
if topological and type(datastruct) == list:
# in order to build the graph links from the flat list, sort by the
diff --git a/cobbler/modules/serializer_yaml.py b/cobbler/modules/serializer_yaml.py
index 52570cf..4c3dfbb 100644
--- a/cobbler/modules/serializer_yaml.py
+++ b/cobbler/modules/serializer_yaml.py
@@ -21,10 +21,10 @@ plib = distutils.sysconfig.get_python_lib()
mod_path="%s/cobbler" % plib
sys.path.insert(0, mod_path)
-
from rhpl.translate import _, N_, textdomain, utf8
+import utils
import yaml # Howell-Clark version
-from cexceptions import *
+import cexceptions
import os
def register():
@@ -39,7 +39,7 @@ def serialize(obj):
Will create intermediate paths if it can. Returns True on Success,
False on permission errors.
"""
- filename = obj.filename()
+ filename = get_filename(obj.collection_type())
try:
fd = open(filename,"w+")
except IOError, ioe:
@@ -53,7 +53,7 @@ def serialize(obj):
try:
fd = open(filename,"w+")
except IOError, ioe3:
- raise CX(_("Need permissions to write to %s") % filename)
+ raise cexceptions.CX(_("Need permissions to write to %s") % filename)
return False
datastruct = obj.to_datastruct()
encoded = yaml.dump(datastruct)
@@ -61,6 +61,24 @@ def serialize(obj):
fd.close()
return True
+def get_filename(collection_type):
+ # FIXME: use this everywhere
+ ending = collection_type
+ if not ending.endswith("s"):
+ ending = ending + "s"
+ return "/var/lib/cobbler/%s" % ending
+
+def deserialize_raw(collection_type):
+ filename = get_filename(collection_type)
+ try:
+ fd = open(filename,"r")
+ except IOError, ioe:
+ return [{}]
+ data = fd.read()
+ datastruct = yaml.load(data).next() # first record
+ fd.close()
+ return datastruct
+
def deserialize(obj,topological=False):
"""
Populate an existing object with the contents of datastruct.
@@ -68,7 +86,7 @@ def deserialize(obj,topological=False):
files could be read and contained decent YAML. Otherwise returns
False.
"""
- filename = obj.filename()
+ filename = get_filename(obj.collection_type())
try:
fd = open(filename,"r")
except IOError, ioe:
@@ -77,7 +95,7 @@ def deserialize(obj,topological=False):
if not os.path.exists(filename):
return True
else:
- raise CX(_("Need permissions to read %s") % obj.filename())
+ raise cexceptions.CX(_("Need permissions to read %s") % obj.filename())
data = fd.read()
datastruct = yaml.load(data).next() # first record
fd.close()
diff --git a/cobbler/remote.py b/cobbler/remote.py
index 8fb2209..0cdc426 100644
--- a/cobbler/remote.py
+++ b/cobbler/remote.py
@@ -69,14 +69,23 @@ class CobblerXMLRPCInterface:
def ping(self):
return True
+ def __get_all(self,collection_name,page=-1,results_per_page=50):
+ """
+ Helper method to return all data to the WebUI or another caller
+ without going through the process of loading all the data into
+ objects and recalculating. This does require that the cobbler
+ data in the files is up-to-date in terms of serialized formats.
+ """
+ # FIXME: this method, and those that use it, need to allow page, and per_page
+ data = self.api.deserialize_raw(collection_name)
+ data.sort(self.__sorter)
+ return self._fix_none(data)
+
def get_settings(self,token=None):
"""
Return the contents of /var/lib/cobbler/settings, which is a hash.
"""
- self.api.clear()
- self.api.deserialize()
- data = self.api.settings().to_datastruct()
- return self._fix_none(data)
+ return self.__get_all("settings")
def disable_netboot(self,name,token=None):
"""
@@ -108,14 +117,6 @@ class CobblerXMLRPCInterface:
self.api.clear()
self.api.deserialize()
- def __get_all(self,collection_fn):
- """
- Internal function to return an array of hashes from a particular collection object.
- """
- self._refresh()
- data = collection_fn().to_datastruct()
- data.sort(self.__sorter)
- return self._fix_none(data)
def version(self,token=None):
"""
@@ -128,25 +129,25 @@ class CobblerXMLRPCInterface:
"""
Returns all cobbler distros as an array of hashes.
"""
- return self.__get_all(self.api.distros)
+ return self.__get_all("distro")
def get_profiles(self,token=None):
"""
Returns all cobbler profiles as an array of hashes.
"""
- return self.__get_all(self.api.profiles)
+ return self.__get_all("profile")
def get_systems(self,token=None):
"""
Returns all cobbler systems as an array of hashes.
"""
- return self.__get_all(self.api.systems)
+ return self.__get_all("system")
def get_repos(self,token=None):
"""
Returns all cobbler repos as an array of hashes.
"""
- return self.__get_all(self.api.repos)
+ return self.__get_all("repo")
def __get_specific(self,collection_fn,name,flatten=False):
"""
@@ -640,7 +641,6 @@ class CobblerReadWriteXMLRPCInterface(CobblerXMLRPCInterface):
"""
self.__validate_token(token)
rc = self.api._config.distros().remove(name)
- self.api.serialize()
return rc
def profile_remove(self,name,token):
@@ -650,7 +650,6 @@ class CobblerReadWriteXMLRPCInterface(CobblerXMLRPCInterface):
"""
self.__validate_token(token)
rc = self.api._config.profiles().remove(name)
- self.api.serialize()
return rc
def system_remove(self,name,token):
@@ -660,7 +659,6 @@ class CobblerReadWriteXMLRPCInterface(CobblerXMLRPCInterface):
"""
self.__validate_token(token)
rc = self.api._config.systems().remove(name)
- self.api.serialize()
return rc
def repo_remove(self,name,token):
@@ -670,7 +668,6 @@ class CobblerReadWriteXMLRPCInterface(CobblerXMLRPCInterface):
"""
self.__validate_token(token)
rc = self.api._config.repos().remove(name)
- self.api.serialize()
return rc
def sync(self,token):
@@ -785,13 +782,11 @@ if __name__ == "__main__":
my_uri = "http://127.0.0.1/cobbler_api_rw"
remote = xmlrpclib.Server(my_uri)
- testuser = "testuser"
- testpass = "llamas2007"
+ testuser = "admin"
+ testpass = "mooses9"
token = remote.login(testuser,testpass)
print token
- rc = remote.test(token)
- print "test result: %s" % rc
# just to make things "work"
os.system("touch /tmp/vmlinuz")
@@ -823,18 +818,8 @@ if __name__ == "__main__":
system_id = remote.new_system(token)
remote.modify_system(system_id, 'name', 'example-system', token)
remote.modify_system(system_id, 'profile', 'example-profile', token)
- remote.modify_system(system_id, 'mac', 'FF:EE:DD:CC:BB:AA', token)
- remote.modify_system(system_id, 'ip', '192.168.1.25', token)
- remote.save_system(system_id, token)
-
- # now load a system (coincidence, the same one) and edit something about it
- system_id = remote.get_system_handle('example-system',token)
- remote.modify_system(system_id, 'ip', '192.168.1.26', token)
remote.save_system(system_id, token)
- # now use some of the read-only functions to show the config
- # note that these do not require a token (though they won't complain if you
- # give one)
print remote.get_distros()
print remote.get_profiles()
print remote.get_systems()
diff --git a/cobbler/serializer.py b/cobbler/serializer.py
index 2aa5d87..f7904c1 100644
--- a/cobbler/serializer.py
+++ b/cobbler/serializer.py
@@ -42,7 +42,7 @@ def serialize_item(collection, item):
storage_module = __get_storage_module(collection.collection_type())
save_fn = getattr(storage_module, "serialize_item", None)
if save_fn is None:
- # print "DEBUG: full serializer"
+ # print "DEBUG: WARNING: full serializer"
return storage_module.serialize(collection)
else:
# print "DEBUG: partial serializer"
@@ -66,6 +66,10 @@ def deserialize(obj,topological=False):
storage_module = __get_storage_module(obj.collection_type())
return storage_module.deserialize(obj,topological)
+def deserialize_raw(collection_type):
+ storage_module = __get_storage_module(collection_type)
+ return storage_module.deserialize_raw(collection_type)
+
def __get_storage_module(collection_type):
diff --git a/cobbler/settings.py b/cobbler/settings.py
index 53d85b3..6573b40 100644
--- a/cobbler/settings.py
+++ b/cobbler/settings.py
@@ -59,15 +59,6 @@ DEFAULTS = {
class Settings(serializable.Serializable):
- def filename(self):
- """
- The filename where settings are serialized.
- """
- if TESTMODE:
- return "/var/lib/cobbler/test/settings"
- else:
- return "/var/lib/cobbler/settings"
-
def collection_type(self):
return "settings"
diff --git a/config/rsync.exclude b/config/rsync.exclude
index 15c6993..7a96037 100644
--- a/config/rsync.exclude
+++ b/config/rsync.exclude
@@ -4,6 +4,10 @@
### re-enable debug RPM's.
**/debug/**
**/ppc/**
+**/alpha/**
+**/ia64/**
+**/s390/**
+**/s390x/**
**/source/**
**/SRPMS/**
**/*.iso
diff --git a/tests/tests.py b/tests/tests.py
index d92905a..4fe7a5d 100644
--- a/tests/tests.py
+++ b/tests/tests.py
@@ -19,20 +19,18 @@ import subprocess
import tempfile
import shutil
+from cobbler.cexceptions import *
+
from cobbler import settings
from cobbler import collection_distros
from cobbler import collection_profiles
from cobbler import collection_systems
-settings.TESTMODE = True
-collection_distros.TESTMODE = True
-collection_profiles.TESTMODE = True
-collection_systems.TESTMODE = True
-
from cobbler import api
+
from cobbler import config
from cobbler import utils
-from cobbler.cexceptions import CobblerException
+utils.TEST_MODE = True
FAKE_INITRD="initrd-2.6.15-1.2054_FAKE.img"
FAKE_INITRD2="initrd-2.5.16-2.2055_FAKE.img"