def _resolve_modules(self, compose_source):
        koji_session = get_koji_session(self.workflow, fallback=NO_FALLBACK)

        resolved_modules = {}
        for module in compose_source.strip().split():
            module_spec = split_module_spec(module)
            build, rpm_list = get_koji_module_build(koji_session, module_spec)

            # The returned RPM list contains source RPMs and RPMs for all
            # architectures.
            rpms = [
                '{name}-{epochnum}:{version}-{release}.{arch}.rpm'.format(
                    epochnum=rpm['epoch'] or 0, **rpm) for rpm in rpm_list
            ]

            objects = Modulemd.objects_from_string(
                build['extra']['typeinfo']['module']['modulemd_str'])
            assert len(objects) == 1
            mmd = objects[0]
            assert isinstance(mmd, Modulemd.Module)
            # Make sure we have a version 2 modulemd file
            mmd.upgrade()

            resolved_modules[module_spec.name] = ModuleInfo(
                module_spec.name, module_spec.stream, module_spec.version, mmd,
                rpms)
        return resolved_modules
    def _resolve_compose(self):
        odcs_client = get_odcs_session(self.workflow, self.odcs_fallback)
        self.read_configs_general()

        modules = self.data.get('modules', [])

        if not modules:
            raise RuntimeError(
                '"compose" config has no modules, a module is required for Flatpaks'
            )

        source_spec = modules[0]
        if len(modules) > 1:
            self.log.info(
                "compose config contains multiple modules,"
                "using first module %s", source_spec)

        module = split_module_spec(source_spec)
        self.log.info(
            "Resolving module compose for name=%s, stream=%s, version=%s",
            module.name, module.stream, module.version)

        noprofile_spec = module.to_str(include_profile=False)

        if self.compose_ids:
            if len(self.compose_ids) > 1:
                self.log.info("Multiple compose_ids, using first compose %d",
                              self.compose_ids[0])
            self.compose_id = self.compose_ids[0]

        if self.compose_id is None:
            self.compose_id = odcs_client.start_compose(
                source_type='module', source=noprofile_spec)['id']

        compose_info = odcs_client.wait_for_compose(self.compose_id)
        if compose_info['state_name'] != "done":
            raise RuntimeError("Compose cannot be retrieved, state='%s'" %
                               compose_info['state_name'])

        compose_source = compose_info['source']
        self.log.info("Resolved list of modules: %s", compose_source)

        resolved_modules = self._resolve_modules(compose_source)
        base_module = resolved_modules[module.name]
        assert base_module.stream == module.stream
        if module.version is not None:
            assert base_module.version == module.version

        return ComposeInfo(source_spec=source_spec,
                           compose_id=self.compose_id,
                           base_module=base_module,
                           modules=resolved_modules,
                           repo_url=compose_info['result_repo'] +
                           '/$basearch/os/')
def setup_flatpak_source_info(workflow, config=APP_CONFIG):
    compose = setup_flatpak_compose_info(workflow, config)

    flatpak_yaml = yaml.safe_load(config['container_yaml'])['flatpak']

    module_spec = split_module_spec(compose.source_spec)

    source = FlatpakSourceInfo(flatpak_yaml, compose.modules,
                               compose.base_module, module_spec.profile)
    set_flatpak_source_info(workflow, source)

    return source
    def _load_source(self):
        flatpak_yaml = self.workflow.source.config.flatpak

        compose_info = get_compose_info(self.workflow)
        if compose_info is None:
            raise RuntimeError(
                "resolve_module_compose must be run before flatpak_create_dockerfile"
            )

        module_spec = split_module_spec(compose_info.source_spec)

        return FlatpakSourceInfo(flatpak_yaml, compose_info.modules,
                                 compose_info.base_module, module_spec.profile)
