Esempio n. 1
0
    def get_or_create_build(self,
                            identifier,
                            original_nvr=None,
                            force_container_label=False):
        """
        Get a Koji build from Neo4j, or create it if it does not exist in Neo4j.

        :param str/int identifier: an NVR (str) or build ID (int), or a dict of info from Koji API
        :kwarg str original_nvr: original_nvr property for the ContainerKojiBuild
        :kwarg bool force_container_label: when true, this skips the check to see if the build is a
            container and just creates the build with the ContainerKojiBuild label
        :rtype: KojiBuild
        :return: the Koji Build retrieved or created from Neo4j
        """
        if type(identifier) is dict:
            build_info = identifier
        else:
            try:
                build_info = self.koji_session.getBuild(identifier,
                                                        strict=True)
            except Exception:
                log.error(
                    'Failed to get brew build using the identifier {0}'.format(
                        identifier))
                raise

        build_params = {
            'epoch': build_info['epoch'],
            'id_': str(build_info['id']),
            'name': build_info['package_name'],
            'release': build_info['release'],
            'state': build_info['state'],
            'version': build_info['version']
        }

        if build_info.get('extra'):
            build_params['extra'] = json.dumps(build_info['extra'])

        # To handle the case when a message has a null timestamp
        for time_key in ('completion_time', 'creation_time', 'start_time'):
            # Certain Koji API endpoints omit the *_ts values but have the *_time values, so that's
            # why the *_time values are used
            if build_info[time_key]:
                ts_format = r'%Y-%m-%d %H:%M:%S'
                if len(build_info[time_key].rsplit('.', 1)) == 2:
                    # If there are microseconds, go ahead and parse that too
                    ts_format += r'.%f'
                build_params[time_key] = datetime.strptime(
                    build_info[time_key], ts_format)

        owner = User.create_or_update({
            'username':
            build_info['owner_name'],
            'email':
            '{0}@redhat.com'.format(build_info['owner_name'])
        })[0]

        if force_container_label or self.is_container_build(build_info):
            if original_nvr:
                build_params['original_nvr'] = original_nvr
            build = ContainerKojiBuild.create_or_update(build_params)[0]
        elif self.is_module_build(build_info):
            module_extra_info = build_info['extra'].get('typeinfo',
                                                        {}).get('module')
            build_params['context'] = module_extra_info.get('context')
            build_params['mbs_id'] = module_extra_info.get(
                'module_build_service_id')
            build_params['module_name'] = module_extra_info.get('name')
            build_params['module_stream'] = module_extra_info.get('stream')
            build_params['module_version'] = module_extra_info.get('version')
            try:
                build = ModuleKojiBuild.create_or_update(build_params)[0]
            except neomodel.exceptions.ConstraintValidationFailed:
                # This must have errantly been created as a KojiBuild instead of a
                # ModuleKojiBuild, so let's fix that.
                build = KojiBuild.nodes.get_or_none(id_=build_params['id_'])
                if not build:
                    # If there was a constraint validation failure and the build isn't just the
                    # wrong label, then we can't recover.
                    raise
                build.add_label(ModuleKojiBuild.__label__)
                build = ModuleKojiBuild.create_or_update(build_params)[0]
        else:
            build = KojiBuild.create_or_update(build_params)[0]

        build.conditional_connect(build.owner, owner)

        return build
