# HG changeset patch # User osimons # Date 1252565660 0 # Node ID 251be647314c94d5b9926a9753097f10f499e977 # Parent 80d4c32c810344037600d96384fda228d44729c7 0.6dev: Adding some error-handling to bitten-slave for config files. It now reports errors and exists gracefully if a) config file isn't found, or b) problem parsing content (wrong format). Closes #443. diff --git a/bitten/build/config.py b/bitten/build/config.py --- a/bitten/build/config.py +++ b/bitten/build/config.py @@ -21,6 +21,8 @@ __docformat__ = 'restructuredtext en' +class ConfigFileNotFound(Exception): + pass class Configuration(object): """Encapsulates the configuration of a build machine. @@ -43,6 +45,9 @@ self.packages = {} parser = SafeConfigParser() if filename: + if not (os.path.isfile(filename) or os.path.islink(filename)): + raise ConfigFileNotFound( + "Configuration file %r not found." % filename) parser.read(filename) self._merge_sysinfo(parser, properties) self._merge_packages(parser, properties) diff --git a/bitten/build/tests/config.py b/bitten/build/tests/config.py --- a/bitten/build/tests/config.py +++ b/bitten/build/tests/config.py @@ -13,7 +13,7 @@ import tempfile import unittest -from bitten.build.config import Configuration +from bitten.build.config import Configuration, ConfigFileNotFound class ConfigurationTestCase(unittest.TestCase): @@ -125,6 +125,14 @@ finally: os.remove(ininame) + def test_package_configfile_non_existant(self): + try: + conf = Configuration(filename='doesnotexist.ini') + self.fail('Expected ConfigFileNotFound') + except ConfigFileNotFound, e: + self.assertEquals(str(e), + "Configuration file 'doesnotexist.ini' not found.") + def test_get_dirpath_non_existant(self): tempdir = tempfile.mkdtemp() os.rmdir(tempdir) diff --git a/bitten/slave.py b/bitten/slave.py --- a/bitten/slave.py +++ b/bitten/slave.py @@ -24,15 +24,17 @@ import time import re import cookielib +from ConfigParser import MissingSectionHeaderError from bitten import PROTOCOL_VERSION from bitten.build import BuildError -from bitten.build.config import Configuration +from bitten.build.config import Configuration, ConfigFileNotFound from bitten.recipe import Recipe from bitten.util import xmlio EX_OK = getattr(os, "EX_OK", 0) EX_UNAVAILABLE = getattr(os, "EX_UNAVAILABLE", 69) +EX_IOERR = getattr(os, "EX_IOERR", 74) EX_PROTOCOL = getattr(os, "EX_PROTOCOL", 76) EX_NOPERM = getattr(os, "EX_NOPERM", 77) @@ -462,7 +464,9 @@ log.info("Slave launched at %s" % \ datetime.now().strftime('%Y-%m-%d %H:%M:%S')) - slave = BuildSlave(urls, name=options.name, config=options.config, + slave = None + try: + slave = BuildSlave(urls, name=options.name, config=options.config, dry_run=options.dry_run, work_dir=options.work_dir, build_dir=options.build_dir, keep_files=options.keep_files, @@ -472,15 +476,21 @@ username=options.username, password=options.password, dump_reports=options.dump_reports, form_auth=options.form_auth) - try: try: exit_code = slave.run() except KeyboardInterrupt: slave.quit() + except ConfigFileNotFound, e: + log.error(e) + exit_code = EX_IOERR + except MissingSectionHeaderError: + log.error("Error parsing configuration file %r. Wrong format?" \ + % options.config) + exit_code = EX_IOERR except ExitSlave, e: exit_code = e.exit_code - if not (options.work_dir or options.keep_files): + if slave and not (options.work_dir or options.keep_files): log.debug('Removing working directory %s' % slave.work_dir) _rmtree(slave.work_dir)