Esempio n. 1
0
def test_flatpak_create_oci_no_source(workflow):
    workflow.user_params['flatpak'] = True
    setup_flatpak_composes(workflow)
    (flexmock(FlatpakUtil).should_receive(
        'get_flatpak_source_info').and_return(None))
    runner = PostBuildPluginsRunner(workflow, [{
        'name': FlatpakCreateOciPlugin.key,
        'args': {}
    }])

    msg = "flatpak_create_dockerfile must be run before flatpak_create_oci"

    with pytest.raises(PluginFailedException, match=msg):
        runner.run()
Esempio n. 2
0
def test_flatpak_update_dockerfile(tmpdir, docker_tasker, config_name, worker,
                                   breakage):
    config = CONFIGS[config_name]

    container_yaml = config['container_yaml']

    workflow = mock_workflow(tmpdir, container_yaml)

    assert get_flatpak_compose_info(workflow) is None
    assert get_flatpak_source_info(workflow) is None

    if breakage == 'branch_mismatch':
        config = deepcopy(config)
        base_module = config['modules'][config['base_module']]
        base_module['metadata'] = base_module['metadata'].replace(
            'branch: f28', 'branch: MISMATCH')

        expected_exception = "Mismatch for 'branch'"
    elif breakage == 'no_compose':
        config = deepcopy(config)
        config['odcs_composes'] = []
        expected_exception = "Can't find main module"
    else:
        assert breakage is None
        expected_exception = None

    mock_koji_session(config)

    set_flatpak_source_spec(workflow, config['source_spec'])

    args = {}

    if worker:
        # composes resolved in the parent, compose IDs passed in
        mock_odcs_session(workflow, config)
        args['compose_ids'] = [c['id'] for c in config['odcs_composes']]
    else:
        # composes run by resolve_composes plugin
        setup_flatpak_composes(workflow, config)

    secrets_path = os.path.join(str(tmpdir), "secret")
    os.mkdir(secrets_path)
    with open(os.path.join(secrets_path, "token"), "w") as f:
        f.write("green_eggs_and_ham")

    workflow.plugin_workspace[ReactorConfigPlugin.key] = {}
    workflow.plugin_workspace[ReactorConfigPlugin.key][WORKSPACE_CONF_KEY] =\
        ReactorConfig({'version': 1,
                       'odcs': {'api_url': ODCS_URL,
                                'auth': {'openidc_dir': secrets_path},
                                'signing_intents': [
                                    {
                                        'name': 'unsigned',
                                        'keys': [],
                                    },
                                    {
                                        'name': 'release',
                                        'keys': ['R123', 'R234'],
                                    },
                                    {
                                        'name': 'beta',
                                        'keys': ['R123', 'B456', 'B457'],
                                    },
                                ],
                                'default_signing_intent': 'unsigned'},
                       'koji':  {'auth': {},
                                 'hub_url': 'https://koji.example.com/hub'}})

    runner = PreBuildPluginsRunner(
        docker_tasker, workflow, [{
            'name': FlatpakUpdateDockerfilePlugin.key,
            'args': args
        }])

    if expected_exception:
        with pytest.raises(PluginFailedException) as ex:
            runner.run()
        assert expected_exception in str(ex.value)
    else:
        runner.run()

        assert os.path.exists(workflow.builder.df_path)
        with open(workflow.builder.df_path) as f:
            df = f.read()

        m = re.search(r'module enable\s*(.*?)\s*$', df, re.MULTILINE)
        assert m
        enabled_modules = sorted(m.group(1).split())

        if config_name == 'app':
            assert enabled_modules == ['eog:f28', 'flatpak-runtime:f28']
        else:
            assert enabled_modules == ['flatpak-runtime:f28']

        includepkgs_path = os.path.join(workflow.builder.df_dir,
                                        'atomic-reactor-includepkgs')
        assert os.path.exists(includepkgs_path)
        with open(includepkgs_path) as f:
            includepkgs = f.read()
            assert 'librsvg2' in includepkgs
            if config_name == 'app':
                assert 'eog-0:3.28.3-1.module_2123+73a9ef6f.x86_64' in includepkgs

        assert os.path.exists(
            os.path.join(workflow.builder.df_dir, 'cleanup.sh'))

        compose_info = get_flatpak_compose_info(workflow)
        assert compose_info.source_spec == config['source_spec']

        if config_name == 'app':
            assert compose_info.main_module.name == 'eog'
            assert compose_info.main_module.stream == 'f28'
            assert compose_info.main_module.version == '20170629213428'
            assert (compose_info.main_module.mmd.get_summary("C") ==
                    'Eye of GNOME Application Module')
            assert compose_info.main_module.rpms == [
                'eog-0:3.28.3-1.module_2123+73a9ef6f.src.rpm',
                'eog-0:3.28.3-1.module_2123+73a9ef6f.x86_64.rpm',
                'eog-0:3.28.3-1.module_2123+73a9ef6f.ppc64le.rpm',
            ]

        source_info = get_flatpak_source_info(workflow)
        assert source_info.base_module.name == config['base_module']
