File product-composer.obscpio of Package product-composer

07070100000000000081a4000000000000000000000001684059c400000029000000000000000000000000000000000000001600000000product-composer/.gitgitdir: ../.git/modules/product-composer
07070100000001000081a4000000000000000000000001684059c4000002f5000000000000000000000000000000000000002e00000000product-composer/.github/workflows/tests.yamlname: 'tests'

on:
  pull_request:
    branches: ['main']

concurrency:
  group: ${{ github.workflow }}-${{ github.ref }}
  cancel-in-progress: true

jobs:
  unit:
    name: "basic"
    runs-on: 'ubuntu-latest'
    container: 'registry.suse.com/bci/python:3.11'

    steps:
      - name: 'Install packages'
        run: |
            zypper -n install python311-pydantic python311-pytest python311-setuptools python311-rpm python311-PyYAML

      - uses: actions/checkout@v4

      - name: 'Run basic example verification'
        run: |
          python3 -m venv venv --system-site-packages
          source venv/bin/activate
          pip install --no-dependencies -e .
          productcomposer verify examples/ftp.productcompose
#          pytest tests
07070100000002000041ed000000000000000000000001684059c400000000000000000000000000000000000000000000002300000000product-composer/.github/workflows07070100000003000041ed000000000000000000000001684059c400000000000000000000000000000000000000000000001900000000product-composer/.github07070100000004000081a4000000000000000000000001684059c400000045000000000000000000000000000000000000001c00000000product-composer/.gitignore.venv
examples/repos
src/productcomposer.egg-info
output
__pycache__
07070100000005000081a4000000000000000000000001684059c40000464b000000000000000000000000000000000000001900000000product-composer/COPYING		    GNU GENERAL PUBLIC LICENSE
		       Version 2, June 1991

 Copyright (C) 1989, 1991 Free Software Foundation, Inc.
 51 Franklin Steet, Fifth Floor, Boston, MA  02111-1307  USA
 Everyone is permitted to copy and distribute verbatim copies
 of this license document, but changing it is not allowed.

			    Preamble

  The licenses for most software are designed to take away your
freedom to share and change it.  By contrast, the GNU General Public
License is intended to guarantee your freedom to share and change free
software--to make sure the software is free for all its users.  This
General Public License applies to most of the Free Software
Foundation's software and to any other program whose authors commit to
using it.  (Some other Free Software Foundation software is covered by
the GNU Library General Public License instead.)  You can apply it to
your programs, too.

  When we speak of free software, we are referring to freedom, not
price.  Our General Public Licenses are designed to make sure that you
have the freedom to distribute copies of free software (and charge for
this service if you wish), that you receive source code or can get it
if you want it, that you can change the software or use pieces of it
in new free programs; and that you know you can do these things.

  To protect your rights, we need to make restrictions that forbid
anyone to deny you these rights or to ask you to surrender the rights.
These restrictions translate to certain responsibilities for you if you
distribute copies of the software, or if you modify it.

  For example, if you distribute copies of such a program, whether
gratis or for a fee, you must give the recipients all the rights that
you have.  You must make sure that they, too, receive or can get the
source code.  And you must show them these terms so they know their
rights.

  We protect your rights with two steps: (1) copyright the software, and
(2) offer you this license which gives you legal permission to copy,
distribute and/or modify the software.

  Also, for each author's protection and ours, we want to make certain
that everyone understands that there is no warranty for this free
software.  If the software is modified by someone else and passed on, we
want its recipients to know that what they have is not the original, so
that any problems introduced by others will not reflect on the original
authors' reputations.

  Finally, any free program is threatened constantly by software
patents.  We wish to avoid the danger that redistributors of a free
program will individually obtain patent licenses, in effect making the
program proprietary.  To prevent this, we have made it clear that any
patent must be licensed for everyone's free use or not licensed at all.

  The precise terms and conditions for copying, distribution and
modification follow.

		    GNU GENERAL PUBLIC LICENSE
   TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION

  0. This License applies to any program or other work which contains
a notice placed by the copyright holder saying it may be distributed
under the terms of this General Public License.  The "Program", below,
refers to any such program or work, and a "work based on the Program"
means either the Program or any derivative work under copyright law:
that is to say, a work containing the Program or a portion of it,
either verbatim or with modifications and/or translated into another
language.  (Hereinafter, translation is included without limitation in
the term "modification".)  Each licensee is addressed as "you".

Activities other than copying, distribution and modification are not
covered by this License; they are outside its scope.  The act of
running the Program is not restricted, and the output from the Program
is covered only if its contents constitute a work based on the
Program (independent of having been made by running the Program).
Whether that is true depends on what the Program does.

  1. You may copy and distribute verbatim copies of the Program's
source code as you receive it, in any medium, provided that you
conspicuously and appropriately publish on each copy an appropriate
copyright notice and disclaimer of warranty; keep intact all the
notices that refer to this License and to the absence of any warranty;
and give any other recipients of the Program a copy of this License
along with the Program.

You may charge a fee for the physical act of transferring a copy, and
you may at your option offer warranty protection in exchange for a fee.

  2. You may modify your copy or copies of the Program or any portion
of it, thus forming a work based on the Program, and copy and
distribute such modifications or work under the terms of Section 1
above, provided that you also meet all of these conditions:

    a) You must cause the modified files to carry prominent notices
    stating that you changed the files and the date of any change.

    b) You must cause any work that you distribute or publish, that in
    whole or in part contains or is derived from the Program or any
    part thereof, to be licensed as a whole at no charge to all third
    parties under the terms of this License.

    c) If the modified program normally reads commands interactively
    when run, you must cause it, when started running for such
    interactive use in the most ordinary way, to print or display an
    announcement including an appropriate copyright notice and a
    notice that there is no warranty (or else, saying that you provide
    a warranty) and that users may redistribute the program under
    these conditions, and telling the user how to view a copy of this
    License.  (Exception: if the Program itself is interactive but
    does not normally print such an announcement, your work based on
    the Program is not required to print an announcement.)

These requirements apply to the modified work as a whole.  If
identifiable sections of that work are not derived from the Program,
and can be reasonably considered independent and separate works in
themselves, then this License, and its terms, do not apply to those
sections when you distribute them as separate works.  But when you
distribute the same sections as part of a whole which is a work based
on the Program, the distribution of the whole must be on the terms of
this License, whose permissions for other licensees extend to the
entire whole, and thus to each and every part regardless of who wrote it.

Thus, it is not the intent of this section to claim rights or contest
your rights to work written entirely by you; rather, the intent is to
exercise the right to control the distribution of derivative or
collective works based on the Program.

In addition, mere aggregation of another work not based on the Program
with the Program (or with a work based on the Program) on a volume of
a storage or distribution medium does not bring the other work under
the scope of this License.

  3. You may copy and distribute the Program (or a work based on it,
under Section 2) in object code or executable form under the terms of
Sections 1 and 2 above provided that you also do one of the following:

    a) Accompany it with the complete corresponding machine-readable
    source code, which must be distributed under the terms of Sections
    1 and 2 above on a medium customarily used for software interchange; or,

    b) Accompany it with a written offer, valid for at least three
    years, to give any third party, for a charge no more than your
    cost of physically performing source distribution, a complete
    machine-readable copy of the corresponding source code, to be
    distributed under the terms of Sections 1 and 2 above on a medium
    customarily used for software interchange; or,

    c) Accompany it with the information you received as to the offer
    to distribute corresponding source code.  (This alternative is
    allowed only for noncommercial distribution and only if you
    received the program in object code or executable form with such
    an offer, in accord with Subsection b above.)

The source code for a work means the preferred form of the work for
making modifications to it.  For an executable work, complete source
code means all the source code for all modules it contains, plus any
associated interface definition files, plus the scripts used to
control compilation and installation of the executable.  However, as a
special exception, the source code distributed need not include
anything that is normally distributed (in either source or binary
form) with the major components (compiler, kernel, and so on) of the
operating system on which the executable runs, unless that component
itself accompanies the executable.

If distribution of executable or object code is made by offering
access to copy from a designated place, then offering equivalent
access to copy the source code from the same place counts as
distribution of the source code, even though third parties are not
compelled to copy the source along with the object code.

  4. You may not copy, modify, sublicense, or distribute the Program
except as expressly provided under this License.  Any attempt
otherwise to copy, modify, sublicense or distribute the Program is
void, and will automatically terminate your rights under this License.
However, parties who have received copies, or rights, from you under
this License will not have their licenses terminated so long as such
parties remain in full compliance.

  5. You are not required to accept this License, since you have not
signed it.  However, nothing else grants you permission to modify or
distribute the Program or its derivative works.  These actions are
prohibited by law if you do not accept this License.  Therefore, by
modifying or distributing the Program (or any work based on the
Program), you indicate your acceptance of this License to do so, and
all its terms and conditions for copying, distributing or modifying
the Program or works based on it.

  6. Each time you redistribute the Program (or any work based on the
Program), the recipient automatically receives a license from the
original licensor to copy, distribute or modify the Program subject to
these terms and conditions.  You may not impose any further
restrictions on the recipients' exercise of the rights granted herein.
You are not responsible for enforcing compliance by third parties to
this License.

  7. If, as a consequence of a court judgment or allegation of patent
infringement or for any other reason (not limited to patent issues),
conditions are imposed on you (whether by court order, agreement or
otherwise) that contradict the conditions of this License, they do not
excuse you from the conditions of this License.  If you cannot
distribute so as to satisfy simultaneously your obligations under this
License and any other pertinent obligations, then as a consequence you
may not distribute the Program at all.  For example, if a patent
license would not permit royalty-free redistribution of the Program by
all those who receive copies directly or indirectly through you, then
the only way you could satisfy both it and this License would be to
refrain entirely from distribution of the Program.

If any portion of this section is held invalid or unenforceable under
any particular circumstance, the balance of the section is intended to
apply and the section as a whole is intended to apply in other
circumstances.

It is not the purpose of this section to induce you to infringe any
patents or other property right claims or to contest validity of any
such claims; this section has the sole purpose of protecting the
integrity of the free software distribution system, which is
implemented by public license practices.  Many people have made
generous contributions to the wide range of software distributed
through that system in reliance on consistent application of that
system; it is up to the author/donor to decide if he or she is willing
to distribute software through any other system and a licensee cannot
impose that choice.

This section is intended to make thoroughly clear what is believed to
be a consequence of the rest of this License.

  8. If the distribution and/or use of the Program is restricted in
certain countries either by patents or by copyrighted interfaces, the
original copyright holder who places the Program under this License
may add an explicit geographical distribution limitation excluding
those countries, so that distribution is permitted only in or among
countries not thus excluded.  In such case, this License incorporates
the limitation as if written in the body of this License.

  9. The Free Software Foundation may publish revised and/or new versions
of the General Public License from time to time.  Such new versions will
be similar in spirit to the present version, but may differ in detail to
address new problems or concerns.

Each version is given a distinguishing version number.  If the Program
specifies a version number of this License which applies to it and "any
later version", you have the option of following the terms and conditions
either of that version or of any later version published by the Free
Software Foundation.  If the Program does not specify a version number of
this License, you may choose any version ever published by the Free Software
Foundation.

  10. If you wish to incorporate parts of the Program into other free
programs whose distribution conditions are different, write to the author
to ask for permission.  For software which is copyrighted by the Free
Software Foundation, write to the Free Software Foundation; we sometimes
make exceptions for this.  Our decision will be guided by the two goals
of preserving the free status of all derivatives of our free software and
of promoting the sharing and reuse of software generally.

			    NO WARRANTY

  11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW.  EXCEPT WHEN
OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.  THE ENTIRE RISK AS
TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU.  SHOULD THE
PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
REPAIR OR CORRECTION.

  12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
POSSIBILITY OF SUCH DAMAGES.

		     END OF TERMS AND CONDITIONS

	    How to Apply These Terms to Your New Programs

  If you develop a new program, and you want it to be of the greatest
possible use to the public, the best way to achieve this is to make it
free software which everyone can redistribute and change under these terms.

  To do so, attach the following notices to the program.  It is safest
to attach them to the start of each source file to most effectively
convey the exclusion of warranty; and each file should have at least
the "copyright" line and a pointer to where the full notice is found.

    <one line to give the program's name and a brief idea of what it does.>
    Copyright (C) <year>  <name of author>

    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation; either version 2 of the License, or
    (at your option) any later version.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with this program; if not, write to the Free Software
    Foundation, Inc., 51 Franklin Steet, Fifth Floor, Boston, MA  02111-1307  USA


Also add information on how to contact you by electronic and paper mail.

If the program is interactive, make it output a short notice like this
when it starts in an interactive mode:

    Gnomovision version 69, Copyright (C) year name of author
    Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
    This is free software, and you are welcome to redistribute it
    under certain conditions; type `show c' for details.

The hypothetical commands `show w' and `show c' should show the appropriate
parts of the General Public License.  Of course, the commands you use may
be called something other than `show w' and `show c'; they could even be
mouse-clicks or menu items--whatever suits your program.

You should also get your employer (if you work as a programmer) or your
school, if any, to sign a "copyright disclaimer" for the program, if
necessary.  Here is a sample; alter the names:

  Yoyodyne, Inc., hereby disclaims all copyright interest in the program
  `Gnomovision' (which makes passes at compilers) written by James Hacker.

  <signature of Ty Coon>, 1 April 1989
  Ty Coon, President of Vice

This General Public License does not permit incorporating your program into
proprietary programs.  If your program is a subroutine library, you may
consider it more useful to permit linking proprietary applications with the
library.  If this is what you want to do, use the GNU Library General
Public License instead of this License.
07070100000006000081a4000000000000000000000001684059c4000001df000000000000000000000000000000000000001a00000000product-composer/Makefile# Project management tasks.

VENV = .venv
PYTHON = . $(VENV)/bin/activate && python
PYTEST = $(PYTHON) -m pytest


$(VENV)/.make-update: pyproject.toml
	python3 -m venv $(VENV)
	$(PYTHON) -m pip install -U pip  # needs to be updated first
	$(PYTHON) -m pip install -e ".[dev]"
	touch $@


.PHONY: dev
dev: $(VENV)/.make-update


.PHONY: docs
docs: dev
	asciidoc docs/productcomposer.adoc


.PHONY: test-unit
test-unit: dev
	$(PYTEST) tests/unit/


.PHONY: check
check: test-unit
07070100000007000081a4000000000000000000000001684059c400000999000000000000000000000000000000000000001c00000000product-composer/README.rstproduct-composer
================

This is the successor of product-builder. A tool to create rpm product
repositories inside of Open Build Service based on a larger pool
of packages.

It is used by any SLFO based product during product creation and
also during maintenance time.

Currently it supports:
 - processing based on a list of rpm package names
 - optional filters for architectures, versions and flavors can be defined
 - it can either just take a single rpm of a given name or all of them
 - it can post process updateinfo data
 - post processing like rpm meta data generation
 - modify pre-generated installer images to put a package set for 
   off-line installation on it.

Development
===========

Create the development environment:

.. code-block:: console

    $ python -m venv .venv
    $ .venv/bin/python -m pip install -e ".[dev]"


Run tests:

.. code-block::

    $ .venv/bin/python -m pytest -v tests/


Build documentation:

.. code-block::

    $ make docs



Installation
============

Packaging and distributing a Python application is dependent on the target
operating system(s) and execution environment, which could be a Python virtual
environment, Linux container, or native application.

Install the application to a self-contained Python virtual environment:

    $ python -m venv .venv
    $ .venv/bin/python -m pip install <project source>
    $ cp -r <project source>/etc .venv/
    $ .venv/bin/productcomposer --help



Execution
=========

The installed application includes a wrapper script for command line execution.
The location of this scripts depends on how the application was installed.


Configuration
-------------

The application uses `TOML`_ files for configuration. Configuration supports
runtime parameter substitution via a shell-like variable syntax, *i.e.*
``var = ${VALUE}``. CLI invocation will use the current environment for
parameter substitution, which makes it simple to pass host-specific values
to the application without needing to change the config file for every
installation.

.. code-block:: toml

    mailhost = $SENDMAIL_HOST


Logging
-------

The application uses standard `Python logging`_. All loggins is to ``STDERR``,
nd the logging level can be set via the config file or on the command line.


.. _TOML: https://toml.io
.. _Python logging: https://docs.python.org/3/library/logging.html
.. _mdklatt/cookiecutter-python-app: https://github.com/mdklatt/cookiecutter-python-app
07070100000008000081a4000000000000000000000001684059c400000029000000000000000000000000000000000000002100000000product-composer/docs/.gitignore# Ignore Sphinx build artifacts.

_build
07070100000009000081a4000000000000000000000001684059c400002602000000000000000000000000000000000000002d00000000product-composer/docs/build_description.adoc
== productcompose build description options

=== minimal version

 product_compose_schema: 0.2
 vendor: I_and_myself
 name: my_product
 version: 1.0
 product-type: module

 architectures: [ x86_64 ]

 packages:
  - my-single-rpm-package

=== build options

The build options may be used to change the behaviour of the build
process. The options are described in the details below.

Just add them to enable the desired functionality, no further
arguments are allowed.

=== flavors

Flavors can be defined with any name. These can be
used to build multiple media from one build description.

Each flavor may define an own architecture list.

It can also be used to add different package sets.

You need to add a _multibuild file to your sources
to enable the build.

=== iso

Enables iso file generation and requires configuration of
iso9660 headers.

=== content

content defines the packagesets to be used as entry
point for the medium.

The default is just to use the "main" packageset.

=== unpack

unpack defines the packagesets to be used for extracting
the content of the rpm packages directly on the medium.

These rpm packages need to provide these files below

 /usr/lib/skelcd/CD1

Currently it gets only extracted to the first/main medium,
but not on source or debug media.

=== packagesets

The packagesets definitions. A packageset lists rpm names
to be put on the medium.

There is usually one master list and in addition there
can be addional optional lists.

The additional lists can be filtered by flavors and/or
architectures.

The packageset requires at least a packages definition,
but may optionaly also a name, flavors or architectures.

==== name

Defines the name of the package set. 'main' is the default
name.

==== architecture

Lists the architectures where the set is to be used. The
default is for all architectures.

==== flavor

Lists the flavors where the set is to be used. The
default is for all flavors.

==== add

Can be used to add further packagesets by specifing
their names.

A special packageset called '__all__' will add all
package names local available.

==== sub

Can be used to remove packages from the specified
packageset names.

==== intersect

Can be used to filter packages with specified package
set lists.

==== packages

Lists all package names to be added. This is just the rpm
name, not the file name.

==== supportstatus

Define support status level for the packages listed in
packages. Valid support levels are l3, l2, unsupported.
However these are handled as strings. If the string starts
with a "=", it overrides any previously set support status
from inherited package sets.


=== Details

==== name

The product name.

==== version

The product version

==== update

Optional update level string for CPE

==== edition

Optional edition string for CPE

==== summary

The product name in explaining words. It will be presented to the
user on overview screens

==== product-type

Either 'base' for operation systems or 'module' for any product
depending on any existing installation.

'extension' is handled as alias for 'module'.

==== architectures

An array of the master architectures to be put into the repository.
This can be used to build a single repository usable for many
hardware architectures.

product composer will automatically fall back to "noarch" packages
if the package is not found natively.

Setting a global architecture list is optional, when architectures
are listed for each flavor.

==== bcntsynctag

Optionaly defines a bcntsynctag for OBS. OBS will sync the build
counter over all packages in same repository and architecture
according to this tag.

==== milestone

Optionaly defines a milestone which will be used by OBS at release
time. This can be used to turn candidate builds into a Beta1 for
example

==== build_options

===== take_all_available_versions

By default only "the best" version of each rpm is taken.
Use this switch to put all candidates on the medium.
For example for maintenance repositories.

===== OBS_unordered_product_repos

OBS is by default filtering rpm packages based on the repository
path layering.

This switch can be used to disable this behaviour in cases where
a binary from a lower priorisated repository should be used.

This can increase the amount of required binaries a lot when
dealing with deep path lists.

===== ignore_missing_packages

Missing packages lead by default to a build failure.
Use this switch to continue. The missing packages are
still listed in the build log.

===== hide_flavor_in_product_directory_name

The flavor name is by default part of the directory
name of the build result. This can be disabled,
when each flavor has a different arch list. Otherwise
conflicts can happen.

===== add_slsa_provenance

Add slsa provenance files for each rpm if available

===== abort_on_empty_updateinfo

Existing updateinfo.xml are scanned by default and reduced to
the available package binaries. In case none are found the
update is skipped. Enableing this option leads to a build failure
instead.

===== skip_updateinfos

No updateinfo meta information is added to the media.
This might be required when not using take_all_available_versions,
but building on a former released code base.

===== updateinfo_packages_only

Build a pure update repository. Skipping all matching rpms
which are not referenced via an updateinfo.

===== base_skip_packages

Controls whether packages should be copied in the `/install` directory
when using base iso images.

Enabling this would result in a simply repacked base image, without
any package copied there.

==== iso

===== publisher

For setting the iso9660 PUBLISHER header

===== vendor_id

For setting the iso9660 VENDOR_ID header

===== tree

Can be set to "drop" for creating only the iso files.

===== base

Can be used to copy the result into a pre generated iso file.
product-composer itself is not creating bootable iso images,
aka installer images. But it can used for example to use iso
images with the agama-installer where it copies the main tree
inside.

When defining a base iso name, it is expected that:
 * the image gets provided via an rpm called baseiso-NAME
 * the image is available in the /usr/libexec/base-isos directory
   with the given NAME prefix.

product-composer will add the main product tree into /install
directory of this media. The build result will be a single
iso file name with the product name and a .install.iso suffix.

Only a single repository per product is usable. In case source
or debug rpm's need to be added, they need to be part of the
main repository.

==== installcheck

Runs a repository closure test for each architecture. This will
report any missing dependencies and abort.

===== ignore_errors

For reporting the dependency errors, but ignoring them.

==== debug

Configure the handling of debuginfo and debugsource rpms.
Use either

  debug: include

to include them or

  debug: drop

to drop all debug packages or

  debug: split

to create a seperate medium mwith -Debug suffix.

Missing debug packages will always be ignored.

This default setting may get specified per flavor.

==== packages

The package list. It can contain either simple name or it can
be extended by a >, >=, =, <, <= operator to specify a
specific version constraint.

The syntax for the version is rpm like

 [EPOCH:]VERSION[-RELEASE]

A missing epoch means epoch zero. If the release is missing, it
matches any release.

The package list can be valid globally or limited to specific flavors
or architectures.

==== product_compose_schema

Defines the level of the yaml syntax.
Please expect incompatible changes at any time atm.

This will be used to provide backward compability once
we stabilized.

==== product_directory_name

Can be used to specify a directory or medium name manually.
The default is "name-version".

The directory name will always be suffixed by the architecture
and build number.

==== source

Configure the handling of src or nosrc rpms for the picked binaries.
Use either

  source: include

to include all source packages or

  source: drop

to drop all source packages or

  source: split

to create a seperate medium with -Source suffix.

A missing source package leads to a build failure unless
the ignore_missing_packages built option is used.

This default setting may get specified per flavor.

==== repodata

Write architecture specific repository meta data into the architecture
specific sub directories. This way a client needs to process less
data. The disadvantage is that different URL's need to be handled
per architecture.

  repodata: split

It is also possible to have a main repodata including all architectures
in addition to the architecture splitted ones.

  repodata: all

In absence of the repodata element only the main repodata is created
and includes all architectures.

This may get specified per flavor.

==== vendor

Defines the company responsible for the content. Can be for example
openSUSE or SUSE. It is used by the install stack.

==== set_updateinfo_from

Can be set to replace the "from" attribute in updateinfo.xml files with a fixed value.
This is shown as patch provider by zypp stack. Otherwise the value stays, OBS is setting
the packager from _patchinfo file here by default.

==== set_updateinfo_id_prefix

Sets a fixed prefix to all id's of included updateinfo data. It is not adding again
if the prefix exists already.

This can be used to have a common identifier for an update for many products, but
still being able to identify the filtering for a specific product.

==== block_updates_under_embargo

The current default is to include maintenance updates under embargo. This option can
be set to abort when an embargo date is in future.

0707010000000a000081a4000000000000000000000001684059c400000756000000000000000000000000000000000000002b00000000product-composer/docs/productcomposer.adoc= productcomposer
:toc:
:icons:
:numbered:
:website: https://www.geckito.org/

== Goals

A lightweight successor for product builder.

It is used to generate product RPM repositories out of a pool of RPMs.
Unlike product builder, these can also be used to ship maintenance updates.

.Currently it supports:
- processing based on a list of RPM package names.
  product compose is currently not taking care of dependencies.
- providing matching source and/or debug packages for picked RPM packages.
  These can be either included into main repository or prepared via
  extra repositories
- optional filters for architectures, versions and flavors can be defined
- it can provide either just a single RPM of a given name or all of them
- it can post process updateinfo data
- post processing to provide various types of RPM meta data generation

Not yet implemented:
- create bootable iso files

== Design

product composer is supposed to be used only inside of OBS builds atm.
OBS or osc is preparing all binary RPM candidates in local directory 
before starting the build.

== Setup in OBS

You will require OBS 2.11 or later.

.Create a new repository with any name. Either in a new or existing project.
- The product-composer package must be available in any repository
  listed in the path elements.
- All scheduler architectures where packages are taken from must be listed.

Your build description file may have any name, but must have a .productcompose
suffix.

The build type for the repository must be set to

  Type: productcompose

in the build configuration (aka prjconf).

== Special setup for maintenance

Ensure to build your patchinfo builds in a repository where "local" is the first
architecture.

Your productcompose file may provide all versions of each RPM if you enable
"take_all_available_versions" in the build options.

include::build_description.adoc[]

0707010000000b000081a4000000000000000000000001684059c400009031000000000000000000000000000000000000002b00000000product-composer/docs/productcomposer.html<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
    "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en">
<head>
<meta http-equiv="Content-Type" content="application/xhtml+xml; charset=UTF-8" />
<meta name="generator" content="AsciiDoc 10.2.1" />
<title>productcomposer</title>
<style type="text/css">
/* Shared CSS for AsciiDoc xhtml11 and html5 backends */

/* Default font. */
body {
  font-family: Georgia,serif;
}

/* Title font. */
h1, h2, h3, h4, h5, h6,
div.title, caption.title,
thead, p.table.header,
#toctitle,
#author, #revnumber, #revdate, #revremark,
#footer {
  font-family: Arial,Helvetica,sans-serif;
}

body {
  margin: 1em 5% 1em 5%;
}

a {
  color: blue;
  text-decoration: underline;
}
a:visited {
  color: fuchsia;
}

em {
  font-style: italic;
  color: navy;
}

strong {
  font-weight: bold;
  color: #083194;
}

h1, h2, h3, h4, h5, h6 {
  color: #527bbd;
  margin-top: 1.2em;
  margin-bottom: 0.5em;
  line-height: 1.3;
}

h1, h2, h3 {
  border-bottom: 2px solid silver;
}
h2 {
  padding-top: 0.5em;
}
h3 {
  float: left;
}
h3 + * {
  clear: left;
}
h5 {
  font-size: 1.0em;
}

div.sectionbody {
  margin-left: 0;
}

hr {
  border: 1px solid silver;
}

p {
  margin-top: 0.5em;
  margin-bottom: 0.5em;
}

ul, ol, li > p {
  margin-top: 0;
}
ul > li     { color: #aaa; }
ul > li > * { color: black; }

.monospaced, code, pre {
  font-family: "Courier New", Courier, monospace;
  font-size: inherit;
  color: navy;
  padding: 0;
  margin: 0;
}
pre {
  white-space: pre-wrap;
}

#author {
  color: #527bbd;
  font-weight: bold;
  font-size: 1.1em;
}
#email {
}
#revnumber, #revdate, #revremark {
}

#footer {
  font-size: small;
  border-top: 2px solid silver;
  padding-top: 0.5em;
  margin-top: 4.0em;
}
#footer-text {
  float: left;
  padding-bottom: 0.5em;
}
#footer-badges {
  float: right;
  padding-bottom: 0.5em;
}

#preamble {
  margin-top: 1.5em;
  margin-bottom: 1.5em;
}
div.imageblock, div.exampleblock, div.verseblock,
div.quoteblock, div.literalblock, div.listingblock, div.sidebarblock,
div.admonitionblock {
  margin-top: 1.0em;
  margin-bottom: 1.5em;
}
div.admonitionblock {
  margin-top: 2.0em;
  margin-bottom: 2.0em;
  margin-right: 10%;
  color: #606060;
}

div.content { /* Block element content. */
  padding: 0;
}

/* Block element titles. */
div.title, caption.title {
  color: #527bbd;
  font-weight: bold;
  text-align: left;
  margin-top: 1.0em;
  margin-bottom: 0.5em;
}
div.title + * {
  margin-top: 0;
}

td div.title:first-child {
  margin-top: 0.0em;
}
div.content div.title:first-child {
  margin-top: 0.0em;
}
div.content + div.title {
  margin-top: 0.0em;
}

div.sidebarblock > div.content {
  background: #ffffee;
  border: 1px solid #dddddd;
  border-left: 4px solid #f0f0f0;
  padding: 0.5em;
}

div.listingblock > div.content {
  border: 1px solid #dddddd;
  border-left: 5px solid #f0f0f0;
  background: #f8f8f8;
  padding: 0.5em;
}

div.quoteblock, div.verseblock {
  padding-left: 1.0em;
  margin-left: 1.0em;
  margin-right: 10%;
  border-left: 5px solid #f0f0f0;
  color: #888;
}

div.quoteblock > div.attribution {
  padding-top: 0.5em;
  text-align: right;
}

div.verseblock > pre.content {
  font-family: inherit;
  font-size: inherit;
}
div.verseblock > div.attribution {
  padding-top: 0.75em;
  text-align: left;
}
/* DEPRECATED: Pre version 8.2.7 verse style literal block. */
div.verseblock + div.attribution {
  text-align: left;
}

div.admonitionblock .icon {
  vertical-align: top;
  font-size: 1.1em;
  font-weight: bold;
  text-decoration: underline;
  color: #527bbd;
  padding-right: 0.5em;
}
div.admonitionblock td.content {
  padding-left: 0.5em;
  border-left: 3px solid #dddddd;
}

div.exampleblock > div.content {
  border-left: 3px solid #dddddd;
  padding-left: 0.5em;
}

div.imageblock div.content { padding-left: 0; }
span.image img { border-style: none; vertical-align: text-bottom; }
a.image:visited { color: white; }

dl {
  margin-top: 0.8em;
  margin-bottom: 0.8em;
}
dt {
  margin-top: 0.5em;
  margin-bottom: 0;
  font-style: normal;
  color: navy;
}
dd > *:first-child {
  margin-top: 0.1em;
}

ul, ol {
    list-style-position: outside;
}
ol.arabic {
  list-style-type: decimal;
}
ol.loweralpha {
  list-style-type: lower-alpha;
}
ol.upperalpha {
  list-style-type: upper-alpha;
}
ol.lowerroman {
  list-style-type: lower-roman;
}
ol.upperroman {
  list-style-type: upper-roman;
}

div.compact ul, div.compact ol,
div.compact p, div.compact p,
div.compact div, div.compact div {
  margin-top: 0.1em;
  margin-bottom: 0.1em;
}

tfoot {
  font-weight: bold;
}
td > div.verse {
  white-space: pre;
}

div.hdlist {
  margin-top: 0.8em;
  margin-bottom: 0.8em;
}
div.hdlist tr {
  padding-bottom: 15px;
}
dt.hdlist1.strong, td.hdlist1.strong {
  font-weight: bold;
}
td.hdlist1 {
  vertical-align: top;
  font-style: normal;
  padding-right: 0.8em;
  color: navy;
}
td.hdlist2 {
  vertical-align: top;
}
div.hdlist.compact tr {
  margin: 0;
  padding-bottom: 0;
}

.comment {
  background: yellow;
}

.footnote, .footnoteref {
  font-size: 0.8em;
}

span.footnote, span.footnoteref {
  vertical-align: super;
}

#footnotes {
  margin: 20px 0 20px 0;
  padding: 7px 0 0 0;
}

#footnotes div.footnote {
  margin: 0 0 5px 0;
}

#footnotes hr {
  border: none;
  border-top: 1px solid silver;
  height: 1px;
  text-align: left;
  margin-left: 0;
  width: 20%;
  min-width: 100px;
}

div.colist td {
  padding-right: 0.5em;
  padding-bottom: 0.3em;
  vertical-align: top;
}
div.colist td img {
  margin-top: 0.3em;
}

@media print {
  #footer-badges { display: none; }
}

#toc {
  margin-bottom: 2.5em;
}

#toctitle {
  color: #527bbd;
  font-size: 1.1em;
  font-weight: bold;
  margin-top: 1.0em;
  margin-bottom: 0.1em;
}

div.toclevel0, div.toclevel1, div.toclevel2, div.toclevel3, div.toclevel4 {
  margin-top: 0;
  margin-bottom: 0;
}
div.toclevel2 {
  margin-left: 2em;
  font-size: 0.9em;
}
div.toclevel3 {
  margin-left: 4em;
  font-size: 0.9em;
}
div.toclevel4 {
  margin-left: 6em;
  font-size: 0.9em;
}

span.aqua { color: aqua; }
span.black { color: black; }
span.blue { color: blue; }
span.fuchsia { color: fuchsia; }
span.gray { color: gray; }
span.green { color: green; }
span.lime { color: lime; }
span.maroon { color: maroon; }
span.navy { color: navy; }
span.olive { color: olive; }
span.purple { color: purple; }
span.red { color: red; }
span.silver { color: silver; }
span.teal { color: teal; }
span.white { color: white; }
span.yellow { color: yellow; }

span.aqua-background { background: aqua; }
span.black-background { background: black; }
span.blue-background { background: blue; }
span.fuchsia-background { background: fuchsia; }
span.gray-background { background: gray; }
span.green-background { background: green; }
span.lime-background { background: lime; }
span.maroon-background { background: maroon; }
span.navy-background { background: navy; }
span.olive-background { background: olive; }
span.purple-background { background: purple; }
span.red-background { background: red; }
span.silver-background { background: silver; }
span.teal-background { background: teal; }
span.white-background { background: white; }
span.yellow-background { background: yellow; }

span.big { font-size: 2em; }
span.small { font-size: 0.6em; }

span.underline { text-decoration: underline; }
span.overline { text-decoration: overline; }
span.line-through { text-decoration: line-through; }

div.unbreakable { page-break-inside: avoid; }


/*
 * xhtml11 specific
 *
 * */

div.tableblock {
  margin-top: 1.0em;
  margin-bottom: 1.5em;
}
div.tableblock > table {
  border: 3px solid #527bbd;
}
thead, p.table.header {
  font-weight: bold;
  color: #527bbd;
}
p.table {
  margin-top: 0;
}
/* Because the table frame attribute is overridden by CSS in most browsers. */
div.tableblock > table[frame="void"] {
  border-style: none;
}
div.tableblock > table[frame="hsides"] {
  border-left-style: none;
  border-right-style: none;
}
div.tableblock > table[frame="vsides"] {
  border-top-style: none;
  border-bottom-style: none;
}


/*
 * html5 specific
 *
 * */

table.tableblock {
  margin-top: 1.0em;
  margin-bottom: 1.5em;
}
thead, p.tableblock.header {
  font-weight: bold;
  color: #527bbd;
}
p.tableblock {
  margin-top: 0;
}
table.tableblock {
  border-width: 3px;
  border-spacing: 0px;
  border-style: solid;
  border-color: #527bbd;
  border-collapse: collapse;
}
th.tableblock, td.tableblock {
  border-width: 1px;
  padding: 4px;
  border-style: solid;
  border-color: #527bbd;
}

table.tableblock.frame-topbot {
  border-left-style: hidden;
  border-right-style: hidden;
}
table.tableblock.frame-sides {
  border-top-style: hidden;
  border-bottom-style: hidden;
}
table.tableblock.frame-none {
  border-style: hidden;
}

th.tableblock.halign-left, td.tableblock.halign-left {
  text-align: left;
}
th.tableblock.halign-center, td.tableblock.halign-center {
  text-align: center;
}
th.tableblock.halign-right, td.tableblock.halign-right {
  text-align: right;
}

th.tableblock.valign-top, td.tableblock.valign-top {
  vertical-align: top;
}
th.tableblock.valign-middle, td.tableblock.valign-middle {
  vertical-align: middle;
}
th.tableblock.valign-bottom, td.tableblock.valign-bottom {
  vertical-align: bottom;
}


/*
 * manpage specific
 *
 * */

body.manpage h1 {
  padding-top: 0.5em;
  padding-bottom: 0.5em;
  border-top: 2px solid silver;
  border-bottom: 2px solid silver;
}
body.manpage h2 {
  border-style: none;
}
body.manpage div.sectionbody {
  margin-left: 3em;
}

@media print {
  body.manpage div#toc { display: none; }
}


</style>
<script type="text/javascript">
/*<![CDATA[*/
var asciidoc = {  // Namespace.

/////////////////////////////////////////////////////////////////////
// Table Of Contents generator
/////////////////////////////////////////////////////////////////////

/* Author: Mihai Bazon, September 2002
 * http://students.infoiasi.ro/~mishoo
 *
 * Table Of Content generator
 * Version: 0.4
 *
 * Feel free to use this script under the terms of the GNU General Public
 * License, as long as you do not remove or alter this notice.
 */

 /* modified by Troy D. Hanson, September 2006. License: GPL */
 /* modified by Stuart Rackham, 2006, 2009. License: GPL */

// toclevels = 1..4.
toc: function (toclevels) {

  function getText(el) {
    var text = "";
    for (var i = el.firstChild; i != null; i = i.nextSibling) {
      if (i.nodeType == 3 /* Node.TEXT_NODE */) // IE doesn't speak constants.
        text += i.data;
      else if (i.firstChild != null)
        text += getText(i);
    }
    return text;
  }

  function TocEntry(el, text, toclevel) {
    this.element = el;
    this.text = text;
    this.toclevel = toclevel;
  }

  function tocEntries(el, toclevels) {
    var result = new Array;
    var re = new RegExp('[hH]([1-'+(toclevels+1)+'])');
    // Function that scans the DOM tree for header elements (the DOM2
    // nodeIterator API would be a better technique but not supported by all
    // browsers).
    var iterate = function (el) {
      for (var i = el.firstChild; i != null; i = i.nextSibling) {
        if (i.nodeType == 1 /* Node.ELEMENT_NODE */) {
          var mo = re.exec(i.tagName);
          if (mo && (i.getAttribute("class") || i.getAttribute("className")) != "float") {
            result[result.length] = new TocEntry(i, getText(i), mo[1]-1);
          }
          iterate(i);
        }
      }
    }
    iterate(el);
    return result;
  }

  var toc = document.getElementById("toc");
  if (!toc) {
    return;
  }

  // Delete existing TOC entries in case we're reloading the TOC.
  var tocEntriesToRemove = [];
  var i;
  for (i = 0; i < toc.childNodes.length; i++) {
    var entry = toc.childNodes[i];
    if (entry.nodeName.toLowerCase() == 'div'
     && entry.getAttribute("class")
     && entry.getAttribute("class").match(/^toclevel/))
      tocEntriesToRemove.push(entry);
  }
  for (i = 0; i < tocEntriesToRemove.length; i++) {
    toc.removeChild(tocEntriesToRemove[i]);
  }

  // Rebuild TOC entries.
  var entries = tocEntries(document.getElementById("content"), toclevels);
  for (var i = 0; i < entries.length; ++i) {
    var entry = entries[i];
    if (entry.element.id == "")
      entry.element.id = "_toc_" + i;
    var a = document.createElement("a");
    a.href = "#" + entry.element.id;
    a.appendChild(document.createTextNode(entry.text));
    var div = document.createElement("div");
    div.appendChild(a);
    div.className = "toclevel" + entry.toclevel;
    toc.appendChild(div);
  }
  if (entries.length == 0)
    toc.parentNode.removeChild(toc);
},


/////////////////////////////////////////////////////////////////////
// Footnotes generator
/////////////////////////////////////////////////////////////////////

/* Based on footnote generation code from:
 * http://www.brandspankingnew.net/archive/2005/07/format_footnote.html
 */

footnotes: function () {
  // Delete existing footnote entries in case we're reloading the footnodes.
  var i;
  var noteholder = document.getElementById("footnotes");
  if (!noteholder) {
    return;
  }
  var entriesToRemove = [];
  for (i = 0; i < noteholder.childNodes.length; i++) {
    var entry = noteholder.childNodes[i];
    if (entry.nodeName.toLowerCase() == 'div' && entry.getAttribute("class") == "footnote")
      entriesToRemove.push(entry);
  }
  for (i = 0; i < entriesToRemove.length; i++) {
    noteholder.removeChild(entriesToRemove[i]);
  }

  // Rebuild footnote entries.
  var cont = document.getElementById("content");
  var spans = cont.getElementsByTagName("span");
  var refs = {};
  var n = 0;
  for (i=0; i<spans.length; i++) {
    if (spans[i].className == "footnote") {
      n++;
      var note = spans[i].getAttribute("data-note");
      if (!note) {
        // Use [\s\S] in place of . so multi-line matches work.
        // Because JavaScript has no s (dotall) regex flag.
        note = spans[i].innerHTML.match(/\s*\[([\s\S]*)]\s*/)[1];
        spans[i].innerHTML =
          "[<a id='_footnoteref_" + n + "' href='#_footnote_" + n +
          "' title='View footnote' class='footnote'>" + n + "</a>]";
        spans[i].setAttribute("data-note", note);
      }
      noteholder.innerHTML +=
        "<div class='footnote' id='_footnote_" + n + "'>" +
        "<a href='#_footnoteref_" + n + "' title='Return to text'>" +
        n + "</a>. " + note + "</div>";
      var id =spans[i].getAttribute("id");
      if (id != null) refs["#"+id] = n;
    }
  }
  if (n == 0)
    noteholder.parentNode.removeChild(noteholder);
  else {
    // Process footnoterefs.
    for (i=0; i<spans.length; i++) {
      if (spans[i].className == "footnoteref") {
        var href = spans[i].getElementsByTagName("a")[0].getAttribute("href");
        href = href.match(/#.*/)[0];  // Because IE return full URL.
        n = refs[href];
        spans[i].innerHTML =
          "[<a href='#_footnote_" + n +
          "' title='View footnote' class='footnote'>" + n + "</a>]";
      }
    }
  }
},

install: function(toclevels) {
  var timerId;

  function reinstall() {
    asciidoc.footnotes();
    if (toclevels) {
      asciidoc.toc(toclevels);
    }
  }

  function reinstallAndRemoveTimer() {
    clearInterval(timerId);
    reinstall();
  }

  timerId = setInterval(reinstall, 500);
  if (document.addEventListener)
    document.addEventListener("DOMContentLoaded", reinstallAndRemoveTimer, false);
  else
    window.onload = reinstallAndRemoveTimer;
}

}
asciidoc.install(2);
/*]]>*/
</script>
</head>
<body class="article">
<div id="header">
<h1>productcomposer</h1>
<div id="toc">
  <div id="toctitle">Table of Contents</div>
  <noscript><p><b>JavaScript must be enabled in your browser to display the table of contents.</b></p></noscript>
</div>
</div>
<div id="content">
<div class="sect1">
<h2 id="_goals">1. Goals</h2>
<div class="sectionbody">
<div class="paragraph"><p>A lightweight successor for product builder.</p></div>
<div class="paragraph"><p>It is used to generate product RPM repositories out of a pool of RPMs.
Unlike product builder, these can also be used to ship maintenance updates.</p></div>
<div class="ulist"><div class="title">Currently it supports:</div><ul>
<li>
<p>
processing based on a list of RPM package names.
  product compose is currently not taking care of dependencies.
</p>
</li>
<li>
<p>
providing matching source and/or debug packages for picked RPM packages.
  These can be either included into main repository or prepared via
  extra repositories
</p>
</li>
<li>
<p>
optional filters for architectures, versions and flavors can be defined
</p>
</li>
<li>
<p>
it can provide either just a single RPM of a given name or all of them
</p>
</li>
<li>
<p>
it can post process updateinfo data
</p>
</li>
<li>
<p>
post processing to provide various types of RPM meta data generation
</p>
</li>
</ul></div>
<div class="paragraph"><p>Not yet implemented:
- create bootable iso files</p></div>
</div>
</div>
<div class="sect1">
<h2 id="_design">2. Design</h2>
<div class="sectionbody">
<div class="paragraph"><p>product composer is supposed to be used only inside of OBS builds atm.
OBS or osc is preparing all binary RPM candidates in local directory
before starting the build.</p></div>
</div>
</div>
<div class="sect1">
<h2 id="_setup_in_obs">3. Setup in OBS</h2>
<div class="sectionbody">
<div class="paragraph"><p>You will require OBS 2.11 or later.</p></div>
<div class="ulist"><div class="title">Create a new repository with any name. Either in a new or existing project.</div><ul>
<li>
<p>
The product-composer package must be available in any repository
  listed in the path elements.
</p>
</li>
<li>
<p>
All scheduler architectures where packages are taken from must be listed.
</p>
</li>
</ul></div>
<div class="paragraph"><p>Your build description file may have any name, but must have a .productcompose
suffix.</p></div>
<div class="paragraph"><p>The build type for the repository must be set to</p></div>
<div class="literalblock">
<div class="content">
<pre><code>Type: productcompose</code></pre>
</div></div>
<div class="paragraph"><p>in the build configuration (aka prjconf).</p></div>
</div>
</div>
<div class="sect1">
<h2 id="_special_setup_for_maintenance">4. Special setup for maintenance</h2>
<div class="sectionbody">
<div class="paragraph"><p>Ensure to build your patchinfo builds in a repository where "local" is the first
architecture.</p></div>
<div class="paragraph"><p>Your productcompose file may provide all versions of each RPM if you enable
"take_all_available_versions" in the build options.</p></div>
</div>
</div>
<div class="sect1">
<h2 id="_productcompose_build_description_options">5. productcompose build description options</h2>
<div class="sectionbody">
<div class="sect2">
<h3 id="_minimal_version">5.1. minimal version</h3>
<div class="literalblock">
<div class="content">
<pre><code>product_compose_schema: 0.2
vendor: I_and_myself
name: my_product
version: 1.0
product-type: module</code></pre>
</div></div>
<div class="literalblock">
<div class="content">
<pre><code>architectures: [ x86_64 ]</code></pre>
</div></div>
<div class="literalblock">
<div class="content">
<pre><code>packages:
 - my-single-rpm-package</code></pre>
</div></div>
</div>
<div class="sect2">
<h3 id="_build_options">5.2. build options</h3>
<div class="paragraph"><p>The build options may be used to change the behaviour of the build
process. The options are described in the details below.</p></div>
<div class="paragraph"><p>Just add them to enable the desired functionality, no further
arguments are allowed.</p></div>
</div>
<div class="sect2">
<h3 id="_flavors">5.3. flavors</h3>
<div class="paragraph"><p>Flavors can be defined with any name. These can be
used to build multiple media from one build description.</p></div>
<div class="paragraph"><p>Each flavor may define an own architecture list.</p></div>
<div class="paragraph"><p>It can also be used to add different package sets.</p></div>
<div class="paragraph"><p>You need to add a _multibuild file to your sources
to enable the build.</p></div>
</div>
<div class="sect2">
<h3 id="_iso">5.4. iso</h3>
<div class="paragraph"><p>Enables iso file generation and requires configuration of
iso9660 headers.</p></div>
</div>
<div class="sect2">
<h3 id="_content">5.5. content</h3>
<div class="paragraph"><p>content defines the packagesets to be used as entry
point for the medium.</p></div>
<div class="paragraph"><p>The default is just to use the "main" packageset.</p></div>
</div>
<div class="sect2">
<h3 id="_unpack">5.6. unpack</h3>
<div class="paragraph"><p>unpack defines the packagesets to be used for extracting
the content of the rpm packages directly on the medium.</p></div>
<div class="paragraph"><p>These rpm packages need to provide these files below</p></div>
<div class="literalblock">
<div class="content">
<pre><code>/usr/lib/skelcd/CD1</code></pre>
</div></div>
<div class="paragraph"><p>Currently it gets only extracted to the first/main medium,
but not on source or debug media.</p></div>
</div>
<div class="sect2">
<h3 id="_packagesets">5.7. packagesets</h3>
<div class="paragraph"><p>The packagesets definitions. A packageset lists rpm names
to be put on the medium.</p></div>
<div class="paragraph"><p>There is usually one master list and in addition there
can be addional optional lists.</p></div>
<div class="paragraph"><p>The additional lists can be filtered by flavors and/or
architectures.</p></div>
<div class="paragraph"><p>The packageset requires at least a packages definition,
but may optionaly also a name, flavors or architectures.</p></div>
<div class="sect3">
<h4 id="_name">5.7.1. name</h4>
<div class="paragraph"><p>Defines the name of the package set. <em>main</em> is the default
name.</p></div>
</div>
<div class="sect3">
<h4 id="_architecture">5.7.2. architecture</h4>
<div class="paragraph"><p>Lists the architectures where the set is to be used. The
default is for all architectures.</p></div>
</div>
<div class="sect3">
<h4 id="_flavor">5.7.3. flavor</h4>
<div class="paragraph"><p>Lists the flavors where the set is to be used. The
default is for all flavors.</p></div>
</div>
<div class="sect3">
<h4 id="_add">5.7.4. add</h4>
<div class="paragraph"><p>Can be used to add further packagesets by specifing
their names.</p></div>
<div class="paragraph"><p>A special packageset called <em><em>all</em></em> will add all
package names local available.</p></div>
</div>
<div class="sect3">
<h4 id="_sub">5.7.5. sub</h4>
<div class="paragraph"><p>Can be used to remove packages from the specified
packageset names.</p></div>
</div>
<div class="sect3">
<h4 id="_intersect">5.7.6. intersect</h4>
<div class="paragraph"><p>Can be used to filter packages with specified package
set lists.</p></div>
</div>
<div class="sect3">
<h4 id="_packages">5.7.7. packages</h4>
<div class="paragraph"><p>Lists all package names to be added. This is just the rpm
name, not the file name.</p></div>
</div>
<div class="sect3">
<h4 id="_supportstatus">5.7.8. supportstatus</h4>
<div class="paragraph"><p>Define support status level for the packages listed in
packages. Valid support levels are l3, l2, unsupported.
However these are handled as strings. If the string starts
with a "=", it overrides any previously set support status
from inherited package sets.</p></div>
</div>
</div>
<div class="sect2">
<h3 id="_details">5.8. Details</h3>
<div class="sect3">
<h4 id="_name_2">5.8.1. name</h4>
<div class="paragraph"><p>The product name.</p></div>
</div>
<div class="sect3">
<h4 id="_version">5.8.2. version</h4>
<div class="paragraph"><p>The product version</p></div>
</div>
<div class="sect3">
<h4 id="_update">5.8.3. update</h4>
<div class="paragraph"><p>Optional update level string for CPE</p></div>
</div>
<div class="sect3">
<h4 id="_edition">5.8.4. edition</h4>
<div class="paragraph"><p>Optional edition string for CPE</p></div>
</div>
<div class="sect3">
<h4 id="_summary">5.8.5. summary</h4>
<div class="paragraph"><p>The product name in explaining words. It will be presented to the
user on overview screens</p></div>
</div>
<div class="sect3">
<h4 id="_product_type">5.8.6. product-type</h4>
<div class="paragraph"><p>Either <em>base</em> for operation systems or <em>module</em> for any product
depending on any existing installation.</p></div>
<div class="paragraph"><p><em>extension</em> is handled as alias for <em>module</em>.</p></div>
</div>
<div class="sect3">
<h4 id="_architectures">5.8.7. architectures</h4>
<div class="paragraph"><p>An array of the master architectures to be put into the repository.
This can be used to build a single repository usable for many
hardware architectures.</p></div>
<div class="paragraph"><p>product composer will automatically fall back to "noarch" packages
if the package is not found natively.</p></div>
<div class="paragraph"><p>Setting a global architecture list is optional, when architectures
are listed for each flavor.</p></div>
</div>
<div class="sect3">
<h4 id="_bcntsynctag">5.8.8. bcntsynctag</h4>
<div class="paragraph"><p>Optionaly defines a bcntsynctag for OBS. OBS will sync the build
counter over all packages in same repository and architecture
according to this tag.</p></div>
</div>
<div class="sect3">
<h4 id="_milestone">5.8.9. milestone</h4>
<div class="paragraph"><p>Optionaly defines a milestone which will be used by OBS at release
time. This can be used to turn candidate builds into a Beta1 for
example</p></div>
</div>
<div class="sect3">
<h4 id="_build_options_2">5.8.10. build_options</h4>
<div class="sect4">
<h5 id="_take_all_available_versions">take_all_available_versions</h5>
<div class="paragraph"><p>By default only "the best" version of each rpm is taken.
Use this switch to put all candidates on the medium.
For example for maintenance repositories.</p></div>
</div>
<div class="sect4">
<h5 id="_obs_unordered_product_repos">OBS_unordered_product_repos</h5>
<div class="paragraph"><p>OBS is by default filtering rpm packages based on the repository
path layering.</p></div>
<div class="paragraph"><p>This switch can be used to disable this behaviour in cases where
a binary from a lower priorisated repository should be used.</p></div>
<div class="paragraph"><p>This can increase the amount of required binaries a lot when
dealing with deep path lists.</p></div>
</div>
<div class="sect4">
<h5 id="_ignore_missing_packages">ignore_missing_packages</h5>
<div class="paragraph"><p>Missing packages lead by default to a build failure.
Use this switch to continue. The missing packages are
still listed in the build log.</p></div>
</div>
<div class="sect4">
<h5 id="_hide_flavor_in_product_directory_name">hide_flavor_in_product_directory_name</h5>
<div class="paragraph"><p>The flavor name is by default part of the directory
name of the build result. This can be disabled,
when each flavor has a different arch list. Otherwise
conflicts can happen.</p></div>
</div>
<div class="sect4">
<h5 id="_add_slsa_provenance">add_slsa_provenance</h5>
<div class="paragraph"><p>Add slsa provenance files for each rpm if available</p></div>
</div>
<div class="sect4">
<h5 id="_abort_on_empty_updateinfo">abort_on_empty_updateinfo</h5>
<div class="paragraph"><p>Existing updateinfo.xml are scanned by default and reduced to
the available package binaries. In case none are found the
update is skipped. Enableing this option leads to a build failure
instead.</p></div>
</div>
<div class="sect4">
<h5 id="_skip_updateinfos">skip_updateinfos</h5>
<div class="paragraph"><p>No updateinfo meta information is added to the media.
This might be required when not using take_all_available_versions,
but building on a former released code base.</p></div>
</div>
<div class="sect4">
<h5 id="_updateinfo_packages_only">updateinfo_packages_only</h5>
<div class="paragraph"><p>Build a pure update repository. Skipping all matching rpms
which are not referenced via an updateinfo.</p></div>
</div>
<div class="sect4">
<h5 id="_base_skip_packages">base_skip_packages</h5>
<div class="paragraph"><p>Controls whether packages should be copied in the <code>/install</code> directory
when using base iso images.</p></div>
<div class="paragraph"><p>Enabling this would result in a simply repacked base image, without
any package copied there.</p></div>
</div>
</div>
<div class="sect3">
<h4 id="_iso_2">5.8.11. iso</h4>
<div class="sect4">
<h5 id="_publisher">publisher</h5>
<div class="paragraph"><p>For setting the iso9660 PUBLISHER header</p></div>
</div>
<div class="sect4">
<h5 id="_vendor_id">vendor_id</h5>
<div class="paragraph"><p>For setting the iso9660 VENDOR_ID header</p></div>
</div>
<div class="sect4">
<h5 id="_tree">tree</h5>
<div class="paragraph"><p>Can be set to "drop" for creating only the iso files.</p></div>
</div>
<div class="sect4">
<h5 id="_base">base</h5>
<div class="paragraph"><p>Can be used to copy the result into a pre generated iso file.
product-composer itself is not creating bootable iso images,
aka installer images. But it can used for example to use iso
images with the agama-installer where it copies the main tree
inside.</p></div>
<div class="paragraph"><p>When defining a base iso name, it is expected that:
 * the image gets provided via an rpm called baseiso-NAME
 * the image is available in the /usr/libexec/base-isos directory
   with the given NAME prefix.</p></div>
<div class="paragraph"><p>product-composer will add the main product tree into /install
directory of this media. The build result will be a single
iso file name with the product name and a .install.iso suffix.</p></div>
<div class="paragraph"><p>Only a single repository per product is usable. In case source
or debug rpm&#8217;s need to be added, they need to be part of the
main repository.</p></div>
</div>
</div>
<div class="sect3">
<h4 id="_installcheck">5.8.12. installcheck</h4>
<div class="paragraph"><p>Runs a repository closure test for each architecture. This will
report any missing dependencies and abort.</p></div>
<div class="sect4">
<h5 id="_ignore_errors">ignore_errors</h5>
<div class="paragraph"><p>For reporting the dependency errors, but ignoring them.</p></div>
</div>
</div>
<div class="sect3">
<h4 id="_debug">5.8.13. debug</h4>
<div class="paragraph"><p>Configure the handling of debuginfo and debugsource rpms.
Use either</p></div>
<div class="literalblock">
<div class="content">
<pre><code>debug: include</code></pre>
</div></div>
<div class="paragraph"><p>to include them or</p></div>
<div class="literalblock">
<div class="content">
<pre><code>debug: drop</code></pre>
</div></div>
<div class="paragraph"><p>to drop all debug packages or</p></div>
<div class="literalblock">
<div class="content">
<pre><code>debug: split</code></pre>
</div></div>
<div class="paragraph"><p>to create a seperate medium mwith -Debug suffix.</p></div>
<div class="paragraph"><p>Missing debug packages will always be ignored.</p></div>
<div class="paragraph"><p>This default setting may get specified per flavor.</p></div>
</div>
<div class="sect3">
<h4 id="_packages_2">5.8.14. packages</h4>
<div class="paragraph"><p>The package list. It can contain either simple name or it can
be extended by a &gt;, &gt;=, =, &lt;, &#8656; operator to specify a
specific version constraint.</p></div>
<div class="paragraph"><p>The syntax for the version is rpm like</p></div>
<div class="literalblock">
<div class="content">
<pre><code>[EPOCH:]VERSION[-RELEASE]</code></pre>
</div></div>
<div class="paragraph"><p>A missing epoch means epoch zero. If the release is missing, it
matches any release.</p></div>
<div class="paragraph"><p>The package list can be valid globally or limited to specific flavors
or architectures.</p></div>
</div>
<div class="sect3">
<h4 id="_product_compose_schema">5.8.15. product_compose_schema</h4>
<div class="paragraph"><p>Defines the level of the yaml syntax.
Please expect incompatible changes at any time atm.</p></div>
<div class="paragraph"><p>This will be used to provide backward compability once
we stabilized.</p></div>
</div>
<div class="sect3">
<h4 id="_product_directory_name">5.8.16. product_directory_name</h4>
<div class="paragraph"><p>Can be used to specify a directory or medium name manually.
The default is "name-version".</p></div>
<div class="paragraph"><p>The directory name will always be suffixed by the architecture
and build number.</p></div>
</div>
<div class="sect3">
<h4 id="_source">5.8.17. source</h4>
<div class="paragraph"><p>Configure the handling of src or nosrc rpms for the picked binaries.
Use either</p></div>
<div class="literalblock">
<div class="content">
<pre><code>source: include</code></pre>
</div></div>
<div class="paragraph"><p>to include all source packages or</p></div>
<div class="literalblock">
<div class="content">
<pre><code>source: drop</code></pre>
</div></div>
<div class="paragraph"><p>to drop all source packages or</p></div>
<div class="literalblock">
<div class="content">
<pre><code>source: split</code></pre>
</div></div>
<div class="paragraph"><p>to create a seperate medium with -Source suffix.</p></div>
<div class="paragraph"><p>A missing source package leads to a build failure unless
the ignore_missing_packages built option is used.</p></div>
<div class="paragraph"><p>This default setting may get specified per flavor.</p></div>
</div>
<div class="sect3">
<h4 id="_repodata">5.8.18. repodata</h4>
<div class="paragraph"><p>Write architecture specific repository meta data into the architecture
specific sub directories. This way a client needs to process less
data. The disadvantage is that different URL&#8217;s need to be handled
per architecture.</p></div>
<div class="literalblock">
<div class="content">
<pre><code>repodata: split</code></pre>
</div></div>
<div class="paragraph"><p>It is also possible to have a main repodata including all architectures
in addition to the architecture splitted ones.</p></div>
<div class="literalblock">
<div class="content">
<pre><code>repodata: all</code></pre>
</div></div>
<div class="paragraph"><p>In absence of the repodata element only the main repodata is created
and includes all architectures.</p></div>
<div class="paragraph"><p>This may get specified per flavor.</p></div>
</div>
<div class="sect3">
<h4 id="_vendor">5.8.19. vendor</h4>
<div class="paragraph"><p>Defines the company responsible for the content. Can be for example
openSUSE or SUSE. It is used by the install stack.</p></div>
</div>
<div class="sect3">
<h4 id="_set_updateinfo_from">5.8.20. set_updateinfo_from</h4>
<div class="paragraph"><p>Can be set to replace the "from" attribute in updateinfo.xml files with a fixed value.
This is shown as patch provider by zypp stack. Otherwise the value stays, OBS is setting
the packager from _patchinfo file here by default.</p></div>
</div>
<div class="sect3">
<h4 id="_set_updateinfo_id_prefix">5.8.21. set_updateinfo_id_prefix</h4>
<div class="paragraph"><p>Sets a fixed prefix to all id&#8217;s of included updateinfo data. It is not adding again
if the prefix exists already.</p></div>
<div class="paragraph"><p>This can be used to have a common identifier for an update for many products, but
still being able to identify the filtering for a specific product.</p></div>
</div>
<div class="sect3">
<h4 id="_block_updates_under_embargo">5.8.22. block_updates_under_embargo</h4>
<div class="paragraph"><p>The current default is to include maintenance updates under embargo. This option can
be set to abort when an embargo date is in future.</p></div>
</div>
</div>
</div>
</div>
</div>
<div id="footnotes"><hr /></div>
<div id="footer">
<div id="footer-text">
Last updated
 2025-05-27 10:43:38 CEST
</div>
</div>
</body>
</html>
0707010000000c000041ed000000000000000000000001684059c400000000000000000000000000000000000000000000001600000000product-composer/docs0707010000000d000081a4000000000000000000000001684059c40000001b000000000000000000000000000000000000002100000000product-composer/etc/config.toml[core]
logging = "WARNING"
0707010000000e000041ed000000000000000000000001684059c400000000000000000000000000000000000000000000001500000000product-composer/etc0707010000000f000081a4000000000000000000000001684059c400000a1e000000000000000000000000000000000000002d00000000product-composer/examples/ftp.productcompose# Our initial schema version. Be prepared that it breaks until we are
# in full production mode
product_compose_schema: 0.2

vendor: openSUSE
name: Tumbleweed
version: 1.0
# update: sp7
product-type: base # or module
# summary is the short product description as available in meta data
summary: openSUSE Tumbleweed

# OBS specials:
# bcntsynctag: MyProductFamily
# milestone: Beta1

# scc data has no effect to the build result, it is just managing data
# for the infrastructure
scc:
  description: >
    openSUSE Tumbleweed is the rolling distribution by the
    openSUSE.org project.
  # family: sl-micro
  # free: false

iso:
  publisher: 'Iggy'
  volume_id: 'Pop'
#  tree: 'drop'
#  base: 'agama-installer'

build_options:
### For maintenance, otherwise only "the best" version of each package is picked:
- take_all_available_versions
# - ignore_missing_packages
# - hide_flavor_in_product_directory_name
# - block_updates_under_embargo
# - add_slsa_provenance
# - skip_updateinfos
# - updateinfo_packages_only
# - base_skip_packages

installcheck:
 - ignore_errors

# Enable collection of source and debug packages. Either "include" it
# on main medium, "drop" it or "split" it away on extra medium.
source: split
debug: drop

# repository meta data is written into arch specific directories
# + smaller size of meta data to be processed by the client
# - different URL's per arch are needed
repodata: split

# The default architecture list. Each of these will be put on the medium.
# It is optional to have a default list, when each flavor defines an
# architecture list. The main package won't be build in that case.
architectures: [x86_64]

# A flavor list, each flavor may change the architecture list
flavors:
  small: {}
  large_arm:
    architectures: [armv7l, aarch64]
    name: Tumbleweed_ARM
    summary: openSUSE Tumbleweed ARM
    edition: arm
    # debug: include
    # source: drop

unpack:
  - unpackset
  - unpackset_powerpc_DVD_only

# packages to be put on the medium
packagesets:
- name: unpackset_powerpc_DVD_only
  flavors:
  - DVD medium
  architectures:
  - ppc64le
  packages:
  - Super-Special-Slideshow-for-DVD_medium-on-ppc64le

- name: unpackset
  packages:
  - skelcd-openSUSE
  - skelcd-openSUSE-installer

- name: 32bit
  architectures:
  - i586
  - i686
  packages:
  - kernel-default-pae

- packages:
  - kernel-default
  # take only glibc packages newer than 2.38-9
  # note: this works like a rpm dependency, i.e. the release part is optional
  # and epochs can be specified with EPOCH: prefix
  - glibc > 2.38-9
  add:
  - 32bit
  supportstatus: l2
07070100000010000041ed000000000000000000000001684059c400000000000000000000000000000000000000000000001a00000000product-composer/examples07070100000011000081a4000000000000000000000001684059c400000366000000000000000000000000000000000000002000000000product-composer/pyproject.toml[project]
name = "productcomposer"
description = "OBS product image creator"

authors = [
    { name = "Adrian Schröter", email = "adrian@suse.de" },
]
license = {text = "GPL-2.0-or-later"}

requires-python = ">=3.11"
dependencies = [
    "rpm",
    "zstandard",
    "pydantic",
    "pyyaml",
]
dynamic = ["version", "readme"]

[project.urls]
"Homepage" = "https://somewhere"

[project.scripts]
productcomposer = "productcomposer.cli:main"

[project.optional-dependencies]
dev = [
    "pytest>=7.3.1,<8",
    "sphinx>=6.2.1,<7",
    "sphinx_rtd_theme>=1.2.1,<2",
]

[build-system]
requires = ["setuptools>=61.0", "setuptools_scm[toml]>=6.2"]
build-backend = "setuptools.build_meta"

[tool.setuptools.dynamic]
version = {attr = "productcomposer.__version__"}
readme = {file = ["README.rst"], content-type = "text/x-rst"}

[tool.setuptools.packages.find]
where = ["src"]
07070100000012000081a4000000000000000000000001684059c40000007a000000000000000000000000000000000000003100000000product-composer/src/productcomposer/__init__.py""" Package for the obs product builder application.

"""
from .__version__ import __version__
from .__main__ import main
07070100000013000081a4000000000000000000000001684059c4000000fa000000000000000000000000000000000000003100000000product-composer/src/productcomposer/__main__.py""" Main application entry point.

    python -m productcomposer  ...

"""


def main():
    """ Execute the application.

    """
    raise NotImplementedError


# Make the script executable.

if __name__ == "__main__":
    raise SystemExit(main())
07070100000014000081a4000000000000000000000001684059c4000002d2000000000000000000000000000000000000003400000000product-composer/src/productcomposer/__version__.py""" Current version of the obs product builder application.

This project uses the Semantic Versioning scheme in conjunction with PEP 0440:

    <https://semver.org/>
    <https://www.python.org/dev/peps/pep-0440>

Major versions introduce significant changes to the API, and backwards
compatibility is not guaranteed. Minor versions are for new features and other
backwards-compatible changes to the API. Patch versions are for bug fixes and
internal code changes that do not affect the API. Development versions are
incomplete states of a release .

Version 0.x should be considered a development version with an unstable API,
and backwards compatibility is not guaranteed for minor versions.

"""
__version__ = "0.0.0"
07070100000015000081a4000000000000000000000001684059c40000006e000000000000000000000000000000000000003500000000product-composer/src/productcomposer/api/__init__.py""" Application commands common to all interfaces.

"""
from .parse import main as parse


__all__ = "parse",
07070100000016000081a4000000000000000000000001684059c4000000ff000000000000000000000000000000000000003200000000product-composer/src/productcomposer/api/parse.py""" Implement the hello command.

"""
from ..core.logger import logger


def main(name="World") -> str:
    """ Execute the command.

    :param name: name to use in greeting
    """
    logger.debug("executing hello command")
    return "Hello, parser!"
07070100000017000041ed000000000000000000000001684059c400000000000000000000000000000000000000000000002900000000product-composer/src/productcomposer/api07070100000018000081a4000000000000000000000001684059c400000330000000000000000000000000000000000000002c00000000product-composer/src/productcomposer/cli.py""" Implementation of the command line interface.

"""

from .core import logger
from .utils.loggerutils import (die)

from . import cliparser
from .dispatcher import dispatch

__all__ = "main",

def main(argv=None) -> int:
    parser = cliparser.build_parser()
    args = parser.parse_args()
    
    filename = args.filename
    if not filename:
        # No subcommand was specified.
        print("No filename")
        parser.print_help()
        die(None)

    dispatch(args)
    
    return 0

if __name__ == "__main__":
    try:
        status = main()
    except Exception as err:
        # Error handler of last resort.
        logger.error(repr(err))
        logger.critical("shutting down due to fatal error")
        raise  # print stack trace
    else:
        raise SystemExit(status)

# vim: sw=4 et
07070100000019000081a4000000000000000000000001684059c400000733000000000000000000000000000000000000003200000000product-composer/src/productcomposer/cliparser.pyfrom argparse import ArgumentParser
from productcomposer.config import DEFAULT_EULADIR

def build_parser():
    parser = ArgumentParser('productcomposer')
    #subparsers = parser.add_subparsers(required=True, help='sub-command help')
    subparsers = parser.add_subparsers(dest="command", required=True,  help='sub-command help')

    # One sub parser for each command
    verify_parser = subparsers.add_parser('verify', help='Verify the build recipe')
    build_parser = subparsers.add_parser('build', help='Run a product build')

    #verify_parser.set_defaults(func=verify)
    #build_parser.set_defaults(func=build)

    # Generic options
    for cmd_parser in (verify_parser, build_parser):
        cmd_parser.add_argument('-f', '--flavor', help='Build a given flavor')
        cmd_parser.add_argument('-v', '--verbose', action='store_true',  help='Enable verbose output')
        cmd_parser.add_argument('--reposdir', action='store',  help='Take packages from this directory')
        cmd_parser.add_argument('filename', default='default.productcompose',  help='Filename of product YAML spec')

    # build command options
    build_parser.add_argument('-r', '--release', default=None,  help='Define a build release counter')
    build_parser.add_argument('--disturl', default=None,  help='Define a disturl')
    build_parser.add_argument('--build-option', action='append', nargs='+', default=[],  help='Set a build option')
    build_parser.add_argument('--vcs', default=None,  help='Define a source repository identifier')
    build_parser.add_argument('--clean', action='store_true',  help='Remove existing output directory first')
    build_parser.add_argument('--euladir', default=DEFAULT_EULADIR, help='Directory containing EULA data')
    build_parser.add_argument('out',  help='Directory to write the result')

    return parser0707010000001a000081a4000000000000000000000001684059c400000182000000000000000000000000000000000000003a00000000product-composer/src/productcomposer/commands/__init__.pyimport importlib
import pkgutil
import sys

COMMANDS = {}

def register(name):
    def decorator(cls):
        COMMANDS[name] = cls
        return cls
    return decorator

def _load_all_commands():
    package = sys.modules[__name__]
    for _, module_name, _ in pkgutil.iter_modules(package.__path__):
        importlib.import_module(f"{__name__}.{module_name}")

_load_all_commands()0707010000001b000081a4000000000000000000000001684059c400000cf9000000000000000000000000000000000000003700000000product-composer/src/productcomposer/commands/build.pyimport os
import shutil

from . import register
from ..parsers.yamlparser import parse_yaml
from ..parsers.supportstatusparser import parse_supportstatus
from ..parsers.eulasparser import parse_eulas
from ..utils.loggerutils import (die, note)
from ..createartifacts.createtree import create_tree
from ..core.Pool import Pool

# hashed via file name
tree_report = {}
# global db for eulas
eulas = {}
# global db for supportstatus
supportstatus = {}
# per package override via supportstatus.txt file
supportstatus_override = {}

@register("build")
class BuildCommand:
    def run(self, args):
        result = self.build(args)

    def get_product_dir(self, yml, flavor, release):
        name = f'{yml["name"]}-{yml["version"]}'
        if yml['product_directory_name']:
            # manual override
            name = yml['product_directory_name']
        if flavor and 'hide_flavor_in_product_directory_name' not in yml['build_options']:
            name += f'-{flavor}'
        if yml['architectures']:
            name += "-" + "-".join([a for a in yml['architectures'] if a != 'local'])
        if release:
            name += f'-Build{release}'
        if '/' in name:
            die("Illegal product name")
        return name

    def build(self, args):
        flavor = None
        global verbose_level

        if args.flavor:
            f = args.flavor.split('.')
            if f[0] != '':
                flavor = f[0]

        if args.verbose:
            verbose_level = 1

        if not args.out:
            die("No output directory given")

        yml = parse_yaml(args.filename, flavor)

        for arg in args.build_option:
            for option in arg:
                yml['build_options'].append(option)

        if not yml['architectures']:
            die(f'No architecture defined for flavor {flavor}')

        directory = os.getcwd()
        if args.filename.startswith('/'):
            directory = os.path.dirname(args.filename)
        reposdir = args.reposdir if args.reposdir else directory + "/repos"

        supportstatus_fn = os.path.join(directory, 'supportstatus.txt')
        if os.path.isfile(supportstatus_fn):
            parse_supportstatus(supportstatus_fn)

        if args.euladir and os.path.isdir(args.euladir):
            parse_eulas(args.euladir, eulas)

        pool = Pool()
        note(f"Scanning: {reposdir}")
        pool.scan(reposdir)

        # clean up blacklisted packages
        for u in sorted(pool.lookup_all_updateinfos()):
            for update in u.root.findall('update'):
                if not update.find('blocked_in_product'):
                    continue

                parent = update.findall('pkglist')[0].findall('collection')[0]
                for pkgentry in parent.findall('package'):
                    name = pkgentry.get('name')
                    epoch = pkgentry.get('epoch')
                    version = pkgentry.get('version')
                    pool.remove_rpms(None, name, '=', epoch, version, None)

        if args.clean and os.path.exists(args.out):
            shutil.rmtree(args.out)

        product_base_dir = self.get_product_dir(yml, flavor, args.release)

        create_tree(args.out, product_base_dir, yml, pool, flavor, tree_report, supportstatus, supportstatus_override, eulas, args.vcs, args.disturl)
0707010000001c000081a4000000000000000000000001684059c40000056d000000000000000000000000000000000000003800000000product-composer/src/productcomposer/commands/verify.pyfrom ..parsers.yamlparser import parse_yaml
from . import register
from ..utils.loggerutils import (die, note)
from ..utils.rpmutils import (create_package_set)
from ..core.Pool import Pool

# global db for eulas
eulas = {}
# global db for supportstatus
supportstatus = {}
# per package override via supportstatus.txt file
supportstatus_override = {}

@register("verify")
class VerifyCommand:
    def run(self, args):
        result = self.verify(args)

    def verify_flavor(self, filename, flavor):
        yml = parse_yaml(filename, flavor)
        if 'architectures' not in yml or not yml['architectures']:
            if flavor:
                die(f'No architecture defined for flavor {flavor}')
            else:
                die('No architecture defined and no flavor.')
        # check package sets
        for arch in yml['architectures']:
            pool = Pool()
            for pkgset_name in yml['content']:
                create_package_set(yml, arch, flavor, pkgset_name, pool=pool)
            for pkgset_name in yml['unpack']:
                create_package_set(yml, arch, flavor, pkgset_name, pool=pool)
        return yml.get('flavors')
        
    def verify(self, args):
        flavors = self.verify_flavor(args.filename, args.flavor)
        if args.flavor == None:
            for flavor in flavors:
                self.verify_flavor(args.filename, flavor)
0707010000001d000041ed000000000000000000000001684059c400000000000000000000000000000000000000000000002e00000000product-composer/src/productcomposer/commands0707010000001e000081a4000000000000000000000001684059c4000000fd000000000000000000000000000000000000002f00000000product-composer/src/productcomposer/config.pyDEFAULT_EULADIR = "/usr/share/doc/packages/eulas"
ET_ENCODING = "unicode"
ISO_PREPARER = "Product Composer - http://www.github.com/openSUSE/product-composer"

# hardcoded defaults for now
chksums_tool = 'sha512sum'

# debug aka verbose
verbose_level = 00707010000001f000081a4000000000000000000000001684059c400001421000000000000000000000000000000000000003500000000product-composer/src/productcomposer/core/Package.py""" Package base class

"""
import os
import re
import rpm
import functools


@functools.total_ordering
class Package:
    def __init__(self, location=None, rpm_ts=None):
        if location is None:
            return
        self.location = location
        h = self._read_rpm_header(rpm_ts=rpm_ts)
        for tag in 'name', 'epoch', 'version', 'release', 'arch', 'sourcerpm', \
                   'buildtime', 'disturl', 'license', 'filesizes', 'filemodes', \
                   'filedevices', 'fileinodes', 'dirindexes', 'basenames', 'dirnames':
            val = h[tag]
            if isinstance(val, bytes):
                val = val.decode('utf-8')
            setattr(self, tag, val)
        if not self.sourcerpm:
            self.arch = 'nosrc' if h['nosource'] or h['nopatch'] else 'src'

    def __eq__(self, other):
        return (self.name, self.evr) == (other.name, other.evr)

    def __lt__(self, other):
        if self.name == other.name:
            return rpm.labelCompare((self.epoch, self.version, self.release), (other.epoch, other.version, other.release)) == -1
        return self.name < other.name

    def __str__(self):
        return self.nevra

    @property
    def evr(self):
        if self.epoch and self.epoch != "0":
            return f"{self.epoch}:{self.version}-{self.release}"
        return f"{self.version}-{self.release}"

    @property
    def nevra(self):
        return f"{self.name}-{self.evr}.{self.arch}"

    @property
    def canonfilename(self):
        return f"{self.name}-{self.version}-{self.release}.{self.arch}.rpm"

    @property
    def provides(self):
        h = self._read_rpm_header()
        if h is None:
            return None
        return [dep.DNEVR()[2:] for dep in rpm.ds(h, 'provides')]

    def _read_rpm_header(self, rpm_ts=None):
        if self.location is None:
            return None
        if rpm_ts is None:
            rpm_ts = rpm.TransactionSet()
            rpm_ts.setVSFlags(rpm._RPMVSF_NOSIGNATURES)
        fd = os.open(self.location, os.O_RDONLY)
        h = rpm_ts.hdrFromFdno(fd)
        os.close(fd)
        return h

    @staticmethod
    def _cpeid_hexdecode(p):
        pout = ''
        while True:
            match = re.match(r'^(.*?)%([0-9a-fA-F][0-9a-fA-F])(.*)', p)
            if not match:
                return pout + p
            pout = pout + match.group(1) + chr(int(match.group(2), 16))
            p = match.group(3)

    @functools.cached_property
    def product_cpeid(self):
        cpeid_prefix = "product-cpeid() = "
        for dep in self.provides:
            if dep.startswith(cpeid_prefix):
                return Package._cpeid_hexdecode(dep[len(cpeid_prefix):])
        return None

    def get_src_package(self):
        if not self.sourcerpm:
            return None
        match = re.match(r'^(.*)-([^-]*)-([^-]*)\.([^\.]*)\.rpm$', self.sourcerpm)
        if not match:
            return None
        srcpkg = Package()
        srcpkg.name = match.group(1)
        srcpkg.epoch = None             # sadly unknown
        srcpkg.version = match.group(2)
        srcpkg.release = match.group(3)
        srcpkg.arch = match.group(4)
        return srcpkg

    def matches(self, arch, name, op, epoch, version, release):
        if name is not None and self.name != name:
            return False
        if arch is not None and self.arch != arch:
            if arch in ('src', 'nosrc') or self.arch != 'noarch':
                return False
        if op is None:
            return True
        # special case a missing release or epoch in the match as labelCompare
        # does not handle it
        tepoch = self.epoch if epoch is not None else None
        trelease = self.release if release is not None else None
        cmp = rpm.labelCompare((tepoch, self.version, trelease), (epoch, version, release))
        if cmp > 0:
            return '>' in op
        if cmp < 0:
            return '<' in op
        return '=' in op

    def get_directories(self):
        h = self._read_rpm_header()
        if h is None:
            return None
        dirs = {}
        filedevs = h['filedevices']
        fileinos= h['fileinodes']
        filesizes = h['filesizes']
        filemodes = h['filemodes']
        dirnames = h['dirnames']
        dirindexes = h['dirindexes']
        basenames = h['basenames']
        if not basenames:
            return dirs
        for basename, dirindex, filesize, filemode, filedev, fileino in zip(basenames, dirindexes, filesizes, filemodes, filedevs, fileinos):
            dirname = dirnames[dirindex]
            if isinstance(basename, bytes):
                basename = basename.decode('utf-8')
            if isinstance(dirname, bytes):
                dirname = dirname.decode('utf-8')
            if dirname != '' and not dirname.endswith('/'):
                dirname += '/'
            if not dirname in dirs:
                dirs[dirname] = []
            cookie = f"{filedev}/{fileino}"
            if (filemode & 0o170000) != 0o100000:
                filesize = 0
            dirs[dirname].append((basename, filesize, cookie))
        return dirs



# vim: sw=4 et
07070100000020000081a4000000000000000000000001684059c4000014e5000000000000000000000000000000000000003700000000product-composer/src/productcomposer/core/PkgSelect.py""" Package selector specification

"""

import re
import rpm


class PkgSelect:
    def __init__(self, spec, supportstatus=None):
        self.supportstatus = supportstatus
        match = re.match(r'([^><=]*)([><=]=?)(.*)', spec.replace(' ', ''))
        if match:
            self.name = match.group(1)
            self.op = match.group(2)
            epoch = '0'
            version = match.group(3)
            release = None
            if ':' in version:
                (epoch, version) = version.split(':', 2)
            if '-' in version:
                (version, release) = version.rsplit('-', 2)
            self.epoch = epoch
            self.version = version
            self.release = release
        else:
            self.name = spec
            self.op = None
            self.epoch = None
            self.version = None
            self.release = None

    def matchespkg(self, arch, pkg):
        return pkg.matches(arch, self.name, self.op, self.epoch, self.version, self.release)

    @staticmethod
    def _sub_ops(op1, op2):
        if '>' in op2:
            op1 = re.sub(r'>', '', op1)
        if '<' in op2:
            op1 = re.sub(r'<', '', op1)
        if '=' in op2:
            op1 = re.sub(r'=', '', op1)
        return op1

    @staticmethod
    def _intersect_ops(op1, op2):
        outop = ''
        if '<' in op1 and '<' in op2:
            outop = outop + '<'
        if '>' in op1 and '>' in op2:
            outop = outop + '>'
        if '=' in op1 and '=' in op2:
            outop = outop + '='
        return outop

    def _cmp_evr(self, other):
        release1 = self.release if self.release is not None else other.release
        release2 = other.release if other.release is not None else self.release
        return rpm.labelCompare((self.epoch, self.version, release1), (other.epoch, other.version, release2))

    def _throw_unsupported_sub(self, other):
        raise RuntimeError(f"unsupported sub operation: {self}, {other}")

    def _throw_unsupported_intersect(self, other):
        raise RuntimeError(f"unsupported intersect operation: {self}, {other}")

    def sub(self, other):
        if self.name != other.name:
            return self
        if other.op is None:
            return None
        if self.op is None:
            out = self.copy()
            out.op = PkgSelect._sub_ops('<=>', other.op)
            return out
        cmp = self._cmp_evr(other)
        if cmp == 0:
            if (self.release is not None and other.release is None) or (other.release is not None and self.release is None):
                self._throw_unsupported_sub(other)
            out = self.copy()
            out.op = PkgSelect._sub_ops(self.op, other.op)
            return out if out.op != '' else None
        elif cmp < 0:
            if '>' in self.op:
                self._throw_unsupported_sub(other)
            return None if '<' in other.op else self
        elif cmp > 0:
            if '<' in self.op:
                self._throw_unsupported_sub(other)
            return None if '>' in other.op else self
        self._throw_unsupported_sub(other)

    def intersect(self, other):
        if self.name != other.name:
            return None
        if other.op is None:
            return self
        if self.op is None:
            return other
        cmp = self._cmp_evr(other)
        if cmp == 0:
            if self.release is not None or other.release is None:
                out = self.copy()
            else:
                out = other.copy()
            out.op = PkgSelect._intersect_ops(self.op, other.op)
            if out.op == '':
                if (self.release is not None and other.release is None) or (other.release is not None and self.release is None):
                    self._throw_unsupported_intersect(other)
                return None
            return out
        elif cmp < 0:
            if '>' in self.op and '<' not in other.op:
                return other
            if '<' in other.op and '>' not in self.op:
                return self
            if '<' not in other.op and '>' not in self.op:
                return None
        elif cmp > 0:
            if '>' in other.op and '<' not in self.op:
                return self
            if '<' in self.op and '>' not in other.op:
                return other
            if '<' not in self.op and '>' not in other.op:
                return None
        self._throw_unsupported_intersect(other)

    def copy(self):
        out = PkgSelect(self.name)
        out.op = self.op
        out.epoch = self.epoch
        out.version = self.version
        out.release = self.release
        out.supportstatus = self.supportstatus
        return out

    def __str__(self):
        if self.op is None:
            return self.name
        evr = self.version
        if self.release is not None:
            evr = evr + '-' + self.release
        if self.epoch and self.epoch != '0':
            evr = self.epoch + ':' + evr
        return self.name + ' ' + self.op + ' ' + evr

    def __hash__(self):
        if self.op:
            return hash((self.name, self.op, self.epoch, self.version, self.release))
        return hash(self.name)

    def __eq__(self, other):
        if self.name != other.name:
            return False
        return str(self) == str(other)

# vim: sw=4 et
07070100000021000081a4000000000000000000000001684059c400000b00000000000000000000000000000000000000003400000000product-composer/src/productcomposer/core/PkgSet.py""" Package selection set

"""

from .PkgSelect import PkgSelect


class PkgSet:
    def __init__(self, name):
        self.name = name
        self.pkgs = []
        self.byname = None
        self.supportstatus = None
        self.override_supportstatus = False

    def _create_byname(self):
        byname = {}
        for sel in self.pkgs:
            name = sel.name
            if name not in byname:
                byname[name] = []
            byname[name].append(sel)
        self.byname = byname

    def _byname(self):
        if self.byname is None:
            self._create_byname()
        return self.byname

    def add_specs(self, specs):
        for spec in specs:
            sel = PkgSelect(spec, supportstatus=self.supportstatus)
            self.pkgs.append(sel)
        self.byname = None

    def add(self, other):
        s1 = set(self)
        for sel in other.pkgs:
            if sel not in s1:
                if self.override_supportstatus or (self.supportstatus is not None and sel.supportstatus is None):
                    sel = sel.copy()
                    sel.supportstatus = self.supportstatus
                self.pkgs.append(sel)
                s1.add(sel)
        self.byname = None

    def sub(self, other):
        otherbyname = other._byname()
        pkgs = []
        for sel in self.pkgs:
            name = sel.name
            if name not in otherbyname:
                pkgs.append(sel)
                continue
            for other_sel in otherbyname[name]:
                if sel is not None:
                    sel = sel.sub(other_sel)
            if sel is not None:
                pkgs.append(sel)
        self.pkgs = pkgs
        self.byname = None

    def intersect(self, other):
        otherbyname = other._byname()
        pkgs = []
        s1 = set()
        pkgs = []
        for sel in self.pkgs:
            name = sel.name
            if name not in otherbyname:
                continue
            for osel in otherbyname[name]:
                isel = sel.intersect(osel)
                if isel and isel not in s1:
                    pkgs.append(isel)
                    s1.add(isel)
        self.pkgs = pkgs
        self.byname = None

    def matchespkg(self, arch, pkg):
        if self.byname is None:
            self._create_byname()
        if pkg.name not in self.byname:
            return False
        for sel in self.byname[pkg.name]:
            if sel.matchespkg(arch, pkg):
                return True
        return False

    def names(self):
        if self.byname is None:
            self._create_byname()
        return set(self.byname.keys())

    def __str__(self):
        return self.name + "(" + ", ".join(str(p) for p in self.pkgs) + ")"

    def __iter__(self):
        return iter(self.pkgs)

# vim: sw=4 et
07070100000022000081a4000000000000000000000001684059c4000009bf000000000000000000000000000000000000003200000000product-composer/src/productcomposer/core/Pool.py""" Pool base class

"""

import os
import rpm

from .Package import Package
from .Updateinfo import Updateinfo


class Pool:
    def __init__(self):
        self.rpms = {}
        self.updateinfos = {}

    def make_rpm(self, location, rpm_ts=None):
        return Package(location, rpm_ts=rpm_ts)

    def make_updateinfo(self, location):
        return Updateinfo(location)

    def add_rpm(self, pkg, origin=None):
        if origin is not None:
            pkg.origin = origin
        name = pkg.name
        if not name in self.rpms:
            self.rpms[name] = []
        self.rpms[name].append(pkg)

    def add_updateinfo(self, uinfo):
        self.updateinfos[uinfo.location] = uinfo

    def scan(self, directory):
        ts = rpm.TransactionSet()
        ts.setVSFlags(rpm._RPMVSF_NOSIGNATURES)

        for dirpath, dirs, files in os.walk(directory):
            reldirpath = os.path.relpath(dirpath, directory)
            for filename in files:
                fname = os.path.join(dirpath, filename)
                if filename.endswith('updateinfo.xml'):
                    uinfo = self.make_updateinfo(fname)
                    self.add_updateinfo(uinfo)
                elif filename.endswith('.rpm'):
                    pkg = self.make_rpm(fname, rpm_ts=ts)
                    self.add_rpm(pkg, os.path.join(reldirpath, filename))

    def lookup_all_rpms(self, arch, name, op=None, epoch=None, version=None, release=None):
        if name not in self.rpms:
            return []
        return [rpm for rpm in self.rpms[name] if rpm.matches(arch, name, op, epoch, version, release)]

    def lookup_rpm(self, arch, name, op=None, epoch=None, version=None, release=None):
        return max(self.lookup_all_rpms(arch, name, op, epoch, version, release), default=None)

    def lookup_all_updateinfos(self):
        return self.updateinfos.values()

    def remove_rpms(self, arch, name, op=None, epoch=None, version=None, release=None):
        if name not in self.rpms:
            return
        self.rpms[name] = [rpm for rpm in self.rpms[name] if not rpm.matches(arch, name, op, epoch, version, release)]

    def names(self, arch=None):
        if arch is None:
            return set(self.rpms.keys())
        names = set()
        for name in self.rpms:
            for pkg in self.rpms[name]:
                if pkg.matches(arch, None, None, None, None, None):
                    names.add(name)
                    break
        return names

# vim: sw=4 et
07070100000023000081a4000000000000000000000001684059c4000001d9000000000000000000000000000000000000003800000000product-composer/src/productcomposer/core/Updateinfo.py""" Updateinfo base class

"""
import functools

from xml.etree import ElementTree as ET


@functools.total_ordering
class Updateinfo:
    def __init__(self, location=None):
        if location is None:
            return
        self.root = ET.parse(location).getroot()
        self.location = location

    def __eq__(self, other):
        return self.location == other.location

    def __lt__(self, other):
        return self.location < other.location

# vim: sw=4 et
07070100000024000081a4000000000000000000000001684059c400000026000000000000000000000000000000000000003600000000product-composer/src/productcomposer/core/__init__.py""" Core implementation package.

"""
07070100000025000081a4000000000000000000000001684059c400000bb3000000000000000000000000000000000000003400000000product-composer/src/productcomposer/core/logger.py""" Global application logging.

All modules use the same global logging object. No messages will be emitted
until the logger is started.

"""
from logging import getLogger, getLoggerClass, setLoggerClass
from logging import Formatter, NullHandler, StreamHandler


__all__ = "logger",


class _Logger(getLoggerClass()):
    """ Message logger.

    """
    LOGFMT = "%(asctime)s;%(levelname)s;%(name)s;%(message)s"

    def __init__(self, name=None):
        """ Initialize this logger.

        Loggers with the same name refer to the same underlying object.
        Names are hierarchical, e.g. 'parent.child' defines a logger that is a
        descendant of 'parent'.

        :param name: logger name (application name by default)
        """
        # With a NullHandler, client code may make logging calls without regard
        # to whether the logger has been started yet. The standard Logger API
        # may be used to add and remove additional handlers, but the
        # NullHandler should always be left in place.
        super().__init__(name or __name__.split(".")[0])
        self.addHandler(NullHandler())  # default to no output

    def start(self, level="WARN", stream=None):
        """ Start logging to a stream.

        Until the logger is started, no messages will be emitted. This applies
        to all loggers with the same name and any child loggers.

        Multiple streams can be logged to by calling start() for each one.
        Calling start() more than once for the same stream will result in
        duplicate records to that stream.

        Messages less than the given priority level will be ignored. The
        default level conforms to the *nix convention that a successful run
        should produce no diagnostic output. Call setLevel() to change the
        logger's priority level after it has been stared. Available levels and
        their suggested meanings:

            DEBUG - output useful for developers
            INFO - trace normal program flow, especially external interactions
            WARN - an abnormal condition was detected that might need attention
            ERROR - an error was detected but execution continued
            CRITICAL - an error was detected and execution was halted

        :param level: logger priority level
        :param stream: output stream (stderr by default)
        """
        self.setLevel(level.upper())
        handler = StreamHandler(stream)
        handler.setFormatter(Formatter(self.LOGFMT))
        handler.setLevel(self.level)
        self.addHandler(handler)

    def stop(self):
        """ Stop logging with this logger.

        """
        for handler in self.handlers[1:]:
            # Remove everything but the NullHandler.
            self.removeHandler(handler)


# Never instantiate a Logger object directly, always use getLogger().
setLoggerClass(_Logger)  # applies to all subsequent getLogger() calls
logger = getLogger(__name__.split(".", 1)[0])  # use application name
07070100000026000041ed000000000000000000000001684059c400000000000000000000000000000000000000000000002a00000000product-composer/src/productcomposer/core07070100000027000081a4000000000000000000000001684059c400000969000000000000000000000000000000000000004700000000product-composer/src/productcomposer/createartifacts/createagamaiso.pyimport os
import shutil
import glob
from ..utils.loggerutils import (note,die)
from ..utils.runhelper import run_helper
from ..utils.cryptoutils import create_sha256_for
from ..config import (verbose_level, ISO_PREPARER)

def create_agama_iso(outdir, isoconf, build_options, pool, workdir, application_id, arch):
    verbose = True if verbose_level > 0 else False
    base = isoconf['base']
    if verbose:
        note(f"Looking for baseiso-{base} rpm on {arch}")
    agama = pool.lookup_rpm(arch, f"baseiso-{base}")
    if not agama:
        die(f"Base iso in baseiso-{base} rpm was not found")
    baseisodir = f"{outdir}/baseiso"
    os.mkdir(baseisodir)
    args = ['unrpm', '-q', agama.location]
    run_helper(args, cwd=baseisodir, failmsg=f"extract {agama.location}", verbose=verbose)
    files = glob.glob(f"usr/libexec/base-isos/{base}*.iso", root_dir=baseisodir)
    if not files:
        die(f"Base iso {base} not found in {agama}")
    if len(files) > 1:
        die(f"Multiple base isos for {base} found in {agama}")
    agamaiso = f"{baseisodir}/{files[0]}"
    if verbose:
        note(f"Found base iso image {agamaiso}")

    # create new iso
    tempdir = f"{outdir}/mksusecd"
    os.mkdir(tempdir)
    if 'base_skip_packages' not in build_options:
        args = ['cp', '-al', workdir, f"{tempdir}/install"]
        run_helper(args, failmsg="add tree to agama image")
    args = ['mksusecd', agamaiso, tempdir, '--create', workdir + '.install.iso']
    # mksusecd would take the volume_id, publisher, application_id, preparer from the agama iso
    args += ['--preparer', ISO_PREPARER]
    if 'publisher' in isoconf and isoconf['publisher'] is not None:
        args += ['--vendor', isoconf['publisher']]
    if 'volume_id' in isoconf and isoconf['volume_id'] is not None:
        args += ['--volume', isoconf['volume_id']]
    args += ['--application', application_id]
    run_helper(args, failmsg="add tree to agama image", verbose=verbose)
    # mksusecd already did a tagmedia call with a sha256 digest
    # cleanup directories
    shutil.rmtree(tempdir)
    shutil.rmtree(baseisodir)
    # just for the bootable image, signature is not yet applied, so ignore that error
    run_helper(['verifymedia', workdir + '.install.iso', '--ignore', 'ISO is signed'], fatal=False, failmsg="verify install.iso")
    # creating .sha256 for iso file
    create_sha256_for(workdir + '.install.iso')
07070100000028000081a4000000000000000000000001684059c400000203000000000000000000000000000000000000004800000000product-composer/src/productcomposer/createartifacts/createappstream.pyimport os

from ..config import verbose_level
from ..utils.runhelper import run_helper

OPENSUSE_APPSTREAM_PROCESS = '/usr/bin/openSUSE-appstream-process'


# Create the main susedata.xml with translations, support, and disk usage information
def create_appstream(rpmdir):
    if not os.path.exists(OPENSUSE_APPSTREAM_PROCESS):
        return

    run_helper(
        [OPENSUSE_APPSTREAM_PROCESS, rpmdir, f'{rpmdir}/repodata'],
        failmsg='adding AppStream meta data',
        verbose=verbose_level > 0,
    )
07070100000029000081a4000000000000000000000001684059c40000028b000000000000000000000000000000000000004b00000000product-composer/src/productcomposer/createartifacts/createchecksumfile.pyimport os
from ..utils.runhelper import run_helper
from ..config import chksums_tool

def create_checksums_file(maindir):
    with open(maindir + '/CHECKSUMS', 'a') as chksums_file:
        for subdir in ('boot', 'EFI', 'docu', 'media.1'):
            if not os.path.exists(maindir + '/' + subdir):
                continue
            for root, dirnames, filenames in os.walk(maindir + '/' + subdir):
                for name in filenames:
                    relname = os.path.relpath(root + '/' + name, maindir)
                    run_helper(
                        [chksums_tool, relname], cwd=maindir, stdout=chksums_file
                    )
0707010000002a000081a4000000000000000000000001684059c400000411000000000000000000000000000000000000004200000000product-composer/src/productcomposer/createartifacts/createiso.py
from ..utils.loggerutils import (note,die)
from ..utils.runhelper import run_helper
from ..config import (verbose_level, ISO_PREPARER)
from ..utils.cryptoutils import create_sha256_for

def create_iso(outdir, isoconf, workdir, application_id):
    verbose = True if verbose_level > 0 else False
    args = ['/usr/bin/mkisofs', '-quiet', '-p', ISO_PREPARER]
    args += ['-r', '-pad', '-f', '-J', '-joliet-long']
    if isoconf['publisher']:
        args += ['-publisher', isoconf['publisher']]
    if isoconf['volume_id']:
        args += ['-V', isoconf['volume_id']]
    args += ['-A', application_id]
    args += ['-o', workdir + '.iso', workdir]
    run_helper(args, cwd=outdir, failmsg="create iso file", verbose=verbose)
    # simple tag media call ... we may add options for pading or triggering media check later
    args = ['tagmedia' , '--digest' , 'sha256', workdir + '.iso']
    run_helper(args, cwd=outdir, failmsg="tagmedia iso file", verbose=verbose)
    # creating .sha256 for iso file
    create_sha256_for(workdir + ".iso")0707010000002b000081a4000000000000000000000001684059c400000244000000000000000000000000000000000000004700000000product-composer/src/productcomposer/createartifacts/createmediadir.pyimport os

def create_media_dir(maindir, vendorstr, identstr, products):
    media1dir = maindir + '/' + 'media.1'
    if not os.path.isdir(media1dir):
        os.mkdir(media1dir)  # we do only support seperate media atm
    with open(media1dir + '/media', 'w') as media_file:
        media_file.write(vendorstr + "\n")
        media_file.write(identstr + "\n")
        media_file.write("1\n")
    if products:
        with open(media1dir + '/products', 'w') as products_file:
            for productname in products:
                products_file.write('/ ' + productname + "\n")0707010000002c000081a4000000000000000000000001684059c4000019d4000000000000000000000000000000000000004a00000000product-composer/src/productcomposer/createartifacts/createsusedataxml.pyimport os
import re
import gettext
from xml.etree import ElementTree as ET
from ..utils.repomdutils import find_primary
from ..utils.loggerutils import (die)
from ..core.Package import Package
from ..config import ET_ENCODING
from ..wrappers import ModifyrepoWrapper


# Get supported translations based on installed packages
def get_package_translation_languages():
    i18ndir = '/usr/share/locale/en_US/LC_MESSAGES'
    p = re.compile('package-translations-(.+).mo')
    languages = set()
    for file in os.listdir(i18ndir):
        m = p.match(file)
        if m:
            languages.add(m.group(1))
    return sorted(list(languages))

def generate_du_data(pkg, maxdepth):
    seen = set()
    dudata_size = {}
    dudata_count = {}
    for dir, filedatas in pkg.get_directories().items():
        size = 0
        count = 0
        for filedata in filedatas:
            (basename, filesize, cookie) = filedata
            if cookie:
                if cookie in seen:
                    next
                seen.add(cookie)
            size += filesize
            count += 1
        if dir == '':
            dir = '/usr/src/packages/'
        dir = '/' + dir.strip('/')
        subdir = ''
        depth = 0
        for comp in dir.split('/'):
            if comp == '' and subdir != '':
                next
            subdir += comp + '/'
            if subdir not in dudata_size:
                dudata_size[subdir] = 0
                dudata_count[subdir] = 0
            dudata_size[subdir] += size
            dudata_count[subdir] += count
            depth += 1
            if depth > maxdepth:
                break
    dudata = []
    for dir, size in sorted(dudata_size.items()):
        dudata.append((dir, size, dudata_count[dir]))
    return dudata

# Create the main susedata.xml with translations, support, and disk usage information
def create_susedata_xml(rpmdir, yml, supportstatus, eulas):
    susedatas = {}
    susedatas_count = {}

    # find translation languages
    languages = get_package_translation_languages()

    # create gettext translator object
    i18ntrans = {}
    for lang in languages:
        i18ntrans[lang] = gettext.translation(f'package-translations-{lang}',
                                              languages=['en_US'])

    primary_fn = find_primary(rpmdir)

    # read compressed primary.xml
    openfunction = None
    if primary_fn.endswith('.gz'):
        import gzip
        openfunction = gzip.open
    elif primary_fn.endswith('.zst'):
        import zstandard
        openfunction = zstandard.open
    else:
        die(f"unsupported primary compression type ({primary_fn})")
    tree = ET.parse(openfunction(primary_fn, 'rb'))
    ns = '{http://linux.duke.edu/metadata/common}'

    # Create main susedata structure
    susedatas[''] = ET.Element('susedata')
    susedatas_count[''] = 0

    # go for every rpm file of the repo via the primary
    for pkg in tree.findall(f".//{ns}package[@type='rpm']"):
        name = pkg.find(f'{ns}name').text
        arch = pkg.find(f'{ns}arch').text
        pkgid = pkg.find(f'{ns}checksum').text
        version = pkg.find(f'{ns}version').attrib

        susedatas_count[''] += 1
        package = ET.SubElement(susedatas[''], 'package', {'name': name, 'arch': arch, 'pkgid': pkgid})
        ET.SubElement(package, 'version', version)

        # add supportstatus
        if name in supportstatus and supportstatus[name] is not None:
            ET.SubElement(package, 'keyword').text = f'support_{supportstatus[name]}'

        # add disk usage data
        location = pkg.find(f'{ns}location').get('href')
        if os.path.exists(rpmdir + '/' + location):
            p = Package()
            p.location = rpmdir + '/' + location
            dudata = generate_du_data(p, 3)
            if dudata:
                duelement = ET.SubElement(package, 'diskusage')
                dirselement = ET.SubElement(duelement, 'dirs')
                for duitem in dudata:
                    ET.SubElement(dirselement, 'dir', {'name': duitem[0], 'size': str(duitem[1]), 'count': str(duitem[2])})

        # add eula
        eula = eulas.get(name)
        if eula:
            ET.SubElement(package, 'eula').text = eula

        # get summary/description/category of the package
        summary = pkg.find(f'{ns}summary').text
        description = pkg.find(f'{ns}description').text
        category = pkg.find(".//{http://linux.duke.edu/metadata/rpm}entry[@name='pattern-category()']")
        category = Package._cpeid_hexdecode(category.get('ver')) if category else None

        # look for translations
        for lang in languages:
            isummary = i18ntrans[lang].gettext(summary)
            idescription = i18ntrans[lang].gettext(description)
            icategory = i18ntrans[lang].gettext(category) if category is not None else None
            ieula = eulas.get(name + '.' + lang, eula) if eula is not None else None
            if isummary == summary and idescription == description and icategory == category and ieula == eula:
                continue
            if lang not in susedatas:
                susedatas[lang] = ET.Element('susedata')
                susedatas_count[lang] = 0
            susedatas_count[lang] += 1
            ipackage = ET.SubElement(susedatas[lang], 'package', {'name': name, 'arch': arch, 'pkgid': pkgid})
            ET.SubElement(ipackage, 'version', version)
            if isummary != summary:
                ET.SubElement(ipackage, 'summary', {'lang': lang}).text = isummary
            if idescription != description:
                ET.SubElement(ipackage, 'description', {'lang': lang}).text = idescription
            if icategory != category:
                ET.SubElement(ipackage, 'category', {'lang': lang}).text = icategory
            if ieula != eula:
                ET.SubElement(ipackage, 'eula', {'lang': lang}).text = ieula

    # write all susedata files
    for lang, susedata in sorted(susedatas.items()):
        susedata.set('xmlns', 'http://linux.duke.edu/metadata/susedata')
        susedata.set('packages', str(susedatas_count[lang]))
        ET.indent(susedata, space="    ", level=0)
        mdtype = (f'susedata.{lang}' if lang else 'susedata')
        susedata_fn = f'{rpmdir}/{mdtype}.xml'
        with open(susedata_fn, 'x') as sd_file:
            sd_file.write(ET.tostring(susedata, encoding=ET_ENCODING))
        mr = ModifyrepoWrapper(
            file=susedata_fn,
            mdtype=mdtype,
            directory=os.path.join(rpmdir, "repodata"),
        )
        mr.run_cmd()
        os.unlink(susedata_fn)
0707010000002d000081a4000000000000000000000001684059c400002c1d000000000000000000000000000000000000004300000000product-composer/src/productcomposer/createartifacts/createtree.pyimport os
import re
import shutil
from ..utils.runhelper import run_helper
from ..utils.loggerutils import (die, warn, note)
from ..utils.rpmutils import (link_rpms_to_tree, unpack_meta_rpms)
from ..utils.runcreaterepo import run_createrepo
from ..createartifacts.createmediadir import create_media_dir
from ..createartifacts.createchecksumfile import create_checksums_file
from ..createartifacts.createsusedataxml import create_susedata_xml
from ..createartifacts.createappstream import create_appstream
from ..createartifacts.createupdateinfoxml import create_updateinfo_xml
from ..createartifacts.createagamaiso import create_agama_iso
from ..createartifacts.createiso import create_iso
from ..utils.report import (write_report_file)
from ..utils.repomdutils import find_primary
from ..wrappers import ModifyrepoWrapper

def create_tree(outdir, product_base_dir, yml, pool, flavor, tree_report, supporstatus, supportstatus_override, eulas, vcs=None, disturl=None):
    if not os.path.exists(outdir):
        os.mkdir(outdir)

    maindir = outdir + '/' + product_base_dir
    if not os.path.exists(maindir):
        os.mkdir(maindir)

    workdirectories = [maindir]
    debugdir = sourcedir = None

    if yml['source']:
        match yml['source']:
            case 'split':
                sourcedir = outdir + '/' + product_base_dir + '-Source'
                os.mkdir(sourcedir)
                workdirectories.append(sourcedir)
            case 'include':
                sourcedir = maindir
            case 'drop':
                pass
            case _:
                die("Bad source option, must be either 'include', 'split' or 'drop'")

    if yml['debug']:
        match yml['debug']:
            case 'split':
                debugdir = outdir + '/' + product_base_dir + '-Debug'
                os.mkdir(debugdir)
                workdirectories.append(debugdir)
            case 'include':
                debugdir = maindir
            case 'drop':
                pass
            case _:
                die("Bad debug option, must be either 'include', 'split' or 'drop'")

    for arch in yml['architectures']:
        note(f"Linking rpms for {arch}")
        link_rpms_to_tree(maindir, yml, pool, arch, flavor, tree_report, supporstatus, supportstatus_override, debugdir, sourcedir)

    for arch in yml['architectures']:
        note(f"Unpack rpms for {arch}")
        unpack_meta_rpms(maindir, yml, pool, arch, flavor, medium=1)  # only for first medium am

    repos = []
    if disturl:
        match = re.match("^obs://([^/]*)/([^/]*)/.*", disturl)
        if match:
            obsname = match.group(1)
            project = match.group(2)
            repo = f"obsproduct://{obsname}/{project}/{yml['name']}/{yml['version']}"
            repos = [repo]
    if vcs:
        repos.append(vcs)

    default_content = ["pool"]
    for file in os.listdir(maindir):
        if not file.startswith('gpg-pubkey-'):
            continue

        args = ['gpg', '--no-keyring', '--no-default-keyring', '--with-colons',
              '--import-options', 'show-only', '--import', '--fingerprint']
        out = run_helper(args, stdin=open(f'{maindir}/{file}', 'rb'),
                         failmsg="get fingerprint of gpg file")
        for line in out.splitlines():
            if line.startswith("fpr:"):
                content = f"{file}?fpr={line.split(':')[9]}"
                default_content.append(content)

    note("Create rpm-md data")
    run_createrepo(maindir, yml, content=default_content, repos=repos)
    if debugdir:
        note("Create rpm-md data for debug directory")
        run_createrepo(debugdir, yml, content=["debug"], repos=repos)
    if sourcedir:
        note("Create rpm-md data for source directory")
        run_createrepo(sourcedir, yml, content=["source"], repos=repos)

    repodatadirectories = workdirectories.copy()
    if yml['repodata']:
        if yml['repodata'] != 'all':
            repodatadirectories = []
        for workdir in workdirectories:
            if sourcedir and sourcedir == workdir:
                continue
            for arch in yml['architectures']:
                if os.path.exists(workdir + f"/{arch}"):
                    repodatadirectories.append(workdir + f"/{arch}")

    note("Write report file")
    write_report_file(tree_report, maindir, maindir + '.report')
    if sourcedir and maindir != sourcedir:
        note("Write report file for source directory")
        write_report_file(tree_report, sourcedir, sourcedir + '.report')
    if debugdir and maindir != debugdir:
        note("Write report file for debug directory")
        write_report_file(tree_report, debugdir, debugdir + '.report')

    # CHANGELOG file
    # the tools read the subdirectory of the maindir from environment variable
    os.environ['ROOT_ON_CD'] = '.'
    if os.path.exists("/usr/bin/mk_changelog"):
        args = ["/usr/bin/mk_changelog", maindir]
        run_helper(args)

    # ARCHIVES.gz
    if os.path.exists("/usr/bin/mk_listings"):
        args = ["/usr/bin/mk_listings", maindir]
        run_helper(args)

    # media.X structures FIXME
    mediavendor = yml['vendor'] + ' - ' + product_base_dir
    mediaident = product_base_dir
    # FIXME: calculate from product provides
    mediaproducts = [yml['vendor'] + '-' + yml['name'] + ' ' + str(yml['version']) + '-1']
    create_media_dir(maindir, mediavendor, mediaident, mediaproducts)

    create_checksums_file(maindir)

    for repodatadir in repodatadirectories:
        if os.path.exists(f"{repodatadir}/repodata"):
            create_appstream(repodatadir)
            create_susedata_xml(repodatadir, yml, supporstatus, eulas)

    if yml['installcheck']:
       for arch in yml['architectures']:
           note(f"Run installcheck for {arch}")
           args = ['installcheck', arch, '--withsrc']
           subdir = ""
           if yml['repodata']:
               subdir = f"/{arch}"
           if not os.path.exists(maindir + subdir):
               warn(f"expected path is missing, no rpm files matched? ({maindir}{subdir})")
               continue
           args.append(find_primary(maindir + subdir))
           if debugdir:
               args.append(find_primary(debugdir + subdir))
           run_helper(args, fatal=('ignore_errors' not in yml['installcheck']), failmsg="run installcheck validation")

    if 'skip_updateinfos' not in yml['build_options']:
        create_updateinfo_xml(maindir, yml, pool, flavor, debugdir, sourcedir)

    # Add License File and create extra .license directory
    if yml['iso'] and yml['iso'].get('tree', None) != 'drop':
      licensefilename = '/license.tar'
      if os.path.exists(maindir + '/license-' + yml['name'] + '.tar') or os.path.exists(maindir + '/license-' + yml['name'] + '.tar.gz'):
          licensefilename = '/license-' + yml['name'] + '.tar'
      if os.path.exists(maindir + licensefilename + '.gz'):
          run_helper(['gzip', '-d', maindir + licensefilename + '.gz'],
                     failmsg="uncompress license.tar.gz")
      if os.path.exists(maindir + licensefilename):
          note("Setup .license directory")
          licensedir = maindir + ".license"
          if not os.path.exists(licensedir):
              os.mkdir(licensedir)
          args = ['tar', 'xf', maindir + licensefilename, '-C', licensedir]
          output = run_helper(args, failmsg="extract license tar ball")
          if not os.path.exists(licensedir + "/license.txt"):
              die("No license.txt extracted", details=output)

          mr = ModifyrepoWrapper(
              file=maindir + licensefilename,
              directory=os.path.join(maindir, "repodata"),
          )
          mr.run_cmd()
          os.unlink(maindir + licensefilename)
          # meta package may bring a second file or expanded symlink, so we need clean up
          if os.path.exists(maindir + '/license.tar'):
              os.unlink(maindir + '/license.tar')
          if os.path.exists(maindir + '/license.tar.gz'):
              os.unlink(maindir + '/license.tar.gz')

    for repodatadir in repodatadirectories:
        # detached signature
        args = ['/usr/lib/build/signdummy', '-d', repodatadir + "/repodata/repomd.xml"]
        run_helper(args, failmsg="create detached signature")

        # pubkey
        with open(repodatadir + "/repodata/repomd.xml.key", 'w') as pubkey_file:
            args = ['/usr/lib/build/signdummy', '-p']
            run_helper(args, stdout=pubkey_file, failmsg="write signature public key")

    for workdir in workdirectories:
        if os.path.exists(workdir + '/CHECKSUMS'):
            args = ['/usr/lib/build/signdummy', '-d', workdir + '/CHECKSUMS']
            run_helper(args, failmsg="create detached signature for CHECKSUMS")

        application_id = product_base_dir
        # When using the baseiso feature, the primary media should be
        # the base iso, with the packages added.
        # Other medias/workdirs would then be generated as usual, as
        # presumably you wouldn't need a bootable iso for source and
        # debuginfo packages.
        if yml['iso']:
           if workdir == maindir and yml['iso']['base']:
               agama_arch = yml['architectures'][0]
               note(f"Export main tree into agama iso file for {agama_arch}")
               create_agama_iso(outdir, yml['iso'], yml['build_options'], pool, workdir, application_id, agama_arch)
           else:
               create_iso(outdir, yml['iso'], workdir, application_id);

           # cleanup
           if yml['iso']['tree'] == 'drop':
               shutil.rmtree(workdir)

    # create SBOM data
    generate_sbom_call = None
    if os.path.exists("/usr/lib/build/generate_sbom"):
        generate_sbom_call = ["/usr/lib/build/generate_sbom"]

    # Take sbom generation from OBS server
    # Con: build results are not reproducible
    # Pro: SBOM formats are constant changing, we don't need to adapt always all distributions for that
    if os.path.exists("/.build/generate_sbom"):
        # unfortunatly, it is not exectuable by default
        generate_sbom_call = ['env', 'BUILD_DIR=/.build', 'perl', '/.build/generate_sbom']

    if generate_sbom_call:
        spdx_distro = f"{yml['name']}-{yml['version']}"
        note(f"Creating sboom data for {spdx_distro}")
        # SPDX
        args = generate_sbom_call + [
                 "--format", 'spdx',
                 "--distro", spdx_distro,
                 "--product", maindir
               ]
        with open(maindir + ".spdx.json", 'w') as sbom_file:
            run_helper(args, stdout=sbom_file, failmsg="run generate_sbom for SPDX")

        # CycloneDX
        args = generate_sbom_call + [
                  "--format", 'cyclonedx',
                  "--distro", spdx_distro,
                  "--product", maindir
               ]
        with open(maindir + ".cdx.json", 'w') as sbom_file:
            run_helper(args, stdout=sbom_file, failmsg="run generate_sbom for CycloneDX")

    # cleanup main repodata if wanted and existing
    if yml['repodata'] and yml['repodata'] != 'all':
        for workdir in workdirectories:
            repodatadir = workdir + "/repodata"
            if os.path.exists(repodatadir):
                shutil.rmtree(repodatadir)
0707010000002e000081a4000000000000000000000001684059c400001548000000000000000000000000000000000000004c00000000product-composer/src/productcomposer/createartifacts/createupdateinfoxml.pyimport os
import re
from datetime import datetime
from xml.etree import ElementTree as ET
from ..utils.rpmutils import create_package_set
from ..utils.loggerutils import (note,warn,die)
from ..core.PkgSet import PkgSet
from ..core.Package import Package
from ..wrappers import ModifyrepoWrapper
from ..config import ET_ENCODING

# create a fake package entry from an updateinfo package spec
def create_updateinfo_package(pkgentry):
    entry = Package()
    for tag in ('name', 'epoch', 'version', 'release', 'arch'):
        setattr(entry, tag, pkgentry.get(tag))
    return entry

# Add updateinfo.xml to metadata
def create_updateinfo_xml(rpmdir, yml, pool, flavor, debugdir, sourcedir):
    if not pool.updateinfos:
        return

    missing_package = False

    # build the union of the package sets for all requested architectures

    ### This needs to be kept in sync with src/productcomposer/utils/rpmutils.py
    ### or factored out
    main_pkgset = PkgSet(None)
    for pkgset_name in yml['content']:
        for arch in yml['architectures']:
            main_pkgset.add(create_package_set(yml, arch, flavor, pkgset_name, pool=pool))

    main_pkgset_names = main_pkgset.names()
    ###

    uitemp = None

    for u in sorted(pool.lookup_all_updateinfos()):
        note("Add updateinfo " + u.location)
        for update in u.root.findall('update'):
            needed = False
            parent = update.findall('pkglist')[0].findall('collection')[0]

            # drop OBS internal patchinforef element
            for pr in update.findall('patchinforef'):
                update.remove(pr)

            if 'set_updateinfo_from' in yml:
                update.set('from', yml['set_updateinfo_from'])

            id_node = update.find('id')
            if 'set_updateinfo_id_prefix' in yml:
                # avoid double application of same prefix
                id_text = re.sub(r'^'+yml['set_updateinfo_id_prefix'], '', id_node.text)
                id_node.text = yml['set_updateinfo_id_prefix'] + id_text

            for pkgentry in parent.findall('package'):
                src = pkgentry.get('src')

                # check for embargo date
                embargo = pkgentry.get('embargo_date')
                if embargo is not None:
                    try:
                        embargo_time = datetime.strptime(embargo, '%Y-%m-%d %H:%M')
                    except ValueError:
                        embargo_time = datetime.strptime(embargo, '%Y-%m-%d')

                    if embargo_time > datetime.now():
                        warn(f"Update is still under embargo! {update.find('id').text}")
                        if 'block_updates_under_embargo' in yml['build_options']:
                            die("shutting down due to block_updates_under_embargo flag")

                # clean internal attributes
                for internal_attributes in (
                    'supportstatus',
                    'superseded_by',
                    'embargo_date',
                ):
                    pkgentry.attrib.pop(internal_attributes, None)

                # check if we have files for the entry
                if os.path.exists(rpmdir + '/' + src):
                    needed = True
                    continue
                if debugdir and os.path.exists(debugdir + '/' + src):
                    needed = True
                    continue
                if sourcedir and os.path.exists(sourcedir + '/' + src):
                    needed = True
                    continue
                name = pkgentry.get('name')
                pkgarch = pkgentry.get('arch')

                # do not insist on debuginfo or source packages
                if pkgarch == 'src' or pkgarch == 'nosrc':
                    parent.remove(pkgentry)
                    continue
                if name.endswith('-debuginfo') or name.endswith('-debugsource'):
                    parent.remove(pkgentry)
                    continue
                # ignore unwanted architectures
                if pkgarch != 'noarch' and pkgarch not in yml['architectures']:
                    parent.remove(pkgentry)
                    continue

                # check if we should have this package
                if name in main_pkgset_names:
                    updatepkg = create_updateinfo_package(pkgentry)
                    if main_pkgset.matchespkg(None, updatepkg):
                        warn(f"package {updatepkg} not found")
                        missing_package = True

                parent.remove(pkgentry)

            if not needed:
                if 'abort_on_empty_updateinfo' in yml['build_options']:
                    die(f'Stumbled over an updateinfo.xml where no rpm is used: {id_node.text}')
                continue

            if not uitemp:
                uitemp = open(rpmdir + '/updateinfo.xml', 'x')
                uitemp.write("<updates>\n  ")
            uitemp.write(ET.tostring(update, encoding=ET_ENCODING))

    if uitemp:
        uitemp.write("</updates>\n")
        uitemp.close()

        mr = ModifyrepoWrapper(
                file=os.path.join(rpmdir, "updateinfo.xml"),
                directory=os.path.join(rpmdir, "repodata"),
                )
        mr.run_cmd()

        os.unlink(rpmdir + '/updateinfo.xml')

    if missing_package and 'ignore_missing_packages' not in yml['build_options']:
        die('Abort due to missing packages for updateinfo')
0707010000002f000041ed000000000000000000000001684059c400000000000000000000000000000000000000000000003500000000product-composer/src/productcomposer/createartifacts07070100000030000081a4000000000000000000000001684059c40000015b000000000000000000000000000000000000003100000000product-composer/src/productcomposer/defaults.py"""
Product composer executes programs that have their own defaults.
These defaults rarely change, but if they do, they'll impact product composes.

To avoid such unexpected changes, we define our defaults here
and explicitly pass them to the programs.
"""


CREATEREPO_CHECKSUM_TYPE: str = "sha512"
CREATEREPO_GENERAL_COMPRESS_TYPE: str = "zstd"
07070100000031000081a4000000000000000000000001684059c4000000ec000000000000000000000000000000000000003300000000product-composer/src/productcomposer/dispatcher.pyfrom .commands import COMMANDS

def dispatch(args):
    cmd_class = COMMANDS.get(args.command)
    if not cmd_class:
        raise ValueError(f"Unknown command: {args.command}")
    cmd_instance = cmd_class()
    cmd_instance.run(args)
07070100000032000081a4000000000000000000000001684059c400000196000000000000000000000000000000000000003c00000000product-composer/src/productcomposer/parsers/eulasparser.pyimport os
from ..utils.loggerutils import note

def parse_eulas(euladir, eulas):
    note(f"Reading eula data from {euladir}")
    for dirpath, _, files in os.walk(euladir):
        for filename in files:
            if filename.startswith('.'):
                continue
            pkgname = filename.removesuffix('.en')
            eulas[pkgname] = (Path(dirpath) / filename).read_text(encoding='utf-8')
07070100000033000081a4000000000000000000000001684059c40000016b000000000000000000000000000000000000004400000000product-composer/src/productcomposer/parsers/supportstatusparser.pyfrom ..utils.loggerutils import (warn)

def parse_supportstatus(filename, supportstatus_override):
    with open(filename, 'r') as file:
        for line in file.readlines():
            a = line.strip().split(' ')
            if len(a) == 2:
                supportstatus_override[a[0]] = a[1]
            else:
                warn(f'wrong supportstatus line')
07070100000034000081a4000000000000000000000001684059c4000007e0000000000000000000000000000000000000003b00000000product-composer/src/productcomposer/parsers/yamlparser.pyfrom typing import Dict
import yaml
import pydantic

from ..utils.loggerutils import (die, warn, note)
from ..validators.composeschema import ComposeSchema



def parse_yaml(filename: str, flavor: str | None) -> Dict[str, any]:
    with open(filename, 'r') as file:
        _yml = yaml.safe_load(file)

    # we may not allow this in future anymore, but for now convert these from float to str
    for a in ('product_compose_schema', 'version'):
        if a in _yml:
            _yml[a] = str(_yml[a])

    try:
        model = ComposeSchema(**_yml)
        note(f"Configuration is valid for flavor: {flavor}")
    except pydantic.ValidationError as se:
        warn(f"Configuration is invalid for flavor: {flavor}")
        raise se

    # Use the pydantic validated/converted representation
    yml: Dict[str, Any] = model.dict()

    if flavor:
        if flavor not in yml['flavors']:
            die(f'Flavor not found: {flavor}')
        f = yml['flavors'][flavor]
        # overwrite global values from flavor overwrites
        for tag in (
            'architectures',
            'name',
            'summary',
            'version',
            'update',
            'edition',
            'product_type',
            'product_directory_name',
            'source',
            'debug',
            'repodata',
            'content',
            'unpack',
        ):
            if f.get(tag, None):
                yml[tag] = f[tag]

        # Merge build_options instead of replacing global defined set
        if 'build_options' in f:
            for option in f['build_options']:
                yml['build_options'].append(option)

        if f['iso']:
            for tag in ('volume_id', 'publisher', 'tree', 'base'):
                if f['iso'].get(tag, None):
                    yml['iso'][tag] = f['iso'][tag]

    for tag in (
            'installcheck',
            'unpack',
            'content'
    ):
        if tag in yml and yml[tag] is None:
            yml[tag] = []

    return yml
07070100000035000041ed000000000000000000000001684059c400000000000000000000000000000000000000000000002d00000000product-composer/src/productcomposer/parsers07070100000036000081a4000000000000000000000001684059c400000194000000000000000000000000000000000000003a00000000product-composer/src/productcomposer/utils/cryptoutils.pyfrom pathlib import Path

from .runhelper import run_helper


def create_sha256_for(filename: str) -> None:
    with open(f'{filename}.sha256', 'w') as sha_file:
        # argument must not have the path
        run_helper(
            ['sha256sum', Path(filename).name],
            cwd=Path(filename).parent.absolute(),
            stdout=sha_file,
            failmsg='create .sha256 file',
        )
07070100000037000081a4000000000000000000000001684059c400000108000000000000000000000000000000000000003a00000000product-composer/src/productcomposer/utils/loggerutils.pydef die(msg, details=None):
    if msg:
        print("ERROR: " + msg)
    if details:
        print(details)
    raise SystemExit(1)


def warn(msg, details=None):
    print("WARNING: " + msg)
    if details:
        print(details)

def note(msg):
    print(msg)
07070100000038000081a4000000000000000000000001684059c400000133000000000000000000000000000000000000003a00000000product-composer/src/productcomposer/utils/repomdutils.pyfrom xml.etree import ElementTree as ET

# get the file name from repomd.xml
def find_primary(directory):
    ns = '{http://linux.duke.edu/metadata/repo}'
    tree = ET.parse(directory + '/repodata/repomd.xml')
    return directory + '/' + tree.find(f".//{ns}data[@type='primary']/{ns}location").get('href')07070100000039000081a4000000000000000000000001684059c400000516000000000000000000000000000000000000003500000000product-composer/src/productcomposer/utils/report.pyfrom xml.etree import ElementTree as ET

def add_entry_to_report(tree_report, entry, outname):
    # first one wins, see link_file_into_dir
    if outname not in tree_report:
        tree_report[outname] = entry

def write_report_file(tree_report, directory, outfile):
    root = ET.Element('report')
    if not directory.endswith('/'):
        directory += '/'
    for fn, entry in sorted(tree_report.items()):
        if not fn.startswith(directory):
            continue
        binary = ET.SubElement(root, 'binary')
        binary.text = 'obs://' + entry.origin
        for tag in (
            'name',
            'epoch',
            'version',
            'release',
            'arch',
            'buildtime',
            'disturl',
            'license',
        ):
            val = getattr(entry, tag, None)
            if val is None or val == '':
                continue
            if tag == 'epoch' and val == 0:
                continue
            if tag == 'arch':
                binary.set('binaryarch', str(val))
            else:
                binary.set(tag, str(val))
        if entry.name.endswith('-release'):
            cpeid = entry.product_cpeid
            if cpeid:
                binary.set('cpeid', cpeid)
    tree = ET.ElementTree(root)
    tree.write(outfile)
0707010000003a000081a4000000000000000000000001684059c400002544000000000000000000000000000000000000003700000000product-composer/src/productcomposer/utils/rpmutils.pyimport os
import re
import shutil

from ..core.PkgSet import PkgSet
from ..utils.loggerutils import die, note, warn
from ..utils.report import add_entry_to_report
from ..utils.runhelper import run_helper


def create_package_set_all(setname, pool, arch):
    if pool is None:
        die('need a package pool to create the __all__ package set')
    pkgset = PkgSet(setname)
    pkgset.add_specs([n for n in pool.names(arch) if not (n.endswith('-debuginfo') or n.endswith('-debugsource'))])
    return pkgset

def filter_pkgsets(yml, arch, flavor):
    pkgsets_raw = {}
    for entry in list(yml['packagesets']):
        name = entry['name'] if 'name' in entry else 'main'
        if name not in pkgsets_raw:
            pkgsets_raw[name] = None    # mark as known
        if flavor and entry['flavors'] and flavor not in entry['flavors']:
            continue
        if entry['architectures'] and arch not in entry['architectures']:
            continue
        if pkgsets_raw.get(name):
            die(f'package set {name} is already defined')
        pkgsets_raw[name] = entry
    return pkgsets_raw
    
def create_package_set_cached(yml, arch, flavor, setname, pkgsetcache, pkgsets_rawcache, pool=None):
    if flavor is None:
        flavor = ''

    # process arch/flavor overwrites
    m = re.fullmatch(r'(\S+)(?:\s+architecture=(\S+))?(?:\s+flavor=(\S*))?(?:\s+architecture=(\S+))?\s*', setname)
    if m:
        setname = m[1]
        arch = m[4] or m[2] or arch
        flavor = m[3] or flavor

    if setname == '__all__':
        setkey = f"{setname}/{arch}"
        if not pkgsetcache.get(setkey):
            pkgsetcache[setkey] = create_package_set_all(setname, pool, arch)
        return pkgsetcache[setkey]

    setkey = f"{setname}/{arch}/{flavor}"
    if setkey in pkgsetcache:
        if not pkgsetcache[setkey]:
            die(f"cyclic definition of package set '{setname}'")
        return pkgsetcache[setkey]
    pkgsetcache[setkey] = None  # mark as in progress for cycle detection

    rawcachekey = f"{arch}/{flavor}"
    pkgsets_raw = pkgsets_rawcache.get(rawcachekey)
    if not pkgsets_raw:
        pkgsets_raw = filter_pkgsets(yml, arch, flavor)
        pkgsets_rawcache[rawcachekey] = pkgsets_raw

    if setname not in pkgsets_raw:
        die(f'package set {setname} does not exist')

    pkgset = PkgSet(setname)

    entry = pkgsets_raw.get(setname)
    if not entry:
        pkgsetcache[setkey] = pkgset
        return pkgset    # return empty package set if there is no matching flavor/arch

    if entry['supportstatus']:
        pkgset.supportstatus = entry['supportstatus']
        if pkgset.supportstatus.startswith('='):
            pkgset.override_supportstatus = True
            pkgset.supportstatus = pkgset.supportstatus[1:]
    if entry['packages']:
        pkgset.add_specs(entry['packages'])
    for setop in 'add', 'sub', 'intersect':
        if entry.get(setop) is None:
            continue
        for oname in entry[setop]:
            opkgset = create_package_set_cached(yml, arch, flavor, oname, pkgsetcache, pkgsets_rawcache, pool=pool)
            match setop:
                case 'add':
                    pkgset.add(opkgset)
                case 'sub':
                    pkgset.sub(opkgset)
                case 'intersect':
                    pkgset.intersect(opkgset)
                case _:
                    die(f"unsupported package set operation '{setop}'")
    pkgsetcache[setkey] = pkgset
    return pkgset

def create_package_set(yml, arch, flavor, setname, pool=None):
    return create_package_set_cached(yml, arch, flavor, setname, {}, {}, pool=pool)


def link_file_into_dir(source, directory, name=None):
    if not os.path.exists(directory):
        os.mkdir(directory)
    if name is None:
        name = os.path.basename(source)
    outname = directory + '/' + name
    if not os.path.exists(outname):
        if os.path.islink(source):
            # osc creates a repos/ structure with symlinks to it's cache
            # but these would point outside of our media
            shutil.copyfile(source, outname)
        else:
            os.link(source, outname)


def link_entry_into_dir(tree_report, entry, directory, add_slsa=False):
    canonfilename = entry.canonfilename
    outname = directory + '/' + entry.arch + '/' + canonfilename
    if not os.path.exists(outname):
        link_file_into_dir(entry.location, directory + '/' + entry.arch, name=canonfilename)
        add_entry_to_report(tree_report, entry, outname)
        if add_slsa:
            slsalocation = entry.location.removesuffix('.rpm') + '.slsa_provenance.json'
            if os.path.exists(slsalocation):
                slsaname = canonfilename.removesuffix('.rpm') + '.slsa_provenance.json'
                link_file_into_dir(slsalocation, directory + '/' + entry.arch, name=slsaname)

def unpack_one_meta_rpm(rpmdir, rpm, medium):
    tempdir = rpmdir + "/temp"
    os.mkdir(tempdir)
    run_helper(['unrpm', '-q', rpm.location], cwd=tempdir, failmsg=f"extract {rpm.location}")

    skel_dir = tempdir + "/usr/lib/skelcd/CD" + str(medium)
    if os.path.exists(skel_dir):
        shutil.copytree(skel_dir, rpmdir, dirs_exist_ok=True)
    shutil.rmtree(tempdir)

def unpack_meta_rpms(rpmdir, yml, pool, arch, flavor, medium):
    missing_package = False
    for unpack_pkgset_name in yml.get('unpack', []):
        unpack_pkgset = create_package_set(yml, arch, flavor, unpack_pkgset_name, pool=pool)
        for sel in unpack_pkgset:
            rpm = pool.lookup_rpm(arch, sel.name, sel.op, sel.epoch, sel.version, sel.release)
            if not rpm:
                warn(f"package {sel} not found")
                missing_package = True
                continue
            unpack_one_meta_rpm(rpmdir, rpm, medium)

    if missing_package and 'ignore_missing_packages' not in yml['build_options']:
        die('Abort due to missing meta packages')

def link_rpms_to_tree(rpmdir, yml, pool, arch, flavor, tree_report, supportstatus, supportstatus_override, debugdir=None, sourcedir=None):
    singlemode = True
    if 'take_all_available_versions' in yml['build_options']:
        singlemode = False
    add_slsa = False
    if 'add_slsa_provenance' in yml['build_options']:
        add_slsa = True

    referenced_update_rpms = None
    if 'updateinfo_packages_only' in yml['build_options']:
        if not pool.updateinfos:
            die("filtering for updates enabled, but no updateinfo found")
        if singlemode:
            die("filtering for updates enabled, but take_all_available_versions is not set")

        referenced_update_rpms = {}
        for u in sorted(pool.lookup_all_updateinfos()):
            for update in u.root.findall('update'):
                parent = update.findall('pkglist')[0].findall('collection')[0]
                for pkgentry in parent.findall('package'):
                    referenced_update_rpms[pkgentry.get('src')] = 1

    ### This needs to be kept in sync with src/productcomposer/createartifacts/createupdateinfoxml.py
    ### or factored out
    main_pkgset = PkgSet(None)
    for pkgset_name in yml['content']:
       main_pkgset.add(create_package_set(yml, arch, flavor, pkgset_name, pool=pool))
    ###

    missing_package = None
    for sel in main_pkgset:
        if singlemode:
            rpm = pool.lookup_rpm(arch, sel.name, sel.op, sel.epoch, sel.version, sel.release)
            rpms = [rpm] if rpm else []
        else:
            rpms = pool.lookup_all_rpms(arch, sel.name, sel.op, sel.epoch, sel.version, sel.release)

        if not rpms:
            if referenced_update_rpms is not None:
                continue
            warn(f"package {sel} not found for {arch}")
            missing_package = True
            continue

        for rpm in rpms:
            if referenced_update_rpms is not None:
                if (rpm.arch + '/' + rpm.canonfilename) not in referenced_update_rpms:
                    note(f"No update for {rpm}")
                    continue

            link_entry_into_dir(tree_report, rpm, rpmdir, add_slsa=add_slsa)
            if rpm.name in supportstatus_override:
                supportstatus[rpm.name] = supportstatus_override[rpm.name]
            else:
                supportstatus[rpm.name] = sel.supportstatus

            srcrpm = rpm.get_src_package()
            if not srcrpm:
                warn(f"package {rpm} does not have a source rpm")
                continue

            if sourcedir:
                # so we need to add also the src rpm
                srpm = pool.lookup_rpm(srcrpm.arch, srcrpm.name, '=', None, srcrpm.version, srcrpm.release)
                if srpm:
                    link_entry_into_dir(tree_report, srpm, sourcedir, add_slsa=add_slsa)
                else:
                    warn(f"source rpm package {srcrpm} not found", details=f"         required by  {rpm}")
                    missing_package = True

            if debugdir:
                drpm = pool.lookup_rpm(arch, srcrpm.name + "-debugsource", '=', None, srcrpm.version, srcrpm.release)
                if drpm:
                    link_entry_into_dir(tree_report, drpm, debugdir, add_slsa=add_slsa)

                drpm = pool.lookup_rpm(arch, rpm.name + "-debuginfo", '=', rpm.epoch, rpm.version, rpm.release)
                if drpm:
                    link_entry_into_dir(tree_report, drpm, debugdir, add_slsa=add_slsa)

    if missing_package and 'ignore_missing_packages' not in yml['build_options']:
        die('Abort due to missing packages')
0707010000003b000081a4000000000000000000000001684059c4000005a4000000000000000000000000000000000000003c00000000product-composer/src/productcomposer/utils/runcreaterepo.pyimport os
import subprocess
from ..wrappers import CreaterepoWrapper
from ..utils.loggerutils import (die, warn, note)

def run_createrepo(rpmdir, yml, content=[], repos=[]):
    match yml['product_type']:
        case 'base' | None:
            product_type = '/o'
        case 'module' | 'extension':
            product_type = '/a'
        case _:
            die('Undefined product-type')
    cr = CreaterepoWrapper(directory=".")
    cr.distro = f"{yml.get('summary', yml['name'])} {yml['version']}"
    cr.cpeid = f"cpe:{product_type}:{yml['vendor']}:{yml['name']}:{yml['version']}"
    if yml['update']:
        cr.cpeid = cr.cpeid + f":{yml['update']}"
        if yml['edition']:
            cr.cpeid = cr.cpeid + f":{yml['edition']}"
    elif yml['edition']:
        cr.cpeid = cr.cpeid + f"::{yml['edition']}"
    cr.repos = repos
    # cr.split = True
    # cr.baseurl = "media://"
    cr.content = content
    cr.excludes = ["boot"]
    # default case including all architectures. Unique URL for all of them.
    # we need it in any case at least temporarly
    cr.run_cmd(cwd=rpmdir, stdout=subprocess.PIPE)
    # multiple arch specific meta data set
    if yml['repodata']:
        cr.complete_arch_list = yml['architectures']
        for arch in yml['architectures']:
            if os.path.isdir(f"{rpmdir}/{arch}"):
                cr.arch_specific_repodata = arch
                cr.run_cmd(cwd=rpmdir, stdout=subprocess.PIPE)0707010000003c000081a4000000000000000000000001684059c40000033d000000000000000000000000000000000000003800000000product-composer/src/productcomposer/utils/runhelper.pyimport subprocess
from ..utils.loggerutils import (die, warn, note)

def run_helper(args, cwd=None, fatal=True, stdout=None, stdin=None, failmsg=None, verbose=False):
    if verbose:
        note(f'Calling {args}')
    if stdout is None:
        stdout = subprocess.PIPE
    if stdin is None:
        stdin = subprocess.PIPE
    popen = subprocess.Popen(args, stdout=stdout, stdin=stdin, cwd=cwd)

    output = popen.communicate()[0]
    if isinstance(output, bytes):
        output = output.decode(errors='backslashreplace')

    if popen.returncode:
        if failmsg:
            msg="Failed to " + failmsg
        else:
            msg="Failed to run " + args[0]
        if fatal:
            die(msg, details=output)
        else:
            warn(msg, details=output)
    return output if stdout == subprocess.PIPE else ''0707010000003d000041ed000000000000000000000001684059c400000000000000000000000000000000000000000000002b00000000product-composer/src/productcomposer/utils0707010000003e000081a4000000000000000000000001684059c400000c8e000000000000000000000000000000000000004100000000product-composer/src/productcomposer/validators/composeschema.py"""Schema definition for productcompose files"""

from pydantic import BaseModel, Field

from typing import Literal
from typing import Optional


class compose_schema_iso(BaseModel):
    publisher: Optional[str] = None
    volume_id: Optional[str] = None
    tree: Optional[str] = None
    base: Optional[str] = None


_compose_schema_supportstatus = Literal[
    'l3', 'l2', 'acc', 'unsupported', '=l3', '=l2', '=acc', '=unsupported'
]


class compose_schema_packageset(BaseModel):
    name: Optional[str] = "main"
    supportstatus: Optional[str] = None
    flavors: Optional[list[str]] = None
    architectures: Optional[list[str]] = None
    add: Optional[list[str]] = None
    sub: Optional[list[str]] = None
    intersect: Optional[list[str]] = None
    packages: Optional[list[str]] = None


class compose_schema_scc_cpe(BaseModel):
    cpe: str
    online: Optional[bool] = None


class compose_schema_scc(BaseModel):
    description: Optional[str] = None
    family: Optional[str] = None
    product_class: Optional[str] = Field(default=None, alias='product-class')
    free: Optional[bool] = False
    predecessors: Optional[list[compose_schema_scc_cpe]] = None
    shortname: Optional[str] = None
    base_products: Optional[list[compose_schema_scc_cpe]] = None
    root_products: Optional[list[compose_schema_scc_cpe]] = None
    recommended_for: Optional[list[compose_schema_scc_cpe]] = None
    migration_extra_for: Optional[list[compose_schema_scc_cpe]] = None


compose_schema_build_option = Literal[
    'add_slsa_provenance',
    'base_skip_packages',
    'block_updates_under_embargo',
    'hide_flavor_in_product_directory_name',
    'ignore_missing_packages',
    'skip_updateinfos',
    'take_all_available_versions',
    'updateinfo_packages_only',
]

compose_schema_source_and_debug = Literal['drop', 'include', 'split']
compose_schema_repodata = Literal['all', 'split']

class compose_schema(BaseModel):
    architectures: Optional[list[str]] = []
    name: Optional[str] = None
    version: Optional[str] = None
    edition: Optional[str] = None
    update: Optional[str] = None
    product_type: Optional[str] = Field(default=None, alias='product-type')
    product_directory_name: Optional[str] = None
    content: Optional[list[str]] = ['main']
    unpack: Optional[list[str]] = []
    repodata: Optional[compose_schema_repodata] = None
    summary: Optional[str] = None
    debug: Optional[compose_schema_source_and_debug] = None
    source: Optional[compose_schema_source_and_debug] = None
    build_options: Optional[list[compose_schema_build_option]] = []
    scc: Optional[compose_schema_scc] = None
    iso: Optional[compose_schema_iso] = None

class ComposeSchema(compose_schema, BaseModel):
    product_compose_schema: Literal['0.1', '0.2']
    vendor: str
    bcntsynctag: Optional[str] = None
    milestone: Optional[str] = None
    installcheck: Optional[list[Literal['ignore_errors']]] | None = None

    set_updateinfo_from: Optional[str] = None
    set_updateinfo_id_prefix: Optional[str] = None
    block_updates_under_embargo: Optional[str] = None

    flavors: Optional[dict[str, compose_schema]] = {}
    packagesets: Optional[list[compose_schema_packageset]] = None
0707010000003f000041ed000000000000000000000001684059c400000000000000000000000000000000000000000000003000000000product-composer/src/productcomposer/validators07070100000040000081a4000000000000000000000001684059c400000054000000000000000000000000000000000000003a00000000product-composer/src/productcomposer/wrappers/__init__.pyfrom .createrepo import CreaterepoWrapper
from .modifyrepo import ModifyrepoWrapper
07070100000041000081a4000000000000000000000001684059c40000036a000000000000000000000000000000000000003800000000product-composer/src/productcomposer/wrappers/common.py__all__ = (
    "BaseWrapper",
    "Field",
)


import os
import subprocess
from abc import abstractmethod

from pydantic import BaseModel
from pydantic import Field


class BaseWrapper(BaseModel, validate_assignment=True, extra="forbid"):
    @abstractmethod
    def get_cmd(self) -> list[str]:
        pass

    def run_cmd(self, check=True, stdout=None, stderr=None, cwd=None, env=None) -> subprocess.CompletedProcess:
        cmd = self.get_cmd()

        if env:
            # merge partial user-specified env with os.environ and pass it to the program call
            full_env = os.environ.copy()
            full_env.update(env)
            env = full_env

        return subprocess.run(
            cmd,
            check=check,
            stdout=stdout,
            stderr=stderr,
            cwd=cwd,
            env=env,
            encoding="utf-8",
        )
07070100000042000081a4000000000000000000000001684059c4000007d5000000000000000000000000000000000000003c00000000product-composer/src/productcomposer/wrappers/createrepo.pyfrom .common import *
from .. import defaults


class CreaterepoWrapper(BaseWrapper):
    directory: str = Field()
    baseurl: str | None = Field(default=None)
    checksum_type: str = Field(default=defaults.CREATEREPO_CHECKSUM_TYPE)
    content: list[str] | None = Field(default=None)
    cpeid: str | None = Field(default=None)
    distro: str | None = Field(default=None)
    repos: list[str] | None = Field(default=None)
    excludes: list[str] | None = Field(default=None)
    general_compress_type: str = Field(default=defaults.CREATEREPO_GENERAL_COMPRESS_TYPE)
    split: bool = Field(default=False)
    arch_specific_repodata: str | None = Field(default=None)
    complete_arch_list: list[str] | None = Field(default=None)

    def get_cmd(self):
        cmd = ["createrepo", self.directory]

        cmd.append("--no-database")
        cmd.append("--unique-md-filenames")
        cmd.append(f"--checksum={self.checksum_type}")
        cmd.append(f"--general-compress-type={self.general_compress_type}")

        if self.baseurl:
            cmd.append(f"--baseurl={self.baseurl}")

        if self.content:
            for i in self.content:
                cmd.append(f"--content={i}")

        if self.distro:
            if self.cpeid:
                cmd.append(f"--distro={self.cpeid},{self.distro}")
            else:
                cmd.append(f"--distro={self.distro}")

        if self.excludes:
            for i in self.excludes:
                cmd.append(f"--excludes={i}")

        if self.repos:
            for i in self.repos:
                cmd.append(f"--repo={i}")

        if self.split:
            cmd.append("--split")

        if self.arch_specific_repodata:
            cmd.append("--location-prefix=../")
            cmd.append(f"--outputdir={self.arch_specific_repodata}")
            for exclude in self.complete_arch_list:
                if exclude != self.arch_specific_repodata:
                    cmd.append(f"--excludes=*.{exclude}.rpm")

        return cmd
07070100000043000081a4000000000000000000000001684059c4000003a0000000000000000000000000000000000000003c00000000product-composer/src/productcomposer/wrappers/modifyrepo.pyfrom pydantic.types import DirectoryPath
from pydantic.types import FilePath

from .common import *
from .. import defaults


class ModifyrepoWrapper(BaseWrapper):
    file: FilePath = Field()
    directory: DirectoryPath = Field()
    checksum_type: str = Field(default=defaults.CREATEREPO_CHECKSUM_TYPE)
    compress: bool = Field(default=True)
    compress_type: str = Field(default=defaults.CREATEREPO_GENERAL_COMPRESS_TYPE)
    mdtype: str | None = Field(default=None)

    def get_cmd(self):
        cmd = ["modifyrepo", self.file, self.directory]

        cmd.append("--unique-md-filenames")
        cmd.append(f"--checksum={self.checksum_type}")

        if self.compress:
            cmd.append("--compress")
        else:
            cmd.append("--no-compress")

        cmd.append(f"--compress-type={self.compress_type}")

        if self.mdtype:
            cmd.append(f"--mdtype={self.mdtype}")

        return cmd
07070100000044000041ed000000000000000000000001684059c400000000000000000000000000000000000000000000002e00000000product-composer/src/productcomposer/wrappers07070100000045000041ed000000000000000000000001684059c400000000000000000000000000000000000000000000002500000000product-composer/src/productcomposer07070100000046000041ed000000000000000000000001684059c400000000000000000000000000000000000000000000001500000000product-composer/src07070100000047000081a4000000000000000000000001684059c40000002d000000000000000000000000000000000000002200000000product-composer/tests/.gitignore# Ignore pytest cache files.

.pytest_cache/
07070100000048000081a4000000000000000000000001684059c400000043000000000000000000000000000000000000002900000000product-composer/tests/assets/conf1.tomlstr = "$$str"  # literal `$`, no substitution
var = "${var1}$var2"
07070100000049000081a4000000000000000000000001684059c400000035000000000000000000000000000000000000002900000000product-composer/tests/assets/conf2.tomlvar = "${var1}$var3"  # override `var` in conf1.toml
0707010000004a000081a4000000000000000000000001684059c400001ace000000000000000000000000000000000000003100000000product-composer/tests/assets/eulas/eulaTest1.enLorem ipsum dolor sit amet, consectetur adipiscing elit. Sed est nibh, sodales a lacus non, venenatis pellentesque ante. Morbi mauris felis, interdum et ligula tristique, pellentesque suscipit metus. Quisque eget elementum elit, at posuere mi. Aliquam rutrum in neque laoreet gravida. Suspendisse purus urna, tincidunt in urna sit amet, rutrum laoreet nibh. Maecenas quis volutpat risus. Quisque et bibendum ligula. Mauris at dictum arcu, at placerat nisi. Curabitur eu risus ut justo commodo imperdiet.

Mauris pellentesque metus non velit eleifend lacinia. Curabitur finibus arcu in est egestas, a ornare leo ullamcorper. Nullam et pellentesque velit. Donec efficitur finibus mi, sed vehicula massa ornare in. Proin risus tellus, finibus eu ullamcorper vitae, blandit et purus. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Quisque non consequat lectus. Integer scelerisque commodo odio, at accumsan ligula commodo nec.

Etiam congue nulla sed mi ultricies, a accumsan ante aliquet. Nulla sed tristique dolor. Fusce aliquam metus et ligula aliquam, et convallis leo faucibus. Quisque interdum cursus tellus in scelerisque. Aenean ultrices porta mi, a interdum eros rhoncus at. Quisque nec neque metus. Nullam molestie ut tellus et luctus. Vestibulum tempus enim urna. Etiam augue purus, sagittis nec elit a, vulputate sodales odio. Proin bibendum nisi et augue facilisis interdum eu sed eros. Maecenas placerat sem ac malesuada consequat. Fusce mauris purus, dictum vitae arcu quis, efficitur congue risus.

Aliquam sit amet nibh sit amet quam pretium rutrum vel non mauris. Donec id metus lorem. Aenean sed nisi eros. Mauris blandit nisi ac arcu semper, vel vulputate velit luctus. Aliquam sit amet augue nec turpis ultrices cursus sed id lacus. Proin elementum nunc massa, a maximus quam vestibulum eget. Mauris placerat, mauris a semper pharetra, orci erat pretium leo, vel mattis arcu metus nec eros. Sed et lorem faucibus, ullamcorper tortor nec, eleifend dolor. Vestibulum ornare dolor a tristique dignissim. Cras id accumsan erat. Etiam consectetur, ante eu condimentum scelerisque, sem lacus auctor ex, in congue velit est nec lorem.

Etiam non est non nunc viverra aliquam ac sed turpis. Donec fringilla orci sed felis imperdiet fermentum nec et dolor. In imperdiet nec mauris a lobortis. Donec vitae posuere dolor, non semper mauris. Suspendisse purus ligula, lacinia a tincidunt id, maximus non tellus. Morbi eu convallis risus. Maecenas urna risus, porta nec orci pharetra, venenatis finibus nisi. Praesent nec fermentum ipsum. Vestibulum vehicula sapien diam, et vestibulum felis egestas dapibus. Quisque ultricies, massa eu sollicitudin posuere, felis dui mattis leo, non aliquet arcu erat sed enim. Vestibulum sed velit rutrum, vulputate mauris et, viverra enim. Interdum et malesuada fames ac ante ipsum primis in faucibus. Nam non convallis mauris. Phasellus vulputate, felis id placerat suscipit, massa justo pellentesque ipsum, eu malesuada est arcu sit amet lorem.

Vivamus faucibus et ex in molestie. Mauris vehicula nulla scelerisque metus vulputate, sit amet blandit leo egestas. Nullam lacinia a neque vitae malesuada. Etiam elementum felis et ultrices tempor. Morbi ac feugiat eros. Cras molestie massa non euismod porttitor. Phasellus nisl massa, tempus quis tristique a, tristique condimentum tortor.

Aliquam ut lacus in augue lobortis mattis ut vel risus. Etiam et quam non tellus aliquam venenatis vestibulum et augue. Donec blandit lacus elit, id interdum lacus viverra ut. Fusce eu erat quis nunc pretium varius at eu ante. Donec in leo et dolor volutpat luctus. Aliquam feugiat nunc est, eget eleifend est scelerisque at. In hac habitasse platea dictumst. Aliquam venenatis imperdiet est, quis porta sapien. Etiam et rhoncus est. Vivamus neque lectus, feugiat id velit congue, placerat eleifend erat. Curabitur dapibus, justo a mattis aliquam, odio nulla blandit sem, vel cursus felis ipsum ut mi.

Phasellus nisi odio, hendrerit scelerisque porttitor vel, cursus ornare risus. Quisque commodo ipsum a elit malesuada fermentum ac vitae sem. Curabitur ut egestas enim. Sed vel ullamcorper lacus. Sed suscipit scelerisque porttitor. Ut elit risus, cursus ut ipsum sit amet, commodo posuere mauris. Sed posuere ante non libero eleifend iaculis. Etiam auctor sem augue, sit amet accumsan augue lacinia a. Donec id venenatis velit. Proin a turpis eget diam tempor fringilla. Curabitur vulputate nec lectus eget cursus. Donec semper purus dictum mi tristique, ac condimentum massa consequat. Nunc convallis elit vitae placerat varius.

Proin quis nibh ultricies, laoreet ex eu, tincidunt elit. Donec et quam pharetra, bibendum nibh ac, tristique leo. Curabitur lobortis ultricies tellus, et dapibus ligula. Nullam consequat nunc vitae mi varius laoreet. Fusce pellentesque faucibus ante, sit amet tincidunt metus fermentum sed. Proin euismod pretium ante, vel ultrices nisl tristique sed. Ut ex enim, pulvinar a accumsan sit amet, blandit id turpis.

Cras blandit sit amet sem in ultricies. Quisque malesuada orci in luctus pellentesque. Integer in faucibus arcu, non pellentesque augue. Fusce at erat quis justo lacinia pellentesque eget eu tellus. Suspendisse non velit diam. Maecenas tincidunt tincidunt vestibulum. Donec fermentum augue a dignissim dapibus. Nulla ultricies at mi vel commodo. Suspendisse eget malesuada magna. Nunc eu augue lectus. Phasellus tristique sem id imperdiet ultrices. Praesent et dolor eu enim porta volutpat. Sed nunc arcu, commodo in fringilla a, consectetur eget est. Vestibulum at vehicula ligula, sit amet hendrerit elit. Duis semper ipsum ut nisl posuere lobortis.

Nunc quis metus blandit massa cursus auctor sed eu sapien. Nulla vitae dui eget risus maximus porttitor a a arcu. Sed vulputate maximus augue ut mollis. Vestibulum ac neque eget velit vehicula tincidunt. Donec mollis leo non augue vestibulum, vel efficitur lectus eleifend. Nulla ultricies diam vitae nunc pellentesque pellentesque. Sed sit amet sagittis est. Phasellus tempus tristique metus quis vehicula. Nullam pulvinar elementum nisi vel tempor. Aenean vitae est et sapien laoreet luctus. Sed pellentesque ultricies condimentum. Donec vel rhoncus nibh, et ornare lacus. Aliquam tempor commodo nunc, sed finibus nibh rutrum id. Nam tempus lorem suscipit dolor congue, quis aliquam diam euismod. Duis at diam sed lectus viverra feugiat in ut ipsum. Proin diam orci, dapibus at scelerisque vel, sagittis vel nibh.

Etiam vel volutpat neque. Cras ultrices ligula vitae leo aliquam molestie. Suspendisse potenti. Maecenas at mollis est, eu volutpat orci. Etiam rhoncus lorem tortor, vel mattis justo volutpat ut. Quisque sit amet rutrum est. Ut a volutpat mauris. In nec ligula metus. Fusce in massa purus. Duis vel ante justo. Phasellus blandit erat sit amet nisi cursus tristique.
0707010000004b000081a4000000000000000000000001684059c400001935000000000000000000000000000000000000003100000000product-composer/tests/assets/eulas/eulaTest2.enMaecenas eget orci ornare, suscipit magna sit amet, lobortis neque. Ut nec libero sodales, ultrices orci tristique, elementum orci. Suspendisse dolor augue, sagittis non est vel, sollicitudin tristique massa. In luctus, risus at ornare sollicitudin, sem purus vestibulum lacus, quis blandit lectus ex in eros. Aenean lacinia maximus nisl, eu tristique orci. Nullam consectetur lacinia justo quis lobortis. Vivamus sodales, quam sed convallis fermentum, est ante vestibulum nulla, et condimentum arcu nunc ac enim. Suspendisse aliquet quam dui, a varius tellus semper a. Aenean at gravida magna. Nulla ac lacus venenatis odio aliquet pretium.

Lorem ipsum dolor sit amet, consectetur adipiscing elit. Curabitur varius nisi et dolor aliquam, nec varius tortor porttitor. Morbi tincidunt nunc a orci suscipit, et ultrices dolor pellentesque. Vivamus vitae mi condimentum, lacinia nulla a, luctus arcu. Nulla id purus sit amet nunc scelerisque interdum at efficitur justo. Donec pellentesque rhoncus risus, eget ultrices ligula fringilla et. Vivamus cursus suscipit mi, vitae consequat nulla dapibus eu. Sed eleifend aliquam tellus sit amet iaculis. Sed at mauris tincidunt ligula tristique vehicula. Nunc condimentum egestas felis at condimentum. Vestibulum nec metus ut nulla pharetra pretium tristique sit amet nunc. Curabitur euismod nibh sed neque rutrum egestas. Donec nec mauris vel orci pellentesque facilisis consectetur blandit augue. Nam gravida egestas metus eu vestibulum. Vivamus ultrices augue vitae lacus ultrices, sed tincidunt ligula mattis. Aenean ullamcorper elit nibh, et tristique erat imperdiet nec.

Aenean sit amet tempus nisl, eu accumsan augue. Fusce tristique scelerisque urna sit amet interdum. Aliquam non risus a est hendrerit lobortis. Suspendisse pretium lorem non ex laoreet, nec congue lacus accumsan. Donec a lectus urna. Morbi faucibus varius orci nec faucibus. Sed lobortis mauris ac molestie feugiat. Maecenas eleifend magna in porttitor tincidunt. Suspendisse feugiat nisl nec erat posuere, at feugiat justo semper. Quisque quis dapibus mauris, vel vulputate nisi. Vestibulum convallis diam non magna sagittis consequat.

Integer rhoncus nisi rhoncus nisl volutpat dapibus. Nunc ut laoreet augue. Pellentesque consectetur diam at eros fringilla, vitae scelerisque neque molestie. Vestibulum lorem velit, tristique in nunc at, dignissim tristique sem. Nam porta posuere justo ac fermentum. Nam dignissim risus a est tempus, ut gravida nisi sagittis. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia curae; Pellentesque ornare et lectus non euismod. Donec vulputate molestie odio fermentum condimentum.

Aliquam ut vulputate nisi. Pellentesque porta nisi vitae dui lobortis tincidunt. Morbi et nunc sodales, feugiat mi quis, sollicitudin sapien. Vestibulum eu sem feugiat nisl molestie tempor. Sed finibus, lorem at pulvinar egestas, mauris tellus ullamcorper metus, vel mattis leo leo at enim. Integer gravida dolor quis dolor tempor molestie. Quisque a mauris in magna consequat porta.

Orci varius natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Pellentesque elementum lacinia pharetra. Suspendisse scelerisque lectus lectus. Sed ac lacus elit. Nunc ut libero eleifend, vestibulum orci vel, vestibulum elit. Donec et fermentum tellus, in convallis neque. Morbi et tincidunt nunc. Nullam ornare varius erat, id tempor mi maximus et. Morbi luctus velit quis fringilla pellentesque. Nulla luctus, elit vitae tempor congue, augue odio efficitur urna, ac sodales libero tellus vel neque. Vivamus id cursus lorem, vitae accumsan enim.

Etiam et ipsum eget turpis laoreet vulputate id et ipsum. In rutrum libero id purus dapibus, a volutpat neque pretium. Nunc eu ligula viverra eros malesuada pretium sit amet molestie est. Vivamus interdum ligula vel tempus ultricies. Donec magna lacus, suscipit ac placerat quis, ullamcorper ut ex. Nullam a risus vitae eros egestas rhoncus. Aenean nec fermentum dui, eget suscipit arcu. Pellentesque non nisi quis turpis ultricies mollis ac et libero. Mauris nisi dui, pretium at molestie suscipit, facilisis sit amet turpis. Fusce maximus dapibus congue. Vestibulum suscipit felis diam, nec porttitor massa aliquam et. Integer a elementum odio. Integer id gravida arcu.

Sed tortor arcu, lobortis eu elit et, egestas vulputate justo. Nullam posuere eleifend sagittis. Fusce magna erat, rutrum non rhoncus porttitor, ornare id erat. In lacinia nisi erat, id congue velit vulputate sed. Integer quis eros vitae nisl consectetur gravida quis eu nisl. Orci varius natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Donec dapibus venenatis dui, sit amet bibendum neque tincidunt a. In hac habitasse platea dictumst. In tempor neque sodales, suscipit libero nec, commodo nisi. In nec arcu ut nisl tincidunt molestie in volutpat elit. Aliquam erat volutpat.

Sed lobortis fringilla fringilla. Etiam consectetur ut erat sit amet consequat. Quisque at facilisis purus, et tincidunt orci. Vivamus vestibulum facilisis dolor non feugiat. Ut elementum, justo vitae pellentesque convallis, nulla quam blandit metus, sed finibus mi tellus non massa. Phasellus dictum sagittis volutpat. Integer sit amet malesuada ex. Morbi nulla ligula, laoreet in odio eu, commodo maximus sem. Aliquam neque neque, facilisis id mauris a, bibendum iaculis ligula. Vestibulum blandit, elit quis pellentesque suscipit, risus nisi finibus nisl, vel consectetur nisl libero vel mauris. Ut pretium convallis enim, non mollis nisl luctus sed. Duis eget luctus ligula. Sed rutrum turpis maximus quam cursus, sed tempus lectus malesuada. Vivamus at imperdiet ipsum, eget placerat ante.

Pellentesque ultricies sit amet eros varius elementum. Proin urna ipsum, posuere sed mi vitae, malesuada cursus ipsum. Nulla ultrices urna nulla, sed mollis ligula rutrum in. Aenean in neque ullamcorper, interdum risus in, tincidunt nunc. Donec rhoncus consectetur ipsum, vitae pellentesque neque dignissim vel. Suspendisse mollis ante elit, non rhoncus tortor pulvinar bibendum. Nullam porta erat sit amet dui sollicitudin, eu suscipit mi blandit. Quisque lobortis tincidunt finibus. Nulla sit amet turpis ac augue tempor hendrerit. Aliquam eget orci eros. Sed laoreet, nulla id vulputate hendrerit, dui diam sollicitudin dui, non aliquam magna sem sit amet felis. Morbi eu diam ut nibh tristique vulputate. Nunc eu odio at justo bibendum consequat.


0707010000004c000081a4000000000000000000000001684059c400001690000000000000000000000000000000000000003100000000product-composer/tests/assets/eulas/eulaTest3.enFusce in tellus sed justo rhoncus viverra. Suspendisse egestas, augue vel porttitor imperdiet, metus mauris pharetra velit, at finibus ligula ex vel metus. Morbi sagittis quam vitae placerat ornare. Cras vitae libero tincidunt, dignissim dui sed, sollicitudin neque. Donec congue, libero vel consectetur molestie, lorem enim auctor nisl, pretium placerat eros dolor in leo. Donec tempor est in ante eleifend, varius eleifend dolor consectetur. Nunc ac consectetur ligula. Vestibulum eget volutpat enim, sed porta neque. Aliquam laoreet risus sit amet pulvinar cursus. Sed sed massa arcu. Sed accumsan ultrices est eu tincidunt. Aliquam quam velit, lobortis ut augue id, cursus vehicula mi. Duis tincidunt condimentum sem, et interdum tellus sollicitudin nec. Vivamus vestibulum, eros non ultrices porttitor, turpis odio sodales nisl, quis iaculis augue elit sed elit. Pellentesque rhoncus dolor quis lectus posuere posuere.

Phasellus vitae sodales mauris. Donec sit amet dolor dui. Aliquam quis purus tristique, laoreet turpis vitae, euismod orci. Aliquam sit amet consectetur sapien, eu iaculis dui. Proin congue pharetra nisl in mattis. Vivamus neque ipsum, consectetur sit amet eros quis, aliquet venenatis lectus. Sed et interdum leo. Integer mollis magna ex, ut congue erat eleifend id.

Morbi pulvinar nulla in neque mattis pulvinar. Nam scelerisque condimentum lectus in elementum. Nunc rhoncus semper augue, eget sodales lacus euismod at. Vivamus posuere erat eu enim vulputate, ac laoreet justo sodales. Maecenas fringilla, erat in egestas sodales, est erat bibendum orci, vitae placerat augue ex eget enim. Suspendisse potenti. Mauris aliquet lobortis metus, sed sodales orci commodo eget. Proin finibus massa sapien, vel semper massa tempor a. Maecenas nisl leo, ullamcorper vel vehicula a, vehicula vel nunc. Etiam ac dolor tincidunt, consequat urna eget, eleifend ligula.

Vestibulum non egestas sem. Duis lacus sem, euismod sit amet facilisis nec, scelerisque nec dui. Integer libero augue, cursus id turpis ac, rhoncus dapibus arcu. Ut iaculis, libero vel volutpat fringilla, felis ex vestibulum elit, eu bibendum nisl dolor quis est. Morbi a sodales ipsum, vel efficitur massa. Donec sit amet rhoncus dui. Sed eu efficitur mi. Nullam tincidunt ultrices risus, id consectetur lectus viverra nec. Mauris in condimentum mauris. Nullam molestie erat vitae orci pharetra sagittis. Donec ac interdum nisi, sodales bibendum felis. Etiam vitae velit quis neque viverra vulputate. Sed congue erat magna, ut molestie lorem scelerisque sit amet. Aenean bibendum sem id varius commodo. Nam est nulla, rutrum et turpis eget, blandit congue felis.

Nam fermentum ante tempor leo ullamcorper, ac venenatis urna bibendum. Pellentesque quis aliquam lacus. Sed libero ipsum, facilisis ac aliquet a, convallis at eros. Sed tempor tellus vel dictum mattis. Nullam et eros sodales, elementum metus eget, congue magna. Aenean odio enim, aliquet eu erat molestie, condimentum volutpat massa. Maecenas elementum nisl iaculis orci pharetra tincidunt. Aliquam blandit lectus at turpis finibus aliquam. Donec quis est lectus. Donec ac est molestie, tempus enim a, molestie libero. Proin tellus nibh, auctor id augue nec, faucibus efficitur ante. Duis nec hendrerit libero, at pharetra nisi. Sed ut dolor leo. Nulla dapibus mi sed dolor accumsan, ut fermentum tellus congue. Donec mollis tellus erat, eu ullamcorper magna rutrum id.

Sed vel eros ultrices, tristique eros in, aliquet ante. Ut mollis molestie magna, eu vulputate odio. Ut sodales efficitur ultrices. In luctus id ipsum in scelerisque. Donec a elit erat. Quisque ipsum dui, ultrices varius placerat vel, ultrices eget sapien. Vestibulum enim nisl, blandit non ipsum quis, finibus rutrum odio. Nam varius odio sit amet nisl venenatis, sit amet elementum lorem imperdiet. Morbi sed purus nunc. Proin finibus commodo enim, et dapibus nisl vehicula vel. Nam nec auctor eros. Praesent ut posuere libero. Maecenas auctor maximus odio tincidunt aliquam.

In pharetra bibendum varius. Nunc convallis, magna non posuere posuere, tellus odio imperdiet nulla, non viverra neque sapien porttitor metus. Nam tincidunt ligula ac libero tempus tincidunt. Nullam ultrices imperdiet mollis. In vitae eros lobortis neque commodo volutpat. Proin molestie metus purus, eget ultrices tortor vestibulum sit amet. Proin dictum ex et sem consectetur, commodo auctor mi gravida. Maecenas quis felis vel mi sagittis convallis. Nunc ac venenatis metus, sed hendrerit nisl. Duis euismod, sapien ac suscipit malesuada, massa metus malesuada urna, vitae viverra massa mi at libero. Nam congue pretium mollis. Maecenas ultrices, metus ac cursus interdum, ipsum risus venenatis nibh, quis facilisis odio turpis id tortor. Nam tempus lacus ex, at posuere ex tempor ut.

Curabitur rutrum at lorem ac suscipit. Mauris at leo rutrum, tincidunt sapien quis, cursus nisl. Integer quis tempor lorem, non egestas nisi. Pellentesque hendrerit mi porta eros pellentesque, ac venenatis nisi accumsan. Mauris eget tellus placerat, fermentum diam rhoncus, euismod mi. Morbi ut massa ac dui aliquet fringilla quis quis diam. Quisque tristique posuere elementum. Nullam suscipit eget felis at mattis. Cras scelerisque est eu fringilla tempus. Praesent auctor nisl ante. Donec vitae ligula suscipit, consequat nisi eget, sagittis purus.

Duis massa diam, eleifend non felis sit amet, iaculis aliquam enim. Vestibulum in congue sem. Donec sem odio, suscipit quis sem ut, porta feugiat nibh. Praesent pulvinar nunc vehicula felis scelerisque, ac tincidunt sapien tristique. Morbi sed ante tincidunt, consequat nisl quis, porta magna. Aliquam euismod vehicula posuere. Vivamus ex nunc, cursus at venenatis eget, feugiat eget nulla. Nam a nulla id urna viverra consectetur.
0707010000004d000041ed000000000000000000000001684059c400000000000000000000000000000000000000000000002400000000product-composer/tests/assets/eulas0707010000004e000081a4000000000000000000000001684059c400000038000000000000000000000000000000000000003600000000product-composer/tests/assets/supportstatus-wrong.txtbluez-firmwarel2
dejavu-fontsl2
google-opensans-fontsl2
0707010000004f000081a4000000000000000000000001684059c400000618000000000000000000000000000000000000003000000000product-composer/tests/assets/supportstatus.txtbluez-firmware l2
dejavu-fonts l2
google-opensans-fonts l2
google-poppins-fonts l2
ipw-firmware l2
libxmlsec1-1 l2
patterns-microos-base l2
patterns-microos-basesystem l2
patterns-microos-bootloader l2
patterns-microos-cockpit l2
patterns-microos-container_runtime l2
patterns-microos-defaults l2
patterns-microos-fips l2
patterns-microos-hardware l2
patterns-microos-k3s l2
patterns-microos-kvm_host l2
patterns-microos-salt_minion l2
patterns-microos-selinux l2
patterns-microos-sssd_ldap l2
release-notes-sles l2
sac l2
bluez-firmware l2
dejavu-fonts l2
google-opensans-fonts l2
ipw-firmware l2
libxmlsec1-1 l2
sac l2
fdo-client l2
fdo-client-devel l2
yast2-trans-af l2
yast2-trans-ar l2
yast2-trans-bg l2
yast2-trans-bn l2
yast2-trans-bs l2
yast2-trans-ca l2
yast2-trans-cs l2
yast2-trans-cy l2
yast2-trans-da l2
yast2-trans-de l2
yast2-trans-el l2
yast2-trans-en_GB l2
yast2-trans-es l2
yast2-trans-et l2
yast2-trans-fa l2
yast2-trans-fi l2
yast2-trans-fr l2
yast2-trans-gl l2
yast2-trans-gu l2
yast2-trans-hi l2
yast2-trans-hr l2
yast2-trans-hu l2
yast2-trans-id l2
yast2-trans-it l2
yast2-trans-ja l2
yast2-trans-jv l2
yast2-trans-ka l2
yast2-trans-km l2
yast2-trans-ko l2
yast2-trans-lo l2
yast2-trans-lt l2
yast2-trans-mk l2
yast2-trans-mr l2
yast2-trans-nb l2
yast2-trans-nl l2
yast2-trans-pa l2
yast2-trans-pl l2
yast2-trans-pt_BR l2
yast2-trans-pt l2
yast2-trans-ro l2
yast2-trans-ru l2
yast2-trans-si l2
yast2-trans-sk l2
yast2-trans-sl l2
yast2-trans-sr l2
yast2-trans-sv l2
yast2-trans-ta l2
yast2-trans-th l2
yast2-trans-tr l2
yast2-trans-uk l207070100000050000081a4000000000000000000000001684059c40002a3bc000000000000000000000000000000000000003d00000000product-composer/tests/assets/tomls/Backports.productcomposeproduct_compose_schema: 0.2

vendor: openSUSE
name: Backports
version: 16
product-type: base
summary: openSUSE Backports

scc:
  description: >
    Leap ftp tree, also known as POOL.
    Used for GA and maintenance update afterwards.

build_options:
### For maintenance, otherwise only "the best" version of each package is picked:
# - take_all_available_versions
- hide_flavor_in_product_directory_name

installcheck:
- ignore_errors

source: split
debug: split

# repodata: all = legacy + spllt
# repodata will be presented at root directory and be presented at $ARCH/repodata also
repodata: all

# has only an effect during maintenance:
set_updateinfo_from: maint-coord@suse.de

flavors:
  backports_aarch64:
    architectures: [aarch64]
    name: Backports
    product_directory_name: Backports-16
  backports_ppc64le:
    architectures: [ppc64le]
    name: Backports
    product_directory_name: Backports-16
  backports_s390x:
    architectures: [s390x]
    name: Backports
    product_directory_name: Backports-16
  backports_x86_64:
    architectures: [x86_64]
    name: Backports
    product_directory_name: Backports-16

unpack:
  - unpackset

packagesets:
# TODO: not sure this is needed for Backports, but it was like skelcd-SLES or skelcd-openSUSE
- name: unpackset
  packages:

- name: backports_unneeded
  packages:

# TODO: unneeded Leap package per architecture
- name: backports_unneeded_aarch64
  packages:
  - syslinux-x86_64
  - syslinux-debuginfo-x86_64

- name: backports_unneeded_ppc64le
  packages:
  - syslinux-x86_64
  - syslinux-debuginfo-x86_64

- name: backports_unneeded_s390x
  packages:
  - syslinux-x86_64
  - syslinux-debuginfo-x86_64

- name: backports_unneeded_x86_64
  packages:
  - audit-devel-32bit
  - binutils-devel-32bit
  - bison-32bit
  - gdbm-devel-32bit
  - glibc-32bit
  - glibc-devel-32bit
  - glibc-devel-static-32bit
  - glibc-gconv-modules-extra-32bit
  - glibc-profile-32bit
  - gmp-devel-32bit
  - file-devel-32bit
  - isl-devel-32bit
  - jitterentropy-devel-32bit
  - libacl-devel-32bit
  - libacl1-32bit
  - libasm1-32bit
  - libattr-devel-32bit
  - libattr1-32bit
  - libaudit1-32bit
  - libauparse0-32bit
  - libblkid-devel-32bit
  - libblkid1-32bit
  - libbz2-1-32bit
  - libbz2-devel-32bit
  - libcap2-32bit
  - libcap-ng0-32bit
  - libcrypt1-32bit
  - libdb-4_8-devel-32bit
  - libdb-4_8-32bit
  - libdw1-32bit
  - libeconf0-32bit
  - libedit0-32bit
  - libelf-devel-32bit
  - libelf1-32bit
  - libexpat-devel-32bit
  - libexpat1-32bit
  - libfdisk-devel-32bit
  - libfdisk1-32bit
  - libffi-devel-32bit
  - libffi8-32bit
  - libfipscheck1-32bit
  - libfl-devel-32bit
  - libfl2-32bit
  - libgcrypt-devel-32bit
  - libgcrypt20-32bit
  - libgdbm_compat4-32bit
  - libgdbm6-32bit
  - libgmp10-32bit
  - libgmpxx4-32bit
  - libgpg-error-devel-32bit
  - libgpg-error0-32bit
  - libgpm2-32bit
  - libisl23-32bit
  - libjitterentropy3-32bit
  - libltdl7-32bit
  - liblua5_4-5-32bit
  - liblzma5-32bit
  - libmagic1-32bit
  - libmount-devel-32bit
  - libmount1-32bit
  - libmpc3-32bit
  - libmpdec++3-32bit
  - libmpdec3-32bit
  - libmpfr6-32bit
  - libncurses5-32bit
  - libncurses6-32bit
  - libnss_usrfiles2-32bit
  - libpcre2-8-0-32bit
  - libpcre2-16-0-32bit
  - libpcre2-32-0-32bit
  - libpcre2-posix3-32bit
  - libpopt0-32bit
  - libpsx2-32bit
  - libpython3_13-1_0-32bit
  - libreadline8-32bit
  - libseccomp2-32bit
  - libselinux1-32bit
  - libsemanage2-32bit
  - libsepol2-32bit
  - libsmartcols-devel-32bit
  - libsmartcols1-32bit
  - libtool-32bit
  - libuuid-devel-32bit
  - libuuid1-32bit
  - libuv1-32bit
  - libwrap0-32bit
  - libxcrypt-devel-32bit
  - libzio1-32bit
  - libzstd-devel-32bit
  - libzstd1-32bit
  - mpc-devel-32bit
  - mpdecimal-devel-32bit
  - mpfr-devel-32bit
  - ncurses-devel-32bit
  - ncurses5-devel-32bit
  - pam-32bit
  - pam-devel-32bit
  - perl-32bit
  - perl-base-32bit
  - popt-devel-32bit
  - python313-base-32bit
  - readline-devel-32bit
  - rpm-32bit
  - xz-devel-32bit

# TODO: unneeded SLES package on all architectures
- name: sles_unneeded
  packages:
  - 389-ds
  - 389-ds-devel
  - 389-ds-snmp
  - 7zip
  - AppStream
  - AppStream-compose
  - AppStream-compose-devel
  - AppStream-devel
  - AppStream-doc
  - AppStream-lang
  - Catch2-2-devel
  - Catch2-devel
  - ClusterTools2
  - FastCGI
  - FastCGI-devel
  - ImageMagick
  - ImageMagick-config-7-SUSE
  - ImageMagick-devel
  - ImageMagick-doc
  - ImageMagick-extra
  - Imath-devel
  - Mesa
  - Mesa-KHR-devel
  - Mesa-devel
  - Mesa-dri
  - Mesa-dri-devel
  - Mesa-libEGL-devel
  - Mesa-libEGL1
  - Mesa-libGL-devel
  - Mesa-libGL1
  - Mesa-libGLESv1_CM-devel
  - Mesa-libGLESv2-devel
  - Mesa-libGLESv3-devel
  - Mesa-libglapi-devel
  - Mesa-libglapi0
  - ModemManager
  - ModemManager-bash-completion
  - ModemManager-devel
  - ModemManager-lang
  - MozillaFirefox
  - MozillaFirefox-branding-SLE
  - MozillaFirefox-devel
  - MozillaFirefox-translations-common
  - MozillaFirefox-translations-other
  - NetworkManager
  - NetworkManager-branding-SLE
  - NetworkManager-cloud-setup
  - NetworkManager-devel
  - NetworkManager-lang
  - NetworkManager-pppoe
  - NetworkManager-tui
  - NetworkManager-wwan
  - OpenIPMI
  - OpenIPMI-devel
  - OpenIPMI-python3
  - PackageKit
  - PackageKit-backend-zypp
  - PackageKit-branding-upstream
  - SAPHanaSR-angi
  - SLES-release
  - ServiceReport
  - WebKitGTK-4.0-lang
  - WebKitGTK-4.1-lang
  - WebKitGTK-6.0-lang
  - a52dec
  - aaa_base
  - aaa_base-extras
  - aaa_base-malloccheck
  - aaa_base-wsl
  - aaa_base-yama-enable-ptrace
  - aardvark-dns
  - abseil-cpp-devel
  - accountsservice
  - accountsservice-devel
  - accountsservice-lang
  - accountsservice-vala
  - acl
  - acpica
  - adaptec-firmware
  - adcli
  - adcli-doc
  - adobe-sourcecodepro-fonts
  - adobe-sourcehansans-cn-fonts
  - adobe-sourcehansans-hk-fonts
  - adobe-sourcehansans-jp-fonts
  - adobe-sourcehansans-kr-fonts
  - adobe-sourcehansans-tw-fonts
  - adwaita-icon-theme
  - agama-scripts
  - aide
  - alsa
  - alsa-devel
  - alsa-docs
  - alsa-firmware
  - alsa-ucm-conf
  - alsa-utils
  - alsabat
  - alts
  - ansible
  - ansible-core
  - ansible-linux-system-roles
  - ansible-sap-infrastructure
  - ansible-sap-operations
  - ant
  - ant-antlr
  - ant-apache-bcel
  - ant-apache-bsf
  - ant-apache-log4j
  - ant-apache-oro
  - ant-apache-regexp
  - ant-apache-resolver
  - ant-apache-xalan2
  - ant-commons-logging
  - ant-commons-net
  - ant-contrib
  - ant-contrib-javadoc
  - ant-contrib-manual
  - ant-imageio
  - ant-jakartamail
  - ant-javamail
  - ant-jdepend
  - ant-jmf
  - ant-jsch
  - ant-junit
  - ant-junit5
  - ant-manual
  - ant-scripts
  - ant-swing
  - ant-testutil
  - ant-xz
  - antlr
  - antlr-devel
  - antlr-java
  - antlr-manual
  - aom-tools
  - aopalliance
  - aopalliance-javadoc
  - apache-commons-beanutils
  - apache-commons-beanutils-javadoc
  - apache-commons-cli
  - apache-commons-cli-javadoc
  - apache-commons-codec
  - apache-commons-codec-javadoc
  - apache-commons-collections
  - apache-commons-collections-javadoc
  - apache-commons-collections-testframework
  - apache-commons-collections4
  - apache-commons-collections4-javadoc
  - apache-commons-compress
  - apache-commons-compress-javadoc
  - apache-commons-configuration2
  - apache-commons-configuration2-javadoc
  - apache-commons-daemon
  - apache-commons-daemon-javadoc
  - apache-commons-daemon-jsvc
  - apache-commons-dbcp
  - apache-commons-dbcp-javadoc
  - apache-commons-digester
  - apache-commons-digester-javadoc
  - apache-commons-exec
  - apache-commons-httpclient
  - apache-commons-httpclient-demo
  - apache-commons-httpclient-javadoc
  - apache-commons-httpclient-manual
  - apache-commons-io
  - apache-commons-io-javadoc
  - apache-commons-jexl
  - apache-commons-jexl-javadoc
  - apache-commons-jxpath
  - apache-commons-jxpath-javadoc
  - apache-commons-lang3
  - apache-commons-lang3-javadoc
  - apache-commons-logging
  - apache-commons-net
  - apache-commons-net-javadoc
  - apache-commons-pool2
  - apache-commons-pool2-javadoc
  - apache-commons-text
  - apache-commons-text-javadoc
  - apache-commons-vfs2
  - apache-commons-vfs2-ant
  - apache-commons-vfs2-examples
  - apache-commons-vfs2-javadoc
  - apache-ivy
  - apache-ivy-javadoc
  - apache-parent
  - apache-pdfbox
  - apache-pdfbox-javadoc
  - apache-rex
  - apache2
  - apache2-devel
  - apache2-event
  - apache2-manual
  - apache2-mod_auth_mellon
  - apache2-mod_auth_mellon-diagnostics
  - apache2-mod_auth_mellon-doc
  - apache2-mod_auth_openidc
  - apache2-mod_php8
  - apache2-mod_security2
  - apache2-prefork
  - apache2-utils
  - apache2-worker
  - apiguardian
  - apiguardian-javadoc
  - appstream-glib
  - appstream-glib-devel
  - appstream-glib-lang
  - appx-util
  - apr-devel
  - apr-util-devel
  - aqute-bnd
  - aqute-bnd-javadoc
  - aqute-bndlib
  - argon2
  - argon2-devel
  - argon2-doc
  - argyllcms
  - argyllcms-doc
  - arm-trusted-firmware
  - arpwatch
  - arpwatch-ethercodes
  - aspell
  - aspell-devel
  - aspell-ispell
  - aspell-spell
  - assertj-core
  - assertj-core-javadoc
  - at
  - at-spi2-core
  - at-spi2-core-devel
  - at-spi2-core-lang
  - atinject
  - atinject-javadoc
  - atkmm1_6-devel
  - atmel-firmware
  - attr
  - audit
  - audit-audispd-plugins
  - audit-devel
  - audit-rules
  - augeas
  - augeas-bash-completion
  - augeas-devel
  - augeas-lenses
  - auto
  - auto-common
  - auto-javadoc
  - auto-service
  - auto-service-aggregator
  - auto-service-annotations
  - auto-value
  - auto-value-annotations
  - auto-value-parent
  - autoconf
  - autoconf-archive
  - autoconf-el
  - autoconf213
  - autofs
  - autogen
  - automake
  - autoopts
  - avahi
  - avahi-autoipd
  - avahi-compat-mDNSResponder-devel
  - avahi-lang
  - avahi-utils
  - avahi-utils-gtk
  - avalon-logkit
  - avalon-logkit-javadoc
  - avif-tools
  - azure-vm-utils
  - babeltrace
  - babeltrace-devel
  - bash
  - bash-completion
  - bash-completion-devel
  - bash-devel
  - bash-doc
  - bash-lang
  - bash-loadables
  - bash-sh
  - bats
  - bc
  - bcache-tools
  - bcc-tools
  - bcel
  - bcel-javadoc
  - bcm43xx-firmware
  - bdf2psf
  - bdftopcf
  - benchmark-devel
  - beust-jcommander
  - beust-jcommander-javadoc
  - bind
  - bind-doc
  - bind-modules-generic
  - bind-modules-ldap
  - bind-modules-mysql
  - bind-modules-perl
  - bind-modules-sqlite3
  - bind-utils
  - binutils
  - binutils-devel
  - bison
  - bison-lang
  - bitstream-vera-fonts
  - blas-devel
  - blas-devel-static
  - blog
  - blog-devel
  - blog-plymouth
  - blosc-devel
  - bluez
  - bluez-auto-enable-devices
  - bluez-cups
  - bluez-devel
  - bluez-firmware
  - bluez-obexd
  - bnd-maven-plugin
  - bnd-maven-plugin-javadoc
  - bonnie
  - boost-devel
  - boost-jam
  - boost-license1_86_0
  - boost1_86_0-jam
  - bosh
  - bouncycastle
  - bouncycastle-javadoc
  - bouncycastle-jmail
  - bouncycastle-mail
  - bouncycastle-pg
  - bouncycastle-pkix
  - bouncycastle-tls
  - bouncycastle-util
  - bpftool
  - bpftool-bash-completion
  - bpftrace
  - bpftrace-tools
  - branding-SLE
  - brlapi-devel
  - brltty
  - brltty-driver-at-spi2
  - brltty-driver-brlapi
  - brltty-driver-espeak
  - brltty-driver-libbraille
  - brltty-driver-speech-dispatcher
  - brltty-driver-xwindow
  - brltty-lang
  - brltty-udev-generic
  - brltty-utils
  - brotli
  - bs2b-tools
  - bscalc
  - bsdtar
  - bsf
  - bsf-javadoc
  - bsh2
  - bsh2-bsf
  - bsh2-classgen
  - bsh2-demo
  - bsh2-javadoc
  - bsh2-manual
  - btcflash
  - btrfsmaintenance
  - btrfsprogs
  - btrfsprogs-bash-completion
  - btrfsprogs-static
  - btrfsprogs-udev-rules
  - bubblewrap
  - buildah
  - buildkit
  - busybox
  - busybox-static
  - byte-buddy
  - byte-buddy-agent
  - byte-buddy-javadoc
  - byte-buddy-maven-plugin
  - bzip2
  - bzip2-doc
  - c-ares-devel
  - c-ares-utils
  - ca-certificates
  - ca-certificates-mozilla
  - ca-certificates-mozilla-prebuilt
  - cairo-devel
  - cairo-tools
  - cairomm1_0-devel
  - cairomm1_0-doc
  - cal10n
  - cal10n-javadoc
  - cal10n-maven-plugins
  - cal10n-maven-plugins-javadoc
  - canberra-gtk-play
  - canberra-gtk-play-gnome
  - cantarell-fonts
  - cargo
  - cargo-auditable
  - cargo-c
  - cargo-packaging
  - cargo1.83
  - cargo1.84
  - cargo1.85
  - catatonit
  - cblas-devel
  - cblas-devel-static
  - ccache
  - cd-paranoia
  - cdda2wav
  - cdi-api
  - cdi-api-javadoc
  - cdio-utils
  - cdparanoia
  - cdrecord
  - cdrskin
  - celt
  - cepces
  - cepces-certmonger
  - cepces-selinux
  - certmonger
  - cglib
  - cglib-javadoc
  - check-devel
  - checkbashisms
  - checker-qual
  - checker-qual-javadoc
  - checkmedia
  - checkpolicy
  - chkstat
  - chrony
  - chrony-pool-suse
  - chrpath
  - cifs-utils
  - cifs-utils-devel
  - clamav
  - clamav-devel
  - clamav-docs-html
  - clamav-milter
  - cloud-init
  - cloud-init-config-suse
  - cloud-init-doc
  - cluster-md-kmp-default
  - cmake
  - cmake-full
  - cni
  - cni-plugins
  - coccinelle
  - cockpit
  - cockpit-bridge
  - cockpit-devel
  - cockpit-doc
  - cockpit-kdump
  - cockpit-machines
  - cockpit-networkmanager
  - cockpit-packagekit
  - cockpit-podman
  - cockpit-repos
  - cockpit-selinux
  - cockpit-selinux-policies
  - cockpit-storaged
  - cockpit-subscriptions
  - cockpit-system
  - cockpit-tukit
  - cockpit-ws
  - codespell
  - colord
  - colord-color-profiles
  - colord-gtk
  - colord-gtk-doc
  - colord-gtk-lang
  - colord-lang
  - combustion
  - compat-usrmerge
  - compat-usrmerge-tools
  - conmon
  - conntrack-tools
  - conntrackd
  - console-setup
  - container-build-checks-strict
  - container-selinux
  - container-suseconnect
  - containerd
  - containerd-ctr
  - containerd-devel
  - corepack22
  - coreutils
  - coreutils-doc
  - coreutils-lang
  - coreutils-single
  - coreutils-systemd
  - corosync
  - corosync-devel
  - corosync-libs
  - corosync-qdevice
  - corosync-qnetd
  - cpio
  - cpio-lang
  - cpio-mt
  - cpp
  - cpp13
  - cpp15
  - cppunit-devel
  - cppunit-devel-doc
  - cpupower
  - cpupower-bash-completion
  - cpupower-bench
  - cpupower-devel
  - cpupower-lang
  - cracklib
  - cracklib-devel
  - cracklib-dict-full
  - cracklib-dict-small
  - crash
  - crash-devel
  - crash-doc
  - crash-kmp-default
  - crda
  - createrepo_c
  - criu
  - criu-devel
  - crmsh
  - crmsh-scripts
  - cron
  - cronie
  - cronie-anacron
  - cross-bpf-binutils
  - cross-bpf-gcc15
  - crun
  - crypto-policies
  - crypto-policies-scripts
  - cryptsetup
  - cryptsetup-doc
  - cryptsetup-lang
  - cryptsetup-ssh
  - cscope
  - csync2
  - ctags
  - ctdb
  - ctdb-pcp-pmda
  - cunit-devel
  - cunit-doc
  - cups
  - cups-client
  - cups-config
  - cups-ddk
  - cups-devel
  - cups-rpm-helper
  - curl
  - cyrus-sasl
  - cyrus-sasl-crammd5
  - cyrus-sasl-devel
  - cyrus-sasl-digestmd5
  - cyrus-sasl-gs2
  - cyrus-sasl-gssapi
  - cyrus-sasl-ldap-auxprop
  - cyrus-sasl-ntlm
  - cyrus-sasl-otp
  - cyrus-sasl-plain
  - cyrus-sasl-saslauthd
  - cyrus-sasl-scram
  - cyrus-sasl-sqlauxprop
  - datefudge
  - dav1d
  - dav1d-devel
  - db48-doc
  - db48-utils
  - dbus-1
  - dbus-1-common
  - dbus-1-daemon
  - dbus-1-devel
  - dbus-1-glib-bash-completion
  - dbus-1-glib-devel
  - dbus-1-glib-doc
  - dbus-1-glib-tool
  - dbus-1-tools
  - dbus-1-x11
  - dbus-broker
  - dbus-broker-block-restart
  - dcatools
  - dconf
  - dconf-devel
  - dcraw
  - dcraw-lang
  - debianutils
  - debugedit
  - debuginfod-client
  - debuginfod-profile
  - dejagnu
  - dejavu-fonts
  - desktop-data-SLE
  - desktop-data-SLE-extra
  - desktop-file-utils
  - device-mapper
  - device-mapper-devel
  - dhcp
  - dhcp-client
  - dhcp-doc
  - dhcp-keama
  - dhcp-relay
  - dhcpcd
  - dialog
  - dialog-devel
  - dialog-examples
  - dialog-lang
  - diffutils
  - diffutils-lang
  - dirmngr
  - distribution-logos-SLE
  - djvulibre
  - djvulibre-doc
  - dlm-kmp-default
  - dmraid
  - dmraid-devel
  - dmz-icon-theme-cursors
  - dnsmasq
  - dnsmasq-utils
  - docker
  - docker-bash-completion
  - docker-compose
  - docker-compose-switch
  - docker-fish-completion
  - docker-rootless-extras
  - dom4j
  - dom4j-demo
  - dom4j-javadoc
  - dos2unix
  - dosfstools
  - dotconf-devel
  - double-conversion-devel
  - doxygen
  - doxygen2man
  - dpkg
  - dpkg-devel
  - dpkg-lang
  - dracut
  - dracut-extra
  - dracut-fips
  - dracut-ima
  - dracut-kiwi-lib
  - dracut-kiwi-live
  - dracut-kiwi-oem-dump
  - dracut-kiwi-oem-repart
  - dracut-kiwi-overlay
  - dracut-kiwi-verity
  - dracut-tools
  - dracut-transactional-update
  - drbd
  - drbd-kmp-default
  - drbd-selinux
  - drbd-utils
  - driverctl
  - dtc
  - dtdinst
  - duktape-devel
  - dump
  - dump-rmt
  - dvb-utils
  - dwarves
  - dwarves-devel
  - dwz
  - e2fsprogs
  - e2fsprogs-devel
  - e2fsprogs-scrub
  - ebtables
  - ecj
  - ed
  - ed25519-java
  - ed25519-java-javadoc
  - efibootmgr
  - efivar
  - efivar-devel
  - eglexternalplatform-devel
  - elfutils
  - elfutils-debuginfod
  - elfutils-lang
  - ell-devel
  - emacs
  - emacs-el
  - emacs-eln
  - emacs-info
  - emacs-nox
  - emacs-x11
  - enca
  - enca-devel
  - enchant-2-backend-aspell
  - enchant-2-backend-hunspell
  - enchant-2-backend-nuspell
  - enchant-2-backend-voikko
  - enchant-data
  - enchant-devel
  - enchant-tools
  - espeak-ng
  - espeak-ng-compat
  - espeak-ng-compat-devel
  - espeak-ng-devel
  - espeak-ng-vim
  - etags
  - ethtool
  - ethtool-bash-completion
  - evmctl
  - evolution-data-server
  - evolution-data-server-devel
  - evolution-data-server-lang
  - exec-maven-plugin
  - exec-maven-plugin-javadoc
  - exfatprogs
  - expat
  - expect
  - expect-devel
  - fabtests
  - fcoe-utils
  - fdo-client
  - fdo-client-devel
  - fdupes
  - felix-bundlerepository
  - felix-bundlerepository-javadoc
  - felix-gogo-runtime
  - felix-gogo-runtime-javadoc
  - felix-osgi-obr
  - felix-osgi-obr-javadoc
  - felix-parent
  - felix-shell
  - felix-shell-javadoc
  - felix-utils
  - felix-utils-javadoc
  - fence-agents-all
  - fence-agents-alom
  - fence-agents-apc
  - fence-agents-apc-snmp
  - fence-agents-aws
  - fence-agents-azure-arm
  - fence-agents-bladecenter
  - fence-agents-brocade
  - fence-agents-cisco-mds
  - fence-agents-cisco-ucs
  - fence-agents-common
  - fence-agents-devel
  - fence-agents-drac5
  - fence-agents-eaton-snmp
  - fence-agents-eaton-ssh
  - fence-agents-emerson
  - fence-agents-eps
  - fence-agents-gce
  - fence-agents-hds-cb
  - fence-agents-hpblade
  - fence-agents-ibm-powervs
  - fence-agents-ibm-vpc
  - fence-agents-ibmblade
  - fence-agents-ibmz
  - fence-agents-ifmib
  - fence-agents-ilo-moonshot
  - fence-agents-ilo-mp
  - fence-agents-ilo-ssh
  - fence-agents-ilo2
  - fence-agents-intelmodular
  - fence-agents-ipdu
  - fence-agents-ipmilan
  - fence-agents-kdump
  - fence-agents-lpar
  - fence-agents-mpath
  - fence-agents-netio
  - fence-agents-pve
  - fence-agents-raritan
  - fence-agents-rcd-serial
  - fence-agents-redfish
  - fence-agents-rsa
  - fence-agents-rsb
  - fence-agents-sanbox2
  - fence-agents-sbd
  - fence-agents-scsi
  - fence-agents-vbox
  - fence-agents-virsh
  - fence-agents-vmware
  - fence-agents-vmware-rest
  - fence-agents-wti
  - fence-agents-zvm
  - fetchmail
  - ffado
  - ffado-mixer
  - ffmpeg-7
  - ffnvcodec-devel
  - fftw3-devel
  - fftw3-openmp-devel
  - fftw3-threads-devel
  - file
  - file-devel
  - file-magic
  - filesystem
  - fillup
  - findutils
  - findutils-lang
  - fipscheck
  - fipscheck-devel
  - firewall-macros
  - firewalld
  - firewalld-bash-completion
  - firewalld-lang
  - fish
  - fish-devel
  - flac
  - flatpak
  - flatpak-devel
  - flatpak-remote-flathub
  - flatpak-selinux
  - flex
  - fltk-devel
  - fltk-devel-static
  - fmt-devel
  - foma
  - foma-devel
  - font-util
  - fontconfig
  - fontconfig-devel
  - fontconfig-devel-doc
  - fontconfig-doc
  - fontconfig-lang
  - fontforge
  - fontforge-devel
  - fontforge-doc
  - fontpackages-devel
  - fonts-config
  - fonttosfnt
  - fping
  - freeglut-demo
  - freeglut-devel
  - freeipmi
  - freeipmi-bmc-watchdog
  - freeipmi-devel
  - freeipmi-ipmidetectd
  - freeipmi-ipmiseld
  - freeradius-client
  - freeradius-client-devel
  - freeradius-client-libs
  - freeradius-server
  - freeradius-server-devel
  - freeradius-server-doc
  - freeradius-server-krb5
  - freeradius-server-ldap
  - freeradius-server-ldap-schemas
  - freeradius-server-libs
  - freeradius-server-mysql
  - freeradius-server-perl
  - freeradius-server-postgresql
  - freeradius-server-python3
  - freeradius-server-sqlite
  - freeradius-server-utils
  - freerdp
  - freerdp-devel
  - freerdp-proxy
  - freerdp-proxy-plugins
  - freerdp-sdl
  - freerdp-server
  - freerdp-wayland
  - freetds-config
  - freetds-devel
  - freetds-doc
  - freetds-tools
  - freetype2-devel
  - freetype2-profile-tti35
  - fribidi
  - fribidi-devel
  - frr
  - frr-devel
  - fstrm
  - fstrm-devel
  - fsverity-utils
  - fsverity-utils-devel
  - ftbench
  - ftdiff
  - ftdump
  - ftgamma
  - ftgl-demo
  - ftgl-devel
  - ftgrid
  - ftlint
  - ftmulti
  - ftsdf
  - ftstring
  - ftvalid
  - ftview
  - fuse
  - fuse-devel
  - fuse-devel-static
  - fuse-doc
  - fuse-overlayfs
  - fuse2fs
  - fuse3
  - fuse3-devel
  - fuse3-doc
  - fwupd
  - fwupd-bash-completion
  - fwupd-devel
  - fwupd-doc
  - fwupd-lang
  - gawk
  - gc-devel
  - gcab
  - gcab-devel
  - gcab-lang
  - gcc
  - gcc-PIE
  - gcc-ada
  - gcc-c++
  - gcc-fortran
  - gcc-go
  - gcc-info
  - gcc-locale
  - gcc-obj-c++
  - gcc-objc
  - gcc13
  - gcc15
  - gcc15-PIE
  - gcc15-ada
  - gcc15-c++
  - gcc15-fortran
  - gcc15-go
  - gcc15-info
  - gcc15-locale
  - gcc15-obj-c++
  - gcc15-objc
  - gcr-doc
  - gcr-lang
  - gcr-ssh-agent
  - gcr-ssh-askpass
  - gcr-viewer
  - gcr3-data
  - gcr3-lang
  - gcr3-prompter
  - gcr3-ssh-agent
  - gcr3-ssh-askpass
  - gcr3-viewer
  - gd
  - gd-devel
  - gdb
  - gdbm-devel
  - gdbm-lang
  - gdbserver
  - gdk-pixbuf-devel
  - gdk-pixbuf-lang
  - gdk-pixbuf-loader-libavif
  - gdk-pixbuf-loader-libheif
  - gdk-pixbuf-loader-rsvg
  - gdk-pixbuf-query-loaders
  - gdk-pixbuf-thumbnailer
  - gdk-pixbuf-xlib-devel
  - gdm
  - gdm-branding-SLE
  - gdm-devel
  - gdm-lang
  - gdm-schema
  - gdm-systemd
  - gdmflexiserver
  - gengetopt
  - geoclue2
  - geoclue2-devel
  - geocode-glib
  - geronimo-annotation-1_0-api
  - geronimo-j2ee-connector-1_5-api
  - geronimo-jaf-1_0_2-api
  - geronimo-jaf-1_1-api
  - geronimo-jaxrpc-1_1-api
  - geronimo-jms-1_1-api
  - geronimo-jpa-3_0-api
  - geronimo-jta-1_0_1B-api
  - geronimo-jta-1_1-api
  - geronimo-qname-1_1-api
  - geronimo-saaj-1_1-api
  - geronimo-servlet-2_4-api
  - geronimo-servlet-2_5-api
  - gettext-its-gtk3
  - gettext-its-gtk4
  - gettext-java
  - gettext-runtime
  - gettext-runtime-tools-doc
  - gettext-tools
  - gfs2-kmp-default
  - gfs2-utils
  - ghostscript
  - ghostscript-devel
  - ghostscript-fonts-std
  - ghostscript-x11
  - giflib-devel
  - giflib-progs
  - gio-branding-SLE
  - girepository-1_0
  - git
  - git-arch
  - git-core
  - git-credential-libsecret
  - git-daemon
  - git-doc
  - git-email
  - git-gui
  - git-p4
  - git-web
  - gitk
  - gjs
  - glassfish-activation
  - glassfish-activation-api
  - glassfish-activation-javadoc
  - glassfish-annotation-api
  - glassfish-annotation-api-javadoc
  - glassfish-jaxb-api
  - glassfish-jaxb-api-javadoc
  - glassfish-servlet-api
  - glassfish-servlet-api-javadoc
  - glew
  - glew-devel
  - glib-networking
  - glib-networking-lang
  - glib2-devel
  - glib2-devel-static
  - glib2-doc
  - glib2-lang
  - glib2-tools
  - glibc
  - glibc-devel
  - glibc-devel-static
  - glibc-extra
  - glibc-html
  - glibc-i18ndata
  - glibc-info
  - glibc-lang
  - glibc-locale
  - glibc-locale-base
  - glibc-profile
  - glibc-utils
  - glibmm2-devel
  - glibmm2_4-devel
  - glm-devel
  - glm-doc
  - glslang-devel
  - glslang-nonstd-devel
  - glu-devel
  - gmock
  - gmp-devel
  - gnome-autoar-devel
  - gnome-bluetooth
  - gnome-bluetooth-devel
  - gnome-bluetooth-lang
  - gnome-color-manager
  - gnome-color-manager-lang
  - gnome-console
  - gnome-control-center
  - gnome-control-center-color
  - gnome-control-center-devel
  - gnome-control-center-goa
  - gnome-control-center-lang
  - gnome-control-center-user-faces
  - gnome-control-center-users
  - gnome-desktop-lang
  - gnome-extensions
  - gnome-menus
  - gnome-menus-branding-upstream
  - gnome-menus-lang
  - gnome-online-accounts
  - gnome-online-accounts-devel
  - gnome-online-accounts-lang
  - gnome-remote-desktop
  - gnome-remote-desktop-lang
  - gnome-session
  - gnome-session-core
  - gnome-session-lang
  - gnome-session-wayland
  - gnome-settings-daemon
  - gnome-settings-daemon-devel
  - gnome-settings-daemon-lang
  - gnome-shell
  - gnome-shell-calendar
  - gnome-shell-devel
  - gnome-shell-lang
  - gnome-themes-accessibility
  - gnomekbd-tools
  - gnu-unifont-bitmap-fonts
  - gnu-unifont-jp-otf-fonts
  - gnu-unifont-otf-fonts
  - gnu_parallel
  - gnutls
  - go
  - go-doc
  - go-md2man
  - go-race
  - go1.23
  - go1.23-doc
  - go1.23-openssl
  - go1.23-openssl-doc
  - go1.23-openssl-race
  - go1.23-race
  - go1.24
  - go1.24-doc
  - go1.24-race
  - gobject-introspection
  - gobject-introspection-devel
  - golang-github-cpuguy83-go-md2man
  - golang-github-google-jsonnet
  - golang-github-prometheus-prometheus
  - golang-github-prometheus-promu
  - golang-packaging
  - google-errorprone-annotation
  - google-errorprone-annotations
  - google-errorprone-annotations-javadoc
  - google-errorprone-docgen_processor
  - google-errorprone-javadoc
  - google-errorprone-parent
  - google-errorprone-type_annotations
  - google-gson
  - google-gson-javadoc
  - google-guice
  - google-guice-javadoc
  - google-noto-coloremoji-fonts
  - google-noto-fangsongkssrotated-fonts
  - google-noto-fangsongkssvertical-fonts
  - google-noto-fonts
  - google-noto-kufiarabic-fonts
  - google-noto-music-fonts
  - google-noto-naskharabic-fonts
  - google-noto-nastaliqurdu-fonts
  - google-noto-rashihebrew-fonts
  - google-noto-sans-adlam-fonts
  - google-noto-sans-adlamunjoined-fonts
  - google-noto-sans-anatolianhieroglyphs-fonts
  - google-noto-sans-arabic-fonts
  - google-noto-sans-armenian-fonts
  - google-noto-sans-avestan-fonts
  - google-noto-sans-balinese-fonts
  - google-noto-sans-bamum-fonts
  - google-noto-sans-bassavah-fonts
  - google-noto-sans-batak-fonts
  - google-noto-sans-bengali-fonts
  - google-noto-sans-bhaiksuki-fonts
  - google-noto-sans-brahmi-fonts
  - google-noto-sans-buginese-fonts
  - google-noto-sans-buhid-fonts
  - google-noto-sans-canadianaboriginal-fonts
  - google-noto-sans-carian-fonts
  - google-noto-sans-caucasianalbanian-fonts
  - google-noto-sans-chakma-fonts
  - google-noto-sans-cham-fonts
  - google-noto-sans-cherokee-fonts
  - google-noto-sans-chorasmian-fonts
  - google-noto-sans-cjk-fonts
  - google-noto-sans-coptic-fonts
  - google-noto-sans-cuneiform-fonts
  - google-noto-sans-cypriot-fonts
  - google-noto-sans-cyprominoan-fonts
  - google-noto-sans-deseret-fonts
  - google-noto-sans-devanagari-fonts
  - google-noto-sans-duployan-fonts
  - google-noto-sans-egyptianhieroglyphs-fonts
  - google-noto-sans-elbasan-fonts
  - google-noto-sans-elymaic-fonts
  - google-noto-sans-ethiopic-fonts
  - google-noto-sans-fonts
  - google-noto-sans-georgian-fonts
  - google-noto-sans-glagolitic-fonts
  - google-noto-sans-gothic-fonts
  - google-noto-sans-grantha-fonts
  - google-noto-sans-gujarati-fonts
  - google-noto-sans-gunjalagondi-fonts
  - google-noto-sans-gurmukhi-fonts
  - google-noto-sans-hanifirohingya-fonts
  - google-noto-sans-hanunoo-fonts
  - google-noto-sans-hatran-fonts
  - google-noto-sans-hebrew-fonts
  - google-noto-sans-hk-fonts
  - google-noto-sans-hk-mono-fonts
  - google-noto-sans-imperialaramaic-fonts
  - google-noto-sans-indicsiyaqnumbers-fonts
  - google-noto-sans-inscriptionalpahlavi-fonts
  - google-noto-sans-inscriptionalparthian-fonts
  - google-noto-sans-javanese-fonts
  - google-noto-sans-jp-fonts
  - google-noto-sans-jp-mono-fonts
  - google-noto-sans-kaithi-fonts
  - google-noto-sans-kannada-fonts
  - google-noto-sans-kawi-fonts
  - google-noto-sans-kayahli-fonts
  - google-noto-sans-kharoshthi-fonts
  - google-noto-sans-khmer-fonts
  - google-noto-sans-khojki-fonts
  - google-noto-sans-khudawadi-fonts
  - google-noto-sans-kr-fonts
  - google-noto-sans-kr-mono-fonts
  - google-noto-sans-lao-fonts
  - google-noto-sans-laolooped-fonts
  - google-noto-sans-lepcha-fonts
  - google-noto-sans-limbu-fonts
  - google-noto-sans-lineara-fonts
  - google-noto-sans-linearb-fonts
  - google-noto-sans-lisu-fonts
  - google-noto-sans-lycian-fonts
  - google-noto-sans-lydian-fonts
  - google-noto-sans-mahajani-fonts
  - google-noto-sans-malayalam-fonts
  - google-noto-sans-mandaic-fonts
  - google-noto-sans-manichaean-fonts
  - google-noto-sans-marchen-fonts
  - google-noto-sans-masaramgondi-fonts
  - google-noto-sans-math-fonts
  - google-noto-sans-mayannumerals-fonts
  - google-noto-sans-medefaidrin-fonts
  - google-noto-sans-meeteimayek-fonts
  - google-noto-sans-mendekikakui-fonts
  - google-noto-sans-meroitic-fonts
  - google-noto-sans-miao-fonts
  - google-noto-sans-modi-fonts
  - google-noto-sans-mongolian-fonts
  - google-noto-sans-mono-fonts
  - google-noto-sans-mro-fonts
  - google-noto-sans-multani-fonts
  - google-noto-sans-myanmar-fonts
  - google-noto-sans-nabataean-fonts
  - google-noto-sans-nagmundari-fonts
  - google-noto-sans-nandinagari-fonts
  - google-noto-sans-newa-fonts
  - google-noto-sans-newtailue-fonts
  - google-noto-sans-nko-fonts
  - google-noto-sans-nkounjoined-fonts
  - google-noto-sans-nushu-fonts
  - google-noto-sans-ogham-fonts
  - google-noto-sans-olchiki-fonts
  - google-noto-sans-oldhungarian-fonts
  - google-noto-sans-olditalic-fonts
  - google-noto-sans-oldnortharabian-fonts
  - google-noto-sans-oldpermic-fonts
  - google-noto-sans-oldpersian-fonts
  - google-noto-sans-oldsogdian-fonts
  - google-noto-sans-oldsoutharabian-fonts
  - google-noto-sans-oldturkic-fonts
  - google-noto-sans-oriya-fonts
  - google-noto-sans-osage-fonts
  - google-noto-sans-osmanya-fonts
  - google-noto-sans-pahawhhmong-fonts
  - google-noto-sans-palmyrene-fonts
  - google-noto-sans-paucinhau-fonts
  - google-noto-sans-phagspa-fonts
  - google-noto-sans-phoenician-fonts
  - google-noto-sans-psalterpahlavi-fonts
  - google-noto-sans-rejang-fonts
  - google-noto-sans-runic-fonts
  - google-noto-sans-samaritan-fonts
  - google-noto-sans-saurashtra-fonts
  - google-noto-sans-sc-fonts
  - google-noto-sans-sc-mono-fonts
  - google-noto-sans-sharada-fonts
  - google-noto-sans-shavian-fonts
  - google-noto-sans-siddham-fonts
  - google-noto-sans-signwriting-fonts
  - google-noto-sans-sinhala-fonts
  - google-noto-sans-sogdian-fonts
  - google-noto-sans-sorasompeng-fonts
  - google-noto-sans-soyombo-fonts
  - google-noto-sans-sundanese-fonts
  - google-noto-sans-sylotinagri-fonts
  - google-noto-sans-symbols-fonts
  - google-noto-sans-symbols2-fonts
  - google-noto-sans-syriac-fonts
  - google-noto-sans-syriaceastern-fonts
  - google-noto-sans-syriacwestern-fonts
  - google-noto-sans-tagalog-fonts
  - google-noto-sans-tagbanwa-fonts
  - google-noto-sans-taile-fonts
  - google-noto-sans-taitham-fonts
  - google-noto-sans-taiviet-fonts
  - google-noto-sans-takri-fonts
  - google-noto-sans-tamil-fonts
  - google-noto-sans-tamilsupplement-fonts
  - google-noto-sans-tangsa-fonts
  - google-noto-sans-tc-fonts
  - google-noto-sans-tc-mono-fonts
  - google-noto-sans-telugu-fonts
  - google-noto-sans-thaana-fonts
  - google-noto-sans-thai-fonts
  - google-noto-sans-thailooped-fonts
  - google-noto-sans-tifinagh-fonts
  - google-noto-sans-tirhuta-fonts
  - google-noto-sans-ugaritic-fonts
  - google-noto-sans-vai-fonts
  - google-noto-sans-vithkuqi-fonts
  - google-noto-sans-wancho-fonts
  - google-noto-sans-warangciti-fonts
  - google-noto-sans-yi-fonts
  - google-noto-sans-zanabazarsquare-fonts
  - google-noto-serif-ahom-fonts
  - google-noto-serif-armenian-fonts
  - google-noto-serif-balinese-fonts
  - google-noto-serif-bengali-fonts
  - google-noto-serif-devanagari-fonts
  - google-noto-serif-display-fonts
  - google-noto-serif-divesakuru-fonts
  - google-noto-serif-dogra-fonts
  - google-noto-serif-ethiopic-fonts
  - google-noto-serif-fonts
  - google-noto-serif-georgian-fonts
  - google-noto-serif-grantha-fonts
  - google-noto-serif-gujarati-fonts
  - google-noto-serif-gurmukhi-fonts
  - google-noto-serif-hebrew-fonts
  - google-noto-serif-hk-fonts
  - google-noto-serif-jp-fonts
  - google-noto-serif-kannada-fonts
  - google-noto-serif-khitansmallscript-fonts
  - google-noto-serif-khmer-fonts
  - google-noto-serif-khojki-fonts
  - google-noto-serif-kr-fonts
  - google-noto-serif-lao-fonts
  - google-noto-serif-makasar-fonts
  - google-noto-serif-malayalam-fonts
  - google-noto-serif-myanmar-fonts
  - google-noto-serif-nphmong-fonts
  - google-noto-serif-olduyghur-fonts
  - google-noto-serif-oriya-fonts
  - google-noto-serif-ottomansiyaq-fonts
  - google-noto-serif-sc-fonts
  - google-noto-serif-sinhala-fonts
  - google-noto-serif-tamil-fonts
  - google-noto-serif-tangut-fonts
  - google-noto-serif-tc-fonts
  - google-noto-serif-telugu-fonts
  - google-noto-serif-thai-fonts
  - google-noto-serif-tibetan-fonts
  - google-noto-serif-toto-fonts
  - google-noto-serif-vithkuqi-fonts
  - google-noto-serif-yezidi-fonts
  - google-noto-traditionalnushu-fonts
  - google-noto-znamennymusicalnotation-fonts
  - google-opensans-fonts
  - govulncheck
  - govulncheck-vulndb
  - gpart
  - gperf
  - gperftools
  - gperftools-devel
  - gperftools-devel-static
  - gperftools-doc
  - gpg2
  - gpg2-lang
  - gpg2-tpm
  - gpgme
  - gpm
  - gpm-devel
  - gptfdisk
  - gptfdisk-fixparts
  - graphite2
  - graphite2-devel
  - graphviz
  - graphviz-gd
  - graphviz-plugins-core
  - grep
  - grep-lang
  - groff
  - groff-doc
  - groff-full
  - growpart
  - growpart-generator
  - growpart-rootgrow
  - grpc-devel
  - grub2
  - grub2-common
  - grub2-snapper-plugin
  - grub2-systemd-sleep-plugin
  - gsettings-backend-dconf
  - gsettings-desktop-schemas
  - gsettings-desktop-schemas-devel
  - gsettings-desktop-schemas-lang
  - gsound
  - gsound-devel
  - gspell
  - gspell-devel
  - gspell-lang
  - gssdp-doc
  - gstreamer
  - gstreamer-devel
  - gstreamer-devtools
  - gstreamer-docs
  - gstreamer-lang
  - gstreamer-libnice
  - gstreamer-plugin-pipewire
  - gstreamer-plugins-bad
  - gstreamer-plugins-bad-lang
  - gstreamer-plugins-base
  - gstreamer-plugins-base-devel
  - gstreamer-plugins-base-lang
  - gstreamer-plugins-good
  - gstreamer-plugins-good-extra
  - gstreamer-plugins-good-gtk
  - gstreamer-plugins-good-jack
  - gstreamer-plugins-good-lang
  - gstreamer-plugins-libav
  - gstreamer-plugins-libcamera
  - gstreamer-plugins-ugly
  - gstreamer-plugins-ugly-lang
  - gstreamer-transcoder
  - gstreamer-utils
  - gtest
  - gtk2-data
  - gtk2-devel
  - gtk2-immodule-amharic
  - gtk2-immodule-inuktitut
  - gtk2-immodule-multipress
  - gtk2-immodule-thai
  - gtk2-immodule-tigrigna
  - gtk2-immodule-vietnamese
  - gtk2-immodule-xim
  - gtk2-lang
  - gtk2-metatheme-adwaita
  - gtk2-theming-engine-adwaita
  - gtk2-tools
  - gtk3-data
  - gtk3-devel
  - gtk3-devel-doc
  - gtk3-immodule-amharic
  - gtk3-immodule-broadway
  - gtk3-immodule-inuktitut
  - gtk3-immodule-multipress
  - gtk3-immodule-thai
  - gtk3-immodule-tigrigna
  - gtk3-immodule-vietnamese
  - gtk3-immodule-xim
  - gtk3-lang
  - gtk3-metatheme-adwaita
  - gtk3-schema
  - gtk3-tools
  - gtk4-devel
  - gtk4-devel-tools
  - gtk4-docs
  - gtk4-lang
  - gtk4-schema
  - gtk4-tools
  - gtkglext-devel
  - gtkglext-doc
  - gtkmm2-devel
  - gtkmm3-devel
  - gtkmm3-doc
  - guava
  - guava-javadoc
  - guava-testlib
  - guestfs-tools
  - guestfs-tools-bash-completion
  - guestfs-tools-man-pages-ja
  - guestfs-tools-man-pages-uk
  - guice-assistedinject
  - guice-bom
  - guice-extensions
  - guice-grapher
  - guice-jmx
  - guice-jndi
  - guice-parent
  - guice-servlet
  - guice-throwingproviders
  - guile
  - guile-devel
  - guile-modules-3_0
  - gupnp-dlna
  - gupnp-dlna-tools
  - gupnp-doc
  - gvim
  - gweather4-data
  - gxditview
  - gzip
  - hamcrest
  - hamcrest-javadoc
  - haproxy
  - harfbuzz-devel
  - harfbuzz-tools
  - hawk-apiserver
  - hawk2
  - hdparm
  - health-checker
  - health-checker-plugins-MicroOS
  - health-checker-testing
  - helm
  - helm-bash-completion
  - helm-fish-completion
  - help2man
  - help2man-lang
  - hfst-ospell
  - hfst-ospell-devel
  - hicolor-icon-theme
  - highway-devel
  - highway-devel-doc
  - hiredis
  - hiredis-devel
  - hivex
  - hivex-devel
  - hivex-lang
  - hmaccalc
  - hostname
  - hsqldb
  - hsqldb-demo
  - hsqldb-javadoc
  - hsqldb-manual
  - http-parser-devel
  - httpcomponents-client
  - httpcomponents-client-cache
  - httpcomponents-client-javadoc
  - httpcomponents-core
  - httpcomponents-core-javadoc
  - hunspell
  - hunspell-devel
  - hunspell-tools
  - hwdata
  - hwinfo
  - hwinfo-devel
  - hwloc
  - hwloc-data
  - hwloc-devel
  - hwloc-doc
  - hwloc-gl
  - hwloc-gui
  - hyphen
  - hyphen-devel
  - ibacm
  - ibmswtpm2
  - ibmtss
  - ibmtss-base
  - ibmtss-devel
  - ibsim
  - ibus
  - ibus-dict-emoji
  - ibus-gtk
  - ibus-gtk3
  - ibus-gtk4
  - ibus-lang
  - ibutils
  - ibutils-devel
  - icoutils
  - icu
  - icu4j
  - icu4j-charset
  - icu4j-javadoc
  - icu4j-localespi
  - ignition
  - ima-evm-utils-devel
  - imlib2
  - imlib2-devel
  - imlib2-filters
  - imlib2-loaders
  - infiniband-diags
  - info
  - info-lang
  - info-std
  - intlfonts
  - intlfonts-euro-bitmap-fonts
  - intltool
  - iotop
  - iperf
  - iperf-devel
  - ipmitool
  - ipmitool-bmc-snmp-proxy
  - iproute2
  - iproute2-arpd
  - iproute2-bash-completion
  - ipset
  - ipset-devel
  - iptables
  - iptables-backend-nft
  - iputils
  - ipw-firmware
  - iscsiuio
  - iso-codes
  - iso-codes-devel
  - iso_ent
  - isorelax
  - issue-generator
  - itstool
  - ivy-local
  - iwpmd
  - j2objc-annotations
  - j2objc-annotations-javadoc
  - jack
  - jack-dbus
  - jackson-annotations
  - jackson-annotations-javadoc
  - jackson-core
  - jackson-core-javadoc
  - jackson-databind
  - jackson-databind-javadoc
  - jakarta-activation
  - jakarta-activation-javadoc
  - jakarta-inject
  - jakarta-inject-javadoc
  - jakarta-mail
  - jakarta-mail-javadoc
  - jakarta-servlet
  - jakarta-servlet-javadoc
  - jakarta-taglibs-standard
  - jakarta-taglibs-standard-javadoc
  - jansi
  - jansi-javadoc
  - jasper
  - java-11-openjdk
  - java-11-openjdk-demo
  - java-11-openjdk-devel
  - java-11-openjdk-headless
  - java-11-openjdk-javadoc
  - java-11-openjdk-jmods
  - java-11-openjdk-src
  - java-17-openjdk
  - java-17-openjdk-demo
  - java-17-openjdk-devel
  - java-17-openjdk-headless
  - java-17-openjdk-javadoc
  - java-17-openjdk-jmods
  - java-17-openjdk-src
  - java-1_8_0-openjdk
  - java-1_8_0-openjdk-accessibility
  - java-1_8_0-openjdk-demo
  - java-1_8_0-openjdk-devel
  - java-1_8_0-openjdk-headless
  - java-1_8_0-openjdk-javadoc
  - java-1_8_0-openjdk-src
  - java-21-openjdk
  - java-21-openjdk-demo
  - java-21-openjdk-devel
  - java-21-openjdk-headless
  - java-21-openjdk-javadoc
  - java-21-openjdk-jmods
  - java-21-openjdk-src
  - java-atk-wrapper
  - java-cup
  - java-cup-manual
  - javacc
  - javacc-demo
  - javacc-javadoc
  - javacc-manual
  - javacc-maven-plugin
  - javacc-maven-plugin-javadoc
  - javadoc-parser
  - javadoc-parser-javadoc
  - javamail
  - javamail-javadoc
  - javapackages-filesystem
  - javapackages-ivy
  - javapackages-local
  - javapackages-tools
  - javapoet
  - javapoet-javadoc
  - javassist
  - javassist-demo
  - javassist-javadoc
  - javassist-manual
  - javazic
  - jaxen
  - jaxen-demo
  - jaxen-javadoc
  - jbcrypt
  - jbcrypt-javadoc
  - jbigkit
  - jboss-interceptors-1.2-api
  - jboss-interceptors-1.2-api-javadoc
  - jcat-tool
  - jcl-over-slf4j
  - jdepend
  - jdepend-demo
  - jdepend-javadoc
  - jdom
  - jdom-demo
  - jdom-javadoc
  - jdom2
  - jdom2-javadoc
  - jemalloc
  - jemalloc-devel
  - jeos-firstboot
  - jetbrains-annotations
  - jetbrains-annotations-javadoc
  - jflex
  - jflex-javadoc
  - jfsutils
  - jigit
  - jing
  - jing-javadoc
  - jitterentropy-devel
  - jitterentropy-devel-static
  - jlex
  - jline
  - jline-javadoc
  - jna
  - jna-contrib
  - jna-javadoc
  - joe
  - jopt-simple
  - jopt-simple-javadoc
  - jq
  - jsch
  - jsch-agent-proxy-connector-factory
  - jsch-agent-proxy-core
  - jsch-agent-proxy-javadoc
  - jsch-agent-proxy-jsch
  - jsch-agent-proxy-pageant
  - jsch-agent-proxy-sshagent
  - jsch-agent-proxy-svnkit-trilead-ssh2
  - jsch-agent-proxy-usocket-jna
  - jsch-agent-proxy-usocket-nc
  - jsch-demo
  - jsch-javadoc
  - json-glib-devel
  - json-glib-lang
  - jsoncpp-devel
  - jsoup
  - jsoup-javadoc
  - jsr-305
  - jsr-305-javadoc
  - jtb
  - jtb-javadoc
  - jtidy
  - jtidy-javadoc
  - jtidy-scripts
  - judy-devel
  - judy-doc
  - jul-to-slf4j
  - junit
  - junit-javadoc
  - junit-manual
  - junit5
  - junit5-bom
  - junit5-guide
  - junit5-javadoc
  - junit5-minimal
  - junit5-minimal-javadoc
  - jurand
  - jzlib
  - jzlib-demo
  - jzlib-javadoc
  - kbd
  - kbd-legacy
  - kdump
  - kea
  - kea-doc
  - kea-hooks
  - keepalived
  - kernel-default
  - kernel-default-devel
  - kernel-default-extra
  - kernel-devel
  - kernel-firmware-all
  - kernel-firmware-amdgpu
  - kernel-firmware-ath10k
  - kernel-firmware-ath11k
  - kernel-firmware-ath12k
  - kernel-firmware-atheros
  - kernel-firmware-bluetooth
  - kernel-firmware-bnx2
  - kernel-firmware-brcm
  - kernel-firmware-chelsio
  - kernel-firmware-dpaa2
  - kernel-firmware-i915
  - kernel-firmware-intel
  - kernel-firmware-iwlwifi
  - kernel-firmware-liquidio
  - kernel-firmware-marvell
  - kernel-firmware-media
  - kernel-firmware-mediatek
  - kernel-firmware-mellanox
  - kernel-firmware-mwifiex
  - kernel-firmware-network
  - kernel-firmware-nfp
  - kernel-firmware-nvidia
  - kernel-firmware-platform
  - kernel-firmware-prestera
  - kernel-firmware-qcom
  - kernel-firmware-qlogic
  - kernel-firmware-radeon
  - kernel-firmware-realtek
  - kernel-firmware-serial
  - kernel-firmware-sound
  - kernel-firmware-ti
  - kernel-firmware-ueagle
  - kernel-firmware-usb-network
  - kernel-install-tools
  - kernel-livepatch-tools
  - kernel-livepatch-tools-devel
  - kernel-macros
  - kernel-obs-qa
  - kernel-source
  - kernel-source-vanilla
  - kernel-syms
  - kexec-tools
  - keylime-config
  - keylime-firewalld
  - keylime-ima-policy
  - keylime-logrotate
  - keylime-registrar
  - keylime-tenant
  - keylime-tpm_cert_store
  - keylime-verifier
  - keyutils
  - keyutils-devel
  - kiwi-bash-completion
  - kiwi-man-pages
  - kiwi-systemdeps
  - kiwi-systemdeps-bootloaders
  - kiwi-systemdeps-containers
  - kiwi-systemdeps-containers-wsl
  - kiwi-systemdeps-core
  - kiwi-systemdeps-disk-images
  - kiwi-systemdeps-filesystems
  - kiwi-systemdeps-image-validation
  - kiwi-systemdeps-iso-media
  - kiwi-templates-Minimal
  - klogd
  - kmod
  - kpartx
  - krb5
  - krb5-client
  - krb5-devel
  - krb5-plugin-kdb-ldap
  - krb5-plugin-preauth-otp
  - krb5-plugin-preauth-pkinit
  - krb5-plugin-preauth-spake
  - krb5-server
  - kselftests-kmp-default
  - kxml
  - kxml-javadoc
  - kyotocabinet
  - ladspa
  - lame
  - lame-doc
  - lame-mp3rtp
  - lapack-devel
  - lapack-devel-static
  - lapack-man
  - lapacke-devel
  - lapacke-devel-static
  - lastlog2
  - lcms2
  - ldb-tools
  - ldmtool
  - ldns
  - ldns-devel
  - ledmon
  - less
  - lib389
  - libEMF-devel
  - libEMF-utils
  - libEMF1
  - libFLAC++10
  - libFLAC12
  - libGLEW2_2
  - libGLU1
  - libHX32
  - libICE-devel
  - libICE6
  - libIex-3_2-31
  - libIlmThread-3_2-31
  - libImath-3_1-29
  - libImlib2-1
  - libJudy1
  - libLLVM17
  - libLLVM19
  - libLTO17
  - libMagick++-7_Q16HDRI5
  - libMagick++-devel
  - libMagickCore-7_Q16HDRI10
  - libMagickWand-7_Q16HDRI10
  - libOSMesa-devel
  - libOSMesa8
  - libOpenCL1
  - libOpenEXR-3_2-31
  - libOpenEXRCore-3_2-31
  - libOpenEXRUtil-3_2-31
  - libOpenIPMI0
  - libOpenIPMIui1
  - libQt63DAnimation6
  - libQt63DCore6
  - libQt63DExtras6
  - libQt63DInput6
  - libQt63DLogic6
  - libQt63DQuick6
  - libQt63DQuickAnimation6
  - libQt63DQuickExtras6
  - libQt63DQuickInput6
  - libQt63DQuickRender6
  - libQt63DQuickScene2D6
  - libQt63DQuickScene3D6
  - libQt63DRender6
  - libQt6Bluetooth6
  - libQt6Charts6
  - libQt6ChartsQml6
  - libQt6Concurrent6
  - libQt6Core5Compat6
  - libQt6Core6
  - libQt6DBus6
  - libQt6DataVisualization6
  - libQt6DataVisualizationQml6
  - libQt6Designer6
  - libQt6DesignerComponents6
  - libQt6Graphs6
  - libQt6Gui6
  - libQt6Help6
  - libQt6HttpServer6
  - libQt6LabsAnimation6
  - libQt6LabsFolderListModel6
  - libQt6LabsPlatform6
  - libQt6LabsQmlModels6
  - libQt6LabsSettings6
  - libQt6LabsSharedImage6
  - libQt6LabsWavefrontMesh6
  - libQt6Location6
  - libQt6Multimedia6
  - libQt6MultimediaQuick6
  - libQt6MultimediaWidgets6
  - libQt6Network6
  - libQt6NetworkAuth6
  - libQt6Nfc6
  - libQt6OpenGL6
  - libQt6OpenGLWidgets6
  - libQt6Positioning6
  - libQt6PositioningQuick6
  - libQt6PrintSupport6
  - libQt6Qml6
  - libQt6QmlCompiler6
  - libQt6QmlCore6
  - libQt6QmlLocalStorage6
  - libQt6QmlMeta6
  - libQt6QmlModels6
  - libQt6QmlNetwork6
  - libQt6QmlWorkerScript6
  - libQt6QmlXmlListModel6
  - libQt6Quick3D6
  - libQt6Quick3DAssetImport6
  - libQt6Quick3DAssetUtils6
  - libQt6Quick3DEffects6
  - libQt6Quick3DGlslParser6
  - libQt6Quick3DHelpers6
  - libQt6Quick3DHelpersImpl6
  - libQt6Quick3DIblBaker6
  - libQt6Quick3DParticleEffects6
  - libQt6Quick3DParticles6
  - libQt6Quick3DRuntimeRender6
  - libQt6Quick3DSpatialAudio6
  - libQt6Quick3DUtils6
  - libQt6Quick3DXr6
  - libQt6Quick6
  - libQt6QuickControls2-6
  - libQt6QuickControls2Impl6
  - libQt6QuickDialogs2-6
  - libQt6QuickDialogs2QuickImpl6
  - libQt6QuickDialogs2Utils6
  - libQt6QuickEffects6
  - libQt6QuickLayouts6
  - libQt6QuickParticles6
  - libQt6QuickShapes6
  - libQt6QuickTemplates2-6
  - libQt6QuickTest6
  - libQt6QuickTimeline6
  - libQt6QuickVectorImage6
  - libQt6QuickWidgets6
  - libQt6RemoteObjects6
  - libQt6RemoteObjectsQml6
  - libQt6Scxml6
  - libQt6ScxmlQml6
  - libQt6SerialBus6
  - libQt6SerialPort6
  - libQt6ShaderTools6
  - libQt6SpatialAudio6
  - libQt6Sql6
  - libQt6StateMachine6
  - libQt6StateMachineQml6
  - libQt6Svg6
  - libQt6SvgWidgets6
  - libQt6Test6
  - libQt6UiTools6
  - libQt6WaylandClient6
  - libQt6WaylandCompositor6
  - libQt6WaylandEglClientHwIntegration6
  - libQt6WaylandEglCompositorHwIntegration6
  - libQt6WebChannel6
  - libQt6WebChannelQuick6
  - libQt6WebSockets6
  - libQt6Widgets6
  - libQt6WlShellIntegration6
  - libQt6Xml6
  - libSDL-1_2-0
  - libSDL2-2_0-0
  - libSDL2_ttf-2_0-0
  - libSDL_gfx16
  - libSM-devel
  - libSM6
  - libSPIRV-Tools-2024_4_rc2
  - libSoundTouch1
  - libSoundTouchDll1
  - libWPEBackend-fdo-1_0-1
  - libX11-6
  - libX11-data
  - libX11-devel
  - libX11-devel-doc
  - libX11-xcb1
  - libXNVCtrl-devel
  - libXNVCtrl0
  - libXRes1
  - libXau-devel
  - libXau6
  - libXaw-devel
  - libXaw3d-devel
  - libXaw3d6
  - libXaw3d7
  - libXaw3d8
  - libXaw6
  - libXaw7
  - libXaw8
  - libXcomposite-devel
  - libXcomposite1
  - libXcursor-devel
  - libXcursor1
  - libXdamage-devel
  - libXdamage1
  - libXdmcp-devel
  - libXdmcp6
  - libXext-devel
  - libXext6
  - libXfixes-devel
  - libXfixes3
  - libXfont-devel
  - libXfont1
  - libXfont2-2
  - libXfont2-devel
  - libXft-devel
  - libXft2
  - libXi-devel
  - libXi6
  - libXinerama-devel
  - libXinerama1
  - libXmu-devel
  - libXmu6
  - libXmuu1
  - libXpm-devel
  - libXpm-tools
  - libXpm4
  - libXrandr-devel
  - libXrandr2
  - libXrender-devel
  - libXrender1
  - libXres-devel
  - libXss-devel
  - libXss1
  - libXt-devel
  - libXt6
  - libXtst-devel
  - libXtst6
  - libXv-devel
  - libXv1
  - libXvMC-devel
  - libXvMC1
  - libXxf86dga-devel
  - libXxf86dga1
  - libXxf86vm-devel
  - libXxf86vm1
  - libZXing3
  - liba52-0
  - libabsl_2407_0_0
  - libabsl_lite_2407_0_0
  - libaccountsservice0
  - libacl-devel
  - libacl1
  - libada15
  - libaddrxlat-devel
  - libaddrxlat3
  - libadwaita-1-0
  - libadwaita-devel
  - libadwaita-docs
  - libadwaita-lang
  - libaio-devel
  - libaio1
  - libalternatives-devel
  - libalternatives1
  - libao-devel
  - libao-plugins4
  - libao4
  - libaom3
  - libappindicator3-1
  - libappstream-compose0
  - libappstream-glib8
  - libappstream5
  - libapr-util1-0
  - libapr-util1-0-dbd-mysql
  - libapr-util1-0-dbd-pgsql
  - libapr-util1-0-dbd-sqlite3
  - libapr1-0
  - libarchive-devel
  - libarchive13
  - libargon2-1
  - libasan8
  - libasm-devel
  - libasm1
  - libasound2
  - libaspell15
  - libass9
  - libassimp5
  - libassuan-devel
  - libassuan0
  - libatasmart-devel
  - libatasmart-utils
  - libatasmart4
  - libatk-1_0-0
  - libatk-bridge-2_0-0
  - libatkmm-1_6-1
  - libatm1
  - libatomic1
  - libatomic_ops-devel
  - libatspi0
  - libattr-devel
  - libattr-devel-static
  - libattr1
  - libaudit1
  - libaugeas0
  - libauparse0
  - libavahi-client3
  - libavahi-common3
  - libavahi-core7
  - libavahi-devel
  - libavahi-glib-devel
  - libavahi-glib1
  - libavahi-gobject-devel
  - libavahi-gobject0
  - libavahi-libevent1
  - libavahi-ui-gtk3-0
  - libavc1394-0
  - libavc1394-tools
  - libavcodec61
  - libavdevice61
  - libavfilter10
  - libavformat61
  - libavif16
  - libavtp0
  - libavutil59
  - libb2-1
  - libbacktrace0
  - libbasicobjects-devel
  - libbasicobjects0
  - libbcc0
  - libbd_btrfs-devel
  - libbd_btrfs3
  - libbd_crypto-devel
  - libbd_crypto3
  - libbd_dm-devel
  - libbd_dm3
  - libbd_fs-devel
  - libbd_fs3
  - libbd_loop-devel
  - libbd_loop3
  - libbd_lvm-dbus-devel
  - libbd_lvm-dbus3
  - libbd_lvm-devel
  - libbd_lvm3
  - libbd_mdraid-devel
  - libbd_mdraid3
  - libbd_mpath-devel
  - libbd_mpath3
  - libbd_nvme3
  - libbd_part-devel
  - libbd_part3
  - libbd_swap-devel
  - libbd_swap3
  - libbd_utils-devel
  - libbd_utils3
  - libbenchmark1
  - libblas3
  - libblkid-devel
  - libblkid-devel-static
  - libblkid1
  - libblockdev
  - libblockdev-devel
  - libblockdev3
  - libblogger2
  - libblosc1
  - libbluetooth3
  - libbluray2
  - libboost_atomic-devel
  - libboost_atomic1_86_0
  - libboost_atomic1_86_0-devel
  - libboost_charconv1_86_0
  - libboost_charconv1_86_0-devel
  - libboost_chrono-devel
  - libboost_chrono1_86_0
  - libboost_chrono1_86_0-devel
  - libboost_container-devel
  - libboost_container1_86_0
  - libboost_container1_86_0-devel
  - libboost_context-devel
  - libboost_context1_86_0
  - libboost_context1_86_0-devel
  - libboost_contract-devel
  - libboost_contract1_86_0
  - libboost_contract1_86_0-devel
  - libboost_coroutine-devel
  - libboost_coroutine1_86_0
  - libboost_coroutine1_86_0-devel
  - libboost_date_time-devel
  - libboost_date_time1_86_0
  - libboost_date_time1_86_0-devel
  - libboost_fiber-devel
  - libboost_fiber1_86_0
  - libboost_fiber1_86_0-devel
  - libboost_filesystem-devel
  - libboost_filesystem1_86_0
  - libboost_filesystem1_86_0-devel
  - libboost_graph-devel
  - libboost_graph1_86_0
  - libboost_graph1_86_0-devel
  - libboost_headers-devel
  - libboost_headers1_86_0-devel
  - libboost_iostreams-devel
  - libboost_iostreams1_86_0
  - libboost_iostreams1_86_0-devel
  - libboost_json1_86_0
  - libboost_json1_86_0-devel
  - libboost_locale-devel
  - libboost_locale1_86_0
  - libboost_locale1_86_0-devel
  - libboost_log-devel
  - libboost_log1_86_0
  - libboost_log1_86_0-devel
  - libboost_math-devel
  - libboost_math1_86_0
  - libboost_math1_86_0-devel
  - libboost_nowide-devel
  - libboost_nowide1_86_0
  - libboost_nowide1_86_0-devel
  - libboost_process-devel
  - libboost_process1_86_0
  - libboost_process1_86_0-devel
  - libboost_program_options-devel
  - libboost_program_options1_86_0
  - libboost_program_options1_86_0-devel
  - libboost_random-devel
  - libboost_random1_86_0
  - libboost_random1_86_0-devel
  - libboost_regex-devel
  - libboost_regex1_86_0
  - libboost_regex1_86_0-devel
  - libboost_serialization-devel
  - libboost_serialization1_86_0
  - libboost_serialization1_86_0-devel
  - libboost_stacktrace-devel
  - libboost_stacktrace1_86_0
  - libboost_stacktrace1_86_0-devel
  - libboost_system-devel
  - libboost_system1_86_0
  - libboost_system1_86_0-devel
  - libboost_test-devel
  - libboost_test1_86_0
  - libboost_test1_86_0-devel
  - libboost_thread-devel
  - libboost_thread1_86_0
  - libboost_thread1_86_0-devel
  - libboost_timer-devel
  - libboost_timer1_86_0
  - libboost_timer1_86_0-devel
  - libboost_type_erasure-devel
  - libboost_type_erasure1_86_0
  - libboost_type_erasure1_86_0-devel
  - libboost_url1_86_0
  - libboost_url1_86_0-devel
  - libboost_wave-devel
  - libboost_wave1_86_0
  - libboost_wave1_86_0-devel
  - libbpf-devel
  - libbpf-devel-static
  - libbpf1
  - libbraille
  - libbraille-devel
  - libbraille0-14
  - libbrlapi0_8
  - libbrotli-devel
  - libbrotlicommon1
  - libbrotlidec1
  - libbrotlienc1
  - libbs2b0
  - libbsd-devel
  - libbsd0
  - libbtrfs-devel
  - libbtrfs0
  - libbtrfsutil-devel
  - libbtrfsutil1
  - libburn-devel
  - libburn4
  - libbytesize-devel
  - libbytesize-lang
  - libbytesize1
  - libbz2-1
  - libbz2-devel
  - libcaca-devel
  - libcaca-ruby
  - libcaca0
  - libcaca0-plugins
  - libcacard-devel
  - libcacard0
  - libcairo-gobject2
  - libcairo-script-interpreter2
  - libcairo2
  - libcairomm-1_0-1
  - libcamel-1_2-64
  - libcamera-base0_4
  - libcamera-devel
  - libcamera0_4
  - libcanberra-devel
  - libcanberra-gtk-module-common
  - libcanberra-gtk0
  - libcanberra-gtk2-module
  - libcanberra-gtk3-0
  - libcanberra-gtk3-module
  - libcanberra0
  - libcap-devel
  - libcap-ng-devel
  - libcap-ng-utils
  - libcap-ng0
  - libcap-progs
  - libcap2
  - libcapstone4
  - libcares2
  - libcblas3
  - libcbor-devel
  - libcbor0_10
  - libcdda_interface0
  - libcdda_paranoia0
  - libcddb-devel
  - libcddb2
  - libcdio++1
  - libcdio-devel
  - libcdio-paranoia-devel
  - libcdio19
  - libcdio_cdda2
  - libcdio_paranoia2
  - libcdrdeflt1_0
  - libcdt5
  - libcelt0-2
  - libcgraph6
  - libcheck0
  - libcjose-devel
  - libcjose0
  - libcjson1
  - libclamav12
  - libclammspack0
  - libclang-cpp19
  - libclang13
  - libclc
  - libcloudproviders-devel
  - libcloudproviders0
  - libcmocka-devel
  - libcmocka0
  - libcodec2-1_0
  - libcollection-devel
  - libcollection4
  - libcolord-devel
  - libcolord-gtk-devel
  - libcolord-gtk1
  - libcolord-gtk4-1
  - libcolord2
  - libcolorhug2
  - libcom_err-devel
  - libcom_err-devel-static
  - libcom_err2
  - libcompel1
  - libconfig++-devel
  - libconfig++11
  - libconfig-devel
  - libconfig11
  - libconfuse-devel
  - libconfuse-lang
  - libconfuse2
  - libcontainers-common
  - libcontainers-default-policy
  - libcontainers-openSUSE-policy
  - libcontainers-sles-mounts
  - libcppunit-1_15-1
  - libcpupower1
  - libcrack2
  - libcrc32c-devel
  - libcrc32c1
  - libcreaterepo_c-devel
  - libcreaterepo_c1
  - libcriu2
  - libcrypt1
  - libcryptopp-devel
  - libcryptopp8_9_0
  - libcryptsetup-devel
  - libcryptsetup12
  - libct4
  - libctf-nobfd0
  - libctf0
  - libcue2
  - libcuefile-devel
  - libcuefile0
  - libcunit1
  - libcups2
  - libcupsimage2
  - libcurl-devel
  - libcurl-devel-doc
  - libcurl4
  - libdaemon-devel
  - libdaemon0
  - libdatrie-devel
  - libdatrie1
  - libdav1d7
  - libdb-4_8
  - libdb-4_8-devel
  - libdb_java-4_8
  - libdbi-devel
  - libdbi-drivers-dbd-freetds
  - libdbi-drivers-dbd-mysql
  - libdbi-drivers-dbd-pgsql
  - libdbi-drivers-dbd-sqlite3
  - libdbi3
  - libdbus-1-3
  - libdbus-c++-1-1
  - libdbus-c++-api-docs
  - libdbus-c++-devel
  - libdbus-glib-1-2
  - libdbusmenu-glib-devel
  - libdbusmenu-glib-doc
  - libdbusmenu-glib4
  - libdbusmenu-gtk2-doc
  - libdbusmenu-gtk3-4
  - libdbusmenu-gtk4
  - libdbusmenu-jsonloader-devel
  - libdbusmenu-jsonloader4
  - libdbusmenu-tools
  - libdc1394-26
  - libdc1394-devel
  - libdc1394-tools
  - libdca0
  - libdconf1
  - libdebuginfod-devel
  - libdebuginfod1
  - libdecor
  - libdecor-0-0
  - libdecor-devel
  - libdeflate-devel
  - libdeflate-tools
  - libdeflate0
  - libdeflt1_0
  - libdevmapper-event1_03
  - libdevmapper1_03
  - libdex-1-1
  - libdex-devel
  - libdex-devel-docs
  - libdhash-devel
  - libdhash1
  - libdialog15
  - libdisplay-info-devel
  - libdisplay-info2
  - libdjvulibre-devel
  - libdjvulibre21
  - libdlm
  - libdlm-devel
  - libdlm3
  - libdmmp-devel
  - libdmmp0_2_0
  - libdmx-devel
  - libdmx1
  - libdnet-devel
  - libdnet1
  - libdns_sd
  - libdotconf0
  - libdouble-conversion3
  - libdovi3
  - libdrm-devel
  - libdrm-tools
  - libdrm2
  - libdrm_amdgpu1
  - libdrm_nouveau2
  - libdrm_radeon1
  - libdrop_ambient-devel
  - libdrop_ambient0
  - libduktape207
  - libdv
  - libdv4
  - libdvbv5-0
  - libdvdnav4
  - libdvdread8
  - libdw-devel
  - libdw1
  - libdwarves1
  - libebackend-1_2-11
  - libebook-1_2-21
  - libebook-contacts-1_2-4
  - libebtc0
  - libebur128-1
  - libecal-2_0-3
  - libeconf-devel
  - libeconf-devel-static
  - libeconf-utils
  - libeconf0
  - libecpg6
  - libedata-book-1_2-27
  - libedata-cal-2_0-2
  - libedataserver-1_2-27
  - libedataserverui-1_2-4
  - libedataserverui4-1_0-0
  - libedc_ecc1_0
  - libedc_ecc_dec1_0
  - libedit-devel
  - libedit0
  - libefa1
  - libefivar1
  - libei-devel
  - libei1
  - libelf-devel
  - libelf1
  - libell0
  - libenca0
  - libenchant-2-2
  - libepoxy-devel
  - libepoxy0
  - liberation-fonts
  - libesmtp-devel
  - libesmtp6_2_0
  - libespeak-ng1
  - libev-devel
  - libev4
  - libevdev-devel
  - libevdev-tools
  - libevdev2
  - libevent-2_1-7
  - libevent-devel
  - libevent-devel-static
  - libexempi8
  - libexif-devel
  - libexif12
  - libexiv2-28
  - libexpat-devel
  - libexpat1
  - libexslt0
  - libext2fs-devel
  - libext2fs-devel-static
  - libext2fs2
  - libfa1
  - libfabric
  - libfabric-devel
  - libfabric1
  - libfcgi0
  - libfdisk-devel
  - libfdisk-devel-static
  - libfdisk1
  - libfdk-aac-devel
  - libfdk-aac2
  - libfdt-devel
  - libfdt1
  - libffado-devel
  - libffado2
  - libffi-devel
  - libffi8
  - libfftw3-3
  - libfftw3_omp3
  - libfftw3_threads3
  - libfido2-1
  - libfido2-devel
  - libfido2-udev
  - libfido2-utils
  - libfile1_0
  - libfind4_0
  - libfipscheck1
  - libfl-devel
  - libfl2
  - libflatpak0
  - libfltk1_3
  - libfmt9
  - libfoma0
  - libfontconfig1
  - libfontenc-devel
  - libfontenc1
  - libfreebl3
  - libfreeipmi17
  - libfreerdp-server-proxy3-3
  - libfreerdp3-3
  - libfreetype6
  - libfreshclam3
  - libfribidi0
  - libfrr0
  - libfrr_pb0
  - libfrrcares0
  - libfrrfpm_pb0
  - libfrrospfapiclient0
  - libfrrsnmp0
  - libfrrzmq0
  - libfstrm0
  - libfsverity0
  - libftdi1-2
  - libftdi1-devel
  - libftgl2
  - libfuse2
  - libfuse3-3
  - libfwupd3
  - libgbm-devel
  - libgbm1
  - libgc1
  - libgcab-1_0-0
  - libgcc_s1
  - libgccjit-devel
  - libgccjit0
  - libgccjit0-devel-gcc15
  - libgck-1-0
  - libgck-2-2
  - libgck1-devel
  - libgcr-3-1
  - libgcr-4-4
  - libgcr3-devel
  - libgcrypt-devel
  - libgcrypt20
  - libgd3
  - libgdbm6
  - libgdbm_compat4
  - libgdk_pixbuf-2_0-0
  - libgdk_pixbuf_xlib-2_0-0
  - libgdm1
  - libgeocode-glib-2-0
  - libgeocode-glib0
  - libgexiv2-2
  - libgfortran5
  - libgif7
  - libgio-2_0-0
  - libgiomm-2_4-1
  - libgiomm-2_68-1
  - libgirepository-1_0-1
  - libgirepository-2_0-0
  - libgjs-devel
  - libgjs0
  - libglade-2_0-0
  - libglade2-devel
  - libglade2-doc
  - libglib-2_0-0
  - libglibmm-2_4-1
  - libglibmm-2_68-1
  - libglslang12
  - libglut3
  - libglvnd
  - libglvnd-devel
  - libgme0
  - libgmodule-2_0-0
  - libgmp10
  - libgmpxx4
  - libgnome-autoar-0-0
  - libgnome-autoar-gtk-0-0
  - libgnome-bluetooth-3_0-13
  - libgnome-bluetooth-ui-3_0-13
  - libgnome-desktop-3-20
  - libgnome-desktop-3-devel
  - libgnome-desktop-3_0-common
  - libgnome-desktop-4-2
  - libgnome-desktop-4-devel
  - libgnome-keyring-lang
  - libgnome-keyring0
  - libgnome-menu-3-0
  - libgnomekbd-devel
  - libgnomekbd-lang
  - libgnomekbd8
  - libgnustep-base1_30
  - libgnutls-devel
  - libgnutls30
  - libgnutlsxx-devel
  - libgnutlsxx30
  - libgo24
  - libgoa-1_0-0
  - libgoa-backend-1_0-2
  - libgobject-2_0-0
  - libgomp1
  - libgpg-error-devel
  - libgpg-error0
  - libgpgme-devel
  - libgpgme11
  - libgpgmepp-devel
  - libgpgmepp6
  - libgpiod-devel
  - libgpiod-utils
  - libgpiod2
  - libgpiodcxx1
  - libgpiomockup0
  - libgpm2
  - libgraphene-1_0-0
  - libgraphene-devel
  - libgraphite2-3
  - libgrpc++1_59
  - libgrpc1_59
  - libgrpc36
  - libgsasl-devel
  - libgsasl-lang
  - libgsasl7
  - libgsf-1-114
  - libgsm-utils
  - libgsm1
  - libgsound0
  - libgspell-1-3
  - libgssdp-1_6-0
  - libgssdp-devel
  - libgstadaptivedemux-1_0-0
  - libgstallocators-1_0-0
  - libgstanalytics-1_0-0
  - libgstapp-1_0-0
  - libgstaudio-1_0-0
  - libgstbadaudio-1_0-0
  - libgstbasecamerabinsrc-1_0-0
  - libgstcodecparsers-1_0-0
  - libgstcodecs-1_0-0
  - libgstcuda-1_0-0
  - libgstfft-1_0-0
  - libgstgl-1_0-0
  - libgstinsertbin-1_0-0
  - libgstisoff-1_0-0
  - libgstmpegts-1_0-0
  - libgstmse-1_0-0
  - libgstpbutils-1_0-0
  - libgstphotography-1_0-0
  - libgstplay-1_0-0
  - libgstplayer-1_0-0
  - libgstreamer-1_0-0
  - libgstriff-1_0-0
  - libgstrtp-1_0-0
  - libgstrtsp-1_0-0
  - libgstrtspserver-1_0-0
  - libgstsctp-1_0-0
  - libgstsdp-1_0-0
  - libgsttag-1_0-0
  - libgsttranscoder-1_0-0
  - libgsturidownloader-1_0-0
  - libgstva-1_0-0
  - libgstvalidate-1_0-0
  - libgstvideo-1_0-0
  - libgstvulkan-1_0-0
  - libgstwayland-1_0-0
  - libgstwebrtc-1_0-0
  - libgstwebrtcnice-1_0-0
  - libgthread-2_0-0
  - libgtk-2_0-0
  - libgtk-3-0
  - libgtk-4-1
  - libgtkglext-x11-1_0-0
  - libgtkmm-2_4-1
  - libgtkmm-3_0-1
  - libgtop
  - libgtop-2_0-11
  - libgtop-doc
  - libgtop-lang
  - libgts-0_7-5
  - libgudev-1_0-0
  - libgudev-1_0-devel
  - libguess-devel
  - libguess1
  - libguestfs
  - libguestfs-appliance
  - libguestfs-bash-completion
  - libguestfs-devel
  - libguestfs-gobject-1_0
  - libguestfs-gobject-devel
  - libguestfs-inspect-icons
  - libguestfs-man-pages-ja
  - libguestfs-man-pages-uk
  - libguestfs-rescue
  - libguestfs-rsync
  - libguestfs-typelib-Guestfs-1_0
  - libguestfs-winsupport
  - libguestfs-xfs
  - libguestfs0
  - libguestfsd
  - libguile-3_0-1
  - libgupnp-1_6-0
  - libgupnp-devel
  - libgupnp-dlna-2_0-4
  - libgupnp-dlna-backend-gstreamer
  - libgupnp-dlna-devel
  - libgupnp-igd-1_6-0
  - libgupnp-igd-devel
  - libgusb-devel
  - libgusb2
  - libgvc6
  - libgvpr2
  - libgweather-4-0
  - libgweather4-lang
  - libgxps2
  - libhandle1
  - libhandy-1-0
  - libharfbuzz-cairo0
  - libharfbuzz-gobject0
  - libharfbuzz-icu0
  - libharfbuzz-subset0
  - libharfbuzz0
  - libhd23
  - libheif-aom
  - libheif-dav1d
  - libheif-ffmpeg
  - libheif-jpeg
  - libheif-openjpeg
  - libheif-rav1e
  - libheif1
  - libhfstospell11
  - libhidapi-devel
  - libhidapi-hidraw0
  - libhidapi-libusb0
  - libhiredis1_1_0
  - libhivex0
  - libhns1
  - libhogweed6
  - libhowl0
  - libhttp_parser2_9
  - libhugetlbfs
  - libhugetlbfs-devel
  - libhunspell-1_7-0
  - libhwloc15
  - libhwy1
  - libhyphen0
  - libi2c0
  - libibdm1
  - libibmad5
  - libibmtss2
  - libibnetdisc5
  - libibumad3
  - libibus-1_0-5
  - libibverbs
  - libibverbs-utils
  - libibverbs1
  - libical-devel
  - libical-doc
  - libical-glib-devel
  - libical-glib-doc
  - libical-glib3
  - libical3
  - libicu-devel
  - libicu-doc
  - libicu77
  - libid3tag-devel
  - libid3tag0
  - libidn-devel
  - libidn-tools
  - libidn12
  - libidn2-0
  - libidn2-devel
  - libidn2-lang
  - libidn2-tools
  - libiec61883-0
  - libiec61883-tools
  - libimaevm5
  - libimagequant-devel
  - libimagequant0
  - libimobiledevice-1_0-6
  - libimobiledevice-devel
  - libimobiledevice-glue-1_0-0
  - libimobiledevice-glue-devel
  - libini_config-devel
  - libini_config5
  - libinih-devel
  - libinih0
  - libiniparser-devel
  - libiniparser1
  - libinput-devel
  - libinput-tools
  - libinput-udev
  - libinput10
  - libinstpatch-1_0-2
  - libip4tc2
  - libip6tc2
  - libipa_hbac-devel
  - libipa_hbac0
  - libiperf0
  - libipmiconsole2
  - libipmidetect0
  - libipmimonitoring6
  - libipq-devel
  - libipq0
  - libipset13
  - libiptc-devel
  - libiptcdata
  - libiptcdata0
  - libirml1
  - libiscsi-devel
  - libiscsi-utils
  - libiscsi9
  - libisl23
  - libiso9660++0
  - libiso9660-11
  - libisoburn-devel
  - libisoburn1
  - libisofs-devel
  - libisofs6
  - libitm1
  - libiw-devel
  - libiw30
  - libjack0
  - libjacknet0
  - libjackserver0
  - libjansson-devel
  - libjansson4
  - libjasper-devel
  - libjasper7
  - libjavascriptcoregtk-4_0-18
  - libjavascriptcoregtk-4_1-0
  - libjavascriptcoregtk-6_0-1
  - libjbig-devel
  - libjbig2
  - libjcat-devel
  - libjcat1
  - libjemalloc2
  - libjitterentropy3
  - libjpeg-turbo
  - libjpeg62
  - libjpeg62-devel
  - libjpeg8
  - libjpeg8-devel
  - libjq-devel
  - libjq1
  - libjson-c-devel
  - libjson-c-doc
  - libjson-c5
  - libjson-glib-1_0-0
  - libjsoncpp25
  - libjte-devel
  - libjte2
  - libjxl-devel
  - libjxl0_11
  - libkbdfile1
  - libkcapi-devel
  - libkcapi-tools
  - libkcapi1
  - libkdumpfile-devel
  - libkdumpfile10
  - libkea-asiodns48
  - libkea-asiolink71
  - libkea-cc68
  - libkea-cfgclient65
  - libkea-cryptolink50
  - libkea-d2srv46
  - libkea-database61
  - libkea-dhcp++89
  - libkea-dhcp_ddns56
  - libkea-dhcpsrv108
  - libkea-dns++56
  - libkea-eval69
  - libkea-exceptions33
  - libkea-hooks97
  - libkea-http71
  - libkea-log61
  - libkea-mysql69
  - libkea-pgsql69
  - libkea-process72
  - libkea-stats41
  - libkea-tcp18
  - libkea-util-io0
  - libkea-util84
  - libkeymap1
  - libkeyutils1
  - libkfont0
  - libkmip-devel
  - libkmip-tools
  - libkmip0
  - libkmod-devel
  - libkmod2
  - libknet-devel
  - libknet1
  - libknet1-compress-bzip2-plugin
  - libknet1-compress-lz4-plugin
  - libknet1-compress-lzma-plugin
  - libknet1-compress-lzo2-plugin
  - libknet1-compress-plugins-all
  - libknet1-compress-zlib-plugin
  - libknet1-compress-zstd-plugin
  - libknet1-crypto-nss-plugin
  - libknet1-crypto-openssl-plugin
  - libknet1-crypto-plugins-all
  - libknet1-plugins-all
  - libksba-devel
  - libksba8
  - libkyotocabinet-devel
  - libkyotocabinet16
  - liblab_gamut1
  - liblapack3
  - liblapacke3
  - liblasso-devel
  - liblasso3
  - liblastlog2-2
  - liblastlog2-devel
  - liblavfile-2_2-0
  - liblavjpeg-2_2-0
  - liblavplay-2_2-0
  - liblavrec-2_2-0
  - liblbxutil-devel
  - liblbxutil1
  - liblc3-1
  - liblc3-devel
  - liblc3-tools
  - liblcms2-2
  - liblcms2-devel
  - liblcms2-doc
  - libldap-data
  - libldap2
  - libldapcpp-devel
  - libldapcpp0
  - libldb-devel
  - libldb2
  - libldm-1_0-0
  - libldm-1_0-0-devel
  - libldns3
  - liblilv-0-0
  - liblldb19
  - liblldp_clif1
  - liblmdb-0_9_30
  - liblog4cplus-2_1-9
  - liblog4shib2
  - liblqr-1-0
  - liblqr-devel
  - liblrdf2
  - liblsan0
  - libltdl7
  - liblua5_1-5
  - liblua5_3-5
  - liblua5_4-5
  - liblvm2cmd2_03
  - liblz1
  - liblz4-1
  - liblz4-devel
  - liblzma5
  - liblzo2-2
  - libm17n0
  - libmagic1
  - libmailutils9
  - libmalcontent-0-0
  - libmalcontent-ui-1-1
  - libmana1
  - libmanette-0_2-0
  - libmanette-devel
  - libmariadb-devel
  - libmariadb3
  - libmariadb_plugins
  - libmariadbd-devel
  - libmariadbd19
  - libmariadbprivate
  - libmaxminddb-devel
  - libmaxminddb0
  - libmbim
  - libmbim-devel
  - libmbim-glib4
  - libmd-devel
  - libmd0
  - libmd4c0
  - libmediacheck6
  - libmemcached
  - libmemcached-devel
  - libmemcached11
  - libmemcachedprotocol0
  - libmemcachedutil2
  - libmetalink-devel
  - libmetalink3
  - libmetis5
  - libmetrics-devel
  - libmetrics0
  - libmgmt_be_nb0
  - libmicrodns1
  - libmicrohttpd-devel
  - libmicrohttpd12
  - libmilter1_0
  - libminizip1
  - libmjpegutils-2_2-0
  - libmlx4-1
  - libmlx5-1
  - libmm-glib0
  - libmng-devel
  - libmng2
  - libmnl-devel
  - libmnl0
  - libmodbus5
  - libmodulemd-devel
  - libmodulemd2
  - libmount-devel
  - libmount-devel-static
  - libmount1
  - libmowgli-2-0
  - libmowgli2-devel
  - libmozjs-128-0
  - libmp3lame0
  - libmpath0
  - libmpc3
  - libmpcdec6
  - libmpdec++3
  - libmpdec3
  - libmpeg2-0
  - libmpeg2convert0
  - libmpeg2encpp-2_2-0
  - libmpfr6
  - libmpg123-0
  - libmplex2-2_2-0
  - libmspack-devel
  - libmspack0
  - libmtdev1
  - libmtp-devel
  - libmtp-udev
  - libmtp9
  - libmysofa1
  - libnautilus-extension4
  - libnbd
  - libnbd-bash-completion
  - libnbd0
  - libncurses5
  - libncurses6
  - libndp
  - libndp-devel
  - libndp0
  - libneon-devel
  - libneon27
  - libnet-devel
  - libnet-doc
  - libnet9
  - libnetfilter_conntrack-devel
  - libnetfilter_conntrack3
  - libnetfilter_cthelper-devel
  - libnetfilter_cthelper0
  - libnetfilter_cttimeout-devel
  - libnetfilter_cttimeout1
  - libnetfilter_queue-devel
  - libnetfilter_queue1
  - libnetlink-devel
  - libnetpbm-devel
  - libnetpbm11
  - libnettle-devel
  - libnettle8
  - libnewt0_52
  - libnfnetlink-devel
  - libnfnetlink0
  - libnfs-devel
  - libnfs14
  - libnfsidmap-sss
  - libnfsidmap1
  - libnftables1
  - libnftnl-devel
  - libnftnl11
  - libnghttp2-14
  - libnghttp2-devel
  - libnice
  - libnice-devel
  - libnice10
  - libnl-config
  - libnl-tools
  - libnl3-200
  - libnl3-devel
  - libnm0
  - libnma-docs
  - libnma-glib-schema
  - libnma-gtk4-0
  - libnma-lang
  - libnma0
  - libnotify-devel
  - libnotify-tools
  - libnotify4
  - libnozzle-devel
  - libnozzle1
  - libnpth0
  - libnscd-devel
  - libnscd1
  - libnss_usrfiles2
  - libntfs-3g-devel
  - libntfs-3g89
  - libntlm-devel
  - libntlm0
  - libnuma-devel
  - libnuma1
  - libnuspell5
  - libnutclient2
  - libnutclientstub1
  - libnutscan2
  - libnvidia-egl-gbm-devel
  - libnvidia-egl-gbm1
  - libnvidia-egl-x11-devel
  - libnvidia-egl-x111
  - libnvme-devel
  - libnvme-mi1
  - libnvme1
  - liboath-devel
  - liboath0
  - libobjc4
  - libodbc2
  - libogg0
  - liboldX-devel
  - liboldX6
  - libonig5
  - libopenal0
  - libopenal1
  - libopenblas_openmp-devel
  - libopenblas_openmp0
  - libopenblas_pthreads-devel
  - libopenblas_pthreads0
  - libopenblas_serial-devel
  - libopenblas_serial0
  - libopencore-amrnb0
  - libopencore-amrwb0
  - libopencsd1
  - libopencsd_c_api1
  - libopeniscsiusr0
  - libopenjp2-7
  - libopenmpt0
  - libopenscap33
  - libopenscap_sce33
  - libopensm9
  - libopenssl-3-devel
  - libopenssl-3-fips-provider
  - libopenssl-devel
  - libopenssl-fips-provider
  - libopenssl3
  - libopenvswitch-3_5-0
  - libopts25
  - libopus0
  - liborc-0_4-0
  - libosinfo
  - libosinfo-1_0-0
  - libosmcomp5
  - libosmvendor5
  - libostree
  - libostree-1-1
  - libostree-devel
  - libotf
  - libotf-devel
  - libotf1
  - libout123-0
  - libovn-25_03-0
  - libp11-3
  - libp11-kit0
  - libpackagekit-glib2-18
  - libpamtest-devel-doc
  - libpanel-1-1
  - libpanel-lang
  - libpango-1_0-0
  - libpangomm-1_4-1
  - libpaper
  - libpaper-devel
  - libpaper-tools
  - libpaper2
  - libparanoia1_0
  - libparted-fs-resize0
  - libparted2
  - libpath_utils-devel
  - libpath_utils1
  - libpathplan4
  - libpcap-devel
  - libpcap1
  - libpcaudio0
  - libpci3
  - libpciaccess-devel
  - libpciaccess0
  - libpcp-devel
  - libpcp3
  - libpcp_gui2
  - libpcp_import1
  - libpcp_mmv1
  - libpcp_trace2
  - libpcp_web1
  - libpcre1
  - libpcre16-0
  - libpcre2-16-0
  - libpcre2-32-0
  - libpcre2-8-0
  - libpcre2-posix3
  - libpcrecpp0
  - libpcreposix0
  - libpcsclite1
  - libpcscspy0
  - libpfm-devel
  - libpfm-devel-static
  - libpfm4
  - libpgm-5_3-0
  - libphonenumber-devel
  - libphonenumber8
  - libpipeline-devel
  - libpipeline1
  - libpipewire-0_3-0
  - libpixman-1-0
  - libpixman-1-0-devel
  - libpkcs11-helper1
  - libpkgconf-devel
  - libpkgconf5
  - libplacebo349
  - libplist++-2_0-4
  - libplist++-2_0-devel
  - libplist-2_0-4
  - libplist-2_0-devel
  - libplot2
  - libplotter2
  - libply-boot-client5
  - libply-splash-core5
  - libply-splash-graphics5
  - libply5
  - libpng16-16
  - libpng16-compat-devel
  - libpng16-devel
  - libpng16-tools
  - libpolkit-agent-1-0
  - libpolkit-gobject-1-0
  - libpoppler-cpp2
  - libpoppler-devel
  - libpoppler-glib8
  - libpoppler-qt6-3
  - libpoppler145
  - libpopt0
  - libportal-devel
  - libportal-gtk3-1
  - libportal-gtk3-devel
  - libportal-gtk4-1
  - libportal-gtk4-devel
  - libportal-qt6-1
  - libportal1
  - libportaudio2
  - libportaudiocpp0
  - libpostproc58
  - libpowerman0
  - libpq5
  - libproc2-1
  - libprofiler0
  - libprotobuf-c1
  - libprotobuf-lite28_3_0
  - libprotobuf-lite3_21_12
  - libprotobuf28_3_0
  - libprotobuf3_21_12
  - libprotoc28_3_0
  - libprotoc3_21_12
  - libproxy-devel
  - libproxy-tools
  - libproxy1
  - libpskc-devel
  - libpskc0
  - libpsl-devel
  - libpsl5
  - libpspell15
  - libpsx2
  - libpulse-devel
  - libpulse-mainloop-glib0
  - libpulse0
  - libpwquality-devel
  - libpwquality-lang
  - libpwquality-tools
  - libpwquality1
  - libpxbackend-1_0
  - libpython3_11-1_0
  - libpython3_13-1_0
  - libqb-devel
  - libqb-tools
  - libqb100
  - libqca-qt6-2
  - libqgpgmeqt6-15
  - libqmi-devel
  - libqmi-glib5
  - libqmi-tools
  - libqrencode4
  - libqrtr-glib-devel
  - libqrtr-glib-devel-doc
  - libqrtr-glib0
  - libquicktime0
  - libraptor2-0
  - librav1e0_7
  - libraw-devel
  - libraw-devel-static
  - libraw-tools
  - libraw1394-11
  - libraw1394-devel
  - libraw1394-tools
  - libraw23
  - librcc-devel
  - librcc0
  - librcd-devel
  - librcd0
  - librdmacm-utils
  - librdmacm1
  - librdtk0-0
  - libre2-10
  - libreadline-java
  - libreadline-java-javadoc
  - libreadline8
  - libref_array-devel
  - libref_array1
  - libreplaygain1
  - librepo-devel
  - librepo0
  - librest-1_0-0
  - librhash1
  - librist4
  - librmt-devel-doc
  - librmt1_0
  - librpmbuild9
  - librrd8
  - librscg1_0
  - librsvg-2-2
  - librsvg-devel
  - librsync-devel
  - librsync2
  - librtr0
  - librubberband2
  - libruby3_4-3_4
  - libsaml13
  - libsamplerate-devel
  - libsamplerate0
  - libsasl2-3
  - libsbc1
  - libscg-devel
  - libscg1_0
  - libscgcmd1_0
  - libschily-devel
  - libschily-devel-doc
  - libschily2_0
  - libschroedinger-1_0-0
  - libseccomp-devel
  - libseccomp-tools
  - libseccomp2
  - libsecret-1-0
  - libsecret-devel
  - libsecret-lang
  - libselinux-devel
  - libselinux-devel-static
  - libselinux1
  - libsemanage-conf
  - libsemanage-devel
  - libsemanage-devel-static
  - libsemanage-migrate-store
  - libsemanage2
  - libsensors4
  - libsensors4-devel
  - libsepol-devel
  - libsepol-devel-static
  - libsepol-utils
  - libsepol2
  - libserd-0-0
  - libsgutils-devel
  - libsgutils2-1_48-2
  - libsha1detectcoll-devel
  - libsha1detectcoll1
  - libshaderc_shared1
  - libsharpyuv0
  - libshibsp-lite12
  - libshibsp12
  - libshout3
  - libsigc++2-devel
  - libsigc++3-devel
  - libsigc-2_0-0
  - libsigc-3_0-0
  - libslang2
  - libslirp-devel
  - libslirp0
  - libslp1
  - libsmartcols-devel
  - libsmartcols-devel-static
  - libsmartcols1
  - libsmi
  - libsmi-devel
  - libsmi2
  - libsnapper-devel
  - libsnapper7
  - libsnappy1
  - libsndfile1
  - libsnmp40
  - libsodium-devel
  - libsodium26
  - libsoftokn3
  - libsolv-demo
  - libsolv-devel
  - libsolv-tools
  - libsolv-tools-base
  - libsord-0-0
  - libsoup-2_4-1
  - libsoup-3_0-0
  - libsoup-devel
  - libsoup-lang
  - libsoup2-devel
  - libsoup2-lang
  - libsource-highlight-devel
  - libsource-highlight4
  - libsoxr-lsr0
  - libsoxr0
  - libspandsp3
  - libspeechd-devel
  - libspeechd2
  - libspeechd_module0
  - libspeex1
  - libspeexdsp1
  - libspiro-devel
  - libspiro1
  - libsqlite3-0
  - libsratom-0-0
  - libsrt1_5
  - libsrtp-devel
  - libsrtp1
  - libsrtp2-1
  - libssh-config
  - libssh-devel
  - libssh2-1
  - libssh2-devel
  - libssh4
  - libsss_certmap-devel
  - libsss_certmap0
  - libsss_idmap-devel
  - libsss_idmap0
  - libsss_nss_idmap-devel
  - libsss_nss_idmap0
  - libstartup-notification-1-0
  - libstdc++-devel
  - libstdc++6
  - libstdc++6-devel-gcc15
  - libstdc++6-locale
  - libstdc++6-pp
  - libstemmer1d
  - libstoragemgmt
  - libstoragemgmt-arcconf-plugin
  - libstoragemgmt-devel
  - libstoragemgmt-hpsa-plugin
  - libstoragemgmt-local-plugin
  - libstoragemgmt-megaraid-plugin
  - libstoragemgmt-nfs-plugin
  - libstoragemgmt-targetd-plugin
  - libstoragemgmt-udev
  - libstoragemgmt1
  - libsubid-devel
  - libsubid5
  - libsuseconnect
  - libsvrcore0
  - libswresample5
  - libswscale8
  - libsybdb5
  - libsyn123-0
  - libsysfs2
  - libsysprof-6-6
  - libsystemd0
  - libtag1
  - libtag_c0
  - libtalloc-devel
  - libtalloc2
  - libtasn1-6
  - libtasn1-devel
  - libtasn1-tools
  - libtcmalloc4
  - libtcmalloc_and_profiler4
  - libtcmalloc_debug4
  - libtcmalloc_minimal4
  - libtcmalloc_minimal_debug4
  - libtcnative-1-0
  - libtdb-devel
  - libtdb1
  - libtdsodbc0
  - libtelepathy-glib0
  - libtevent-devel
  - libtevent0
  - libtextstyle-devel
  - libtextstyle0
  - libthai-data
  - libthai-devel
  - libthai0
  - libtheora0
  - libtheoradec1
  - libtheoraenc1
  - libtidy-devel
  - libtidy58
  - libtidyp-1_04-0
  - libtidyp-devel
  - libtiff-devel
  - libtiff6
  - libtirpc-devel
  - libtirpc-netconfig
  - libtirpc3
  - libtool
  - libtotem-plparser18
  - libtpl-extensions3
  - libtpm_unseal1
  - libtpms0
  - libtraceevent-devel
  - libtraceevent1
  - libtraceevent1-plugins
  - libtracefs-devel
  - libtracefs-tools
  - libtracefs1
  - libtracker-sparql-3_0-0
  - libtree-sitter0_25
  - libts0
  - libtsan2
  - libtspi1
  - libtss2-esys0
  - libtss2-fapi-common
  - libtss2-fapi1
  - libtss2-mu0
  - libtss2-policy0
  - libtss2-rc0
  - libtss2-sys1
  - libtss2-tcti-cmd0
  - libtss2-tcti-device0
  - libtss2-tcti-i2c-helper0
  - libtss2-tcti-mssim0
  - libtss2-tcti-pcap0
  - libtss2-tcti-spi-helper0
  - libtss2-tcti-spidev0
  - libtss2-tcti-swtpm0
  - libtss2-tcti-tabrmd0
  - libtss2-tctildr0
  - libtukit-devel
  - libtukit4
  - libturbojpeg0
  - libtwolame0
  - libubsan1
  - libuchardet-devel
  - libuchardet0
  - libucm-devel
  - libucm0
  - libucp-devel
  - libucp0
  - libucs-devel
  - libucs0
  - libuct-devel
  - libuct0
  - libudev1
  - libudf0
  - libudisks2-0
  - libudisks2-0-devel
  - libudisks2-0_btrfs
  - libudisks2-0_lsm
  - libudisks2-0_lvm2
  - libulockmgr1
  - libumockdev-preload0
  - libumockdev0
  - libunbound8
  - libunibreak5
  - libunistring-devel
  - libunistring5
  - libunwind-devel
  - libunwind-ptrace0
  - libunwind-setjmp0
  - libunwind8
  - libupb36
  - libupower-glib-devel
  - libupower-glib3
  - libupsclient6
  - liburcu-devel
  - liburcu8
  - liburing-devel
  - liburing-ffi2
  - liburing2
  - liburiparser1
  - libusb-0_1-4
  - libusb-1_0-0
  - libusb-1_0-devel
  - libusb-compat-devel
  - libusbguard1
  - libusbmuxd-2_0-6
  - libusbmuxd-devel
  - libusbmuxd-tools
  - libusbredirparser1
  - libutf8_range-28_3_0
  - libutf8proc3
  - libuuid-devel
  - libuuid-devel-static
  - libuuid1
  - libuv-devel
  - libuv1
  - libuwac0-0
  - libv4l
  - libv4l1-0
  - libv4l2-0
  - libv4l2rds0
  - libv4lconvert0
  - libva-devel
  - libva-drm2
  - libva-glx2
  - libva-wayland2
  - libva-x11-2
  - libva2
  - libvala-0_56-0
  - libvala-0_56-devel
  - libvaladoc-0_56-0
  - libvcdinfo0
  - libvdeplug3
  - libvdpau-devel
  - libvdpau1
  - libvdpau_trace1
  - libverto-devel
  - libverto-glib-devel
  - libverto-glib1
  - libverto-libev-devel
  - libverto-libev1
  - libverto1
  - libvidstab1_2
  - libvirglrenderer1
  - libvirt-client
  - libvirt-client-qemu
  - libvirt-daemon
  - libvirt-daemon-common
  - libvirt-daemon-config-network
  - libvirt-daemon-config-nwfilter
  - libvirt-daemon-driver-network
  - libvirt-daemon-driver-nodedev
  - libvirt-daemon-driver-nwfilter
  - libvirt-daemon-driver-qemu
  - libvirt-daemon-driver-secret
  - libvirt-daemon-driver-storage
  - libvirt-daemon-driver-storage-core
  - libvirt-daemon-driver-storage-disk
  - libvirt-daemon-driver-storage-iscsi
  - libvirt-daemon-driver-storage-iscsi-direct
  - libvirt-daemon-driver-storage-logical
  - libvirt-daemon-driver-storage-mpath
  - libvirt-daemon-driver-storage-scsi
  - libvirt-daemon-hooks
  - libvirt-daemon-lock
  - libvirt-daemon-log
  - libvirt-daemon-plugin-lockd
  - libvirt-daemon-proxy
  - libvirt-daemon-qemu
  - libvirt-dbus
  - libvirt-devel
  - libvirt-doc
  - libvirt-glib-1_0-0
  - libvirt-glib-devel
  - libvirt-libs
  - libvirt-nss
  - libvirt-ssh-proxy
  - libvisual-0_4-0
  - libvmaf1
  - libvncclient1
  - libvncserver1
  - libvo-amrwbenc0
  - libvoikko-devel
  - libvoikko1
  - libvorbis0
  - libvorbisenc2
  - libvorbisfile3
  - libvpd-2_2-3
  - libvpd-base
  - libvpd-devel
  - libvpx9
  - libvte-2_91-0
  - libvulkan1
  - libwacom-data
  - libwacom-devel
  - libwacom-tools
  - libwacom9
  - libwavpack1
  - libwayland-client0
  - libwayland-cursor0
  - libwayland-egl1
  - libwayland-server0
  - libwebkit2gtk-4_0-37
  - libwebkit2gtk-4_1-0
  - libwebkitgtk-6_0-4
  - libwebp-devel
  - libwebp7
  - libwebpdecoder3
  - libwebpdemux2
  - libwebpmux3
  - libwebrtc_audio_processing-devel
  - libwebrtc_audio_processing-devel-static
  - libwebrtc_audio_processing1
  - libwinpr3-3
  - libwireplumber-0_5-0
  - libwireshark18
  - libwiretap15
  - libwmf-0_2-7
  - libwmf-devel
  - libwmf-gnome
  - libwmf-tools
  - libwoff2common1_0_2
  - libwoff2dec1_0_2
  - libwoff2enc1_0_2
  - libwpe-1_0-1
  - libwpe-devel
  - libwrap0
  - libwsutil16
  - libwtmpdb0
  - libx86emu-devel
  - libx86emu3
  - libxcb-composite0
  - libxcb-cursor0
  - libxcb-damage0
  - libxcb-dbe0
  - libxcb-devel
  - libxcb-devel-doc
  - libxcb-dpms0
  - libxcb-dri2-0
  - libxcb-dri3-0
  - libxcb-ewmh2
  - libxcb-glx0
  - libxcb-icccm4
  - libxcb-image0
  - libxcb-keysyms1
  - libxcb-present0
  - libxcb-randr0
  - libxcb-record0
  - libxcb-render-util0
  - libxcb-render0
  - libxcb-res0
  - libxcb-screensaver0
  - libxcb-shape0
  - libxcb-shm0
  - libxcb-sync1
  - libxcb-util1
  - libxcb-xf86dri0
  - libxcb-xfixes0
  - libxcb-xinerama0
  - libxcb-xinput0
  - libxcb-xkb1
  - libxcb-xtest0
  - libxcb-xv0
  - libxcb-xvmc0
  - libxcb1
  - libxcrypt-devel
  - libxcrypt-devel-static
  - libxcvt
  - libxcvt-devel
  - libxcvt0
  - libxerces-c-3_3
  - libxkbcommon-devel
  - libxkbcommon-tools
  - libxkbcommon-x11-0
  - libxkbcommon-x11-devel
  - libxkbcommon0
  - libxkbfile-devel
  - libxkbfile1
  - libxkbregistry-devel
  - libxkbregistry0
  - libxkbui-devel
  - libxkbui1
  - libxklavier-devel
  - libxklavier-doc
  - libxklavier16
  - libxmi0
  - libxml++-3_0-1
  - libxml++-5_0-1
  - libxml++-devel
  - libxml++30-devel
  - libxml-security-c30
  - libxml2-2
  - libxml2-devel
  - libxml2-doc
  - libxml2-tools
  - libxmlb-devel
  - libxmlb2
  - libxmlrpc++8
  - libxmlrpc3
  - libxmlrpc_abyss++8
  - libxmlrpc_abyss3
  - libxmlrpc_client++8
  - libxmlrpc_client3
  - libxmlrpc_cpp8
  - libxmlrpc_packetsocket8
  - libxmlrpc_server++8
  - libxmlrpc_server3
  - libxmlrpc_server_abyss++8
  - libxmlrpc_server_abyss3
  - libxmlrpc_server_cgi++8
  - libxmlrpc_server_cgi3
  - libxmlrpc_server_pstream++8
  - libxmlrpc_util++8
  - libxmlrpc_util4
  - libxmlsec1-1
  - libxmlsec1-gcrypt1
  - libxmlsec1-gnutls1
  - libxmlsec1-nss1
  - libxmlsec1-openssl1
  - libxmltooling-lite11
  - libxmltooling11
  - libxshmfence-devel
  - libxshmfence1
  - libxslt-devel
  - libxslt-tools
  - libxslt1
  - libxtables-devel
  - libxtables12
  - libxtermcap1_0
  - libxxhash0
  - libyajl-devel
  - libyajl-devel-static
  - libyajl2
  - libyaml-0-2
  - libyaml-cpp0_8
  - libyaml-devel
  - libyang2
  - libyuv0
  - libz1
  - libzbar0
  - libzck-devel
  - libzck1
  - libzimg2
  - libzio-devel
  - libzio1
  - libzip-devel
  - libzip-tools
  - libzip5
  - libzmq5
  - libzopfli-devel
  - libzopfli1
  - libzopflipng1
  - libzstd-devel
  - libzstd-devel-static
  - libzstd1
  - libzvbi-chains0
  - libzvbi0
  - libzypp
  - libzypp-devel
  - libzypp-devel-doc
  - libzypp-plugin-appdata
  - lilv
  - linux-atm
  - linux-atm-devel
  - linux-glibc-devel
  - linuxptp
  - live-langset-data
  - lksctp-tools
  - lksctp-tools-devel
  - lmdb
  - lmdb-devel
  - lndir
  - local-npm-registry
  - localsearch
  - log4cplus-devel
  - log4j-over-slf4j
  - login_defs
  - logrotate
  - lsb-release
  - lshw
  - lsof
  - lsscsi
  - ltrace
  - lua-macros
  - lua-rrdtool
  - lua51
  - lua51-devel
  - lua51-doc
  - lua51-luafilesystem
  - lua51-luaposix
  - lua51-luarocks
  - lua51-luaterm
  - lua53
  - lua53-devel
  - lua53-doc
  - lua53-luafilesystem
  - lua53-luaposix
  - lua53-luarocks
  - lua53-luaterm
  - lua54
  - lua54-devel
  - lua54-doc
  - lua54-luafilesystem
  - lua54-luaposix
  - lua54-luarocks
  - lua54-luaterm
  - luaposix-doc
  - luit
  - lv2
  - lv2-docs
  - lvm2
  - lvm2-devel
  - lvm2-lockd
  - lz4
  - lzfse
  - lzip
  - lzo-devel
  - lzo-devel-static
  - lzop
  - m17n-db
  - m17n-db-lang
  - m17n-lib
  - m17n-lib-devel
  - m4
  - mailutils
  - mailutils-delivery
  - mailutils-devel
  - mailutils-imap4d
  - mailutils-mh
  - mailutils-notify
  - mailutils-pop3d
  - mailx
  - make
  - make-lang
  - makedumpfile
  - makeinfo
  - makeinfo-lang
  - malaga-suomi
  - malcontent
  - malcontent-control
  - malcontent-devel
  - malcontent-lang
  - man
  - man-pages
  - man-pages-posix
  - mandoc
  - mandoc-bin
  - mariadb
  - mariadb-bench
  - mariadb-client
  - mariadb-errormessages
  - mariadb-tools
  - maven
  - maven-archiver
  - maven-archiver-javadoc
  - maven-artifact-transfer
  - maven-artifact-transfer-javadoc
  - maven-assembly-plugin
  - maven-assembly-plugin-javadoc
  - maven-bundle-plugin
  - maven-bundle-plugin-javadoc
  - maven-common-artifact-filters
  - maven-common-artifact-filters-javadoc
  - maven-compiler-plugin
  - maven-compiler-plugin-javadoc
  - maven-dependency-analyzer
  - maven-dependency-analyzer-javadoc
  - maven-dependency-plugin
  - maven-dependency-plugin-javadoc
  - maven-dependency-tree
  - maven-dependency-tree-javadoc
  - maven-doxia-core
  - maven-doxia-javadoc
  - maven-doxia-module-apt
  - maven-doxia-module-fml
  - maven-doxia-module-xdoc
  - maven-doxia-module-xhtml5
  - maven-doxia-sink-api
  - maven-doxia-sitetools
  - maven-doxia-sitetools-javadoc
  - maven-doxia-test-docs
  - maven-failsafe-plugin
  - maven-file-management
  - maven-file-management-javadoc
  - maven-filtering
  - maven-filtering-javadoc
  - maven-invoker
  - maven-invoker-javadoc
  - maven-invoker-plugin
  - maven-invoker-plugin-javadoc
  - maven-jar-plugin
  - maven-jar-plugin-javadoc
  - maven-javadoc
  - maven-javadoc-plugin
  - maven-javadoc-plugin-javadoc
  - maven-lib
  - maven-local
  - maven-mapping
  - maven-mapping-javadoc
  - maven-parent
  - maven-plugin-annotations
  - maven-plugin-plugin
  - maven-plugin-plugin-javadoc
  - maven-plugin-tools-annotations
  - maven-plugin-tools-ant
  - maven-plugin-tools-api
  - maven-plugin-tools-beanshell
  - maven-plugin-tools-generators
  - maven-plugin-tools-java
  - maven-plugin-tools-javadoc
  - maven-plugin-tools-model
  - maven-reporting-api
  - maven-reporting-api-javadoc
  - maven-reporting-impl
  - maven-reporting-impl-javadoc
  - maven-resolver
  - maven-resolver-api
  - maven-resolver-connector-basic
  - maven-resolver-impl
  - maven-resolver-javadoc
  - maven-resolver-named-locks
  - maven-resolver-spi
  - maven-resolver-test-util
  - maven-resolver-transport-classpath
  - maven-resolver-transport-file
  - maven-resolver-transport-http
  - maven-resolver-transport-wagon
  - maven-resolver-util
  - maven-resources-plugin
  - maven-resources-plugin-javadoc
  - maven-script-ant
  - maven-script-beanshell
  - maven-script-interpreter
  - maven-script-interpreter-javadoc
  - maven-shared-incremental
  - maven-shared-incremental-javadoc
  - maven-shared-io
  - maven-shared-io-javadoc
  - maven-shared-utils
  - maven-shared-utils-javadoc
  - maven-surefire
  - maven-surefire-javadoc
  - maven-surefire-plugin
  - maven-surefire-plugins-javadoc
  - maven-surefire-provider-junit
  - maven-surefire-provider-junit5
  - maven-surefire-provider-junit5-javadoc
  - maven-surefire-provider-testng
  - maven-surefire-report-parser
  - maven-surefire-report-plugin
  - maven-wagon-file
  - maven-wagon-ftp
  - maven-wagon-http
  - maven-wagon-http-lightweight
  - maven-wagon-http-shared
  - maven-wagon-javadoc
  - maven-wagon-provider-api
  - maven-wagon-ssh
  - maven-wagon-ssh-common
  - maven-wagon-ssh-external
  - mbimcli-bash-completion
  - mcstrans
  - mdadm
  - mdevctl
  - memcached
  - memcached-devel
  - mercurial
  - mercurial-lang
  - meson
  - metatheme-adwaita-common
  - metis
  - metis-devel
  - metis-doc
  - metis-examples
  - microos-devel-tools
  - microos-tools
  - minizip-devel
  - mjpegtools
  - mkisofs
  - mksh
  - mmdblookup
  - mobile-broadband-provider-info
  - modello
  - modello-javadoc
  - modello-maven-plugin
  - modello-maven-plugin-javadoc
  - modulemaker-maven-plugin
  - modulemaker-maven-plugin-javadoc
  - modulemd-validator
  - mojo-parent
  - mozilla-nspr
  - mozilla-nspr-devel
  - mozilla-nss
  - mozilla-nss-certs
  - mozilla-nss-devel
  - mozilla-nss-sysinit
  - mozilla-nss-tools
  - mozjs128
  - mozjs128-devel
  - mpc-devel
  - mpdecimal-devel
  - mpeg2dec
  - mpfr-devel
  - mpg123
  - mpg123-jack
  - mpg123-openal
  - mpg123-portaudio
  - mpg123-pulse
  - mpg123-sdl
  - mpi-selector
  - mpt-firmware
  - mspack-examples
  - mstflint
  - mtdev
  - mtdev-devel
  - mtools
  - mtools-doc
  - mtp-tools
  - mujs
  - mujs-devel
  - multipath-tools
  - multipath-tools-devel
  - musepack
  - mutt
  - mutt-doc
  - mutt-lang
  - mutter
  - mutter-devel
  - mutter-lang
  - myspell-af_NA
  - myspell-af_ZA
  - myspell-an
  - myspell-an_ES
  - myspell-ar
  - myspell-ar_AE
  - myspell-ar_BH
  - myspell-ar_DZ
  - myspell-ar_EG
  - myspell-ar_IQ
  - myspell-ar_JO
  - myspell-ar_KW
  - myspell-ar_LB
  - myspell-ar_LY
  - myspell-ar_MA
  - myspell-ar_OM
  - myspell-ar_QA
  - myspell-ar_SA
  - myspell-ar_SD
  - myspell-ar_SY
  - myspell-ar_TN
  - myspell-ar_YE
  - myspell-be_BY
  - myspell-bg_BG
  - myspell-bn_BD
  - myspell-bn_IN
  - myspell-bo
  - myspell-bo_CN
  - myspell-bo_IN
  - myspell-br_FR
  - myspell-bs
  - myspell-bs_BA
  - myspell-ca
  - myspell-ca_AD
  - myspell-ca_ES
  - myspell-ca_ES_valencia
  - myspell-ca_FR
  - myspell-ca_IT
  - myspell-ckb
  - myspell-ckb_IQ
  - myspell-ckb_IR
  - myspell-cs_CZ
  - myspell-da_DK
  - myspell-de
  - myspell-de_AT
  - myspell-de_CH
  - myspell-de_DE
  - myspell-dictionaries
  - myspell-el_GR
  - myspell-en
  - myspell-en_AU
  - myspell-en_BS
  - myspell-en_BZ
  - myspell-en_CA
  - myspell-en_GB
  - myspell-en_GH
  - myspell-en_IE
  - myspell-en_IL
  - myspell-en_IN
  - myspell-en_JM
  - myspell-en_MW
  - myspell-en_NA
  - myspell-en_NZ
  - myspell-en_PH
  - myspell-en_TT
  - myspell-en_US
  - myspell-en_ZA
  - myspell-en_ZW
  - myspell-eo
  - myspell-es
  - myspell-es_AR
  - myspell-es_BO
  - myspell-es_CL
  - myspell-es_CO
  - myspell-es_CR
  - myspell-es_CU
  - myspell-es_DO
  - myspell-es_EC
  - myspell-es_ES
  - myspell-es_GQ
  - myspell-es_GT
  - myspell-es_HN
  - myspell-es_MX
  - myspell-es_NI
  - myspell-es_PA
  - myspell-es_PE
  - myspell-es_PH
  - myspell-es_PR
  - myspell-es_PY
  - myspell-es_SV
  - myspell-es_US
  - myspell-es_UY
  - myspell-es_VE
  - myspell-et_EE
  - myspell-fa_IR
  - myspell-fr_BE
  - myspell-fr_CA
  - myspell-fr_CH
  - myspell-fr_FR
  - myspell-fr_LU
  - myspell-fr_MC
  - myspell-gd_GB
  - myspell-gl
  - myspell-gl_ES
  - myspell-gu_IN
  - myspell-gug
  - myspell-gug_PY
  - myspell-he_IL
  - myspell-hi_IN
  - myspell-hr_HR
  - myspell-hu_HU
  - myspell-id
  - myspell-id_ID
  - myspell-is
  - myspell-is_IS
  - myspell-it_IT
  - myspell-kmr_Latn
  - myspell-kmr_Latn_SY
  - myspell-kmr_Latn_TR
  - myspell-ko_KR
  - myspell-lightproof-en
  - myspell-lightproof-hu_HU
  - myspell-lightproof-pt_BR
  - myspell-lightproof-ru_RU
  - myspell-lo_LA
  - myspell-lt_LT
  - myspell-lv_LV
  - myspell-mn_Cyrl_MN
  - myspell-mn_MN
  - myspell-nb_NO
  - myspell-ne_NP
  - myspell-nl_BE
  - myspell-nl_NL
  - myspell-nn_NO
  - myspell-no
  - myspell-oc_FR
  - myspell-oc_FR_lengadoc
  - myspell-pl_PL
  - myspell-pt_BR
  - myspell-pt_PT
  - myspell-ro
  - myspell-ro_RO
  - myspell-ru_RU
  - myspell-si_LK
  - myspell-sk_SK
  - myspell-sl_SI
  - myspell-sq_AL
  - myspell-sr
  - myspell-sr_CS
  - myspell-sr_Latn_CS
  - myspell-sr_Latn_RS
  - myspell-sr_RS
  - myspell-sv_FI
  - myspell-sv_SE
  - myspell-sw_TZ
  - myspell-te
  - myspell-te_IN
  - myspell-th_TH
  - myspell-tr
  - myspell-tr_TR
  - myspell-uk_UA
  - myspell-vi
  - myspell-vi_VN
  - myspell-zu_ZA
  - mysql-connector-java
  - nautilus
  - nbd
  - nbdfuse
  - nbdkit
  - nbdkit-basic-filters
  - nbdkit-basic-plugins
  - nbdkit-curl-plugin
  - nbdkit-linuxdisk-plugin
  - nbdkit-server
  - nbdkit-ssh-plugin
  - ncat
  - ncurses-devel
  - ncurses-devel-static
  - ncurses-examples
  - ncurses-utils
  - ncurses5-devel
  - ncurses5-devel-static
  - net-snmp
  - net-snmp-devel
  - net-tools
  - net-tools-deprecated
  - net-tools-lang
  - netavark
  - netcat-openbsd
  - netcfg
  - nethogs
  - netpbm
  - nettle
  - newt
  - newt-devel
  - newt-doc
  - newt-static
  - nfs-client
  - nfs-kernel-server
  - nfsidmap-devel
  - nftables
  - nftables-devel
  - nghttp2
  - nginx
  - nginx-macros
  - nginx-source
  - ninja
  - nmap
  - nodejs-common
  - nodejs-default
  - nodejs-devel-default
  - nodejs22
  - nodejs22-devel
  - nodejs22-docs
  - novnc
  - npm-default
  - npm22
  - npth-devel
  - nss-mdns
  - ntfs-3g
  - ntfsprogs
  - ntfsprogs-extra
  - numactl
  - nuspell
  - nuspell-devel
  - nuspell-doc
  - nut
  - nut-drivers-net
  - nvidia-libXNVCtrl
  - nvidia-settings
  - nvme-cli
  - nvme-cli-bash-completion
  - nvme-cli-regress-script
  - oath-toolkit
  - oath-toolkit-xml
  - objectweb-asm
  - objectweb-asm-javadoc
  - ocaml
  - ocaml-compiler-libs
  - ocaml-compiler-libs-devel
  - ocaml-parmap
  - ocaml-parmap-devel
  - ocaml-pcre2
  - ocaml-pcre2-devel
  - ocaml-runtime
  - ocaml-stdcompat
  - ocaml-stdcompat-devel
  - ocl-icd-devel
  - ongres-scram
  - ongres-scram-client
  - ongres-scram-javadoc
  - ongres-scram-parent
  - ongres-stringprep
  - ongres-stringprep-codegenerator
  - ongres-stringprep-javadoc
  - ongres-stringprep-parent
  - ongres-stringprep-saslprep
  - oniguruma-devel
  - open-iscsi
  - open-iscsi-devel
  - open-isns
  - open-isns-devel
  - open-lldp
  - open-lldp-devel
  - open-test-reporting-cli
  - open-test-reporting-events
  - open-test-reporting-javadoc
  - open-test-reporting-schema
  - open-test-reporting-tooling
  - openCryptoki
  - openCryptoki-64bit
  - openCryptoki-devel
  - openSUSE-appdata-extra
  - openSUSE-appstream-process
  - openal-soft-devel
  - openblas-common-devel
  - openblas_openmp-devel-static
  - openblas_pthreads-devel-static
  - openblas_serial-devel-static
  - opencensus-proto-source
  - opencl-headers
  - openexr
  - openexr-devel
  - openexr-doc
  - openjade
  - openjade-devel
  - openjpeg2
  - openjpeg2-devel
  - openjpeg2-devel-doc
  - openldap2
  - openldap2-back-meta
  - openldap2-back-perl
  - openldap2-back-sock
  - openldap2-back-sql
  - openldap2-client
  - openldap2-contrib
  - openldap2-devel
  - openldap2-devel-static
  - openldap2-doc
  - openmpi5
  - openmpi5-config
  - openmpi5-devel
  - openmpi5-docs
  - openmpi5-libs
  - openmpt123
  - openpgm-devel
  - opensaml-schemas
  - opensc
  - openscap
  - openscap-containers
  - openscap-content
  - openscap-utils
  - openslp
  - openslp-devel
  - openslp-server
  - opensm
  - opensm-devel
  - opensp
  - opensp-devel
  - opensp-doc
  - openssh
  - openssh-askpass-gnome
  - openssh-cavs
  - openssh-clients
  - openssh-common
  - openssh-fips
  - openssh-helpers
  - openssh-server
  - openssh-server-config-rootlogin
  - openssl
  - openssl-3
  - openssl-3-doc
  - openssl-engine-libp11
  - openssl-pkcs11-sign-provider
  - opentest4j
  - opentest4j-javadoc
  - openucx-tools
  - openvpn
  - openvpn-auth-pam-plugin
  - openvpn-devel
  - openvpn-down-root-plugin
  - openvswitch
  - openvswitch-devel
  - openvswitch-doc
  - openvswitch-ipsec
  - openvswitch-pki
  - openvswitch-vtep
  - orc
  - orc-doc
  - oro
  - oro-javadoc
  - os-update
  - osgi-annotation
  - osgi-annotation-javadoc
  - osgi-compendium
  - osgi-compendium-javadoc
  - osgi-core
  - osgi-core-javadoc
  - osgi-service-subsystem
  - osinfo-db
  - ovn
  - ovn-central
  - ovn-devel
  - ovn-doc
  - ovn-docker
  - ovn-host
  - ovn-vtep
  - p11-kit
  - p11-kit-devel
  - p11-kit-nss-trust
  - p11-kit-server
  - p11-kit-tools
  - pacemaker
  - pacemaker-cli
  - pacemaker-cts
  - pacemaker-devel
  - pacemaker-libs
  - pacemaker-remote
  - pacemaker-schemas
  - pam
  - pam-config
  - pam-devel
  - pam-extra
  - pam_cifscreds
  - pam_krb5
  - pam_oath
  - pam_pkcs11
  - pam_pkcs11-devel-doc
  - pam_pwquality
  - pam_snapper
  - pam_u2f
  - pango-devel
  - pango-tools
  - pangomm1_4-devel
  - parboiled
  - parboiled-javadoc
  - parted
  - parted-devel
  - parted-lang
  - passt
  - passt-selinux
  - patch
  - patchutils
  - patterns-base-base
  - patterns-base-basesystem
  - patterns-base-bootloader
  - patterns-base-documentation
  - patterns-base-enhanced_base
  - patterns-base-fips
  - patterns-base-minimal_base
  - patterns-base-selinux
  - patterns-base-sw_management
  - patterns-cockpit
  - patterns-container-runtime_docker
  - patterns-container-runtime_podman
  - patterns-devel-base-devel_basis
  - patterns-gnome-gnome
  - patterns-gnome-gnome_basic
  - patterns-gnome-gnome_basis
  - patterns-ha-ha_sles
  - patterns-server-dhcp_dns_server
  - patterns-server-directory_server
  - patterns-server-file_server
  - patterns-server-gateway_server
  - patterns-server-kvm_server
  - patterns-server-kvm_tools
  - patterns-server-lamp_server
  - patterns-server-mail_server
  - patterns-server-printing
  - pcaudiolib-devel
  - pciutils
  - pciutils-devel
  - pcp
  - pcp-conf
  - pcp-devel
  - pcp-doc
  - pcp-export-pcp2elasticsearch
  - pcp-export-pcp2graphite
  - pcp-export-pcp2influxdb
  - pcp-export-pcp2json
  - pcp-export-pcp2spark
  - pcp-export-pcp2xml
  - pcp-export-pcp2zabbix
  - pcp-import-collectl2pcp
  - pcp-import-ganglia2pcp
  - pcp-import-iostat2pcp
  - pcp-import-mrtg2pcp
  - pcp-import-sar2pcp
  - pcp-pmda-activemq
  - pcp-pmda-apache
  - pcp-pmda-bash
  - pcp-pmda-bonding
  - pcp-pmda-cifs
  - pcp-pmda-cisco
  - pcp-pmda-dbping
  - pcp-pmda-dm
  - pcp-pmda-docker
  - pcp-pmda-ds389
  - pcp-pmda-ds389log
  - pcp-pmda-elasticsearch
  - pcp-pmda-gfs2
  - pcp-pmda-gluster
  - pcp-pmda-gpfs
  - pcp-pmda-gpsd
  - pcp-pmda-hacluster
  - pcp-pmda-haproxy
  - pcp-pmda-json
  - pcp-pmda-lio
  - pcp-pmda-lmsensors
  - pcp-pmda-logger
  - pcp-pmda-lustre
  - pcp-pmda-lustrecomm
  - pcp-pmda-mailq
  - pcp-pmda-memcache
  - pcp-pmda-mic
  - pcp-pmda-mounts
  - pcp-pmda-mysql
  - pcp-pmda-named
  - pcp-pmda-netcheck
  - pcp-pmda-netfilter
  - pcp-pmda-news
  - pcp-pmda-nfsclient
  - pcp-pmda-nginx
  - pcp-pmda-nutcracker
  - pcp-pmda-nvidia-gpu
  - pcp-pmda-openmetrics
  - pcp-pmda-openvswitch
  - pcp-pmda-oracle
  - pcp-pmda-pdns
  - pcp-pmda-postfix
  - pcp-pmda-rabbitmq
  - pcp-pmda-redis
  - pcp-pmda-roomtemp
  - pcp-pmda-rsyslog
  - pcp-pmda-samba
  - pcp-pmda-sendmail
  - pcp-pmda-shping
  - pcp-pmda-slurm
  - pcp-pmda-smart
  - pcp-pmda-snmp
  - pcp-pmda-sockets
  - pcp-pmda-summary
  - pcp-pmda-systemd
  - pcp-pmda-trace
  - pcp-pmda-unbound
  - pcp-pmda-weblog
  - pcp-pmda-zimbra
  - pcp-pmda-zswap
  - pcp-system-tools
  - pcp-zeroconf
  - pcre-devel
  - pcre-devel-static
  - pcre-doc
  - pcre-tools
  - pcre2-devel
  - pcre2-devel-static
  - pcre2-doc
  - pcre2-tools
  - pcsc-ccid
  - pcsc-lite
  - pcsc-lite-devel
  - pcsc-tools
  - pegdown
  - pegdown-javadoc
  - perf
  - perftest
  - perl
  - perl-Algorithm-Diff
  - perl-Alien-Build
  - perl-Alien-Build-Plugin-Download-GitLab
  - perl-Alien-Libxml2
  - perl-Alien-Tidyp
  - perl-AnyEvent
  - perl-Archive-Cpio
  - perl-Archive-Extract
  - perl-Archive-Zip
  - perl-Authen-SASL
  - perl-B-COW
  - perl-B-Hooks-EndOfScope
  - perl-Bit-Vector
  - perl-Business-ISBN
  - perl-Business-ISBN-Data
  - perl-Business-ISMN
  - perl-Business-ISSN
  - perl-CGI
  - perl-CPAN-Meta-Check
  - perl-CPAN-Meta-Requirements
  - perl-Cairo
  - perl-Cairo-GObject
  - perl-Canary-Stability
  - perl-Capture-Tiny
  - perl-Carp-Clan
  - perl-Class-Accessor
  - perl-Class-Data-Inheritable
  - perl-Class-Factory-Util
  - perl-Class-Inspector
  - perl-Class-Singleton
  - perl-Class-Tiny
  - perl-Clone
  - perl-Config-AutoConf
  - perl-Config-IniFiles
  - perl-Convert-ASN1
  - perl-Crypt-DES
  - perl-Crypt-RC4
  - perl-Crypt-Rijndael
  - perl-Crypt-SSLeay
  - perl-DBD-SQLite
  - perl-DBD-mysql
  - perl-DBI
  - perl-DNS-LDNS
  - perl-Data-Compare
  - perl-Data-Dump
  - perl-Data-OptList
  - perl-Data-Uniqid
  - perl-Date-Calc
  - perl-Date-Manip
  - perl-Date-Simple
  - perl-DateTime
  - perl-DateTime-Calendar-Julian
  - perl-DateTime-Format-Builder
  - perl-DateTime-Format-Strptime
  - perl-DateTime-Locale
  - perl-DateTime-TimeZone
  - perl-Devel-CheckLib
  - perl-Devel-CoreStack
  - perl-Devel-Cycle
  - perl-Devel-Leak
  - perl-Devel-StackTrace
  - perl-Devel-Symdump
  - perl-Digest-HMAC
  - perl-Digest-Perl-MD5
  - perl-Digest-SHA1
  - perl-Dist-CheckConflicts
  - perl-Encode-EUCJPASCII
  - perl-Encode-HanExtra
  - perl-Encode-JIS2K
  - perl-Encode-Locale
  - perl-Error
  - perl-Eval-Closure
  - perl-Exception-Class
  - perl-Expect
  - perl-Exporter-Tiny
  - perl-ExtUtils-CChecker
  - perl-ExtUtils-Config
  - perl-ExtUtils-Depends
  - perl-ExtUtils-Helpers
  - perl-ExtUtils-InstallPaths
  - perl-ExtUtils-LibBuilder
  - perl-ExtUtils-MakeMaker
  - perl-ExtUtils-PkgConfig
  - perl-FFI-CheckLib
  - perl-FastCGI
  - perl-File-Copy-Recursive
  - perl-File-Find-Rule
  - perl-File-HomeDir
  - perl-File-Listing
  - perl-File-Path
  - perl-File-ShareDir
  - perl-File-ShareDir-Install
  - perl-File-Slurp
  - perl-File-Slurp-Unicode
  - perl-File-Slurper
  - perl-File-Which
  - perl-File-chdir
  - perl-Font-AFM
  - perl-Git
  - perl-Glib
  - perl-Glib-Object-Introspection
  - perl-Gtk3
  - perl-HTML-Form
  - perl-HTML-Format
  - perl-HTML-Parser
  - perl-HTML-Tagset
  - perl-HTML-Tidy
  - perl-HTML-Tree
  - perl-HTTP-Cookies
  - perl-HTTP-DAV
  - perl-HTTP-Daemon
  - perl-HTTP-Date
  - perl-HTTP-Message
  - perl-HTTP-Negotiate
  - perl-IO-CaptureOutput
  - perl-IO-HTML
  - perl-IO-Socket-SSL
  - perl-IO-String
  - perl-IO-Tty
  - perl-IO-stringy
  - perl-IPC-Run3
  - perl-IPC-System-Simple
  - perl-Importer
  - perl-JSON
  - perl-LWP-MediaTypes
  - perl-LWP-Protocol-https
  - perl-Lingua-Translit
  - perl-List-AllUtils
  - perl-List-MoreUtils
  - perl-List-MoreUtils-XS
  - perl-List-SomeUtils
  - perl-List-SomeUtils-XS
  - perl-List-UtilsBy
  - perl-Log-Log4perl
  - perl-MIME-Charset
  - perl-MRO-Compat
  - perl-MailTools
  - perl-Mixin-Linewise
  - perl-Mock-Config
  - perl-Module-Build
  - perl-Module-Build-Tiny
  - perl-Module-Implementation
  - perl-Module-Pluggable
  - perl-Module-Runtime
  - perl-Mojo-DOM58
  - perl-Net-DBus
  - perl-Net-HTTP
  - perl-Net-SMTP-SSL
  - perl-Net-SNMP
  - perl-Net-SSLeay
  - perl-Net-Telnet
  - perl-Number-Compare
  - perl-OLE-Storage_Lite
  - perl-PCP-LogImport
  - perl-PCP-LogSummary
  - perl-PCP-MMV
  - perl-PCP-PMDA
  - perl-Package-DeprecationManager
  - perl-Package-Stash
  - perl-Package-Stash-XS
  - perl-PadWalker
  - perl-Params-Util
  - perl-Params-Validate
  - perl-Params-ValidationCompiler
  - perl-Parse-RecDescent
  - perl-Parse-Yapp
  - perl-Path-Class
  - perl-Path-Tiny
  - perl-PerlIO-utf8_strict
  - perl-PerlMagick
  - perl-Pod-Coverage
  - perl-Pod-Coverage-TrustPod
  - perl-Pod-Eventual
  - perl-Pod-Parser
  - perl-Protocol-HTTP2
  - perl-RPC-XML
  - perl-Readonly
  - perl-Readonly-XS
  - perl-Regexp-Common
  - perl-Role-Tiny
  - perl-SGMLS
  - perl-SNMP
  - perl-Scope-Guard
  - perl-Socket6
  - perl-Sort-Key
  - perl-Sort-Versions
  - perl-Specio
  - perl-Spiffy
  - perl-Spreadsheet-ParseExcel
  - perl-Sub-Exporter
  - perl-Sub-Exporter-Progressive
  - perl-Sub-Identify
  - perl-Sub-Info
  - perl-Sub-Install
  - perl-Sub-Override
  - perl-Sub-Quote
  - perl-Sub-Uplevel
  - perl-Switch
  - perl-Syntax-Keyword-Try
  - perl-Sys-Guestfs
  - perl-Term-ReadKey
  - perl-Term-Table
  - perl-Test-Base
  - perl-Test-CPAN-Meta
  - perl-Test-Deep
  - perl-Test-Differences
  - perl-Test-EOL
  - perl-Test-Exception
  - perl-Test-Fatal
  - perl-Test-File
  - perl-Test-File-ShareDir
  - perl-Test-Inter
  - perl-Test-LeakTrace
  - perl-Test-Memory-Cycle
  - perl-Test-Needs
  - perl-Test-NoTabs
  - perl-Test-NoWarnings
  - perl-Test-Output
  - perl-Test-Pod
  - perl-Test-Pod-Coverage
  - perl-Test-Requires
  - perl-Test-RequiresInternet
  - perl-Test-SharedFork
  - perl-Test-Strict
  - perl-Test-TCP
  - perl-Test-Taint
  - perl-Test-Warn
  - perl-Test-Warnings
  - perl-Test-Without-Module
  - perl-Test-YAML
  - perl-Test2-Plugin-NoWarnings
  - perl-Test2-Suite
  - perl-Text-CSV
  - perl-Text-CSV_XS
  - perl-Text-CharWidth
  - perl-Text-Diff
  - perl-Text-Glob
  - perl-Text-Iconv
  - perl-Text-Markdown
  - perl-Text-Roman
  - perl-Text-Soundex
  - perl-Text-Unidecode
  - perl-Text-WrapI18N
  - perl-Text-Wrapper
  - perl-Tie-Cycle
  - perl-Tie-IxHash
  - perl-TimeDate
  - perl-Try-Tiny
  - perl-URI
  - perl-Unicode-EastAsianWidth
  - perl-Unicode-LineBreak
  - perl-Unicode-Map8
  - perl-Unicode-String
  - perl-Variable-Magic
  - perl-WWW-Mechanize
  - perl-WWW-RobotRules
  - perl-Win-Hivex
  - perl-X11-Protocol
  - perl-X500-DN
  - perl-XML-DOM
  - perl-XML-Filter-BufferText
  - perl-XML-Handler-YAWriter
  - perl-XML-LibXML
  - perl-XML-LibXML-Simple
  - perl-XML-LibXSLT
  - perl-XML-NamespaceSupport
  - perl-XML-Parser
  - perl-XML-RegExp
  - perl-XML-SAX
  - perl-XML-SAX-Base
  - perl-XML-SAX-Expat
  - perl-XML-SAX-Writer
  - perl-XML-Simple
  - perl-XML-Structured
  - perl-XML-Twig
  - perl-XML-Writer
  - perl-XML-Writer-String
  - perl-XML-XPath
  - perl-XML-XPathEngine
  - perl-XS-Parse-Keyword
  - perl-XString
  - perl-YAML
  - perl-YAML-LibYAML
  - perl-YAML-Tiny
  - perl-autovivification
  - perl-base
  - perl-doc
  - perl-gettext
  - perl-ldap
  - perl-libintl-perl
  - perl-libwww-perl
  - perl-libxml-perl
  - perl-namespace-autoclean
  - perl-namespace-clean
  - perl-pcsc
  - perl-rrdtool
  - perl-solv
  - permissions
  - permissions-config
  - permissions-zypp-plugin
  - pesign-obs-integration
  - php8
  - php8-bcmath
  - php8-bz2
  - php8-calendar
  - php8-cli
  - php8-ctype
  - php8-curl
  - php8-dba
  - php8-devel
  - php8-dom
  - php8-embed
  - php8-enchant
  - php8-exif
  - php8-fastcgi
  - php8-ffi
  - php8-fileinfo
  - php8-fpm
  - php8-fpm-apache
  - php8-ftp
  - php8-gd
  - php8-gettext
  - php8-gmp
  - php8-iconv
  - php8-intl
  - php8-ldap
  - php8-mbstring
  - php8-mysql
  - php8-odbc
  - php8-opcache
  - php8-openssl
  - php8-pcntl
  - php8-pdo
  - php8-pear
  - php8-pecl
  - php8-pgsql
  - php8-phar
  - php8-posix
  - php8-readline
  - php8-shmop
  - php8-snmp
  - php8-soap
  - php8-sockets
  - php8-sodium
  - php8-sqlite
  - php8-sysvmsg
  - php8-sysvsem
  - php8-sysvshm
  - php8-tidy
  - php8-tokenizer
  - php8-xmlreader
  - php8-xmlwriter
  - php8-xsl
  - php8-zip
  - php8-zlib
  - picocli
  - picocli-codegen
  - picocli-javadoc
  - picocli-shell-jline2
  - pigz
  - pinentry
  - pipewire
  - pipewire-alsa
  - pipewire-devel
  - pipewire-doc
  - pipewire-jack
  - pipewire-lang
  - pipewire-libjack-0_3
  - pipewire-libjack-0_3-devel
  - pipewire-module-x11-0_3
  - pipewire-modules-0_3
  - pipewire-pulseaudio
  - pipewire-spa-plugins-0_2
  - pipewire-spa-plugins-0_2-jack
  - pipewire-spa-tools
  - pipewire-tools
  - pkcs11-helper
  - pkcs11-helper-devel
  - pkexec
  - pkgconf
  - pkgconf-m4
  - pkgconf-pkg-config
  - plexus-ant-factory
  - plexus-ant-factory-javadoc
  - plexus-archiver
  - plexus-archiver-javadoc
  - plexus-bsh-factory
  - plexus-bsh-factory-javadoc
  - plexus-build-api
  - plexus-build-api-javadoc
  - plexus-build-api0
  - plexus-build-api0-javadoc
  - plexus-cipher
  - plexus-cipher-javadoc
  - plexus-classworlds
  - plexus-classworlds-javadoc
  - plexus-cli
  - plexus-cli-javadoc
  - plexus-compiler
  - plexus-compiler-extras
  - plexus-compiler-javadoc
  - plexus-component-metadata
  - plexus-component-metadata-javadoc
  - plexus-containers-component-annotations
  - plexus-containers-javadoc
  - plexus-i18n
  - plexus-i18n-javadoc
  - plexus-interactivity-api
  - plexus-interactivity-javadoc
  - plexus-interpolation
  - plexus-interpolation-javadoc
  - plexus-io
  - plexus-io-javadoc
  - plexus-languages
  - plexus-languages-javadoc
  - plexus-metadata-generator
  - plexus-metadata-generator-javadoc
  - plexus-pom
  - plexus-sec-dispatcher
  - plexus-sec-dispatcher-javadoc
  - plexus-utils
  - plexus-utils-javadoc
  - plexus-velocity
  - plexus-velocity-javadoc
  - plexus-xml
  - plexus-xml-javadoc
  - plotutils
  - plotutils-devel
  - plotutils-doc
  - plymouth
  - plymouth-branding-SLE
  - plymouth-branding-upstream
  - plymouth-devel
  - plymouth-dracut
  - plymouth-lang
  - plymouth-plugin-fade-throbber
  - plymouth-plugin-label
  - plymouth-plugin-label-ft
  - plymouth-plugin-script
  - plymouth-plugin-space-flares
  - plymouth-plugin-tribar
  - plymouth-plugin-two-step
  - plymouth-scripts
  - plymouth-theme-bgrt
  - plymouth-theme-fade-in
  - plymouth-theme-script
  - plymouth-theme-solar
  - plymouth-theme-spinfinity
  - plymouth-theme-spinner
  - plymouth-theme-tribar
  - pngquant
  - po4a
  - po4a-lang
  - podman
  - podman-docker
  - podman-remote
  - podmansh
  - policycoreutils
  - policycoreutils-devel
  - policycoreutils-lang
  - policycoreutils-newrole
  - policycoreutils-python-utils
  - polkit
  - polkit-default-privs
  - polkit-devel
  - polkit-doc
  - poppler-data
  - poppler-data-devel
  - poppler-tools
  - popt-devel
  - popt-lang
  - postfix
  - postfix-bdb
  - postfix-bdb-lmdb
  - postfix-doc
  - postfix-ldap
  - postfix-mysql
  - postfix-postgresql
  - postgresql
  - postgresql-contrib
  - postgresql-devel
  - postgresql-docs
  - postgresql-jdbc
  - postgresql-jdbc-javadoc
  - postgresql-llvmjit
  - postgresql-plperl
  - postgresql-plpython
  - postgresql-pltcl
  - postgresql-server
  - postgresql-server-devel
  - postgresql13
  - postgresql13-contrib
  - postgresql13-devel
  - postgresql13-docs
  - postgresql13-llvmjit
  - postgresql13-plperl
  - postgresql13-plpython
  - postgresql13-pltcl
  - postgresql13-server
  - postgresql13-server-devel
  - postgresql14
  - postgresql14-contrib
  - postgresql14-devel
  - postgresql14-docs
  - postgresql14-llvmjit
  - postgresql14-plperl
  - postgresql14-plpython
  - postgresql14-pltcl
  - postgresql14-server
  - postgresql14-server-devel
  - postgresql15
  - postgresql15-contrib
  - postgresql15-devel
  - postgresql15-docs
  - postgresql15-llvmjit
  - postgresql15-plperl
  - postgresql15-plpython
  - postgresql15-pltcl
  - postgresql15-server
  - postgresql15-server-devel
  - postgresql16
  - postgresql16-contrib
  - postgresql16-devel
  - postgresql16-docs
  - postgresql16-llvmjit
  - postgresql16-plperl
  - postgresql16-plpython
  - postgresql16-pltcl
  - postgresql16-server
  - postgresql16-server-devel
  - postgresql17
  - postgresql17-contrib
  - postgresql17-devel
  - postgresql17-docs
  - postgresql17-llvmjit
  - postgresql17-plperl
  - postgresql17-plpython
  - postgresql17-pltcl
  - postgresql17-server
  - postgresql17-server-devel
  - powerman
  - powerman-devel
  - powertop
  - powertop-lang
  - ppp
  - ppp-devel
  - ppp-modem
  - pprof
  - pps-tools
  - pps-tools-devel
  - pps-udev
  - prctl
  - procmail
  - procps
  - procps-devel
  - procps-lang
  - protobuf-devel
  - protobuf-java
  - protobuf21-devel
  - psl
  - psl-make-dafsa
  - psmisc
  - psmisc-lang
  - psutils
  - pthread-stubs-devel
  - publicsuffix
  - pulseaudio
  - pulseaudio-bash-completion
  - pulseaudio-lang
  - pulseaudio-module-bluetooth
  - pulseaudio-module-gsettings
  - pulseaudio-module-jack
  - pulseaudio-module-x11
  - pulseaudio-module-zeroconf
  - pulseaudio-setup
  - pulseaudio-system-wide
  - pulseaudio-utils
  - purge-kernels-service
  - pv
  - python-Genshi-doc
  - python-M2Crypto-doc
  - python-SQLAlchemy-doc
  - python-Twisted-doc
  - python-WebOb-doc
  - python-WebTest-doc
  - python-Whoosh-doc
  - python-beautifulsoup4-doc
  - python-blinker-doc
  - python-bottle-doc
  - python-btrfsutil
  - python-dbus-python-common-devel
  - python-flake8-doc
  - python-gevent-doc
  - python-gobject-common-devel
  - python-gunicorn-doc
  - python-langtable-data
  - python-libeconf-doc
  - python-lxml-doc
  - python-marshmallow-doc
  - python-paramiko-doc
  - python-ply-doc
  - python-pybind11-common-devel
  - python-pycairo-common-devel
  - python-pycurl-doc
  - python-pyserial-doc
  - python-rdflib-doc
  - python-rpm-generators
  - python-rpm-macros
  - python-rpm-packaging
  - python-rtslib-fb-common
  - python-sip4-common
  - python-sip4-doc
  - python-six-doc
  - python-tqdm-bash-completion
  - python-zope.event-doc
  - python-zope.hookable-doc
  - python-zope.i18nmessageid-doc
  - python3-audit
  - python3-avahi-gtk
  - python3-babeltrace
  - python3-bcc
  - python3-brlapi
  - python3-bytesize
  - python3-caca
  - python3-capng
  - python3-cepces
  - python3-createrepo_c
  - python3-firewall
  - python3-gi-docgen
  - python3-hivex
  - python3-ipa_hbac
  - python3-kea
  - python3-kiwi
  - python3-ldb
  - python3-ldns
  - python3-libblockdev
  - python3-libftdi1
  - python3-libguestfs
  - python3-libmodulemd
  - python3-libnbd
  - python3-libnvme
  - python3-librepo
  - python3-libstoragemgmt
  - python3-libvoikko
  - python3-lilv
  - python3-newt
  - python3-openvswitch
  - python3-pacemaker
  - python3-pcp
  - python3-pwquality
  - python3-rrdtool
  - python3-seccomp
  - python3-sss-murmur
  - python3-sss_nss_idmap
  - python3-sssd-config
  - python3-talloc
  - python3-talloc-devel
  - python3-tdb
  - python3-tevent
  - python3-unbound
  - python3-virt-scenario
  - python3-xcb-proto-devel
  - python3-zbar
  - python311
  - python311-PyJWT
  - python311-aiohappyeyeballs
  - python311-aiohttp
  - python311-aiosignal
  - python311-apache-libcloud
  - python311-attrs
  - python311-azure-common
  - python311-azure-core
  - python311-azure-identity
  - python311-azure-mgmt-compute
  - python311-azure-mgmt-core
  - python311-azure-mgmt-network
  - python311-azure-mgmt-nspkg
  - python311-azure-nspkg
  - python311-base
  - python311-bcrypt
  - python311-certifi
  - python311-cffi
  - python311-charset-normalizer
  - python311-cryptography
  - python311-frozenlist
  - python311-idna
  - python311-isodate
  - python311-libvirt-python
  - python311-msal
  - python311-msal-extensions
  - python311-multidict
  - python311-pexpect
  - python311-portalocker
  - python311-propcache
  - python311-ptyprocess
  - python311-pycparser
  - python311-pycurl
  - python311-pyvmomi
  - python311-requests
  - python311-six
  - python311-typing_extensions
  - python311-urllib3
  - python311-yarl
  - python313
  - python313-Automat
  - python313-Babel
  - python313-Brotli
  - python313-ConfigUpdater
  - python313-Cycler
  - python313-Cython
  - python313-Cython0
  - python313-Deprecated
  - python313-EasyProcess
  - python313-Faker
  - python313-Flask
  - python313-Flask-doc
  - python313-FontTools
  - python313-FormEncode
  - python313-Genshi
  - python313-Jinja2
  - python313-Js2Py
  - python313-M2Crypto
  - python313-Mako
  - python313-Markdown
  - python313-MarkupSafe
  - python313-Paste
  - python313-PasteDeploy
  - python313-PyHamcrest
  - python313-PyJWT
  - python313-PyMeeus
  - python313-PyMySQL
  - python313-PyNaCl
  - python313-PySocks
  - python313-PyYAML
  - python313-Pygments
  - python313-Pympler
  - python313-SQLAlchemy
  - python313-SecretStorage
  - python313-Sphinx
  - python313-Twisted
  - python313-Twisted-all_non_platform
  - python313-Twisted-conch
  - python313-Twisted-conch_nacl
  - python313-Twisted-contextvars
  - python313-Twisted-http2
  - python313-Twisted-serial
  - python313-Twisted-tls
  - python313-WSGIProxy2
  - python313-WebOb
  - python313-WebTest
  - python313-Werkzeug
  - python313-Whoosh
  - python313-abseil
  - python313-aiodns
  - python313-aiofiles
  - python313-aiohappyeyeballs
  - python313-aiohttp
  - python313-aiohttp_cors
  - python313-aiosignal
  - python313-aiosqlite
  - python313-alabaster
  - python313-alembic
  - python313-anyio
  - python313-apipkg
  - python313-appdirs
  - python313-apsw
  - python313-argcomplete
  - python313-argon2-cffi
  - python313-argon2-cffi-bindings
  - python313-argparse-manpage
  - python313-arrow
  - python313-asgiref
  - python313-aspectlib
  - python313-astor
  - python313-astroid
  - python313-astunparse
  - python313-async_generator
  - python313-async_timeout
  - python313-asyncpg
  - python313-atspi
  - python313-attrs
  - python313-autocommand
  - python313-avahi
  - python313-backports.tarfile
  - python313-base
  - python313-bcrypt
  - python313-beautifulsoup4
  - python313-beniget
  - python313-betamax
  - python313-black
  - python313-bleach
  - python313-blessings
  - python313-blinker
  - python313-boto3
  - python313-botocore
  - python313-bottle
  - python313-build
  - python313-cachetools
  - python313-cairocffi
  - python313-cairocffi-pixbuf
  - python313-calver
  - python313-cbor2
  - python313-cchardet
  - python313-certifi
  - python313-cffi
  - python313-chardet
  - python313-charset-normalizer
  - python313-cheroot
  - python313-click
  - python313-cloudpickle
  - python313-cmarkgfm
  - python313-cmdln
  - python313-colorama
  - python313-configobj
  - python313-constantly
  - python313-contextvars
  - python313-contourpy
  - python313-convertdate
  - python313-cookies
  - python313-coverage
  - python313-cppy
  - python313-cryptography
  - python313-cryptography-vectors
  - python313-cssselect
  - python313-cssselect2
  - python313-curses
  - python313-dasbus
  - python313-databases
  - python313-dateparser
  - python313-dbm
  - python313-dbus-python
  - python313-dbus-python-devel
  - python313-ddt
  - python313-decorator
  - python313-defusedxml
  - python313-deprecation
  - python313-devel
  - python313-dirty-equals
  - python313-diskcache
  - python313-distlib
  - python313-distro
  - python313-dnspython
  - python313-doc
  - python313-doc-devhelp
  - python313-docopt
  - python313-docutils
  - python313-domdf-python-tools
  - python313-dpcontracts
  - python313-drgn
  - python313-ecdsa
  - python313-editables
  - python313-elastic-transport
  - python313-elasticsearch
  - python313-elementpath
  - python313-email-validator
  - python313-entrypoint2
  - python313-ephemeral-port-reserve
  - python313-eventlet
  - python313-exceptiongroup
  - python313-execnet
  - python313-executing
  - python313-extras
  - python313-fakeredis
  - python313-fasteners
  - python313-fasttext
  - python313-fields
  - python313-filelock
  - python313-fixtures
  - python313-flake8
  - python313-flaky
  - python313-flasgger
  - python313-flit
  - python313-flit-core
  - python313-flit-scm
  - python313-fluidity-sm
  - python313-fqdn
  - python313-freezegun
  - python313-frozenlist
  - python313-fs
  - python313-furl
  - python313-gast
  - python313-geoip2
  - python313-gevent
  - python313-gitdb
  - python313-gmpy2
  - python313-gobject
  - python313-gobject-Gdk
  - python313-gobject-cairo
  - python313-gobject-devel
  - python313-google-api-core
  - python313-google-api-python-client
  - python313-google-auth
  - python313-google-auth-httplib2
  - python313-google-crc32c
  - python313-google-resumable-media
  - python313-googleapis-common-protos
  - python313-gpg
  - python313-greenlet
  - python313-greenlet-devel
  - python313-grpcio
  - python313-grpcio-status
  - python313-gssapi
  - python313-gunicorn
  - python313-h11
  - python313-h2
  - python313-hatch-fancy-pypi-readme
  - python313-hatch_vcs
  - python313-hatchling
  - python313-hpack
  - python313-html5lib
  - python313-httpbin
  - python313-httpcore
  - python313-httplib2
  - python313-httpretty
  - python313-httptools
  - python313-httpx
  - python313-hyperframe
  - python313-hyperlink
  - python313-hypothesis
  - python313-hypothesmith
  - python313-idle
  - python313-idna
  - python313-imagesize
  - python313-immutables
  - python313-importlib-metadata
  - python313-importlib-resources
  - python313-incremental
  - python313-ini2toml
  - python313-ini2toml-all
  - python313-ini2toml-full
  - python313-ini2toml-lite
  - python313-iniconfig
  - python313-installer
  - python313-invoke
  - python313-ipaddr
  - python313-iso8601
  - python313-isodate
  - python313-itsdangerous
  - python313-jaraco.classes
  - python313-jaraco.context
  - python313-jaraco.envs
  - python313-jaraco.functools
  - python313-jaraco.packaging
  - python313-jaraco.path
  - python313-jaraco.vcs
  - python313-jaraco.versioning
  - python313-javapackages
  - python313-jeepney
  - python313-jmespath
  - python313-jsonpatch
  - python313-jsonpointer
  - python313-jsonschema
  - python313-jsonschema-specifications
  - python313-jwcrypto
  - python313-k5test
  - python313-keylime
  - python313-keyring
  - python313-kiwisolver
  - python313-langdetect
  - python313-langtable
  - python313-lark
  - python313-lazy-object-proxy
  - python313-ldap
  - python313-legacy-cgi
  - python313-lexicon
  - python313-libcst
  - python313-libeconf
  - python313-libevdev
  - python313-libmount
  - python313-libpfm
  - python313-libvirt-python
  - python313-libxml2
  - python313-linkify-it-py
  - python313-linux-procfs
  - python313-littleutils
  - python313-looseversion
  - python313-lxml
  - python313-lxml-devel
  - python313-lz4
  - python313-magic
  - python313-marshmallow
  - python313-maturin
  - python313-maxminddb
  - python313-mccabe
  - python313-mdurl
  - python313-mistune
  - python313-mocket
  - python313-more-itertools
  - python313-msgpack
  - python313-multidict
  - python313-munch
  - python313-munkres
  - python313-mypy_extensions
  - python313-mysqlclient
  - python313-natsort
  - python313-net-snmp
  - python313-netaddr
  - python313-netifaces
  - python313-nftables
  - python313-nose2
  - python313-notify2
  - python313-numpy
  - python313-numpy-devel
  - python313-oauthlib
  - python313-olefile
  - python313-opentelemetry-api
  - python313-opentelemetry-sdk
  - python313-opentelemetry-semantic-conventions
  - python313-opentelemetry-test-utils
  - python313-orderedmultidict
  - python313-orjson
  - python313-outcome
  - python313-packaging
  - python313-parameterized
  - python313-parso
  - python313-passlib
  - python313-path
  - python313-pathable
  - python313-pathspec
  - python313-pathtools
  - python313-pbr
  - python313-pdm-backend
  - python313-peewee
  - python313-pefile
  - python313-pendulum
  - python313-pexpect
  - python313-pickleshare
  - python313-pip
  - python313-pip-run
  - python313-pip-wheel
  - python313-pipx
  - python313-pkgconfig
  - python313-platformdirs
  - python313-pluggy
  - python313-ply
  - python313-poetry-core
  - python313-policycoreutils
  - python313-pook
  - python313-portend
  - python313-pretend
  - python313-prettytable
  - python313-priority
  - python313-process-tests
  - python313-prometheus-client
  - python313-prompt_toolkit
  - python313-propcache
  - python313-proto-plus
  - python313-protobuf
  - python313-psutil
  - python313-ptyprocess
  - python313-pure-eval
  - python313-puremagic
  - python313-purl
  - python313-py
  - python313-py-cpuinfo
  - python313-pyOpenSSL
  - python313-pyasn1
  - python313-pyasn1-modules
  - python313-pybind11
  - python313-pybind11-devel
  - python313-pycairo
  - python313-pycairo-devel
  - python313-pycares
  - python313-pycodestyle
  - python313-pycountry
  - python313-pycparser
  - python313-pycryptodome
  - python313-pycups
  - python313-pycurl
  - python313-pyelftools
  - python313-pyenchant
  - python313-pyfakefs
  - python313-pyflakes
  - python313-pyftpdlib
  - python313-pygaljs
  - python313-pygments-ansi-color
  - python313-pygments-pytest
  - python313-pyinotify
  - python313-pyjsparser
  - python313-pylibmc
  - python313-pylons-sphinx-themes
  - python313-pyparsing
  - python313-pyperclip
  - python313-pyproject-hooks
  - python313-pyproject-metadata
  - python313-pyquery
  - python313-pyrsistent
  - python313-pysendfile
  - python313-pyserial
  - python313-pytest
  - python313-pytest-asyncio
  - python313-pytest-cov
  - python313-pytest-datadir
  - python313-pytest-dependency
  - python313-pytest-env
  - python313-pytest-expect
  - python313-pytest-fixture-config
  - python313-pytest-forked
  - python313-pytest-freezegun
  - python313-pytest-home
  - python313-pytest-httpbin
  - python313-pytest-httpserver
  - python313-pytest-lazy-fixture
  - python313-pytest-localserver
  - python313-pytest-mock
  - python313-pytest-relaxed
  - python313-pytest-rerunfailures
  - python313-pytest-services
  - python313-pytest-shutil
  - python313-pytest-subprocess
  - python313-pytest-subtests
  - python313-pytest-timeout
  - python313-pytest-trio
  - python313-pytest-virtualenv
  - python313-pytest-xdist
  - python313-pytest-xprocess
  - python313-python-dateutil
  - python313-python-docs-theme
  - python313-python-dotenv
  - python313-python-jose
  - python313-python-jose-cryptography
  - python313-python-magic
  - python313-python-mimeparse
  - python313-python-multipart
  - python313-python-slugify
  - python313-python-xlib
  - python313-pytz
  - python313-pytz-deprecation-shim
  - python313-pytzdata
  - python313-pyu2f
  - python313-pyudev
  - python313-pywbem
  - python313-pyxdg
  - python313-railroad-diagrams
  - python313-random2
  - python313-rdflib
  - python313-re-assert
  - python313-redis
  - python313-referencing
  - python313-regex
  - python313-requests
  - python313-requests-futures
  - python313-requests-gssapi
  - python313-requests-mock
  - python313-requests-oauthlib
  - python313-requests-toolbelt
  - python313-requests-unixsocket
  - python313-resolvelib
  - python313-responses
  - python313-respx
  - python313-rfc3339-validator
  - python313-rfc3986-validator
  - python313-rfc3987
  - python313-roman
  - python313-rpds-py
  - python313-rpm
  - python313-rsa
  - python313-rst.linker
  - python313-rtslib-fb
  - python313-ruamel.yaml
  - python313-ruamel.yaml.clib
  - python313-ruff
  - python313-s3transfer
  - python313-scripttest
  - python313-scrypt
  - python313-selinux
  - python313-semanage
  - python313-semantic_version
  - python313-service_identity
  - python313-setools
  - python313-setuptools
  - python313-setuptools-git
  - python313-setuptools-rust
  - python313-setuptools-wheel
  - python313-setuptools_scm
  - python313-sh
  - python313-shellingham
  - python313-simplejson
  - python313-sip-devel
  - python313-sip4
  - python313-sip4-devel
  - python313-sip6-devel
  - python313-six
  - python313-smartypants
  - python313-smmap
  - python313-sniffio
  - python313-snowballstemmer
  - python313-solv
  - python313-sortedcontainers
  - python313-soupsieve
  - python313-speechd
  - python313-sphinx_rtd_theme
  - python313-sphinxcontrib-applehelp
  - python313-sphinxcontrib-devhelp
  - python313-sphinxcontrib-htmlhelp
  - python313-sphinxcontrib-jquery
  - python313-sphinxcontrib-jsmath
  - python313-sphinxcontrib-qthelp
  - python313-sphinxcontrib-serializinghtml
  - python313-sphinxcontrib-websupport
  - python313-sqlparse
  - python313-starlette
  - python313-strict-rfc3339
  - python313-suds
  - python313-sure
  - python313-sybil
  - python313-systemd
  - python313-tabulate
  - python313-tblib
  - python313-tempora
  - python313-termcolor
  - python313-testfixtures
  - python313-testpath
  - python313-testresources
  - python313-testscenarios
  - python313-testtools
  - python313-text-unidecode
  - python313-threadpoolctl
  - python313-time-machine
  - python313-tinycss2
  - python313-tk
  - python313-toml
  - python313-tomli
  - python313-tomli-w
  - python313-tomlkit
  - python313-tools
  - python313-tornado
  - python313-tornado6
  - python313-tqdm
  - python313-traitlets
  - python313-transaction
  - python313-trio
  - python313-trove-classifiers
  - python313-trustme
  - python313-typeguard
  - python313-typing-inspect
  - python313-typing_extensions
  - python313-typogrify
  - python313-tzdata
  - python313-tzlocal
  - python313-u-msgpack-python
  - python313-uc-micro-py
  - python313-ujson
  - python313-uri-template
  - python313-uritemplate
  - python313-urllib3
  - python313-urllib3_1
  - python313-userpath
  - python313-uvicorn
  - python313-uvloop
  - python313-validators
  - python313-versioneer
  - python313-versioneer-toml
  - python313-virtualenv
  - python313-virtue
  - python313-voluptuous
  - python313-waitress
  - python313-watchdog
  - python313-watchdog-doc
  - python313-wcwidth
  - python313-webcolors
  - python313-webencodings
  - python313-websocket-client
  - python313-websockets
  - python313-websockify
  - python313-wheel
  - python313-wrapt
  - python313-wsproto
  - python313-xattr
  - python313-xcffib
  - python313-xmlschema
  - python313-xmltodict
  - python313-xxhash
  - python313-yamllint
  - python313-yamlloader
  - python313-yapf
  - python313-yarl
  - python313-zc.lockfile
  - python313-zipp
  - python313-zope.component
  - python313-zope.configuration
  - python313-zope.copy
  - python313-zope.deferredimport
  - python313-zope.event
  - python313-zope.exceptions
  - python313-zope.hookable
  - python313-zope.i18nmessageid
  - python313-zope.interface
  - python313-zope.location
  - python313-zope.proxy
  - python313-zope.proxy-devel
  - python313-zope.schema
  - python313-zope.security
  - python313-zope.testing
  - python313-zope.testrunner
  - python313-zopfli
  - python313-zstandard
  - python313-zypp-plugin
  - qca-qt6
  - qca-qt6-plugins
  - qdox
  - qdox-javadoc
  - qemu
  - qemu-SLOF
  - qemu-accel-tcg-x86
  - qemu-arm
  - qemu-audio-alsa
  - qemu-audio-dbus
  - qemu-audio-jack
  - qemu-audio-oss
  - qemu-block-curl
  - qemu-block-dmg
  - qemu-block-iscsi
  - qemu-block-nfs
  - qemu-block-ssh
  - qemu-doc
  - qemu-extra
  - qemu-guest-agent
  - qemu-headless
  - qemu-hw-display-virtio-gpu
  - qemu-hw-display-virtio-gpu-pci
  - qemu-hw-display-virtio-vga
  - qemu-hw-s390x-virtio-gpu-ccw
  - qemu-hw-usb-host
  - qemu-hw-usb-redirect
  - qemu-hw-usb-smartcard
  - qemu-img
  - qemu-ipxe
  - qemu-ivshmem-tools
  - qemu-ksm
  - qemu-lang
  - qemu-linux-user
  - qemu-microvm
  - qemu-ppc
  - qemu-pr-helper
  - qemu-s390x
  - qemu-seabios
  - qemu-skiboot
  - qemu-tools
  - qemu-vgabios
  - qemu-vhost-user-gpu
  - qemu-x86
  - qml-autoreqprov
  - qmlpluginexports-qt6
  - qperf
  - qrencode
  - qrencode-devel
  - qt6-3d-docs-html
  - qt6-3d-docs-qch
  - qt6-3d-examples
  - qt6-3d-imports
  - qt6-base-common-devel
  - qt6-base-docs-html
  - qt6-base-docs-qch
  - qt6-charts-docs-html
  - qt6-charts-docs-qch
  - qt6-charts-examples
  - qt6-charts-imports
  - qt6-connectivity
  - qt6-connectivity-docs-html
  - qt6-connectivity-docs-qch
  - qt6-connectivity-examples
  - qt6-datavis3d-docs-html
  - qt6-datavis3d-docs-qch
  - qt6-datavis3d-examples
  - qt6-datavisualization-imports
  - qt6-declarative-docs-html
  - qt6-declarative-docs-qch
  - qt6-declarative-examples
  - qt6-declarative-imports
  - qt6-declarative-tools
  - qt6-graphs-docs-html
  - qt6-graphs-docs-qch
  - qt6-graphs-examples
  - qt6-graphs-imports
  - qt6-httpserver-docs-html
  - qt6-httpserver-docs-qch
  - qt6-httpserver-examples
  - qt6-location
  - qt6-location-docs-html
  - qt6-location-docs-qch
  - qt6-location-examples
  - qt6-macros
  - qt6-multimedia
  - qt6-multimedia-docs-html
  - qt6-multimedia-docs-qch
  - qt6-multimedia-examples
  - qt6-multimedia-imports
  - qt6-network-tls
  - qt6-networkauth-docs-html
  - qt6-networkauth-docs-qch
  - qt6-networkauth-examples
  - qt6-networkinformation-glib
  - qt6-networkinformation-nm
  - qt6-platformtheme-gtk3
  - qt6-platformtheme-xdgdesktopportal
  - qt6-positioning
  - qt6-positioning-docs-html
  - qt6-positioning-docs-qch
  - qt6-positioning-examples
  - qt6-positioning-imports
  - qt6-printsupport-cups
  - qt6-qt5compat-docs-html
  - qt6-qt5compat-docs-qch
  - qt6-qt5compat-imports
  - qt6-quick3d
  - qt6-quick3d-docs-html
  - qt6-quick3d-docs-qch
  - qt6-quick3d-examples
  - qt6-quick3d-imports
  - qt6-quicktimeline-docs-html
  - qt6-quicktimeline-docs-qch
  - qt6-quicktimeline-imports
  - qt6-remoteobjects-docs-html
  - qt6-remoteobjects-docs-qch
  - qt6-remoteobjects-examples
  - qt6-remoteobjects-imports
  - qt6-remoteobjects-tools
  - qt6-scxml
  - qt6-scxml-docs-html
  - qt6-scxml-docs-qch
  - qt6-scxml-examples
  - qt6-scxml-imports
  - qt6-sensors-docs-html
  - qt6-sensors-docs-qch
  - qt6-serialbus
  - qt6-serialbus-docs-html
  - qt6-serialbus-docs-qch
  - qt6-serialbus-examples
  - qt6-serialport-docs-html
  - qt6-serialport-docs-qch
  - qt6-serialport-examples
  - qt6-shadertools
  - qt6-shadertools-docs-html
  - qt6-shadertools-docs-qch
  - qt6-speech-docs-html
  - qt6-speech-docs-qch
  - qt6-sql-mysql
  - qt6-sql-postgresql
  - qt6-sql-sqlite
  - qt6-sql-unixODBC
  - qt6-svg-docs-html
  - qt6-svg-docs-qch
  - qt6-tools-assistant
  - qt6-tools-designer
  - qt6-tools-docs-html
  - qt6-tools-docs-qch
  - qt6-tools-examples
  - qt6-tools-linguist
  - qt6-tools-qdbus
  - qt6-wayland
  - qt6-wayland-docs-html
  - qt6-wayland-docs-qch
  - qt6-wayland-examples
  - qt6-wayland-imports
  - qt6-webchannel-docs-html
  - qt6-webchannel-docs-qch
  - qt6-webchannel-examples
  - qt6-webchannel-imports
  - qt6-websockets-docs-html
  - qt6-websockets-docs-qch
  - qt6-websockets-examples
  - qt6-websockets-imports
  - qtdeclarative-imports-provides-qt6
  - quota
  - quota-nfs
  - raptor
  - rasdaemon
  - raspberrypi-eeprom
  - raspberrypi-eeprom-firmware
  - raspberrypi-firmware
  - raspberrypi-firmware-config
  - raspberrypi-firmware-config-camera
  - raspberrypi-firmware-dt
  - raspberrypi-firmware-extra
  - raspberrypi-firmware-extra-pi4
  - rav1e
  - rcc-runtime
  - rdma-core
  - rdma-core-devel
  - rdma-ndd
  - re2-devel
  - re2c
  - read-only-root-fs
  - read-only-root-fs-volatile
  - readcd
  - readline-devel
  - readline-devel-static
  - readline-doc
  - realmd
  - rebootmgr
  - redis
  - regexp
  - registries-conf-default
  - registries-conf-suse
  - relaxngDatatype
  - release-notes-sles-160
  - reload4j
  - reload4j-javadoc
  - resource-agents
  - restorecond
  - rhash
  - rhash-devel
  - rhash-lang
  - rhino
  - rhino-demo
  - rhino-engine
  - rhino-javadoc
  - rhino-runtime
  - rollback-helper
  - rootlesskit
  - rp-pppoe
  - rpcbind
  - rpcgen
  - rpcsvc-proto-devel
  - rpm
  - rpm-build
  - rpm-build-perl
  - rpm-config-SUSE
  - rpm-devel
  - rpmlint-strict
  - rrdtool
  - rrdtool-cached
  - rrdtool-devel
  - rrdtool-doc
  - rscsi
  - rsocket
  - rsvg-convert
  - rsvg-thumbnailer
  - rsync
  - rtkit
  - rtr-tools
  - rtrlib-devel
  - rtrlib-devel-doc
  - rubberband-cli
  - rubberband-ladspa
  - rubberband-lv2
  - ruby
  - ruby-bundled-gems-rpmhelper
  - ruby-common
  - ruby-common-rails
  - ruby-devel
  - ruby-packaging-helpers
  - ruby-rrdtool
  - ruby-selinux
  - ruby-solv
  - ruby3.4
  - ruby3.4-devel
  - ruby3.4-devel-extra
  - ruby3.4-doc
  - ruby3.4-doc-ri
  - ruby3.4-rubygem-actioncable-8.0
  - ruby3.4-rubygem-actionmailbox-8.0
  - ruby3.4-rubygem-actionmailer-8.0
  - ruby3.4-rubygem-actionpack-8.0
  - ruby3.4-rubygem-actiontext-8.0
  - ruby3.4-rubygem-actionview-8.0
  - ruby3.4-rubygem-activejob-8.0
  - ruby3.4-rubygem-activemodel-8.0
  - ruby3.4-rubygem-activerecord-8.0
  - ruby3.4-rubygem-activestorage-8.0
  - ruby3.4-rubygem-activesupport-8.0
  - ruby3.4-rubygem-axiom-types
  - ruby3.4-rubygem-builder
  - ruby3.4-rubygem-coercible
  - ruby3.4-rubygem-concurrent-ruby
  - ruby3.4-rubygem-connection_pool
  - ruby3.4-rubygem-crass
  - ruby3.4-rubygem-descendants_tracker
  - ruby3.4-rubygem-erubi
  - ruby3.4-rubygem-execjs
  - ruby3.4-rubygem-fast_gettext
  - ruby3.4-rubygem-ffi
  - ruby3.4-rubygem-gem2rpm
  - ruby3.4-rubygem-gettext
  - ruby3.4-rubygem-gettext_i18n_rails
  - ruby3.4-rubygem-gettext_i18n_rails_js
  - ruby3.4-rubygem-globalid
  - ruby3.4-rubygem-i18n
  - ruby3.4-rubygem-ice_nine
  - ruby3.4-rubygem-js-routes
  - ruby3.4-rubygem-kramdown
  - ruby3.4-rubygem-locale
  - ruby3.4-rubygem-loofah
  - ruby3.4-rubygem-mail
  - ruby3.4-rubygem-marcel
  - ruby3.4-rubygem-mini_mime
  - ruby3.4-rubygem-nio4r
  - ruby3.4-rubygem-nokogiri
  - ruby3.4-rubygem-po_to_json
  - ruby3.4-rubygem-puma
  - ruby3.4-rubygem-rack
  - ruby3.4-rubygem-rack-session
  - ruby3.4-rubygem-rack-test
  - ruby3.4-rubygem-rackup
  - ruby3.4-rubygem-rails-8.0
  - ruby3.4-rubygem-rails-dom-testing
  - ruby3.4-rubygem-rails-html-sanitizer
  - ruby3.4-rubygem-railties-8.0
  - ruby3.4-rubygem-ruby-augeas
  - ruby3.4-rubygem-sass-rails
  - ruby3.4-rubygem-sassc
  - ruby3.4-rubygem-sassc-rails
  - ruby3.4-rubygem-sorbet-runtime
  - ruby3.4-rubygem-sprockets
  - ruby3.4-rubygem-sprockets-rails
  - ruby3.4-rubygem-text
  - ruby3.4-rubygem-thor
  - ruby3.4-rubygem-thread_safe
  - ruby3.4-rubygem-tilt
  - ruby3.4-rubygem-tzinfo
  - ruby3.4-rubygem-uglifier
  - ruby3.4-rubygem-useragent
  - ruby3.4-rubygem-virtus
  - ruby3.4-rubygem-websocket-driver
  - ruby3.4-rubygem-websocket-extensions
  - ruby3.4-rubygem-zeitwerk
  - runc
  - rust
  - rust-bindgen
  - rust-cbindgen
  - rust-keylime
  - rust1.83
  - rust1.84
  - rust1.85
  - samba
  - samba-ad-dc
  - samba-ad-dc-libs
  - samba-client
  - samba-client-libs
  - samba-dcerpc
  - samba-devel
  - samba-doc
  - samba-dsdb-modules
  - samba-gpupdate
  - samba-ldb-ldap
  - samba-libs
  - samba-libs-python3
  - samba-python3
  - samba-tool
  - samba-winbind
  - samba-winbind-libs
  - sap-suse-cluster-connector
  - sapcontrol-bash-completion
  - saphana-checks
  - sapstartsrv-resource-agents
  - saxon10
  - saxon10-demo
  - saxon10-javadoc
  - saxon10-manual
  - saxon10-scripts
  - saxpath
  - saxpath-javadoc
  - sbc
  - sbc-devel
  - sbd
  - sbd-devel
  - sca-patterns-alp1
  - sca-patterns-base
  - sca-patterns-sle12
  - sca-patterns-sle15
  - sca-server-report
  - sccs
  - schily-ctags
  - schily-mt
  - schily-rmt
  - schroedinger-doc
  - scons
  - screen
  - seahorse
  - secret-tool
  - sed
  - sed-lang
  - selinux-autorelabel
  - selinux-policy
  - selinux-policy-devel
  - selinux-policy-doc
  - selinux-policy-minimum
  - selinux-policy-sandbox
  - selinux-policy-targeted
  - selinux-tools
  - sensord
  - sensors
  - serdi
  - servletapi4
  - servletapi4-javadoc
  - servletapi5
  - setools-console
  - setroubleshoot
  - setroubleshoot-doc
  - setroubleshoot-plugins
  - setroubleshoot-plugins-lang
  - setroubleshoot-server
  - setxkbmap
  - sg3_utils
  - sgml-skel
  - sha1collisiondetection
  - shaderc
  - shaderc-devel
  - shadow
  - shared-mime-info
  - shared-mime-info-lang
  - sharutils
  - sharutils-lang
  - shibboleth-sp
  - sisu-inject
  - sisu-javadoc
  - sisu-mojos
  - sisu-mojos-javadoc
  - sisu-plexus
  - skopeo
  - skopeo-bash-completion
  - skopeo-fish-completion
  - slang-devel
  - slang-slsh
  - sle-ha-release
  - slf4j
  - slf4j-ext
  - slf4j-javadoc
  - slf4j-jcl
  - slf4j-jdk14
  - slf4j-manual
  - slf4j-reload4j
  - slf4j-sources
  - slirp4netns
  - smake
  - smartmontools
  - smc-tools
  - smc-tools-completion
  - snakeyaml
  - snakeyaml-javadoc
  - snapper
  - snapper-zypp-plugin
  - snappy-devel
  - snmp-mibs
  - snowball
  - snowball-devel
  - socat
  - sof-firmware
  - sonatype-oss-parent
  - sord
  - soundtouch
  - source-highlight
  - spandsp-doc
  - sparsehash-devel
  - spax
  - speech-dispatcher
  - speech-dispatcher-configure
  - speech-dispatcher-module-espeak
  - speex
  - spice-vdagent
  - spirv-headers
  - spirv-tools
  - spirv-tools-devel
  - sqlite3
  - sqlite3-devel
  - sqlite3-doc
  - sqlite3-tcl
  - squashfs
  - squid
  - srp_daemon
  - srt
  - sscep
  - ssh-pairing
  - sssd
  - sssd-ad
  - sssd-dbus
  - sssd-ipa
  - sssd-kcm
  - sssd-krb5
  - sssd-krb5-common
  - sssd-ldap
  - sssd-proxy
  - sssd-tools
  - sssd-winbind-idmap
  - stalld
  - star
  - startup-notification-devel
  - strace
  - stress-ng
  - stress-ng-bash-completion
  - strip-nondeterminism
  - strongswan
  - strongswan-doc
  - strongswan-fips
  - strongswan-ipsec
  - strongswan-mysql
  - strongswan-nm
  - strongswan-sqlite
  - stunnel
  - stunnel-doc
  - sudo
  - sudo-devel
  - sudo-plugin-python
  - sudo-policy-sudo-auth-self
  - sudo-policy-wheel-auth-self
  - supermin
  - supportutils
  - supportutils-plugin-ha-sap
  - suse-build-key
  - suse-fonts
  - suse-module-tools
  - suse-module-tools-scriptlets
  - suse-prime
  - suseconnect-ng
  - suseconnect-ruby-bindings
  - swig
  - swig-doc
  - swig-examples
  - swtpm
  - swtpm-selinux
  - sysctl-logger
  - sysfsutils
  - sysfsutils-devel
  - syslog-service
  - syslogd
  - sysprof
  - sysprof-devel
  - sysprof-gtk
  - sysprof-lang
  - sysstat
  - system-group-audit
  - system-group-hardware
  - system-group-kvm
  - system-group-libvirt
  - system-group-obsolete
  - system-group-sudo
  - system-group-wheel
  - system-user-bin
  - system-user-brltty
  - system-user-daemon
  - system-user-flatpak
  - system-user-ftp
  - system-user-games
  - system-user-libvirt-dbus
  - system-user-lp
  - system-user-mail
  - system-user-man
  - system-user-news
  - system-user-nobody
  - system-user-ntp
  - system-user-prometheus
  - system-user-pulse
  - system-user-qemu
  - system-user-root
  - system-user-srvGeoClue
  - system-user-tftp
  - system-user-tss
  - system-user-upsd
  - system-user-uucp
  - system-user-uuidd
  - system-user-velociraptor
  - system-user-vscan
  - system-user-wwwrun
  - systemd
  - systemd-container
  - systemd-default-settings
  - systemd-default-settings-branding-SLE
  - systemd-devel
  - systemd-doc
  - systemd-experimental
  - systemd-homed
  - systemd-journal-remote
  - systemd-lang
  - systemd-network
  - systemd-portable
  - systemd-presets-branding-SLE
  - systemd-presets-common-SUSE
  - systemd-rpm-macros
  - systemd-status-mail
  - systemd-zram-service
  - systemtap
  - systemtap-docs
  - systemtap-dtrace
  - systemtap-headers
  - systemtap-runtime
  - systemtap-sdt-devel
  - systemtap-server
  - sysuser-shadow
  - sysuser-tools
  - t1utils
  - tack
  - taglib
  - talloc-man
  - tar
  - tar-backup-scripts
  - tar-doc
  - tar-lang
  - tar-rmt
  - tcl
  - tcl-brlapi
  - tcl-devel
  - tcl-rrdtool
  - tclap
  - tcpd
  - tcpd-devel
  - tcpdump
  - tcsh
  - tcsh-lang
  - tdb-tools
  - tecla-keyboard-layout-viewer
  - tecla-keyboard-layout-viewer-lang
  - telnet
  - telnet-server
  - terminfo
  - terminfo-base
  - terminfo-iterm
  - terminfo-screen
  - testng
  - testng-javadoc
  - tevent-man
  - texi2html
  - texi2html-lang
  - tftp
  - thin-provisioning-tools
  - tidy
  - tidy-doc
  - tidyp
  - tiff
  - tigervnc
  - time
  - timezone
  - tinysparql
  - tix
  - tk
  - tk-devel
  - tmux
  - tomcat
  - tomcat-admin-webapps
  - tomcat-docs-webapp
  - tomcat-el-3_0-api
  - tomcat-embed
  - tomcat-jakartaee-migration
  - tomcat-jakartaee-migration-javadoc
  - tomcat-javadoc
  - tomcat-jsp-2_3-api
  - tomcat-jsvc
  - tomcat-lib
  - tomcat-servlet-4_0-api
  - tomcat-webapps
  - tomcat10
  - tomcat10-admin-webapps
  - tomcat10-doc
  - tomcat10-docs-webapp
  - tomcat10-el-5_0-api
  - tomcat10-embed
  - tomcat10-jsp-3_1-api
  - tomcat10-jsvc
  - tomcat10-lib
  - tomcat10-servlet-6_0-api
  - tomcat10-webapps
  - toolbox
  - totem-pl-parser
  - tpm-tools
  - tpm-tools-devel
  - tpm-tools-pkcs11
  - tpm2-0-tss
  - tpm2-0-tss-devel
  - tpm2-openssl
  - tpm2-tss-engine
  - tpm2-tss-engine-bash-completion
  - tpm2-tss-engine-devel
  - tpm2.0-abrmd
  - tpm2.0-abrmd-devel
  - tpm2.0-tools
  - traceroute
  - tracker-data-files
  - trang
  - transactional-update
  - transactional-update-zypp-config
  - tree
  - tree-sitter-devel
  - trilead-ssh2
  - trilead-ssh2-javadoc
  - trousers
  - trousers-devel
  - truth
  - truth-javadoc
  - ttf-converter
  - tukit
  - tukitd
  - tunctl
  - tuned
  - tuned-gtk
  - tuned-profiles-atomic
  - tuned-profiles-nfv
  - tuned-profiles-openshift
  - tuned-profiles-oracle
  - tuned-profiles-postgresql
  - tuned-profiles-realtime
  - tuned-profiles-spectrumscale
  - tuned-utils
  - tuned-utils-systemtap
  - twolame
  - typelib-1_0-AccountsService-1_0
  - typelib-1_0-Adw-1
  - typelib-1_0-AppIndicator3-0_1
  - typelib-1_0-AppStream-1.0
  - typelib-1_0-AppStream-compose-1.0
  - typelib-1_0-AppStreamGlib-1_0
  - typelib-1_0-Atk-1_0
  - typelib-1_0-Atspi-2_0
  - typelib-1_0-Avahi-0_6
  - typelib-1_0-BlockDev-3_0
  - typelib-1_0-Camel-1_2
  - typelib-1_0-CloudProviders-0_3_0
  - typelib-1_0-Colord-1_0
  - typelib-1_0-ColordGtk-1_0
  - typelib-1_0-Colorhug-1_0
  - typelib-1_0-CudaGst-1_0
  - typelib-1_0-Dbusmenu-0_4
  - typelib-1_0-DbusmenuGtk-0_4
  - typelib-1_0-DbusmenuGtk3-0_4
  - typelib-1_0-Dex-1_0
  - typelib-1_0-EBackend-1_2
  - typelib-1_0-EBook-1_2
  - typelib-1_0-EBookContacts-1_2
  - typelib-1_0-ECal-2_0
  - typelib-1_0-EDataBook-1_2
  - typelib-1_0-EDataCal-2_0
  - typelib-1_0-EDataServer-1_2
  - typelib-1_0-EDataServerUI-1_2
  - typelib-1_0-EDataServerUI4-1_0
  - typelib-1_0-Flatpak-1_0
  - typelib-1_0-Fwupd-2_0
  - typelib-1_0-GCab-1_0
  - typelib-1_0-GIRepository-3_0
  - typelib-1_0-GLib-2_0
  - typelib-1_0-GLibUnix-2_0
  - typelib-1_0-GMenu-3_0
  - typelib-1_0-GModule-2_0
  - typelib-1_0-GObject-2_0
  - typelib-1_0-GSSDP-1_0
  - typelib-1_0-GSound-1_0
  - typelib-1_0-GTop-2_0
  - typelib-1_0-GUPnP-1_0
  - typelib-1_0-GUPnPDLNA-2_0
  - typelib-1_0-GUPnPDLNAGst-2_0
  - typelib-1_0-GUPnPIgd-1_6
  - typelib-1_0-GUdev-1_0
  - typelib-1_0-GUsb-1_0
  - typelib-1_0-GWeather-4_0
  - typelib-1_0-Gck-1
  - typelib-1_0-Gck-2
  - typelib-1_0-Gcr-3
  - typelib-1_0-Gcr-4
  - typelib-1_0-GcrUi-3
  - typelib-1_0-GdkPixbuf-2_0
  - typelib-1_0-GdkPixdata-2_0
  - typelib-1_0-Gdm-1_0
  - typelib-1_0-Geoclue-2_0
  - typelib-1_0-GeocodeGlib-1_0
  - typelib-1_0-GeocodeGlib-2_0
  - typelib-1_0-Gio-2_0
  - typelib-1_0-GjsPrivate-1_0
  - typelib-1_0-Gkbd-3_0
  - typelib-1_0-GnomeAutoar-0_1
  - typelib-1_0-GnomeAutoarGtk-0_1
  - typelib-1_0-GnomeBG-4_0
  - typelib-1_0-GnomeBluetooth-3_0
  - typelib-1_0-GnomeDesktop-3_0
  - typelib-1_0-GnomeDesktop-4_0
  - typelib-1_0-GnomeKeyring-1_0
  - typelib-1_0-GnomeRR-4_0
  - typelib-1_0-Goa-1_0
  - typelib-1_0-Graphene-1_0
  - typelib-1_0-Gspell-1
  - typelib-1_0-Gst-1_0
  - typelib-1_0-GstAllocators-1_0
  - typelib-1_0-GstAnalytics-1_0
  - typelib-1_0-GstApp-1_0
  - typelib-1_0-GstAudio-1_0
  - typelib-1_0-GstBadAudio-1_0
  - typelib-1_0-GstCodecs-1_0
  - typelib-1_0-GstCuda-1_0
  - typelib-1_0-GstGL-1_0
  - typelib-1_0-GstGLEGL-1_0
  - typelib-1_0-GstGLWayland-1_0
  - typelib-1_0-GstGLX11-1_0
  - typelib-1_0-GstInsertBin-1_0
  - typelib-1_0-GstMpegts-1_0
  - typelib-1_0-GstMse-1_0
  - typelib-1_0-GstPbutils-1_0
  - typelib-1_0-GstPlay-1_0
  - typelib-1_0-GstPlayer-1_0
  - typelib-1_0-GstRtp-1_0
  - typelib-1_0-GstRtsp-1_0
  - typelib-1_0-GstRtspServer-1_0
  - typelib-1_0-GstSdp-1_0
  - typelib-1_0-GstTag-1_0
  - typelib-1_0-GstTranscoder-1_0
  - typelib-1_0-GstVa-1_0
  - typelib-1_0-GstValidate-1_0
  - typelib-1_0-GstVideo-1_0
  - typelib-1_0-GstVulkan-1_0
  - typelib-1_0-GstVulkanWayland-1_0
  - typelib-1_0-GstVulkanXCB-1_0
  - typelib-1_0-GstWebRTC-1_0
  - typelib-1_0-Gtk-2_0
  - typelib-1_0-Gtk-3_0
  - typelib-1_0-Gtk-4_0
  - typelib-1_0-HarfBuzz-0_0
  - typelib-1_0-IBus-1_0
  - typelib-1_0-ICal-3_0
  - typelib-1_0-ICalGLib-3_0
  - typelib-1_0-JavaScriptCore-4_0
  - typelib-1_0-JavaScriptCore-4_1
  - typelib-1_0-JavaScriptCore-6_0
  - typelib-1_0-Jcat-1_0
  - typelib-1_0-Json-1_0
  - typelib-1_0-Libosinfo-1_0
  - typelib-1_0-LibvirtGConfig-1_0
  - typelib-1_0-LibvirtGLib-1_0
  - typelib-1_0-LibvirtGObject-1_0
  - typelib-1_0-Malcontent-0
  - typelib-1_0-MalcontentUi-1
  - typelib-1_0-Manette-0_2-0
  - typelib-1_0-Mbim-1_0
  - typelib-1_0-ModemManager-1_0
  - typelib-1_0-Modulemd-2_0
  - typelib-1_0-NM-1_0
  - typelib-1_0-NMA-1_0
  - typelib-1_0-NMA4-1_0
  - typelib-1_0-Nice-0_1
  - typelib-1_0-Notify-0_7
  - typelib-1_0-OSTree-1_0
  - typelib-1_0-Panel-1
  - typelib-1_0-Pango-1_0
  - typelib-1_0-Polkit-1_0
  - typelib-1_0-Poppler-0_18
  - typelib-1_0-Qmi-1_0
  - typelib-1_0-Qrtr-1_0
  - typelib-1_0-Rest-1_0
  - typelib-1_0-Rsvg-2_0
  - typelib-1_0-Secret-1
  - typelib-1_0-Soup-2_4
  - typelib-1_0-Soup-3_0
  - typelib-1_0-Tracker-3_0
  - typelib-1_0-UDisks-2_0
  - typelib-1_0-UMockdev-1_0
  - typelib-1_0-UpowerGlib-1_0
  - typelib-1_0-Vte-2_91
  - typelib-1_0-Vte-3_91
  - typelib-1_0-WebKit-6_0
  - typelib-1_0-WebKit2-4_0
  - typelib-1_0-WebKit2-4_1
  - typelib-1_0-WebKit2WebExtension-4_0
  - typelib-1_0-WebKit2WebExtension-4_1
  - typelib-1_0-WebKitWebProcessExtension-6_0
  - typelib-1_0-Wp-0_5
  - typelib-1_0-Xdp-1_0
  - typelib-1_0-XdpGtk3-1_0
  - typelib-1_0-XdpGtk4-1_0
  - typelib-1_0-Xkl-1_0
  - typelib-1_0-Xmlb-1_0
  - tzdb
  - uchardet
  - ucode-amd
  - udev
  - udisks2
  - udisks2-docs
  - udisks2-lang
  - umoci
  - umockdev
  - umockdev-devel
  - unar
  - unbound
  - unbound-anchor
  - unbound-devel
  - unifdef
  - univocity-parsers
  - univocity-parsers-javadoc
  - unixODBC
  - unixODBC-devel
  - unzip
  - unzip-doc
  - unzip-rcc
  - upb-devel
  - update-alternatives
  - update-bootloader
  - update-desktop-files
  - upower
  - upower-lang
  - uriparser
  - uriparser-devel
  - uriparser-doc
  - usbguard
  - usbguard-devel
  - usbguard-tools
  - usbutils
  - utf8proc-devel
  - util-linux
  - util-linux-lang
  - util-linux-systemd
  - util-linux-tty-tools
  - util-macros-devel
  - utils-libnfs
  - uuidd
  - uv
  - v4l-utils
  - v4l-utils-devel-tools
  - v4l-utils-lang
  - vacation
  - vala
  - valadoc
  - valadoc-doclet-devhelp
  - valadoc-doclet-gtkdoc
  - valadoc-doclet-html
  - valgrind
  - valgrind-client-headers
  - valgrind-devel
  - vcdimager
  - vcdimager-devel
  - ved
  - velociraptor-client
  - velocity
  - velocity-custom-parser-example
  - velocity-demo
  - velocity-engine-core
  - velocity-engine-core-javadoc
  - velocity-engine-examples
  - velocity-engine-javadoc
  - velocity-engine-parent
  - velocity-engine-scripting
  - velocity-javadoc
  - velocity-manual
  - velocity-master
  - vexctl
  - vhostmd
  - vim
  - vim-data
  - vim-data-common
  - vim-small
  - virt-bridge-setup
  - virt-firmware
  - virt-install
  - virt-manager-common
  - virt-scenario-gtk
  - virt-top
  - virt-what
  - virt-win-reg
  - virtiofsd
  - virtual-host-gatherer
  - virtual-host-gatherer-Libvirt
  - virtual-host-gatherer-Nutanix
  - virtual-host-gatherer-VMware
  - virtual-host-gatherer-libcloud
  - vm-dump-metrics
  - voikkospell
  - vpx-tools
  - vsftpd
  - vte-devel
  - vte-lang
  - vte-tools
  - vte-tools-gtk4
  - vulkan-devel
  - vulkan-headers
  - w3m
  - w3m-inline-image
  - wallpaper-branding-SLE
  - wavpack
  - wavpack-doc
  - wayland-devel
  - wayland-protocols-devel
  - wb-cifs-idmap-plugin
  - wdiff
  - wdiff-lang
  - webkit-jsc-4
  - webkit-jsc-4.1
  - webkit-jsc-6.0
  - webkit2gtk-4_0-injected-bundles
  - webkit2gtk-4_1-injected-bundles
  - webkit2gtk3-devel
  - webkit2gtk3-minibrowser
  - webkit2gtk3-soup2-devel
  - webkit2gtk3-soup2-minibrowser
  - webkit2gtk4-devel
  - webkit2gtk4-minibrowser
  - webkitgtk-6_0-injected-bundles
  - werken-xpath
  - werken-xpath-javadoc
  - wget
  - wget-lang
  - which
  - whois
  - whois-bash-completion
  - winpr-devel
  - wireguard-tools
  - wireless-regdb
  - wireless-tools
  - wireplumber
  - wireplumber-audio
  - wireplumber-devel
  - wireplumber-doc
  - wireplumber-lang
  - wireshark
  - wireshark-devel
  - woff2
  - woff2-devel
  - wpa_supplicant
  - wpebackend-fdo-devel
  - wsdl4j
  - wsdl4j-javadoc
  - wtmpdb
  - wtmpdb-devel
  - x11-tools
  - x3270
  - xalan-j2
  - xalan-j2-manual
  - xalan-j2-xsltc
  - xauth
  - xaw3dd
  - xbean
  - xbean-javadoc
  - xbitmaps
  - xbitmaps-devel
  - xbrlapi
  - xcb-proto-devel
  - xcb-util-cursor-devel
  - xcb-util-devel
  - xcb-util-image-devel
  - xcb-util-keysyms-devel
  - xcb-util-renderutil-devel
  - xcb-util-wm-devel
  - xclip
  - xconsole
  - xcursorgen
  - xdg-dbus-proxy
  - xdg-desktop-portal
  - xdg-desktop-portal-devel
  - xdg-desktop-portal-lang
  - xdg-menu
  - xdg-utils
  - xdpyinfo
  - xerces-j2
  - xerces-j2-demo
  - xerces-j2-javadoc
  - xeyes
  - xfsprogs
  - xfsprogs-devel
  - xfsprogs-scrub
  - xhost
  - xinit
  - xkbcomp
  - xkbcomp-devel
  - xkeyboard-config
  - xkeyboard-config-lang
  - xmessage
  - xml-commons-apis
  - xml-commons-apis-javadoc
  - xml-commons-apis-manual
  - xml-commons-resolver
  - xml-commons-resolver-javadoc
  - xmlb-tool
  - xmlcharent
  - xmlgraphics-batik
  - xmlgraphics-batik-css
  - xmlgraphics-batik-demo
  - xmlgraphics-batik-javadoc
  - xmlgraphics-batik-rasterizer
  - xmlgraphics-batik-slideshow
  - xmlgraphics-batik-squiggle
  - xmlgraphics-batik-svgpp
  - xmlgraphics-batik-ttf2svg
  - xmlgraphics-commons
  - xmlgraphics-commons-javadoc
  - xmlgraphics-fop
  - xmlrpc-c-devel
  - xmlsec1
  - xmlsec1-devel
  - xmlsec1-gcrypt-devel
  - xmlsec1-gnutls-devel
  - xmlsec1-nss-devel
  - xmlsec1-openssl-devel
  - xmlstarlet
  - xmltoman
  - xmltooling-schemas
  - xmlunit
  - xmlunit-javadoc
  - xmodmap
  - xmvn
  - xmvn-api
  - xmvn-connector
  - xmvn-connector-ivy
  - xmvn-connector-ivy-javadoc
  - xmvn-connector-javadoc
  - xmvn-core
  - xmvn-install
  - xmvn-minimal
  - xmvn-mojo
  - xmvn-mojo-javadoc
  - xmvn-parent
  - xmvn-resolve
  - xmvn-subst
  - xmvn-tools-javadoc
  - xom
  - xom-demo
  - xom-javadoc
  - xorg-x11-fonts
  - xorg-x11-fonts-converted
  - xorg-x11-fonts-core
  - xorg-x11-fonts-legacy
  - xorgproto-devel
  - xorriso
  - xorriso-tcltk
  - xpp3
  - xpp3-javadoc
  - xpp3-minimal
  - xprop
  - xrdb
  - xsel
  - xset
  - xsetroot
  - xtables-plugins
  - xterm
  - xterm-bin
  - xterm-resize
  - xtrans
  - xwayland
  - xwayland-devel
  - xxd
  - xxhash
  - xxhash-devel
  - xz
  - xz-devel
  - xz-java
  - xz-java-javadoc
  - xz-lang
  - yajl
  - yaml-cpp-devel
  - yelp-tools
  - yelp-xsl
  - zchunk
  - zd1211-firmware
  - zeromq-devel
  - zeromq-tools
  - zip
  - zisofs-tools
  - zlib-devel
  - zlib-devel-static
  - zopfli
  - zram-generator
  - zstd
  - zstd-gzip
  - zvbi
  - zvbi-lang
  - zypp-boot-plugin
  - zypper
  - zypper-aptitude
  - zypper-lifecycle-plugin
  - zypper-log
  - zypper-needs-restarting

# TODO: unneeded SLES package per architecture
- name: sles_unneeded_aarch64
  packages:
  - Mesa-dri-nouveau
  - Mesa-gallium
  - Mesa-libOpenCL
  - Mesa-libRusticlOpenCL
  - Mesa-libva
  - Mesa-vulkan-device-select
  - Mesa-vulkan-overlay
  - SLES_SAP-release
  - SVT-AV1
  - SVT-AV1-devel
  - afterburn
  - afterburn-dracut
  - alsa-topology-devel
  - arm-trusted-firmware-rpi3
  - arm-trusted-firmware-rpi4
  - blosc2-devel
  - busybox-warewulf3
  - cluster-md-kmp-64kb
  - crash-kmp-64kb
  - criu-plugin-amdgpu
  - dlm-kmp-64kb
  - dmidecode
  - dnsdist
  - dpdk
  - dpdk-devel
  - dpdk-devel-static
  - dpdk-doc
  - dpdk-tools
  - drbd-kmp-64kb
  - fde-firstboot
  - fde-tools
  - fde-tools-bash-completion
  - fde-tpm-helper
  - fftw3-mpi-devel
  - flashrom
  - flashrom-devel
  - fwts
  - fwupd-efi
  - gcc-d
  - gcc15-d
  - gfs2-kmp-64kb
  - go1.23-libstd
  - go1.24-libstd
  - gprofng
  - grub2-arm64-efi
  - grub2-branding-SLE
  - gstreamer-plugins-bad-devel
  - gstreamer-plugins-rs
  - gstreamer-plugins-rs-devel
  - himmelblau
  - himmelblau-sshd-config
  - hyper-v
  - irqbalance
  - irqbalance-ui
  - kernel-64kb
  - kernel-64kb-devel
  - kernel-debug
  - kernel-debug-devel
  - kernel-default-base
  - kernel-kvmsmall
  - kernel-kvmsmall-devel
  - ldacBT-devel
  - lftp
  - libLLVMSPIRVLib19
  - libQt6Pdf6
  - libQt6PdfQuick6
  - libQt6PdfWidgets6
  - libQt6WebEngineCore6
  - libQt6WebEngineQuick6
  - libQt6WebEngineWidgets6
  - libSvtAv1Enc2
  - libatopology2
  - libblosc2-2
  - libc++1
  - libc++abi1
  - libdpdk-25
  - libdrm_etnaviv1
  - libdrm_exynos1
  - libdrm_freedreno1
  - libdrm_intel1
  - libdrm_tegra0
  - libfftw3_mpi3
  - libflashrom1
  - libgdruntime6
  - libgphobos6
  - libgstdxva-1_0-0
  - libheif-svtenc
  - libhwasan0
  - libicu77-ledata
  - libkrun-devel
  - libkrun1
  - libkrunfw-devel
  - libkrunfw3
  - libldac2
  - liblttng-ctl0
  - liblttng-ust-ctl5
  - liblttng-ust-python-agent1
  - liblttng-ust1
  - libluajit-5_1-2
  - libndctl-devel
  - libndctl6
  - libnss_himmelblau2
  - libnvidia-egl-wayland-devel
  - libnvidia-egl-wayland1
  - libostree-grub2
  - libpmem1
  - libpmem2-1
  - libpmempool1
  - librpmem1
  - libunwind-coredump0
  - libvdpau_nouveau
  - libvdpau_r600
  - libvdpau_radeonsi
  - libvdpau_virtio_gpu
  - libvma
  - libvma-devel
  - libvma9
  - libvmtools-devel
  - libvmtools0
  - libvpl
  - libvpl-devel
  - libvpl2
  - libvulkan_broadcom
  - libvulkan_freedreno
  - libvulkan_lvp
  - libvulkan_radeon
  - libwebrtc-audio-coding-1-3
  - libwebrtc-audio-processing-1-3
  - libxatracker-devel
  - libxatracker2
  - lttng-tools
  - lttng-tools-devel
  - lttng-ust-devel
  - lttng-ust-doc
  - luajit
  - luajit-devel
  - mokutil
  - ndctl
  - nv-prefer-signed-open-driver
  - nvidia-open-driver-G06-signed-64kb-devel
  - nvidia-open-driver-G06-signed-cuda-64kb-devel
  - nvidia-open-driver-G06-signed-cuda-default-devel
  - nvidia-open-driver-G06-signed-cuda-kmp-64kb
  - nvidia-open-driver-G06-signed-cuda-kmp-default
  - nvidia-open-driver-G06-signed-default-devel
  - nvidia-open-driver-G06-signed-kmp-64kb
  - nvidia-open-driver-G06-signed-kmp-default
  - nvptx-tools
  - open-vm-tools
  - open-vm-tools-containerinfo
  - open-vm-tools-desktop
  - open-vm-tools-sdmp
  - ovmf
  - ovmf-tools
  - pam-doc
  - pam-manpages
  - pcp-pmda-infiniband
  - pcp-pmda-perfevent
  - pcr-oracle
  - pesign
  - pmdk-devel-doc
  - python3-lttngust
  - python313-BTrees
  - python313-BTrees-devel
  - python313-CairoSVG
  - python313-Pillow
  - python313-Pillow-tk
  - python313-apache-libcloud
  - python313-asttokens
  - python313-enrich
  - python313-factory_boy
  - python313-falcon
  - python313-fastjsonschema
  - python313-hatch
  - python313-isoduration
  - python313-jsonschema-format
  - python313-jsonschema-format-nongpl
  - python313-manuel
  - python313-manuel-doc
  - python313-markdown-it-py
  - python313-mdit-py-plugins
  - python313-paramiko
  - python313-persistent
  - python313-persistent-devel
  - python313-pygal
  - python313-pytest-benchmark
  - python313-pytest-randomly
  - python313-pytest-regressions
  - python313-pyzmq
  - python313-pyzmq-devel
  - python313-rich
  - python313-subprocess-tee
  - python313-validate-pyproject
  - qemu-ovmf-x86_64
  - qemu-uefi-aarch64
  - qt6-pdf-imports
  - qt6-webengine
  - qt6-webengine-docs-html
  - qt6-webengine-docs-qch
  - qt6-webengine-examples
  - qt6-webengine-imports
  - shim
  - systemd-boot
  - tftpboot-agama-installer-SUSE_SLE_16_PXE-aarch64
  - typelib-1_0-GstDxva-1_0
  - u-boot-rpi3
  - u-boot-rpi3-doc
  - u-boot-rpi4
  - u-boot-rpi4-doc
  - u-boot-rpiarm64
  - u-boot-rpiarm64-doc
  - u-boot-tools

- name: sles_unneeded_ppc64le
  packages:
  - Mesa-dri-nouveau
  - Mesa-gallium
  - Mesa-libOpenCL
  - Mesa-libRusticlOpenCL
  - Mesa-libva
  - SLES_SAP-release
  - alsa-topology-devel
  - blosc2-devel
  - dovecot
  - dovecot24
  - dovecot24-backend-mysql
  - dovecot24-backend-pgsql
  - dovecot24-backend-sqlite
  - dovecot24-devel
  - dovecot24-fts
  - dovecot24-fts-solr
  - dpdk
  - dpdk-devel
  - dpdk-devel-static
  - dpdk-doc
  - dpdk-tools
  - fence-agents-ironic
  - fftw3-mpi-devel
  - grub2-branding-SLE
  - grub2-powerpc-ieee1275
  - iprutils
  - irqbalance
  - irqbalance-ui
  - kernel-debug
  - kernel-debug-devel
  - kernel-default-base
  - kernel-kvmsmall
  - kernel-kvmsmall-devel
  - ldacBT-devel
  - libLLVMSPIRVLib19
  - libatopology2
  - libblosc2-2
  - libdpdk-25
  - libdrm_intel1
  - libfftw3_mpi3
  - libicu77-ledata
  - libldac2
  - liblttng-ctl0
  - liblttng-ust-ctl5
  - liblttng-ust-python-agent1
  - liblttng-ust1
  - libndctl-devel
  - libndctl6
  - libnxz-devel
  - libnxz0
  - libostree-grub2
  - libpmem-devel
  - libpmem1
  - libpmem2-1
  - libpmemblk-devel
  - libpmemblk1
  - libpmemlog-devel
  - libpmemlog1
  - libpmemobj-devel
  - libpmemobj1
  - libpmempool-devel
  - libpmempool1
  - libpulp-tools
  - libpulp0
  - libpython3_13t-1_0
  - libquadmath-devel
  - libquadmath0
  - libquadmath0-devel-gcc15
  - librpmem1
  - librtas2
  - libservicelog
  - libservicelog-1_1-1
  - libvdpau_nouveau
  - libvdpau_r600
  - libvdpau_radeonsi
  - libvdpau_virtio_gpu
  - libvma
  - libvma-devel
  - libvma9
  - libwebrtc-audio-coding-1-3
  - libwebrtc-audio-processing-1-3
  - libxatracker-devel
  - libxatracker2
  - lsvpd
  - lttng-tools
  - lttng-tools-devel
  - lttng-ust-devel
  - lttng-ust-doc
  - ndctl
  - numatop
  - patterns-sap-APP
  - patterns-sap-DB
  - patterns-sap-HAAPP
  - patterns-sap-HADB
  - patterns-sap-addons
  - patterns-sap-automation
  - patterns-sap-base_sap_server
  - patterns-sap-debug
  - patterns-sap-gui
  - patterns-sap-minimal_sap
  - patterns-sap-monitoring
  - patterns-sap-sap_all
  - patterns-sap-security
  - patterns-sap-trento_agent
  - patterns-sap-trento_server
  - pcp-pmda-infiniband
  - pcp-pmda-perfevent
  - pcr-oracle
  - pmdk
  - pmdk-devel-doc
  - pmdk-tools
  - powerpc-utils
  - ppc64-diag
  - python3-lttngust
  - python313-BTrees
  - python313-BTrees-devel
  - python313-CairoSVG
  - python313-Pillow
  - python313-Pillow-tk
  - python313-apache-libcloud
  - python313-asttokens
  - python313-enrich
  - python313-factory_boy
  - python313-falcon
  - python313-fastjsonschema
  - python313-hatch
  - python313-isoduration
  - python313-jsonschema-format
  - python313-jsonschema-format-nongpl
  - python313-manuel
  - python313-manuel-doc
  - python313-markdown-it-py
  - python313-mdit-py-plugins
  - python313-nogil
  - python313-nogil-base
  - python313-nogil-curses
  - python313-nogil-dbm
  - python313-nogil-devel
  - python313-nogil-idle
  - python313-nogil-tk
  - python313-nogil-tools
  - python313-paramiko
  - python313-persistent
  - python313-persistent-devel
  - python313-pygal
  - python313-pytest-benchmark
  - python313-pytest-randomly
  - python313-pytest-regressions
  - python313-pyzmq
  - python313-pyzmq-devel
  - python313-rich
  - python313-subprocess-tee
  - python313-validate-pyproject
  - saptune
  - secvarctl
  - servicelog
  - sysctl-logger
  - systemd-presets-branding-SLE-SAP
  - tftpboot-agama-installer-SUSE_SLE_16_PXE-ppc64le

- name: sles_unneeded_s390x
  packages:
  - SLES-release
  - dnsdist
  - gcc-d
  - gcc15-d
  - grub2-s390x-emu
  - kernel-zfcpdump
  - kiwi-settings
  - lftp
  - libHBAAPI2
  - libekmfweb1
  - libgdruntime6
  - libgphobos6
  - libica-devel
  - libica-tools
  - libica4
  - libicu77-bedata
  - libkmipclient1
  - libluajit-5_1-2
  - libpython3_13t-1_0
  - libqc2
  - libzdnn-devel
  - libzdnn0
  - libzfcphbaapi0
  - libzpc-devel
  - libzpc1
  - luajit
  - luajit-devel
  - openssl-ibmca
  - openssl-ibmca-engine
  - openssl-ibmca-provider
  - osasnmpd
  - pam-doc
  - pam-manpages
  - python-falcon-doc
  - python311-Pygments
  - python311-markdown-it-py
  - python311-mdurl
  - python311-pyzmq
  - python311-rich
  - python313-nogil
  - python313-nogil-base
  - python313-nogil-curses
  - python313-nogil-dbm
  - python313-nogil-devel
  - python313-nogil-idle
  - python313-nogil-tk
  - python313-nogil-tools
  - qclib
  - s390-tools
  - s390-tools-chreipl-fcp-mpath
  - s390-tools-genprotimg-data
  - s390-tools-hmcdrvfs
  - s390-tools-zdsfs
  - tftpboot-agama-installer-SUSE_SLE_16_PXE-s390x

- name: sles_unneeded_x86_64
  packages:
  - DirectX-Headers
  - Mesa-dri-nouveau
  - Mesa-gallium
  - Mesa-libOpenCL
  - Mesa-libRusticlOpenCL
  - Mesa-libd3d
  - Mesa-libd3d-devel
  - Mesa-libva
  - Mesa-vulkan-device-select
  - Mesa-vulkan-overlay
  - SLES_SAP-release
  - SVT-AV1
  - SVT-AV1-devel
  - accel-config
  - accel-config-devel
  - afterburn
  - afterburn-dracut
  - alsa-topology-devel
  - biosdevname
  - blosc2-devel
  - busybox-warewulf3
  - crash-gcore
  - criu-plugin-amdgpu
  - cross-nvptx-gcc15
  - cross-nvptx-newlib15-devel
  - dmidecode
  - dnsdist
  - dovecot
  - dovecot24
  - dovecot24-backend-mysql
  - dovecot24-backend-pgsql
  - dovecot24-backend-sqlite
  - dovecot24-devel
  - dovecot24-fts
  - dovecot24-fts-solr
  - dpdk
  - dpdk-devel
  - dpdk-devel-static
  - dpdk-doc
  - dpdk-tools
  - eth-basic-tools
  - eth-fastfabric
  - fde-firstboot
  - fde-tools
  - fde-tools-bash-completion
  - fde-tpm-helper
  - fence-agents-aliyun
  - fence-agents-ironic
  - fftw3-mpi-devel
  - flashrom
  - flashrom-devel
  - fwts
  - fwupd-efi
  - gcc-d
  - gcc15-d
  - gfxboot
  - gfxboot-branding-SLES
  - gfxboot-devel
  - gmmlib-devel
  - go1.23-libstd
  - go1.24-libstd
  - gprofng
  - grub2-branding-SLE
  - grub2-i386-pc
  - grub2-x86_64-efi
  - gstreamer-plugins-bad-devel
  - gstreamer-plugins-rs
  - gstreamer-plugins-rs-devel
  - himmelblau
  - himmelblau-sshd-config
  - hyper-v
  - infinipath-psm-devel
  - intel-cmt-cat
  - intel-lpmd
  - intel-media-driver
  - ipmctl
  - irqbalance
  - irqbalance-ui
  - kernel-debug
  - kernel-debug-devel
  - kernel-debug-vdso
  - kernel-default-base
  - kernel-default-vdso
  - kernel-kvmsmall
  - kernel-kvmsmall-devel
  - kernel-kvmsmall-vdso
  - kiwi-pxeboot
  - ldacBT-devel
  - lftp
  - libFLAC++10-x86-64-v3
  - libFLAC12-x86-64-v3
  - libLLVMSPIRVLib19
  - libQt6Pdf6
  - libQt6PdfQuick6
  - libQt6PdfWidgets6
  - libQt6WebEngineCore6
  - libQt6WebEngineQuick6
  - libQt6WebEngineWidgets6
  - libSvtAv1Enc2
  - libaccel-config1
  - libatopology2
  - libblosc2-2
  - libblosc2-2-x86-64-v3
  - libboost_atomic1_86_0-x86-64-v3
  - libboost_charconv1_86_0-x86-64-v3
  - libboost_container1_86_0-x86-64-v3
  - libboost_date_time1_86_0-x86-64-v3
  - libboost_filesystem1_86_0-x86-64-v3
  - libboost_graph1_86_0-x86-64-v3
  - libboost_iostreams1_86_0-x86-64-v3
  - libboost_json1_86_0-x86-64-v3
  - libboost_locale1_86_0-x86-64-v3
  - libboost_math1_86_0-x86-64-v3
  - libboost_nowide1_86_0-x86-64-v3
  - libboost_process1_86_0-x86-64-v3
  - libboost_program_options1_86_0-x86-64-v3
  - libboost_random1_86_0-x86-64-v3
  - libboost_regex1_86_0-x86-64-v3
  - libboost_serialization1_86_0-x86-64-v3
  - libboost_stacktrace1_86_0-x86-64-v3
  - libboost_system1_86_0-x86-64-v3
  - libboost_test1_86_0-x86-64-v3
  - libboost_thread1_86_0-x86-64-v3
  - libboost_type_erasure1_86_0-x86-64-v3
  - libboost_url1_86_0-x86-64-v3
  - libboost_wave1_86_0-x86-64-v3
  - libbrotlicommon1-x86-64-v3
  - libbrotlidec1-x86-64-v3
  - libbrotlienc1-x86-64-v3
  - libbz2-1-x86-64-v3
  - libc++1
  - libc++abi1
  - libdb-4_8-x86-64-v3
  - libdpdk-25
  - libdrm_intel1
  - libfftw3_mpi3
  - libflashrom1
  - libgcrypt-devel-x86-64-v3
  - libgcrypt20-x86-64-v3
  - libgdruntime6
  - libgphobos6
  - libgstdxva-1_0-0
  - libheif-svtenc
  - libhogweed6-x86-64-v3
  - libhwasan0
  - libicu77-ledata
  - libigdgmm12
  - libigfxcmrt-devel
  - libigfxcmrt7
  - libinfinipath4
  - libiscsi9-x86-64-v3
  - libjpeg8-x86-64-v3
  - libjsoncpp25-x86-64-v3
  - libjxl0_11-x86-64-v3
  - libkrun-devel
  - libkrun-sev-devel
  - libkrun-sev1
  - libkrun1
  - libkrunfw-devel
  - libkrunfw-sev-devel
  - libkrunfw-sev3
  - libkrunfw3
  - libldac2
  - liblttng-ctl0
  - liblttng-ust-ctl5
  - liblttng-ust-python-agent1
  - liblttng-ust1
  - libluajit-5_1-2
  - liblz4-1-x86-64-v3
  - liblzma5-x86-64-v3
  - liblzo2-2-x86-64-v3
  - libmfx
  - libmfx1
  - libminizip1-x86-64-v3
  - libmng2-x86-64-v3
  - libmp3lame0-x86-64-v3
  - libndctl-devel
  - libndctl6
  - libnettle8-x86-64-v3
  - libnsl-stub1
  - libnss_himmelblau2
  - libnvidia-egl-wayland-devel
  - libnvidia-egl-wayland1
  - libopamgt-devel
  - libopamgt0
  - libopasadb1_0_0
  - libopenjp2-7-x86-64-v3
  - libopenssl-3-fips-provider-x86-64-v3
  - libopenssl3-x86-64-v3
  - libostree-grub2
  - libpmem-devel
  - libpmem1
  - libpmem2-1
  - libpmem2-devel
  - libpmemblk-devel
  - libpmemblk1
  - libpmemlog-devel
  - libpmemlog1
  - libpmemobj-devel
  - libpmemobj1
  - libpmempool-devel
  - libpmempool1
  - libpng16-16-x86-64-v3
  - libpng16-compat-devel-x86-64-v3
  - libpng16-devel-x86-64-v3
  - libpqos-devel
  - libpqos5
  - libpsm2-2
  - libpsm2-compat
  - libpsm2-devel
  - libpsm_infinipath1
  - libpulp-tools
  - libpulp0
  - libpython3_11-1_0-x86-64-v3
  - libpython3_13t-1_0
  - libqat4
  - libqatzip3
  - libquadmath-devel
  - libquadmath0
  - libquadmath0-devel-gcc15
  - librpmem1
  - libsmbios-devel
  - libsmbios-lang
  - libsmbios_c2
  - libsqlite3-0-x86-64-v3
  - libtalloc2-x86-64-v3
  - libtree-sitter0_25-x86-64-v3
  - libturbojpeg0-x86-64-v3
  - libunwind-coredump0
  - libusdm0
  - libvdpau_nouveau
  - libvdpau_r600
  - libvdpau_radeonsi
  - libvdpau_virtio_gpu
  - libvma
  - libvma-devel
  - libvma9
  - libvmtools-devel
  - libvmtools0
  - libvorbis0-x86-64-v3
  - libvorbisenc2-x86-64-v3
  - libvorbisfile3-x86-64-v3
  - libvpl
  - libvpl-devel
  - libvpl2
  - libvulkan_intel
  - libvulkan_lvp
  - libvulkan_radeon
  - libwavpack1-x86-64-v3
  - libwebrtc-audio-coding-1-3
  - libwebrtc-audio-processing-1-3
  - libxatracker-devel
  - libxatracker2
  - libxmlb2-x86-64-v3
  - libz1-x86-64-v3
  - libzopfli1-x86-64-v3
  - libzopflipng1-x86-64-v3
  - libzstd1-x86-64-v3
  - lttng-tools
  - lttng-tools-devel
  - lttng-ust-devel
  - lttng-ust-doc
  - luajit
  - luajit-devel
  - mcelog
  - mokutil
  - nbdkit-nbd-plugin
  - nbdkit-python-plugin
  - nbdkit-vddk-plugin
  - ndctl
  - numatop
  - nv-prefer-signed-open-driver
  - nvidia-open-driver-G06-signed-cuda-default-devel
  - nvidia-open-driver-G06-signed-cuda-kmp-default
  - nvidia-open-driver-G06-signed-default-devel
  - nvidia-open-driver-G06-signed-kmp-default
  - nvptx-tools
  - opa-address-resolution
  - opa-address-resolution-devel
  - opa-basic-tools
  - opa-fastfabric
  - opa-fm
  - opa-snapconfig
  - open-vm-tools
  - open-vm-tools-containerinfo
  - open-vm-tools-desktop
  - open-vm-tools-sdmp
  - ovmf
  - ovmf-tools
  - pam-doc
  - pam-manpages
  - patterns-sap-APP
  - patterns-sap-DB
  - patterns-sap-HAAPP
  - patterns-sap-HADB
  - patterns-sap-addons
  - patterns-sap-automation
  - patterns-sap-base_sap_server
  - patterns-sap-debug
  - patterns-sap-gui
  - patterns-sap-minimal_sap
  - patterns-sap-monitoring
  - patterns-sap-sap_all
  - patterns-sap-security
  - patterns-sap-trento_agent
  - patterns-sap-trento_server
  - pcp-pmda-infiniband
  - pcp-pmda-perfevent
  - pcp-pmda-resctrl
  - pcr-oracle
  - pesign
  - pmdk
  - pmdk-devel-doc
  - pmdk-tools
  - python3-lttngust
  - python3-smbios
  - python3-smbios-utils
  - python3-talloc-x86-64-v3
  - python313-BTrees
  - python313-BTrees-devel
  - python313-CairoSVG
  - python313-Pillow
  - python313-Pillow-tk
  - python313-apache-libcloud
  - python313-asttokens
  - python313-base-x86-64-v3
  - python313-enrich
  - python313-factory_boy
  - python313-falcon
  - python313-fastjsonschema
  - python313-hatch
  - python313-isoduration
  - python313-jsonschema-format
  - python313-jsonschema-format-nongpl
  - python313-manuel
  - python313-manuel-doc
  - python313-markdown-it-py
  - python313-mdit-py-plugins
  - python313-nogil
  - python313-nogil-base
  - python313-nogil-curses
  - python313-nogil-dbm
  - python313-nogil-devel
  - python313-nogil-idle
  - python313-nogil-tk
  - python313-nogil-tools
  - python313-paramiko
  - python313-persistent
  - python313-persistent-devel
  - python313-pygal
  - python313-pytest-benchmark
  - python313-pytest-randomly
  - python313-pytest-regressions
  - python313-pyzmq
  - python313-pyzmq-devel
  - python313-rich
  - python313-subprocess-tee
  - python313-validate-pyproject
  - python313-x86-64-v3
  - qatengine
  - qatlib
  - qatlib-devel
  - qatzip
  - qatzip-devel
  - qemu-ovmf-x86_64
  - qemu-vmsr-helper
  - qt6-pdf-imports
  - qt6-webengine
  - qt6-webengine-docs-html
  - qt6-webengine-docs-qch
  - qt6-webengine-examples
  - qt6-webengine-imports
  - rpmemd
  - s390-tools
  - s390-tools-genprotimg-data
  - saptune
  - sevctl
  - shim
  - smbios-utils
  - snpguest
  - sysctl-logger
  - syslinux
  - systemd-boot
  - systemd-presets-branding-SLE-SAP
  - tftpboot-agama-installer-SUSE_SLE_16_PXE-x86_64
  - thermald
  - typelib-1_0-GstDxva-1_0
  - ucode-intel
  - velociraptor
  - virt-v2v
  - virt-v2v-bash-completion
  - virt-v2v-man-pages-ja
  - virt-v2v-man-pages-uk

- name: backports_aarch64
  flavors:
  - backports_aarch64
  architectures:
  - aarch64
  add:
  - __all__
  sub:
  - backports_unneeded
  - sles_unneeded
  - backports_unneeded_aarch64
  - sles_unneeded_aarch64

- name: backports_ppc64le
  flavors:
  - backports_ppc64le
  architectures:
  - ppc64le
  add:
  - __all__
  sub:
  - backports_unneeded
  - sles_unneeded
  - backports_unneeded_ppc64le
  - sles_unneeded_ppc64le

- name: backports_s390x
  flavors:
  - backports_s390x
  architectures:
  - s390x
  add:
  - __all__
  sub:
  - backports_unneeded
  - sles_unneeded
  - backports_unneeded_s390x
  - sles_unneeded_s390x

- name: backports_x86_64
  flavors:
  - backports_x86_64
  architectures:
  - x86_64
  add:
  - __all__
  sub:
  - backports_unneeded
  - sles_unneeded
  - backports_unneeded_x86_64
  - sles_unneeded_x86_64

- name: main
  add:
  - backports_aarch64
  - backports_ppc64le
  - backports_s390x
  - backports_x86_64

07070100000051000081a4000000000000000000000001684059c4000000a0000000000000000000000000000000000000004600000000product-composer/tests/assets/tomls/InvalidBuildOption.productcomposeproduct_compose_schema: 0.2

vendor: openSUSE
name: Backports
version: 16
product-type: base
summary: openSUSE Backports

build_options:
- invalid_build_option
07070100000052000081a4000000000000000000000001684059c400000066000000000000000000000000000000000000004100000000product-composer/tests/assets/tomls/InvalidSchema.productcomposeproduct_compose_schema: 0.2

vendor: openSUSE
name: Backports
version: 16
summary: openSUSE Backports
07070100000053000081a4000000000000000000000001684059c40000005c000000000000000000000000000000000000004400000000product-composer/tests/assets/tomls/MissingSchemaVer.productcomposevendor: openSUSE
name: Backports
version: 16
product-type: base
summary: openSUSE Backports
07070100000054000081a4000000000000000000000001684059c400000079000000000000000000000000000000000000004800000000product-composer/tests/assets/tomls/UnsupportedSchemaVer.productcomposeproduct_compose_schema: 0.3

vendor: openSUSE
name: Backports
version: 16
product-type: base
summary: openSUSE Backports
07070100000055000041ed000000000000000000000001684059c400000000000000000000000000000000000000000000002400000000product-composer/tests/assets/tomls07070100000056000041ed000000000000000000000001684059c400000000000000000000000000000000000000000000001e00000000product-composer/tests/assets07070100000057000081a4000000000000000000000001684059c40000008c000000000000000000000000000000000000002200000000product-composer/tests/pytest.ini[pytest]
# Names with with a leading underscore are ignored.
python_files = test_*.py
python_classes = [A-Z]*Test
python_functions = test_*
07070100000058000081a4000000000000000000000001684059c4000008af000000000000000000000000000000000000003900000000product-composer/tests/unit/core/test_logger.py.disabled""" Test suite for the core.logger module.

The script can be executed on its own or incorporated into a larger test suite.
However the tests are run, be aware of which version of the package is actually
being tested. If the package is installed in site-packages, that version takes
precedence over the version in this project directory. Use a virtualenv test
environment or setuptools develop mode to test against the development version.

"""
from logging import DEBUG
from io import StringIO

import pytest

from obsimager.core.logger import logger as _logger


@pytest.fixture
def logger():
    """ Get the global logger object for testing.

    """
    yield _logger
    _logger.stop()  # reset logger after each test
    return


class LoggerTest(object):
    """ Test suite for the Logger class.

    """
    def test_start(self, capsys, logger):
        """ Test the start method.

        """
        message = "test message"
        logger.start("debug")
        logger.debug(message)
        _, stderr = capsys.readouterr()
        assert logger.level == DEBUG
        assert message in stderr
        return

    def test_stop(self, capsys, logger):
        """ Test the stop() method.

        """
        logger.start("debug")
        logger.stop()
        logger.critical("test")
        _, stderr = capsys.readouterr()
        assert not stderr
        return

    def test_restart(self, capsys, logger):
        """ Test a restart.

        """
        debug_message = "debug message"
        logger.start("INFO")
        logger.debug(debug_message)
        _, stderr = capsys.readouterr()
        assert debug_message not in stderr
        logger.stop()
        logger.start("DEBUG")
        logger.debug(debug_message)
        _, stderr = capsys.readouterr()
        assert debug_message in stderr
        return

    def test_stream(self, logger):
        """ Test output to an alternate stream.

        """
        message = "test message"
        stream = StringIO()
        logger.start("debug", stream)
        logger.debug(message)
        assert message in stream.getvalue()
        return


# Make the module executable.

if __name__ == "__main__":
    raise SystemExit(pytest.main([__file__]))
07070100000059000041ed000000000000000000000001684059c400000000000000000000000000000000000000000000002100000000product-composer/tests/unit/core0707010000005a000081a4000000000000000000000001684059c40000013d000000000000000000000000000000000000003800000000product-composer/tests/unit/parsers/test_eulasparser.pyimport pytest
from productcomposer.parsers.eulasparser import parse_eulas

def test_eulasparser_ok():
    eulas = {}
    parse_eulas("./tests/assets/eulas", eulas)
    assert len(eulas) == 3

def test_eulasparser_wrong_path():
    eulas = {}
    parse_eulas("./tests/assets/xulas", eulas)
    assert len(eulas) == 0

0707010000005b000081a4000000000000000000000001684059c400000208000000000000000000000000000000000000004000000000product-composer/tests/unit/parsers/test_supportstatusparser.pyimport pytest
from productcomposer.parsers.supportstatusparser import parse_supportstatus

def test_supportstatusparser_ok():
    supportstatus_override={}
    parse_supportstatus("./tests/assets/supportstatus.txt", supportstatus_override)
    print(supportstatus_override)
    assert len(supportstatus_override) == 73

def test_supportstatusparser_ko():
    supportstatus_override={}
    parse_supportstatus("./tests/assets/supportstatus-wrong.txt", supportstatus_override)
    assert len(supportstatus_override) == 0

0707010000005c000081a4000000000000000000000001684059c40000074c000000000000000000000000000000000000003700000000product-composer/tests/unit/parsers/test_yamlparser.pyimport pytest
from schema import Schema, And, Or, Optional, SchemaError, SchemaMissingKeyError
from productcomposer.parsers.yamlparser import parse_yaml

def test_yamlparser_ok():
    yml = parse_yaml('./tests/assets/tomls/Backports.productcompose', 'backports_x86_64')
    assert len(yml['flavors']) == 4


def test_yamlparser_wrong_schema(capsys):
    with pytest.raises(SystemExit) as excinfo:
        yml = parse_yaml('./tests/assets/tomls/UnsupportedSchemaVer.productcompose', 'backports_x86_64')

    assert excinfo.type == SystemExit
    assert excinfo.value.code == 1

    captured = capsys.readouterr()
    assert "ERROR: Unsupported product composer schema: 0.3" in captured.out


def test_yamlparser_missing_schema(capsys):
    with pytest.raises(SystemExit) as excinfo:
        yml = parse_yaml('./tests/assets/tomls/MissingSchemaVer.productcompose', 'backports_x86_64')

    assert excinfo.type == SystemExit
    assert excinfo.value.code == 1

    captured = capsys.readouterr()
    assert "ERROR: missing product composer schema" in captured.out    

def test_yamlparser_invalid_schema():
    with pytest.raises(SchemaMissingKeyError, match="Missing key: 'product-type'"):
        yml = parse_yaml('./tests/assets/tomls/InvalidSchema.productcompose', 'backports_x86_64')

def test_yamlparser_flavor_notfound(capsys):
    with pytest.raises(SystemExit) as excinfo:
        yml = parse_yaml('./tests/assets/tomls/Backports.productcompose', 'ports_x86_64')

    assert excinfo.type == SystemExit
    assert excinfo.value.code == 1

    captured = capsys.readouterr()
    assert "ERROR: Flavor not found" in captured.out            

def test_yamlparser_invalid_buildoption(capsys):
    with pytest.raises(SchemaError, match="Key 'build_options' error"):
        yml = parse_yaml('./tests/assets/tomls/InvalidBuildOption.productcompose', 'backports_x86_64')0707010000005d000041ed000000000000000000000001684059c400000000000000000000000000000000000000000000002400000000product-composer/tests/unit/parsers0707010000005e000081a4000000000000000000000001684059c40000034f000000000000000000000000000000000000003100000000product-composer/tests/unit/test_api.py.disabled""" Test suite for the api module.

The script can be executed on its own or incorporated into a larger test suite.
However the tests are run, be aware of which version of the module is actually
being tested. If the library is installed in site-packages, that version takes
precedence over the version in this project directory. Use a virtualenv test
environment or setuptools develop mode to test against the development version.

"""
import pytest
from obsimager.api import *  # tests __all__


def test_hello():
    """ Test the hello() function.

    """
    assert hello() == "Hello, World!"
    return


def test_hello_name():
    """ Test the hello() function with a name.

    """
    assert hello("foo") == "Hello, foo!"
    return


# Make the script executable.

if __name__ == "__main__":
    raise SystemExit(pytest.main([__file__]))
0707010000005f000081a4000000000000000000000001684059c4000005d6000000000000000000000000000000000000003100000000product-composer/tests/unit/test_cli.py.disabled""" Test suite for the cli module.

The script can be executed on its own or incorporated into a larger test suite.
However the tests are run, be aware of which version of the module is actually
being tested. If the library is installed in site-packages, that version takes
precedence over the version in this project directory. Use a virtualenv test
environment or setuptools develop mode to test against the development version.

"""
from shlex import split
from subprocess import call
from sys import executable

import pytest
from obsimager.cli import *  # test __all__


@pytest.fixture(params=("--help", "hello"))
def command(request):
    """ Return the command to run.

    """
    return request.param


def test_main(command):
    """ Test the main() function.

    """
    try:
        status = main(split(command))
    except SystemExit as ex:
        status = ex.code
    assert status == 0
    return

def test_main_none():
    """ Test the main() function with no arguments.
    
    """
    with pytest.raises(SystemExit) as exinfo:
        main([])  # displays a help message and exits gracefully
    assert exinfo.value.code == 1


def test_script(command):
    """ Test command line execution.

    """
    # Call with the --help option as a basic sanity check.
    cmdl = f"{executable} -m obsimager.cli {command} --help"
    assert 0 == call(cmdl.split())
    return


# Make the script executable.

if __name__ == "__main__":
    raise SystemExit(pytest.main([__file__]))
07070100000060000041ed000000000000000000000001684059c400000000000000000000000000000000000000000000001c00000000product-composer/tests/unit07070100000061000041ed000000000000000000000001684059c400000000000000000000000000000000000000000000001700000000product-composer/tests07070100000062000041ed000000000000000000000001684059c400000000000000000000000000000000000000000000001100000000product-composer07070100000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000b00000000TRAILER!!!
openSUSE Build Service is sponsored by