def test_create_session_failures(self, tmpdir, auth_type, auth_args, error_type, should_recover, attempts): url = 'https://example.com' if auth_args.get('ssl_certs_dir', None) == 'value': auth_args['ssl_certs_dir'] = str(tmpdir) session = flexmock(_value="test_value") (flexmock(koji_util.koji).should_receive('ClientSession').with_args( url, opts={ 'krb_rdns': False }).and_return(session)) flexmock(time).should_receive('sleep').and_return(None) if should_recover: (session.should_receive(auth_type).and_raise(error_type).and_raise( error_type).and_return(True)) test_session = create_koji_session(url, auth_args) assert test_session._wrapped_session == session assert test_session._value == "test_value" else: session.should_receive(auth_type).and_raise(error_type).times( attempts) with pytest.raises(error_type): create_koji_session(url, auth_args)
def test_fail_authenticated_session(self, tmpdir, ssl_session): url = 'https://example.com' args = {} session = flexmock() if ssl_session: args['ssl_certs_dir'] = str(tmpdir) session.should_receive('ssl_login').once().and_return(False) else: session.should_receive('krb_login').once().and_return(False) (flexmock(koji_util.koji).should_receive('ClientSession').with_args( url, opts={'krb_rdns': False}).and_return(session)) with pytest.raises(RuntimeError): create_koji_session(url, args)
def run(self): base_image = self.workflow.builder.base_image if base_image.namespace != 'koji' or base_image.repo != 'image-build': self.log.info('Base image not supported: %s', base_image) return image_build_conf = base_image.tag if not image_build_conf or image_build_conf == 'latest': image_build_conf = 'image-build.conf' self.session = create_koji_session(self.koji_hub, self.koji_auth_info) task_id, filesystem_regex = self.build_filesystem(image_build_conf) task = TaskWatcher(self.session, task_id, self.poll_interval) task.wait() if task.failed(): try: # Koji may re-raise the error that caused task to fail task_result = self.session.getTaskResult(task_id) except Exception as exc: task_result = repr(exc) raise RuntimeError('image task, {}, failed: {}'.format( task_id, task_result)) filesystem = self.download_filesystem(task_id, filesystem_regex) new_base_image = self.import_base_image(filesystem) self.workflow.builder.set_base_image(new_base_image) defer_removal(self.workflow, new_base_image) return { 'base-image-id': new_base_image, 'filesystem-koji-task-id': task_id, }
def __init__(self, tasker, workflow, koji_hub, koji_ssl_certs_dir=None, poll_interval=DEFAULT_POLL_INTERVAL, poll_timeout=DEFAULT_POLL_TIMEOUT): """ :param tasker: DockerTasker instance :param workflow: DockerBuildWorkflow instance :param koji_hub: str, koji hub (xmlrpc) :param koji_ssl_certs_dir: str, path to "cert", "ca", and "serverca" used when Koji's identity certificate is not trusted :param poll_interval: int, seconds between polling for Koji build :param poll_timeout: int, max amount of seconds to wait for Koji build """ super(KojiParentPlugin, self).__init__(tasker, workflow) koji_auth_info = None if koji_ssl_certs_dir: koji_auth_info = { 'ssl_certs_dir': koji_ssl_certs_dir, } self.koji_session = create_koji_session(koji_hub, koji_auth_info) self.poll_interval = poll_interval self.poll_timeout = poll_timeout self._parent_image_nvr = None self._parent_image_build = None self._poll_start = None
def __init__(self, tasker, workflow, hub, target=None, koji_ssl_certs_dir=None): """ constructor :param tasker: DockerTasker instance :param workflow: DockerBuildWorkflow instance :param hub: string, koji hub (xmlrpc) :param target: unused - backwards compatibility :param koji_ssl_certs_dir: str, path to "cert", "ca", and "serverca" Note that this plugin requires koji_ssl_certs_dir set if Koji certificate is not trusted by CA bundle. """ # call parent constructor super(BumpReleasePlugin, self).__init__(tasker, workflow) koji_auth_info = None if koji_ssl_certs_dir: koji_auth_info = { 'ssl_certs_dir': koji_ssl_certs_dir, } self.xmlrpc = create_koji_session(hub, koji_auth_info)
def run(self): dockerfile = DockerfileParser(self.workflow.builder.df_path) image_name = ImageName.parse(dockerfile.baseimage) if image_name.namespace != 'koji' or image_name.repo != 'image-build' : self.log.info('Base image not supported: %s', dockerfile.baseimage) return image_build_conf = image_name.tag or 'image-build.conf' self.session = create_koji_session(self.koji_hub, self.koji_auth_info) task_id, filesystem_regex = self.build_filesystem(image_build_conf) task = TaskWatcher(self.session, task_id, self.poll_interval) task.wait() if task.failed(): raise RuntimeError('Create filesystem task failed: {}' .format(task_id)) filesystem = self.download_filesystem(task_id, filesystem_regex) base_image = self.import_base_image(filesystem) dockerfile.baseimage = base_image return base_image
def test_create_simple_session(self): url = 'https://koji-hub-url.com' session = flexmock() (flexmock(koji_util.koji).should_receive('ClientSession').with_args( url).and_return(session)) assert create_koji_session(url) == session
def __init__(self, tasker, workflow, hub, target=None, koji_ssl_certs_dir=None, append=False): """ constructor :param tasker: DockerTasker instance :param workflow: DockerBuildWorkflow instance :param hub: string, koji hub (xmlrpc) :param target: unused - backwards compatibility :param koji_ssl_certs_dir: str, path to "cert", "ca", and "serverca" Note that this plugin requires koji_ssl_certs_dir set if Koji certificate is not trusted by CA bundle. :param append: if True, the release will be obtained by appending a '.' and a unique integer to the release label in the dockerfile. """ # call parent constructor super(BumpReleasePlugin, self).__init__(tasker, workflow) koji_auth_info = None if koji_ssl_certs_dir: koji_auth_info = { 'ssl_certs_dir': koji_ssl_certs_dir, } self.xmlrpc = create_koji_session(hub, koji_auth_info) self.append = append
def __init__(self, tasker, workflow, koji_parent_build, koji_hub, koji_ssl_certs_dir=None): """ :param tasker: DockerTasker instance :param workflow: DockerBuildWorkflow instance :param koji_parent_build: str, either Koji build ID or Koji build NVR :param koji_hub: str, koji hub (xmlrpc) :param koji_ssl_certs_dir: str, path to "cert", "ca", and "serverca" used when Koji's identity certificate is not trusted """ super(InjectParentImage, self).__init__(tasker, workflow) koji_auth_info = None if koji_ssl_certs_dir: koji_auth_info = { 'ssl_certs_dir': koji_ssl_certs_dir, } self.koji_session = create_koji_session(koji_hub, koji_auth_info) try: self.koji_parent_build = int(koji_parent_build) except ValueError: self.koji_parent_build = koji_parent_build self._koji_parent_build_info = None self._repositories = None self._new_parent_image = None
def run(self): base_image = self.workflow.builder.base_image if base_image.namespace != 'koji' or base_image.repo != 'image-build': self.log.info('Base image not supported: %s', base_image) return image_build_conf = base_image.tag if not image_build_conf or image_build_conf == 'latest': image_build_conf = 'image-build.conf' self.session = create_koji_session(self.koji_hub, self.koji_auth_info) task_id, filesystem_regex = self.build_filesystem(image_build_conf) task = TaskWatcher(self.session, task_id, self.poll_interval) task.wait() if task.failed(): raise RuntimeError( 'Create filesystem task failed: {}'.format(task_id)) filesystem = self.download_filesystem(task_id, filesystem_regex) new_base_image = self.import_base_image(filesystem) self.workflow.builder.set_base_image(new_base_image) defer_removal(self.workflow, new_base_image) return { 'base-image-id': new_base_image, 'filesystem-koji-task-id': task_id, }
def test_create_simple_session(self): url = 'https://koji-hub-url.com' session = flexmock() (flexmock(koji_util.koji) .should_receive('ClientSession').with_args(url).and_return(session)) assert create_koji_session(url) == session
def __init__(self, tasker, workflow, target, hub, root, proxy=None, koji_ssl_certs_dir=None): """ constructor :param tasker: DockerTasker instance :param workflow: DockerBuildWorkflow instance :param target: string, koji target to use as a source :param hub: string, koji hub (xmlrpc) :param root: string, koji root (storage) :param koji_ssl_certs_dir: str, path to "cert", "ca", and "serverca" Note that this plugin requires koji_ssl_certs_dir set if Koji certificate is not trusted by CA bundle. """ # call parent constructor super(KojiPlugin, self).__init__(tasker, workflow) self.target = target koji_auth_info = None if koji_ssl_certs_dir: koji_auth_info = { 'ssl_certs_dir': koji_ssl_certs_dir, } self.xmlrpc = create_koji_session(hub, koji_auth_info) self.pathinfo = koji.PathInfo(topdir=root) self.proxy = proxy
def test_create_simple_session(self): url = 'https://example.com' session = flexmock() (flexmock(koji_util.koji).should_receive('ClientSession').with_args( url, opts={'krb_rdns': False}).and_return(session)) assert create_koji_session(url)._wrapped_session == session
def test_create_authenticated_session(self): url = 'https://koji-hub-url.com' session = flexmock() session.should_receive('krb_login').once().and_return(True) (flexmock(koji_util.koji) .should_receive('ClientSession').with_args(url).and_return(session)) assert create_koji_session(url, {}) == session
def test_create_authenticated_session(self): url = 'https://koji-hub-url.com' session = flexmock() session.should_receive('krb_login').once().and_return(True) (flexmock(koji_util.koji).should_receive('ClientSession').with_args( url).and_return(session)) assert create_koji_session(url, {}) == session
def koji_session(self): if not self._koji_session: koji_auth_info = None if self.koji_ssl_certs_dir: koji_auth_info = { 'ssl_certs_dir': self.koji_ssl_certs_dir, } self._koji_session = create_koji_session(self.koji_hub, koji_auth_info) return self._koji_session
def __init__(self, tasker, workflow, hub, target=None): """ constructor :param tasker: DockerTasker instance :param workflow: DockerBuildWorkflow instance :param hub: string, koji hub (xmlrpc) :param target: unused - backwards compatibility """ # call parent constructor super(BumpReleasePlugin, self).__init__(tasker, workflow) self.xmlrpc = create_koji_session(hub)
def run(self): self.session = create_koji_session(self.koji_info['hub'], self.koji_info.get('auth')) nvr_requests = self.read_nvr_requests() url_requests = self.read_url_requests() download_queue = (self.process_by_nvr(nvr_requests) + self.process_by_url(url_requests)) self.download_files(download_queue) # TODO: Return a list of files for koji metadata return download_queue
def get_koji_session(workflow, fallback): config = get_koji(workflow, fallback) from atomic_reactor.koji_util import create_koji_session auth_info = { "proxyuser": config['auth'].get('proxyuser'), "ssl_certs_dir": config['auth'].get('ssl_certs_dir'), "krb_principal": config['auth'].get('krb_principal'), "krb_keytab": config['auth'].get('krb_keytab_path') } return create_koji_session(config['hub_url'], auth_info)
def login(self): """ Log in to koji :return: koji.ClientSession instance, logged in """ auth_info = { "proxyuser": self.koji_proxy_user, "ssl_certs_dir": self.koji_ssl_certs, "krb_principal": self.koji_principal, "krb_keytab": self.koji_keytab } return create_koji_session(self.kojihub, auth_info)
def test_create_authenticated_session(self, tmpdir, ssl_session): url = 'https://example.com' args = {} session = flexmock() if ssl_session: args['ssl_certs_dir'] = str(tmpdir) session.should_receive('ssl_login').once().and_return(True) else: session.should_receive('krb_login').once().and_return(True) (flexmock(koji_util.koji).should_receive('ClientSession').with_args( url, opts={'krb_rdns': False}).and_return(session)) assert create_koji_session(url, args)._wrapped_session == session
def login(self): """ Log in to koji :return: koji.ClientSession instance, logged in """ # krbV python library throws an error if these are unicode auth_info = { "proxyuser": self.koji_proxy_user, "ssl_certs_dir": self.koji_ssl_certs, "krb_principal": str(self.koji_principal), "krb_keytab": str(self.koji_keytab) } return create_koji_session(str(self.kojihub), auth_info)
def run(self): """ Run the plugin. """ if self.workflow.build_process_failed: self.log.info('Build failed, skipping koji tagging') return build_id = self.workflow.exit_results.get(KojiPromotePlugin.key) if not build_id: self.log.info('No koji build from %s', KojiPromotePlugin.key) return session = create_koji_session(self.kojihub, self.koji_auth) build_tag = tag_koji_build(session, build_id, self.target, poll_interval=self.poll_interval) return build_tag
def run(self): """ Run the plugin. """ if self.workflow.build_process_failed: self.log.info('Build failed, skipping koji tagging') return build_id = self.workflow.exit_results.get(KojiImportPlugin.key) if not build_id: build_id = self.workflow.exit_results.get(KojiPromotePlugin.key) if not build_id: self.log.info('No koji build from %s or %s', KojiImportPlugin.key, KojiPromotePlugin.key) return session = create_koji_session(self.kojihub, self.koji_auth) build_tag = tag_koji_build(session, build_id, self.target, poll_interval=self.poll_interval) return build_tag
def run(self): base_image = self.workflow.builder.base_image if base_image.namespace != 'koji' or base_image.repo != 'image-build': self.log.info('Base image not supported: %s', base_image) return image_build_conf = base_image.tag if not image_build_conf or image_build_conf == 'latest': image_build_conf = 'image-build.conf' self.session = create_koji_session(self.koji_hub, self.koji_auth_info) task_id, filesystem_regex = self.run_image_task(image_build_conf) new_base_image = None if not self.is_orchestrator: new_base_image = self.stream_filesystem(task_id, filesystem_regex) return { 'base-image-id': new_base_image, 'filesystem-koji-task-id': task_id, }
def __init__(self, tasker, workflow, smtp_host, from_address, send_on=(AUTO_CANCELED, AUTO_FAIL, MANUAL_SUCCESS, MANUAL_FAIL), url=None, error_addresses=(), additional_addresses=(), email_domain=None, koji_hub=None, koji_root=None, koji_proxyuser=None, koji_ssl_certs_dir=None, koji_krb_principal=None, koji_krb_keytab=None, to_koji_submitter=False, to_koji_pkgowner=False): """ constructor :param tasker: DockerTasker instance :param workflow: DockerBuildWorkflow instance :param send_on: list of str, list of build states when a notification should be sent see 'allowed_states' constant and rules in '_should_send' function :param url: str, URL to OSv3 instance where the build logs are stored :param smtp_host: str, URL of SMTP server to use to send the message (e.g. "foo.com:25") :param from_address: str, the "From" of the notification email :param error_addresses: list of str, list of email addresses where to send an email if an error occurred (e.g. if we can't find out who to notify about the failed build) :param additional_addresses: list of str, always send a message to these email addresses :param email_domain: str, email domain used when email addresses cannot be fetched via kerberos principal :param koji_hub: str, koji hub (xmlrpc) :param koji_root: str, koji root (storage) :param koji_proxyuser: str, proxy user :param koji_ssl_certs_dir: str, path to "cert", "ca", and "serverca" :param koji_krb_principal: str, name of Kerberos principal :param koji_krb_keytab: str, Kerberos keytab :param to_koji_submitter: bool, send a message to the koji submitter :param to_koji_pkgowner: bool, send messages to koji package owners """ super(SendMailPlugin, self).__init__(tasker, workflow) self.send_on = set(send_on) self.url = url self.additional_addresses = list(additional_addresses) self.smtp_host = smtp_host self.from_address = from_address self.error_addresses = list(error_addresses) self.email_domain = email_domain self.koji_hub = koji_hub self.koji_root = koji_root self.koji_auth_info = { 'proxyuser': koji_proxyuser, 'ssl_certs_dir': koji_ssl_certs_dir, 'krb_principal': koji_krb_principal, 'krb_keytab': koji_krb_keytab, } self.to_koji_submitter = to_koji_submitter self.to_koji_pkgowner = to_koji_pkgowner self.submitter = self.DEFAULT_SUBMITTER try: metadata = get_build_json().get("metadata", {}) self.koji_task_id = int(metadata['labels']['koji-task-id']) except Exception: self.log.exception("Failed to fetch koji task ID") self.koji_task_id = None else: self.log.info("Koji task ID: %s", self.koji_task_id) try: self.koji_build_id = self.workflow.exit_results.get( KojiPromotePlugin.key) except Exception: self.log.exception("Failed to fetch koji build ID") self.koji_build_id = None else: self.log.info("Koji build ID: %s", self.koji_build_id) try: self.session = create_koji_session(self.koji_hub, self.koji_auth_info) except Exception: self.log.exception("Failed to connect to koji") self.session = None else: self.log.info("Koji connection established")
def __init__(self, tasker, workflow, smtp_host, from_address, send_on=(AUTO_CANCELED, AUTO_FAIL, MANUAL_SUCCESS, MANUAL_FAIL), url=None, error_addresses=(), additional_addresses=(), email_domain=None, koji_hub=None, koji_root=None, koji_proxyuser=None, koji_ssl_certs_dir=None, koji_krb_principal=None, koji_krb_keytab=None, to_koji_submitter=False, to_koji_pkgowner=False): """ constructor :param tasker: DockerTasker instance :param workflow: DockerBuildWorkflow instance :param send_on: list of str, list of build states when a notification should be sent see 'allowed_states' constant and rules in '_should_send' function :param url: str, URL to OSv3 instance where the build logs are stored :param smtp_host: str, URL of SMTP server to use to send the message (e.g. "foo.com:25") :param from_address: str, the "From" of the notification email :param error_addresses: list of str, list of email addresses where to send an email if an error occurred (e.g. if we can't find out who to notify about the failed build) :param additional_addresses: list of str, always send a message to these email addresses :param email_domain: str, email domain used when email addresses cannot be fetched via kerberos principal :param koji_hub: str, koji hub (xmlrpc) :param koji_root: str, koji root (storage) :param koji_proxyuser: str, proxy user :param koji_ssl_certs_dir: str, path to "cert", "ca", and "serverca" :param koji_krb_principal: str, name of Kerberos principal :param koji_krb_keytab: str, Kerberos keytab :param to_koji_submitter: bool, send a message to the koji submitter :param to_koji_pkgowner: bool, send messages to koji package owners """ super(SendMailPlugin, self).__init__(tasker, workflow) self.send_on = set(send_on) self.url = url self.additional_addresses = list(additional_addresses) self.smtp_host = smtp_host self.from_address = from_address self.error_addresses = list(error_addresses) self.email_domain = email_domain self.koji_hub = koji_hub # Make sure koji_root doesn't end with a slash for a prettier link self.koji_root = koji_root[:-1] if koji_root and koji_root[-1] == '/' else koji_root self.koji_auth_info = { 'proxyuser': koji_proxyuser, 'ssl_certs_dir': koji_ssl_certs_dir, 'krb_principal': koji_krb_principal, 'krb_keytab': koji_krb_keytab, } self.to_koji_submitter = to_koji_submitter self.to_koji_pkgowner = to_koji_pkgowner self.submitter = self.DEFAULT_SUBMITTER try: metadata = get_build_json().get("metadata", {}) self.koji_task_id = int(metadata['labels']['koji-task-id']) except Exception: self.log.exception("Failed to fetch koji task ID") self.koji_task_id = None else: self.log.info("Koji task ID: %s", self.koji_task_id) self.koji_build_id = self.workflow.exit_results.get(KojiImportPlugin.key) if not self.koji_build_id: self.koji_build_id = self.workflow.exit_results.get(KojiPromotePlugin.key) if not self.koji_build_id: self.log.info("Failed to fetch koji build ID") else: self.log.info("Koji build ID: %s", self.koji_build_id) else: self.log.info("Koji build ID: %s", self.koji_build_id) try: self.session = create_koji_session(self.koji_hub, self.koji_auth_info) except Exception: self.log.exception("Failed to connect to koji") self.session = None else: self.log.info("Koji connection established")