#24 Refactor build image handler
Merged 8 years ago by cqi. Opened 8 years ago by cqi.
cqi/freshmaker refactor-build-image  into  master

@@ -24,6 +24,7 @@ 

  from freshmaker import log, conf

  from freshmaker.handlers import BaseHandler

  from freshmaker.events import DockerfileChanged

+ from freshmaker.kojiservice import koji_service

  

  

  class DockerImageRebuildHandler(BaseHandler):
@@ -33,52 +34,31 @@ 

  

      def handle(self, event):

          """Rebuild docker image"""

-         self.build_image(event)

- 

-     def build_image(self, event):

          import koji

  

-         config = koji.read_config(conf.koji_profile)

-         koji_server = config['server']

- 

-         session = koji.ClientSession(koji_server, {'krb_rdns': config['krb_rdns']})

- 

-         log.debug('Logging into {0} with Kerberos authentication.'.format(koji_server))

-         proxyuser = conf.koji_build_owner if conf.koji_proxyuser else None

- 

          try:

-             session.krb_login(proxyuser=proxyuser)

-         except Exception as e:

-             log.error('Failed to login Koji via Kerberos using GSSAPI')

-             log.error('Error message from Koji: %s', e)

-             return

+             self.build_image(event)

+         except koji.krbV.Krb5Error as e:

+             log.exception('Failed to login Koji via Kerberos using GSSAPI. %s', e.args[1])

+         except:

+             log.exception('Could not create task to build docker image %s', event.repo)

  

-         if not session.logged_in:

-             log.error('Could not login server %s', koji_server)

-             return

+     def build_image(self, event):

+         with koji_service(profile=conf.koji_profile, logger=log) as service:

+             log.debug('Logging into {0} with Kerberos authentication.'.format(service.server))

+             proxyuser = conf.koji_build_owner if conf.koji_proxyuser else None

  

-         build_opts = {

-             'scratch': conf.koji_container_scratch_build,

-             'git_branch': event.branch,

-         }

+             service.krb_login(proxyuser=proxyuser)

+ 

+             if not service.logged_in:

+                 log.error('Could not login server %s', service.server)

+                 return

  

-         try:

-             build_target = '{}-{}-candidate'.format(

-                 'rawhide' if event.branch == 'master' else event.branch,

-                 event.namespace)

              build_source = '{}#{}'.format(event.repo_url, event.rev)

  

              log.info('Start to build docker image %s', event.repo)

              log.debug('Build from source: %s', build_source)

-             log.debug('Build in target: %s', build_target)

-             log.debug('Build options: %s', build_opts)

  

-             task_id = session.buildContainer(build_source, build_target, build_opts)

-         except Exception as e:

-             log.exception('Could not create task to build docker image %s', event.repo)

-         else:

-             log.info('Task %s is created to build docker image for repo %s', task_id, event.repo)

-             log.info('Task info: %s/taskinfo?taskID=%s', config['weburl'], task_id)

-         finally:

-             log.debug('Logout Koji session')

-             session.logout()

+             return service.build_container(build_source, event.branch,

+                                            namespace=event.namespace,

+                                            scratch=conf.koji_container_scratch_build)

@@ -0,0 +1,123 @@ 

+ # -*- coding: utf-8 -*-

+ # Copyright (c) 2017  Red Hat, Inc.

+ #

+ # Permission is hereby granted, free of charge, to any person obtaining a copy

+ # of this software and associated documentation files (the "Software"), to deal

+ # in the Software without restriction, including without limitation the rights

+ # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell

+ # copies of the Software, and to permit persons to whom the Software is

+ # furnished to do so, subject to the following conditions:

+ #

+ # The above copyright notice and this permission notice shall be included in

+ # all copies or substantial portions of the Software.

+ #

+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR

+ # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,

+ # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE

+ # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER

+ # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,

+ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE

+ # SOFTWARE.

+ #

+ # Written by Chenxiong Qi <cqi@redhat.com>

+ 

+ import contextlib

+ 

+ 

+ class KojiService(object):

+     """Wrapper of Koji API and profile configuration

+ 

+     As an interface of Koji profile configuration, KojiService exposes part

+     of options that would be used frequently. However, other options are still

+     accessible from ``config`` property.

+ 

+     As a wrapper of Koji API, new APIs could be added as well.

+     """

+ 

+     def __init__(self, profile=None, logger=None):

+         import koji

+ 

+         self._config = koji.read_config(profile or 'koji')

+         self._logger = logger

+ 

+     @property

+     def config(self):

+         return self._config

+ 

+     @property

+     def weburl(self):

+         return self.config['weburl']

+ 

+     @property

+     def server(self):

+         return self.config['server']

+ 

+     @property

+     def session(self):

+         import koji

+         if not hasattr(self, '_session'):

+             self._session = koji.ClientSession(self.config['server'],

+                                                {'krb_rdns': self.config['krb_rdns']})

+         return self._session

+ 

+     def krb_login(self, proxyuser=None):

+         self.session.krb_login(proxyuser=proxyuser)

+ 

+     @property

+     def logged_in(self):

+         return self.session.logged_in

+ 

+     def logout(self):

+         self.session.logout()

+ 

+     def build_container(self, source_url, branch, namespace=None, scratch=None):

+         """Build container by buildContainer"""

+ 

+         build_target = '{}-{}-candidate'.format(

+             'rawhide' if branch == 'master' else branch,

+             'container' if namespace is None else namespace)

+ 

+         build_opts = {

+             'scratch': False if scratch is None else True,

+             'git_branch': branch,

+         }

+ 

+         if self._logger:

+             self._logger.debug('Build from target: %s', build_target)

+             self._logger.debug('Build options: %s', build_opts)

+ 

+         task_id = self.session.buildContainer(source_url, build_target, build_opts)

+ 

+         if self._logger:

+             self._logger.info('Task %s is created to build docker image for %s',

+                               task_id, source_url)

+             self._logger.info('Task info: %s/taskinfo?taskID=%s', self.weburl, task_id)

+ 

+         return task_id

+ 

+ 

+ @contextlib.contextmanager

+ def koji_service(profile=None, logger=None):

+     """A Koji service context manager that could be used with with

+ 

+     Example::

+ 

+         with KojiService() as service:

+             ...

+ 

+         # if you want it to log something

+         with KojiService(logger=logger) as service:

+             ...

+ 

+         # if you want it to use alternative Koji profile rather than the default one koji

+         with KojiService(koji='stg', logger=logger) as service:

+             ...

+     """

+     service = KojiService(profile=profile, logger=logger)

+     try:

+         yield service

+     finally:

+         if service.logged_in:

+             if logger:

+                 logger.debug('Logout Koji session')

+             service.logout()

  • Move Koji session operations into a separate module
  • New context manager koji_service used with with statement
  • Simplify build_image method

Signed-off-by: Chenxiong Qi cqi@redhat.com

rebased

8 years ago

Pull-Request has been merged by cqi

8 years ago