From 085db1cba3899c90562811fcb7267c2c4984c45f Mon Sep 17 00:00:00 2001 From: Markus Lehtonen Date: Mon, 2 Jun 2014 18:42:32 +0300 Subject: [PATCH] Implement 'error-pkg' parameter Instead of causing a service error generate a special "error package" that shows the service error log but fails to build. The parameter value is a comma-separated list of integers, representing the exit codes for which the special error package is created. This is a special hack to prevent the +creation of broken packages in case of service failures. Change-Id: I20b1e810b498a120245fe94276c180b458ab0b9a Signed-off-by: Markus Lehtonen --- obs_service_gbs/command.py | 79 ++++++++++++++++++++++++++++++++++++------- service/gbs.service | 3 ++ tests/test_obs_service_gbs.py | 13 +++++++ 3 files changed, 82 insertions(+), 13 deletions(-) diff --git a/obs_service_gbs/command.py b/obs_service_gbs/command.py index a8f75d7..1372c65 100644 --- a/obs_service_gbs/command.py +++ b/obs_service_gbs/command.py @@ -41,6 +41,37 @@ EXIT_ERR_SERVICE = 1 EXIT_ERR_GBS_EXPORT = 2 EXIT_ERR_GBS_CRASH = 3 +# Template spec file for the "error package" +ERROR_PKG_SPEC = """ +Name: service-error +Version: 1 +Release: 0 +License: GPL-2.0+ +Summary: Package indicating an export error in gbs source service +Source0: service-error + +%description +This is a dummy package created by obs-service-gbs that indicates that +exporting the packaging files failed. This is a special hack to prevent the +creation of broken packages in case of service failures. This behaviour was +implicitly enabled with the 'error-pkg' parameter of the service. + +%build +cat << EOF +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! +!!! +!!! +!!! OBS-SERVICE-GBS FAILED +!!! +!!! +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! +--- SERVICE ERROR LOG -------------------------------------------------------- +`sed s'/^/ /' %{SOURCE0}` +--- END OF SERVICE ERROR LOG ------------------------------------------------- +EOF +exit 1 +""" + # Setup logging LOGGER = gbplog.getLogger('source_service') LOGGER.setLevel(gbplog.INFO) @@ -143,6 +174,10 @@ def gbs_export(repo, args, config): finally: shutil.rmtree(tmpdir) +def integer_list(string): + """Convert a string of comma-separated integers into a list of ints""" + return [int(val.strip()) for val in string.split(',') if val] + def parse_args(argv): """Argument parser""" default_configs = ['/etc/obs/services/gbs', @@ -161,6 +196,11 @@ def parse_args(argv): parser.add_argument('--git-meta', metavar='FILENAME', help='Create a json-formatted file FILENAME containing' 'metadata about the exported revision') + parser.add_argument('--error-pkg', metavar='EXIT_CODES', type=integer_list, + default=[], + help='Comma-separated list of exit codes that cause ' + 'an "error package" to be created instead of ' + 'causing a service error.') args = parser.parse_args(argv) if not args.config: args.config = default_configs @@ -182,22 +222,30 @@ def main(argv=None): else: gbplog.setup(color='auto', verbose=False) gbs_log.setup(verbose=False) + # Add a new handler writing to a tempfile into the root logger + file_log = tempfile.NamedTemporaryFile(prefix='gbs-service_') + file_handler = gbplog.GbpStreamHandler(file_log) + gbplog.getLogger().addHandler(file_handler) LOGGER.info('Starting GBS source service') + # Create outdir + try: + os.makedirs(args.outdir) + except OSError as err: + if err.errno != os.errno.EEXIST: + LOGGER.error('Failed to create outdir: %s', err) + return EXIT_ERR_SERVICE + try: config = read_config(args.config) # Create / update cached repository - repo = CachedRepo(config['repo-cache-dir'], args.url) - args.revision = repo.update_working_copy(args.revision, - submodules=False) - # Create outdir try: - os.makedirs(args.outdir) - except OSError as err: - if err.errno != os.errno.EEXIST: - raise ServiceError('Failed to create outdir: %s' % err, - EXIT_ERR_SERVICE) + repo = CachedRepo(config['repo-cache-dir'], args.url) + args.revision = repo.update_working_copy(args.revision, + submodules=False) + except CachedRepoError as err: + raise ServiceError('RepoCache: %s' % err, EXIT_ERR_SERVICE) # Export sources with GBS gbs_export(repo, args, config) @@ -211,9 +259,14 @@ def main(argv=None): raise ServiceError(str(err), EXIT_ERR_SERVICE) except ServiceError as err: LOGGER.error(err[0]) - ret = err[1] - except CachedRepoError as err: - LOGGER.error('RepoCache: %s', err) - ret = EXIT_ERR_SERVICE + if err[1] in args.error_pkg: + file_handler.flush() + error_fn = os.path.join(args.outdir, 'service-error') + shutil.copy2(file_log.name, error_fn) + with open(error_fn + '.spec', 'w') as error_spec: + error_spec.write(ERROR_PKG_SPEC) + ret = EXIT_OK + else: + ret = err[1] return ret diff --git a/service/gbs.service b/service/gbs.service index fdaeb06..c1e2846 100644 --- a/service/gbs.service +++ b/service/gbs.service @@ -1,6 +1,9 @@ Build with GBS (Git Build System) Export packaging files from a git repository managed with GBS (Git Build System). + + Instead of service error create an "error package". Comma-separated list of exit codes. + Export meta data about the revision into a file in JSON format. diff --git a/tests/test_obs_service_gbs.py b/tests/test_obs_service_gbs.py index cbc20ea..93659bc 100644 --- a/tests/test_obs_service_gbs.py +++ b/tests/test_obs_service_gbs.py @@ -234,6 +234,19 @@ class TestGbsService(UnitTestsBase): eq_(service(['--url', self.orig_repo.path, '--git-meta=test-package.spec']), 1) + def test_options_error_pkg(self): + """Test the --error-pkg option""" + # Do not create err-pkg if exit code not listed + eq_(service(['--url', self.orig_repo.path, '--error-pkg=2,3', + '--revision=foobar']), 1) + self.check_files([]) + + # Catch error and create err-pkg + eq_(service(['--url', self.orig_repo.path, '--error-pkg=1,2,3', + '--revision=foobar', '--outdir=foo']), 0) + self.check_files(['service-error.spec', 'service-error'], + directory='foo') + def test_user_group_config(self): """Test the user/group settings""" # Changing to current user/group should succeed -- 2.7.4