Esempio n. 2
0
def test_module_story_node_siblings(client, resource, uid, backward_rel, expected):
    """Tests getting the siblings of an artifact's adjacent node in the module story path."""
    bug = BugzillaBug.get_or_create({
        'classification': 'Red Hat',
        'creation_time': datetime(2017, 4, 2, 19, 39, 6),
        'id_': '12345',
        'modified_time': datetime(2018, 2, 7, 19, 30, 47),
        'priority': 'high',
        'product_name': 'Red Hat Enterprise Linux',
        'product_version': '7.5',
        'resolution': '',
        'severity': 'low',
        'short_description': 'Some description',
        'status': 'VERIFIED',
        'target_milestone': 'rc',
        'votes': 0
    })[0]
    commit = DistGitCommit.get_or_create({
        'author_date': datetime(2017, 4, 26, 11, 44, 38),
        'commit_date': datetime(2017, 4, 26, 11, 44, 38),
        'hash_': '8a63adb248ba633e200067e1ad6dc61931727bad',
        'log_message': 'Related: #12345 - fix xyz'
    })[0]
    build = KojiBuild.get_or_create({
        'completion_time': datetime(2017, 4, 2, 19, 39, 6),
        'creation_time': datetime(2017, 4, 2, 19, 39, 6),
        'epoch': '0',
        'id_': '2345',
        'name': 'slf4j',
        'release': '4.el7_4',
        'start_time': datetime(2017, 4, 2, 19, 39, 6),
        'state': 1,
        'version': '1.7.4'
    })[0]
    build_two = KojiBuild.get_or_create({
        'completion_time': datetime(2017, 4, 2, 19, 39, 6),
        'creation_time': datetime(2017, 4, 2, 19, 39, 6),
        'epoch': '0',
        'id_': '3456',
        'name': 'slf3j',
        'release': '4.el6_3',
        'start_time': datetime(2017, 4, 2, 19, 39, 6),
        'state': 2,
        'version': '1.7.1'
    })[0]
    module_build = ModuleKojiBuild.get_or_create({
        'completion_time': datetime(2017, 4, 2, 19, 39, 6),
        'creation_time': datetime(2017, 4, 2, 19, 39, 6),
        'epoch': '0',
        'id_': '2345',
        'name': '389-ds',
        'context': 'a2037af3',
        'release': '20180805121332.a2037af3',
        'start_time': datetime(2017, 4, 2, 19, 39, 6),
        'mbs_id': 1338,
        'module_name': '389-ds',
        'module_version': '20180805121332',
        'module_stream': '1.4'
    })[0]
    advisory = Advisory.get_or_create({
        'actual_ship_date': datetime(2017, 8, 1, 15, 43, 51),
        'advisory_name': 'RHBA-2017:2251-02',
        'content_types': ['docker'],
        'created_at': datetime(2017, 4, 3, 14, 47, 23),
        'id_': '27825',
        'issue_date': datetime(2017, 8, 1, 5, 59, 34),
        'product_name': 'Red Hat Enterprise Linux',
        'product_short_name': 'RHEL',
        'security_impact': 'None',
        'state': 'SHIPPED_LIVE',
        'status_time': datetime(2017, 8, 1, 15, 43, 51),
        'synopsis': 'cifs-utils bug fix update',
        'update_date': datetime(2017, 8, 1, 7, 16)
    })[0]
    fm_event = FreshmakerEvent.get_or_create({
        'event_type_id': 8,
        'id_': '1180',
        'message_id': 'ID:messaging-devops-broker01.test',
        'state': 2,
        'state_name': 'COMPLETE',
        'state_reason': 'All container images have been rebuilt.',
        'time_created': datetime(2019, 8, 21, 13, 42, 20),
        'time_done': datetime(2099, 8, 21, 13, 42, 20)
    })[0]
    cb = ContainerKojiBuild.get_or_create({
        'completion_time': datetime(2017, 4, 2, 19, 39, 6),
        'creation_time': datetime(2017, 4, 2, 19, 39, 6),
        'epoch': '0',
        'id_': '710',
        'name': 'slf4j_2',
        'release': '4.el7_4_as',
        'start_time': datetime(2017, 4, 2, 19, 39, 6),
        'state': 1,
        'version': '1.7.4'
    })[0]
    cb_two = ContainerKojiBuild.get_or_create({
        'completion_time': datetime(2018, 4, 2, 19, 39, 6),
        'creation_time': datetime(2018, 4, 2, 19, 39, 6),
        'epoch': '0',
        'id_': '811',
        'name': 'some_build',
        'release': '4.el7_4_as',
        'start_time': datetime(2018, 4, 2, 19, 39, 6),
        'state': 2,
        'version': '1.7.5'
    })[0]
    ca = ContainerAdvisory.get_or_create({
        'actual_ship_date': datetime(2017, 8, 1, 15, 43, 51),
        'advisory_name': 'RHBA-2017:2251-03',
        'content_types': ['docker'],
        'created_at': datetime(2017, 4, 3, 14, 47, 23),
        'id_': '12327',
        'issue_date': datetime(2017, 8, 1, 5, 59, 34),
        'product_name': 'Red Hat Enterprise Linux',
        'product_short_name': 'RHEL',
        'security_impact': 'None',
        'state': 'SHIPPED_LIVE',
        'status_time': datetime(2017, 8, 1, 15, 43, 51),
        'synopsis': 'cifs-utils bug fix update',
        'update_date': datetime(2017, 8, 1, 7, 16)
    })[0]

    commit.resolved_bugs.connect(bug)
    commit.koji_builds.connect(build)
    build.advisories.connect(advisory)
    build_two.advisories.connect(advisory)
    fm_event.triggered_by_advisory.connect(advisory)
    fm_event.successful_koji_builds.connect(cb)
    fm_event.successful_koji_builds.connect(cb_two)
    ca.attached_builds.connect(cb)
    ca.attached_builds.connect(cb_two)
    module_build.components.connect(build)
    module_build.components.connect(build_two)
    module_build.advisories.connect(advisory)

    url = '/api/v1/siblings/{0}/{1}?story_type=module'.format(resource, uid)
    if backward_rel:
        url = '{0}&backward_rel=true'.format(url)
    rv = client.get(url)
    assert rv.status_code == 200
    assert json.loads(rv.data.decode('utf-8')) == expected