def test_flatpak_update_dockerfile(workflow, build_dir, config_name, breakage):
    config = CONFIGS[config_name]

    container_yaml = config['container_yaml']

    workflow = mock_workflow(workflow, build_dir, container_yaml)

    if breakage == 'branch_mismatch':
        config = deepcopy(config)
        base_module = config['modules'][config['base_module']]
        base_module['metadata'] = base_module['metadata'].replace(
            'branch: f28', 'branch: MISMATCH')

        expected_exception = "Mismatch for 'branch'"
    elif breakage == 'no_compose':
        config = deepcopy(config)
        config['odcs_composes'] = []
        expected_exception = "Can't find main module"
    else:
        assert breakage is None
        expected_exception = None

    mock_koji_session(config)

    # composes run by resolve_composes plugin
    setup_flatpak_composes(workflow, config)

    secrets_path = build_dir / "secret"
    secrets_path.mkdir()
    secrets_path.joinpath("token").write_text("green_eggs_and_ham", "utf-8")

    rcm = {
        'version': 1,
        'odcs': {
            'api_url':
            ODCS_URL,
            'auth': {
                'openidc_dir': secrets_path
            },
            'signing_intents': [
                {
                    'name': 'unsigned',
                    'keys': [],
                },
                {
                    'name': 'release',
                    'keys': ['R123', 'R234'],
                },
                {
                    'name': 'beta',
                    'keys': ['R123', 'B456', 'B457'],
                },
            ],
            'default_signing_intent':
            'unsigned'
        },
        'koji': {
            'auth': {},
            'hub_url': 'https://koji.example.com/hub'
        }
    }

    runner = (MockEnv(workflow).for_plugin(
        FlatpakUpdateDockerfilePlugin.key).set_reactor_config(
            rcm).create_runner())

    if expected_exception:
        with pytest.raises(PluginFailedException) as ex:
            runner.run()
        assert expected_exception in str(ex.value)
    else:
        runner.run()

        assert os.path.exists(workflow.build_dir.any_platform.dockerfile_path)
        df = workflow.build_dir.any_platform.dockerfile.content

        m = re.search(r'module enable\s*(.*?)\s*$', df, re.MULTILINE)
        assert m
        enabled_modules = sorted(m.group(1).split())

        if config_name == 'app':
            assert enabled_modules == ['eog:f28', 'flatpak-runtime:f28']
        else:
            assert enabled_modules == ['flatpak-runtime:f28']

        includepkgs_path = os.path.join(workflow.build_dir.any_platform.path,
                                        'atomic-reactor-includepkgs')
        assert os.path.exists(includepkgs_path)
        with open(includepkgs_path) as f:
            includepkgs = f.read()
            assert 'librsvg2' in includepkgs
            if config_name == 'app':
                assert 'eog-0:3.28.3-1.module_2123+73a9ef6f.x86_64' in includepkgs

        assert os.path.exists(
            os.path.join(workflow.build_dir.any_platform.path, 'cleanup.sh'))

        resolve_comp_result = workflow.data.plugins_results.get(
            PLUGIN_RESOLVE_COMPOSES_KEY)
        flatpak_util = FlatpakUtil(workflow_config=workflow.conf,
                                   source_config=workflow.source.config,
                                   composes=resolve_comp_result['composes'])
        compose_info = flatpak_util.get_flatpak_compose_info()
        assert compose_info.source_spec == config['source_spec']

        if config_name == 'app':
            assert compose_info.main_module.name == 'eog'
            assert compose_info.main_module.stream == 'f28'
            assert compose_info.main_module.version == '20170629213428'
            assert (compose_info.main_module.mmd.get_summary("C") ==
                    'Eye of GNOME Application Module')
            assert compose_info.main_module.rpms == [
                'eog-0:3.28.3-1.module_2123+73a9ef6f.src.rpm',
                'eog-0:3.28.3-1.module_2123+73a9ef6f.x86_64.rpm',
                'eog-0:3.28.3-1.module_2123+73a9ef6f.ppc64le.rpm',
            ]

        source_info = flatpak_util.get_flatpak_source_info()
        assert source_info.base_module.name == config['base_module']