Exemple #5
0
    def __init__(self, flatpak_yaml, compose):
        self.flatpak_yaml = flatpak_yaml
        self.compose = compose

        mmd = compose.base_module.mmd
        # A runtime module must have a 'runtime' profile, but can have other
        # profiles for SDKs, minimal runtimes, etc.
        self.runtime = 'runtime' in mmd.peek_profiles()

        module_spec = split_module_spec(compose.source_spec)
        if module_spec.profile:
            self.profile = module_spec.profile
        elif self.runtime:
            self.profile = 'runtime'
        else:
            self.profile = 'default'

        assert self.profile in mmd.peek_profiles()
Exemple #6
0
    def test_without_context(self, koji_return, should_raise):
        module = 'eog:master:20180821163756'
        spec = split_module_spec(module)

        session = flexmock()
        (session.should_receive('getPackageID').with_args('eog').and_return(
            303))
        (session.should_receive('listBuilds').with_args(
            packageID=303, type='module',
            state=koji.BUILD_STATES['COMPLETE']).and_return(koji_return))

        if should_raise:
            with pytest.raises(Exception) as e:
                get_koji_module_build(session, spec)
            assert should_raise in str(e)
        else:
            self.mock_get_rpms(session)
            get_koji_module_build(session, spec)
Exemple #7
0
    def _resolve_modules(self, compose_source):
        resolved_modules = {}
        # The effect of develop=True is that requests to the PDC are made without authentication;
        # since we our interaction with the PDC is read-only, this is fine for our needs and
        # makes things simpler.
        pdc_client = get_pdc_session(self.workflow, self.pdc_fallback)

        for module_spec in compose_source.strip().split():
            try:
                module = split_module_spec(module_spec)
                if not module.version:
                    raise RuntimeError
            except RuntimeError:
                raise RuntimeError("Cannot parse resolved module in compose: %s" % module_spec)

            query = {
                'variant_id': module.name,
                'variant_version': module.stream,
                'variant_release': module.version,
                'active': True,
            }

            self.log.info("Looking up module metadata for '%s' in the PDC", module_spec)
            retval = pdc_client['unreleasedvariants/'](page_size=-1,
                                                       fields=['modulemd', 'rpms'], **query)
            # Error handling
            if not retval:
                raise RuntimeError("Failed to find module in PDC %r" % query)
            if len(retval) != 1:
                raise RuntimeError("Multiple modules in the PDC matched %r" % query)

            objects = Modulemd.objects_from_string(retval[0]['modulemd'])
            assert len(objects) == 1
            mmd = objects[0]
            assert isinstance(mmd, Modulemd.Module)
            # Make sure we have a version 2 modulemd file
            mmd.upgrade()
            rpms = set(retval[0]['rpms'])

            resolved_modules[module.name] = ModuleInfo(module.name, module.stream, module.version,
                                                       mmd, rpms)
        return resolved_modules
Exemple #8
0
    def test_with_context(self):
        module = 'eog:master:20180821163756:775baa8e'
        module_koji_nvr = 'eog-master-20180821163756.775baa8e'
        koji_return = {
            'build_id': 1138198,
            'name': 'eog',
            'version': 'master',
            'release': '20180821163756.775baa8e',
            'extra': {
                'typeinfo': {
                    'module': {
                        'modulemd_str': 'document: modulemd\nversion: 2'
                    }
                }
            }
        }

        spec = split_module_spec(module)
        session = flexmock()
        (session.should_receive('getBuild').with_args(
            module_koji_nvr).and_return(koji_return))
        self.mock_get_rpms(session)

        get_koji_module_build(session, spec)
Exemple #9
0
def test_module_spec_to_str(as_str, as_str_no_profile):
    spec = split_module_spec(as_str)
    assert spec.to_str() == as_str
    assert spec.to_str(include_profile=False) == as_str_no_profile
Exemple #10
0
def test_split_module_spec(module, should_raise, expected):
    if should_raise:
        with pytest.raises(RuntimeError):
            split_module_spec(module)
    else:
        assert split_module_spec(module) == expected