diff options
-rw-r--r-- | Makefile | 1 | ||||
-rw-r--r-- | cobbler.conf | 11 | ||||
-rw-r--r-- | cobbler/api.py | 12 | ||||
-rwxr-xr-x | cobbler/cobbler.py | 37 | ||||
-rw-r--r-- | cobbler/config.py | 25 | ||||
-rw-r--r-- | cobbler/msg.py | 6 | ||||
-rw-r--r-- | cobbler/sync.py | 1 | ||||
-rw-r--r-- | setup.py | 2 | ||||
-rw-r--r-- | tests/tests.py | 14 |
9 files changed, 60 insertions, 49 deletions
@@ -7,6 +7,7 @@ manpage: test: python tests/tests.py + \rm -rf /tmp/_cobbler-* install: clean manpage python setup.py sdist diff --git a/cobbler.conf b/cobbler.conf new file mode 100644 index 0000000..f41ed35 --- /dev/null +++ b/cobbler.conf @@ -0,0 +1,11 @@ +--- +config: + httpd_bin: /usr/sbin/httpd + pxelinux: /usr/lib/syslinux/pxelinux.0 + dhcpd_conf: /etc/dhcpd.conf + tftpd_bin: /usr/sbin/in.tftpd + server: localhost + dhcpd_bin: /usr/sbin/dhcpd + kernel_options: append devfs=nomount ramdisk_size=16438 lang= vga=788 ksdevice=eth0 + tftpd_conf: /etc/xinetd.d/tftp + tftpboot: /tftpboot diff --git a/cobbler/api.py b/cobbler/api.py index 77dd835..e48fe7a 100644 --- a/cobbler/api.py +++ b/cobbler/api.py @@ -29,13 +29,19 @@ class BootAPI: try: if self.config.files_exist(): self.config.deserialize() - except: - # traceback.print_exc() - print m("no_cfg") + except Exception, e: + # parse errors, attempt to recover + print self.last_error + if self.last_error == m("parse_error"): + # the error came from /etc/cobbler.conf, and must be fixed + # manually, CLI can't do it for policy reasons on /etc + raise Exception, "parse_error" try: self.config.serialize() except: + # shouldn't get here. File permissions issue, perhaps? traceback.print_exc() + raise Exception, "parse_error2" if not self.config.files_exist(): self.config.serialize() diff --git a/cobbler/cobbler.py b/cobbler/cobbler.py index 0b26307..fb58ff7 100755 --- a/cobbler/cobbler.py +++ b/cobbler/cobbler.py @@ -10,6 +10,7 @@ import os import sys import api import syck +import traceback from msg import * class BootCLI: @@ -59,13 +60,13 @@ class BootCLI: def run(self): """ - Run the command line + Run the command line and return system exit code """ rc = self.curry_args(self.args[1:], self.commands['toplevel']) if not rc: print self.api.last_error - return rc - + return 1 + return 0 def usage(self,args): """ @@ -294,19 +295,21 @@ def main(): # verify syck isn't busted (old syck bindings were) if not hasattr(syck,"dump"): - raise Exception("needs a more-recent PySyck") + raise Exception("needs a more-recent PySyck") if os.getuid() != 0: - # while it's true that we don't technically need root, we do need - # permissions on a relatively long list of files that ordinarily - # only root has access to, and we don't know specifically what - # files are where (other distributions in play, etc). It's - # fairly safe to assume root is required. This might be patched - # later. - print m("need_root") - sys.exit(1) - if BootCLI(sys.argv).run(): - sys.exit(0) - else: - sys.exit(1) - + # while it's true that we don't technically need root, we do need + # permissions on a relatively long list of files that ordinarily + # only root has access to, and we don't know specifically what + # files are where (other distributions in play, etc). It's + # fairly safe to assume root is required. This might be patched + # later. + print m("need_root") + sys.exit(1) + try: + cli = BootCLI(sys.argv) + except Exception, e: + if not str(e) or not str(e).startswith("parse_error"): + traceback.print_exc() + sys.exit(3) + sys.exit(cli.run()) diff --git a/cobbler/config.py b/cobbler/config.py index aa17763..197da91 100644 --- a/cobbler/config.py +++ b/cobbler/config.py @@ -15,7 +15,6 @@ global_settings_file = "/etc/cobbler.conf" global_state_file = "/var/lib/cobbler/cobbler.conf" - class BootConfig: def __init__(self,api): @@ -153,17 +152,9 @@ class BootConfig: state = None # ------ - # dump global config (pathing, urls, etc)... - try: - settings = open(self.settings_file,"w+") - except IOError: - self.api.last_error = m("cant_create: %s" % self.settings_file) - return False - data = self.to_hash(True) - settings.write(syck.dump(data)) + # dump internal state (distros, profiles, systems...) into /var/lib/... + # /etc is not serialized, it's packaged. - # ------ - # dump internal state (distros, profiles, systems...) if not os.path.isdir(os.path.dirname(self.state_file)): dirname = os.path.dirname(self.state_file) if dirname != "": @@ -194,11 +185,10 @@ class BootConfig: self.from_hash(settings,True) else: self.last_error = m("parse_error") - return False + raise Exception("parse_error") except: - traceback.print_exc() self.api.last_error = m("parse_error") - return False + raise Exception("parse_error") # ----- # load internal state(distros, systems, profiles...) @@ -207,12 +197,11 @@ class BootConfig: if state is not None: self.from_hash(state,False) else: - self.last_error = m("parse_error") - return False + self.last_error = m("parse_error2") + raise Exception("parse_error2") except: - traceback.print_exc() self.api.last_error = m("parse_error2") - return False + raise Exception("parse_error2") # all good return True diff --git a/cobbler/msg.py b/cobbler/msg.py index f50443c..1eeb8e6 100644 --- a/cobbler/msg.py +++ b/cobbler/msg.py @@ -8,8 +8,8 @@ be reused and potentially translated. msg_table = { "bad_server" : "server field in /etc/cobbler.conf must be set to something other than localhost, or kickstarts will fail", - "parse_error" : "could not parse /etc/cobbler.conf", - "parse_error2" : "could not parse /var/cobbler/cobbler.conf", + "parse_error" : "could not parse /etc/cobbler.conf, must fix manually", + "parse_error2" : "could not parse /var/lib/cobbler/cobbler.conf, replacing...", "no_create" : "cannot create: %s", "no_args" : "this command requires arguments.", "missing_options" : "cannot add, all parameters have not been set", @@ -29,7 +29,7 @@ msg_table = { "no_exist" : "%s does not exist", "no_line" : "file '%s' should have a line '%s' somewhere", "no_dir2" : "can't find %s for %s in cobbler.conf", - "no_cfg" : "could not find cobbler.conf, recreating", + "no_cfg" : "could not find a valid /etc/cobbler.conf, rebuilding", "bad_param" : "at least one parameter is missing for this function", "empty_list" : "(Empty)", "err_resolv" : "system (%s) did not resolve", diff --git a/cobbler/sync.py b/cobbler/sync.py index 80b0c67..3494382 100644 --- a/cobbler/sync.py +++ b/cobbler/sync.py @@ -101,6 +101,7 @@ class BootSync: initrd = self.api.utils.find_initrd(d.initrd) # full path if kernel is None or not os.path.isfile(kernel): self.api.last_error = "Kernel for distro (%s) cannot be found and needs to be fixed: %s" % (d.name, d.kernel) + print self.api.last_error raise "error" if initrd is None or not os.path.isfile(initrd): self.api.last_error = "Initrd for distro (%s) cannot be found and needs to be fixed: %s" % (d.name, d.initrd) @@ -14,6 +14,7 @@ Cobbler is a command line tool for simplified configuration of boot/provisioning if __name__ == "__main__": # docspath="share/doc/koan-%s/" % VERSION manpath="share/man/man1/" + etcpath="etc/" setup( name="cobbler", version = VERSION, @@ -27,6 +28,7 @@ if __name__ == "__main__": data_files = [ # (docspath, ['README']), (manpath, ['cobbler.1.gz']) + (etcpath, ['cobbler.conf']) ], description = SHORT_DESC, long_description = LONG_DESC diff --git a/tests/tests.py b/tests/tests.py index 2673cdd..cfe1081 100644 --- a/tests/tests.py +++ b/tests/tests.py @@ -24,11 +24,14 @@ FAKE_KERNEL2="vmlinuz-2.5.16-2.2055_FAKE" FAKE_KERNEL3="vmlinuz-1.8.18-3.9999_FAKE" FAKE_KICKSTART="http://127.0.0.1/fake.ks" +cleanup_dirs = [] + class BootTest(unittest.TestCase): def setUp(self): # Create temp dir - self.topdir = tempfile.mkdtemp(prefix="_cobbler-") + self.topdir = tempfile.mkdtemp(prefix="_cobbler-",dir="/tmp") + print "using dir = %s" % self.topdir self.fk_initrd = os.path.join(self.topdir, FAKE_INITRD) self.fk_initrd2 = os.path.join(self.topdir, FAKE_INITRD2) self.fk_initrd3 = os.path.join(self.topdir, FAKE_INITRD3) @@ -37,11 +40,6 @@ class BootTest(unittest.TestCase): self.fk_kernel2 = os.path.join(self.topdir, FAKE_KERNEL2) self.fk_kernel3 = os.path.join(self.topdir, FAKE_KERNEL3) - try: - # it will interfere with results... - os.remove("/etc/cobbler.conf") - except: - pass self.api = api.BootAPI() self.hostname = os.uname()[1] create = [ self.fk_initrd, self.fk_initrd2, self.fk_initrd3, @@ -51,7 +49,8 @@ class BootTest(unittest.TestCase): self.make_basic_config() def tearDown(self): - shutil.rmtree(self.topdir, ignore_errors=1) + # this is causing problems with the sync() test + # shutil.rmtree(self.topdir,ignore_errors=True) self.api = None def make_basic_config(self): @@ -297,4 +296,3 @@ if __name__ == "__main__": print "tests: must invoke from top level directory" sys.exit(1) unittest.main() - |