Esempio n. 4
0
def test_flatpak_create_oci(workflow, config_name, flatpak_metadata, breakage):
    # Check that we actually have flatpak available
    have_flatpak = False
    try:
        output = subprocess.check_output(['flatpak', '--version'],
                                         universal_newlines=True)
        m = re.search(r'(\d+)\.(\d+)\.(\d+)', output)
        if m and (int(m.group(1)), int(m.group(2)), int(
                m.group(3))) >= (0, 9, 7):
            have_flatpak = True

    except (subprocess.CalledProcessError, OSError):
        pytest.skip(msg='flatpak not available')

    if not have_flatpak:
        return

    # Check if we have skopeo
    try:
        subprocess.check_output(['skopeo', '--version'])
    except (subprocess.CalledProcessError, OSError):
        pytest.skip(msg='skopeo not available')

    config = CONFIGS[config_name]

    platforms = ['x86_64', 'aarch64', 's390x', 'ppc64le']

    workflow.user_params['flatpak'] = True
    write_docker_file(config, workflow.source.path)
    workflow.build_dir.init_build_dirs(platforms, workflow.source)
    mock_extract_filesystem_call = functools.partial(mock_extract_filesystem,
                                                     config)
    (flexmock(ImageUtil).should_receive(
        'extract_filesystem_layer').replace_with(mock_extract_filesystem_call))

    make_and_store_reactor_config_map(workflow, flatpak_metadata)

    if breakage == 'no_runtime':
        # Copy the parts of the config we are going to change
        config = dict(config)
        config['modules'] = dict(config['modules'])
        config['modules']['eog'] = dict(config['modules']['eog'])

        module_config = config['modules']['eog']

        mmd = Modulemd.ModuleStream.read_string(module_config['metadata'],
                                                strict=True)
        mmd.clear_dependencies()
        mmd.add_dependencies(Modulemd.Dependencies())
        mmd_index = Modulemd.ModuleIndex.new()
        mmd_index.add_module_stream(mmd)
        module_config['metadata'] = mmd_index.dump_to_string()

        expected_exception = 'Failed to identify runtime module'
    else:
        assert breakage is None
        expected_exception = None

    runner = PostBuildPluginsRunner(workflow, [{
        'name': FlatpakCreateOciPlugin.key,
        'args': {}
    }])

    setup_flatpak_composes(workflow)
    source = setup_flatpak_source_info(config)
    (flexmock(FlatpakUtil).should_receive(
        'get_flatpak_source_info').and_return(source))

    if expected_exception:
        with pytest.raises(PluginFailedException) as ex:
            runner.run()
        assert expected_exception in str(ex.value)
    else:
        builder = FlatpakBuilder(source,
                                 workflow.build_dir.any_platform.path,
                                 'var/tmp/flatpak-build',
                                 parse_manifest=parse_rpm_output,
                                 flatpak_metadata=FLATPAK_METADATA_ANNOTATIONS)
        with NamedTemporaryFile(dir=workflow.build_dir.any_platform.path) as f:
            f.write(
                config['filesystem_contents']['/var/tmp/flatpak-build.rpm_qf'])
            f.flush()
            expected_components = builder.get_components(f.name)
        results = runner.run()
        x86_64_results = results[FlatpakCreateOciPlugin.key][platforms[0]]
        dir_metadata = x86_64_results['metadata']
        components = x86_64_results['components']
        assert components == expected_components
        assert dir_metadata['type'] == IMAGE_TYPE_OCI

        # Check that the correct labels and annotations were written

        labels, annotations = load_labels_and_annotations(dir_metadata)

        if config_name == 'app':
            assert labels['name'] == 'eog'
            assert labels['com.redhat.component'] == 'eog'
            assert labels['version'] == 'f28'
            assert labels['release'] == '20170629213428'
        elif config_name == 'runtime':  # runtime
            assert labels['name'] == 'flatpak-runtime'
            assert labels[
                'com.redhat.component'] == 'flatpak-runtime-container'
            assert labels['version'] == 'f28'
            assert labels['release'] == '20170701152209'
        else:
            assert labels['name'] == 'flatpak-sdk'
            assert labels['com.redhat.component'] == 'flatpak-sdk-container'
            assert labels['version'] == 'f28'
            assert labels['release'] == '20170701152209'

        if flatpak_metadata == 'annotations':
            assert annotations.get(
                'org.flatpak.ref') == config['expected_ref_name']
            assert 'org.flatpak.ref' not in labels
        elif flatpak_metadata == 'labels':
            assert 'org.flatpak.ref' not in annotations
            assert labels.get('org.flatpak.ref') == config['expected_ref_name']
        elif flatpak_metadata == 'both':
            assert annotations.get(
                'org.flatpak.ref') == config['expected_ref_name']
            assert labels.get('org.flatpak.ref') == config['expected_ref_name']

        # Check that the expected files ended up in the flatpak

        # Flatpak versions before 1.6 require annotations to be present, and Flatpak
        # versions 1.6 and later require labels to be present. Skip the remaining
        # checks unless we have both annotations and labels.
        if flatpak_metadata != 'both':
            return

        inspector = DefaultInspector(str(workflow.build_dir.any_platform.path),
                                     dir_metadata)

        files = inspector.list_files()
        assert sorted(files) == config['expected_contents']

        metadata_lines = inspector.cat_file('/metadata').split('\n')
        assert any(
            re.match(r'runtime=org.fedoraproject.Platform/.*/f28$', line)
            for line in metadata_lines)
        assert any(
            re.match(r'sdk=org.fedoraproject.Sdk/.*/f28$', line)
            for line in metadata_lines)

        if config_name == 'app':
            # Check that the desktop file was rewritten
            output = inspector.cat_file(
                '/export/share/applications/org.gnome.eog.desktop')
            lines = output.split('\n')
            assert 'Icon=org.gnome.eog' in lines

            assert 'name=org.gnome.eog' in metadata_lines
            assert 'tags=Viewer' in metadata_lines
            assert 'command=eog2' in metadata_lines
        elif config_name == 'runtime':  # runtime
            # Check that permissions have been normalized
            assert inspector.get_file_perms('/files/etc/shadow') == '-00644'
            assert inspector.get_file_perms('/files/bin/mount') == '-00755'
            assert inspector.get_file_perms('/files/share/foo') == 'd00755'

            assert 'name=org.fedoraproject.Platform' in metadata_lines
        else:  # SDK
            assert 'name=org.fedoraproject.Sdk' in metadata_lines