summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Makefile6
-rw-r--r--cobbler/action_check.py29
-rw-r--r--cobbler/action_sync.py46
-rw-r--r--cobbler/api.py6
-rwxr-xr-xcobbler/cobbler.py52
-rw-r--r--cobbler/cobbler_exception.py20
-rw-r--r--cobbler/cobbler_msg.py (renamed from cobbler/msg.py)13
-rw-r--r--cobbler/collection.py8
-rw-r--r--cobbler/collection_distros.py6
-rw-r--r--cobbler/collection_profiles.py7
-rw-r--r--cobbler/collection_systems.py4
-rw-r--r--cobbler/item_distro.py7
-rw-r--r--cobbler/item_profile.py8
-rw-r--r--cobbler/item_system.py7
-rw-r--r--cobbler/serializer.py78
-rw-r--r--cobbler/utils.py16
16 files changed, 172 insertions, 141 deletions
diff --git a/Makefile b/Makefile
index ef8922d..2a2560a 100644
--- a/Makefile
+++ b/Makefile
@@ -1,13 +1,13 @@
clean:
- \rm -f cobbler*.gz cobbler*.rpm MANIFEST
- \rm -rf cobbler-* dist build
+ -rm -f cobbler*.gz cobbler*.rpm MANIFEST
+ -rm -rf cobbler-* dist build
manpage:
pod2man --center="cobbler" --release="" cobbler.pod | gzip -c > cobbler.1.gz
test:
python tests/tests.py
- \rm -rf /tmp/_cobbler-*
+ -rm -rf /tmp/_cobbler-*
install: clean manpage
python setup.py sdist
diff --git a/cobbler/action_check.py b/cobbler/action_check.py
index 05718b3..fdcc5d5 100644
--- a/cobbler/action_check.py
+++ b/cobbler/action_check.py
@@ -7,8 +7,7 @@ Michael DeHaan <mdehaan@redhat.com>
import os
import re
-
-from msg import *
+import cobbler_msg
class BootCheck:
@@ -43,14 +42,14 @@ class BootCheck:
parameters.
"""
if self.settings.server == "localhost":
- status.append(m("bad_server"))
+ status.append(cobbler_msg.lookup("bad_server"))
def check_httpd(self,status):
"""
Check if Apache is installed.
"""
if not os.path.exists(self.settings.httpd_bin):
- status.append(m("no_httpd"))
+ status.append(cobbler_msg.lookup("no_httpd"))
def check_dhcpd_bin(self,status):
@@ -58,28 +57,28 @@ class BootCheck:
Check if dhcpd is installed
"""
if not os.path.exists(self.settings.dhcpd_bin):
- status.append(m("no_dhcpd"))
+ status.append(cobbler_msg.lookup("no_dhcpd"))
def check_pxelinux_bin(self,status):
"""
Check if pxelinux (part of syslinux) is installed
"""
if not os.path.exists(self.settings.pxelinux):
- status.append(m("no_pxelinux"))
+ status.append(cobbler_msg.lookup("no_pxelinux"))
def check_tftpd_bin(self,status):
"""
Check if tftpd is installed
"""
if not os.path.exists(self.settings.tftpd_bin):
- status.append(m("no_tftpd"))
+ status.append(cobbler_msg.lookup("no_tftpd"))
def check_tftpd_dir(self,status):
"""
Check if cobbler.conf's tftpboot directory exists
"""
if not os.path.exists(self.settings.tftpboot):
- status.append(m("no_dir") % self.settings.tftpboot)
+ status.append(cobbler_msg.lookup("no_dir") % self.settings.tftpboot)
def check_tftpd_conf(self,status):
@@ -94,15 +93,15 @@ class BootCheck:
found_bootdir = False
for line in f.readlines():
if re_1.search(line):
- status.append(m("chg_attrib") % ('default','on',self.settings.tftpd_conf))
+ status.append(cobbler_msg.lookup("chg_attrib") % ('default','on',self.settings.tftpd_conf))
if re_2.search(line):
- status.append(m("chg_attrib") % ('disable','no',self.settings.tftpd_conf))
+ status.append(cobbler_msg.lookup("chg_attrib") % ('disable','no',self.settings.tftpd_conf))
if line.find("-s %s" % self.settings.tftpboot) != -1:
found_bootdir = True
if not found_bootdir:
- status.append(m("chg_attrib") % ('server_args',"-s %s" % self.settings.tftpboot, self.settings.tftpd_conf))
+ status.append(cobbler_msg.lookup("chg_attrib") % ('server_args',"-s %s" % self.settings.tftpboot, self.settings.tftpd_conf))
else:
- status.append(m("no_exist") % self.settings.tftpd_conf)
+ status.append(cobbler_msg.lookup("no_exist") % self.settings.tftpd_conf)
def check_dhcpd_conf(self,status):
@@ -122,10 +121,10 @@ class BootCheck:
if line.find("filename") != -1:
match_file = True
if not match_next:
- status.append(m("no_line") % (self.settings.dhcpd_conf, 'next-server ip-address'))
+ status.append(cobbler_msg.lookup("no_line") % (self.settings.dhcpd_conf, 'next-server ip-address'))
if not match_file:
- status.append(m("no_line") % (self.settings.dhcpd_conf, 'filename "%s/pxelinux.0";' % self.settings.tftpboot))
+ status.append(cobbler_msg.lookup("no_line") % (self.settings.dhcpd_conf, 'filename "%s/pxelinux.0";' % self.settings.tftpboot))
else:
- status.append(m("no_exist") % self.settings.dhcpd_conf)
+ status.append(cobbler_msg.lookup("no_exist") % self.settings.dhcpd_conf)
diff --git a/cobbler/action_sync.py b/cobbler/action_sync.py
index fede994..6fc3c6b 100644
--- a/cobbler/action_sync.py
+++ b/cobbler/action_sync.py
@@ -11,7 +11,8 @@ import shutil
import syck
import utils
-from msg import *
+import cobbler_msg
+from cobbler_exception import CobblerException
"""
Handles conversion of internal state to the tftpboot tree layout
@@ -63,7 +64,7 @@ class BootSync:
cobbler infrastructure available over TFTP over HTTP also.
"""
if not os.path.exists("/etc/httpd/conf.d"):
- self.sync_log(m("no_httpd"))
+ self.sync_log(cobbler_msg.lookup("no_httpd"))
return
f = self.open_file("/etc/httpd/conf.d/cobbler.conf","w+")
config_data = """
@@ -107,12 +108,9 @@ class BootSync:
kernel = utils.find_kernel(d.kernel) # full path
initrd = utils.find_initrd(d.initrd) # full path
if kernel is None or not os.path.isfile(kernel):
- utils.set_error("Kernel for distro (%s) cannot be found and needs to be fixed: %s" % (d.name, d.kernel))
- print utils.last_error()
- raise Exception, "error"
+ raise CobblerException("sync_kernel", (d.name, d.kernel))
if initrd is None or not os.path.isfile(initrd):
- utils.set_error("Initrd for distro (%s) cannot be found and needs to be fixed: %s" % (d.name, d.initrd))
- raise Exception, "error"
+ raise CobblerException("sync_initrd", (d.name, d.initrd))
b_kernel = os.path.basename(kernel)
b_initrd = os.path.basename(initrd)
self.copyfile(kernel, os.path.join(distro_dir, b_kernel))
@@ -131,7 +129,7 @@ class BootSync:
# it's up to the user to make sure they are nicely served by their URLs
for g in self.profiles:
- self.sync_log("mirroring any local kickstarts: %s" % g.name)
+ self.sync_log(cobbler_msg.lookup("sync_mirror_ks"))
kickstart_path = utils.find_kickstart(g.kickstart)
if kickstart_path and os.path.exists(kickstart_path):
# the input is an *actual* file, hence we have to copy it
@@ -141,8 +139,7 @@ class BootSync:
try:
self.copyfile(g.kickstart, dest)
except:
- utils.set_error("err_kickstart2")
- raise Exception, "error"
+ raise CobblerException("err_kickstart2")
def build_trees(self):
"""
@@ -151,12 +148,12 @@ class BootSync:
configured IP or MAC address. Also build a parallel 'xeninfo' tree
for xen-net-install info.
"""
- self.sync_log("building trees...")
+ self.sync_log(cobbler_msg.lookup("sync_buildtree"))
# create pxelinux.cfg under tftpboot
# and file for each MAC or IP (hex encoded 01-XX-XX-XX-XX-XX-XX)
for d in self.distros:
- self.sync_log("processing distro: %s" % d.name)
+ self.sync_log(cobbler_msg.lookup("sync_processing") % d.name)
# TODO: add check to ensure all distros have profiles (=warning)
filename = os.path.join(self.settings.tftpboot,"distros",d.name)
d.kernel_options = self.blend_kernel_options((
@@ -166,7 +163,7 @@ class BootSync:
self.write_distro_file(filename,d)
for p in self.profiles:
- self.sync_log("processing profile: %s" % p.name)
+ self.sync_log(cobbler_msg.lookup("sync_processing") % p.name)
# TODO: add check to ensure all profiles have distros (=error)
# TODO: add check to ensure all profiles have systems (=warning)
filename = os.path.join(self.settings.tftpboot,"profiles",p.name)
@@ -180,15 +177,13 @@ class BootSync:
self.write_profile_file(filename,p)
for system in self.systems:
- self.sync_log("processing system: %s" % system.name)
+ self.sync_log(cobbler_msg.lookup("sync_processing") % system.name)
profile = self.profiles.find(system.profile)
if profile is None:
- utils.set_error("orphan_profile2")
- raise Exception, "error"
+ raise CobblerException("orphan_profile2")
distro = self.distros.find(profile.distro)
if distro is None:
- utils.set_error("orphan_system2")
- raise Exception, "error"
+ raise CobblerException("orphan_system2")
f1 = self.get_pxelinux_filename(system.name)
f2 = os.path.join(self.settings.tftpboot, "pxelinux.cfg", f1)
f3 = os.path.join(self.settings.tftpboot, "systems", f1)
@@ -210,8 +205,7 @@ class BootSync:
elif utils.is_mac(name):
return "01-" + "-".join(name.split(":")).lower()
else:
- utils.set_error(m("err_resolv" % name))
- raise Exception, "error"
+ raise CobblerException("err_resolv", name)
def write_pxelinux_file(self,filename,system,profile,distro):
@@ -223,7 +217,7 @@ class BootSync:
kernel_path = os.path.join("/images",distro.name,os.path.basename(distro.kernel))
initrd_path = os.path.join("/images",distro.name,os.path.basename(distro.initrd))
kickstart_path = profile.kickstart
- self.sync_log("writing: %s" % filename)
+ self.sync_log(cobbler_msg.lookup("writing") % filename)
self.sync_log("---------------------------------")
fd = self.open_file(filename,"w+")
self.tee(fd,"default linux\n")
@@ -309,7 +303,7 @@ class BootSync:
"""
For dry_run support: potentially copy a file.
"""
- self.sync_log("copy %s to %s" % (src,dst))
+ self.sync_log(cobbler_msg.lookup("copying") % (src,dst))
if self.dry_run:
return True
return shutil.copyfile(src,dst)
@@ -318,7 +312,7 @@ class BootSync:
"""
For dry_run support: potentially copy a file.
"""
- self.sync_log("copy %s to %s" % (src,dst))
+ self.sync_log(cobbler_msg.lookup("copying") % (src,dst))
if self.dry_run:
return True
return shutil.copy(src,dst)
@@ -327,7 +321,7 @@ class BootSync:
"""
For dry_run support: potentially delete a tree.
"""
- self.sync_log("removing dir %s" % (path))
+ self.sync_log(cobbler_msg.lookup("removing") % (path))
if self.dry_run:
return True
return shutil.rmtree(path,ignore)
@@ -336,7 +330,7 @@ class BootSync:
"""
For dry_run support: potentially make a directory.
"""
- self.sync_log("creating dir %s" % (path))
+ self.sync_log(cobbler_msg.lookup("mkdir") % (path))
if self.dry_run:
return True
return os.mkdir(path,mode)
@@ -348,7 +342,7 @@ class BootSync:
"""
if self.verbose:
if self.dry_run:
- print "dry_run | %s" % message
+ print cobbler_msg.lookup("dry_run") % message
else:
print message
diff --git a/cobbler/api.py b/cobbler/api.py
index d3ea377..a7dbe8b 100644
--- a/cobbler/api.py
+++ b/cobbler/api.py
@@ -109,9 +109,3 @@ class BootAPI:
"""
return _config.deserialize()
- def last_error(self):
- """
- In the event of failure, what went wrong?
- """
- return utils.last_error()
-
diff --git a/cobbler/cobbler.py b/cobbler/cobbler.py
index a8de380..33f2253 100755
--- a/cobbler/cobbler.py
+++ b/cobbler/cobbler.py
@@ -11,7 +11,9 @@ import sys
import api
import syck
import traceback
-from msg import *
+
+import cobbler_msg
+from cobbler_exception import CobblerException
class BootCLI:
@@ -58,13 +60,27 @@ class BootCLI:
}
+ def deserialize(self):
+ """
+ Load data from file(s)
+ """
+ return self.api.deserialize()
+
+ def serialize(self):
+ """
+ Save data to file(s)
+ """
+ return self.api.serialize()
+
def run(self):
"""
Run the command line and return system exit code
"""
- rc = self.curry_args(self.args[1:], self.commands['toplevel'])
+ rc = self.deserialize()
+ if rc:
+ rc = self.curry_args(self.args[1:], self.commands['toplevel'])
if not rc:
- print self.api.last_error
+ print self.api.last_error()
return 1
return 0
@@ -72,7 +88,7 @@ class BootCLI:
"""
Print out abbreviated help if user gives bad syntax
"""
- print m("usage")
+ print cobbler_msg.lookup("usage")
return False
@@ -187,7 +203,7 @@ class BootCLI:
Parses arguments of the form --foo=bar, see profile_edit for example
"""
if len(args) == 0:
- print m("no_args")
+ print cobbler_msg.lookup("no_args")
return False
for x in args:
try:
@@ -195,25 +211,25 @@ class BootCLI:
key, value = x.split("=",1)
value = value.replace('"','').replace("'",'')
except:
- print m("bad_arg") % x
+ print cobbler_msg.lookup("bad_arg") % x
return False
if key in input_routines:
# --argument is recognized, so run the loader
# attached to it in the dispatch table
if not input_routines[key](value):
# loader does not like passed value
- print m("reject_arg") % key
+ print cobbler_msg.lookup("reject_arg") % key
return False
else:
# --argument is not recognized
- print m("weird_arg") % key
+ print cobbler_msg.lookup("weird_arg") % key
return False
# success thus far, so run the success routine for the set of
# arguments. Configuration will only be written to file if the
# final routine succeeds.
rc = on_ok()
if rc and serialize:
- self.api.serialize()
+ return self.serialize()
return rc
@@ -223,7 +239,7 @@ class BootCLI:
See profiles(), system(), or distro() for examples
"""
if args is None or len(args) == 0:
- print m("help")
+ print cobbler_msg.lookup("help")
return False
if args[0] in commands:
# if the subargument is in the dispatch table, run
@@ -233,7 +249,7 @@ class BootCLI:
if not rc:
return False
else:
- print m("unknown_cmd") % args[0]
+ print cobbler_msg.lookup("unknown_cmd") % args[0]
return False
return True
@@ -258,10 +274,10 @@ class BootCLI:
if status is None:
return False
elif len(status) == 0:
- print m("check_ok")
+ print cobbler_msg.lookup("check_ok")
return True
else:
- print m("need_to_fix")
+ print cobbler_msg.lookup("need_to_fix")
for i,x in enumerate(status):
print "#%d: %s" % (i,x)
return False
@@ -294,16 +310,12 @@ def main():
# verify syck isn't busted (old syck bindings were)
if not hasattr(syck,"dump"):
- raise Exception("needs a more-recent PySyck module")
+ raise CobblerException("needs a more-recent PySyck module")
- if os.getuid() != 0:
- # FIXME: don't require root
- print m("need_root")
- sys.exit(1)
try:
cli = BootCLI(sys.argv)
- except Exception:
- traceback.print_exc()
+ except Exception, exc:
+ print exc
sys.exit(1)
sys.exit(cli.run())
diff --git a/cobbler/cobbler_exception.py b/cobbler/cobbler_exception.py
new file mode 100644
index 0000000..c6abfce
--- /dev/null
+++ b/cobbler/cobbler_exception.py
@@ -0,0 +1,20 @@
+"""
+Custom error for fatal cobbler exceptions that come with human readable error messages.
+These can be caught and printed without stack traces.
+
+Michael DeHaan <mdehaan@redhat.com>
+"""
+
+import exceptions
+import cobbler_msg
+
+class CobblerException(exceptions.Exception):
+
+ def __init__(self, value, args=[]):
+ if type(args) == str or type(args) == int:
+ args = (args)
+ self.value = cobbler_msg.lookup(value) % args
+
+ def __str__(self):
+ return repr(self.value)
+
diff --git a/cobbler/msg.py b/cobbler/cobbler_msg.py
index e617e58..69a5dbd 100644
--- a/cobbler/msg.py
+++ b/cobbler/cobbler_msg.py
@@ -6,7 +6,7 @@ be reused and potentially translated.
Michael DeHaan <mdehaan@redhat.com>
"""
-msg_table = {
+_msg_table = {
"bad_server" : "server field in /var/lib/cobbler/settings must be set to something other than localhost, or kickstarts will fail",
"parse_error" : "could not read %s, replacing...",
"no_create" : "cannot create: %s",
@@ -19,7 +19,7 @@ msg_table = {
"bad_sys_name" : "system name must be a MAC, IP, or resolveable host",
"usage" : "for help, see 'man cobbler'",
"need_to_fix" : "the following potential problems were detected:",
- "need_root" : "cobbler must be run as root",
+ "need_perms" : "cobbler cannot access %s",
"no_dhcpd" : "can't find dhcpd, try 'yum install dhcpd'",
"no_pxelinux" : "can't find pxelinux, try 'yum install pxelinux'",
"no_tftpd" : "can't find tftpd, try 'yum install tftpd'",
@@ -43,6 +43,8 @@ msg_table = {
"no_profile" : "profile does not exist",
"no_kickstart" : "kickstart must be an http://, ftp:// or nfs:// URL",
"no_kernel" : "the kernel needs to be a directory containing a kernel, or a full path. Kernels must be named just 'vmlinuz' or in the form 'vmlinuz-AA.BB.CC-something'",
+ "sync_kernel" : "the kernel (%s) for distro (%s) cannot be found and must be fixed",
+ "sync_initrd" : "the initrd (%s) for distro (%s) cannot be found and must be fixed",
"no_initrd" : "the initrd needs to be a directory containing an initrd, or a full path. Initrds must be named just 'initrd.img' or in the form 'initrd-AA.BB.CC-something.img",
"check_ok" : """
No setup problems found.
@@ -54,13 +56,12 @@ Good luck.
"help" : "see 'man cobbler'"
}
-def m(key):
+def lookup(key):
"""
Return the lookup of a string key.
"""
- if key in msg_table:
- # localization could use different tables or just gettext.
- return msg_table[key]
+ if _msg_table.has_key(key):
+ return _msg_table[key]
else:
return key
diff --git a/cobbler/collection.py b/cobbler/collection.py
index 24a2691..607b344 100644
--- a/cobbler/collection.py
+++ b/cobbler/collection.py
@@ -8,7 +8,7 @@ import exceptions
import serializable
import utils
-import msg
+import cobbler_msg
class Collection(serializable.Serializable):
@@ -70,9 +70,7 @@ class Collection(serializable.Serializable):
won't be added to the collection).
"""
if ref is None or not ref.is_valid():
- if utils.last_error() is None or utils.last_error() == "":
- utils.set_error("bad_param")
- return False
+ raise CobblerException("bad_param")
self.listing[ref.name] = ref
return True
@@ -87,7 +85,7 @@ class Collection(serializable.Serializable):
if len(values) > 0:
return "\n\n".join(values)
else:
- return msg.m("empty_list")
+ return cobbler_msg.lookup("empty_list")
def __iter__(self):
"""
diff --git a/cobbler/collection_distros.py b/cobbler/collection_distros.py
index be024fc..5f49d16 100644
--- a/cobbler/collection_distros.py
+++ b/cobbler/collection_distros.py
@@ -30,11 +30,9 @@ class Distros(collection.Collection):
# first see if any Groups use this distro
for v in self.config.profiles():
if v.distro == name:
- utils.set_error("orphan_files")
- return False
+ raise CobblerException("orphan_files")
if self.find(name):
del self.listing[name]
return True
- utils.set_error("delete_nothing")
- return False
+ raise CobblerException("delete_nothing")
diff --git a/cobbler/collection_profiles.py b/cobbler/collection_profiles.py
index a5b1996..b1c92dd 100644
--- a/cobbler/collection_profiles.py
+++ b/cobbler/collection_profiles.py
@@ -10,6 +10,7 @@ Michael DeHaan <mdehaan@redhat.com>
import item_profile as profile
import utils
import collection
+from cobbler_exception import CobblerException
#--------------------------------------------
@@ -27,11 +28,9 @@ class Profiles(collection.Collection):
"""
for k,v in self.config.systems().listing.items():
if v.profile == name:
- utils.set_error("orphan_system")
- return False
+ raise CobblerException("orphan_system")
if self.find(name):
del self.listing[name]
return True
- utils.set_error("delete_nothing")
- return False
+ raise CobblerException("delete_nothing")
diff --git a/cobbler/collection_systems.py b/cobbler/collection_systems.py
index 5d201bc..3147a67 100644
--- a/cobbler/collection_systems.py
+++ b/cobbler/collection_systems.py
@@ -8,6 +8,7 @@ Michael DeHaan <mdehaan@redhat.com>
import item_system as system
import utils
import collection
+from cobbler_exception import CobblerException
#--------------------------------------------
@@ -32,6 +33,5 @@ class Systems(collection.Collection):
if self.find(name):
del self.listing[name]
return True
- utils.set_error("delete_nothing")
- return False
+ raise CobblerException("delete_nothing")
diff --git a/cobbler/item_distro.py b/cobbler/item_distro.py
index aa2d463..59250af 100644
--- a/cobbler/item_distro.py
+++ b/cobbler/item_distro.py
@@ -10,6 +10,7 @@ import utils
import item
import weakref
import os
+from cobbler_exception import CobblerException
class Distro(item.Item):
@@ -50,8 +51,7 @@ class Distro(item.Item):
if utils.find_kernel(kernel):
self.kernel = kernel
return True
- utils.set_error("no_kernel")
- return False
+ raise CobblerException("no_kernel")
def set_initrd(self,initrd):
"""
@@ -61,8 +61,7 @@ class Distro(item.Item):
if utils.find_initrd(initrd):
self.initrd = initrd
return True
- utils.set_error("no_initrd")
- return False
+ raise CobblerException("no_initrd")
def is_valid(self):
"""
diff --git a/cobbler/item_profile.py b/cobbler/item_profile.py
index 9fd308a..c344fc3 100644
--- a/cobbler/item_profile.py
+++ b/cobbler/item_profile.py
@@ -7,7 +7,7 @@ Michael DeHaan <mdehaan@redhat.com>
import utils
import item
-from msg import *
+from cobbler_exception import CobblerException
class Profile(item.Item):
@@ -57,8 +57,7 @@ class Profile(item.Item):
if self.config.distros().find(distro_name):
self.distro = distro_name
return True
- utils.set_error("no_distro")
- return False
+ raise CobblerException("no_distro")
def set_kickstart(self,kickstart):
"""
@@ -68,8 +67,7 @@ class Profile(item.Item):
if utils.find_kickstart(kickstart):
self.kickstart = kickstart
return True
- utils.set_error("no_kickstart")
- return False
+ raise CobblerException("no_kickstart")
def set_xen_name(self,str):
"""
diff --git a/cobbler/item_system.py b/cobbler/item_system.py
index 0819781..fef3743 100644
--- a/cobbler/item_system.py
+++ b/cobbler/item_system.py
@@ -6,6 +6,7 @@ Michael DeHaan <mdehaan@redhat.com>
import utils
import item
+from cobbler_exception import CobblerException
class System(item.Item):
@@ -32,8 +33,7 @@ class System(item.Item):
"""
new_name = utils.find_system_identifier(name)
if not new_name:
- utils.set_error("bad_sys_name")
- return False
+ raise CobblerException("bad_sys_name")
self.name = name # we check it add time, but store the original value.
return True
@@ -52,8 +52,7 @@ class System(item.Item):
A system is valid when it contains a valid name and a profile.
"""
if self.name is None:
- utils.set_error("bad_sys_name")
- return False
+ raise CobblerException("bad_sys_name")
if self.profile is None:
return False
return True
diff --git a/cobbler/serializer.py b/cobbler/serializer.py
index da4c684..a63cd6e 100644
--- a/cobbler/serializer.py
+++ b/cobbler/serializer.py
@@ -1,28 +1,64 @@
# Michael DeHaan <mdehaan@redhat.com>
import syck # PySyck 0.61 or greater, not syck-python 0.55
-import msg
+import errno
+import os
+
+import utils
def serialize(obj):
- if obj.filename() is None:
- raise Exception("not serializable")
- fd = open(obj.filename(),"w+")
- datastruct = obj.to_datastruct()
- encoded = syck.dump(datastruct)
- fd.write(encoded)
- fd.close()
- return True
+ """
+ Save an object to disk. Object must "implement" Serializable.
+ Will create intermediate paths if it can. Returns True on Success,
+ False on permission errors.
+ """
+ filename = obj.filename()
+ try:
+ fd = open(filename,"w+")
+ except IOError, ioe:
+ basename = os.path.basename(filename)
+ if not os.path.exists(basename):
+ try:
+ os.makedirs(basename)
+ except:
+ raise CobblerException("need_perms", basename)
+ return False
+ try:
+ fd = open(filename,"w+")
+ except:
+ raise CobblerException("need_perms", filename)
+ return False
+ datastruct = obj.to_datastruct()
+ encoded = syck.dump(datastruct)
+ fd.write(encoded)
+ fd.close()
+ return True
def deserialize(obj):
- if obj.filename() is None:
- raise Exception("not serializable")
- try:
- fd = open(obj.filename(),"r")
- except:
- print msg.m("parse_error") % obj.filename()
- return
- data = fd.read()
- datastruct = syck.load(data)
- fd.close()
- obj.from_datastruct(datastruct)
- return True
+ """
+ Populate an existing object with the contents of datastruct.
+ Object must "implement" Serializable. Returns True assuming
+ files could be read and contained decent YAML. Otherwise returns
+ False.
+ """
+ filename = obj.filename()
+ try:
+ fd = open(filename,"r")
+ except IOError, ioe:
+ # if it doesn't exist, that's cool -- it's not a bug until we try
+ # to write the file and can't create it.
+ if not os.path.exists(filename):
+ return True
+ else:
+ raise CobblerException("need_perms",obj.filename())
+ data = fd.read()
+ datastruct = syck.load(data)
+ if type(datastruct) == str:
+ # PySyck returns strings when it chokes on data
+ # it doesn't really throw exceptions
+ raise CobblerException("parse_error",filename)
+ fd.close()
+ obj.from_datastruct(datastruct)
+ return True
+
+
diff --git a/cobbler/utils.py b/cobbler/utils.py
index c6cc019..3c82044 100644
--- a/cobbler/utils.py
+++ b/cobbler/utils.py
@@ -10,24 +10,8 @@ import socket
import glob
import subprocess
-import msg
-
_re_kernel = re.compile(r'vmlinuz-(\d+)\.(\d+)\.(\d+)-(.*)')
_re_initrd = re.compile(r'initrd-(\d+)\.(\d+)\.(\d+)-(.*).img')
-_utils_last_error = ""
-
-def last_error():
- """
- Return the last error message set with set_error
- """
- return _utils_last_error
-
-def set_error(strmsg):
- """
- Set the error message for the last failed operation
- """
- global _utils_last_error
- _utils_last_error = msg.m(strmsg)
def get_host_ip(ip):
"""