Esempio n. 3
0
    def update_neo4j(self, builds):
        """
        Update Neo4j with Koji build information from Teiid.

        :param list builds: a list of dictionaries
        """
        # Uploads builds data to their respective nodes
        log.info('Beginning to upload data to Neo4j')
        count = 0

        for build_dict in builds:
            build_params = dict(
                id_=build_dict['id'],
                epoch=build_dict['epoch'],
                state=build_dict['state'],
                creation_time=build_dict['creation_time'],
                start_time=build_dict['start_time'],
                completion_time=build_dict['completion_time'],
                name=build_dict['package_name'],
                version=build_dict['version'],
                release=build_dict['release']
            )

            try:
                extra_json = json.loads(build_dict['extra'])
            except (ValueError, TypeError):
                extra_json = {}

            if self.is_container_build(build_dict):
                build_params['operator'] = bool(
                    extra_json.get('typeinfo', {}).get('operator-manifests', {}).get('archive')
                )
                try:
                    build = ContainerKojiBuild.create_or_update(build_params)[0]
                except neomodel.exceptions.ConstraintValidationFailed:
                    # This must have errantly been created as a KojiBuild instead of a
                    # ContainerKojiBuild, so let's fix that.
                    build = KojiBuild.nodes.get_or_none(id_=build_params['id_'])
                    if not build:
                        # If there was a constraint validation failure and the build isn't just the
                        # wrong label, then we can't recover.
                        raise
                    build.add_label(ContainerKojiBuild.__label__)
                    build = ContainerKojiBuild.create_or_update(build_params)[0]
            elif self.is_module_build(build_dict):
                module_extra_info = extra_json.get('typeinfo', {}).get('module')
                try:
                    build_params['context'] = module_extra_info.get('context')
                    build_params['mbs_id'] = module_extra_info.get('module_build_service_id')
                    build_params['module_name'] = module_extra_info.get('name')
                    build_params['module_stream'] = module_extra_info.get('stream')
                    build_params['module_version'] = module_extra_info.get('version')
                    build = ModuleKojiBuild.create_or_update(build_params)[0]
                except neomodel.exceptions.ConstraintValidationFailed:
                    # This must have errantly been created as a KojiBuild instead of a
                    # ModuleKojiBuild, so let's fix that.
                    build = KojiBuild.nodes.get_or_none(id_=build_params['id_'])
                    if not build:
                        # If there was a constraint validation failure and the build isn't just the
                        # wrong label, then we can't recover.
                        raise
                    build.add_label(ModuleKojiBuild.__label__)
                    build = ModuleKojiBuild.create_or_update(build_params)[0]
            else:
                build = KojiBuild.create_or_update(build_params)[0]

            username = build_dict['owner_name']
            user = User.get_or_create(dict(username=username))[0]
            build.conditional_connect(build.owner, user)

            if build.__label__ == ModuleKojiBuild.__label__:
                module_build_tag_name = module_extra_info.get('content_koji_tag')
                if module_build_tag_name:
                    module_components = self.get_tag_info(module_build_tag_name)
                    # Some modules don't have components
                    if module_components:
                        for item in module_components:
                            module_component = KojiBuild.get_or_create(dict(
                                id_=item['build_id']
                            ))[0]
                            build.components.connect(module_component)

                        component_builds = self.get_build_info(
                            [item['build_id'] for item in module_components])
                        self.update_neo4j(component_builds)

            count += 1
            log.info('Uploaded {0} builds out of {1}'.format(count, len(builds)))

            container_koji_task_id = extra_json.get('container_koji_task_id')
            if build_dict['task_id']:
                task_id = build_dict['task_id']
            elif container_koji_task_id:
                task_id = container_koji_task_id
            else:
                # Continue if the task_id is None
                continue
            # Getting task related to the current build
            try:
                task_dict = self.get_task(task_id)[0]
            except IndexError:
                continue

            commit_hash = None
            # Only look for the commit hash if the build is an RPM or container
            if task_dict['method'] in ('build', 'buildContainer'):
                xml_root = ET.fromstring(task_dict['request'])
                for child in xml_root.iter('string'):
                    if child.text and child.text.startswith('git'):
                        commit_hash = child.text.rsplit('#', 1)[1]
                        break

            if commit_hash:
                commit = DistGitCommit.get_or_create(dict(hash_=commit_hash))[0]
                build.conditional_connect(build.commit, commit)