Compare commits

...

2679 Commits

Author SHA1 Message Date
5152dfa764
- Add x86_64_v2 to a lisf of exclusive arches if there is any arch with base x86_64
- Changelog
- Bumbed version
2024-09-27 15:43:27 +03:00
b61614969d - Add x86_64_v2 to arch list if x86_64 in list 2024-09-16 14:59:03 +03:00
38cc2f79a0
- Unittests are fixed 2024-09-08 12:01:32 +03:00
d8b7f9210e
- Typo 2024-09-08 11:47:45 +03:00
69ec4df8f0
- Release is fixed 2024-09-06 22:30:35 +03:00
20841cfd4c
- Changelog
- Release is bumped
2024-09-06 22:29:55 +03:00
cb53de3c46
- Truncate a volume ID to 32 bytes
- Add new architecture `x86_64_v2`
2024-09-06 22:28:38 +03:00
72635cf5c1
- Release is bumped 2024-09-06 15:06:55 +03:00
9ce519426d
- Typo 2024-09-06 15:06:35 +03:00
208c71c194
- Typo 2024-09-05 17:36:42 +03:00
71c4e3c178
- Use xorriso as recommended package and genisoimage as required for RHEL8/9 and vice versa for RHEL10 2024-09-05 17:28:11 +03:00
1308986569
- New release of AL version of Pungi 2024-08-30 13:42:27 +03:00
Lubomír Sedlář
e05a11f99a
Release 4.7.0
JIRA: RHELCMP-13991
Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>

(cherry picked from commit a8dbd77f7f)
2024-08-30 13:40:54 +03:00
Lubomír Sedlář
cb9dede604
kiwibuild: Add support for type, type attr and bundle format
This is a very basic support. Whatever users specify in the new option
will be passed to the koji task.

Related: https://bugzilla.redhat.com/show_bug.cgi?id=2270197
Related: https://pagure.io/koji/pull-request/4157
Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
(cherry picked from commit e43cf68f08)
2024-08-30 13:40:50 +03:00
Lubomír Sedlář
ce2c222dc2
createiso: Block reuse if unsigned packages are allowed
We can have a compose with unsigned packages.

By the time the next compose is generated, the packages could have been
signed. However, the new compose would still reuse the ISO with unsigned
copies.

Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
(cherry picked from commit d546a49299)
2024-08-30 13:40:49 +03:00
Lubomír Sedlář
be4fd75a7a
Allow live_images phase to still be skipped
Without this fix existing configurations break even though they don't
use the phase.

Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
(cherry picked from commit c59f2371a3)
2024-08-30 13:40:48 +03:00
Lubomír Sedlář
33bb0ceceb
createiso: Recompute .treeinfo checksums for images
Running xorriso to modify an ISO image can update content of included
images such as images/eltorito.img, unless we explicitly update the
image, which is undesirable (https://pagure.io/pungi/issue/1647).

However, when the file is changed, the checksum changes and .treeinfo no
longer matches.

This patch implements a workaround: once the DVD is written, it looks
for incorrect checksums, recalculates them and updates the .treeinfo on
the DVD. Since only the checksum is changing and the size of the file
remains the same, this seems to help fix the issue.

An additional step for implanting MD5 is needed again, as that gets
erased by the workaround.

JIRA: RHELCMP-13664
Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>

(cherry picked from commit 3b2c6ae72a)
2024-08-30 13:40:47 +03:00
Lubomír Sedlář
aef48c0ab4
Drop support for signing rpm-wrapped artifacts
This was only usable in live_images phase that doesn't exist anymore,
and wasn't used much in the first place.

Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
(cherry picked from commit 0726a4dca7)
2024-08-30 13:40:15 +03:00
Adam Williamson
bd91ef1d10
Remove live_images.py (LiveImagesPhase)
This phase was used to create live images with livecd-creator
and 32-bit ARM images with appliance-creator. We also remove
get_create_image_cmd from the Koji wrapper as it was only used
for this phase, remove associated tests, and remove related
configuration settings and documentation.

Fixes: https://pagure.io/pungi/issue/1753
Merges: https://pagure.io/pungi/pull-request/1774
Signed-off-by: Adam Williamson <awilliam@redhat.com>

(cherry picked from commit 531f0ef389)
2024-08-30 13:40:14 +03:00
Lubomír Sedlář
32d5d32a6e
Clean up requirements
* dict.sorted and funcsigs are not used anywhere anymore
* urlgrabber is used only in the yum based gather.py module, and thus
  only needed on Python 2
* py3 doesn't need to reinstall mock as that is part of stdlib now

Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
(cherry picked from commit c96b5358ba)
2024-08-30 13:40:02 +03:00
Haibo Lin
5bcb3f5ac1
Release 4.6.3
JIRA: RHELCMP-13724

Signed-off-by: Haibo Lin <hlin@redhat.com>

(cherry picked from commit 0cb18bfa24)
2024-08-30 13:39:59 +03:00
Lubomír Sedlář
78bfbef206
Fix formatting of long line
Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
(cherry picked from commit f72adc03b1)
2024-08-30 13:39:51 +03:00
Lubomír Sedlář
88b6d8ebf5
unified-isos: Resolve symlinks
If the compose is configured to use symlinks for packages, the unified
ISO would include the symlinks which is useless.

Instead, let's check and replace any symlinks pointing outside of the
compose with the actual file.

JIRA: RHELCMP-13802
Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
(cherry picked from commit 8ced384540)
2024-08-30 13:39:50 +03:00
Lubomír Sedlář
6223baa2ba
gather: Skip lookaside packages from local lookaside repo
When variant X depends on variant A, Pungi creates a temporary local
lookaside with packages from A. If there's an external lookaside
configured, the list of package for variant A can contain URLs to the
external repo.

Newer versions of createrepo fail when pkglist specifies an unreachable
package, and it doesn't do downloading.

JIRA: RHELCMP-13648
Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
(cherry picked from commit 4a5106375e)
2024-08-30 13:39:49 +03:00
Haibo Lin
9d6226b436
pkgset: Avoid adding modules to unavailable arches
If a module is not built for specific arches, pungi will skip adding it
to these arches in pkgset phase.

JIRA: RHELCMP-13625
Signed-off-by: Haibo Lin <hlin@redhat.com>
(cherry picked from commit 627b72597e)
2024-08-30 13:39:48 +03:00
Lubomír Sedlář
927a0d35ab
iso: Extract volume id with xorriso if available
Pungi can use either genisoimage or xorriso to create ISOs.

It also needed isoinfo utility for querying volume ID from the ISO
image. However, the utility is part of the genisoimage suite of tools.

On systems that no longer provide genisoimage, the image would be
successfully generate with xorriso, but then pungi would fail to extract
the volume id leading to metadata with missing values.

Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
(cherry picked from commit bc0334cc09)
2024-08-30 13:39:47 +03:00
Adam Williamson
d81ee0f553
De-duplicate log messages for ostree and ostree_container phases
The ostree and ostree_container phases both log messages in the
exact same form, which is rather confusing. This will make it
much clearer which message comes from which phase.

Signed-off-by: Adam Williamson <awilliam@redhat.com>
(cherry picked from commit 5c9e79f535)
2024-08-30 13:39:46 +03:00
Lubomír Sedlář
e601345a38
Handle tracebacks as str or bytes
Kobo 0.36.0 changed how tracebacks are handled. Instead of `bytes`, it
returns a `str`. That makes pungi fail to write it into a file opened as
binary.

Relates: https://github.com/release-engineering/kobo/pull/246
Fixes: https://pagure.io/pungi/issue/1756
Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
(cherry picked from commit 29c166ab99)
2024-08-30 13:39:45 +03:00
Adam Williamson
1fe075e7e4
ostree/container: add missing --version arg
https://pagure.io/pungi/pull-request/1726 tries to use
`self.args.version`, but the `pungi-make-ostree container`
subcommand does not actually have a `--version` arg, so that is
not going to work. This adds the required arg.

We *could* make it optional by still setting an empty update
dict if it's not specified, I guess, but not sure if that's worth
the effort.

Fixes: https://pagure.io/pungi/issue/1751

Signed-off-by: Adam Williamson <awilliam@redhat.com>
(cherry picked from commit 51d58322f2)
2024-08-30 13:39:44 +03:00
Lubomír Sedlář
a8fc1b183b
Block pkgset reuse on module defaults change
JIRA: RHELCMP-13463
Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
(cherry picked from commit 0ef1c102b8)
2024-08-30 13:39:43 +03:00
Adam Williamson
8f171b81a1
Include task ID in DONE message for OSBS phase
Again, composetracker expects the message in this format.

Signed-off-by: Adam Williamson <awilliam@redhat.com>
(cherry picked from commit b6cfd8c5d4)
2024-08-30 13:39:41 +03:00
Adam Williamson
ee8a56e64d
Various phases: consistent format of failure message
composetracker expects the failure message to be in a specific
form, but some phases weren't using it. They were phrasing it
slightly differently, which throws off composetracker's parsing.
We could extend composetracker to handle both forms, but it seems
simpler to just make all the phases use a consistent form.

Signed-off-by: Adam Williamson <awilliam@redhat.com>
(cherry picked from commit 9f8377abab)
2024-08-30 13:39:40 +03:00
Lubomír Sedlář
2bf6c216bc
Update tests to exercise kiwi specific metadata
Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
(cherry picked from commit 949add0dac)
2024-08-30 13:39:39 +03:00
Adam Williamson
99a6dfe8ad
Kiwi: translate virtualbox and azure productmd formats
As discussed in
https://pagure.io/releng/failed-composes/issue/6047#comment-899622
the list of 'acceptable' types and formats (in productmd terms)
is locked down in productmd, we cannot just 'declare' new formats
in pungi as we kinda wound up doing by adding these Kiwi
extensions to the EXTENSIONS dict in image_build phase. So
instead, let's return the image_build phase to the way it was,
and add an additional layer of handling in kiwibuild phase for
these awkward cases, which 'translates' the file suffix to a
format productmd knows about already. This is actually how we
would rather behave anyway, because a Kiwi-produced
`vagrant.libvirt.box` file really is the same kind of thing as an
ImageFactory-produced `vagrant-libvirt.box` file; we want them to
have compatible metadata, we don't want them to look like
different things.

Merges: https://pagure.io/pungi/pull-request/1740
Signed-off-by: Adam Williamson <awilliam@redhat.com>
(cherry picked from commit 8fb694f000)
2024-08-30 13:39:37 +03:00
Lubomír Sedlář
c63f9f41b6
kiwibuild: Add tests for the basic functionality
Merges: https://pagure.io/pungi/pull-request/1739
Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
(cherry picked from commit 8a3b64e5b8)
2024-08-30 13:39:36 +03:00
Lubomír Sedlář
ab1960de6d
kiwibuild: Remove repos as dicts
The task needs just URLs, the dics don't bring anything here.

Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
(cherry picked from commit c80ebb029b)
2024-08-30 13:39:35 +03:00
Lubomír Sedlář
c17b820490
Fix additional image metadata
Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
(cherry picked from commit e2ceb48450)
2024-08-30 13:39:33 +03:00
Lubomír Sedlář
36133b71da
Drop kiwibuild_version option
Version in kiwibuild is embedded in the definition file. The option
makes no sense.

Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
(cherry picked from commit 242d7d951f)
2024-08-30 13:39:32 +03:00
Lubomír Sedlář
50b217145c
Update docs with kiwibuild options
Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
(cherry picked from commit 04d4e1d585)
2024-08-30 13:39:31 +03:00
Adam Williamson
57f2b428d5
kiwibuild: allow setting description scm and path at phase level
Neal wanted this to work - he tried using global_description_scm
and global_description_path in the initial PR - but it wasn't
wired up to work. This should make it possible to set
`kiwibuild_description_scm` and `kiwibuild_description_path`.
It also technically lets you set `global_` for both, since the
`get_config` implementation is very generic, but it doesn't add
it to the checks, so you'd still get an "unrecognized config
option" warning, I think. It seems appropriate to encourage
setting this as a phase-level option rather than a global one
since it seems quite specific to the kiwibuild phase.

Merges: https://pagure.io/pungi/pull-request/1737
Signed-off-by: Adam Williamson <awilliam@redhat.com>
(cherry picked from commit e90ffdfd93)
2024-08-30 13:39:29 +03:00
Lubomír Sedlář
3cdc8d0ba7
Use latest Fedora for python 3 test environment
Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
(cherry picked from commit 0d310fb3b3)
2024-08-30 13:39:28 +03:00
Lubomír Sedlář
07829f2229
Install unittest2 only on python 2
Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
(cherry picked from commit 5172d7e5eb)
2024-08-30 13:39:26 +03:00
Adam Williamson
bdf06ea038
Fix 'failable' handling for kiwibuild phase
The mechanisms here are a bit subtle and the kiwibuild phase
didn't quite get them right. The arg passed to `util.failable`
is supposed to be a boolean, but kiwibuild was passing it the
list of failable arches (which will always evaluate True).

How this is meant to work is that we only make *the Koji task
as a whole* failable (by passing `True` to `util.failable`) if
*all* the arches in it are failable. If *any* arch in the task
is not failable, the task should not be failable.

We allow a subset of arches to fail by passing the Koji task a
list of `optional_arches`, later. If an arch is 'optional', that
arch failing won't cause the Koji task itself to be considered
failed.

This commit fixes the logic (I hope), renames all the variables
and adds a couple of comments to make it clearer what's going on,
and does a bit of making the code simpler.

Signed-off-by: Adam Williamson <awilliam@redhat.com>
(cherry picked from commit 0d306d4964)
2024-08-30 13:39:25 +03:00
Jeremy Cline
bcab3431e1
image_build: Accept Kiwi extension for Azure VHD images
Kiwi builds for Azure fixed VHD images are suffixed with "vhdfixed"
instead of plain "vhd". Add that to the list of suffixes.

Signed-off-by: Jeremy Cline <jeremycline@microsoft.com>
(cherry picked from commit 1494f203ce)
2024-08-30 13:39:24 +03:00
Adam Williamson
b181b08033
image_build: accept Kiwi vagrant image name format
According to Neal, Vagrant images produced by Kiwi end in e.g.
`vagrant.libvirt.box` and `vagrant.virtualbox.box` - with a
period between `vagrant` and the image type, not a dash as with
oz. We should accept this slightly different format so we can
correctly derive the productmd `type` and `format` for these.

Signed-off-by: Adam Williamson <awilliam@redhat.com>
(cherry picked from commit 93b4b4ae0f)
2024-08-30 13:39:23 +03:00
Lubomír Sedlář
e05b1bcd78
Release 4.6.2
Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>

(cherry picked from commit b8e26bfb64)
2024-08-30 13:39:22 +03:00
Tomáš Hozza
a97488721d
Phases/osbuild: support passing 'customizations' for image builds
The osbuild Koji plugin supports passing customizations for an image
build. This is also supported in the Koji CLI plugin. Some teams want to
pass image customizations for images built as part of Pungi composes.
Extend the osbuild phase to support passing customizations in the Pungi
configuration.

Merges: https://pagure.io/pungi/pull-request/1733
Signed-off-by: Tomáš Hozza <thozza@redhat.com>
(cherry picked from commit e738f65458)
2024-08-30 13:39:16 +03:00
Lubomír Sedlář
4d858ef958
dnf: Load filelists for actual solver too
Not just in tests.

Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
(cherry picked from commit 209d308e1c)
2024-08-30 13:39:14 +03:00
Lubomír Sedlář
744b00499d
kiwibuild: Tell Koji which arches are allowed to fail
Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
(cherry picked from commit be410d9fd5)
2024-08-30 13:39:13 +03:00
Lubomír Sedlář
583547c6ee
kiwibuild: Update documentation with more details
Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
(cherry picked from commit 1f819ee08a)
2024-08-30 13:39:11 +03:00
Lubomír Sedlář
f28053eecc
kiwibuild: Add kiwibuild global options
This is already supported by code, just missing in the schema.

Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
(cherry picked from commit b9d94970b5)
2024-08-30 13:39:10 +03:00
Lubomír Sedlář
a196e9c895
kiwibuild: Process images same as image-build
Getting the images from task is less hacky then matching on filenames.

Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
(cherry picked from commit b032425f30)
2024-08-30 13:39:08 +03:00
Lubomír Sedlář
a6f6199910
kiwibuild: Add subvariant configuration
Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
(cherry picked from commit bcd937d16d)
2024-08-30 13:39:07 +03:00
Lubomír Sedlář
a3dcec5059
kiwibuild: Work around missing arch in build data
Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
(cherry picked from commit f0137fd9b9)
2024-08-30 13:39:05 +03:00
Haibo Lin
6aa674fbb3
Support KiwiBuild
Adding kiwibuild phase which is similar to osbuild.

Fixes: https://pagure.io/pungi/issue/1710
Merges: https://pagure.io/pungi/pull-request/1720
JIRA: RHELCMP-13348
Signed-off-by: Haibo Lin <hlin@redhat.com>
(cherry picked from commit 3d630d3e8e)
2024-08-30 13:39:04 +03:00
Timothée Ravier
05d9651eba
ostree/container: Set version in treefile 'automatic-version-prefix'
In the non container path, we're setting the version for the build using
the `--add-metadata-string=version=XYZ` argument passed to `rpm-ostree
compose tree ...`.

The `rpm-ostree compose image` path does not expose this option yet so
modify the treefile directly as we are already doing it to set the
repos used for the compose.

See: https://github.com/coreos/rpm-ostree/issues/4829
See: https://pagure.io/workstation-ostree-config/pull-request/472
Merges: https://pagure.io/pungi/pull-request/1726
Signed-off-by: Timothée Ravier <tim@siosm.fr>
(cherry picked from commit 8412890640)
2024-08-30 13:39:02 +03:00
Lubomír Sedlář
75ab6a14b2
dnf: Explicitly load filelists
Fixes: https://bugzilla.redhat.com/show_bug.cgi?id=2264414
Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
(cherry picked from commit 42befba0b1)
2024-08-30 13:39:01 +03:00
Lubomír Sedlář
533ea641d8
Fix buildinstall reuse with pungi_buildinstall plugin
The keys may not exist anymore. If there's nothing to delete, it's fine.

JIRA: RHELCMP-13464
Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
(cherry picked from commit 52c2cea0ef)
2024-08-30 13:38:59 +03:00
Lubomír Sedlář
185a53d56b
Fix filters for DNF query
Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
(cherry picked from commit d2e9ccefde)
2024-08-30 13:38:58 +03:00
Lubomír Sedlář
305deab9ed
gather-dnf: Support dotarch in filter_packages
Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
(cherry picked from commit 2c61416423)
2024-08-30 13:38:57 +03:00
Lubomír Sedlář
6af11d5747
gather: Support dotarch notation for debuginfo packages
Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
(cherry picked from commit 986099f8b5)
2024-08-30 13:38:56 +03:00
Lubomír Sedlář
58f96531c7
Correctly set input and fultree_exclude flags for debuginfo
This only matters for composes that use the functionality for trimming
addon packages from parent variants.

Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
(cherry picked from commit 947ddf0a1a)
2024-08-30 13:38:55 +03:00
Lubomír Sedlář
e570aa7726
4.6.1 release
Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>

(cherry picked from commit e46393263e)
2024-08-30 13:38:53 +03:00
Lubomír Sedlář
d8a553163f
Make python3-mock dependency optional
https://fedoraproject.org/wiki/Changes/RemovePythonMockUsage

Prefer using unittest.mock to a standalone package. The separate
packages should only really be needed on Python 2.7 these days.

The test requirements file is updated to only require mock on old
Python, and the dependency is removed from setup.py to avoid issues
there.

Relates: https://src.fedoraproject.org/rpms/pungi/pull-request/9

Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>

(cherry picked from commit ff5a7e6377)
2024-08-30 13:38:43 +03:00
Lubomír Sedlář
a9839d8078
Make latest black happy
Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
(cherry picked from commit dd7ecbd5fd)
2024-08-30 13:31:29 +03:00
Lubomír Sedlář
dc05d1fbba
Update tox configuration
The whitelist_externals option has been renamed to allowlist_externals.

Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
(cherry picked from commit ba613563f6)
2024-08-30 13:31:28 +03:00
Lubomír Sedlář
dc4e8b2fb7
Fix scm tests to not use user configuration
If you configure default branch name in new repos to anything else than
master, there will be failures in tests. The test expects the branch to
be called master, but does not ensure it in any way.

Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
(cherry picked from commit c8d16e6978)
2024-08-30 13:31:26 +03:00
Lubomír Sedlář
27d055992e
Add workaround for old requests in kojiwrapper
When running with requests<2.18 (i.e. on RHEL 7), streaming responses
are not a context manager and need to be wrapped in contextlib.closing.

Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
(cherry picked from commit 860360629d)
2024-08-30 13:31:25 +03:00
Lubomír Sedlář
34fcd550b6
Use pungi_buildinstall without NFS
The plugin supports two modes of operation:
1. Mount a shared storage volume into the runroot and have the output
   written there.
2. Have the plugin create a tar.gz with the outputs and upload them to
   the hub, from where they can be downloaded.

This patch switches from option 1 to option 2.

This requires all input repositories to be passes in as URLs and not
paths. Once the task finishes, Pungi will download the output archives
and unpack them into the expected locations.

JIRA: RHELCMP-13284
Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
(cherry picked from commit f25489d060)
2024-08-30 13:31:24 +03:00
Adam Williamson
4c0059e91b
checks: don't require "repo" in the "ostree" schema
Per @siosm in https://pagure.io/pungi-fedora/pull-request/1227
this option "is deprecated and not needed anymore", so Pungi
should not be requiring it.

Merges: https://pagure.io/pungi/pull-request/1714
Signed-off-by: Adam Williamson <awilliam@redhat.com>
(cherry picked from commit 432b0bce04)
2024-08-30 13:31:23 +03:00
Lubomír Sedlář
bb2e32132e
ostree_container: Use unique temporary directory
The config repository is cloned into a path that conflicts with the
regular ostree phase. Let's use a unique name to avoid that problem.

Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
(cherry picked from commit 7e779aa90f)
2024-08-30 13:31:22 +03:00
Lubomír Sedlář
dca3be5861
4.6.0 release
Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>

(cherry picked from commit f4bf0739aa)
2024-08-30 13:31:20 +03:00
Lubomír Sedlář
38ec4ca159
Add ostree container to image metadata
This requires https://github.com/release-engineering/productmd/pull/172

Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
(cherry picked from commit 119b212241)
2024-08-30 13:30:44 +03:00
Lubomír Sedlář
c589ccb56f
Updates for ostree-container phase
This patch connects the phase into the main script, and adds other
modifications:

* The archive is now stored in the images/ subdirectory in the compose.
* Documentation is updated to correctly mention that variant repos are
  not available.
* Configuration for path and name of the final archive is dropped. There
  are reasonable defaults for this and there's no point in having users
  configure it.
* The extra message for the archive is no longer sent.
* The pungi-make-ostree utility is no longer required in the buildroot.

The pungi-make-ostree utility doesn't do any significant work. It
modifies configuration files (which can happen on the compose host), and
it starts other processes.

This patch changes the ostree-container phase to no longer need the
script in the buildroot. Instead, the utility is called on the compose
host to do the config manipulation and output the needed commands. Those
are then passed into the runroot task.

Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
(cherry picked from commit 081c31238b)
2024-08-30 13:30:42 +03:00
Timothée Ravier
e413955849
Add ostree native container support
Add a new `ostree_container` stage to create ostree native container
images as OCI archives, using rpm-ostree compose image.

See: https://fedoraproject.org/wiki/Changes/OstreeNativeContainerStable
See: https://gitlab.com/CentOS/cloud/issue-tracker/-/issues/1

Fixes: https://pagure.io/pungi/issue/1698
Merges: https://pagure.io/pungi/pull-request/1699

Signed-off-by: Timothée Ravier <tim@siosm.fr>
(cherry picked from commit 95497d2676)
2024-08-30 13:30:41 +03:00
Adam Williamson
e70e1841c7
Improve autodetection of productmd image type for osbuild images
I don't love inferring the type from the filename like this -
it's kinda backwards - but it's an improvement on the current
logic (I don't think 'dvd' is ever currently the correct value
here, I don't think osbuild *can* currently build the type of
image that 'dvd' is meant to indicate). I can't immediately see
any better source of data here (we could use the 'name' or
'package_name' from 'build_info', but those are pretty much
just inputs to the filenames anyway).

Types that are possible in productmd but not covered here are
'cd' (never likely to be used again in Fedora at least, not sure
about RHEL), 'dvd-debuginfo' (again not used in Fedora, may be
used in RHEL), 'ec2', 'kvm' (not sure about those), 'netinst'
(this is a synonym for 'boot', we use 'boot' in practice in
Fedora metadata), 'p2v' and 'rescue' (not sure).

Signed-off-by: Adam Williamson <awilliam@redhat.com>
(cherry picked from commit aa7fcc1c20)
2024-08-30 13:30:40 +03:00
Lubomír Sedlář
fc86e03e44
pkgset: ignore events for modular content tags
Generally we want all packages to come from particular event.

There are two exceptions: packages configured via `pkgset_koji_builds`
are pulled in by exact NVR and skip event; and modules in
`pkgset_koji_modules` are pulled in by NSVC and also ignore events.

However, the modular content tag did honor event, and could lead to a
crashed compose if the content tag did not exist at the configured
event.

This patch is a slightly too big hammer. It ignores events for all
modules, not just ones configured by explicit NSVC. It's not a huge deal
as the content tags are created before the corresponding module build is
created, and once all rpm builds are tagged into the content tag, MBS
will never change it again.

JIRA: RHELCMP-12765
Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
(cherry picked from commit b32c8f3e5e)
2024-08-30 13:30:38 +03:00
Lubomír Sedlář
548441644b
pkgset: Ignore duplicated module builds
If the module tag contains the same module build multiple times (because
it's in multiple tags in the inheritance), Pungi will not process that
correctly and try to include the same NSVC in the compose multiple
times. That leads to a crash.

This patch adds another step to the inheritance filter to ensure the
result contains each module only once.

JIRA: RHELCMP-12768
Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
(cherry picked from commit 935da7c246)
2024-08-30 13:30:36 +03:00
Aditya Bisoi
ca369df0df
Drop buildinstall method
JIRA: RHELCMP-12388

Signed-off-by: Aditya Bisoi <abisoi@redhat.com>
(cherry picked from commit b513c8cd00)
2024-08-30 13:30:35 +03:00
Lingyan Zhuang
67ae4202c4
Add step to send UMB message
If reuse old ISO finished, send out UMB message.

Signed-off-by: Lingyan Zhuang <lzhuang@redhat.com>
(cherry picked from commit 8cf1d98312)
2024-08-30 13:30:33 +03:00
Timothée Ravier
aba5a7a093
Fix minor Ruff/flake8 warnings
```
pungi/checks.py:575:17: F601 [*] Dictionary key literal `"type"` repeated
pungi/phases/pkgset/pkgsets.py:617:12: E721 Do not compare types, use `isinstance()`
tests/test_pkgset_source_koji.py:241:16: E721 Do not compare types, use `isinstance()`
tests/test_pkgset_source_koji.py:244:16: E721 Do not compare types, use `isinstance()`
tests/test_pkgset_source_koji.py:370:16: E721 Do not compare types, use `isinstance()`
tests/test_pkgset_source_koji.py:374:20: E721 Do not compare types, use `isinstance()`
```

Signed-off-by: Timothée Ravier <tim@siosm.fr>
(cherry picked from commit 2534ddee99)
2024-08-30 13:30:32 +03:00
Simon de Vlieger
323d1c1eb6
osbuild: manifest type in config
Allow the manifest type used to be specified in the pungi configuration
instead of always selecting the manifest type based on the koji output.

Signed-off-by: Simon de Vlieger <cmdr@supakeen.com>
(cherry picked from commit f30a8b4d15)
2024-08-30 13:30:31 +03:00
Lubomír Sedlář
b0964ff555
4.5.1 release
Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>

(cherry picked from commit 3ffb991bac)
2024-08-30 13:30:30 +03:00
Ozan Unsal
79bc4e0c3a
gather_dnf.py: Do not raise error when the downloaded package is exists.
If the packages are pulled from different repos and a package is already
exists in target directory, pungi raises File exists error and breaks. This
behavior can be suspended and skipped if the package is already available.

Merges: https://pagure.io/pungi/pull-request/1696
Signed-off-by: Ozan Unsal <ounsal@redhat.com>
(cherry picked from commit dbc0e531b2)
2024-08-30 13:30:05 +03:00
Lubomír Sedlář
8772ccca23
New upstream release 4.7.0
(cherry picked from commit e0600a2abac9e0e9b8a3b15b51eb44e3cd467bd3)
2024-08-30 13:29:32 +03:00
Fedora Release Engineering
3bb34225a9
Rebuilt for https://fedoraproject.org/wiki/Fedora_41_Mass_Rebuild
(cherry picked from commit 192a8ef731fbc134bf5337dfb3d60ba6c5ad7bd5)
2024-08-30 13:29:32 +03:00
Haibo Lin
daea6cabdf
Upstream release 4.6.3
(cherry picked from commit 9a24cfff1bfccbafde32a4a34805d9d0aeff5650)
2024-08-30 13:29:30 +03:00
Python Maint
35b720e87a
Rebuilt for Python 3.13
(cherry picked from commit 639bb6214433a96a6275817baf893ab4850a3309)
2024-08-30 13:29:29 +03:00
Lubomír Sedlář
5a6ee9f8eb
Bump release over f40-infra build
(cherry picked from commit 1ad8b6fa2edeb91316dd1d1e33a9c234800e28d9)
2024-08-30 13:29:28 +03:00
Lubomír Sedlář
9a64db0485
Require xorriso for bug#2278677
(cherry picked from commit 22214e03b888c9b5f85919815f2825ad176c5370)
2024-08-30 13:29:27 +03:00
Lubomír Sedlář
de7210f69a
Upstream release 4.6.2
(cherry picked from commit f24f577c89647dc80a84bfa76f3055d24ced55a5)
2024-08-30 13:29:05 +03:00
Lubomír Sedlář
24418ef74d
New upstream release 4.6.1
(cherry picked from commit 98b4f26e0972a2bea2d46f2c74c1db94ed087477)
2024-08-30 13:29:03 +03:00
f4765fbe3a
Remove python3-mock dependency
Merges: https://src.fedoraproject.org/rpms/pungi/pull-request/9

(cherry picked from commit 67a11d878b04bd46a0d9fb98036467bca6ffed92)
2024-08-30 13:28:01 +03:00
Fedora Release Engineering
80b9add9f7
Rebuilt for https://fedoraproject.org/wiki/Fedora_40_Mass_Rebuild
(cherry picked from commit 40fd963a495689a2a3a0279760f5a4024e7e5857)
2024-08-30 13:27:24 +03:00
Fedora Release Engineering
b241545ca6
Rebuilt for https://fedoraproject.org/wiki/Fedora_40_Mass_Rebuild
(cherry picked from commit 5cfb290545fdd5b18bb1691218e5e8e732e351e4)
2024-08-30 13:27:00 +03:00
Lubomír Sedlář
2e536228ae
Backport: Stop requiring repo option in ostree phase
(cherry picked from commit 6778cae05afb2b5784a46ed72ee2703785756dde)
2024-08-30 13:26:39 +03:00
Lubomír Sedlář
ff7950b9d1
ostree_container: Use unique temporary directory
(cherry picked from commit 58ca2a86231e53cc329e3e20294853230fabf587)
2024-08-30 13:26:38 +03:00
Lubomír Sedlář
6971624f83
New upstream release 4.6.0
(cherry picked from commit 2b47d8ea021a7b6e694c52fd8d74880f9a6b79a5)
2024-08-30 13:26:11 +03:00
Lubomír Sedlář
b7d371d1c3
Backport patch for explicit setting of osbuild image type
(cherry picked from commit c0bf9a2a78)
2024-08-30 13:25:21 +03:00
bc8c776872
- Method get_remote_file_content is object's method now 2024-05-04 10:43:19 +03:00
91d282708e
- Method get_remote_file_content is object's method now 2023-11-21 09:19:01 +02:00
ccaf31bc87
- Method get_remote_file_content is object's method now 2023-11-21 08:51:05 +02:00
5fe0504265
- Spec's changelog chronology is fixed 2023-11-15 15:14:22 +02:00
d79f163685
- Bump version 2023-11-15 14:49:51 +02:00
793fb23958
- Bump version 2023-11-15 14:02:10 +02:00
65d0c09e97
- Return empty list if a repo doesn't contain any module 2023-11-15 13:17:57 +02:00
0a9e5df66c
- Properly removing tmp files 2023-11-10 21:38:01 +02:00
ae527a2e01
- The unittests are fixed 2023-11-10 18:08:03 +02:00
Aditya Bisoi
4991144a01
4.5.0 release
Signed-off-by: Aditya Bisoi <abisoi@redhat.com>

(cherry picked from commit 4c7611291d (centos_master))
2023-11-10 16:58:03 +02:00
Lubomír Sedlář
68d94ff488
kojiwrapper: Stop being smart about local access
Rather than trying to use local access when it's accessible, let user
make the decision:

 * if koji_cache is configured use it and download stuff
 * if not, fall back to local access

Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
(cherry picked from commit 0d3cd150bd)
2023-11-10 16:57:53 +02:00
Ozan Unsal
ce45fdc39a
Fix unittest errors
Signed-off-by: Ozan Unsal <ounsal@redhat.com>

(cherry picked from commit aa0aae3d3e (centos_master))
2023-11-10 16:57:51 +02:00
Lubomír Sedlář
b625ccea06
Add integrity checking for builds
When a real build is downloaded, Koji can provide a checksum via API.
This commit adds verification of that checksum.

A mismatch will abort the compose. If Koji doesn't provide a checksum
for the particular sigkey, no checking will happen.

Nothing is still checked for scratch builds and images.

This patch requires Koji 1.32. When talking to an older version, there
is no checking done.

Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
(cherry picked from commit 77f8fa25ad)
2023-11-10 16:55:44 +02:00
Lubomír Sedlář
8eccfc5a03
Add script for cleaning up the cache
Pungi would by default only ever add files to the cache. That would
eventually result in essentially a mirror of the Koji volume.

This patch adds a helper cleanup script. When called, it goes through
files in the cache and deletes anything that is not hardlinked from
elsewhere and with mtime not updated recently.

Cleaning up files that hardlinked from some compose would not save any
space anyway. The mtime check should account for cases like subpackage
being downloaded but not included in any compose. This would avoid it
from being downloaded over and over again.

When a compose fails or is aborted, there can be a stale lock file left
behind in the cache. This script cleans that up too.

Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>

(cherry picked from commit e6d9f31ef4 (centos_master))
2023-11-10 16:55:43 +02:00
Lubomír Sedlář
f5a0e06af5
Add ability to download images
This patch extends the ability to download files from Koji to image
building phases too.

There is no integrity checking for the downloaded images.

Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
(cherry picked from commit bf3e9bc53a)
2023-11-10 16:55:20 +02:00
Lubomír Sedlář
f6f54b56ca
Add support for not having koji volume mounted locally
With this patch, Pungi can be configured with a local directory to be
used as a cache for RPMs, and it will download packages from Koji over
HTTP instead of reading them from filesystem directly.

The files from the cache can then be hardlink as usual.

There is locking in place to avoid different composes running at the
same time to step on each other.

This is now supported for RPMs only, be it real builds or scratch
builds.

Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
(cherry picked from commit 631bb01d8f)
2023-11-10 16:55:19 +02:00
Aditya Bisoi
fcee346c7c
Remove repository cloning multiple times
JIRA: RHELCMP-8913
Signed-off-by: Aditya Bisoi <abisoi@redhat.com>
(cherry picked from commit b6296bdfcd)
2023-11-10 16:55:18 +02:00
Lubomír Sedlář
82ec38ad60
Support require_all_comps_packages on DNF backend
It's not a great name anymore though, because it will fail the compose
if any input package is missing, no matter whether it's from comps,
prepopulate or additional_packages.

JIRA: RHELCMP-12484
Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
(cherry picked from commit 1c4275bbfa)
2023-11-10 16:55:17 +02:00
Lubomír Sedlář
c9cbd80569
Fix new warnings from flake8
Use isinstance rather than directly comparing types.

Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
(cherry picked from commit fe2dad3b3c)
2023-11-10 16:55:16 +02:00
Aditya Bisoi
035fca1e6d
4.4.1 release
Signed-off-by: Aditya Bisoi <abisoi@redhat.com>

(cherry picked from commit 7128021654 (centos_master))
2023-11-10 16:55:15 +02:00
Lubomír Sedlář
0f8cae69b7
ostree: Add configuration for custom runroot packages
Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
(cherry picked from commit bd64894a03)
2023-11-10 16:55:01 +02:00
Lubomír Sedlář
f17628dd5f
pkgset: Emit better error for missing modulemd file
The exceptions from libmodulemd are not particularly helpful as they do
not contain information about what file caused it.

   modulemd-yaml-error-quark: Failed to open file: Permission denied (0)

This patch should add the path to the problematic file into the message.

Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
(cherry picked from commit 14e025a5a1)
2023-11-10 16:55:00 +02:00
Lubomír Sedlář
f3485410ad
Add support for git-credential-helper
This patch adds an additional field `options` to scm_dict, which can be
used to provide additional information to the backends.

It implements a single new option for GitWrapper. This option allows
setting a custom git credentials wrapper. This can be useful if Pungi
needs to get files from a git repository that requires authentication.

The helper can be as simple as this (assuming the username is already
provided in the url):

    #!/bin/sh
    echo password=i-am-secret

The helper would need to be referenced by an absolute path from the
pungi configuration, or prefixed with ! to have git interpret it as a
shell script and look it up in PATH.

See https://git-scm.com/docs/gitcredentials for more details.

Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
JIRA: RHELCMP-11808
(cherry picked from commit ada8f4e346)
2023-11-10 16:54:59 +02:00
Haibo Lin
cccfaea14e
Support OIDC Client Credentials authentication to CTS
JIRA: RHELCMP-11324
Signed-off-by: Haibo Lin <hlin@redhat.com>
(cherry picked from commit e4c525ecbf)
2023-11-10 16:54:58 +02:00
Lubomír Sedlář
e2057b75c5
4.4.0 release
JIRA: RHELCMP-11764
Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>

(cherry picked from commit 091d228219 (centos_stream))
2023-11-10 16:54:57 +02:00
Lubomír Sedlář
44ea4d4419
gather-dnf: Run latest() later
The initial version of the filtered the latest builds at the start. That
doesn't matter in many cases:

* When there are no lookaside repos, there is generally a single version
  of each package.
* When lookaside repos do not overlap with compose repos, or contain
  only older versions.

It is however a problem when the lookaside repos contain higher version
of a package than what is in a compose repo, and some package explicitly
requires the older version.

Consider this scenario:

* lookaside contains bar-1.1
* compose repo contains bar-1.0 and foo-1.0
* foo-1.0 `Requires: bar < 1.1`

The original code would filter out the bar-1.0 package, and then fail on
unresolved dependencies.

This patch moves the computation of latest packages much later, to part
of code where all options to satisfy a dependency are selected and the
best match is chosen. At that point if there are multiple versions
available, we do want the latest one.

JIRA: SPMM-13483
Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
(cherry picked from commit bcc440491e)
2023-11-10 16:54:43 +02:00
Lubomír Sedlář
d4425f7935
iso: Support joliet long names
Without this option the names reported by joliet tree are truncated.

Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
(cherry picked from commit fa50eedfad)
2023-11-10 16:54:42 +02:00
Lubomír Sedlář
c8118527ea
Drop pungi-orchestrator code
This was never actually used.

JIRA: RHELCMP-10218
Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>

(cherry picked from commit b7adbf8a91 (centos_master))
2023-11-10 16:54:40 +02:00
Lubomír Sedlář
a8ea322907
isos: Ensure proper file ownership and permissions
The genisoimage backend uses the -rational-rock option, which sets uid
and gid to 0, and makes file readable by everyone.

With xorriso this must be done explicitly. Setting ownership is a single
command, but the permissions require a per-file command to not make
files executable where not needed.

Fixes: https://bugzilla.redhat.com/show_bug.cgi?id=2203888
Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>

(cherry picked from commit 82ae9e86d5 (centos_master))
2023-11-10 16:54:22 +02:00
Lubomír Sedlář
c4995c8f4b
gather: Always get latest packages
If lookaside contains an older version of a package, but with a
different arch, the depsolver doesn't notice that and prefers the
lookaside version.

This is not correct. The latest package should be used no matter if
there are different arches available.

The filtering in DNF doesn't ensure this, so we have to build it
ourselves. To limit the performance impact, only run this filtering when
there actually are some lookaside repos configured.

JIRA: RHELCMP-11728

Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
(cherry picked from commit 2ad341a01c)
2023-11-10 16:54:01 +02:00
Lubomír Sedlář
997e372f25
Add back compatibility with jsonschema <3.0.0
Resolves: https://pagure.io/pungi/issue/1667
Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>

(cherry picked from commit e888e76992 (centos_master))
2023-11-10 16:54:00 +02:00
Lubomír Sedlář
42f1c62528
Remove useless debug message
Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
(cherry picked from commit 6e72de7efe)
2023-11-10 16:52:27 +02:00
Lubomír Sedlář
3fd29d0ee0
Remove fedmsg from requirements
The code for sending messages in Fedora actually relies on
fedora-messaging library now. However, we do not have any tests for
that, so there's little reason to pull the library in via
requirements.txt

Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
(cherry picked from commit c8263fcd39 (centos_master))
2023-11-10 16:52:04 +02:00
Lubomír Sedlář
c1f2fa5035
gather: Support dotarch in DNF backend
The documentation claims that dotarch syntax is supported for additional
packages. For yum backend this seems to be handled automatically, but
the dnf backend could not interpret this.

This patch checks if a package is specified in the syntax and contains a
valid architecture. If so, the query will honor the arch.

JIRA: RHELCMP-11728
Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
(cherry picked from commit 82ca4f4e65)
2023-11-10 16:51:55 +02:00
Aurélien Bompard
85c9e9e776
Set the priority in the fedora-messaging notifier
According to [infra ticket #10899](https://pagure.io/fedora-infrastructure/issue/10899),
ostree messages should have prioriy 3.

Signed-off-by: Aurélien Bompard <aurelien@bompard.org>
(cherry picked from commit b8b6b46ce7)
2023-11-10 16:51:54 +02:00
Lubomír Sedlář
33012ab31e
Fix compatibility with createrepo_c 0.21.1
The length of the file entry tuple has changed, it can not be unpacked
reliably.

Relates: https://github.com/rpm-software-management/createrepo_c/issues/360
Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
(cherry picked from commit e9d836c115)
2023-11-10 16:51:53 +02:00
Lubomír Sedlář
72ddf65e62
comps: Apply arch filtering to environment/optionlist
Let's filter this list too, not just the grouplist tag.

JIRA: RHELCMP-7926
Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
(cherry picked from commit d3f0701e01)
2023-11-10 16:51:52 +02:00
Haibo Lin
c402ff3d60
Add config file for cleaning up cache files
systemd-tmpfiles is required to enable the auto clean up.

JIRA: RHELCMP-6327
Signed-off-by: Haibo Lin <hlin@redhat.com>
(cherry picked from commit 8f6f0f463f)
2023-11-10 16:51:51 +02:00
Haibo Lin
8dd344f9ee
4.3.8 release
JIRA: RHELCMP-11448
Signed-off-by: Haibo Lin <hlin@redhat.com>

(cherry picked from commit 467c7a7f6a (centos_master))
2023-11-10 16:51:49 +02:00
Lubomír Sedlář
d07f517a90
createiso: Update possibly changed file on DVD
There's no good way of detecting if buildinstall phase tweaked boot
configuration (and efiboot.img). We should update those files in the DVD
just to be sure.

The .discinfo file is always different and needs to be updated.

Relates: https://pagure.io/pungi/issue/1647
JIRA: RHELCMP-10811
Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
(cherry picked from commit e1d7544c2b)
2023-11-10 16:51:39 +02:00
Lubomír Sedlář
48366177cc
pkgset: Stop reuse if configuration changed
When options controlling excluding arches change, it should break reuse.

Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
(cherry picked from commit a71c8e23be)
2023-11-10 16:51:38 +02:00
Lubomír Sedlář
4cb8671fe4
Allow disabling inheriting ExcludeArch to noarch packages
Copying ExcludeArch/ExclusiveArch from source rpm to noarch is an easy
option to block shipping that particular noarch package from a certain
architecture. However, there is no way to bypass it, and it is rather
confusing and not discoverable.

An alternative way to remove an unwanted package is to use the good old
`filter_packages`, which has enough granularity to remove pretty much
anything from anywhere. The only downside is that it requires a change
in configuration, so it can't be done by a packager directly from a spec
file.

When we decide to break backwards compatibility, this option should be
removed and the entire ExcludeArch/ExclusiveArch inheritance removed
completely.

JIRA: ENGCMP-2606
Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
(cherry picked from commit ab508c1511)
2023-11-10 16:51:37 +02:00
Lubomír Sedlář
135bbbfe7e
pkgset: Support extra builds with no tags
This is a rather fringe use case. If the configuration contains
pkgset_koji_builds or pkgset_koji_scratch_tasks but no pkgset_koji_tag,
the compose will be empty.

The expectation though is that the packages should be pulled.

The extra RPMs are added to all non-modular tags because they are
supposed to mask builds from the same packages (e.g. user may want to
explicitly pull in older version than tagged).

This patch adds support for composes containing only explicitly listed
builds by creating a dummy package set that is not actually using any
tag.

JIRA: RHELCMP-11385
Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
(cherry picked from commit f960b4d155)
2023-11-10 16:51:36 +02:00
Lubomír Sedlář
5624829564
buildinstall: Avoid pointlessly tweaking the boot images
Only modify boot images if there actually is some change.

The tweak function updates config files with volume id and kickstart
file. Even if we don't have a kickstart and there is no change in the
config files, the image will be regenerated. This leads to a change in
checksum for no good reason.

This patch keeps track of modified config files. If there are none, it
avoids touching anything else.

Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
(cherry picked from commit 602b698080)
2023-11-10 16:51:35 +02:00
Haibo Lin
5fb4f86312
Prevent to reuse if unsigned packages are allowed
JIRA: RHELCMP-8415
Signed-off-by: Haibo Lin <hlin@redhat.com>
(cherry picked from commit b30f7e0d83)
2023-11-10 16:51:34 +02:00
Lubomír Sedlář
e891fe7b09
Pass parent id/respin id to CTS
When the --target-dir option is used, the compose can be created in CTS,
but the parent and respin information is not passed through. That leads
to data missing later on.

JIRA: RHELCMP-11411
Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>

(cherry picked from commit 0c3b6e22f9 (centos_master))
2023-11-10 16:51:33 +02:00
Haibo Lin
4cd7d39914
Exclude existing files in boot.iso
JIRA: RHELCMP-10811
Fixes: https://pagure.io/pungi/issue/1647
Signed-off-by: Haibo Lin <hlin@redhat.com>
(cherry picked from commit 3175ede38a)
2023-11-10 16:50:46 +02:00
Lubomír Sedlář
5de829d05b
image-build/osbuild: Pull ISOs into the compose
OSBuild tasks can produce ISO files. If they do, we should include them
in the compose, and we should pull them into the iso/ subdirectory
together with other ISOs.

Fixes: https://pagure.io/pungi/issue/1657
Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
(cherry picked from commit 8920eef339)
2023-11-10 16:50:45 +02:00
Lubomír Sedlář
2930a1cc54
Retry 401 error from CTS
This could be a transient error caused by kerberos server instability.

JIRA: RHELCMP-11251
Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
(cherry picked from commit 58036eab84)
2023-11-10 16:50:43 +02:00
Lubomír Sedlář
9c4d3d496d
gather: Better detection of debuginfo in lookaside
If the depsolver wants to include a package that is present in both the
source repo and a lookaside repo, it reliably detects binary packages
present in lookaside, but for debuginfo it's not so reliable.

There is a separate package object for each package in each repo.
Depending on which one is used, debuginfo could be included in the
result or not. This patch fixes that by actually looking if the same
package is present in any lookaside repo.

JIRA: RHELCMP-9373
Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
(cherry picked from commit a4476f2570)
2023-11-10 16:50:42 +02:00
Haibo Lin
4637fd6697
Log versions of all installed packages
JIRA: RHELCMP-9493
Signed-off-by: Haibo Lin <hlin@redhat.com>
(cherry picked from commit 8c06b7a3f1)
2023-11-10 16:50:41 +02:00
Lubomír Sedlář
2ff8132eaf
Use authentication for all CTS calls
The update of compose URL relied on environment being set from the
initial import. This got broken when a unique credentials cache started
to be used, and was cleaned up after the import.

JIRA: RHELCMP-11072
Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
(cherry picked from commit 64ae81b416)
2023-11-10 16:50:40 +02:00
Lubomír Sedlář
f9190d1fd1
Fix black complaints
These are newly detected by black 23.1.0.

Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
(cherry picked from commit 826169af7c)
2023-11-10 16:50:38 +02:00
Lubomír Sedlář
80ad0448ec
Add vhd.gz extension to compressed VHD images
JIRA: RHELCMP-11027
Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
(cherry picked from commit d97b8bdd33)
2023-11-10 16:50:37 +02:00
Lubomír Sedlář
027380f969
Add vhd-compressed image type
JIRA: RHELCMP-11027
Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
(cherry picked from commit 8768b23cbe)
2023-11-10 16:50:36 +02:00
Lubomír Sedlář
41048f60b7
Update to work with latest mock
The `called_once` attribute now raises an exception. Switch to
`assert_called_once` method. Also replace `assertTrue(x.called)` with
`x.assert_called()`.

Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
(cherry picked from commit 51628a974d)
2023-11-10 16:50:34 +02:00
Ondrej Nosek
9f8f6a7956
Default bztar format for sdist command
Usage of the 'bztar' format is unchanged, just changing the way
of configuration. The previous method was deprecated.

Signed-off-by: Ondrej Nosek <onosek@redhat.com>
(cherry picked from commit 88327d5784)
2023-11-10 16:50:33 +02:00
Lubomír Sedlář
3d3e4bafdf
- New upstream release 4.5.0
(cherry picked from commit 4dfabb647b (fedora_master))
2023-11-10 16:47:04 +02:00
Lubomír Sedlář
8fe0257e93
Release 4.4.1
(cherry picked from commit 4c604f434a (fedora_master))
2023-11-10 16:46:02 +02:00
Fedora Release Engineering
d7b5fd2278
Rebuilt for https://fedoraproject.org/wiki/Fedora_39_Mass_Rebuild
Signed-off-by: Fedora Release Engineering <releng@fedoraproject.org>

(cherry picked from commit bf4f5b6e53 (fedora_master))
2023-11-10 16:44:52 +02:00
Lubomír Sedlář
8b49d4ad61
Backport patch from upstream PR 1690
(cherry picked from commit 2362ef59c5 (fedora_master))
2023-11-10 16:44:19 +02:00
Lubomír Sedlář
57443cd0aa
Backport patch from upstream PR 1690
(cherry picked from commit 9ee6caf117 (fedora_master))
2023-11-10 16:43:47 +02:00
Python Maint
1d146bb8d5
Rebuilt for Python 3.12
(cherry picked from commit 8b8b558fbc (fedora_master))
2023-11-10 16:42:36 +02:00
Lubomír Sedlář
790091b7d7
Release 4.4.0
(cherry picked from commit a6196da315 (fedora_master))
2023-11-10 16:42:10 +02:00
Lubomír Sedlář
28aad3ea40
Rebuild without fedmsg dependencs
(cherry picked from commit d142464ef1 (fedora_master))
2023-11-10 16:41:29 +02:00
Pierre-Yves Chibon
7373b4dbbf
Replace the requirement on fedmsg to one on fedora-messaging
Signed-off-by: Pierre-Yves Chibon <pingou@pingoured.fr>
(cherry picked from commit 802f5fe854)
2023-11-10 16:40:34 +02:00
Lubomír Sedlář
218b11f1b7
Backport patches
(cherry picked from commit 20a5d00961 (fedora_master))
2023-11-10 16:40:33 +02:00
Haibo Lin
bfbe9095d2
Release 4.3.8
Signed-off-by: Haibo Lin <hlin@redhat.com>

(cherry picked from commit 3548f55821 (fedora_master))
2023-11-10 16:38:58 +02:00
Lubomír Sedlář
eb17182c04
Update license tag to SPDX
(cherry picked from commit f9143f6ea1 (fedora_master))
2023-11-10 16:33:41 +02:00
f91f90cf64 - Test empty sub-package 2023-10-26 00:01:45 +03:00
49931082b2 - Test empty sub-package 2023-10-25 23:11:26 +03:00
8ba8609bda - Test empty sub-package 2023-10-25 22:58:28 +03:00
6f495a8133 - Test empty sub-package 2023-10-25 22:55:18 +03:00
2b4bddbfe0 - Test empty sub-package 2023-10-25 22:17:42 +03:00
032cf725de - Bump version
- Changelog
2023-07-25 11:12:03 +03:00
8b11bb81af AL-5220: Investigate why CL9 can't built on the new nebula
- Exclude the packages for using in a build
2023-07-24 18:26:51 +03:00
soksanichenko
114a73f100 - gather-module can find modules through symlinks
- Bump version
- Update changelog
2023-04-15 20:03:27 +03:00
soksanichenko
1c3e5dce5e - CLI option --label can be passed through a Pungi config file
- Bump version
- Update changelog
2023-04-13 00:57:39 +03:00
soksanichenko
e55abb17f1 - Bump version 2023-04-04 10:12:22 +03:00
soksanichenko
e81d78a1d1 - The log message contains a variant's name if Pungi didn't find one or more modules for that 2023-04-04 10:11:59 +03:00
soksanichenko
68915d04f8 - Excluded/included modules/packages will be processed correctly 2023-04-02 22:27:24 +03:00
soksanichenko
a25bf72fb8 - Changelog is updated
- Version is bumped
2023-03-31 12:07:22 +03:00
Stepan Oksanichenko
68aee1fa2d Merge pull request 'ALBS-987: Generate i686 and dev repositories with pungi on building new distr. version automatically' (#15) from ALBS-987 into al_master
Reviewed-on: #15
2023-03-31 09:03:39 +00:00
soksanichenko
6592735aec ALBS-987: Generate i686 and dev repositories with pungi on building new distr. version automatically
- Unittests are fixed
2023-03-30 14:05:47 +03:00
soksanichenko
943fd8e77d ALBS-987: Generate i686 and dev repositories with pungi on building new distr. version automatically
- Script `create extra repo` is fixed
- Unittests are fixed
2023-03-30 12:52:51 +03:00
soksanichenko
004fc4382f ALBS-987: Generate i686 and dev repositories with pungi on building new distr. version automatically
- Review comments
2023-03-29 11:40:00 +03:00
soksanichenko
596c5c0b7f ALBS-987: Generate i686 and dev repositories with pungi on building new distr. version automatically
- Refactoring
- Some absent packages are in packages.json now
2023-03-28 12:58:08 +03:00
soksanichenko
141d00e941 ALBS-987: Generate i686 and dev repositories with pungi on building new distr. version automatically
- More info about unsigned packages
2023-03-24 16:39:10 +02:00
soksanichenko
4b64d20826 ALBS-987: Generate i686 and dev repositories with pungi on building new distr. version automatically
- Path.rglob/glob doesn't work with symlinks (it's the bug and reported)
- Refactoring
2023-03-24 12:45:28 +02:00
soksanichenko
0747e967b0 ALBS-987: Generate i686 and dev repositories with pungi on building new distr. version automatically
- Some refactoring
2023-03-23 09:36:52 +02:00
soksanichenko
6d58bc2ed8 ALBS-987: Generate i686 and dev repositories with pungi on building new distr. version automatically
- [Generator of packages.json] Replace using CLI by config.yaml
- [Gather RPMs] os.path is replaced by Path
2023-03-22 15:56:58 +02:00
Stepan Oksanichenko
60a347a4a2 Merge pull request 'ALBS-1030: Generate Devel section in packages.json' (#14) from ALBS-1030 into al_master
Reviewed-on: #14
2023-03-22 10:06:58 +00:00
soksanichenko
53ed7386f3 ALBS-1030: Generate Devel section in packages.json
- Redundant empty lines are removed
2023-03-20 13:56:44 +02:00
soksanichenko
ed43f0038e ALBS-1030: Generate Devel section in packages.json
- Style fix
2023-03-20 13:55:06 +02:00
soksanichenko
fcc9b4f1ca ALBS-1030: Generate Devel section in packages.json
- Skip verifying an RPM signature if sigkeys are empty
2023-03-20 13:25:45 +02:00
soksanichenko
d32c293bca ALBS-1030: Generate Devel section in packages.json
- Some upstream changes to KojiMock parts
2023-03-19 21:11:12 +02:00
soksanichenko
f0bd1af999 ALBS-1030: Generate Devel section in packages.json
- Also the tool can combine (remove and add) packages in a variant from different
  sources according to an url's type of source
2023-03-19 18:21:33 +02:00
soksanichenko
1b4747b915 - Changelog is updated
- Version is bumped
- New release 4.3.7-3.alma
2023-03-17 12:02:48 +02:00
Lubomír Sedlář
6aabfc9285 osbuild: test passing of rich repos from configuration
Test that "rich" repositories defined as dicts in the configuration
stay as dicts in the arguments passed to the osbuild phase.

Signed-off-by: Tomáš Hozza <thozza@redhat.com>
(cherry picked from commit 8be0d84f8a)
2023-03-17 11:58:11 +02:00
Tomáš Hozza
9e014fed6a osbuild: support specifying package_sets for repos
The `koji-osbuild` plugin supports additional formats for the `repo`
property since v4 [1]. Specifically, a repo can be specified as a
dictionary with `baseurl` key and `package_sets` list containing
specific package set names, that the repository should be used for.

Extend the configuration schema to reflect the plugin change.
Extend the documentation to cover the new repository format.
Extend an existing unit test to specify additional repository using the
added format.

[1] https://github.com/osbuild/koji-osbuild/pull/82

Signed-off-by: Tomáš Hozza <thozza@redhat.com>
(cherry picked from commit 8f0906be53)
2023-03-17 11:58:11 +02:00
Tomáš Hozza
7ccb1d4849 osbuild: don't use util.get_repo_urls()
Don't use `util.get_repo_urls()` to resolve provided repositories, but
implement osbuild-specific variant of the function named
`_get_repo_urls(). The reason is that the function from `utils`
transforms repositories defined as dicts to strings, which is
undesired for osbuild. The requirement for osbuild is to preserve the
dict as is, just to resolve the string in `baseurl` to the actual
repository URL.

Add a unit test covering the newly added function. It is inspired by a
similar test from `test_util.py`.

Signed-off-by: Tomáš Hozza <thozza@redhat.com>
(cherry picked from commit e3072c3d5f)
2023-03-17 11:58:11 +02:00
Tomáš Hozza
abec28256d osbuild: update schema and config documentation
The `koji-osbuild` Hub schema has been relaxed a bit in the latest
release (v11). Adjust the schema in Pungi to reflect changes in
`koji-osbuild`.

For more information on the changes in `koji-osbuild`, see:
https://github.com/osbuild/koji-osbuild/pull/108

Signed-off-by: Tomáš Hozza <thozza@redhat.com>
(cherry picked from commit ef6d40dce4)
2023-03-17 11:58:11 +02:00
Lubomír Sedlář
46216b4f17 Speed up tests by 30 seconds
The retry test for CTS doesn't actually need to wait. Let's mock the
sleep function.

Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
(cherry picked from commit df6664098d)
2023-03-17 11:58:11 +02:00
Lubomír Sedlář
02b3adbaeb Stop sending compose paths to CTS
The tracking service will reject it as it's not an HTTP URL. Let's not
even try.

Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
(cherry picked from commit 147df93f75)
2023-03-17 11:58:11 +02:00
Lubomír Sedlář
d17e578645 Report errors from CTS
If the service returns a status code indicating a user error, report
that and do not retry.

Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
(cherry picked from commit dd8c1002d4)
2023-03-17 11:58:11 +02:00
Lubomír Sedlář
6c1c9d9efd createiso: Create Joliet tree with xorriso
This structure is important for isoinfo -J, which is in turn called by
virt-install.

This can be tested by using a bootable ISO by modifying it with a dummy
additional file and preserving boot records:

    $ xorriso -indev netinst.iso -outdev test.iso -boot_image any replay -map setup.py setup.py -end
    ...
    $ isoinfo -J -i test.iso
    isoinfo: Unable to find Joliet SVD
    $ rm test.iso
    $ xorriso -indev netinst.iso -outdev test.iso -joliet on -boot_image any replay -map setup.py setup.py -end
    ...
    $ isoinfo -J -i test.iso
    $

Fixes: https://bugzilla.redhat.com/show_bug.cgi?id=2144105
Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
(cherry picked from commit 12e3a46390)
2023-03-17 11:58:04 +02:00
Stepan Oksanichenko
8dd7d8326f Merge pull request 'ALBS-1040: Investigate why Pungi doesn't put modules packages into the final repos' (#13) from ALBS-1040 into al_master
Reviewed-on: #13
2023-03-16 11:52:02 +00:00
soksanichenko
d7b173cae5 ALBS-1040: Investigate why Pungi doesn't put modules packages into the final repos
- The unitttest is fixed
2023-03-14 18:43:14 +02:00
soksanichenko
fa4640f03e ALBS-1040: Investigate why Pungi doesn't put modules packages into the final repos
- Refactoring
- KojiMock extracts all modules which are suitable for the variant's arches
2023-03-14 18:25:21 +02:00
Stepan Oksanichenko
d66eb0dea8 Merge pull request 'ALBS-1032: Generate i686 section for all variants in packages.json' (#12) from ALBS-1032 into al_master
Reviewed-on: #12
2023-03-14 16:21:41 +00:00
soksanichenko
d56227ab4a ALBS-1032: Generate i686 section for all variants in packages.json
- Remove old non-necessary methods
- Some fixes to arch code
2023-03-09 12:32:11 +02:00
soksanichenko
12433157dd - changelog 2022-11-12 00:04:44 +02:00
soksanichenko
623955cb1f - python3-distro as dependency 2022-11-11 19:21:37 +02:00
soksanichenko
4e0d2d14c9 - Unify branch for both RHEL versions 2022-11-11 16:31:43 +02:00
soksanichenko
b61e59d676 - Use unittest.mock instead external mock 2022-11-11 15:32:00 +02:00
soksanichenko
eb35d7baac - Unify branch for both RHEL versions 2022-11-11 01:38:14 +02:00
soksanichenko
54209f3643 ALBS-732 2022-11-09 21:42:13 +02:00
soksanichenko
80c4536eaa ALBS-732 2022-11-09 21:27:51 +02:00
soksanichenko
9bb5550d36 ALBS-732 2022-11-09 21:01:30 +02:00
soksanichenko
364ed6c3af - kojimock is added to pungi.phases.gather._make_lookaside_repo#prefixes
- unittests are fixed
2022-11-09 20:56:56 +02:00
soksanichenko
0b965096ee - PkgsetSourceKojiMock is added to ALL_SOURCES 2022-11-09 18:18:12 +02:00
soksanichenko
d914626d92 - "kojimock" is valid value for option "pkgset_source" 2022-11-09 17:59:50 +02:00
soksanichenko
32215d955a - fedmsg is removed as not needed 2022-11-09 12:38:34 +02:00
soksanichenko
d711f8a2d6 - fedmsg is removed as not needed 2022-11-09 09:06:09 +02:00
soksanichenko
bd9d800b52 - Fix spec 2022-11-08 17:11:21 +02:00
soksanichenko
e03648589d - Fix spec 2022-11-08 17:09:03 +02:00
soksanichenko
b5fe2e8129 - Fix spec 2022-11-08 17:06:36 +02:00
soksanichenko
b14e85324c - Fix unittests 2022-11-08 14:57:52 +02:00
soksanichenko
5a19ad2258 - Fix unittests 2022-11-08 12:47:14 +02:00
soksanichenko
9ae49dae5b - Fix unittests 2022-11-08 01:43:53 +02:00
soksanichenko
c82cbfdc32 - Fix unittests 2022-11-08 00:59:10 +02:00
soksanichenko
ee9c9a74e6 - Fix unittests 2022-11-07 23:55:26 +02:00
soksanichenko
ea0f933315 - Updates from upstream (https://pagure.io/pungi.git#master) 2022-11-07 23:40:26 +02:00
soksanichenko
323d31df2b Merge branch 'master' into a8_updated
# Conflicts:
#	pungi.spec
#	pungi/wrappers/kojiwrapper.py
#	setup.py
#	tests/test_extra_isos_phase.py
#	tests/test_pkgset_pkgsets.py
2022-11-07 23:38:38 +02:00
soksanichenko
9acd7f5fa4 Merge remote-tracking branch 'centos-origin/master' 2022-11-07 23:33:20 +02:00
soksanichenko
a2b16eb44f - spec is updated (merged with last changed from Fedora repo
https://src.fedoraproject.org/rpms/pungi/blob/main/f/pungi.spec
2022-11-07 23:33:03 +02:00
soksanichenko
ff946d3f7b - Unittests are fixed 2022-11-07 20:15:37 +02:00
soksanichenko
ede91bcd03 - Right name of the class in constructor 2022-11-07 20:03:59 +02:00
soksanichenko
0fa459eb9e - Right name of the class in constructor 2022-11-07 19:56:02 +02:00
soksanichenko
b49ffee06d - Mock of Koji is moved to the separate modules, classes
- Unittests for mock of Koji are moved to the separate
2022-11-07 19:24:39 +02:00
soksanichenko
fce5493f09 Merge remote-tracking branch 'centos-origin/master'
# Conflicts:
#	pungi/phases/init.py
#	pungi/wrappers/comps.py
2022-11-03 22:49:11 +02:00
Lubomír Sedlář
479849042f init: Filter comps for modular variants with tags
Modular variants can either be specified by a list of modules, or by a
list of Koji tags. In terms of comps preprocessing there should not be
any difference between the two.

Resolves: https://pagure.io/pungi/issue/1640
Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2022-11-03 11:11:01 +01:00
Haibo Lin
8cd19605bd Retry failed cts requests
JIRA: RHELCMP-10033
Signed-off-by: Haibo Lin <hlin@redhat.com>
2022-10-31 12:29:44 +08:00
soksanichenko
750499eda1 - The unittests are fixed 2022-10-19 14:10:48 +03:00
soksanichenko
d999960235 - bump the dependency version 2022-10-19 13:00:32 +03:00
soksanichenko
6edece449d - changelog
- bump version
2022-10-19 04:40:39 +03:00
Stepan Oksanichenko
dd22d94a9e Merge pull request 'Replace list of cr.packages by cr.PackageIterator' (#6) from package_iterator into aln8
Reviewed-on: #6
2022-10-19 01:38:44 +00:00
soksanichenko
b157a1825a Do not lose a module from koji if we have more than one arch (e.g. x86_64 + i686) 2022-10-19 04:33:34 +03:00
soksanichenko
fd298d4f17 Replace list of cr.packages by cr.PackageIterator 2022-10-18 22:53:50 +03:00
Lubomír Sedlář
fa967f79b5 Ignore existing kerberos ticket for CTS auth
When there is an existing kerberos ticket, it gets precedence over the
environment variable with path to a keytab. That is not expected and the
user ticket can possibly lack permissions in CTS to be able to run the
compose successfully.

This patch fixes that by setting KRB5CCNAME to a fresh path. That way
there will not be any valid ticket, since the credentials cache does not
exist yet.

JIRA: RHELCMP-9742
Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2022-09-13 12:38:20 +02:00
Tomas Hozza
57739c238f
osbuild: support specifying upload_options
Since version 9, the `koji-osbuild` plugin supports specifying upload
options as part of a Koji build. This enables one to upload the built
image directly to the cloud environment as part of the image build in
Koji.

Extend the configuration schema with `upload_options`.
Extend the documentation and describe valid `upload_options` values.
Add a unit test testing a scenario when `upload_options` are specified.

Signed-off-by: Tomas Hozza <thozza@redhat.com>
2022-09-06 11:20:01 +02:00
Tomas Hozza
805a1083a2
osbuild: accept only a single image type in the configuration
Modify the osbuild configuration schema to accept only an array with a
single value as the `image_types`, in addition to a single string. The
single string was supported by the schema also before, but this fact was
not mentioned in the documentation, nor it was supported by the
`koji-osbuild` plugin of version lower than `9`.

Update the documentation accordingly.

Add unit test for invalid configuration containing more than one image
type.

Signed-off-by: Tomas Hozza <thozza@redhat.com>
2022-09-06 10:55:25 +02:00
Haibo Lin
57ea640916 Add Jenkinsfile for CI
JIRA: RHELCMP-9800
Signed-off-by: Haibo Lin <hlin@redhat.com>
2022-08-29 17:38:04 +08:00
Lubomír Sedlář
c7121f9378 profiler: Flush stdout before printing
Apparently redirecting stderr to the same pipe as stdout does not
guarantee that the data will not be mangled together.

Flushing stdout before the profiler data is printed should ensure that
it does not end up in the middle of some RPM path.

Fixes: https://pagure.io/pungi/issue/1627
Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2022-08-29 05:57:14 +00:00
Lubomír Sedlář
146b88e1e9 4.3.6 release
JIRA: RHELCMP-9914
Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2022-08-26 11:13:43 +02:00
Lubomír Sedlář
8aba2363e2 pkgset: Report better error when module is missing an arch
Pungi expects each module to be built for all architectures by default.
Unless the module is filtered out, missing metadata for a particular
arch would cause it to crash with a incomprehensible error message. This
should make it a little better.

Relates: https://pagure.io/releng/failed-composes/issue/3889
Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2022-08-26 08:46:01 +00:00
Ondřej Budai
779793386c osbuild: add support for building ostree artifacts
In order to start building Fedora IoT images with osbuild, we need to be able
to pass ostree options from pungi to the koji's osbuildImage task.

This commit adds support for it via new configuration options: ostree_url,
ostree_url and ostree_parent.

A test was added to cover these new options and they are were also added
into the documentation.

JIRA: COMPOSER-1702
Merges: https://pagure.io/pungi/pull-request/1624
Signed-off-by: Ondřej Budai <ondrej@budai.cz>
2022-08-25 15:35:17 +02:00
Timothée Ravier
603c61a033 ostree: Add unified core mode for compose in rpm-ostree
rpm-ostree is moving to unified core composes and this is now working
for Silverblue & Kinoite.

This is untested for IoT but they should move to os-build with Fedora
37.

See: https://github.com/coreos/rpm-ostree/issues/729
Merges: https://pagure.io/pungi/pull-request/1626
Signed-off-by: Timothée Ravier <tim@siosm.fr>
2022-08-23 10:52:45 +02:00
Lubomír Sedlář
11fa342507 createiso: Make ISO level more granular
Make it possible to set the level separately for each variant and
architecture.

JIRA: RHELCMP-9341

Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2022-08-16 14:38:18 +02:00
Lubomír Sedlář
13ea8e5834 Create DVDs with xorriso
Use a different approach for building DVDs when xorriso is enabled.

The default of using genisoimage is not changed at all. When the config
option is set to use xorriso, the actual execution is different between
bootable and non-bootable images.

The non-bootable images are still created by running xorrisofs (which is
a compatibility tool with same UI as genisoimage). Since the image is
not bootable, there should be no problems with boot options.

For bootable images, Pungi will instead take the boot.iso generated by
Lorax, and use xorriso to inject all the extra files into the image.

The shell script that used to invoke all the commands to build the ISO
now runs the `xorriso` command in interactive mode and feeds another
file into it. The new file contains the xorriso commands to add the
required files to the image.

Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2022-08-16 14:30:41 +02:00
Lubomír Sedlář
0abf937b0e Fix compatibility with jsonschema >= 4.0.0
Fedora Rawhide (to be 37) packages jsonschema 4.9.0 at the moment, so we
can no longer get by with limiting the requirements. This patch makes
the validation work with both old and new version.

Fixes: rhbz#2113607
Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2022-08-10 09:52:23 +02:00
Lubomír Sedlář
778dcfa587 Fix black complaint
Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2022-08-10 09:04:41 +02:00
Ondřej Budai
ea8020473d
doc: fix osbuild's image_types field name
It's actually image_types, not just image_type. See
https://pagure.io/fork/obudai/pungi/blob/master/f/pungi/checks.py#_1160

Signed-off-by: Ondřej Budai <ondrej@budai.cz>
2022-08-09 17:39:42 +02:00
Haibo Lin
b0b494fff0 Convert _ssh_run output to str for python3
This is for fixing "a bytes-like object is required, not 'str'" issue
in runroot task.

JIRA: RHELCMP-9224
Signed-off-by: Haibo Lin <hlin@redhat.com>
2022-07-15 13:45:15 +08:00
Haibo Lin
19cb013fec Print more logs for git_ls_remote
e.output probably contains the root cause of git ls-remote failure.

JIRA: RHELCMP-9598
JIRA: RHELCMP-9599
Signed-off-by: Haibo Lin <hlin@redhat.com>
2022-07-14 11:11:01 +08:00
Haibo Lin
b27301641a Log time taken of each phase
Signed-off-by: Haibo Lin <hlin@redhat.com>
2022-07-12 16:56:41 +08:00
Haibo Lin
da336f75f8 Avoid crash when loading pickle file failed
The pickle files are used for reusing results from old compose and the
failure should not block the compose process.

JIRA: RHELCMP-9494
Signed-off-by: Haibo Lin <hlin@redhat.com>
2022-07-01 10:33:52 +08:00
Lubomír Sedlář
960c85efde extra_isos: Fix detection of changed packages
Checking start of the line is not sufficient for extra_isos that have
the variants in separate directories.

Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2022-06-27 09:46:35 +02:00
Lubomír Sedlář
d7aebfc7f9 4.3.5 release
JIRA: RHELCMP-9389
Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2022-06-15 12:27:04 +02:00
Marek Kulik
ca185aaea8 Fix module defaults and obsoletes validation
- Remove validation for modules obsoletes
  We can have multiple obsoletes for one module
- Add unit tests to cover basic scenarios for
  modules defaults && obsoletes
- Add additional check for invalid yaml file
  in Defaults. Previously, empty list of default would
  be returned when invalid yaml is present in Defaults
  directory.
- Using MergeIndex for Obsoletes only (for now).

https://pagure.io/pungi/issue/1592

Signed-off-by: Marek Kulik <mkulik@redhat.com>
2022-06-10 11:35:26 +00:00
Ozan Unsal
895b3982d7 Update the cts_keytab field in order to get the hostname of the server
- This change is required for the following issue. Authentication is required for
importing composes to the CTS and finding generic keytabs
in different servers.

JIRA: RHELCMP-8930

Signed-off-by: Ozan Unsal <ounsal@redhat.com>
2022-06-01 07:49:58 +00:00
Lingyan Zhuang
c4aa45beab Add skip_branding to ostree_installer.
Fixes: #1594
Merges: https://pagure.io/pungi/pull-request/1609
Signed-off-by: Lingyan Zhuang <lzhuang@redhat.com>
2022-05-11 15:19:53 +02:00
soksanichenko
f21ed6f607 ALBS-334: Make the ability of Pungi to give module_defaults from remote sources 2022-05-04 20:16:23 +03:00
soksanichenko
cfe6ec3f4e Merge pull request 'ALBS-334: Make the ability of Pungi to give module_defaults from remote sources' (#4) from ALBS-334 into aln8
Reviewed-on: #4
2022-05-04 17:05:45 +00:00
soksanichenko
e6c6f74176 ALBS-334: Make the ability of Pungi to give module_defaults from remote sources 2022-05-03 18:18:17 +03:00
soksanichenko
8676941655 ALBS-334: Make the ability of Pungi to give module_defaults from remote sources 2022-05-02 02:25:32 +03:00
soksanichenko
5f74175c33 ALBS-334: Make the ability of Pungi to give module_defaults from remote sources 2022-05-01 03:41:40 +03:00
soksanichenko
1e18e8995d ALBS-334: Make the ability of Pungi to give module_defaults from remote sources 2022-05-01 03:32:01 +03:00
soksanichenko
38ea822260 ALBS-334: Make the ability of Pungi to give module_defaults from remote sources 2022-04-30 00:27:31 +03:00
soksanichenko
34eb45c7ec ALBS-334: Make the ability of Pungi to give module_defaults from remote sources 2022-04-29 21:39:51 +03:00
soksanichenko
7422d1e045 ALBS-334: Make the ability of Pungi to give module_defaults from remote sources 2022-04-29 21:33:28 +03:00
soksanichenko
97801e772e ALBS-334: Make the ability of Pungi to give module_defaults from remote sources 2022-04-29 21:25:59 +03:00
soksanichenko
dff346eedb - Unit tests are fixed 2022-04-28 16:44:47 +03:00
soksanichenko
de53dd0bbd - Unit tests are fixed 2022-04-28 16:30:03 +03:00
Lubomír Sedlář
80957f5205 kojiwrapper: Ignore warnings before task id
When looking for task ID in output of koji runroot command, do not check
just the first line. Instead look for first line that contains just a
number.

Most of the time, this should really be the first line. But if koji
client decides to print any warnings, this patch should skip that.

JIRA: RHELCMP-8944
Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2022-04-26 08:15:13 +02:00
Lubomír Sedlář
e8d79e9269 Restrict jsonschema version
There's a new major version released on PyPI, and it doesn't seem to
work with Pungi yet. Until code is updated to be compatible, let's
ensure tox won't try to install it.

Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2022-04-19 12:56:13 +02:00
Haibo Lin
c5cdd498ac Revert "Do not clone the same repository multiple times, re-use already cloned repository"
This reverts commit 330ba9b9c4.

As of RHELCMP-8874, revert this patch as a quick fix.

Signed-off-by: Haibo Lin <hlin@redhat.com>
2022-04-13 16:21:55 +08:00
Haibo Lin
e490764985 Involve bandit
JIRA: RHELCMP-8562
Signed-off-by: Haibo Lin <hlin@redhat.com>
2022-04-07 14:03:57 +08:00
Ondrej Nosek
707a2c8d10 4.3.4 release
JIRA: RHELCMP-8627
Signed-off-by: Ondrej Nosek <onosek@redhat.com>
2022-04-04 11:12:21 +02:00
Lubomír Sedlář
f8c7ad28e4 kojiwrapper: Add retries to login call
The gssapi_login call is not retried automatically by Koji yet (see
koji#3170). Let's try to work around that by retrying in the calling
code.

JIRA: RHELCMP-8700
Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2022-04-04 07:51:12 +00:00
Ondrej Nosek
bebbefe46e Variants file in config can contain path
rcm-metadata configs contain definition of variants file. It can
be in form of SCM or file path. Before the fix, only variants
file's basename was consireded. Now the path can be written.
Example: variants_file = "comps/variants-rcmtools-2.0-rhel-8.xml"

JIRA: RHELCMP-8705
Signed-off-by: Ondrej Nosek <onosek@redhat.com>
2022-03-30 22:39:18 +02:00
Christopher O'Brien
d55770898c nomacboot option for livemedia koji tasks
Merges: https://pagure.io/pungi/pull-request/1591
Signed-off-by: Christopher O'Brien <cobrien@redhat.com>
2022-03-23 09:36:51 +01:00
Ken Dreyer
903ab076ba doc: improve osbs_registries explanation
Explain the use-case for this setting, and use the active voice to
explain what actions Pungi performs relative to other tools.

Signed-off-by: Ken Dreyer <kdreyer@redhat.com>
2022-03-21 14:53:11 -04:00
soksanichenko
88121619bc ALBS-226: Patch pungi/lorax for building AL9
- Defaults modules can be empty, but pungi detects
  empty folder while copying and raises the exception in this case
2022-03-18 22:37:57 +02:00
Ken Dreyer
b805ce3d12 osbs: only handle archives of type "image"
Prior to this change, if a container image used Cachito with OSBS, then
OSBS would store additional "remote-sources" files in the Koji archives
for the build. Pungi cannot parse the metadata for these archive
entries, so it would crash in add_metadata():

  File "pungi/phases/osbs.py", line 81, in process
    self.worker(compose, variant, config)
  File "pungi/phases/osbs.py", line 141, in worker
    nvr, archive_ids = add_metadata(variant, task_id, compose, scratch)
  File "pungi/phases/osbs.py", line 447, in add_metadata
    arch = archive["extra"]["image"]["arch"]
  KeyError: 'image'

Tell Koji to only return container image archives, and ignore these
remote-source archives.

Signed-off-by: Ken Dreyer <kdreyer@redhat.com>
2022-03-17 11:04:02 -04:00
Ozan Unsal
0e82663327 Update the default greedy_method value in doc
JIRA: RHELCMP-6308

Signed-off-by: Ozan Unsal <ounsal@redhat.com>
2022-03-10 15:35:13 +01:00
Ozan Unsal
ecb1646042 Fix the wrong working directory for the progress_notification script
Jira: RHELCMP-7901

Signed-off-by: Ozan Unsal <ounsal@redhat.com>
2022-03-01 11:25:06 +00:00
Haibo Lin
6c280f2c46 Filter out environment groups unmatch given arch
JIRA: RHELCMP-7926
Signed-off-by: Haibo Lin <hlin@redhat.com>
2022-02-22 11:33:25 +08:00
Lubomír Sedlář
aabf8faea0 profiler: Respect provided output stream
Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2022-02-07 09:07:59 +00:00
Petr Písař
38810b3f13 modules: Correct a typo in loading obsoletes
Pungi failed:

TypeError: argument obsoletes: Expected Modulemd.Obsoletes, but got list
Frame collect_module_obsoletes in /usr/lib/python3.10/site-packages/pungi/module_util.py at line 91
<CODE>
      84     mod_index = mod_index or Modulemd.ModuleIndex()
      85
      86     for module_name, obsoletes in iter_module_defaults_or_obsoletes(
      87         obsoletes_dir, obsoletes=True
      88     ):
      89         for obsolete in obsoletes:
      90             if not modules_to_load or module_name in modules_to_load:
-->   91                 mod_index.add_obsoletes(obsoletes)
      92
      93     return mod_index
</CODE>
<LOCALS>
           mod_index = <Modulemd.ModuleIndex object at 0x7f01a40fae40 (ModulemdModuleIndex at 0x7f0484338f90)>
         module_name = 'perl'
     modules_to_load = {'perl-Date-Manip', 'subversion', 'sway', 'nginx', 'perl-YAML', 'ghc', 'perl-App-cpanminus', 'perl-XML-Parser', 'varnish', 'nodejs', 'cri-o', 'perl-DBD-Pg', 'perl-DBI', 'perl', 'swig', 'perl-FCGI', 'p
            obsolete = <Modulemd.Obsoletes object at 0x7f00c0fe4a00 (ModulemdObsoletes at 0x7f024c0268b0)>
           obsoletes = [<Modulemd.Obsoletes object at 0x7f00c0fe4a00 (ModulemdObsoletes at 0x7f024c0268b0)>]
       obsoletes_dir = '/mnt/koji/compose/rawhide/Fedora-Rawhide-20220203.n.1/work/global/module_obsoletes'
</LOCALS>

This patches fixes the typo in add_obsoletes() argument.

https://pagure.io/releng/failed-composes/issue/3058
Signed-off-by: Petr Písař <ppisar@redhat.com>
2022-02-04 11:15:31 +01:00
Ozan Unsal
330ba9b9c4 Do not clone the same repository multiple times, re-use already cloned repository
Clone the directory to the compose tmp directory
Update the test_scm in order to create real Compose object. Mock objects are not allowed
to create/delete files for preventing multiple clones

JIRA: RHELCMP-5250

Signed-off-by: Ozan Unsal <ounsal@redhat.com>
2022-01-26 15:57:13 +01:00
Haibo Lin
52c9816755 4.3.3 release
JIRA: RHELCMP-7691
Signed-off-by: Haibo Lin <hlin@redhat.com>
2022-01-13 15:45:30 +08:00
Lubomír Sedlář
32221e8f36 hybrid: Explicitly pull in debugsource packages
This should cover case where we there's a build like this:

foo-1-1.src.rpm
  foo-sub-1-1.noarch.rpm
  foo-debugsource-1-1.x86_64.rpm

The compose contains the noarch package, and should also have the
debugsource package. The original code only checked for
foo-sub-debugsource though.

JIRA: RHELCMP-7628
Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2022-01-12 13:59:09 +00:00
Filip Valder
fe986d68b9 Add module obsoletes feature
JIRA: MODULAR-113
Merges: https://pagure.io/pungi/pull-request/1578
Signed-off-by: Filip Valder <fvalder@redhat.com>
2022-01-12 12:51:37 +01:00
Ozan Unsal
42f668d969 buildinstall: Add ability to install extra packages in runroot
Resolves: https://pagure.io/pungi/issue/1461
Merges: https://pagure.io/pungi/pull-request/1580
JIRA: RHELCMP-2911
Signed-off-by: Ozan Unsal <ounsal@redhat.com>
2022-01-05 14:35:37 +01:00
Haibo Lin
894cce6a5a Ignore osbs/osbuild config when reusing iso images
JIRA: RHELCMP-7562
Signed-off-by: Haibo Lin <hlin@redhat.com>
2022-01-04 16:35:29 +08:00
soksanichenko
0484426e0c ALBS-97: Build AlmaLinux PPC64le repos and ISOs with pungi
- Changelog
- Version is bumped

@BS-NOBUILD
@BS-TARGET-CL8

Change-Id: I933925b7a27a5e1b642020e060f59212fdc6ebf4
2021-12-30 12:42:34 +02:00
soksanichenko
b9d86b90e1 ALBS-97: Build AlmaLinux PPC64le repos and ISOs with pungi
- Scripts `create_packages_json` & `gather_modules` can process lzma compressed yaml files
- Script `create_package_json` can use repodata there are packages with different
  arch by compare with passed to the script

@BS-NOBUILD
@BS-TARGET-CL8

Change-Id: Ia9a3bacfa4344f0cf33b9f416649fd4a5f8d3c37
2021-12-28 16:08:04 +02:00
soksanichenko
58a16e5688 - The version is bumped
- The changelog is updated
- The test `create_packages_json` is fixed

@BS-NOBUILD
@BS-TARGET-CL8

Change-Id: I173013da990eb296e58ca8f3555a05913ca1c852
2021-12-20 14:11:17 +02:00
Lubomír Sedlář
260b3fce8d compose: Make sure temporary dirs are world readable
When the temporary directory is created with 0700, other programs
(potentially on another host) will have problems reading it.

Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
JIRA: RHELCMP-7635
2021-12-17 08:10:48 +01:00
Haibo Lin
20c2e59218 Pass compose parameter for debugging git issue
With this param, get_dir_from_scm will try to copy the tmp git dir to
compose target dir when error occurs.

This does not fix the issue but it would be helpful for debugging when
it occurs again.

JIRA: RHELCMP-7244
Signed-off-by: Haibo Lin <hlin@redhat.com>
2021-11-26 15:40:35 +08:00
Haibo Lin
5e6248e3e0 Generate images.json for extra_isos phase
JIRA: RHELCMP-7241
Signed-off-by: Haibo Lin <hlin@redhat.com>
2021-11-15 14:38:53 +08:00
Haibo Lin
f681956cf1 Fix tests for python 2.6
It failed to build RHEL 6 package as logging.NullHandler does not exist
in python 2.6

JIRA: RHELCMP-7188
Signed-off-by: Haibo Lin <hlin@redhat.com>
2021-11-12 17:04:17 +08:00
Haibo Lin
cfb9882269 4.3.2 release
JIRA: RHELCMP-7182
Signed-off-by: Haibo Lin <hlin@redhat.com>
2021-11-11 16:08:54 +08:00
soksanichenko
f2ed64d952 ALBS-66: Prepare Jenkins jobs for building distribution of AlmaLinux 8.5
- Script `create_packages_json` can duplicate the packages with
  same version in different variants

Change-Id: I3c79ad06c4c22442423c12d5fa06baf82d663a3f
2021-11-10 15:29:59 +02:00
Lubomír Sedlář
b652119d54 gather: Load JSON mapping relative to config dir
JIRA: RHELCMP-7195
Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2021-11-10 11:01:53 +01:00
Lubomír Sedlář
33d7290d78 gather: Stop requiring all variants/arches in JSON
The JSON source file should not require a mapping for all
variants/architectures. When something is specified, it should be
included.

Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2021-11-10 11:01:53 +01:00
Ken Dreyer
9bae86a51e doc: make dnf "backend" settings easier to discover
Mention the corresponding "gather" or "repoclosure" backend settings in
the documentation for each setting.

Signed-off-by: Ken Dreyer <kdreyer@redhat.com>
2021-11-04 10:55:54 -04:00
Lubomír Sedlář
1d654522be Remove with_jigdo argument
It was checked in a condition together with the configuration value, and
only ever explicitly used with the same value.

Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2021-11-04 13:37:51 +00:00
Lubomír Sedlář
80bd254347 Check dependencies after config validation
This way the checks can rely on default values from the config.

Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2021-11-04 13:37:51 +00:00
Ken Dreyer
94ffa1c5c6 default "with_jigdo" to False
Fedora has not composed with jigdo in a long time. Disable it by
default.

Signed-off-by: Ken Dreyer <kdreyer@redhat.com>
Merges: https://pagure.io/pungi/pull-request/1561
Fixes: https://pagure.io/pungi/issue/1560
2021-11-04 13:37:51 +00:00
Lubomír Sedlář
9d02f87c99 Stop trying to validate non-existent metadata
When a compose doesn't build any images, it won't produce any metadata
file for them, and thus it makes no sense to validate it.

Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
Fixes: https://pagure.io/pungi/issue/1565
2021-11-04 09:57:20 +01:00
fdiprete
7b9e08ab28 test images for metadata deserialization error
Merges: https://pagure.io/pungi/pull-request/1559
Jira: https://issues.redhat.com/browse/RHELCMP-6685
Signed-off-by: fdiprete <fdipretre@redhat.com>
2021-11-03 08:50:07 +01:00
Lubomír Sedlář
e2b3002726 repoclosure: Use --forcearch for dnf repoclosure
DNF repoclosure requires this option when checking a repository that is
not compatible with host architecture. It seems that when it is
compatible, it works as well.

Based on how the list of architectures is generated, we know that the
main one will always be first.

Fixes: https://pagure.io/pungi/issue/1562
Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2021-11-02 08:51:40 +01:00
Lubomír Sedlář
e8305f3978 extra_isos: Allow reusing old images
When nothing in configuration or the image itself changed, let's just
copy the older one.

JIRA: RHELCMP-5969
Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2021-11-02 07:08:00 +00:00
Lubomír Sedlář
ac66c3d7f3 createiso: Allow reusing old images
This patch allows Pungi to reuse ISO image created in previous compose
if a list of assumptions proves to hold:

 * If image is bootable, buildinstall phase must have been reused too.
 * Compose configuration must have not changed (except for a few
   whitelisted options).
 * Volume ID of the ISO much not have changed.
 * No RPM on the ISO must have changed.

The ISO also contains other files. Changes in extra files and product ID
certificates should be visible in configuration (the SHA will differ).
Similarly any repodata configuration would be reflected in
configuration.

JIRA: RHELCMP-5969
Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2021-11-02 07:08:00 +00:00
Lubomír Sedlář
eb61c97cdb Remove default runroot channel
When the value is not specified in the configuration file, let Koji pick
the default channel.

JIRA: RHELBLD-8088
Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2021-10-25 15:56:24 +02:00
Ozan Unsal
b03490bf18 4.3.1 release
JIRA: RHELCMP-7116
Signed-off-by: Ozan Unsal <ounsal@redhat.com>
2021-10-25 15:18:26 +02:00
Dan Čermák
ab19043773 Correct irc network name & add matrix room
Signed-off-by: Dan Čermák <dan.cermak@cgc-instruments.com>
2021-10-25 07:26:18 +00:00
Lubomír Sedlář
204d88a351 Add missing mock to osbs tests
We don't want the test to try to a dummy URL.

Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2021-10-21 13:34:37 +02:00
Haibo Lin
8133676270 osbs: Reuse images from old compose
JIRA: RHELCMP-5972
Signed-off-by: Haibo Lin <hlin@redhat.com>
2021-10-20 14:22:19 +08:00
Haibo Lin
e42e65783d image_build: Allow reusing old image_build results
JIRA: RHELCMP-5970
Signed-off-by: Haibo Lin <hlin@redhat.com>
2021-10-20 14:07:02 +08:00
Ozan Unsal
7475d2a3a9 Allow ISO-Level configuration within the config file
In order to enable this feature set "iso_level=<Value from 1 to 4>"
in config file

Jira: RHELCMP-6880

Signed-off-by: Ozan Unsal <ounsal@redhat.com>
2021-10-18 16:32:04 +02:00
Lubomír Sedlář
ac061b2ea8 Work around ODCS creating COMPOSE_ID later
When ODCS starts a compose, it will provide base composeinfo file, but
it doesn't create COMPOSE_ID. This leads to a crash when updating CTS,
since the compose id can't be read from the file. We can instead use the
value we already have in memory.

Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2021-10-04 11:32:59 +00:00
Jan Kaluza
0530cf2712 When cts_url is configured, use CTS /repo API for buildContainer yum_repourls.
Signed-off-by: Jan Kaluza <jkaluza@redhat.com>
2021-09-24 10:29:28 +02:00
Ozan Unsal
9612241396 Add COMPOSE_ID into the pungi log file
Jira: RHELCMP-6739

Signed-off-by: Ozan Unsal <ounsal@redhat.com>
2021-09-21 10:55:03 +02:00
Lubomír Sedlář
ba6f7429ee buildinstall: Add easy way to check if previous result was reused
Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2021-09-14 10:09:44 +02:00
Lubomír Sedlář
72bcee01be 4.3.0 release
JIRA: RHELCMP-6614
Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2021-09-10 11:38:11 +02:00
Lubomír Sedlář
a1ebd234a4 Only build CTS url when configured
JIRA: RHELCMP-6611
Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2021-09-10 11:29:53 +02:00
Lubomír Sedlář
5c26aa9127 Require requests_kerberos only when needed
If CTS integration is not used, let's not import a module that is not
needed.

JIRA: RHELCMP-6611
Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2021-09-10 10:00:54 +02:00
Jan Kaluza
195bfbefa4 Allow specifying $COMPOSE_ID in the repo value for osbs phase.
There should be an option for `yum_repourls` to point to static
URL, for example when CTS is used. The idea is that instead of
setting `repo` to `AppStream`, we could use link similar to this one:

`https://cts.localhost/api/1/composes/$COMPOSE_ID/repo/?variant=AppStream`

This would be translated to real static link during the OSBS phase:

`https://cts.localhost/api/1/composes/CentOS-Stream-9-20210803.0/repo/?variant=AppStream`

That way this statis link would appear in the yum_repourls.

Merges: https://pagure.io/pungi/pull-request/1543
Signed-off-by: Jan Kaluza <jkaluza@redhat.com>
2021-09-09 10:46:33 +02:00
Lubomír Sedlář
20dc4beb6b Make getting old compose config reusable
The file will only be loaded once, it gets cached afterwards.

Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2021-09-09 10:38:34 +02:00
Lubomír Sedlář
d8d1cc520b paths: Allow customizing log file extension
If the file contents is JSON, it would be nice to have matching
extension.

Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2021-09-09 10:38:34 +02:00
Ozan Unsal
904a1c3271 Add authentication for updating the compose URL in CTS.
Put authentication steps in a function in order to prevent code duplication.

Jira: RHELCMP-6318

Signed-off-by: Ozan Unsal <ounsal@redhat.com>
2021-09-09 07:27:55 +00:00
Lubomír Sedlář
e8ddacd10e Fix type detection for osbuild images
The image type value passed to the task doesn't match the type as it
will be recorded by Koji.

JIRA: RHELCMP-5727
Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2021-09-08 09:07:00 +00:00
Ozan Unsal
b7666ba4a4 Enable pungi to send compose_url patches to CTS
If cts_keytab is also enabled then the HTTP requests are handled with
Kerberos Authentication otherwise no authentication is used.

If cts_url is defined in the configuration, translate_paths is required.
This is needed in order to get the host and the path of the composes.

Jira: RHELCMP-6318

Signed-off-by: Ozan Unsal <ounsal@redhat.com>
2021-09-07 16:41:35 +02:00
Ozan Unsal
3d9335e90e Use xorriso instead of isoinfo when createiso_use_xorrisofs is enabled
Update get_mkisofs_cmd in createiso.py file in order to prevent using
default value. With this change it is possible to enable xorriso format

Jira: RHELCMP-6325

Signed-off-by: Ozan Unsal <ounsal@redhat.com>
2021-08-31 08:09:09 +00:00
Dominik Rumian
7c3e8d4276 Fix tests for createrepo
Tests for createrepo failed when pungi is installed in system.

JIRA: RHELCMP-6209

Signed-off-by: Dominik Rumian <drumian@redhat.com>
2021-08-30 13:48:29 +02:00
Dominik Rumian
9cd42a2b5e Formatted files according to flake8 and black feedback
Signed-off-by: Dominik Rumian <drumian@redhat.com>
2021-08-30 09:55:17 +02:00
Ozan Unsal
980c7ba8fb Handle the pungi failures to ensure creation of log files
If the given directory is not a valid git directory, it raises RuntimeError.
This can be catched and raised as GitUrlResolveError, so compose can continue
to log the failure.

Jira: RHELCMP-6077

Signed-off-by: Ozan Unsal <ounsal@redhat.com>
2021-08-25 11:15:23 +00:00
Haibo Lin
66dacb21e0 Add createrepo_enable_cache to configuration doc
JIRA: RHELCMP-5984
Signed-off-by: Haibo Lin <hlin@redhat.com>
2021-08-18 11:14:55 +08:00
Haibo Lin
795bbe31e3 Fix formatting
Signed-off-by: Haibo Lin <hlin@redhat.com>
2021-08-17 14:23:43 +08:00
Haibo Lin
1bb038ca72 Install missing deps in ci image
tests requiring libmodulemd are skipped due to missing deps and
this patch could fix the issue.

Signed-off-by: Haibo Lin <hlin@redhat.com>
2021-08-17 12:01:51 +08:00
Filip Valder
efff2c9504 Use pytest directly incl. support for posargs, e.g.:
tox -- -s -vvv tests/path/to/a/single/test_something.py

Signed-off-by: Filip Valder <fvalder@redhat.com>
2021-08-12 16:35:47 +02:00
Filip Valder
a7c111643d Supersede ModuleStream loading with ModuleIndex
- Use ModuleIndex's update_from_file/update_from_string instead of ModuleStream's
read_file/read_string which is deprecated.
- Extend tests to work with real module streams instead of mocks.

Signed-off-by: Filip Valder <fvalder@redhat.com>
2021-08-12 16:32:38 +02:00
Dominik Rumian
5831d4ae1e Better error message than 'KeyError' in pungi
Jira: RHELCMP-6107

Signed-off-by: Dominik Rumian <drumian@redhat.com>
2021-08-12 10:52:36 +00:00
JamesKunstle
3349585d78 Adding multithreading support for pungi/phases/image_checksum.py
Multithreading was added to parallelize the
computation of image checksums. Resulting memory structures
are protected via synchronization primitives. Max number of
threads is uncapped- experiments were done to determine
whether a maximum number of threads would yield greater
efficiency and there were no gains from this.

Likewise, experiments were done to determine whether pools of
threads computed in separate processes could likewise decrease
compute-time. Evidence did not suggest that this was the
case. This indicate that the checksum operation is bounded
by I/O read/write times.

Merges: https://pagure.io/pungi/pull-request/1520
Jira: RHELCMP-5967
Signed-off-by: James Kunstle jkunstle@redhat.com
2021-08-12 10:13:15 +02:00
Ken Dreyer
5a8df7b69c doc: more additional_packages documentation
Contrast the additional_packages setting with the comps_file setting.

Explain what happens when a user lists a package in additional_packages
but Pungi cannot find it.

Give an example of composing all builds in a Koji tag.

Signed-off-by: Ken Dreyer <kdreyer@redhat.com>
2021-08-12 07:01:49 +00:00
Ken Dreyer
6afcfef919 doc: fix typo in additional_packages description
not -> nor

Signed-off-by: Ken Dreyer <kdreyer@redhat.com>
2021-08-12 07:01:49 +00:00
Ken Dreyer
2a679dcb81 doc: improve signed packages retry docs
Reword the signed_packages_retries and signed_packages_wait
configuration option documentation to use the active voice. This makes
it easier to understand who is doing what in a signing workflow.

Signed-off-by: Ken Dreyer <kdreyer@redhat.com>
2021-08-11 14:07:12 -04:00
Dominik Rumian
8a2d0162d9 Better error message than 'KeyError' in pungi
JIRA: RHELCMP-6107

Signed-off-by: Dominik Rumian <drumian@redhat.com>
2021-08-10 07:56:47 +00:00
Ken Dreyer
01a52447bc doc: explain buildContainer API
Explain how to discover the API documentation about the buildContainer
method, so users can discover more about how "scratch" and "priority"
work.

Signed-off-by: Ken Dreyer <kdreyer@redhat.com>
2021-08-05 12:42:32 -04:00
Haibo Lin
cf761633f4 4.2.10 release
JIRA: RHELCMP-6108
Signed-off-by: Haibo Lin <hlin@redhat.com>
2021-08-04 17:23:19 +08:00
fdiprete
446334fb95 show and log command when using the run_blocking_cmd() method [RHELCMP-2243]
Signed-off-by: fdiprete <fdipretre@redhat.com>
2021-08-03 10:58:18 +00:00
Haibo Lin
56a55db966 Use cachedir when createrepo
Then createrepo can reuse checksum values from cache to make it faster.

JIRA: RHELCMP-5984
Signed-off-by: Haibo Lin <hlin@redhat.com>
2021-07-27 09:23:47 +08:00
Lubomír Sedlář
a435fd58da gather: Add all srpms to variant lookaside repo
The original code could cause a source RPM to be present in two variants
that have a dependency relation.

There is always only one source repo for a variant in the final compose.
When gathering packages for a variant that depends on another variant,
we need to build a temporary lookaside repo that has similar content to
the parent variant. This lookaside only contained source RPMs for
packages present the the architecture.

This could result in duplicated SRPMs in the compose.

Example situation:

 * Variant B depends on variant A.
 * A contains foo.x86_64.rpm (only on x86_64)
 * B pulls in subpackage foo-bar.s390x.rpm (on s390x)

Source repo for A will correctly contain foo.src.rpm. With original code
the srpm would also end up in B.src. By adding all sources to the
temporary lookaside Pungi will know that source repo for B doesn't need
to duplicate the package.

The refactoring to use a set to store the packages is meant to avoid
listing the same SRPM multiple times in the repo in the most common
situation when SRPM is listed in multiple architectures.

JIRA: RHELCMP-6002
Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2021-07-19 14:12:44 +02:00
Haibo Lin
edb091b7b1 Add task URL to watch task log
JIRA: RHELCMP-5666
Signed-off-by: Haibo Lin <hlin@redhat.com>
2021-06-29 09:10:28 +08:00
Haibo Lin
9a5e901cfe Log warning when module defined in variants.xml not found
JIRA: RHELCMP-5573
Signed-off-by: Haibo Lin <hlin@redhat.com>
2021-06-25 14:55:23 +08:00
stepan_oksanichenko
b2c49dcaf6 - The version is bumped
- The changelog is updated

@BS-NOBUILD
@BS-TARGET-CL8

Change-Id: Iadbf3d7223db85a58ba82f41597de27dbfffe1ca
2021-06-18 14:47:09 +03:00
stepan_oksanichenko
14dd6a195f LNX-326: Add the ability to include any package by mask in packages.json to the generator
- The reference packages should be replaced only by the newer reference packages
- The non-reference packages should be replaced by both of types packages

@BS-NOBUILD
@BS-TARGET-CL8

Change-Id: I881bd4e58527ae219ef6e1adbc6332b3b05933c1
2021-06-18 14:23:42 +03:00
stepan_oksanichenko
084321dd97 LNX-326: Add the ability to include any package by mask in packages.json to the generator
- The ability is added
- Also the generator includes only the latest by version packages to packages.json
- The generator has key `--is-reference` for an each repo. This key marks a repo as reference.
  An reference repo is used as main source of packages. A not reference repo is used as source
  of packages which don't exist in the reference repos.
- All cases are covered by the unittest

@BS-NOBUILD
@BS-TARGET-CL8

Change-Id: I2f80ba4fbfce27fb9a30500ae46c0b8a2f2aabcd
2021-06-15 17:42:12 +03:00
stepan_oksanichenko
941d6b064a LNX-318: Modify build scripts for building CloudLinux OS 8.4
- [Fixed] The script `create_packages_json` selects a first
          comer package from variant, but it should select the
          higher by version of package

@BS-NOBUILD
@BS-TARGET-CL8

Change-Id: I36268f2a493897fc11e787c040066d2d501a1c81
2021-06-04 12:36:03 +03:00
stepan_oksanichenko
aaeee7132d - It's bumped version
- It's added changelog

@BS-TARGET-CL8

Change-Id: I51eef1eb45ba54d034e6bed46d99b0470f4e9221
2021-05-25 21:28:47 +03:00
stepan_oksanichenko
cc4d99441c LNX-108: Add multiarch support to pungi
@BS-NOBUILD
@BS-TARGET-CL8

Change-Id: Ibfd540454941922d790ae4e56cc0992c0c85635d
2021-05-24 18:07:11 +03:00
Lubomír Sedlář
bf28e8d50c pkgset: Compare future events correctly
It is possible to try to re-run a compose with old event. When trying to
reuse pkgset data, we must use set the bounds not based on
current/reused event, but actually check which was first.

JIRA: CWFHEALTH-495
Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2021-05-12 16:17:28 +02:00
Lubomír Sedlář
7fe32ae758 util: Strip file:// from local urls
Make sure that the function returns a path even for local files
specified by file:// urls.

JIRA: RHELCMP-5340
Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2021-05-06 12:37:55 +02:00
stepan_oksanichenko
a435eeed06 - it's added changelog
@BS-NOBUILD

Change-Id: I3a0a0377f9c1cefabf52c33fbc0d19ab0e4fe4f1
2021-04-29 17:15:17 +03:00
stepan_oksanichenko
b9f554bf39 LNX-311: Add ability to productmd set a main variant while dumping TreeInfo
@BS-NOBUILD
@BS-TARGET-CL8
@BS-LINKED-608ab56299ce8ac801a396c5  # python3-productmd

Change-Id: Id86d627ae8ae0b9a73b5ce6531c20538f3d040b1
2021-04-29 17:01:49 +03:00
Haibo Lin
c27bfe0c59 Clean up temporary yumroot dir
JIRA: RHELCMP-4948
Signed-off-by: Haibo Lin <hlin@redhat.com>
2021-04-29 15:57:56 +08:00
Ondrej Nosek
76d13d0062 4.2.9 release
Signed-off-by: Ondrej Nosek <onosek@redhat.com>
2021-04-29 06:59:45 +02:00
stepan_oksanichenko
ebf028ca3b LNX-286: Prepare pungi configuration and setup Jenkins job for AlmaLinux 8.4 beta
- The modules from a parsend output of FUS should be have a stream
  with replaced dash by underscore

@BS-NOBUILD
@BS-TARGET-CL8

Change-Id: If36d3d0a1ef8010bf85a4a0218b9838e0888453c
2021-04-27 13:39:09 +03:00
stepan_oksanichenko
305103a38e LNX-286: Prepare pungi configuration and setup Jenkins job for AlmaLinux 8.4 beta
- Some modules can be absent in koji env but be present in variants.xml.
  And Pungi will fail in this case. So we must filter out those modules
  from expected modules list by list from pungi build config

@BS-NOBUILD
@BS-TARGET-CL8

Change-Id: I22c15c42868412e34fd554030130bd7c3e25b8ef
2021-04-23 13:03:05 +03:00
Romain Forlot
da791ed15c Fix can't link XDEV using repos as pkgset_sources
Trying to compose from external classic repositories return an error trying the hardling from
a yum cache directory located in /tmp to the target directory in another filesystem.
This commit fixes this using the 'link' method form linker module which handle the link_type
configuration parameter instead of the hardcoded method 'hardlink'.

Change-Id: Ib79cfbd72f9def6462fddb2ae368730c55f257cd
Signed-off-by: Romain Forlot <romain.forlot@iot.bzh>
2021-04-22 14:03:12 +02:00
stepan_oksanichenko
01bce26275 LNX-286: Prepare pungi configuration and setup Jenkins job for AlmaLinux 8.4 beta
- The script `gather_modules` should replace `-` by `_`
  in stream of modules as pungi does it in self

@BS-NOBUILD
@BS-TARGET-CL8

Change-Id: Iea05b70afbf80f3ccd20ad4943c9d86c7ed7aa90
2021-04-22 13:40:48 +03:00
Lev Veyde
00a9861367 Updated the deprecated ks argument name (to the current inst.ks)
Signed-off-by: Lev Veyde <lveyde@redhat.com>
2021-04-21 21:04:01 +03:00
Haibo Lin
e866d22c04 gather: Adjust reusing with lookaside
- Do not reuse when there is any external lookaside repo
- Do not reuse when lookaside variant is not reused

JIRA: RHELCMP-4596
Signed-off-by: Haibo Lin <hlin@redhat.com>
2021-04-16 10:37:47 +08:00
Lubomír Sedlář
ab1b5b48ec hybrid: Optimize getting lookaside packages
The original code ended up downloading all repodata from the lookaside
repo. This could cause a lot of memory to be used.

The new code only downloads the repomd.xml and then primary record,
which is sufficient to obtain all needed information. A lot less memory
is used and the code is also significantly faster.

Here are some alternative ways of getting a list of packages from the
lookaside repo and reasons why they did not work:

 * dnf repoquery - this doesn't include modular packages unless the
   stream is default
 * dnf reposync - requires `--urls` option to only print the names,
   which is not available on RHEL 7

JIRA: RHELCMP-4761
Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2021-04-15 11:02:04 +02:00
Haibo Lin
c8091899b2 gather: Copy old logs when reusing gather result
This would be helpful for debugging.

JIRA: RHELCMP-4594
Signed-off-by: Haibo Lin <hlin@redhat.com>
2021-04-01 14:42:20 +08:00
Haibo Lin
035b37c566 Cancel koji tasks when pungi terminated
JIRA: RHELCMP-4148
Signed-off-by: Haibo Lin <hlin@redhat.com>
2021-03-23 14:47:48 +08:00
Haibo Lin
edb4517e80 Add Dockerfile for building testing image
There are two images because it's hard to install both Python 2
and Python 3 packages (e.g. libcomps) in latest fedora release.

JIRA: RHELCMP-4580
Signed-off-by: Haibo Lin <hlin@redhat.com>
2021-03-15 18:13:25 +08:00
Lubomír Sedlář
535034ef91 image_container: Fix incorrect arch processing
OSBS will reject no scratch builds with arch_override.

When the option is not specified in Pungi, it would do `"".split(" ")`
to get list of arches, which returns a list with empty string instead of
an empty list.

With this fixed, it might be possible to have multiple images match the
spec (unless arch is used in the filter). To fix that, we can replace
arch with $basearch variable.

JIRA: RHELCMP-3824
Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2021-03-08 11:57:48 +01:00
Haibo Lin
2769232b72 runroot: Adjust permissions always
Previously commands to adjust permissions do not run when main
command failed and then files can't be cleaned up due to
Permission Denied problem.

JIRA: RHELCMP-4253
Signed-off-by: Haibo Lin <hlin@redhat.com>
2021-03-04 16:08:06 +08:00
Haibo Lin
b217470464 Format code
Code didn't get well formatted when jenkins unusable.

Signed-off-by: Haibo Lin <hlin@redhat.com>
2021-03-02 18:31:45 +08:00
soksanichenko
4d763514c1 - Version is bumped
- Changelog is added

Change-Id: I440b44f12c4a1aa41619acd3ba5ca354dc71b419
2021-02-24 17:42:22 +02:00
Lubomír Sedlář
735bfaa0d6 pkgset: Fix meaning of retries
The name brings a different expectation than how it actually worked.
This patch makes the code work similarly to the expectation.

Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2021-02-23 16:01:41 +01:00
Danylo Kuropiatnyk
41381df6a5 LU-2202: Start unittests during installation or build of pungi
* added section with tests and pytest module to requires
IMPORTANT - build.sh script is commented
* added pyfakefs dependency
* fixed little mock_open issue for runroot test
* bumped version

@BS-TARGET-CL8

Change-Id: I036db225646875eb610736cd26f473850a78447c
2021-02-23 07:55:36 -05:00
soksanichenko
02686d7bdf LU-2186 .treeinfo file in AlmaLinux public kickstart repo should contain AppStream variant
- We are modifying existing repo's .treeinfo:
-- Take info about included variants from iso's .treeinfo and put it to repo's .treeinfo

Change-Id: I29bf655d90994e8a1bda40ad04568dd7364f5dca
2021-02-23 06:48:15 -05:00
soksanichenko
2e48c9a56f LU-2195 Change path to sources and iso when generating repositories
- We should add the images to the compose if they will be used only as netinstall image.
  E.g. *-boot.iso.
- And we shouldn't add if the images will be modified in phase `extra_isos`.
  E.g. *-minimal.iso

Change-Id: I9095cfd87414ecca46b1213553589731c82dd2e2
2021-02-22 13:23:48 +02:00
Lubomír Sedlář
5b5069175d pkgset: Store module tag only if module is used
When a module is skipped from the compose, we should not add it to a
mapping of module tags. If it's there, we then spend time building a
repo for the module, and it get's passed to buildinstall, despite the
packages not being supposed to be included in the compose.

If the packages are not included in any variant, they shouldn't be
available to buildinstall either.

Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2021-02-22 10:21:56 +01:00
Lubomír Sedlář
477dcf37d9 Store extended traceback for gather errors
When a gathering thread raises an exception, it gets forwarded to the
main thread and re-raised there. However, during this transition it
loses details about exact location of the problem.

This patch creates an extended traceback in the worker, which should
make it easier to track the problem down later.

JIRA: RHELCMP-4259
Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2021-02-17 11:11:26 +01:00
Ondrej Nosek
98359654cf 4.2.8 release
Signed-off-by: Ondrej Nosek <onosek@redhat.com>
2021-02-12 15:20:40 +01:00
Lubomír Sedlář
64897d7d48 pkgset: Add ability to wait for signed packages
If packages are appearing quickly in Koji, and signing them is triggered
by automation, there may be a delay between the package being signed and
compose running. In such case it may be preferable to wait for the
signed copy rather than fail the compose.

JIRA: RHELCMP-3932
Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2021-02-11 15:31:14 +01:00
soksanichenko
b3a8c3f28a - Version is bumped
- Changelog is added

Change-Id: Ib1366f1fe2639037db99b8e939537bb63801058e
2021-02-11 14:50:12 +02:00
Lubomír Sedlář
40133074b3 Add image-container phase
This phase runs after image-build and osbuild and can embed an image
into a container.

JIRA: RHELCMP-3820
Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2021-02-09 14:47:57 +01:00
soksanichenko
5434d24027 LU-2133: Prepare CI for iso builds of CLOSS 8
@BS-TARGET-CL8
@BS-NOBUILD

- It's added the script which can collect packages/modules
  from the remote repos (including BS repos) and merge them
  to an one local repo with the right repodata (including
  modules.yaml.gz)
- The script `create_packages_json` can use regexps for list of excluded packages

Change-Id: I1365b712460959db6bb451d1199d640bff6ffe5e
2021-02-09 10:47:46 +02:00
Lubomír Sedlář
61e90fd7e0 osbs: Move metadata processing to standalone function
Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2021-02-08 13:23:28 +01:00
Lubomír Sedlář
36373479db Move container metadata into compose object
Rather than tracking this directly in OSBS phase, move this into Compose
object, which will allow access to this from multiple phases.

Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2021-02-08 13:23:26 +01:00
Lubomír Sedlář
44f7eff1b7 Move UnsignedPackagesError to a separate file
This file can contain all Pungi specific exceptions.

It should also fix an issue encountered on Python 2.7:

    AttributeError: 'module' object has no attribute 'pkgsets'

Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2021-02-08 10:16:32 +00:00
Haibo Lin
daa0ca6106 pkgset: Include just one version of module
When adding extra modules via option *pkgset_koji_module_builds*, all
other versions of the same stream potentially available in a Brew tag
should be skipped.

JIRA: RHELCMP-3689
Signed-off-by: Haibo Lin <hlin@redhat.com>
2021-02-02 18:16:52 +08:00
Haibo Lin
d4ee42ec23 pkgset: Check tag inheritance change before reuse
JIRA: RHELCMP-2453
Signed-off-by: Haibo Lin <hlin@redhat.com>
2021-02-01 09:22:42 +08:00
Lubomír Sedlář
49a5661521 pkgset: Remove reuse file when packages are not signed
In such case we never want to reuse the pkgset, as it risks leaking
unsigned packages. Safest option is to remove the file completely.

Fixes: https://pagure.io/pungi/issue/1480
JIRA: RHELCMP-3720
Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2021-01-29 13:06:29 +01:00
soksanichenko
3b5501b4bf LNX-133: Create a server for building nightly builds of AlmaLinux
- It's added key argument '--json-output-path' to script `pungi-generate-package-json`

Change-Id: Ic18fa2708cc4913002023828b3be018d4907de25
2021-01-28 14:03:40 +02:00
soksanichenko
cea8d92906 Bump version for setup.py
Change-Id: I980e9ebb728c3a88597c987d585e1b5937499e81
2021-01-28 00:06:40 +02:00
soksanichenko
1a29de435e - It's added changelog
- Its bumped version

Change-Id: I4c7b8d9c64da3379a24d93837657cec2686a8511
2021-01-27 23:47:39 +02:00
Lubomír Sedlář
c87fce30ac pkgset: Drop kobo.plugin usage from PkgsetSource
Relates: https://pagure.io/pungi/issue/1488
Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2021-01-27 15:55:21 +01:00
Lubomír Sedlář
0f4b0577f7 gather: Drop kobo.plugins usage from GatherMethod
Relates: https://pagure.io/pungi/issue/1488
Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2021-01-27 15:55:21 +01:00
Lubomír Sedlář
83458f26c2 pkgset: Drop kobo.plugins usage from GatherSources
Relates: https://pagure.io/pungi/issue/1488
Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2021-01-27 15:55:21 +01:00
soksanichenko
69ed7699e8 LNX-133: Create a server for building nightly builds of AlmaLinux
- It's added dependency `python3-dataclasses` to spec

Change-Id: Id6b6f33ca6621ddc1408d9ab51e278801e4dd0a2
2021-01-27 07:47:07 -05:00
Stepan Oksanichenko
103c3dc608 LNX-133: Create a server for building nightly builds of AlmaLinux
- Script `pungi-gather-modules` can find valid *modules.yaml.gz in the repo dirs by itself

@BS-LINKED-5ffda6156f44affc6c5ea239  # pungi & dependencies
@BS-TARGET-CL8

Change-Id: I3cddc0cf41ea1087183e23de39126a52c69bc9ac
2021-01-25 16:17:35 +02:00
Stepan Oksanichenko
94ad7603b8 LNX-104: Create gather_prepopulate file generator for Pungi
- It's added the tool which can generate json like as `centos-packages.json` using repodata from completed repos.

@BS-LINKED-5ffda6156f44affc6c5ea239  # pungi & dependencies
@BS-TARGET-CL8

Change-Id: Ib0466a1d8e06feb855e81fb7160fe170e2e82e04
2021-01-25 16:17:34 +02:00
oshyshatskyi
903db91c0f LNX-102: Patch pungi tool to use local koji mock
Instead of koji.mbox use local koji-like wrapper.

@BS-LINKED-5ff8b8cb6f44affc6c5e9a7a
@BS-TARGET-CL8

Change-Id: I82a2bc8bc71ae06240656898f3df71bb28bcb9e9
2021-01-25 16:17:33 +02:00
oshyshatskyi
552343fffe LNX-102: Add tool that gathers directory for all rpms
Tool that finds all available rpm files in directory
and creates special tree for pungi:
 # ls /mnt/koji/
   i686/  noarch/  x86_64/

Change-Id: Ibcf2d23c46411ad89477058f4d56e07ca117f0d1
2021-01-25 16:17:33 +02:00
oshyshatskyi
5806217041 LNX-102: Add tool that collects information about modules
Add special tool that gathers given modules.tar.gz files
and collects information about modules into two dirs:
 - module_defaults
 - modules

 First one is used by pungi during repocreate phase and
 the second one is used by koji mock to get list of
 available modules and their versions.

Change-Id: I50a095a5f3bafa7e7a1effc2c0d4a2fc52ba603b
2021-01-25 16:17:33 +02:00
67eacf8483 LNX-103 Update .spec file for AlmaLinux
New binaries added to pungi rpm:
pungi-gather-rpms
pungi-gather-modules

Change-Id: Idb25dffb10d50fa9f566c99d714d32df962b6f52
2021-01-25 16:17:32 +02:00
Ken Dreyer
38789d07ee doc: remove default createrepo_checksum value from example
createrepo_checksum already defaults to sha256. Remove this setting from
the documented Minimal Example configuration to make it easier to read.

Signed-off-by: Ken Dreyer <kdreyer@redhat.com>
(cherry picked from commit 39b847094a)
2021-01-25 14:06:34 +02:00
Lubomír Sedlář
3735aaa443 comps: Preserve default arg on groupid
When the wrapper processes comps file, it wasn't emitting "default"
argument for groupid element. The default is false and most entries are
actually using the default, so let's only emit it if set to true.

Fixes: https://bugzilla.redhat.com/show_bug.cgi?id=1882358
Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
(cherry picked from commit 9ea1098eae)
2021-01-25 14:06:33 +02:00
Haibo Lin
2c1603c414 Stop copying .git directory with module defaults
JIRA: RHELCMP-3016
Fixes: https://pagure.io/pungi/issue/1464

Signed-off-by: Haibo Lin <hlin@redhat.com>
(cherry picked from commit f518c1bb7c)
2021-01-25 14:06:33 +02:00
Haibo Lin
f2fd10b0ab React to SIGINT signal
ODCS sends SIGINT signal.

JIRA: RHELCMP-3687
Signed-off-by: Haibo Lin <hlin@redhat.com>
(cherry picked from commit f470599f6c)
2021-01-25 14:06:33 +02:00
Ken Dreyer
39b847094a doc: remove default createrepo_checksum value from example
createrepo_checksum already defaults to sha256. Remove this setting from
the documented Minimal Example configuration to make it easier to read.

Signed-off-by: Ken Dreyer <kdreyer@redhat.com>
2021-01-25 08:22:17 +00:00
Lubomír Sedlář
9ea1098eae comps: Preserve default arg on groupid
When the wrapper processes comps file, it wasn't emitting "default"
argument for groupid element. The default is false and most entries are
actually using the default, so let's only emit it if set to true.

Fixes: https://bugzilla.redhat.com/show_bug.cgi?id=1882358
Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2021-01-22 08:33:09 +01:00
Haibo Lin
f518c1bb7c Stop copying .git directory with module defaults
JIRA: RHELCMP-3016
Fixes: https://pagure.io/pungi/issue/1464

Signed-off-by: Haibo Lin <hlin@redhat.com>
2021-01-14 10:36:38 +08:00
Haibo Lin
f470599f6c React to SIGINT signal
ODCS sends SIGINT signal.

JIRA: RHELCMP-3687
Signed-off-by: Haibo Lin <hlin@redhat.com>
2021-01-11 10:02:10 +08:00
Sergey Fokin
ac601ab8ea change Source0 in spec file 2021-01-08 13:30:17 +03:00
oshyshatskyi
757a6ed653 Revert unneeded commit to match upstream sources
This reverts commit b2e439e5

Change-Id: Ia6706415039681a6fe7b5ec6a735c3bda66d6bb1
2020-12-30 13:58:06 +02:00
Oleksandr Shyshatskyi
b2e439e561 current 2020-12-29 10:44:49 +02:00
Lubomír Sedlář
cda67776d9 scm: Only copy debugging data if we have a compose
If we don't have a compose, this copy will fail. Let's prevent that.

Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2020-12-08 08:57:06 +01:00
Lubomír Sedlář
62a97c0e1b 4.2.7 release
Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2020-12-03 14:33:22 +01:00
Lubomír Sedlář
98ddc74c16 osbuild: Fix not failing on failable tasks
The task can only fail as a whole, thus it only makes sense to set all
architectures (`*`) as failable. The correct value needs to be checked
though.

JIRA: RHELCMP-3412
Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2020-12-02 14:30:20 +01:00
Lubomír Sedlář
4a048d4a85 kojiwrapper: Use gssapi_login
The krb_login method is deprecated and will be removed in 1.22

JIRA: RHELCMP-3383
Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2020-12-02 14:21:31 +01:00
Christian Kellner
6998ffe694 osbuild: use task result to get build info
Instead of parsing the log file to get the NVR and then in turn
use that to get to the build info use the structured return value
from the koji task. The return value of the osbuild plugin is:
    result = {
        "composer": {
            "server": <COMPOSER_URL>,
            "id": <COMPOSE_ID>
        },
        "koji": {
            "build": <BUILD_ID>
        }
    }
This means we have direct access to the koji build id, which was
returned by composer to the plugin via its status API. Using that
removes the need to parse the log file.

Adapt the test accordingly.

Merges: https://pagure.io/pungi/pull-request/1475
Signed-off-by: Christian Kellner <christian@kellner.me>
2020-11-30 09:57:48 +01:00
Lubomír Sedlář
9accf5ecf4 docs: Add osbuild phase to overview diagram
Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2020-11-27 09:56:10 +01:00
Lubomír Sedlář
e7af6d2ac2 osbuild: Only send release when not empty
Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2020-11-25 15:37:49 +01:00
Lubomír Sedlář
27bab19a5e Fix config validation for osbuild
Tests are now added for it as well.

Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2020-11-25 14:14:18 +01:00
Haibo Lin
4c88e7dc0e Use xorrisofs for creating ISOs when needed
A new configuration *createiso_use_xorrisofs* is added to determine
which tool to use for creating ISOs.

By default, createiso_use_xorrisofs = False and genisoimage will be used.
When set to True, xorrisofs will be used.

JIRA: RHELCMP-2875
Fixes: https://pagure.io/pungi/issue/1130

Signed-off-by: Haibo Lin <hlin@redhat.com>
2020-11-20 09:47:49 +08:00
Jan Kaluza
c27e21ccf8 Add --respin-of argument.
It is used to defined the relation between original compose
and respun compose with a hotfix in CTS.

Signed-off-by: Jan Kaluza <jkaluza@redhat.com>
2020-11-19 12:26:38 +00:00
Lubomír Sedlář
e3a500ca50 Fix typo in configuration
Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2020-11-16 10:50:01 +01:00
Jan Kaluza
4562fba459 Optimize link_files by creating temporary dict mapping path to pkg_obj.
Previously, the pkg_object has been found by iterating over pkg_sets
for each package. This was quite slow given the number of RPMs in the
compose.

In this commit, the temporary dict is created which stores mapping
between path and pkg_obj and is used instead.

In this commit, the get_package_path is called just once instead of
twice in the loop which might also save some time.

Signed-off-by: Jan Kaluza <jkaluza@redhat.com>
2020-11-11 12:20:01 +00:00
Jan Kaluza
bb8cd030ec Try reuse old gather_phase even if pkgset_koji_builds changed.
The pkgset_koji_builds influences the gather phase, but the
change itself is not a reason to not reuse old gather phase. if
new pkgset_koji_builds value leads to significant change in input
package set, we will find that later in this function when comparing
old and new package set.

Signed-off-by: Jan Kaluza <jkaluza@redhat.com>
2020-11-10 12:52:02 +01:00
Jan Kaluza
94bc5e286d Do not use shlex_quote in get_pungi_buildinstall_cmd and get_pungi_ostree_cmd.
These methods return command as list which is never serialized to str and
never executed using bash. It is instead passed directly to
`kobo.shortcuts.run`.

The `shlex_quote` usage here actually breaks the code, because it adds
quotes there which are needed only if this command would be serialized
to string and passed to bash. But this never happens. As a result,
the arguments passed to `kobo.shortcuts.run` contain those extra
quotes.

In this commit the shlex_quote is removed completely from this
part of code.

Signed-off-by: Jan Kaluza <jkaluza@redhat.com>
2020-11-10 07:45:05 +00:00
Lubomír Sedlář
295a60a704 gather: Fix test for module presence
When testing if a variant has some modules,
it's no longer enough to look at `variant.modules`. That attribute
contains only names of modules configured in variants.xml.

With modules being specified in `pkgset_koji_module_builds` or
`pkgset_scratch_modules` options it is possible the code wouldn't
trigger even if there was a module.

JIRA: RHELCMP-3054
Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2020-11-09 09:33:03 +00:00
Lubomír Sedlář
99c1e2eb5e Kill all subprocess in signal handler
When Pungi receives a signal to terminate, it can sometimes get stuck
if there are threads running. It has to wait for all worker threads to
finish. They generally do finish, unless they get stuck waiting on a
subprocess.

This patch should reduce the likelihood of this happening by stopping
all subprocesses.

JIRA: RHELCMP-3056
Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2020-11-09 08:45:57 +01:00
Bohdan Khomutskyi
4c4c816e70 Pungi 4.2.6 release
Signed-off-by: Bohdan Khomutskyi <bkhomuts@redhat.com>
2020-11-04 12:33:06 +00:00
Lubomír Sedlář
a45f4969f3 Add phase for building images with osbuild
This is similar to image-build in terms of what it does, and somewhat
similar to OSBS phase in how it's implemented.

The phase reads configuration, submits the build via XMLRPC call and
waits for the task to finish. Then it downloads the built image and
includes it in the compose metadata.

JIRA: RHELCMP-315
Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2020-11-04 13:04:43 +01:00
Jan Kaluza
609a555597 Allow setting int arguments for pungi-buildinstall plugin.
Signed-off-by: Jan Kaluza <jkaluza@redhat.com>
2020-11-02 12:14:14 +00:00
Jan Kaluza
d1eac95cda Use shlex_quote for complete --foo=bar argument.
Without that, the resulting string is `--foo="'bar'"`
which results in `'bar'` being passed to Koji task.

With this commit, the resulting string is `"'--foo=bar'"`
which results in `bar` being passed to Koji which is expected.

Signed-off-by: Jan Kaluza <jkaluza@redhat.com>
2020-10-29 16:17:21 +01:00
Haibo Lin
4c297beb65 Include images info in composeinfo.json
This change requires https://github.com/release-engineering/productmd/pull/150

JIRA: RHELCMP-2296
Signed-off-by: Haibo Lin <hlin@redhat.com>
2020-10-14 17:57:30 +08:00
Lubomír Sedlář
f27b120cfc tests: Fix mock usage for Python 2
The `args` attribute doesn't work, let's instead access the arguments
via index.

Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2020-09-25 12:41:05 +02:00
Lubomír Sedlář
9df3f42a44 Fix typo in config validation
Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2020-09-25 09:29:25 +00:00
Lubomír Sedlář
327019264f 4.2.5 release
Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2020-09-25 09:52:31 +02:00
Jan Kaluza
1595e188a9 Allow setting --development compose_type.
This is related to https://github.com/release-engineering/productmd/pull/149.

Signed-off-by: Jan Kaluza <jkaluza@redhat.com>
2020-09-25 07:31:20 +02:00
Haibo Lin
866b881072 Make sure old pkgset arch repo exists when reuing
JIRA: RHELCMP-2482
Fixes: https://pagure.io/pungi/issue/1424

Signed-off-by: Haibo Lin <hlin@redhat.com>
2020-09-24 10:43:35 +08:00
Jan Kaluza
4623536b24 Fix wrong condition when reusing old gather phase results.
When list is used in gather_lookaside_repos, the Pungi currently
fails with an exception. This is caused by inverted condition
in the code which tries to filter-out the lookaside repos
generated during the Pungin execution pointing to different
compose variants.

Signed-off-by: Jan Kaluza <jkaluza@redhat.com>
2020-09-23 07:02:11 +00:00
Haibo Lin
27a825de48 pkgset: Allow to include extra module builds
Signed-off-by: Haibo Lin <hlin@redhat.com>
2020-09-22 13:22:56 +08:00
Jiri Konecny
fdb2449c0e
Adapt tests to new patch-iso --work-dir parameter
Signed-off-by: Jiri Konecny <jkonecny@redhat.com>
2020-09-15 16:07:18 +02:00
Jiri Konecny
59727f84b1
Support change of the patch-iso temp dir
This is useful when running pungi-patch-iso on VM with low amount of
memory but higher disk space. Without this option the operation will
fail because /tmp is tmpfs filesystem.

Signed-off-by: Jiri Konecny <jkonecny@redhat.com>
2020-09-15 15:47:16 +02:00
Lubomír Sedlář
22efe15379 pkgset: Handle exceptions in pkgset threads
There are two thread pools for making package sets. If Pungi is being
terminated by external event and the exception is handled in the first
thread, the second one never gets to the `stop` method and the process
keeps hanging.

This patch should make sure that `stop()` is called on both pools.

JIRA: RHELCMP-2459
Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2020-09-15 09:55:32 +02:00
Haibo Lin
b3a55fd863 gitwrapper: Re-run git init before do full clone
Sometimes full clone failed with error fatal: Not a git repository
and we found that .git/refs/ dir is missing after shallow clone failed.

JIRA: RHELCMP-724
Signed-off-by: Haibo Lin <hlin@redhat.com>
2020-09-10 10:09:46 +08:00
Lubomír Sedlář
c6312b34d0 doc: Improve description of module defaults dir
JIRA: RHELCMP-812
Resolves: https://pagure.io/pungi/issue/1394
Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2020-09-08 07:31:38 +00:00
Lubomír Sedlář
e12331db78 util: Refactor retry function
When running a Bodhi update, somehow the raise condition was triggered
before any exception was raised, which caused the compose to fail.

This shouldn't really happen often, but it's possible if the machine
adjusts time for any reason (e.g. DST).

This commit moves the check for timeout after the function is called.
This can cause an extra invocation of the function, which shouldn't be a
huge deal really.

Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2020-09-01 12:41:06 +00:00
Haibo Lin
160fc4f7df createrepo: Ignore error when cleaning up tmp dir
JIRA: RHELCMP-998
Signed-off-by: Haibo Lin <hlin@redhat.com>
2020-09-01 18:27:00 +08:00
Lubomír Sedlář
a6a96e40db Preserve environment when running koji commands
JIRA: RHELBLD-2479
Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2020-08-25 09:07:28 +02:00
Lubomír Sedlář
e628bb91ec Fix formatting
Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2020-08-20 15:15:13 +02:00
Jiri Konecny
40bbb4325a Adapt tests to a new get_graft_points() argument
Signed-off-by: Jiri Konecny <jkonecny@redhat.com>
2020-08-20 15:15:13 +02:00
Jiri Konecny
8d4fea7890 Fix pungi-patch-iso to work with a new compose top dir solution
get_graft_points has changed but without adapting pungi-patch-iso utility so the
exception was raised when executed.

Fixes: https://pagure.io/pungi/issue/1438
Signed-off-by: Jiri Konecny <jkonecny@redhat.com>
2020-08-20 15:15:02 +02:00
Jiri Konecny
981b69c699 Don't use compose in get_graft_points
Not all usage of the get_graft_points have access to the compose object.

Signed-off-by: Jiri Konecny <jkonecny@redhat.com>
2020-08-20 15:06:49 +02:00
Lubomír Sedlář
b557bf160f Fall back to rpm2cpio
JIRA: RHELCMP-2030
Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2020-08-20 10:19:17 +02:00
Haibo Lin
1e1c8533ac tests: Fix tests for old version of git
GitSCMTestCaseReal failed with error 'Unknown option: -C' when building
rpm for el7.

Signed-off-by: Haibo Lin <hlin@redhat.com>
2020-08-18 12:38:20 +08:00
Haibo Lin
29761d1656 4.2.4 release
Signed-off-by: Haibo Lin <hlin@redhat.com>
2020-08-17 09:19:10 +08:00
Jan Kaluza
2657a12c96 Allow setting CTS parent_compose_ids using --parent-compose-id option.
This is needed to track dependencies between composes in the Compose
Tracking Service.

Signed-off-by: Jan Kaluza <jkaluza@redhat.com>
2020-08-13 13:22:43 +02:00
Bohdan Khomutskyi
7a6d8303dc Replace -c parameter with --config
Also, reformat the invocation of Lorax, since
Lorax does not accept -c=%s, only -c %s.

Jira: RHELCMP-713
Signed-off-by: Bohdan Khomutskyi <bkhomuts@redhat.com>
2020-08-13 11:16:43 +02:00
Haibo Lin
c273350fe5 doc: Update doc/contributing.rst
JIRA: RHELCMP-1773
Signed-off-by: Haibo Lin <hlin@redhat.com>
2020-08-11 20:36:22 +08:00
Haibo Lin
4dcb6dee0d Use requirements.txt
JIRA: RHELCMP-1773
Signed-off-by: Haibo Lin <hlin@redhat.com>
2020-08-11 20:36:22 +08:00
Bohdan Khomutskyi
b899126b7e Allow squashfs-only and configuration_file in lorax_options
The change allows for setting the parameters as described below to Lorax.
Lorax, a program called during the buildInstall phase, creates the SquashFS
during the buildInstall phase.
The Squash filesystem is present both on the DVD and the BOOT.ISO.

squashfs_only --- (str) passes --squashfs-only option.
configuration_file --- (str or scm_dict) passes -c option to Lorax.

The final goal of this change is to allow for optimization of
the installation medium size.

This pull request is related to the Fedora change proposal, which is available
at this location:
https://fedoraproject.org/wiki/Category:Changes/OptimizeSquashFS
See the change proposal for more information about the benefits of higher
compression ratio.

Jira: RHELCMP-693
Signed-off-by: Bohdan Khomutskyi <bkhomuts@redhat.com>
2020-08-11 09:29:50 +00:00
Haibo Lin
9920aa7a74 Hardlink or copy scratch builds always
JIRA: RHELCMP-1566
Signed-off-by: Haibo Lin <hlin@redhat.com>
2020-08-07 18:00:19 +08:00
Lubomír Sedlář
a294a05726 Retry ostree installer task on losetup error
This uses a previous change that added ability to retry and simply
extends the conditions when it fires.

JIRA: RHELCMP-1863
Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2020-08-05 10:58:04 +02:00
Haibo Lin
3c72755814 Use pytest instead of nosetests
Nose has been in maintenance mode for the past several years
and pytest is a good replacement.

Other changes:
- Replace deprecated assertRegexpMatches with assertRegex
- Replace deprecated assertRaisesRegexp with assertRaisesRegex
- Replace deprecated SafeConfigParser with ConfigParser
- Force reinstall pytest and mock in tox virtualenv. This is because
  the globally installed packages may not work as expected(occured in
  jenkins job).

JIRA: RHELCMP-1619
Signed-off-by: Haibo Lin <hlin@redhat.com>
2020-07-29 14:57:16 +08:00
Haibo Lin
495a4c48b2 Run tests via tox
This could simplify jenkins job configuration and make the tasks
trackable in git.

JIRA: RHELCMP-1618
Signed-off-by: Haibo Lin <hlin@redhat.com>
2020-07-27 13:28:32 +08:00
Haibo Lin
05a5e2b1f0 Make sure old_repo_dir for reusing exists
Fixes: https://pagure.io/pungi/issue/1424
JIRA: RHELCMP-1519
Signed-off-by: Haibo Lin <hlin@redhat.com>
2020-07-22 15:11:25 +08:00
Haibo Lin
7e6bed9713 Retry buildinstall tasks on losetup error
JIRA: RHELCMP-1394
Signed-off-by: Haibo Lin <hlin@redhat.com>
2020-07-21 17:15:25 +08:00
Haibo Lin
f7167fa3b6 Allow including scratch module builds
JIRA: RHELCMP-439
Signed-off-by: Haibo Lin <hlin@redhat.com>
2020-07-17 09:08:36 +08:00
Lubomír Sedlář
f5e33950c1 Unpack RPMs using rpm2archive
This should support both older files compressed with cpio as well as
newer zstd-compressed files.

Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2020-07-09 07:25:17 +00:00
Lubomír Sedlář
7d00942d13 Allow test calls in any order
There are threads involved and the order is undefined. We need to accept
any order.

Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2020-07-08 08:26:59 +02:00
Haibo Lin
0ab6f48de3 Create arch repo when reusing failed
Reusing old arch repo may fail for reasons such as arch not
available in old compose or unexpected error when copying data
from old compose.

JIRA: RHELCMP-994
Signed-off-by: Haibo Lin <hlin@redhat.com>
2020-07-07 17:59:12 +08:00
Haibo Lin
b193fa0ab7 createiso: Ignore errors when deleting staging dir
JIRA: RHELCMP-975
Signed-off-by: Haibo Lin <hlin@redhat.com>
2020-07-07 16:32:10 +08:00
Ondrej Nosek
d9f111edae Remove buffering when running koji commands
If the compose is aborted while koji tasks are running, we can be
left with empty log files. That complicates debugging.

JIRA: RHELCMP-1218

Signed-off-by: Ondrej Nosek <onosek@redhat.com>
2020-07-02 09:45:46 +02:00
Lubomír Sedlář
54882a0fc4 Fix typos
Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2020-06-24 14:16:42 +02:00
Jan Kaluza
b6573fab92 Check if composeinfo-base.json exists before creating it.
Previously, we checked only for `compose_dir`, but it makes
more sense to really check for `composeinfo-base.json` instead.

Signed-off-by: Jan Kaluza <jkaluza@redhat.com>
2020-06-23 15:27:53 +02:00
Pierre-Yves Chibon
658a5f805f Port scripts/wait_for_signed_ostree_handler.py to fedora-messaging
Signed-off-by: Pierre-Yves Chibon <pingou@pingoured.fr>
2020-06-17 23:28:27 +02:00
Pierre-Yves Chibon
ad1a3360bc Port scripts/fedmsg_notification.py to fedora-messaging
This commit also adds a --config argument allowing to
override/specify a specific fedora-messaging configuration
file to use.

Signed-off-by: Pierre-Yves Chibon <pingou@pingoured.fr>
2020-06-17 10:11:39 +02:00
Haibo Lin
b6605827b3 buildinstall: Improve error reporting when lorax fails
Logs of DepsolveError will be printed in the main log.

Fixes: https://pagure.io/pungi/issue/1399
JIRA: RHELCMP-955
Signed-off-by: Haibo Lin <hlin@redhat.com>
2020-06-17 13:17:22 +08:00
Lubomír Sedlář
634d30fac5 4.2.3 release
Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2020-06-11 14:17:49 +02:00
Jan Kaluza
e35c250700 Move test for unsigned packages with pkgset_koji_scratch_tasks to PkgsetPhase class.
Signed-off-by: Jan Kaluza <jkaluza@redhat.com>
2020-06-11 12:05:47 +00:00
Jan Kaluza
4a15d1351a Allow building compose with scratch builds defined by pkgset_koji_scratch_tasks.
Signed-off-by: Jan Kaluza <jkaluza@redhat.com>
2020-06-11 12:05:47 +00:00
Lubomír Sedlář
b59bdcea92 createrepo: Allow making productid glob stricter
This patch updates the documentation to match the actual behavior, and
adds a configuration option to remove the leading prefix.

The extra wildcard is causing problems when there are two variants in
the compose and one UID is a suffix of the other (e.g. DevTools and
Tools), since multiple files will match the shorter name and an error
will be reported.

JIRA: RHELCMP-1086
Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2020-06-11 10:36:37 +02:00
Lubomír Sedlář
649ff095c0 docs: Remove outdated note
Fixes: https://pagure.io/pungi/issue/1396
JIRA: RHELCMP-850
Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2020-06-10 14:01:42 +02:00
Lubomír Sedlář
3bb1e3df11 createrepo: Add extra modulemd files to the repo
This is a workaround for modularity design issues and DNF bugs. If there
were gaps in contexts, DNF has trouble handling the upgrades. Thus we
may need to add module metadata for older versions of previously
released module streams and add the missing contexts.

JIRA: RHELCMP-982
Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2020-06-10 09:50:44 +02:00
Haibo Lin
6ac12af343 pkgset: handle exception when using dogpile cache
JIRA: RHELCMP-562
Signed-off-by: Haibo Lin <hlin@redhat.com>
2020-06-10 13:35:12 +08:00
Haibo Lin
f5bfd509ab notification: Add compose_path into the messages
It's needed by the notification script added in RHELCMP-401.

Signed-off-by: Haibo Lin <hlin@redhat.com>
2020-06-09 06:40:26 +00:00
Frédéric Pierret (fepitre)
b973657197 gather: handle mirrorlist in kickstart
Merges: https://pagure.io/pungi/pull-request/1406
Signed-off-by: Frédéric Pierret (fepitre) <frederic.pierret@qubes-os.org>
2020-06-09 08:34:58 +02:00
Haibo Lin
0196d7fd00 Allow only creating unified ISO for specified arch
Fixes: https://pagure.io/pungi/issue/1393
JIRA: RHELCMP-807
Signed-off-by: Haibo Lin <hlin@redhat.com>
2020-06-09 09:47:12 +08:00
Haibo Lin
ffb65e8770 docs: update doc for gather_lookaside_repos option
JIRA: RHELCMP-566
Signed-off-by: Haibo Lin <hlin@redhat.com>
2020-06-02 14:41:56 +08:00
Haibo Lin
7c2743fb50 Include the output of getisoimage in the error message
JIRA: RHELCMP-720
Signed-off-by: Haibo Lin <hlin@redhat.com>
2020-06-01 13:29:55 +08:00
Lubomír Sedlář
d6caf0785b tests: Patch time in CTS related tests
The value must be fixed to match the expected JSON.

Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2020-05-29 10:24:17 +02:00
Jan Kaluza
b8c3ca1abe Allow using Pungi Koji plugin for ostree phases.
This commits changes `ostree` and `ostree_installer` phases
so they can run with Koji Pungi plugin instead of the plain runroot.

It is similar to `buildinstall` phase running with Koji plugin.

Signed-off-by: Jan Kaluza <jkaluza@redhat.com>
2020-05-26 13:23:58 +00:00
Jan Kaluza
f1eea0b5a6 Allow getting the compose id from CTS (Compose Tracking Service).
Signed-off-by: Jan Kaluza <jkaluza@redhat.com>
2020-05-26 13:18:38 +00:00
Lubomír Sedlář
59e2aa9607 Fix flake8 issues
Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2020-05-26 11:49:50 +02:00
Bohdan Khomutskyi
694b7f3d28 Optimize the _link_file function to not call os.stat redundantly.
This will eliminate 2 calls to os.stat per one invocation of the _link_file function.
Assuming during the compose build 50000 files are linked, this change will eliminate 100000 redundant calls to os.stat.

Jira: RHELCMP-797
Signed-off-by: Bohdan Khomutskyi <bkhomuts@redhat.com>
2020-05-21 10:13:28 +02:00
Ken Dreyer
4ba65710c2 doc: explain sigkey behavior
Explain how Pungi operates on the sigkeys list, and what happens when
there is only one item in the list.

Signed-off-by: Ken Dreyer <kdreyer@redhat.com>
2020-05-18 15:42:37 -06:00
Ken Dreyer
5ed5646bca doc: explain tradeoffs with pkgset_allow_reuse
Explain why someone would want to enable or disable the
pkgset_allow_reuse option.

Signed-off-by: Ken Dreyer <kdreyer@redhat.com>
2020-05-15 12:56:46 -06:00
Ken Dreyer
d3acb0fa9e doc: fix grammar for pkgset_allow_reuse setting
Signed-off-by: Ken Dreyer <kdreyer@redhat.com>
2020-05-15 12:56:37 -06:00
Haibo Lin
d4efe17328 Support --skip-branding option in lorax
JIRA: RHELCMP-572
Signed-off-by: Haibo Lin <hlin@redhat.com>
2020-05-14 11:49:40 +08:00
Haibo Lin
fe4b2dd302 docs: Embed phases.svg directly
Signed-off-by: Haibo Lin <hlin@redhat.com>
2020-05-08 17:44:27 +08:00
Haibo Lin
20ba1a7639 Execute image_checksum phase right after the dependent phases
JIRA: RHELCMP-468
Signed-off-by: Haibo Lin <hlin@redhat.com>
2020-05-08 16:12:30 +08:00
Haibo Lin
5d9dcf61fb 4.2.2 release
Signed-off-by: Haibo Lin <hlin@redhat.com>
2020-04-29 19:25:59 +08:00
Lubomír Sedlář
9fced77140 scm: Workaround incorrect permissions on created directory
We have seen the directory created with wrong permissions. Since we
haven't been able to find out why it happens this is a workaround.

JIRA: RHELCMP-142
Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2020-04-29 09:51:53 +02:00
Lubomír Sedlář
9a1b9dd154 Fix warning about productimg in skip_phases option
If phase is skipped in a config option (and not on command line), we
should just print a warning or do nothing in quiet mode.

JIRA: RHELCMP-399
Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2020-04-28 07:51:40 +00:00
Haibo Lin
0525768519 Add pkgset_allow_reuse option
JIRA: RHELCMP-492
Signed-off-by: Haibo Lin <hlin@redhat.com>
2020-04-28 09:54:36 +08:00
Haibo Lin
153eb628e8 Delete outdated comments
JIRA: RHELCMP-395
Signed-off-by: Haibo Lin <hlin@redhat.com>
2020-04-22 17:14:51 +08:00
Lubomír Sedlář
f7944a406e gather: Fix nodeps method to not prefix match
If the input packages contain e.g. `ansible`, and there's
`ansible-runner-service` in the package set, we don't want to pull it
in.

JIRA: RHELCMP-446
Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2020-04-21 09:58:00 +02:00
Lubomír Sedlář
1a5cd9e0bf linker: Remove check after copying file
After a file is copied, a check was done if size and mtime of the files
match.

This has very few benefits in what problems it can detect, and can cause
problems on NFS where it can take a short time before the updated
attributes are visible on the new location.

JIRA: RHELCMP-378
Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2020-04-20 14:52:00 +02:00
Haibo Lin
30f4771db1 Stop creating iso_stage_dir before deleting
It's unreasonable to create the dir and then delete it immediately.

JIRA: RHELCMP-151
Signed-off-by: Haibo Lin <hlin@redhat.com>
2020-04-20 18:10:58 +08:00
Jan Kaluza
5395af416c Allow reusing old buildinstall phase results.
New `buildinstall.metadata` file is created once the buildinstall
phase is done. This file contains:

- list of lorax command line arguments.
- list of RPMs installed in the buildinstall buildroot.
- list of RPMs installed in the resulting boot.iso.

This file is checked in the next compose run to find out if
the result of buildinstall phase from the previous compose
can be reused. Following is checked:

- lorax commandline arguments are the same (except of expected
  differences).
- The NVRAs of RPMs in the runroot_tag are the same as the ones
  installed in the old buildinstall buildroot.
- The NVRAs of RPMs installed in the boot.iso are the same as
  the ones in package sets in the current compose.

By its implementation, this reuse strategy is used only if
pungi_buildinstall Koji plugin is used.

Signed-off-by: Jan Kaluza <jkaluza@redhat.com>

Add tests for buildinstall reuse and buildinstall_allow_reuse option.

Signed-off-by: Jan Kaluza <jkaluza@redhat.com>
2020-04-17 11:37:13 +00:00
Dusty Mabe
3509d7a36c ostree: set umask to be more permissive for ostree operations
We need to set the umask to be more permissive so directories get group
write permissions. See https://pagure.io/releng/issue/8811#comment-629051.

Signed-off-by: Dusty Mabe <dusty@dustymabe.com>
Merges: https://pagure.io/pungi/pull-request/1373
2020-04-17 09:20:24 +02:00
Haibo Lin
477b43d4e9 Split repoclosure into separate phase
Move repoclosure out from test phase into its own phase and
run parallel with image building phases(osbs, imagebuild, ...)
to speed things up.

JIRA: RHELCMP-8
Signed-off-by: Haibo Lin <hlin@redhat.com>
2020-04-14 09:25:57 +08:00
Lubomír Sedlář
e187b5ea79 Break too long line
Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2020-04-06 14:20:47 +02:00
Buvanesh Kumar
4cf11906e8 RCM-79601: Increase time delay in race condition
Signed-off-by: Buvanesh Kumar <bsivasub@redhat.com>
2020-04-06 08:15:57 -04:00
Jan Kaluza
fdfaae8b71 Allow gather phase reuse on product_id change.
I've analysed multiple nigthly composes and often the only difference
in the configuration between two nightly composes is different
`product_id` commit hash.

The `product_id` is used in later `createrepo` phase and does not
influence the gather phase at all. I therefore think it can be
whitelisted in gather phase reuse code.

Signed-off-by: Jan Kaluza <jkaluza@redhat.com>
2020-04-06 08:23:19 +00:00
Haibo Lin
c5e59fa732 Gather more debug data for GitWrapper clone
GitWrapper._clone crashes occasionally but unfortunately
the root cause is not found yet. We need more info for debugging.

JIRA: COMPOSE-4219
Signed-off-by: Haibo Lin <hlin@redhat.com>
2020-04-03 17:08:51 +08:00
Haibo Lin
65251d983a Reuse arch pkgset repos
JIRA: COMPOSE-4217
Signed-off-by: Haibo Lin <hlin@redhat.com>
2020-03-31 13:32:12 +08:00
Haibo Lin
63ec1adc22 Get non-rpm build to pungi's extra_files with inheritance
JIRA: COMPOSE-4214
Signed-off-by: Haibo Lin <hlin@redhat.com>
2020-03-20 13:19:57 +08:00
Lubomír Sedlář
4a78514162 util: Fix regex for detecting debuginfo packages
The `re.match` function already anchors the pattern at the start of the
string, but allows for other characters to continue after match.

This is causing problems with packages like `elfutils-debuginfod-client`
which are not debuginfo.

Let's be safe and explicitly anchor both start and end.

Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2020-03-16 11:13:02 +01:00
Lubomír Sedlář
4efdacd0a0 4.2.1 release
Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2020-03-13 12:55:44 +01:00
Jan Kaluza
a209bda73c Create MaterializedPackageSets in threads to make pkgset faster.
When modules are used, there are lot of small package sets. These
package sets have usually less than 500 packages. The createrepo
part of `MaterializedPackageSet.create` executed for such small
set of packages takes around 1 second. Most of this time
the createrepo_c runs in single thread. It does the initialization,
it writes the XML files, ...

The parts of createrepo which can be run in parallel and therefore
would use all the CPUs are quite small for very small package sets.

This commit therefore executes multiple threads with
`MaterializedPackageSet.create` for these very small package sets.

This saves around 40 seconds from pkgset phase for RHEL compose.

Signed-off-by: Jan Kaluza <jkaluza@redhat.com>
2020-03-13 12:51:02 +01:00
Lon Hohberger
9391ce3065 pungi-koji: Allow user to specify version component count in latest symlink
This change adds an option which allows users to specify
the number of version components (i.e. values between dots)

The default behavior is preserved, and is equivalent to using
'-1' as the value.

- Negative values remove items from the end.
- Positive values specify the count of of components
- Zero will remove the version field entirely from the symlink
- When nonzero, at least one version component will appear

Merges: https://pagure.io/pungi/pull-request/1361
Signed-off-by: Lon Hohberger <lhh@redhat.com>
2020-03-13 10:50:08 +01:00
Haibo Lin
3543f8fb3e pkgset: Reuse pkgset repos
JIRA: COMPOSE-4158
Signed-off-by: Haibo Lin <hlin@redhat.com>
2020-03-13 17:29:53 +08:00
Jan Kaluza
169fa5b453 Allow reusing gather phase results.
- Get also requires/provides of RPMs in package set.
- Store the results of gather phase as pickle file.
- Reuse old gather phase results in case Pungi configuration
  did not change, the "names" of RPMs in global package set
  did not change and their requires/provides did not change.
- Add `gather_allow_reuse` option to enable this feature.

Signed-off-by: Jan Kaluza <jkaluza@redhat.com>

Add gather_allow_reuse, add more tests and better handling of gather_lookaside_repos.
2020-03-13 10:17:59 +01:00
Lubomír Sedlář
a32bf4046f Remove fnmatch from nodeps gather method
Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2020-03-12 09:47:00 +01:00
Lubomír Sedlář
fb7f7396be Remove fnmatch from pkg_is_debug
On Python 2.7 fnmatch is not thread-safe, and this can cause crashes in
nodeps gather source.

Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2020-03-12 09:11:32 +01:00
Jan Kaluza
e70ad8aaa5 Run extra_files phase in parallel to other phases.
It seems the other phases executed in Weaver phase does not need
extra_files output, so it can be run in parallel to them.

Signed-off-by: Jan Kaluza <jkaluza@redhat.com>
2020-03-12 07:58:57 +01:00
Jan Kaluza
afcb3e969b Add Compose.old_compose_path and use it when searching for files in old compose.
The current code calls `find_old_compose` followed by multiple `os.path.*`
calls to find out if particular file exists in the old compose. This
duplicates code a lot and makes it harder to read.

In this commit, new `Compose.old_compose_path` is introduced and
used instead of direct calls of `find_old_compose`.

Signed-off-by: Jan Kaluza <jkaluza@redhat.com>
2020-03-09 12:47:23 +01:00
Jan Kaluza
fc3b5063ca Do not skip symlinks when searching for old compose.
ODCS creates symlinks to real directories containing the composes.
The directory structure is similar to following one:

- `./nightly/Fedora-Rawhide-20200304.n.0` -> `../odcs-3`
- `./nightly/Fedora-Rawhide-20200305.n.0` -> `../odcs-4`
- `./nightly/latest-Fedora-Rawhide` -> `../odcs-5`

The current Pungi code to search for old composes skips symlinks
and therefore old ODCS composes are not found.

This commit removes this check and therefore symlinks are allowed
when searching for old compose.

I think this check existed to prevent using `latest-*` symlink as
source for the compose. But this is not possible, because the
code checks that the old compose directory name has certain pattern
constructed from release_short, release_version, ... The `latest-*`
symlink definitely does not match this pattern.

I also executed test compose and it worked as expected.

Signed-off-by: Jan Kaluza <jkaluza@redhat.com>
2020-03-06 09:03:10 +00:00
Lubomír Sedlář
887c68d05d Display black output in tests
This should make fixing it much easier since it will directly tell users
what it doesn't like.

Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2020-03-05 09:51:47 +01:00
Lubomír Sedlář
16d6e5b0dd Resend message while waiting for ostree ref
If the signing machinery crashes, we don't want to wait forever. This
way at least we can shout for help periodically.

Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
Fixes: https://pagure.io/pungi/issue/1350
JIRA: COMPOSE-4166
2020-03-04 14:48:03 +01:00
Lubomír Sedlář
4734f9859a Silence all productimg related warnings
Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2020-03-03 11:06:52 +01:00
Jan Kaluza
145c3adbef Move buildinstall results to final directories if using pungi-buildinstall Koji plugin.
If Koji pungi-buildinstall is used, then the buildinstall results are
stored in the `output_dir` dir, but in "results" and "logs" subdirectories.
We need to move them to final_output_dir.

Signed-off-by: Jan Kaluza <jkaluza@redhat.com>
2020-03-03 10:35:25 +01:00
Lubomír Sedlář
3cd94a4aa5 Silence productimg warning in quiet mode
When running with `--quiet`, the warning should not be printed. It would
confuse tools that expect only compose path to be printed.

Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2020-03-02 09:24:01 +01:00
Haibo Lin
af5ee7030d Check skip_phases in config file
JIRA: COMPOSE-4143
Fixes: https://pagure.io/pungi/issue/1344
Signed-off-by: Haibo Lin <hlin@redhat.com>
2020-02-19 11:46:15 +08:00
Haibo Lin
e4f878a498 Fix typos in comments
Signed-off-by: Haibo Lin <hlin@redhat.com>
2020-02-19 11:26:15 +08:00
Lubomír Sedlář
d23b576a60 Remove dependency on dict.sorted
This is no longer used, and we don't need to pull it in.

Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2020-02-17 12:45:49 +01:00
Jan Kaluza
5808733270 The pungi-config-validate --dump-schema now respects --schema-override.
It is useful to actually check how the schema changed after applying
--schema-override. This commit changes --dump-schema in a way that
--schema-override is taken into account and dumped schema contains
the changes done using the --schema-override.

Signed-off-by: Jan Kaluza <jkaluza@redhat.com>
2020-02-13 07:27:09 +01:00
Haibo Lin
ff269a8675 gather: Make additional_packages accept debuginfo packages
Now debuginfo packages defined in additional_packages option
could be handled correctly.

JIRA: COMPOSE-4085
Signed-off-by: Haibo Lin <hlin@redhat.com>
2020-02-12 16:38:08 +08:00
Haibo Lin
3a31d47c83 doc: add code convention requirements
JIRA: COMPOSE-4108
Signed-off-by: Haibo Lin <hlin@redhat.com>
2020-02-07 17:00:39 +08:00
Haibo Lin
9b12be7300 Fix formatting issues
Code should be formatted via black.

Signed-off-by: Haibo Lin <hlin@redhat.com>
2020-02-07 16:16:20 +08:00
Haibo Lin
56fea60595 Run flake8 and black via tox
JIRA: COMPOSE-4108
Signed-off-by: Haibo Lin <hlin@redhat.com>
2020-02-07 16:14:45 +08:00
Haibo Lin
65aa8fde2f Fix other flake8 complaints
E231 missing whitespace after ','
E265 block comment should start with '# '
E266 too many leading '#' for block comment
E302 expected 2 blank lines, found 1
E501 line too long (115 > 88 characters)
E713 test for membership should be 'not in'
E722 do not use bare 'except'
F812 list comprehension redefines 'g' from line 1499
F821 undefined name 'cmp'
F841 local variable 'ex' is assigned to but never used

JIRA: COMPOSE-4108
Signed-off-by: Haibo Lin <hlin@redhat.com>
2020-02-07 16:14:09 +08:00
Haibo Lin
c0193c9fca Fix flake8 complaints - E501
E501 line too long (92 > 88 characters)
E501 line too long (103 > 88 characters)
...

JIRA: COMPOSE-4108
Signed-off-by: Haibo Lin <hlin@redhat.com>
2020-02-07 14:36:46 +08:00
Haibo Lin
3eddcfccd8 Fix flake8 complaints - F401
F401 'dnf' imported but unused
F401 'imp' imported but unused
F401 'os' imported but unused
F401 'subprocess' imported but unused
F401 'sys' imported but unused
F401 'yum' imported but unused

JIRA: COMPOSE-4108
Signed-off-by: Haibo Lin <hlin@redhat.com>
2020-02-07 11:48:31 +08:00
Haibo Lin
41a629969c Format code base with black
https://black.readthedocs.io/en/stable/

JIRA: COMPOSE-4086
Signed-off-by: Haibo Lin <hlin@redhat.com>
2020-02-05 17:35:47 +08:00
Haibo Lin
38142d30ba Format tests with black
JIRA: COMPOSE-4086
Signed-off-by: Haibo Lin <hlin@redhat.com>
2020-02-05 17:29:15 +08:00
Jan Kaluza
ef33d00f5b Add --schema-override to pungi-config-validate script
Some composes might need extra validation to ensure they are following
certain strict rules - for example containing only signed packages or
packages only from particular Koji tag.

There is currently no way how to check that Pungi configuration fulfills
these extra requirements.

This commit adds new `--schema-override` option to
`pungi-config-validate` script which allows caller to specify path to
JSON schema overriding the default JSON schema and therefore limitting
it further.

For exmaple, to limit the `pkgset_source` to `koji`, one can use
following JSON schema override:

```
{
    "properties": {
        "pkgset_source": {
            "enum": ["koji"]
        }
    }
}
```

It is possible to use `--schema-override` multiple times to apply
multiple schema overrides.

Merges: https://pagure.io/pungi/pull-request/1341
Signed-off-by: Jan Kaluza <jkaluza@redhat.com>
2020-02-05 10:03:30 +01:00
Lubomír Sedlář
6f23c7b8ba 4.2.0 release
Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2020-02-03 08:26:02 +01:00
Lubomír Sedlář
46ea0743a9 iso: Clean up cache for guestmount
When partial cleanup messes up the guestfs cache, the call to guestmount
will fail. To fix that, let's check if there is a problem first and
clean up everything if needed.

Relates: https://bugzilla.redhat.com/show_bug.cgi?id=1771976
JIRA: COMPOSE-3932
Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2020-01-30 10:35:42 +01:00
Lubomír Sedlář
4c6396f491 Remove deprecated warn() call
Instead warning() should be called.

Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2020-01-29 15:34:00 +01:00
Lubomír Sedlář
116c617b86 arch_utils: Fix ResourceWarnings
Newer versions of Python report an error when a file is not closed.
Let's avoid it by using with statement.

Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2020-01-29 13:08:44 +00:00
Jan Kaluza
3cde5c3a87 Add support for new Pungi Buildinstall Koji plugin.
We would like to start generating the buildinstall phase using the safer
Koji Pungi Buildinstall plugin and stop the direct use of Runroot plugin.

The plugin so far exists only as PR for Koji:
https://pagure.io/koji/pull-request/1939

This commit adds support for this plugin when `lorax_use_koji_plugin`
is set to `True`.

Signed-off-by: Jan Kaluza <jkaluza@redhat.com>
2020-01-23 16:09:15 +01:00
Haibo Lin
6eb6511aa6 Make --task-id mandatory in get_runroot_cmd
JIRA: COMPOSE-4027
Signed-off-by: Haibo Lin <hlin@redhat.com>
2020-01-20 12:56:01 +08:00
Haibo Lin
bce57c2e66 Wait on runroot tasks with wait-task command
JIRA: COMPOSE-4027
Signed-off-by: Haibo Lin <hlin@redhat.com>
2020-01-19 17:56:31 +08:00
Haibo Lin
52f82ccc6e pkgset: Ignore deleted module builds
JIRA: COMPOSE-4058
Signed-off-by: Haibo Lin <hlin@redhat.com>
2020-01-14 16:23:55 +08:00
Lubomír Sedlář
e7a58ccd07 Add tests for new exclude options
Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2020-01-13 10:54:11 +01:00
Haibo Lin
93ed40ad2d Remove invalid parameters from osbs config
JIRA: COMPOSE-4049
Signed-off-by: Haibo Lin <hlin@redhat.com>
2020-01-13 09:05:55 +00:00
Frédéric Pierret (fepitre)
c624aab945
pungi-gather: add options for excluding debug and source packages
Signed-off-by: Frédéric Pierret (fepitre) <frederic.pierret@qubes-os.org>
2020-01-11 22:13:51 +01:00
Haibo Lin
01ab1d2e24 Hide latest koji package via pkgset_koji_builds option
JIRA: COMPOSE-4010
Signed-off-by: Haibo Lin <hlin@redhat.com>
2020-01-09 07:33:46 +00:00
Lubomír Sedlář
aa6a213c8d Add a new option for customizing version in .treeinfo
There was an attempt to achieve this by customizing --version and
--release arguments for Lorax, but Pungi does not take the [general] and
[release] sections from its .treeinfo. Instead it was always using
release version.

The value from this new option will be put into .treeinfo and used for
--version and --release arguments in Lorax (unless explicitly defined in
lorax_options to another value).

JIRA: COMPOSE-4029
Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2020-01-07 10:55:48 +01:00
Lubomír Sedlář
2c2462970d Kickstart on RHEL 7 does not have metalink attr
Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2020-01-07 10:30:16 +01:00
Jan Kaluza
fcf1442f71 Support generating ISOs when using link_type="symlink".
When `link_type = "symlink"` is used, the packages are in fact symlinks
to /mnt/koji. When graft points file is generated, the paths in this graft
points file point to symlinks and therefore symlinks are copied into the
generated ISO file instead of real files.

In this commit, the code to generate the graft points file is changed
so it resolves the symlink to real file stored on /mnt/koji. To make
this code safer, it does such resolving only in case the symlink points
outside of `compose.paths.compose.topdir()`. Therefore you can still
generate ISO file with symlink pointing to file stored within the ISO
file itself, although this is not done currently afaik.

The main reason for this is to be able to generate ISO files even
without hardlinks (which would need read-write access on /mnt/koji)
and without copying all the packages from /mnt/koji to local storage.

Signed-off-by: Jan Kaluza <jkaluza@redhat.com>
2020-01-06 12:30:13 +00:00
Lubomír Sedlář
02ace28fe4 pkgset: Hardlink downloaded packages
When pungi-gather (or old pungi) download the packages from repos into
work/$arch/, they are linked to work/global/. This was using link_type
configuration option.

However if that is set to symlink, we get a relative symlink in
work/global/ which is later copied under the compose/ directory. Since
it's a relative symlink, it gets broken by this.

The fix is to hardlink the downloaded packages instead in the first
step. Since both the source and destination are in work/ directory, we
know it's the same volume and hardlinks should work. There is a fallback
to copy just to be sure, but it shouldn't ever be used.

Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2020-01-06 10:49:25 +01:00
Haibo Lin
3f111b559f Check dependency of --just-phase
JIRA: COMPOSE-4020
Signed-off-by: Haibo Lin <hlin@redhat.com>
2020-01-06 08:52:47 +00:00
Jan Kaluza
3750d6795f Update runroot_method documentation.
Signed-off-by: Jan Kaluza <jkaluza@redhat.com>
2020-01-06 07:47:38 +01:00
Haibo Lin
794d151bef Remove productimg phase
JIRA: COMPOSE-4004
Signed-off-by: Haibo Lin <hlin@redhat.com>
2020-01-03 11:42:38 +00:00
Lubomír Sedlář
38f6162b46 Fix unified isos with missing images.json
The metadata file can be missing if the compose contains no images. We
need to handle that by creating a new empty file to add unified images
to.

JIRA: COMPOSE-4048
Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2020-01-03 09:20:16 +01:00
Jan Kaluza
817acdbbac Allow setting runroot_method per Pungi phase.
The `runroot_method` now accepts `dict` value with phase name as a key
and runroot method as a value. For backward compatibility, the `str`
value is still supported.

The new `global_runroot_method` option has been added which defines
the runroot method in case it is not set in `dict` in the `runroot_method`.

This commit allows running `createiso` phase locally while keeping the other
phases in Koji.

Signed-off-by: Jan Kaluza <jkaluza@redhat.com>
2020-01-02 14:10:20 +00:00
Haibo Lin
b415e31f9d ostree: Fix arg passed to scm.get_dir_from_scm
A compose object should be passed instead of logger.

JIRA: COMPOSE-4050
Signed-off-by: Haibo Lin <hlin@redhat.com>
2020-01-02 13:13:14 +00:00
Lubomír Sedlář
b8bb4f7daa Improve detection of lookaside packages
It is possible we only ever see a package from non-lookaside repo, but
it actually is in lookaside. This patch should check for that before
adding the package to result set.

JIRA: RCM-71946
Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2020-01-02 13:50:29 +01:00
Lubomír Sedlář
38c24b3038 gather: Deduplicate packages before printing
The final set of packages can contain multiple copies of the same
package if it's present in multiple repositories. Since they have the
same NVRA and were built in Koji, we know they are identical and should
merge their flags.

Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2020-01-02 13:36:42 +01:00
Haibo Lin
b043ac66dc Do not mention pdc_client when missing modulemd
JIRA: COMPOSE-4007
Signed-off-by: Haibo Lin <hlin@redhat.com>
2019-12-18 13:50:49 +08:00
Haibo Lin
12828849d6 gather: Improve logging for gathering
Adding arch and variant to log message to make it clearer.

JIRA: COMPOSE-4009
Signed-off-by: Haibo Lin <hlin@redhat.com>
2019-12-16 08:56:22 +00:00
Frédéric Pierret (fepitre)
9b101d554f
gather: handle metalink in kickstart repos
Signed-off-by: Frédéric Pierret (fepitre) <frederic.pierret@qubes-os.org>
2019-12-15 21:05:10 +01:00
Haibo Lin
0ed70fc8b6 tests: drop sys.path modification
It's unnecessary to add the path manually.

Signed-off-by: Haibo Lin <hlin@redhat.com>
2019-12-10 10:53:38 +08:00
Haibo Lin
3cf16eb42d cleanup: refactor scripts via entry points
Fixes: https://pagure.io/pungi/issue/1045
JIRA: COMPOSE-2946
Signed-off-by: Haibo Lin <hlin@redhat.com>
2019-12-10 10:53:31 +08:00
Lubomír Sedlář
ce16e55ebd Avoid crash if a module is not available on all arches
Theoretically it is possible, and this is the bare minimum of changes
needed to survive such situation. There may be other pitfalls.

Fixes: https://pagure.io/pungi/issue/1309
JIRA: COMPOSE-4016
Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2019-12-06 14:22:41 +01:00
Lubomír Sedlář
0f53506765 Add version constraint to productmd dependency
This should be propagated to RPM level with F30+.

Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2019-12-06 09:49:01 +01:00
Frédéric Pierret (fepitre)
fa8b2094da Allow specifying temp dir in pungi-gather
That fix invalid cross-device link when hardlinking when /tmp is a
separate filesystem

Signed-off-by: Frédéric Pierret (fepitre) <frederic.pierret@qubes-os.org>
2019-12-06 08:06:49 +01:00
Lubomír Sedlář
ea2cd448a0 4.1.41 release
Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2019-12-02 14:51:35 +01:00
Lubomír Sedlář
aefe9b186d repoclosure: Parse all fus logs
Originally the list of solvables for fus was growing with each iteration
and nothing was ever removed. That later changed so that fus iterations
are only done on newly added stuff. It's great for performance, but
means that the last log is not a superset of all others.

To get all dependency problems we need to look into all log files, not
just the last one.

JIRA: COMPOSE-3964
Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2019-12-02 11:08:55 +01:00
Lubomír Sedlář
51b1144b70 runroot: Log different commands to different files
JIRA: COMPOSE-3980
Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2019-11-28 15:12:05 +01:00
Lubomír Sedlář
7f35ac622a gather: Collect and re-raise errors from gather method
When there is an exception in gathering (such as after seeing unsigned
packages in deps method), the exception was lost and the compose
continued to run until it tried to access the result and crashed on
KeyError.

Relates: https://pagure.io/releng/failed-composes/issue/587
JIRA: COMPOSE-3986
Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2019-11-25 14:28:34 +01:00
Haibo Lin
6afbe6d20a buildinstall: Log message for boot config change
JIRA: COMPOSE-3945
Signed-off-by: Haibo Lin <hlin@redhat.com>
2019-11-21 12:16:05 +08:00
Haibo Lin
0c040e0a69 livemedia: Remove title option
Fixes: https://pagure.io/pungi/issue/1293
JIRA: COMPOSE-3947
Signed-off-by: Haibo Lin <hlin@redhat.com>
2019-11-20 15:33:28 +08:00
Haibo Lin
242100eb72 Make sure repoclosure cache cleaned when running as root
When running repoclosure as root user, it will use other dir instead of
the one returned by getCacheDir().

For yum, with --tempcache option could let the cache dir returned by
getCacheDir() always be used.

For dnf, there's no such an option and we have to handle it specially.

JIRA: COMPOSE-3922
Signed-off-by: Haibo Lin <hlin@redhat.com>
2019-11-20 14:13:19 +08:00
Haibo Lin
90187298f2 Prefix lookaside cache dir with compose id
Then it could be cleaned up leater.

JIRA: COMPOSE-3922
Signed-off-by: Haibo Lin <hlin@redhat.com>
2019-11-20 13:51:13 +08:00
Haibo Lin
e0dd20dffe Prefix repoclosure cache dir with compose id
JIRA: COMPOSE-3922
Signed-off-by: Haibo Lin <hlin@redhat.com>
2019-11-20 13:51:13 +08:00
Lubomír Sedlář
c87d299a20 hybrid: Download remote files when getting platform
When probing lookasides for platform definition, we need to make sure it
works for repos specified as HTTP urls. Createrepo doesn't seem to
automatically download the repodata, so we have to help it.

JIRA: COMPOSE-3958
Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2019-11-19 08:51:18 +01:00
Lubomír Sedlář
4473b05f10 gather: Use fresh cache for each sequence of fus runs
Each depsolved tree will be using its own cache for fus. This should
still allow for faster loading of metadata after first iteration, but
should prevent errors from using cached files meant for another variant
or architecture. The cache is deleted after the last iteration.

JIRA: COMPOSE-3959
Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2019-11-18 14:39:47 +01:00
Haibo Lin
722411dfcd tests: Add test for compose logger setup
PR#1267 brings in some uncovered code which introduced
an issue fixed by PR#1292.

Signed-off-by: Haibo Lin <hlin@redhat.com>
2019-11-12 18:03:13 +08:00
Lubomír Sedlář
d34b0d7900 pkgset: Fix running without any koji tags
All places in the code assume the option to not be required except for
this one line.

An obsolete comment is removed as well.

Relates: https://pagure.io/releng/failed-composes/issue/477
Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2019-11-11 09:30:37 +01:00
Lubomír Sedlář
254d0cebff Get message from LogRecord with a method
Relates: https://pagure.io/releng/failed-composes/issue/469
Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2019-11-11 08:46:01 +01:00
Haibo Lin
6be2cf5118 Do not write images.json if all related phases skipped
JIRA: COMPOSE-3870
Signed-off-by: Haibo Lin <hlin@redhat.com>
2019-11-11 14:45:01 +08:00
Haibo Lin
2cbd75803a gather: Do not write metadata if gather phase skipped
Signed-off-by: Haibo Lin <hlin@redhat.com>
2019-11-07 16:19:19 +08:00
Lubomír Sedlář
cba3f1c88f Write global metadata about extra files
This is basically collecting all individual extra_files.json and putting
their content into a single location in
compose/metadata/extra_files.json. The file format is part of productmd
1.23.

JIRA: COMPOSE-3831
Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2019-11-05 09:11:01 +01:00
Lubomír Sedlář
20c3614fb3 scm: Add backend for downloading archives from Koji
Tests and documentation included.

JIRA: COMPOSE-3816
Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2019-11-05 08:51:26 +01:00
Lubomír Sedlář
39e8f6f710 Pass compose to SCM wrappers
Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2019-11-05 08:51:26 +01:00
Haibo Lin
b05295c202 Remove misleading warning about size of the ISO
JIRA: COMPOSE-3885
Signed-off-by: Haibo Lin <hlin@redhat.com>
2019-11-04 14:22:59 +08:00
Haibo Lin
114df77c6b Retry watching koji tasks on server outage
Fixes: https://pagure.io/pungi/issue/1285
JIRA: COMPOSE-3896
Signed-off-by: Haibo Lin <hlin@redhat.com>
2019-11-01 15:57:48 +08:00
Haibo Lin
5751de1096 config-dump: Allow overwritting config via -e option
The -e option was designed for defining missing config item,
but users always try to use it to overwrite existing config.

Now it works as expected.

JIRA: COMPOSE-3718
Signed-off-by: Haibo Lin <hlin@redhat.com>
2019-10-24 18:29:47 +08:00
Lubomír Sedlář
8829fc32ab 4.1.40 release
Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2019-10-23 09:02:41 +02:00
Lubomír Sedlář
6771a21916 pkgset: Only reuse valid old repo
Instead of just checking that the repo directory exists, make sure the
repodata subdirectory is in there. If it's missing, then createrepo_c
has nothing to use anyway, and it may help avoid issues.

Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2019-10-22 15:32:13 +02:00
Haibo Lin
4f96164ec7 Clean up skipping phases
It makes no sense to only skip phases needed by other phase.

Fixes: https://pagure.io/pungi/issue/1274
JIRA: COMPOSE-3871
Signed-off-by: Haibo Lin <hlin@redhat.com>
2019-10-22 16:36:01 +08:00
Haibo Lin
3901c227f0 Fix crash on unsigned packages
JIRA: COMPOSE-3869
Signed-off-by: Haibo Lin <hlin@redhat.com>
2019-10-21 17:02:59 +08:00
Juliana Rodrigueiro
f8dcda9dcb doc: Make it clear that the field 'repo' has to be empty for 'file' backend
Leaving the field 'repo' out for the 'file' backend makes the compose fail.

    [ERROR   ] Compose run failed: 'repo'

Signed-off-by: Juliana Rodrigueiro <juliana.rodrigueiro@intra2net.com>
2019-10-18 10:30:25 +02:00
Haibo Lin
2ff1f2fac3 gather: Make depsolving parallel
JIRA: COMPOSE-3827
Signed-off-by: Haibo Lin <hlin@redhat.com>
2019-10-18 14:20:32 +08:00
Lubomír Sedlář
014560f8bd doc: Add full examples of compose configuration
JIRA: COMPOSE-3797
Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2019-10-14 11:04:39 +02:00
Owen W. Taylor
72bf795bd4 ostree-install: allow configuring additional depenencies for runroot
A lorax template used for the ostree-installer might need an additional
package dependency (e.g., flatpak to embed a flatpak repository) - add
a config key 'extra_runroot_pkgs' to the ostree installer configuration
to allow supplementing the set of packages installed into the runroot.

Signed-off-by: Owen W. Taylor <otaylor@fishsoup.net>
2019-10-10 15:13:38 -04:00
Lubomír Sedlář
c346492df4 buildinstall: Allow customizing dracut arguments
JIRA: COMPOSE-3853
Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2019-10-09 15:42:10 +02:00
Lubomír Sedlář
908a6a759d Use custom assertion for checking content of files
Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2019-10-04 15:25:44 +02:00
Lubomír Sedlář
562b770b8d Drop custom ANY object
There is already one such thing in mock library.

Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2019-10-04 15:25:18 +02:00
Lubomír Sedlář
2f54745715 Remove usage of unittest2 on Python 3
It was needed to provide assertItemsEqual method. Starting with Python
3.2, there's assertCountEqual that does the same thing. Six provides a
helper that will dispatch to the existing method. With this change,
unittest 2 is only needed on Python 2.6 to backport the method.

Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2019-10-04 15:25:18 +02:00
Lubomír Sedlář
43fb06e00f Remove shebangs from test files
They should be executed with a runner like nose, not directly.

Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2019-10-04 15:24:17 +02:00
Lubomír Sedlář
26962d94ca gather: Resolve dependencies of debug packages
Until now, the behaviour was that all debuginfo from a build would be
included if at least one package with the same arch was included.

This resulted in many debuginfo packages being included even though
their corresponding package was not present.

With this patch, we will always pull in debugsource, but foo-debuginfo
will only be included if foo is included for the same arch. As a
consequence, it is necessary to resolve dependencies of debuginfo
packages. There are cases where foo-debuginfo needs foo-debuginfo-common
for example.

This change means that DNF and YUM backends are no longer identical in
the output. The tests where this is demonstrated are duplicated and
their results are modified.

JIRA: COMPOSE-3823
Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2019-10-03 10:46:21 +02:00
Lubomír Sedlář
4413b0df24 gather: Fix bare except block
Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2019-10-03 10:46:21 +02:00
Lubomír Sedlář
89fcb79aca gather: Fix formatting
Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2019-10-03 10:46:21 +02:00
Lubomír Sedlář
428f8297e1 gather: Simplify adding packages to result
Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2019-10-03 10:46:21 +02:00
Lubomír Sedlář
c7f3f38822 gather: Remove unused import
Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2019-10-03 10:46:21 +02:00
Lubomír Sedlář
ff526d1dd2 Regenerate test fixture repo
Make dummy-bash -> dummy-glibc dependency require archful. This avoids
potential race condition where order of dependency processing can result in
different packages being pulled in. The tests where this could happen are
updated.

Make dummy-glibc-debuginfo depend on dummy-glibc-debuginfo-common.

The filenames for the repo no longer include hash, and sqlite databases are not
generated.

Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2019-10-03 10:46:21 +02:00
Lubomír Sedlář
8ab7d9f7ba Move import of modulemd to a separate module
This should make it possible to only import the library only when it's
really needed.

DNF does not work with libmodulemd v2. If we import libmodulemd2 and
then dnf, the program will just hang forever. We only need DNF in
pungi-gather, where libmodulemd is not needed, and also where we do need
libmodulemd, we don't have DNF.

Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2019-10-03 10:40:31 +02:00
Lubomír Sedlář
f822ee324a ostree: Run commands in universal_newlines mode
This will mean the output is returned as unicode (decoded as UTF-8).
Thus Kobo will not have to do any decoding. This should work around
possible errors with breaking multibyte unicode character sequences into
different chunks.

Relates: https://pagure.io/releng/failed-composes/issue/237
Relates: https://github.com/release-engineering/kobo/issues/119
Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2019-10-03 09:30:53 +02:00
Lubomír Sedlář
21d45eb243 pkgset: Allow filtering modules from Koji tags
Add a configuration option to enable skipping some modules found in the
configured tag.

Fixes: https://pagure.io/pungi/issue/1260
JIRA: COMPOSE-3794
Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2019-09-24 10:13:00 +02:00
Lubomír Sedlář
44e551317a pkgset: Initialize path_prefix to empty value
Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2019-09-23 09:40:36 +02:00
Lubomír Sedlář
2b112d53f7 Allow loading overrides for module defaults
This patch adds a new config option. This is expected to be a name of
subdirectory in the repo with module defaults. If supplied, overrides
from that location are loaded every time defaults are loaded.

This raises the minimal required version of libmodulemd to 2.8.0

JIRA: COMPOSE-3828
Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2019-09-23 09:23:39 +02:00
Haibo Lin
260df24859 Move pkgset skipping logs to separate file
There will be a new log file logs/global/excluding-arch.global.log

Fixes: https://pagure.io/pungi/issue/1251
Signed-off-by: Haibo Lin <hlin@redhat.com>
2019-09-20 16:02:41 +08:00
Lubomír Sedlář
150f5f0cb6 Fix crash when pkgset phase is skipped
JIRA: COMPOSE-3832
Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2019-09-18 15:47:16 +02:00
Lubomír Sedlář
3e263f33f2 Resolve symlinks to images
Koji started to create relative symlinks to images created in various
tasks. We need to check for that and potentially link the actual file.

JIRA: COMPOSE-3822
Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2019-09-11 15:36:28 +02:00
Lubomír Sedlář
e814e1445a 4.1.39 release
Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2019-09-09 09:30:45 +02:00
Lubomír Sedlář
2d99edc8d8 Fix getting platforms from lookaside
Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2019-09-06 11:14:16 +02:00
Lubomír Sedlář
dfd4ff6016 extra-files: Simplify iterating over variants
Finding variants with particular architecture is not simple. Swapping
the two loops makes it faster, and additionally it fixes to correctly
work with sources.

JIRA: COMPOSE-3787
Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2019-09-04 15:45:15 +02:00
Lubomír Sedlář
b8e41d9b1b createiso: Make media.repo sticky
This means the file will be included on all ISOs when splitting.

JIRA: COMPOSE-3787
Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2019-09-04 15:45:15 +02:00
Lubomír Sedlář
7aa65f00c2 hybrid: Re-add getting platform from lookaside repos
This is needed when a compose does not include any modules itself, but
is using a lookaside with modules.

JIRA: COMPOSE-3720
Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2019-09-03 09:40:46 +02:00
Lubomír Sedlář
1423105802 pkgset: Remove fast_merge method
This is not called anywhere anymore. Instead of merging these package
sets, they exist as separate entities.

Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2019-09-03 09:31:18 +02:00
Lubomír Sedlář
465ecf229c Add test for materialized pkgset
Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2019-09-03 09:31:18 +02:00
Lubomír Sedlář
63a8b7b6c9 Remove package whitelist
This was a workaround to make some packages from the global repo
invisible for depsolving. This is now handled by packages being in
different repos. We can select which repos are enabled at which point.
This achieves the same result, but much faster.

Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2019-09-03 09:31:18 +02:00
Lubomír Sedlář
cec3efed51 paths: Remove arch_repo path
Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2019-09-03 09:31:18 +02:00
Lubomír Sedlář
a426a83ed6 gather: Remove use of arch_repo
The repo was used to speed up creating lookaside repo from a variant.
This uses a similar approach as createrepo phase: selecting the last
available package set and using that data.

Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2019-09-03 09:31:18 +02:00
Lubomír Sedlář
2d0ffb56ca ostree-installer: Remove usage of arch_repo
Pass all pkgset repos as input to the task.

Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2019-09-03 09:31:18 +02:00
Lubomír Sedlář
26ddd46acb ostree: Remove arch_repo path usage
Pass all pkgset repos as input to the task.

Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2019-09-03 09:31:18 +02:00
Lubomír Sedlář
ab9122be2a buildinstall: Remove arch_repo usage
Simply use all existing package set repos as input for the runroot
task. The command line gets a bit long, but the actual behaviour should
remain the same.

Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2019-09-03 09:31:18 +02:00
Lubomír Sedlář
3824eab15b createrepo: Remove arch_repo usage
There is no longer a single repo with all packages. This means that the
metadata has to be loaded from another location.

When taking packages from Koji, we can assume that the non-modular
package tag will be processed last. The repo for this tag will be used.
This has better chance of being useful than using a random module.

For repo sources, there is only one package set anyway, so this change
makes no difference.

Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2019-09-03 09:31:18 +02:00
Lubomír Sedlář
054b91c798 Fix tests
Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2019-09-03 09:31:18 +02:00
Lubomír Sedlář
11779f6644 pkgset: Update processing file cache
The cache is now always saved when the repo is created on disk. The
loading procedure in Koji source is updated to look for cache for
correct tag.

Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2019-09-03 09:31:18 +02:00
Lubomír Sedlář
fe2df01e8b Remove pickling from source repos
The pickled pkgset was only ever used for debug mode. We don't use that
anymore. Let's stop writing files that are not used anywhere.

Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2019-09-03 09:31:18 +02:00
Lubomír Sedlář
6fa478e688 gather: Port hybrid method
Update the code to consume multiple source repos.

Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2019-09-03 09:31:18 +02:00
Lubomír Sedlář
a446593698 pkgset: Update Koji source to create multiple pkgsets
With this patch, there should be a separate package set for each tag
that is consumed.

Generally each module will create a separate package set, with the
exception of -devel modules that will be in the same set as their
non-devel version.

Variants no longer need to keep their own package set objects. Instead
they now include a set of package set names that should be used for the
variant. This can replace the whitelist mechanism of deps gather method.

JIRA: COMPOSE-3620
Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2019-09-03 09:31:18 +02:00
Lubomír Sedlář
eed2aa2753 pkgset: Add object representing a package set on disk
Once a package set repo is written to disk, let's use this object that
connects the repository path with the mapping of packages.

This change also makes it explicit where the dependency on package set
repos are. In the original codebase, any part of code could generate a
path to the repo, even if that repo has not yet been written.

Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2019-09-03 09:31:18 +02:00
Lubomír Sedlář
3f665937b2 pkgset: Add name to package set
This name will serve as an identifier for the group of packages.

For Koji package sets, it should the name of the tag from which the
packages come. For package sets based on repos a dummy constant name is
used.

Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2019-09-03 09:31:18 +02:00
Lubomír Sedlář
be61da0192 paths: Add function to generate path to pkgset repo
This will be used to hold a repository for different package sets.

JIRA: COMPOSE-3620
Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2019-09-03 09:31:18 +02:00
Lubomír Sedlář
90393c4b49 Update code to pass around a list of pkgsets
This opens up a path to having multiple package sets in the compose. The
pkgset phase now creates a list of them (although at this time there is
always a single item in that list).

Any consumer of the package sets objects is updated to handle a list.
Generally this means an extra loop.

JIRA: COMPOSE-3620
Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2019-09-03 09:31:18 +02:00
Pat Riehecky
a99bf8c828 Store the parsed variants for possible later re-use
Merges: https://pagure.io/pungi/pull-request/1257
Signed-off-by: Pat Riehecky <riehecky@fnal.gov>
2019-09-02 13:44:24 +02:00
Pat Riehecky
b420986aa4 compose: additional logging on variants being processed
Merges: https://pagure.io/pungi/pull-request/1254
Signed-off-by: Pat Riehecky <riehecky@fnal.gov>
2019-09-02 13:41:22 +02:00
Haibo Lin
53a93f016a Refactor code for removing repoclosure cache
For 'yum' backend, only cache dirs following repoclosure-$COMPOSE_ID-$variant.$arch
name convention are created, e.g. repoclosure-DP-1.0-20190822.t.0-Bar-Tools.x86_64

But for 'dnf' backend, the dir name looks like
repoclosure-$COMPOSE_ID-$variant.$arch-$suffix and there are other files
created, e.g.
    repoclosure-DP-1.0-20190822.t.0-Bar-Tools.x86_64-df9fe164317e314e
    repoclosure-DP-1.0-20190822.t.0-Bar-Tools.x86_64-filenames.solvx
    repoclosure-DP-1.0-20190822.t.0-Bar-Tools.x86_64.solv

JIRA: COMPOSE-2565
Signed-off-by: Haibo Lin <hlin@redhat.com>
2019-08-23 11:00:17 +08:00
Haibo Lin
82349626c6 Delete cache dirs even though repoclosure command failed
JIRA: COMPOSE-2565
Signed-off-by: Haibo Lin <hlin@redhat.com>
2019-08-22 08:37:53 +00:00
Haibo Lin
29224b02ff Delete lookaside cache dir
If --lookaside option passed to repoclosure command, extra cache dir
will be created and it should be deleted too.

JIRA: COMPOSE-2565
Signed-off-by: Haibo Lin <hlin@redhat.com>
2019-08-22 14:24:40 +08:00
Haibo Lin
048698d885 Delete repoclosure cache
JIRA: COMPOSE-2565
Merges: https://pagure.io/pungi/pull-request/1253
Signed-off-by: Haibo Lin <hlin@redhat.com>
2019-08-15 08:42:16 +02:00
Lubomír Sedlář
eeaee1c20f Add function to get all arches in a compose
The same logic is used in two places. This deserves a common function.

Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2019-08-06 13:30:08 +02:00
Lubomír Sedlář
51d638d5db Remove not-used hack to workaround required option
Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2019-08-06 09:25:29 +02:00
Lubomír Sedlář
e674c2f574 pkgset: Create repos in a single place
Both pkgset sources use the same logic to create per-arch repos. There
is no reason to have that code in both places.

Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2019-08-06 09:24:28 +02:00
Lubomír Sedlář
8994aa5d88 pkgset: Added modules to variant in correct format
The data parsed from variants.xml uses a different format that what we
added in `_add_module_to_variant`. This leads to crashes later.

JIRA: COMPOSE-3746
Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2019-08-05 12:06:26 +02:00
Haibo Lin
c00162413c Add compose_id to repoclosure/lookaside directory names
JIRA: COMPOSE-3616
Signed-off-by: Haibo Lin <hlin@redhat.com>
2019-08-05 15:57:27 +08:00
Lubomír Sedlář
e9a363bfde Fix shadowed variable
This could result in incorrect log messages being printed.

Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2019-07-24 13:45:27 +02:00
Lubomír Sedlář
27d015543f Remove now unused msg variables
Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2019-07-24 13:45:00 +02:00
Lubomír Sedlář
6efaae19fd Remove debug mode
This was already discouraged to not be used, and is a bad idea in
current setup anyway. Removing this can simplify the code.

Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2019-07-24 13:36:23 +02:00
Lubomír Sedlář
0891bfbe59 Remove dead code
Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2019-07-24 12:37:53 +02:00
Lubomír Sedlář
b514e20833 pkgset: Check for empty module index
Instead of testing its return value. Future version of libmodulemd will
raise an exception instead of returning empty data.

Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2019-07-24 07:49:12 +02:00
Lubomír Sedlář
c6d6367932 gather: Mark repos as containing module hotfixes
This should prevent DNF from doing any unwanted magic with the contents.
Ideally we want it to completely ignore the modular metadata in there,
but there seems to be no way to do that.

This should at least prevent it from hiding non-modular packages that
are masked by some default stream.

Fixes: https://pagure.io/pungi/issue/1241
Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2019-07-22 12:35:36 +02:00
Haibo Lin
3811c0a176 config: Deprecate bootable option
JIRA: COMPOSE-2635
Fixes: https://pagure.io/pungi/issue/976
Signed-off-by: Haibo Lin <hlin@redhat.com>
2019-07-22 16:51:38 +08:00
Haibo Lin
cf52665a8d Use createrepo_checksum option instead of hardcoded sha256
JIRA: COMPOSE-3392
Signed-off-by: Haibo Lin <hlin@redhat.com>
2019-07-19 17:53:59 +08:00
Lubomír Sedlář
2dfb1cd4c8 pkgset: Skip adding modulemd if there is none
When libmodulemd is available, but the compose contains no modules, we
don't want to add the modular metadata anywhere. This patch actually
avoids a crash as `ModuleIndex.dump_to_string()` will return `None` if
there is no data.

JIRA: COMPOSE-3662
Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2019-07-16 09:02:49 +02:00
Lubomír Sedlář
3097019338 test: Allow turning strictness off as well
When the value is explicitly set to `False`, the check should not be
strict.

JIRA: COMPOSE-3658
Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2019-07-16 08:24:18 +02:00
Lubomír Sedlář
61e3cb0ef1 Port to libmodulemd v2
Fixes: https://pagure.io/pungi/issue/1225
JIRA: COMPOSE-3662
Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2019-07-15 15:27:05 +02:00
Lubomír Sedlář
62c6d4ddcf test: Option to make size check strict
Sometimes it's practical not just warn when ISO is larger than expected,
but to also abort the compose.

JIRA: COMPOSE-3658
Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2019-07-15 13:57:50 +02:00
Lubomír Sedlář
eeec62756f gather: Remove unused argument
Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2019-07-11 14:25:42 +02:00
Lubomír Sedlář
da78b99fc0 pkgset: Load modulemd only when needed
We can avoid parsing source modulemd information since we can get the
same information from the Koji build info.

Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2019-07-11 14:25:42 +02:00
Lubomír Sedlář
04baa2a4db Stop storing modulemd without arch
Historically each variant had a list of modules. This is no longer
needed and can be dropped. We can also stop logging the modulemd since
we know it was retrieved from Koji and not modified locally.

Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2019-07-11 14:25:42 +02:00
Lubomír Sedlář
a31fe998d5 Remove unused import
Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2019-07-11 14:25:42 +02:00
Lubomír Sedlář
a340663f00 doc: Clarify relationship to Koji
Fixes: https://pagure.io/pungi/issue/1143
JIRA: COMPOSE-3372
Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2019-07-03 09:06:49 +02:00
Lubomír Sedlář
8d00f56117 gather: Correctly sort list with multiple data types
On Python 3 it is not possible to sort str and None or RpmWrapper.

First convert everything to strings and then sort it. The sorting is
really to simplify diffing the files, so exact order does not have to be
preserved.

Fixes: https://pagure.io/pungi/issue/1227
Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2019-07-02 15:13:23 +02:00
Lubomír Sedlář
fc362c5347 git-changelog: Fix running on Python 3
Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2019-07-02 15:05:25 +02:00
Lubomír Sedlář
46333b01ad 4.1.38 release
Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2019-07-02 10:32:01 +02:00
Lubomír Sedlář
bf1b3e8421 Remove remaining mentions of runroot option
This also cleans up the runroot method detection code to not rely on the
now removed option.

JIRA: COMPOSE-2634
Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2019-07-02 09:43:13 +02:00
Lubomír Sedlář
49d0ab797c pkgset: Include module metadata in the repos
If the package set repo contains any modular package, the module
metadata is added there as well.

This is needed to accomodate change in DNF that refuses to work with
repo with modular packages if the metadata is not there. This DNF change
can cause issues in buildinstall phase.

Related: https://bugzilla.redhat.com/show_bug.cgi?id=1623128

The hybrid solver is modified to not create a separate repo with the
module metadata anymore, since it will be available in the repo with
packages. This also allows us to drop code to look into lookaside repos.

We still need to iterate over local modules in order to find out what
platform should be used.

JIRA: COMPOSE-3621
Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2019-07-01 09:09:17 +02:00
Haibo Lin
c4ed2bf3b2 config: Deprecate runroot option
Fixes: https://pagure.io/pungi/issue/975
Signed-off-by: Haibo Lin <hlin@redhat.com>
2019-06-27 18:00:07 +08:00
Daris A Nevil
920eceaa5a Respect --nomacboot flag when calling isohybrid
Fixes: https://pagure.io/pungi/issue/1222
Merges: https://pagure.io/pungi/pull-request/1223
Signed-off-by: Daris A Nevil <dnevil@intrusion.com>
2019-06-26 13:21:22 +02:00
Lubomír Sedlář
32a6415e58 config: Keep known options defined on CLI
If the validation or dumping script is given some options, they should
only be removed if they are not valid. We have to remove the invalid
ones, otherwise that would cause a warning about unknown options.

Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2019-06-25 15:13:16 +02:00
Lubomír Sedlář
d063217d6f config-dump: Report better error for non-existing sources
JIRA: COMPOSE-3624
Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2019-06-25 14:42:50 +02:00
Lubomír Sedlář
4e59c7595e config: Improve config validation for anyOf and oneOf
Instead of just saying that there is a problem, give all possible
reasons.

JIRA: COMPOSE-3636
Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2019-06-25 12:50:07 +02:00
Lubomír Sedlář
acd3c19618 config-validate: Allow defining variables
When trying to validate a template that should later be filled in with
`pungi-config-dump`, there will be errors about undefined variables.
These are meant to be set when the template is populated.

This patch adds support for `-e`, `--define` argument to the validation
script that can be used to suppress these errors.

Alternatively a JSON file is read from the directory with config file
that can contain values for the variables.

The `--define` option is changed in both validation and dumping to allow
empty string as an accepted value.

JIRA: COMPOSE-3599
Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2019-06-21 12:47:50 +02:00
Lubomír Sedlář
32624c59b1 config: Report validation warning if variants fail to load
In a real compose this would be a blocker issue and the compose would be
aborted, but for validation it may make sense to continue. Instead of
crashing, let's report a clear warning.

JIRA: COMPOSE-3606
Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2019-06-21 10:02:25 +02:00
Lubomír Sedlář
2f05a71c61 Allow customizing nosetests command
In some environments there may not be a version of the command without a
version. In such case it's quite convenient to be able to specify what
is the actual name of the nosetests command.

Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2019-06-20 13:26:53 +02:00
Lubomír Sedlář
e6a26571e0 scm: Close stdin of processing command
It is possible the user set a command to run in cloned Git repository,
but that command can ask for additional input. However Pungi will
capture all output, so if there is a prompt, it will never be shown.

In order to prevent confusion ("Did this hang?"), let's send empty
string to stdin of the program. That will cause any possible read to see
EOF immediately, which should cause an error that will then be reported
by Pungi to the user.

It is still possible the program will wait for input if it reads
directly from TTY. However in such case the prompt should hopefully also
be sent to TTY directly, so that possible confusion should be cleared.

JIRA: COMPOSE-3598
Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2019-06-20 09:07:07 +02:00
Lubomír Sedlář
82580ed5b3 pkgset: Create arch repos in parallel
This patch reuses the existing createrepo_num_threads options to limit
maximum number of parallel createrepo processes.

Fixes: https://pagure.io/pungi/issue/955
JIRA: COMPOSE-2575
Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2019-06-19 15:42:46 +02:00
Lubomír Sedlář
f1263eeacb util: Resolve HEAD in repos that have a remote
JIRA: COMPOSE-3597
Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2019-06-19 09:04:01 +02:00
Lubomír Sedlář
d01084337e tests: Avoid using threads in tests
Starting tests just to run mock functions slows the tests down for no
good reason. Let's instead mock the runner and run the dummy tasks
serially.

Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2019-06-18 13:17:17 +02:00
Lubomír Sedlář
2c3e6a5a74 pkgset: Use highest pickle protocol
Higher protocols should be more efficient in terms of performance and
storage size. Since we don't really care about interoperability with
different python version, we can safely go to the highest version.

Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2019-06-18 09:33:11 +02:00
Haibo Lin
6ec206f9ae gather: fix crash issue when gather_method = "nodeps"
JIRA: COMPOSE-3089
Signed-off-by: Haibo Lin <hlin@redhat.com>
2019-06-14 17:50:19 +08:00
Lubomír Sedlář
e68e17d8fe pkgset: Check for unused module patterns across all tags
Since there can be multiple tags, the check must be done once for all of
them at the same time. Otherwise any module found only in some and not
all tags would raise this error.

The code builds a set of all existing patterns and then removes items
from it. If there is something left once all tags are processed, it
means such patterns were not matched by anything.

JIRA: COMPOSE-3609
Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2019-06-13 10:10:30 +02:00
Lubomír Sedlář
f784bbd519 util: Fix offline resolving for scm dict
For scm dict resolving the return value should be git ref (or source
branch for offline mode).

JIRA: COMPOSE-3614
Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2019-06-12 08:22:38 +02:00
Lubomír Sedlář
2a9490526a pkgset: Make serialization more resilient
If the package set is loaded from a pickle, it will not contain this
key, and thus it can not be again written down into a new pickle. While
this is not a common use case, it's still better not to crash in that
case.

Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2019-06-11 08:45:16 +02:00
Lubomír Sedlář
0207260b9f fus: Support HTTP repos
Recent version of fus gained ability to download repodata if repo is
provided as HTTP url.

Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2019-06-07 14:43:04 +02:00
Haibo Lin
ce066707c1 config: Deprecate release_is_layered option
Fixes: https://pagure.io/pungi/issue/977
Merges: https://pagure.io/pungi/pull-request/1204
Signed-off-by: Haibo Lin <hlin@redhat.com>
2019-06-06 13:45:49 +02:00
Lubomír Sedlář
4e5f74b78d pkgset: Set correct nsvc for devel modules
We need to update the source modulemd to match what we want. For most
modules the name will be correct already, but in case of devel modules
the original name will still be present there.

Fixes: COMPOSE-3596
Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2019-05-31 16:02:19 +02:00
Lubomír Sedlář
f6162b90dd Remove unused variable
Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2019-05-31 15:57:55 +02:00
Lubomír Sedlář
c55ed742cd Whitespace fixes
This patch fixes some issues with inconsistent use of whitespace. It
only modifies lines that do not contain any code to not break git blame
too much.

Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2019-05-31 09:31:01 +02:00
Lubomír Sedlář
68115f3502 Whitespace cleanup
Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2019-05-31 09:14:26 +02:00
Lubomír Sedlář
fa6197246b Remove unused variables
Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2019-05-31 09:14:15 +02:00
Lubomír Sedlář
0a90f18b1f Remove unused imports
Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2019-05-31 09:05:50 +02:00
Lubomír Sedlář
163d69713d 4.1.37 release
Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2019-05-27 10:40:38 +02:00
Lubomír Sedlář
217fcd6c02 config-dump: Allow dumping config for multi compose
Clone the main config, all referenced parts and included variants or
comps files.

This requires a new argument: destination directory to which to write
the copied files.

JIRA: COMPOSE-3289
Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2019-05-27 08:42:42 +02:00
Lubomír Sedlář
33471c38bb pkgset: Ignore modules without metadata in Koji
This is fairly similar to a package only being built for particular
arches.

Fixes: https://pagure.io/pungi/issue/1198
Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2019-05-23 13:51:15 +02:00
Lubomír Sedlář
551f52922f runroot: Remove useless argument output_path
The same logic is handled by `chown_paths`, which does the same thing
but supports multiple paths.

Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2019-05-22 15:10:32 +02:00
Lubomír Sedlář
1951b0a521 buildinstall: Change owner of lorax logs
It's created in runroot, the owner and permissions should be updated so
that anyone can read it and user running compose can delete the files.

JIRA: COMPOSE-3545
Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2019-05-22 15:10:32 +02:00
Lubomír Sedlář
f2bbf35429 kojiwrapper: Allow changing mode of multiple files
The directory with logs should have updated owner and permission as
well as the actual output. This patch lays foundation for that by
allowing multiple paths to be specified.

JIRA: COMPOSE-3545
Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2019-05-22 15:10:32 +02:00
Lubomír Sedlář
8acd2c9689 buildinstall: Create toplevel directory on compose host
When using lorax, this directory will contain subdirectories for
individual variants. Those are created in runroot and their ownership
and permissions are fixed there. However the top level dir was only
created and not updated.

JIRA: COMPOSE-3545
Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2019-05-22 15:10:32 +02:00
fanjinke
a74470c18d arch_utils: add Hygon Dhyana CPU support
Add Hygon CPU vendor ID("HygonGenuine") detection and optimize arch to
"athlon" in x86 and "amd64" in x86_64.

Merges: https://pagure.io/pungi/pull-request/1196
Signed-off-by: fanjinke <fanjinke@hygon.cn>
2019-05-21 12:24:28 +02:00
Lubomír Sedlář
187ce8df79 gather: Introduce module source again
This reverts commit ac15f21135.

It is still needed if nodeps gather method is used. It simply returns
all packages listed in all modules.

Fixes: https://bugzilla.redhat.com/show_bug.cgi?id=1708661
Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2019-05-21 08:23:18 +02:00
Lubomír Sedlář
fe723a2094 metadata: Include empty directories in metadata
For example when a variant does not have any debuginfo packages, the
metadata will contain path to a repository, but it will be missing the
package path despite the (empty) directory being present on the
filesystem.

We should really only skip missing directories.

Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2019-05-20 13:26:27 +02:00
Lubomír Sedlář
283bae11da gather: Relax validations on variant_as_lookaside
Instead of validating both variants exist, let's just check the
existence of only the variant that is being used as a lookaside.

If the configuration says Foo depends on Bar, the error is reported only
if Foo exists but Bar does not. Any other situation is silently ignored.

JIRA: COMPOSE-3393
Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2019-05-20 10:46:42 +02:00
Lubomír Sedlář
cbe8457377 tests: Use correct Python interpreter
Instead of guessing based on a good enough name, we can use
`sys.executable` and get path to current python.

Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2019-05-16 09:07:18 +02:00
Lubomír Sedlář
a33cb0bf91 tests: Ignore warnings when running validation script
The script is run as a standalone process. Anything printed to stderr
breaks the test.

Since Python 3.8, we are getting warnings about invalid escape sequences
in some modules that are imported but not owned by us.

This patch should silence the warnings.

Relates: https://bugzilla.redhat.com/show_bug.cgi?id=1698514
Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2019-05-15 15:49:20 +02:00
Lubomír Sedlář
d0e8472ab5 Remove invalid escape sequences
This emits a warning on Python 3.8. Let's just fix it.

Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2019-05-15 15:47:44 +02:00
Jan Kaluza
cfb7b71fca Fix issues in OpenSSH Runroot method found by real tests.
- Pass the runroot_tag to init command in OpenSSH Runroot method.
  This is needed for the init command as a source for initial packages
  for the buildroot.
- Rename the "runroot_ssh_init_command" to "runroot_ssh_init_template"
  to make it consistent with the rest of "runroot_ssh_*" options.
- Add missing "runroot_ssh_*" options to checks.py.
- Use chmod/chown to `output_dir` in OpenSSH Runroot method the same way
  as it is used in Koji runroot method to make the runroot output readable
  for Pungi user.

Signed-off-by: Jan Kaluza <jkaluza@redhat.com>
2019-05-15 07:40:31 +02:00
Lubomír Sedlář
2dd30008ae buildinstall: Copy files in thread
Instead of running the copy from the main script explicitly, make it
part of the thread.

This should make things very slightly faster, and the code is much
simpler.

Fixes: https://pagure.io/pungi/issue/959
JIRA: COMPOSE-2604
Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2019-05-13 11:04:37 +02:00
Lubomír Sedlář
dc69281025 Fall back to C locale if UTF8 version does not exist
This can happen on RHEL 6 or 7. All current Fedora version have it.

Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2019-05-13 10:25:00 +02:00
Lubomír Sedlář
9da70ee7a9 init: Create comps repos in parallel
This should be mostly IO intensive operation, so running multiple
commands at the same time should save us a tiny bit of time.

Fixes: https://pagure.io/pungi/issue/981
JIRA: COMPOSE-2646
Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2019-05-10 12:44:14 +02:00
Lubomír Sedlář
c1a03c259b Switch locale to C.UTF-8
Relates: https://pagure.io/dusty/failed-composes/issue/1642
Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2019-05-09 08:01:13 +02:00
Lubomír Sedlář
b0f0579a9e util: Resolve ref if duplicate branches are present
If the repo contains the same name under multiple directories, make the
resolving work by filtering only to refs/heads and refs/tags.

Fixes: https://pagure.io/pungi/issue/1180
Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2019-05-07 13:44:57 +02:00
Lubomír Sedlář
9517df44c7 config: Fix getting default branch in SCM dict
If user configures branch as explicit None, we want to default to HEAD
(which is most likely refs/heads/master in git).

The original code was getting branch as None, which lead to wrong
resolver being used and the repo url being used as branch.

Fixes: https://pagure.io/pungi/issue/1181
Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2019-05-07 10:35:49 +02:00
Lubomír Sedlář
a9b9ec97fb pkgset: Fix whitelist for modules
The prefix checking only works if there are no streams that would share
prefixes. Let's instead check the value as a whole. There is extra
complexity from the fact that version and context may not be specified.

The stream as specified in input is processed to replace dashes (`-`)
with underscores (`_`) to match how the builds are imported into Koji.

JIRA: COMPOSE-3547
Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2019-05-06 09:48:44 +02:00
Lubomír Sedlář
2ae742af04 pkgset: Fix filtering excluded modular packages
For modular tags we only include packages that are included in the
module. Originally the filter was taking package names from
rpms.artifacts section of MMD.

This however does not work correctly, as there can easily be module
which lists foo.src but does not want to include foo.x86_64 or other
arches.

This patch fixes this particular problem by included arch in the set of
packages to be kept.

JIRA: COMPOSE-3543
Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2019-05-02 13:22:13 +02:00
Lubomír Sedlář
f858cea466 pkgset: Do not overwrite version in module
This value is important to get correct path to metadata.

JIRA: COMPOSE-3541
Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2019-04-30 12:22:13 +02:00
Lubomír Sedlář
b73d2d7f11 pkgset: Treat modular version as number for sorting
The scheme for generating versions has changed multiple times. MBS is
careful to only modify them so that they always compare correctly. This
only works though if the versions are treated as numbers.

This should be safe in that non-numbers should never be encountered as
module version. Libmodulemd internally stores the version as int (or
some version of int).

JIRA: COMPOSE-3540
Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2019-04-26 14:51:24 +02:00
Lubomír Sedlář
e550686e06 Use absolute path for hardlink
Hardlink command can be installed in /usr/sbin, where it is not visible
to non-priviledged users. They can still run it, but don't have it in
their PATH.

Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2019-04-26 13:48:54 +02:00
Jon Disnard
72b4969832 createiso: Run hardlink on staged content
Even if we want to break hardlinks from Koji volume, there may be files
that can be hardlinked and save some space on the media.

JIRA: COMPOSE-3482
Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2019-04-26 13:48:54 +02:00
Lubomír Sedlář
1e7ec68bbd comps-wrapper: Emit attributes sorted
Python 3.8 no longer sorts attributes automatically, which is causing
some of the tests to fail. The easiest fix is to update the code to make
sure sorting is in place.

Fixes: https://bugzilla.redhat.com/show_bug.cgi?id=1698514
Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2019-04-18 10:23:51 +02:00
Jiri Konecny
0cd089802f
patch-iso supports multiple graft directories
Pungi patch iso now supports multiple graft directories. This should
make usage more comfortable.

Signed-off-by: Jiri Konecny <jkonecny@redhat.com>
2019-04-12 15:27:54 +02:00
Lubomír Sedlář
479d17c033 4.1.36 release
Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2019-04-12 12:10:39 +02:00
Jan Kaluza
49d137b444 Extend "openssh" runroot_method to be able to execute "mock"
This adds few new config options which are well described in the
configuration documentation. Please refer to it for more information.

Merges: https://pagure.io/pungi/pull-request/1170
Signed-off-by: Jan Kaluza <jkaluza@redhat.com>
2019-04-12 11:10:40 +02:00
Lubomír Sedlář
d521711957 osbs: Rework configuration for image pushes
Embedding the registry configuration into OSBS config itself is
simple, but makes it impossible to reuse the same configuration for
multiple different composes.

A nice example is a nightly pushing images to a testing registry, and
production compose building the same images but pushing to staging
location. The original design requires duplication of all the
configuration just because registries are different.

With this option, the push information is stored in a separate option as
a mapping from NVR patterns to arbitrary data. The patterns are used to
match finished builds to registry.

The old configuration is marked as deprecated in code and will
eventually be removed. The deprecation handling in config validation
does not allow emitting warnings for nested values.

JIRA: COMPOSE-3394
Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2019-04-05 10:28:34 +02:00
Jan Kaluza
959d6979d4 Add "openssh" runroot method
Merges: https://pagure.io/pungi/pull-request/1166
Signed-off-by: Jan Kaluza <jkaluza@redhat.com>
2019-04-04 14:44:05 +02:00
Lubomír Sedlář
2f8717ec97 Fix printing version on Python 3
Don't crash when getting version from installed package.

Fixes: https://pagure.io/pungi/issue/1152
Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2019-04-04 11:42:19 +02:00
Lubomír Sedlář
b165866f39 config-dump: Fix crash when used without --define
The default value is None, which is not iterable.

Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2019-04-03 13:09:12 +02:00
Lubomír Sedlář
59a9c01304 setup: Fix missing comma in a list
Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2019-04-03 10:25:46 +02:00
Lubomír Sedlář
724255a984 setup: Install some deps on Py2.7 only
Lockfile and dict.sorted are only used in pungi.gather module, which
does not work with Python 3 due to dependency on yum. There's no point
in always pulling in these two libraries there.

This change fixes issues with python dependencies generator that puts
python3.6dist(lockfile) into RPM requires.

For builds on Python 2.6 these libraries are actually needed, but there
are no generators on RHEL 6. So this change can only break development
on RHEL 6. And if someone needs to do that, they have bigger problems...

Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2019-04-02 14:46:19 +02:00
Lubomír Sedlář
fd0117f38c config-dump: Allow defining variables on CLI
This can be used to fill particular values to a predefined template
without editing any file disk.

JIRA: COMPOSE-3316
Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2019-04-02 09:54:25 +02:00
Lubomír Sedlář
e71e91982b Update test data
The parts in multi compose are now named reasonably.

The package set repos are selected only once and not per variant. We
can't use repos with packages for specific arch only as that would
require more transformations during generating test data.

Lookasides for ResilientStorage part are added to point to Server part.

Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2019-04-01 09:49:53 +02:00
Lubomír Sedlář
1f95c33e2a gather: Use wildcard for repo selection
If package source is set to repos, honor wildcard and apply that block
every time.

Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2019-04-01 09:49:53 +02:00
Lubomír Sedlář
c6a86c444a gather: Apply repo path substitutions for DNF backend
Use a method to add repos that will apply $arch and $basearch
substitution automatically. Yum backend only applies $basearch, so if
compatibility is needed, that one should be used.

Drop code for handling mirrorlist, since Pungi does not ever use it, and
being used externally is not really supported.

Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2019-04-01 09:49:53 +02:00
Lubomír Sedlář
c2c36dc3c2 tests: Stop overwriting modulesdir for DNF
Tests are not passing in Fedora builds with this code, since it was
deleted in DNF. I think it's not actually doing anything, so we should
be able to drop it as well.

Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2019-03-26 14:58:09 +01:00
Lubomír Sedlář
5f8b519941 4.1.35 release
Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2019-03-26 10:03:26 +01:00
Lubomír Sedlář
31ef7736aa orchestrator: Monitor status of parts
When a phase is started or stopped, add a line to the to output. This
should help users keep track of what is happening in case the part takes
a long time to run.

JIRA: COMPOSE-3287
Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2019-03-25 14:20:04 +01:00
Lubomír Sedlář
d7ef86293e tests: Skip tests if libmodulemd is not available
These tests need the library, and will crash without it.

Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2019-03-25 10:41:09 +01:00
Lubomír Sedlář
66a127c313 pkgset: Refactor hiding unused modular packages
A module build can create packages that are tagged in the content tag,
but should not be included in the module. Originally Pungi didn't know
what exactly the module contains and so it needed to apply filters to
exclude stuff that was definitely out.

With getting the final MMD from Koji, we can actually make this a bit
more strict by only keeping packages that we know we need.

When processing each content tag, we can put into package set only
packages that are included in some module using that tag. This should
work with -devel modules as well. Both the regular and -devel modules
will contribute to the set and thus all packages will go to the package
set.

Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2019-03-25 08:48:16 +01:00
Lubomír Sedlář
9f9b784e64 Remove configuration for devel modules
They should be loaded in the same way as regular modules straight from
Koji.

Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2019-03-25 08:48:16 +01:00
Lubomír Sedlář
ac15f21135 gather: Remove module source
This source does not really return anything useful. It was necessary to
process the source modulemd to fill in list of RPMs. Since we now get
the final files from Koji, this is not needed anymore and the source can
be dropped.

This change requires a lot of tweaks for test.

Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2019-03-25 08:48:16 +01:00
Lubomír Sedlář
9939d09643 createrepo: Stop processing modulemd
The file we get from Koji has all important bits already filled in.
There is no need to add anything.

This patch also stops filtering the artifacts to only contain packages
that are actually in the repo. Thus debuginfo and source packages will
appear there.

Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2019-03-25 08:48:16 +01:00
Lubomír Sedlář
9229699078 pkgset: Load final modulemd files from Koji
Instead of loading the "source" modulemd, always get the final file for
each architecture from Koji.

Logging the downloaded files locally is no longer necessary, when
debugging a problem we can find the files in the respective builds in
Koji.

Tests are updated to work with new code, and an obsolete test is
removed.

JIRA: COMPOSE-3147
Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2019-03-25 08:48:16 +01:00
Lubomír Sedlář
358fdd50ce buildinstall: Allow overwriting version for lorax
Sometimes the release version can be more specific than what should be
exposed to users of the boot iso.

JIRA: COMPOSE-3295
Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2019-03-22 12:47:16 +01:00
Jan Kaluza
75bb48a882 Create new Runroot class and use it everywhere where runroot task is executed.
This adds new `Runroot` class and new `runroot_method` option which makes
it possible to choose between two currently available runroot methods:

- Local
- Koji

The main goal of this commit is to make it possible to add new runroot
methods in the future and this is the first step in that direction.

Signed-off-by: Jan Kaluza <jkaluza@redhat.com>
2019-03-21 14:15:58 +01:00
Lubomír Sedlář
45cdbb2faf orchestrator: Send messages about the main compose
Only start/finish messages will be sent if a handler is configured.

JIRA: COMPOSE-3288
Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2019-03-21 09:29:54 +01:00
Lubomír Sedlář
088ea7fe37 orchestrator: Support generic pre- and post- scripts
Run arbitrary commands before and after the compose.

The example config is updated to generate latest symlink with a
post-compose script. The pre compose script runs always, post compose
runs only if the compose is not doomed.

JIRA: COMPOSE-3288
Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2019-03-21 09:29:54 +01:00
Lubomír Sedlář
86fb93d603 orchestrator: Support getting kerberos ticket
If the configuration sets keytab path and principal, run kinit with
custom cache file, and delete the file at the end of the run.

JIRA: COMPOSE-3288
Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2019-03-21 09:29:54 +01:00
Lubomír Sedlář
b80efbfd97 hybrid: Refactor handling debuginfo packages
Behavior before this change: debuginfo was added based on source RPMs.
Pungi would get all debuginfo for all architectures that include at
least one binary package. This had a consequence that if foo-x.x86_64
and foo-x.i686 from the same built were included, foo-y-debuginfo.i686
would be included despite foo-y only being present for x86_64.

The patch changes this to work on binary package level: for each
included package `x`, check if there is `x-debuginfo` or
`x-debugsource`, and include them. Packages added in this way have to go
through one iteration of the solver, to account for cases such as
`x-libs-debuginfo` depending on `x-debuginfo` (with only `x` starting
this chain).

To make it slightly faster, the invocation of fus is changed to only
process newly added package in each iteration. It should have no effect
on the results, and subsequent iterations are much faster if they don't
process the same stuff again and again.

JIRA: COMPOSE-3247
Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2019-03-18 13:56:48 +01:00
Ken Dreyer
b5bef68c60 doc: explain koji_profile
Add more details to the documentation for the koji_profile setting.

Signed-off-by: Ken Dreyer <kdreyer@redhat.com>
2019-03-14 15:53:15 -06:00
Lubomír Sedlář
039b8d44b3 pkgset: Stop loading list of module RPMs
The list is not needed for anything anymore, and it only takes time and
space in memory.

Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2019-03-14 09:08:44 -04:00
Lubomír Sedlář
0fc797a06f pkgset: Only load cache once
The file in old compose does not change, there is no need to load it
again for each tag.

One consequence of this change is that the same cache will be used by
all package sets. They add stuff to the cache as they use it. However
that should not be a problem for the same reason it's okay to use the
cache in the first place. If two packages have the same path, they are
actually the same file and it's okay to reuse the data.

JIRA: COMPOSE-3374
Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2019-03-12 08:57:35 -04:00
Jan Kaluza
2d39490909 Do not add pkgset_koji_builds to modules, but only to pkgset_koji_tag tags.
Also remove the useless listTaggedRPMs call which has been used *only*
to catch the very rare error which happened from time to time when
we used PDC in Pungi few years ago. This rare error is not relevant
anymore now.

Signed-off-by: Jan Kaluza <jkaluza@redhat.com>
2019-03-11 17:56:27 +01:00
Lubomír Sedlář
9de036b401 scm: Don't retry git fetch
If it fails, we can't really tell if it's a transient error or just too
old git client. Fall back to full clone immediately and retry there.

Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2019-03-11 13:12:06 +00:00
Marek Marczykowski-Górecki
b3bf6cd9cd
tests: fix metadata tests when SOURCE_DATE_EPOCH is set
SOURCE_DATE_EPOCH is preferred over time.time() call in metadata
generation, which makes time.time() mock ineffective. Set
SOURCE_DATE_EPOCH instead of mocking time.time(). This additionally test
if SOURCE_DATE_EPOCH is really used.
Adjust expected output, as SOURCE_DATE_EPOCH is defined without
fractional component.

Signed-off-by: Marek Marczykowski-Górecki <marmarek@invisiblethingslab.com>
2019-03-09 15:42:57 +01:00
Lubomír Sedlář
9541c75b7e checks: Use GitResolver for scm dicts
Otherwise the offline flag is not honored correctly.

Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2019-03-06 09:46:12 +00:00
Lubomír Sedlář
4431ea8a0c hybrid: Fix opening gzipped files on Python 2.6
GzipFile works in `with` statement starting with 2.7

JIRA: RCM-51070
Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2019-03-06 08:04:19 +01:00
Lubomír Sedlář
cc456d3e75 4.1.34 release
Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2019-03-05 12:37:07 +01:00
Lubomír Sedlář
a206a73db1 config: Allow validating configuration in JSON
JIRA: COMPOSE-3318
Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2019-03-04 14:36:28 +01:00
Lubomír Sedlář
357f556d69 image-build: Accept formats in lists
If the config is loaded from JSON, we will get list instead of tuple.

The validation rule does not really care whether it's a list or tuple,
it only enforces there are two strings. The definition is renamed to be
a bit more descriptive.

Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2019-03-04 08:32:19 +01:00
Lubomír Sedlář
6bd1e9da2a image-build: Resolve git ref in ksurl
The ksurl property was not listed in the config schema, and thus it was
not processed.

Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2019-03-01 09:40:30 +01:00
Lubomír Sedlář
2d694272c0 Resolve git branches in scm_dict
If the config uses SCM dicts that include branch or tag names, they will
be resolved to specific commit ids.

It goes through the caching resolver. The main motivation for that is to
correctly support the --offline flag. It's highly unlikely there will be
two scm_dicts in the config with the same repo.

JIRA: COMPOSE-3279
Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2019-03-01 09:40:30 +01:00
Lubomír Sedlář
5a7ced5b7d util: Refactor resolving git url
Split out a smaller function that receives a git repo URL and ref and
returns the commit id. The caching resolver class is modified to use
this second function if branch is given to it.

The new function checks if the ref received already looks like a commit
ID, and if so it does not attempt to do anything with it.

Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2019-03-01 09:40:30 +01:00
Lubomír Sedlář
ff4e6d4782 scm-wrapper: Refactor getting files from Git
Before this patch, there were two code paths: either getting the only
the wanted content by calling git-archive, or cloning the repository and
copying the files.

Both these approaches have the downside of not allowing retriving
content from a specific git commit.

The workaround is to create a new empty repo (in the location to which
we cloned previously), fetching the specific commit to there and then
checking it out.

This supports any commit and works identically for any protocol. The
downside is that all files in that commit will be downloaded. It should
be no worse than the git-clone path, but can result in bigger transfers
than git-archive.

Unfortunately this is only supported with git 2.5+. On older version
fetch will fail with no error message (tested with 1.8.3). This can be
used to fall back to full clone. This fallback is clearly suboptimal in
terms of data transfer, but it should work reliably.

Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2019-03-01 09:40:30 +01:00
Lubomír Sedlář
ef6bb20a0e osbs: Fix wrong message in logs
We run a thread for each task, not one per variant. If there are
multiple containers in a single variant, the logs contain confusing
entries about starting the phase multiple times.

2019-02-28 01:58:54 ... [BEGIN] OSBS phase for variant Foo
2019-02-28 01:58:54 ... [BEGIN] OSBS phase for variant Foo

Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2019-02-28 09:00:47 +01:00
Lubomír Sedlář
afd2d3ae66 orchestrator: Log exception to log file
This data can be useful for debugging.

JIRA: COMPOSE-3284
Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2019-02-27 09:56:29 +01:00
Lubomír Sedlář
8b84aa384a config-dump: Allow freezing koji event
Accept similar argument to pungi-koji: either direct event ID, or a path
to a compose from which the event will be extracted.

It would be nice if we could reuse the path to compose given as source,
but there may be more that one compose, so ultimately we need a way to
overwrite it anyway.

JIRA: COMPOSE-3278
Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2019-02-26 10:52:45 +01:00
Lubomír Sedlář
fa47d9edba Read koji event from config file
This can be useful for archiving configuration to freeze the koji
package set to a particular event.

JIRA: COMPOSE-3278
Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2019-02-26 10:52:45 +01:00
Lubomír Sedlář
42a8965e87 image-build: Fix typo in file extension for vmdk image
Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2019-02-25 16:06:59 +01:00
Lubomír Sedlář
95596f1c69 osbs: Accept local paths as repo URLs
Translate the using configured patterns, and give OSBS a repo file with
that URL.

JIRA: COMPOSE-3290
Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2019-02-25 08:18:47 +01:00
Lubomír Sedlář
3efcfede6a image-build: Support repo/install_tree as path
If a repo or install tree is specified as an absolute path on the local
filesystem, we should either translate it using the configured mappings,
or if no mapping matches, it should be return unchanged. A variant name
can not start with a slash, so attempting that translation does not make
much sense.

JIRA: COMPOSE-3290
Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2019-02-25 08:18:47 +01:00
Lubomír Sedlář
8c82cfc1c7 osbs: Remove format requirement for registry
Pungi does not really care if it's an object, list or string. Anything
should be allowed.

Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2019-02-22 15:10:45 +01:00
Lubomír Sedlář
f33973ee65 Make the Apple/HFS compatibility configurable
The default is the original behaviour. On F30+ a new option should be
added to config to make it work.

Over time as users move to this option (which requires a new enough
version of lorax), the default should be switched and then the option
removed.

Resolves: https://pagure.io/pungi/issue/1126
Merges: https://pagure.io/pungi/pull-request/1128
Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2019-02-21 16:11:01 +01:00
Dan Horák
071d11a883 update iso creation for ppc64le
Don't produce ISO image with Apple/HFS compatibility stuff on ppc64le.

Signed-off-by: Dan Horák <dan@danny.cz>
2019-02-21 16:11:01 +01:00
Lubomír Sedlář
59c9c150ef orchestrator: Use prefix for config substitutions
This will avoid possible conflicts. The names for parts are chosen by
users, and if we decide to add more options in the future, this can
become handy.

JIRA: COMPOSE-3285
Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2019-02-21 09:42:14 +01:00
Ken Dreyer
5a251ff24c README: add link to documentation
Make it easier for README users to discover the Pungi docs on Pagure.

Signed-off-by: Ken Dreyer <kdreyer@redhat.com>
2019-02-18 14:36:48 -07:00
Lubomír Sedlář
e21c49d9e2 4.1.33 release
Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2019-02-13 10:37:48 +01:00
Lubomír Sedlář
6c6d4759f5 isos: Check maximum expected size
This patch allows the configuration to express maximum expected size for
ISOs created in createiso and extra_isos phases. If the image is larger
than this limit, a warning is emitted in test phase. The compose itself
is not affected in any way.

JIRA: COMPOSE-2824
Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2019-02-12 15:15:30 +01:00
Lubomír Sedlář
7693e562b1 osbs: Process data about pushing images to registries
This patch does not do any actual pushing. It will only extract data
about push targets from the main configuration and store it together
with exact Koji NVR in a well-defined location, and also send the data
to message bus for another service to handle.

JIRA: COMPOSE-3228
Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2019-02-12 15:12:50 +01:00
Lubomír Sedlář
23bf01bb45 hybrid: Apply filters to debuginfo and source packages
For binary packages the filters are handled at the depsolver level.
However sources and debuginfo is added later in the process, so the
filters have to be explicitly applied.

JIRA: COMPOSE-3114
Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2019-02-12 12:20:46 +01:00
Lubomír Sedlář
e573246a2a hybrid: Get platform from lookaside repos
If the hybrid solver is used in a situation where there are modules in
lookaside repo, but not in the compose itself, it will fail to detect
any platform. Since we are already opening the module repodata, we can
retrieve platforms from all modules in there as well.

If there are conflicts (e.g. multiple modules depending on different
platforms), an error will be reported.

JIRA: COMPOSE-3277
Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2019-02-08 14:41:56 +01:00
Jan Kaluza
c3aa297d8c Return RPMs added to -devel module in GatherSourceModule.
Signed-off-by: Jan Kaluza <jkaluza@redhat.com>
2019-02-08 14:24:16 +01:00
Jan Kaluza
31bafa29c5 Allow setting wildcard as a module name in variants to include all the modules.
Signed-off-by: Jan Kaluza <jkaluza@redhat.com>
2019-02-07 13:59:57 +01:00
Lubomír Sedlář
940a581bd9 gather: Link files in order for dependant variants
If there are variants that depend on another, they should be processed
in order to make sure packages from the base variant are linked first.
That way the srpm cache is populated and any package in layered variant
but with source in base will have access to correct epoch information.

Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2019-02-04 08:24:22 +01:00
Lubomír Sedlář
8065239e04 buildinstall: Pick correct config with rootfs_size
If there are multiple matching configuration blocks, we should take the
value that is defined in the last one, but only if it actually is there.
That's how it works for other options.

Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2019-02-01 14:24:20 +01:00
Lubomír Sedlář
f59034b22d hybrid: Add packages from prepopulate to input
This is really an oversight. The list of packages from prepopulate list
should be treated the same as if the packagees were coming from comps or
additional packages.

Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2019-01-29 16:16:44 +01:00
Lubomír Sedlář
da1ea83561 ostree_installer: Pass --buildarch to lorax
This should tell lorax what arch to use and avoids fragile detection
based on contents of source repo.

It uses the same logic buildinstall phase uses to get the buildarch.

Related: https://pagure.io/teamsilverblue/issue/67
Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2019-01-28 13:41:49 +01:00
Lubomír Sedlář
f92c71683f orchestrator: Add missing function arguments
Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2019-01-21 09:13:03 +01:00
Lubomír Sedlář
7320bf4943 orchestrator: Compatibility with Python 2.6
This is why we can't have nice things.

Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2019-01-14 10:57:05 +01:00
Frédéric Pierret (fepitre)
86314fdc83 pungi-legacy: expose lorax's --rootfs-size argument
Merges: https://pagure.io/pungi/pull-request/1112
Fixes: https://pagure.io/pungi/issue/1107
Signed-off-by: Frédéric Pierret (fepitre) <frederic.pierret@qubes-os.org>
2019-01-14 10:41:37 +01:00
Miro Hrončok
3fe4beb20c Only require enum34 on Legacy Python
This resolves https://bugzilla.redhat.com/show_bug.cgi?id=1665501

Signed-off-by: Why Do You <enforce@this.qm>
2019-01-14 09:16:14 +01:00
Lubomír Sedlář
6a32b3b741 ostree: Add test for expanding basearch for message
Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2019-01-10 07:53:46 +01:00
Patrick Uiterwijk
c9c5fcac94 Make sure ${basearch} is also replaced with config['ostree_ref']
Signed-off-by: Patrick Uiterwijk <patrick@puiterwijk.org>
2019-01-09 21:39:33 +01:00
Lubomír Sedlář
dbc0d5736c 4.1.32 release
Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2019-01-08 12:17:29 +01:00
Lubomír Sedlář
90c60f8e64 Add script to orchestrate multiple composes
It may make sense to break a big compose into smaller chunks that can be
done independently. This script allows describing the smaller parts,
runs them with correct dependencies and arranges the result to look like
a single big compose.

All parts use the same koji event, that is either obtained from Koji, or
from command line argument.

JIRA: COMPOSE-2654
Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2019-01-08 09:40:36 +01:00
Lubomír Sedlář
ba260c24e8 buildinstall: Expose lorax's --rootfs-size argument
We already make this possible for the ostree installer, but it was
missing from the traditional one. The default behaviour is to let lorax
decide, but if user knows better, they can overwrite in configuration.

JIRA: COMPOSE-3188
Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2019-01-07 11:00:43 +01:00
Frédéric Pierret (fepitre)
682f959ee0 Support for pungi-legacy with productmd format
Merges: https://pagure.io/pungi/pull-request/1099
Signed-off-by: Frédéric Pierret (fepitre) <frederic.pierret@qubes-os.org>
2019-01-04 14:11:23 +01:00
Ondrej Nosek
70f46dfb62 Unify update-docs.sh script with rpkg
Signed-off-by: Ondrej Nosek <onosek@redhat.com>
2019-01-04 13:32:17 +01:00
Lubomír Sedlář
610bf4b125 Remove createrepo references from doc and spec
Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2019-01-03 10:37:59 +01:00
Frédéric Pierret (fepitre)
b7fa03dffd CreaterepoWrapper: add 'basedir' and 'compress-type' args for createrepo_c
Signed-off-by: Frédéric Pierret (fepitre) <frederic.pierret@qubes-os.org>
2019-01-03 10:37:59 +01:00
Frédéric Pierret (fepitre)
f41c32e413 gather.py: use createrepo_c for creating repodata instead of obsolete createrepo python library
Fixes: https://pagure.io/pungi/issue/1094
Merges: https://pagure.io/pungi/pull-request/1097
Signed-off-by: Frédéric Pierret (fepitre) <frederic.pierret@qubes-os.org>
2019-01-03 10:37:59 +01:00
Frédéric Pierret (fepitre)
c69bc13068 Fix import of ConfigParser for NoSectionError and NoOptionError
Merges: https://pagure.io/pungi/pull-request/1100
Signed-off-by: Frédéric Pierret (fepitre) <frederic.pierret@qubes-os.org>
2019-01-03 10:18:05 +01:00
Ken Dreyer
27d5073b98 doc: explain product_id_allow_missing results in detail
Add more details to the documentation for the product_id_allow_missing
setting:

- Pungi expects a product cert for each arch in each variant.

- Pungi will exit with an error by default if a variant+arch's cert is
  missing.

- Pungi will log a warning if product_id_allow_missing is True.

Merges: https://pagure.io/pungi/pull-request/1102
Signed-off-by: Ken Dreyer <kdreyer@redhat.com>
2019-01-03 10:14:53 +01:00
Ken Dreyer
7c45157a92 doc: describe product_id's output and purpose
Document the "productid" files that Pungi creates when the user
configures the "product_id" setting. Describe where to find the
"productid" files, and how they relate to subscription-manager.

Signed-off-by: Ken Dreyer <kdreyer@redhat.com>
2019-01-02 14:22:21 -05:00
Lubomír Sedlář
5f6dcb37f6 ostree: Send correct ref in the message
If configuration requests a different ref than what treefile has, a
wrong message can be sent.

If the treefile is in JSON, the local copy will be updated in-place and
it works. However with YAML the updated version is still written as JSON
and thus we are still sending the original value.

Fixes: https://pagure.io/pungi/issue/1092
Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2018-12-05 11:20:17 +01:00
Lubomír Sedlář
7c48b808f1 4.1.31 release
Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2018-11-26 13:14:09 +01:00
Lubomír Sedlář
df35f26910 Add script to merge and dump multiple configuration files
The script can either take config from an existing compose, or load
files by path. By default it will perform full validation (and add
default values and resolved git references). This can be turned off.

The final JSON is printed to stdout.

JIRA: COMPOSE-3066
Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2018-11-26 07:59:31 +01:00
Lubomír Sedlář
ca7d6256e5 Move resolving git reference to config validation
Instead of multiple places handling the same thing duplicating the
logic, it's better to do it once upfront. This allows easy caching of
the results.

Additional advantage of this approach is that the config dump will
include resolved URLs. The original reference will still be available in
the copy of the original config.

JIRA: COMPOSE-3065
Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2018-11-21 13:25:35 +01:00
Lubomír Sedlář
444af0396e util: Add a cache for resolved git urls
Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2018-11-21 10:15:52 +01:00
Mohan Boddu
4864a0f58e Copy config files into logs/global/config-copy/ directory
Fixes: https://pagure.io/pungi/issue/994
Merges: https://pagure.io/pungi/pull-request/1013
Signed-off-by: Mohan Boddu <mboddu@bhujji.com>
2018-11-19 14:42:38 +01:00
Lubomír Sedlář
7e923d3823 Remove timestamp from config dump
This makes it hard to programatically access the dump.

The timestamp was included originally to make sure that restarting a
compose in debug mode will preserve all configs. However we don't really
support that usecase anyway.

JIRA: COMPOSE-3063
Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2018-11-19 13:53:34 +01:00
Lubomír Sedlář
7c2e701a74 extra_iso: Support extra files in directory
It works, only the config schema does not allow it.

Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2018-11-19 13:18:42 +01:00
Lubomír Sedlář
c2a4700446 extra_iso: Include extra_files.json metadata
This should be on top level of the ISO, and list files added
specifically to the ISO. If there's anything inherited from one some
variant, the files will be listed in metadata in the variant directory.

JIRA: COMPOSE-3069
Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2018-11-19 13:18:42 +01:00
Lubomír Sedlář
605c9ca435 Allow reading configuration from JSON
JIRA: COMPOSE-3064
Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2018-11-19 12:02:19 +01:00
Lubomír Sedlář
f809cac0b2 Cleanup parsing treefile
...and also add tests for it.

Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2018-11-19 11:59:32 +01:00
Mohan Boddu
324b371cff Fix convert rpm_ostree config to YAML
Merges: https://pagure.io/pungi/pull-request/1088
Signed-off-by: Mohan Boddu <mboddu@bhujji.com>
2018-11-19 11:59:32 +01:00
Lubomír Sedlář
07d08627c6 koji_wrapper: Change owner of runroot output
The files created in runroot task are owned by root by default (because
that's who is running the processes to create them). Making the results
world readable allows the compose to work, but it still can be difficult
to clean up old composes if they contain random files owned by root.

Fixes: https://pagure.io/pungi/issue/1039
JIRA: COMPOSE-2906
Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2018-11-15 12:07:27 +01:00
Lubomír Sedlář
1d020dbedd util: Preserve symlinks when copying
Currently the `copy_all` function resolves all symlinks and crashes on
broken symlinks. Instead it should copy symlinks as symlinks.

Fixes: https://pagure.io/pungi/issue/1084
Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2018-11-15 09:10:16 +01:00
Patrick Uiterwijk
8e88373a82 Move from yaml.load to yaml.safe_load
yaml.load is equally powerful as python pickles, and we don't
need that level of power for the ostree yaml files.
Better safe than sorry.

Signed-off-by: Patrick Uiterwijk <patrick@puiterwijk.org>
2018-11-13 21:11:02 +01:00
Lubomír Sedlář
dc692bc604 extra_iso: Stop including variant extra files
They are not always wanted, so let's not include them by default.
There's a new option to include the same files that extra files phases
uses, or alternatively they can be configured specifically and put into
the variant subdirectory.

JIRA: COMPOSE-3084
Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2018-11-09 12:06:25 +01:00
Lubomír Sedlář
7c7f997d74 gather: Expand wildcards in package names for nodeps
Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2018-11-08 08:44:44 +01:00
Lubomír Sedlář
fa752eb2b5 Configure image name per variant
Up to now it was possible to change the pattern for all images, but
there are use-cases where different variants might want different names.
For example there could be one main variant that should only have
product name in the ISO filename, but addons should still be marked with
variant name.

JIRA: COMPOSE-3041
Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2018-11-05 08:48:36 +01:00
Lubomír Sedlář
85bf5535bc init: Keep parent groups in addon comps environments
The environment in comps for a variant can refer to groups in parent
variant (either for addons, or because of other configuration). We
should not remove the groups in this case.

This requires changes in two places:
 * teaching `comps_filter` about groups that should not be removed
 * fixing writing comps so that it does not actually change the data as
   well

JIRA: COMPOSE-2612
Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2018-11-02 12:43:56 +01:00
Lubomír Sedlář
a73099d446 Support more specific config for devel modules
The initial implementation is very coarse. It enables it for all
variants and all modules. That is not always wanted.

With this patch, the config file has to explicitly list the devel
modules for each variant that should have it. The variant must be
configured also to include the non-devel module (but the module may be
in lookaside so it won't be included).

We now include module metadata in the internal lookaside repo, so that
this whole thing works if one variant is built on top of another.

JIRA: COMPOSE-3034
Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2018-10-30 15:58:35 +01:00
Lubomír Sedlář
32bb9aeabe Load supported milestones from productmd
Since 1.18 productmd will make the list available for consumers. If
possible, we should use it, and fall back to hardcoded list.

JIRA: COMPOSE-3044
Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2018-10-30 14:31:56 +01:00
Lubomír Sedlář
04715f4906 hybrid: Remove dead code
We don't explicitly add modular packages anymore, fus is supposed to
handle that.

Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2018-10-26 14:56:53 +02:00
Lubomír Sedlář
2153c5fe21 Remove dead code
These variables are not used anymore, instead it is taken from extra
data in the build.

Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2018-10-26 14:56:53 +02:00
Lubomír Sedlář
65a1779e3a 4.1.30 release
Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2018-10-26 14:27:53 +02:00
Lubomír Sedlář
e10b893adc gather: Expand wildcards in Pungi
When the configuration lists `*` in `additional_packages`, it has a
special meaning. If it's passed to fus directly, it will use it to match
all modules and RPMs that are not masked by a package available in some
default stream. Neither is good. We don't want it to match modules, and
we want even the masked packages.

The fix is to expand the wildcard to a list of NVRs and give that to
fus. It should include the package even if it is masked.

Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2018-10-26 13:16:12 +02:00
Lubomír Sedlář
fe39056431 repoclosure: Extract logs from hybrid solver
There is no repoclosure that correctly understands modules. The best
thing we can offer is the errors reported by the depsolver.

JIRA: COMPOSE-2321
Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2018-10-26 08:42:21 +02:00
Lubomír Sedlář
12f949fe84 gather: Track multilib that doesn't exist
If a multilib package fails to be added (broken dependencies, or it
doesn't exist at all), we want to track it and eventually stop the
iterations.

Merges: https://pagure.io/pungi/pull-request/1071
Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2018-10-24 08:13:56 +02:00
Jan Kaluza
5fc0f915c6 Get the NSVC from Koji module CG build metadata
Stream can contain dash sign and when MBS imports such NSVC to Koji, the
dash is replaced with underscore. The current Pungi code does not
respect that and tries to use the stream from Koji directly, which
results in wrong stream being using in some Pungi internal data.

In this PR, the NSVC is taken from module metadata section of CG Koji
build, which contains real stream including the dashes.

Merges: https://pagure.io/pungi/pull-request/1072
Signed-off-by: Jan Kaluza <jkaluza@redhat.com>
2018-10-23 15:26:37 +02:00
Lubomír Sedlář
10fa53a6ac gather: Prepare module metadata before starting depsolving
Without this we don't have artifacts from all modules when the first
modular variant is solved. That makes some modular packages appear as
bare.

Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2018-10-19 10:28:17 +02:00
Lubomír Sedlář
0c3e02eeb0 hybrid: Include modulemd from all variants in temporary repo
If there are two variants with different module sets, the missing
modulemd from variant B causeing depsolving in variant A to consider the
packages as non-modular. That is wrong.

Related: https://bugzilla.redhat.com/show_bug.cgi?id=1640125
Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2018-10-19 10:28:17 +02:00
Lubomír Sedlář
66d9c10a6f extra_iso: Include media.repo and .discinfo
JIRA: COMPOSE-2994
Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2018-10-18 16:16:39 +02:00
Lubomír Sedlář
736772f954 hybrid: Don't add debuginfo as langpacks
Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2018-10-17 10:14:04 +02:00
Lubomír Sedlář
9afb8e6801 fus: Write solvables to file
Instead of having one giant command line, write the long list into a
file and pass that to the solver.

The items on the input list are sorted for easy processing.

JIRA: COMPOSE-3012
Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2018-10-17 10:14:04 +02:00
Lubomír Sedlář
4f712259d7 hybrid: Honor filter_packages
JIRA: COMPOSE-3011
Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2018-10-17 10:14:04 +02:00
Lubomír Sedlář
111af836ea Include all test fixtures in source tarball
Listing all possible file extensions is error-prone.

Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2018-10-17 10:09:46 +02:00
Lubomír Sedlář
9d9f0add83 Drop the memory saving code
It actually still does not work if there is inheritance between
variants.

Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2018-10-16 15:35:47 +02:00
Lubomír Sedlář
844f2005a0 Save memory less agressively
We can't drop the whole package set once the first solver iteration
finishes, because it runs for each arch separately and we need the data
for each of them. We can however delete the arch specific portion.

Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2018-10-15 15:34:35 +02:00
Lubomír Sedlář
cbfb556f7c extra-iso: Use correct efiboot.img file
If the file is generated, Pungi will modify it at the end of
buildinstall phase. We need to point ISO creation to the modified file,
otherwise the checksum in .treeinfo will be incorrect.

It's sufficient to just update the graft point to correct file, copying
is not needed.

JIRA: COMPOSE-2976
Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2018-10-12 13:41:36 +02:00
Lubomír Sedlář
a00ea3d4a6 extra-iso: Fix treeinfo
Remove boot.iso references and add [media] section.

JIRA: COMPOSE-2974
JIRA: COMPOSE-2975
Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2018-10-11 13:19:07 +02:00
Lubomír Sedlář
bb6e68a853 createiso: Move code for tweaking treeinfo into a function
The function loads existing treeinfo, removes reference to boot.iso and
adds [media] section. This is the basic tweak that should happen for all
ISOs. Additional changes depend on the actual content.

Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2018-10-11 13:19:07 +02:00
Lubomír Sedlář
740df1bc6c extra-iso: Generate jigdo by default
It can be turned off by the same option that is used in createiso phase.

JIRA: COMPOSE-2962
Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2018-10-10 16:06:46 +02:00
Lubomír Sedlář
0c8702cd6d 4.1.29 release
Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2018-10-10 12:51:04 +02:00
Lubomír Sedlář
ce9ac35640 hybrid: Only include modules that are not in lookaside
If we want to include the -devel modules, the original modules should be
present for the solver. However if we put them in both local and
lookaside repos, fus will get confused. Let's not include modules that
are in lookaside in the module repo created for the solving job.

Even if the modular packages are present in the local repo, they are
identical to the ones in lookaside, and so they should not make it into
the result anyway.

Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2018-10-08 14:41:04 +02:00
Lubomír Sedlář
814103d87f Try to be more conservative about memory usage
Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2018-10-08 14:41:04 +02:00
Lubomír Sedlář
3fea217b9c hybrid: Remove modules not listed by fus
It's possible we ask to include module X, but it's in lookaside and as
such it should not be in the output. Therefore we need to remove it from
the variant.

Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2018-10-08 14:41:04 +02:00
Lubomír Sedlář
1a161982c0 gather: Make devel modules configurable
By default nothing should change. This patch adds a new config option
that enables all this new craziness:

 * it turns of applying module filters at pkgset level
 * it creates new modules and adds them to the compose

Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2018-10-08 14:41:04 +02:00
Lubomír Sedlář
06b32b5d80 pkgset: Stop prefilling RPM artifacts
Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2018-10-08 14:41:04 +02:00
Lubomír Sedlář
08d65bdde6 gather: Create devel module for each normal module
The module has same S:V:C, but the name is suffixed with `-devel`. The
module should contain all packages from the module koji tag that were
not included in the actual module.

The devel module has the same dependencies as the regular module, but
also additionally depends on the original module. The API and profiles
are cleared in the new module.

In the metadata it shows the same koji tag.

The test if package goes to the module is refactored to a function to
make work with the negated case a bit easier.

There may be unneeded multilib packages in the -devel module, because
there might be buildtime dependencies between things that we don't see.

Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>

Clear API and profiles

Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2018-10-08 14:40:13 +02:00
Lubomír Sedlář
410d0125bc pkgset: Save package set for each module
This can be used in figuring out which packages go into the module and
which not.

Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2018-10-08 14:36:43 +02:00
Lubomír Sedlář
1bff5ccfa2 fus: List lookaside repos first
This works around a bug where fus prioritizes first repo and thus could
include packages even if they were in lookaside.

Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2018-10-08 14:36:43 +02:00
Lubomír Sedlář
604ec40c8e gather: Work with repos without location_base
A repo does not necessarily have the location_base attribute if the
packages are next to the repodata. This can easily happen for lookaside
repos.

Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2018-10-08 14:36:43 +02:00
Lubomír Sedlář
e78f8d1f13 Remove extra dependencies
There is a sorted dict implementation in Productmd used to achieve the
exact same thing as Pungi does here. No need for an extra dependency.
While we're at it, we can also sort the imports.

Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2018-10-08 14:15:00 +02:00
Marek Marczykowski-Górecki
d6e72c8e61 Set repodata mtime to SOURCE_DATE_EPOCH
repodata/repomd.xml include timestamps of all the other repodata files.
Even when those files are created reproducibly, they have current
modification time. In general case this is a good thing (ease checking
if repodata cache is up to date). But in case of composing installation
image, it breaks reproducibility.
Avoid this by instructing createrepo to set mtime and revision to
$SOURCE_DATE_EPOCH.

Signed-off-by: Marek Marczykowski-Górecki <marmarek@invisiblethingslab.com>
2018-10-08 13:33:29 +02:00
Marek Marczykowski-Górecki
2aeb8de459 Make sure .treeinfo file is sorted
OrderedDict used by default by ConfigParser isn't enough because order
of entries being added may not be deterministic (depends on directory
list order). To solve this problem, use SortedDict as a base.

Signed-off-by: Marek Marczykowski-Górecki <marmarek@invisiblethingslab.com>
2018-10-08 13:33:29 +02:00
Marek Marczykowski-Górecki
d469cbfef5 Use constant MBR ID for isohybrid
If not set explicitly, isohybrid choose it randomly, which harm
reproducibility.

Signed-off-by: Marek Marczykowski-Górecki <marmarek@invisiblethingslab.com>
2018-10-08 13:33:29 +02:00
Marek Marczykowski-Górecki
a12c2b9ea0 Use xorriso instead of genisoimage
xorriso make the image reproducible (given the same input files),
including support for SOURCE_DATE_EPOCH in various metadata.

Signed-off-by: Marek Marczykowski-Górecki <marmarek@invisiblethingslab.com>
2018-10-08 13:33:29 +02:00
Marek Marczykowski-Górecki
41e144e47d Use $SOURCE_DATE_EPOCH (if set) in discinfo file
This helps the output image to be reproducible.

Signed-off-by: Marek Marczykowski-Górecki <marmarek@invisiblethingslab.com>
2018-10-08 13:33:29 +02:00
Lubomír Sedlář
cb33b0278d unified_isos: Add extra variants to metadata
Each unified ISO contains all toplevel variants, and they are listed in
the metadata multiple times (once for each variant). In each case the
metadata should include all other variants that are included on the
image.

JIRA: COMPOSE-2918
Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2018-10-05 12:01:43 +02:00
Lubomír Sedlář
aab2fc4519 extra_iso: Add list of variants to metadata
The main variant is already available, this patch adds information about
additional variants that are included in the image.

JIRA: COMPOSE-2917
Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2018-10-05 12:01:43 +02:00
Lubomír Sedlář
1aff7fc3ac linker: Simplify creating pool
The pool is created in multiple places, and the process is always to
create an instance and add workers to it. Let's abstract the loop in a
method.

Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2018-10-03 10:27:56 +02:00
Lubomír Sedlář
e2e8df3f09 gather: Hide pid of fus process
There's an environment variable that can suppress printing of PID for
every debug message. It provides us with no real information and only
makes the log larger.

JIRA: COMPOSE-2973
Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2018-10-03 10:23:39 +02:00
Lubomír Sedlář
4537001ff6 fus: Strip protocol from repo path
Only local paths are supported currently. As such, `file://` can be
stripped, and for anything else we should raise an exception.

JIRA: COMPOSE-2996
Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2018-10-03 09:47:00 +02:00
Jan Kaluza
37c89dfde6 Add 'pkgset_koji_builds' option to include extra builds in a compose
This PR adds new pkgset_koji_builds configuration option.

This option allows setting list of extra Koji build NVRs which will be
included in a compose. This is useful in two cases:

a) It allows generating standard composes with few packages update to
certain version to test how the compose behaves when the package is
updated for real.

b) It allows generating compose consisting only from particular builds
when pkgset_koji_tag = '' or None. This is useful when one want to
regenerate the compose with packages which are not tagged in single Koji
tag. This is very useful for ODCS when reproducing old composes.

Merges: https://pagure.io/pungi/pull-request/1049
Signed-off-by: Jan Kaluza <jkaluza@redhat.com>
2018-09-21 14:06:49 +02:00
Lubomír Sedlář
2a65b8fb7d ostree: Reduce duplication in tests
Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2018-09-19 13:07:03 +02:00
Lubomír Sedlář
36c347eb79 ostree: Use --touch-if-changed
There are three different cases:

 * we expect commitid and it's there
 * we expect commitid and it's missing
 * we don't expect commitid

This patch helps differentiate between the second two. In former one we
should report an error and mark the phase as failed. The latter is
perfectly fine and no error should be reported

Fixes: https://pagure.io/pungi/issue/1046
Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2018-09-19 13:07:03 +02:00
Lubomír Sedlář
93bc843682 ostree: Fix handler crash without commit ID
If there is no new commit in the repo, we should not wait for a
signature, as there is nothing to sign.

Fixes: https://pagure.io/pungi/issue/1046
Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2018-09-19 13:07:03 +02:00
Lubomír Sedlář
be81aeaa7d gather: Filter arches similarly to pkgset
There should not be multilib arches when checking if noarch package is
compatible with current arch. Otherwise we might be excluding a package
from x86_64 just because it does not work on i686.

JIRA: COMPOSE-2885
Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2018-09-14 13:27:39 +02:00
Peter Robinson
e580ad6db1 Stop shipping and remove RELEASE-NOTES
The RELEASE-NOTES hasn't been updated in years and when it was it was
only done a handful of times, clearly no one has complained, and git
history is likely more useful so just drop it.

Signed-off-by: Peter Robinson <pbrobinson@gmail.com>
2018-09-13 10:30:17 +01:00
Lubomír Sedlář
21b8f3af3c 4.1.28 release
Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2018-09-06 13:43:04 +02:00
Lubomír Sedlář
5f6ee61c70 gather: Fix multilib query for hybrid solver
The multilib library expects us to ask about the candidate package for
another arch (should I include this as multilib?) and not the current
arch (should I include other arches for this package?).

Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2018-09-05 16:04:40 +02:00
Lubomír Sedlář
a53dc6f1bb gather: Expand multilib lists for hybrid method
If there are globs in the blacklist or whitelist, we need to expand it
to full package name.

Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2018-09-05 15:08:31 +02:00
Lubomír Sedlář
1350684c31 Index arch modulemd by full NSVC
There can be multiple modules with the same name and stream. They should
all have the same version, but will have different contexts. Fus takes
only N:S as input, but should pull in all matching modules. We just need
to give it correct data in the repo.

Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2018-09-05 13:10:53 +02:00
Lubomír Sedlář
fbb739ef17 pkgset: Apply whitelist to modules in the tag
This patch changes the behaviour when both module tag and NSV?C? is
specified. The NSVC are used as a whitelist and only matching modules
will be included in the compose.

Additionally this patch adds filtering based on inheritance: when
finding the latest module for each N:S combination, only the top tag in
which the module is tagged is used. Even if a newer build is available
somewhere deeper in the inheritance, it's not going to be used.

Example inheritance and tagged modules

    f29-compose (foo:1:2018:cafe)
    └─ f29-candidate (foo:1:2019:cafe)

The compose will use 2018 version, because it's in the topmost tag.

JIRA: COMPOSE-2685
Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2018-09-03 12:19:50 +02:00
Lubomír Sedlář
833ba64c51 ostree: Wait for updated ref as well as signature
Fixes: https://pagure.io/pungi/issue/1036
Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2018-09-03 09:54:12 +02:00
Lubomír Sedlář
3419762830 extra_iso: Set unified flag in metadata
This will avoid conflict in productmd that two images share the same
attributes.

JIRA: COMPOSE-2908
Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2018-08-31 08:46:21 +02:00
Lubomír Sedlář
828557b4d6 pkgset: Respect koji event when searching for modules
In the search result, we should ignore any module build that finished
after the event that we are working with.

Fixes: https://pagure.io/pungi/issue/999
Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2018-08-30 14:58:45 +02:00
Jan Kaluza
d2f392fac8 Use dogpile.cache to cache the listTaggedRPMS calls if possible
If the same tag is queried with the same event, Pungi can cache the
response and call the API again. Particularly for small composes this
can save up significant amount of time.

Merges: https://pagure.io/pungi/pull-request/1022
Signed-off-by: Jan Kaluza <jkaluza@redhat.com>
2018-08-30 13:21:01 +02:00
Lubomír Sedlář
92968fe52d gather: Keep original rpms.json in debug mode
If we're running in debug mode and the file is already present, it
should not be modified. This means that in order to rerun the actual
gather phase the file needs to be manually deleted first. However the
much more common use is to skip gather phase (because only images should
be re-run). In that case the manifest will be preserved correctly.

JIRA: COMPOSE-2756
Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2018-08-29 15:52:45 +02:00
Lubomír Sedlář
7c5020e82d Reduce duplication in tests
Set the dummy compose into non-debug mode in a single place, and only
change it when needed.

Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2018-08-29 15:52:45 +02:00
Lubomír Sedlář
19a42792db docs: Add better description for package globs
This is used in multiple places, but not defined anywhere.

Fixes: https://pagure.io/pungi/issue/1028
Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2018-08-29 13:26:56 +02:00
Lubomír Sedlář
5346e000f0 Create non-bootable ISO for variant without buildinstall
If the configuration specifically excludes a variant from buildinstall,
but does not also disable ISO creation, we should just create a
non-bootable ISO instead of reporting a warning.

JIRA: COMPOSE-2887
Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2018-08-28 08:56:03 +02:00
Lubomír Sedlář
45fa9d3273 Clean up after yum tests
The tests create empty directories in current working directory, but
they never clean them up. Instead we can switch to a temporary location
that will be cleaned up automatically.

Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2018-08-27 09:16:40 +02:00
Lubomír Sedlář
03ee632cc8 gather: Honor module whitelist
If the modulemd contains a whitelist of packages (under buildopts), it
means the packages are possibly renamed, and we need to check that list
instead of components.rpms.

Multilib does not really work now, anything with non-native arch is
skipped.

JIRA: RCM-38019
Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2018-08-27 09:08:16 +02:00
Lubomír Sedlář
6f527ae5b9 Clarify error about non-existing module
JIRA: COMPOSE-2825
Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2018-08-24 13:03:18 +02:00
Lubomír Sedlář
a5fa4457c3 gather: Print full unresolved dependency
We should not lose the flag and version. The name is not sufficient to
fully determine the problem.

The log information printed in `pungi/gather.py` is parsed by regex in
`pungi/wrappers/pungi.py`. It handles the dependency with spaces and
versions fine.

JIRA: COMPOSE-2880
Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2018-08-24 08:38:22 +02:00
Lubomír Sedlář
9278008ba0 Fix tests on Python 2.6
It does not like the flags kwargs for re.sub(), which should not really
be needed, since \W is case insensitive anyway.

Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2018-08-17 10:44:32 +02:00
Lubomír Sedlář
0c38ecdc85 Include all test data in tarball
Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2018-08-17 09:34:56 +02:00
Lubomír Sedlář
5be2798c6b 4.1.27 release
Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2018-08-17 08:37:41 +02:00
Lubomír Sedlář
4b05e7b9fd extra-iso: Rename test data file
The file is not being included in the source tarball, which breaks
internal jenkins and will eventually cause the test to fail at RPM build
time.

Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2018-08-15 14:57:43 +02:00
Lubomír Sedlář
ac0d5e4ede createiso: Use correct python version
On some systems we need to use python3, in other places it can be
another version. Instead of guessing, let's look at shebang line in
lorax executable and use the same.

JIRA: COMPOSE-2852
Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2018-08-15 08:37:12 +02:00
Lubomír Sedlář
b85cd7ff9f ostree: Update tests for working with YAML file
Merges: https://pagure.io/pungi/pull-request/1019
Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2018-08-14 16:13:23 +02:00
Colin Walters
b5d5e8da4a pungi/ostree: Convert rpm-ostree YAML to JSON
We'd like to use YAML for future rpm-ostree work; among
other things it supports comments.

See https://pagure.io/fedora-atomic/pull-request/125
and the original https://github.com/projectatomic/rpm-ostree/pull/1377

Signed-off-by: Colin Walters <walters@verbum.org>
2018-08-14 16:13:23 +02:00
Lubomír Sedlář
2fa1f09827 createrepo: Allow passing arbitrary arguments
This could be used to enable zchunk generation, which can require up to
4 different options. Instead of hardcoding every single one, let's just
allow more direct access to the executed command.

Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2018-08-08 16:15:51 +02:00
Lubomír Sedlář
b12deab153 gather: Get modular packages from fus
Fus returns also RPMs in modules, but until latest version it only
worked if the package was in the same repo as the metadata. This changed
in latest version and now Pungi does not need to expand the list
anymore.

JIRA: COMPOSE-2779
Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2018-08-03 08:00:37 +02:00
Lubomír Sedlář
5926858b58 util: Remove escaping spaces from volume ID
This was not configurable for users, and the default was always used,
which meant no escaping. Might as well just remove the dead code.

Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2018-08-03 07:57:09 +02:00
Lubomír Sedlář
add9835b56 Allow removing non-alnum chars from volid
This mimics similar change in lorax.

JIRA: RCM-36970
Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2018-08-03 07:57:09 +02:00
Lubomír Sedlář
10bdb370ba extra-isos: Include treeinfo pointing to all variants
This will be used by Anaconda to consume multiple repos for
installation.

JIRA: RCM-36970
JIRA: COMPOSE-2753
Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>

Fixup
2018-08-03 07:57:09 +02:00
Lubomír Sedlář
90291d7c73 createiso: Use unique paths for breaking hardlinks
If the data needs to be split into multiple ISOs, we need to make sure
the paths are unique for each image. Otherwise all files will be copied
into the same directory, and once the first image is finished, the whole
staging dir is deleting. That obviously breaks the tasks that are still
in progress.

JIRA: COMPOSE-2610
Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2018-08-02 14:53:18 +02:00
Lubomír Sedlář
4d4c6555e2 gather: Detect hybrid variant with additional packages
The check if a variant is hybrid (or modular only) currently only looks
at comps groups. However it's possible there will be no comps groups,
but packages will be listed explicitly in config as additional_packages.

Relates: RCM-37979
Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2018-07-26 17:11:13 -04:00
Mohan Boddu
80c3fd1170 Include exact version of pungi in the logs
Fixes #990

Signed-off-by: Mohan Boddu <mboddu@bhujji.com>
2018-07-26 17:03:58 -04:00
Lubomír Sedlář
4ecf75295a gather: Allow empty result for gather
This only affects Yum backend, and allows to mention packages in comps
groups before they become available. This means a compose can be set up
ahead of all packages being available, and it will simply produce empty
repos.

Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2018-07-23 09:38:39 -04:00
Lubomír Sedlář
b772d4a773 gather: Add langpacks in hybrid solver
Comps file specifies a pattern for some packages. If that package is
installed, all packages matching the pattern are added as well. This can
be added to fus as another pass.

Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2018-07-23 09:08:33 -04:00
Lubomír Sedlář
16ac225013 comps: Add get_langpacks function
This also simplifies the test data by removing a lot of the langpacks.

Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2018-07-23 09:08:33 -04:00
Lubomír Sedlář
9b576bf976 pungi-legacy: Add --joliet-long option
Using `-J` each path component can only be 64 characters long. This is
not sufficient for some packages. Adding `--joliet-long` increases the
limit to 103.

Fixes: https://bugzilla.redhat.com/show_bug.cgi?id=1605103
Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2018-07-20 10:17:38 +02:00
Lubomír Sedlář
7d099012aa Fix tests for DNF 3
The configuration for modules has changed.

Lookaside handling has changed, and there are now test failures. This
is a not a bug in DNF, so we need to fix it on our side.

Relates: https://bugzilla.redhat.com/show_bug.cgi?id=1603123
Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2018-07-19 14:22:10 +02:00
Lubomír Sedlář
9ca454007a gather: Early exit for non-comps sources
When getting list of initial packages, only run the source and do
nothing else. Additional package, system-release etc. will be added only
to comps.

Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2018-07-19 09:11:35 +02:00
Lubomír Sedlář
0b9652f2d6 tests: Use unittest2 when available
Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2018-07-18 12:55:34 +02:00
Jan Kaluza
6080b45178 Fix Koji search for modules with dash in stream
MBS replaces the dash by underscore. We have to match that.

Merges: https://pagure.io/pungi/pull-request/1005
Signed-off-by: Jan Kaluza <jkaluza@redhat.com>
2018-07-18 10:31:19 +02:00
Lubomír Sedlář
23c454ff67 buildinstall: Make output world readable
This makes it possible to run a compose as non-root user, plus removes
the need for workarounds to publish the results directly.

Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2018-07-17 10:12:52 +02:00
Lubomír Sedlář
60917fdc77 buildinstall: Copy file without preserving owner
The files are generally owned by root. If the compose is running as
root, this will still create files owned by root. If it's running as
non-priviledged user, it will crash. With this patch it will work.

Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2018-07-17 10:12:52 +02:00
Lubomír Sedlář
e3de4dcccf Report failed failable deliverables as errors
It does not abort the compose, but it's still an error. It should be
marked as such in the log. This will allow easier searching for the
failures.

Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2018-07-17 09:31:50 +02:00
Lubomír Sedlář
878eaeaaf6 Stop importing PDCClient
We no longer use it anywhere, so drop the import.

Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2018-07-16 15:52:42 +02:00
Lubomír Sedlář
489bb03a3d spec: build require python-multilib
It's needed by some of our tests now.

Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2018-07-16 11:07:57 +02:00
Lubomír Sedlář
c8bd967a57 4.1.26 release
Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2018-07-16 10:37:23 +02:00
Lubomír Sedlář
ba0193ca28 gather: Add a hybrid depsolver backend
This patch adds a new gather method called `hybrid`, which uses a `fus`
binary, which must exist somewhere on the `$PATH`. It will call it
multiple times to add multilib packages.

The solver can handle packages, modules and comps groups as input.
However comps groups are never passed in. Pungi will expand it to a list
of packages to avoid issues with comps handling in fus. It ignores
optional packages, and if the group mentions a package that does not
exist, nothing else from the group is included.

Multilib is also handled outside of fus. Pungi will run it, parse the
packages from output, determines multilib packages and adds them as
input. Then it runs the solver again. This is done until nothing new is
added. Usually two passes should be enough.

Source packages and debuginfo are added as a final step. All debuginfo
packages from any included source are added. If the source or debuginfo
package is included in any lookaside repo, it will be skipped.

The tool expects to get a platform stream that should be provided for
modules to depend on. Pungi looks into the modules and gets the platform
from there. If there are more requests, an error is raised.

There is some missing functionality and options that are ignored.
Particularly these are:

 * gather_fulltree
 * gather_selfhosting
 * greedy_method

Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2018-07-16 10:21:41 +02:00
Lubomír Sedlář
2c6b784f70 Always use lookasides for repoclosure
There's no point in checking for a layered release first. If there are
no repos, the loop will simply not execute even once. If there are
lookasides configured, we want to use them no matter if the release is
layered or not.

Also the log is updated to include the actual command for easier
debugging next time.

Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2018-07-16 08:50:34 +02:00
Ken Dreyer
a509064696 doc: closing parentheses for require_all_comps_packages
"(the default)" was missing the closing parentheses character.

Signed-off-by: Ken Dreyer <kdreyer@redhat.com>
2018-07-11 09:37:29 -06:00
Lubomír Sedlář
d2849d3826 osbs: Generate unique repo names
And include variant in repo file name. The whole path is unique already,
but not the filename itself.

Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2018-07-09 13:21:58 +02:00
Sinny Kumari
1759c1ba80 Expand version field during image_build using version_generator
We can specify !VERSION_FROM_VERSION in version field during
image_build to expand it to correct release number without any label
information.

Also implemented !RELEASE_FROM_DATE_RESPIN to provide correct
release number. This helps to keep Atomic Host media files name
produced by image_build during bodhi updates compose run
consistent with nightly run.

Fixes: https://pagure.io/pungi/issue/987
Merges: https://pagure.io/pungi/pull-request/995

Signed-off-by: Sinny Kumari <sinny@redhat.com>
2018-07-09 12:56:00 +02:00
Lubomír Sedlář
d29e56c7d8 createrepo: Stop including modulemd in debug repos
Debug packages are usually installed by exact NVR, and having two repos
providing the same module (but with different packages) is confusing for
the tooling.

Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2018-06-27 13:35:58 +02:00
Lubomír Sedlář
6c14236562 Simplify iterating over module defaults
There are now two places where we need to do this, so we can simplify
the logic of finding and filtering them.

Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2018-06-27 12:19:12 +02:00
Lubomír Sedlář
98e7106f3e pkgset: Apply module filters on pkgset level
If a module says to filter a package out, we can do it immediately when
getting the build information from Koji.

This avoids a possible problem of something pulling the module package
in as a dependency, but it should also make the package set slightly
smaller.

Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2018-06-25 15:15:42 +02:00
Lubomír Sedlář
470c0ab3be init: Validate whitespace in comps groups
If a package name contains leading or trailing whitespace, it will
eventually lead to issues: pungi will try to include that group, but
since it does not exist, the packages will not make it in.

The root cause is hard to find. Better report an error immediately.

Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2018-06-25 11:58:52 +02:00
Lubomír Sedlář
096075848b createrepo: Include empty modules
A module without any RPMs is still valid and should be included. It
should also be in the metadata.

Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2018-06-22 12:54:39 +02:00
Lubomír Sedlář
38f1a8509e createiso: Break hardlinks by copying files
If a file has multiple hard links, genisoimage will put the wrong number
on the ISO. This patch can work around it by copying hard-linked files
into a temporary staging directory.

JIRA: COMPOSE-2610
Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2018-06-20 12:40:43 +02:00
Martin Curlej
d8c03f6239 pkgset: Query Koji instead of PDC
PDC is deprecated in upstream. The usecase for getting list of modules
by NS, NSV or NSVC can however be satisfied by querying modules imported
into Koji.

This makes it possible to deprecate PDC configuration.

Merges: https://pagure.io/pungi/pull-request/985
Signed-off-by: Martin Curlej <mcurlej@redhat.com>
2018-06-18 15:17:04 +02:00
Lubomír Sedlář
04f68a018f config: Report variants validity issues
If the variants file is invalid, we want to report the errors. If we
fail to load the file at all, that is fine.

Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2018-06-12 12:50:12 +02:00
Lubomír Sedlář
4a61de1e8a variants: Reject values with whitespace
If there is leading or trailing whitespace in a comps group name, it
will not be included in the compose and there will even be no error
message. Whitespace on module name results in a failure.

To avoid these errors, validating the variants file will now also check
that there is no whitespace in significant places, and abort the compose
if there a problem.

Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2018-06-12 12:48:14 +02:00
Lubomír Sedlář
fa92e54c22 osbs: Fresh koji session for getting metadata
The task can take a while to finish, and it's possible for the
authenticated session to expire in the mean time. Watching the task will
work, because that happens by spawning `koji watch-task` as subprocess.

We can work around this by creating a fresh unauthenticated session for
getting the task results.

Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2018-06-11 10:27:39 +02:00
Lubomír Sedlář
004ef31917 gather: Ignore comps in lookaside repo
This fixes a case where extra packages are pulled in.

The scenario is:

 * there's a lookaside repo which contains group G which has package P
 * we want to pull group G into the compose, but our definition of G
   does not contain P
 * lookaside repo does not contain package P
 * current package set has P

DNF depsolver will then merge the two definitions and try to get all the
packages. For most cases this is not a problem, since the package is in
the lookaside repo and will not be pulled into the compose. But in the
example above since P is not in lookaside, Pungi will put it into
current compose.

This is also ugly in the depsolving log says it includes package P
because it was in input. But checking comps file does not show it.

The result of this change is that some packages might disappear from
current composes. This can only happen if there is a lookaside which
defines groups with similar IDs, which should be very rare. In cases
where this would be a problem the fix is to explicitly add wanted
packages either to comps or to additional packages.

Fixes: https://pagure.io/pungi/issue/978
Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2018-06-08 13:32:24 +02:00
Lubomír Sedlář
eed97f357c init: Test that init phase correctly clones defaults
Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2018-06-07 10:25:35 +02:00
Lubomír Sedlář
13f5018ce1 init: Add tests for cloning module defaults
Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2018-06-07 10:25:35 +02:00
Lubomír Sedlář
cd493bc4c1 init: Add validation for module defaults
After cloning the repository with defaults, open each file and try to
check if there is more than one definition for the same module. It's not
a problem for the compose process, but consumers of the compose would
get confused and possibly explode. Better alert people early.

Conceptually this should be part of the test phase, but that would mean
waiting for the compose to finish before reporting the error. The
earlier the better.

Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2018-06-07 10:25:35 +02:00
Lubomír Sedlář
c10a4ca337 ostree-installer: Skip comps repo if there are no comps
When the compose is not using comps, we can't pass the comps to lorax,
since it doesn't exist and it would cause a crash.

Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2018-06-07 09:27:14 +02:00
Lubomír Sedlář
663a07068e kojiwrapper: Call chmod recursively
Related: https://pagure.io/pungi/issue/932
Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2018-06-04 13:11:37 +02:00
Lubomír Sedlář
71f2c61020 Add test for getting licenses from a repo
Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2018-06-04 08:26:26 +02:00
Stephen Gallagher
23ced26588 Add content_licenses to module metadata
During the createrepo phase for Modular variants, this will now
interrogate the repodata from the "work" repositories for the set of
licenses in use by each of the RPMs in a module and add those to the
metadata to be written out into the final repodata location.

Merges: https://pagure.io/pungi/pull-request/968
Signed-off-by: Stephen Gallagher <sgallagh@redhat.com>
2018-06-04 08:26:17 +02:00
Lubomír Sedlář
8b9508b027 Update virtualenv instructions
* Koji can now be installed from PyPI and it will also pull in rpm. This
  needs rpm-devel install on the system. This means we can get kobo from
  PyPI as well.
* Using print function should make it work for python 3 virtualenvs.
* Newer we need kobo in 0.6.0 at least, but newer is fine too.

Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2018-06-01 12:11:55 +02:00
Lubomír Sedlář
102fec83b3 kojiwrapper: Don't mark runroot as successful by chmod
Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2018-05-31 14:50:03 +02:00
Lubomír Sedlář
cbcebe90e1 Allow extracting koji event from another compose
When multiple composes are chained, they should reuse the same event.
However it is tricky as the value would have to be passed by hand. This
patch makes it possible to read the value from another compose (the
first one in the chain).

JIRA: COMPOSE-2571
Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2018-05-31 11:11:21 +02:00
Stephen Gallagher
ec96757707 Copy modules instead of reparsing them
The Modulemd.copy() method has been available since libmodulemd 1.1
and is much faster than dumping to a string and parsing it again.

Signed-off-by: Stephen Gallagher <sgallagh@redhat.com>
Merges: https://pagure.io/pungi/pull-request/965
2018-05-31 09:04:28 +02:00
Lubomír Sedlář
49e8aa0c7e Silence config warnings in quiet mode
It's a bit unfortunate we can't use the logger for printing these, but
there is cyclic dependency: to set up logger, we need Compose object (to
generate path to log file), but to create Compose object we need a valid
config.

JIRA: COMPOSE-2577
Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2018-05-30 15:03:07 +02:00
Lubomír Sedlář
92b5ad2e05 kojiwrapper: Make result of runroot world readable
The commands in runroot run as root every time. If they create files
that are not readable to other users, the reset of compose could have
problems with it if it does not run as root too. Particularly updates
composes in Bodhi run under apache user.

Relates: https://pagure.io/pungi/issue/932
Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2018-05-29 10:31:42 +02:00
Lubomír Sedlář
e53da69db3 osbs: Add nvr to metadata
All the components are there already separately, but having the full NVR
should simplify searching the metadata with grep.

JIRA: COMPOSE-2519
Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2018-05-28 13:16:01 +02:00
Patrick Uiterwijk
f1cd1ae562 Always get old compose with release type suffix
Signed-off-by: Patrick Uiterwijk <patrick@puiterwijk.org>
Merges: https://pagure.io/pungi/pull-request/792
2018-05-25 09:49:14 +02:00
Patrick Uiterwijk
288d9ecc90 Make ostree_installer check if buildinstall is skipped correctly
The _skipped attribute is only set after the buildinstall phase is started.

Fixes: #909
Signed-off-by: Patrick Uiterwijk <puiterwijk@redhat.com>
2018-05-24 13:25:34 +02:00
Ondrej Nosek
420b744193 4.1.25 release
Signed-off-by: Ondrej Nosek <onosek@redhat.com>
2018-05-22 14:12:31 +02:00
Lubomír Sedlář
fdea7878f1 comps-wrapper: Make tests pass on EL6
Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2018-05-22 12:34:39 +02:00
Lubomír Sedlář
a4bbf475f1 pkgset: Add option to ignore noarch in ExclusiveArch
The `add_noarch` option of `get_valid_arches` is broken and doesn't
really do anything (noarch is always present in the result).

This causes packages that have ExclusiveArch including noarch to
actually not be excluded. They should be.

Changing this globally could have a very big impact. Therefore we can
hide it behind a configuration option so that it's opt-in.

JIRA: COMPOSE-2457
Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2018-05-21 12:36:16 +02:00
Ondrej Nosek
c85d80f3c2 Handling multiple modules with the same NSV - PDC
Signed-off-by: Ondrej Nosek <onosek@redhat.com>

JIRA: COMPOSE-2510
Signed-off-by: Ondrej Nosek <onosek@redhat.com>
2018-05-21 11:24:46 +02:00
Lubomír Sedlář
b4e746aa71 createrepo: Allow disabling SQLite database
This is an optimization for Yum. DNF does not care at all.

The behaviour is configurable, but the default depends on gather
backend, as that is what users should be using to consume the packages
from the repo.

Fixes: https://pagure.io/pungi/issue/951
Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2018-05-21 08:13:29 +02:00
Lubomír Sedlář
1afb709404 init: Drop database from comps repo
It should not be needed there, since the repo is empty anyway. A test is
added for the variant specific comps repo.

Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2018-05-21 08:13:29 +02:00
Lubomír Sedlář
89d798006b createrepo: Add module arch to metadata
Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2018-05-18 08:56:22 +02:00
Lubomír Sedlář
f1b71d1eeb arch: Drop mapping ppc64 -> ppc64p7
The ppc64p7 flavour is not used anymore.

Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2018-05-16 16:25:58 +02:00
Lubomír Sedlář
5324c6441f arch: Make i386 map to i686 instead of athlon
This is used for mapping basearch to binary arch.

One use for this is when running depsolving to tell yum/dnf what arch to
work with. With this change it will get i686 instead of athlon when
working on i386 basearch.

The other use case is finding arches compatible with given basearch. The
change will remove athlon from the list for i386.

Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2018-05-16 15:22:31 +02:00
Lubomír Sedlář
2862ae0b28 ostree-installer: Use Python function to copy
This should give us better error reporting. The `copy_all` function
should preserve permissions on all files.

Relates: https://pagure.io/pungi/issue/932
Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2018-05-16 12:35:32 +02:00
Lubomír Sedlář
b2f995d516 Add a phase for creating extra ISOs
Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2018-05-16 12:20:01 +02:00
Lubomír Sedlář
4544b454f8 Stop using .message attribute on exceptions
It does not exist on Python 3. Converting the exception to string works
identically.

The validate methods on many phases are simplified by not calling the
parent (which does not do anything).

Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2018-05-15 14:17:46 +02:00
Ondrej Nosek
b2190c1c3f Validation of parameter skip_phases
It checks config file value 'skip_phases' for valid phases names.
Also checks command-line attribute 'skip-phase' of 'bin/pungi-koji'.

JIRA: COMPOSE-2493

Signed-off-by: Ondrej Nosek <onosek@redhat.com>
2018-05-15 13:30:00 +02:00
Patrick Uiterwijk
ab2faa85b3 Capture sigterm and mark the compose as DOOMED
Merges: https://pagure.io/pungi/pull-request/946
Signed-off-by: Patrick Uiterwijk <puiterwijk@redhat.com>
2018-05-15 12:36:20 +02:00
Lubomír Sedlář
057751381a createiso: Remove useless method
We call the parent, call a method without side effects and return...

Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2018-05-11 12:42:21 +02:00
Lubomír Sedlář
48d0f2f643 createiso: Refactor code into smaller functions
This way some parts of the code will be reusable. This should have no
effects on the outcome, the tests still pass without any changes needed.

Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2018-05-11 12:42:21 +02:00
Lubomír Sedlář
fc78a3cbb3 init: Stop filtering comps environments all the time
For variants that contain all packages (Fedora's Everything) we don't
want to lose any environments.

Fixes: https://pagure.io/pungi/issue/940
Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2018-05-10 10:50:21 +02:00
Patrick Uiterwijk
8f3c06bd14 Make wait-for-signed-ostree repeat the fedmsg in case the signer crashed
Signed-off-by: Patrick Uiterwijk <puiterwijk@redhat.com>
2018-05-09 23:17:59 +02:00
Lubomír Sedlář
905064775a arch: Remove mocks in tests
This was added back when rpmutils module was used. Since we migrated to
Python 3 we have included the code directly in Pungi (because it was
coming from yum which is not going to Py3 any time soon). The mocks can
be dropped.

Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2018-05-09 13:49:29 +02:00
Lubomír Sedlář
7c237c2c63 ostree-installer: Allow overwriting buildinstall
Relates: https://pagure.io/pungi/issue/909
Relates: https://pagure.io/pungi/issue/695
Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2018-05-07 15:22:01 +02:00
Lubomír Sedlář
543154d597 ostree-installer: Work with skipped buildinstall
Fixes: https://pagure.io/pungi/issue/909
Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2018-05-07 12:29:20 +02:00
Lubomír Sedlář
076be762ec createrepo: Use less verbose logs
There is really no need to write out megabytes of logs that are not
really interesting. This should also help the parallelization. With the
verbose log createrepo fills the output buffer and needs to wait for the
busy python program to read it first.

Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2018-05-07 08:38:23 +02:00
Lubomír Sedlář
bd9a0ceda2 pkgset: Create global repo in parallel to merging pkgsets
The work in creating the repo is done in a separate process. This can
easily use two threads.

Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2018-05-07 08:38:23 +02:00
Lubomír Sedlář
dc557b809a ostree-installer: Copy files without owner
The files created in koji runroot will be owned by root. If the compose
is done under different user, there could be a problem with copying the
files preserving the owner. Let's just copy them without that.

Fixes: https://pagure.io/pungi/issue/932
Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2018-05-04 14:18:24 +02:00
Lubomír Sedlář
99b6e44a30 createiso: Skip if buildinstall fails
If the ISO is meant to be bootable but lorax fails, there's no point in
creating the ISO as it will not behave as expected.

Bug: https://bugzilla.redhat.com/show_bug.cgi?id=1574585
Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2018-05-04 08:45:45 +02:00
Lubomír Sedlář
490f079c44 Update tests for libmodulemd 1.4.0
It got a little picky about allowed inputs. We need full RPM NEVRA in
all tests.

Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2018-05-02 15:36:52 +02:00
Lubomír Sedlář
182a5a399b 4.1.24 release
Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2018-05-02 14:16:44 +02:00
Lubomír Sedlář
ed8fffb6d1 koji-wrapper: Log failed subtasks
If the parent task is successful, there can still be failed child tasks
for failable arches. We need to log those and potentially mark the
compose as incomplete.

Fixes: https://pagure.io/pungi/issue/874
Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2018-05-02 08:27:44 +02:00
Lubomír Sedlář
f298121bbc Update compose status when config validation fails
If the config is syntactically correct, but it contains some issues
discovered in `validate` method of any phase, we need to raise an
exception, not exit immediately.

JIRA: COMPOSE-2431
Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2018-04-27 07:41:45 +02:00
Lubomír Sedlář
e419100d5f pkgset: Allow different inheritance for modules
With one compose combining traditional and modular content there might
be different requirements for tag inheritance. This patch adds a new
option that controls whether builds in modular tags should be inherited.
It defaults to False, which is the right option for current MBS
behavior.

JIRA: COMPOSE-2148
Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2018-04-26 14:42:30 +02:00
Lubomír Sedlář
d3938d7c04 ostree: Recognize force_new_commit option in old config
Fixes: https://pagure.io/pungi/issue/925
Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2018-04-26 13:22:21 +02:00
Lubomír Sedlář
68f80751cf modules: Correctly report error for unexpected modules
The code checked with `assert` that there is only one module matching
given NSV. In actual package that would not do anything and we would
silently pick the first value.

Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2018-04-26 09:26:37 +02:00
Lubomír Sedlář
b8555b7869 modules: Allow context in variants XML
JIRA: COMPOSE-2508
Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2018-04-26 09:26:37 +02:00
Lubomír Sedlář
8c22236ad4 gather: Print profiling information to stderr
On stdout it gets mixed with listing of gathered packages. This has no
effect in a real pungi-koji run, where both streams are merged into a
single file which is then parsed, but in manual debugging runs it's a
little obnoxious.

Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2018-04-25 14:21:09 +02:00
Jan Kaluza
4d53a5c9ca pkgset: Stop creating database for repodata
This speeds up the compose quite a bit and there is no need for the
database anyway.

Merges: https://pagure.io/pungi/pull-request/922
Signed-off-by: Jan Kaluza <jkaluza@redhat.com>
2018-04-25 14:19:27 +02:00
Lubomír Sedlář
eaf58f7d40 gather: Use another variant as lookaside
Create a temporary repository and add it as another lookaside in the
compose.

JIRA: COMPOSE-2426
Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2018-04-23 10:51:56 +02:00
Lubomír Sedlář
ea0964eeef buildinstall: Use metadata if skipped
If the phase is skipped, it could mean that we are doing a debug run and
we don't want to mess up the .treefile by missing arch specific images.
The other alternative is that the phase was really skipped, in which
case there will be no files generated and we already handle that fine.

Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2018-04-23 10:42:33 +02:00
Jan Kaluza
9915c7d644 Allow reusing pkgset FileCache from old composes.
Signed-off-by: Jan Kaluza <jkaluza@redhat.com>
2018-04-23 09:57:03 +02:00
Lubomír Sedlář
1e972885f5 validation: Populate dict of all variants
Until now only list of top level variants was enough, but for variant
as lookaside we need a dict including even child variants.

Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2018-04-20 10:03:01 +02:00
Lubomír Sedlář
c07a4d64a1 gather: Stop pulling debuginfo and source for lookaside packages
If a package is in lookaside, we don't really need a debuginfo nor
source for it. Definitely we should not pull them from the package set
even if there is some suitable package. Therefore we should include them
in the output but marked as lookaside.

Fixes: https://pagure.io/pungi/issue/915
Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2018-04-19 08:26:42 +02:00
Lubomír Sedlář
58afece033 Only use comps repo if we really have comps
Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2018-04-17 15:32:02 +02:00
Lubomír Sedlář
267ff86f04 pkgset: Use modules PDC API
Instead of the deprecated and confusing unreleasedvariants.

JIRA: COMPOSE-2363
Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2018-04-17 12:16:18 +02:00
Patrick Uiterwijk
527394707d Access ci_base date via compose
Signed-off-by: Patrick Uiterwijk <puiterwijk@redhat.com>
2018-04-15 02:16:23 +02:00
Lubomír Sedlář
a217eea24e Allow filtering comps for different variants
We already filter for arches, so this just extends the filter to work
with variants as well.

Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2018-04-13 14:56:06 +02:00
Lubomír Sedlář
d7021c5688 comps: Make filtering by attribute more generic
Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2018-04-13 14:56:06 +02:00
Lubomír Sedlář
44c1e2dc6f pkgset: Dump downloaded modulemd to logs
This will allow easier inspection.

JIRA: COMPOSE-2316
Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2018-04-13 14:44:51 +02:00
Lubomír Sedlář
4596020ecd Fix PEP8 warning about if not x in y
Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2018-04-13 14:44:51 +02:00
Ondrej Nosek
cb3d36be5d Variant as a lookaside - configuration
Relates: COMPOSE-2425

Signed-off-by: Ondrej Nosek <onosek@redhat.com>
2018-04-13 14:14:43 +02:00
Lubomír Sedlář
15ccd309fa Remove comps from arch repo
The comps could potentially be different in different variants, so
instead we can create the comps repo for every variant separately and
use two repos instead of one (packages in one repository, comps in
another one).

Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2018-04-12 13:52:36 +02:00
Lubomír Sedlář
9daaf1e038 init: Stop creating module defaults dir twice
JIRA: COMPOSE-2447
Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2018-04-12 13:38:36 +02:00
Lubomír Sedlář
9f583eeb6d gather: Reduce logs from DNF gathering
The log file used to contain a dump of the configuration, which could
potentially be very large. This patch removes data that is directly
visible in the input kickstart file. Instead it just displays the number
of items.

Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2018-04-12 07:49:44 +02:00
Lubomír Sedlář
d1d074ce28 Clone module defaults into work/ directory
We can not rely on config_dir being writable, and should not modify
anything in there anyway.

Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2018-04-11 16:29:36 +02:00
Petr Šabata
8b24c7cbf3 Update the configuration JSON schema for module_defaults_dir
Signed-off-by: Petr Šabata <contyk@redhat.com>
2018-04-11 16:29:18 +02:00
Petr Šabata
8238011bdd Update configuration docs with module_defaults_dir
Signed-off-by: Petr Šabata <contyk@redhat.com>
2018-04-11 16:29:18 +02:00
Petr Šabata
b9523ff5b0 Handle relative paths in module_defaults_dir
This now handles strings as well as sct_dicts with type=file that
include relative paths.

Signed-off-by: Petr Šabata <contyk@redhat.com>
2018-04-11 16:29:18 +02:00
Petr Šabata
0e7f770fb7 Include module defaults in the repodata
If the compose configuration includes the module_defaults_dir (an
scm_dict), clone the directory, read the module defaults contained
therein and include relevant defaults in the combined modulemd file.

Only defaults for modules present in the variant are included.

This requires libmodulemd 1.2.0+.

Merges: https://pagure.io/pungi/pull-request/891
Signed-off-by: Petr Šabata <contyk@redhat.com>
2018-04-11 16:29:17 +02:00
Lubomír Sedlář
506ac99f62 Add *.in fixtures to tarball
The recent comps related commit added a fixture file with new extension
which is not getting included in the source tarball and therefore causes
tests to fail.

Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2018-04-10 08:33:41 +02:00
Lubomír Sedlář
8f1beeb54b init: Always filter comps file
Even for Everything we want to filter the comps file to make sure we
remove the stuff that is not compatible with current arch. All groups
are still preserved in that case.

This allows us to do the filtering once in init phase than just use the
prepared file in comps source.

Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2018-04-10 08:21:56 +02:00
Lubomír Sedlář
6daee968ae docs: Describe comps processing
Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2018-04-10 08:21:56 +02:00
Lubomír Sedlář
aab3b04b08 gather: Use comps for given variant
The file for variant is filtered to only contain relevant parts.

Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2018-04-10 08:21:56 +02:00
Lubomír Sedlář
064f922117 docs: Fix typo
Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2018-04-10 08:21:56 +02:00
Lubomír Sedlář
c705488505 Add all packages to whitelist for hybrid variant
If a variant contains both modules and comps groups, we need to include
builds from the compose tag in the package whitelist. However only
packages that are not already provided by any module should be added.

JIRA: COMPOSE-2435
Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2018-04-09 13:10:36 +02:00
Lubomír Sedlář
de231064b7 comps: Add tests for CompsFilter
All use cases that are actually used by pungi-koji are tested. There is
missing coverage for

 * keeping only items with matching arch
 * not reindenting the file

These aren't currently used and should be removed in the future, but
there may be other tools depending on the comps_filter executable.

Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2018-04-09 07:48:28 +02:00
Lubomír Sedlář
7ea4c33d87 comps: Move filtering into wrapper module
The code should not live directly in the executable, that makes it very
hard to test.

Other than the move there is no functional change.

Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2018-04-09 07:48:28 +02:00
Ondrej Nosek
7798174b30 Tests fail if unittest2 library is missing
Merges: https://pagure.io/pungi/pull-request/894
Signed-off-by: Ondrej Nosek <onosek@redhat.com>
2018-04-09 07:47:17 +02:00
Robert Marshall
6454f30714 Add unittest2 and rpmdevools to contributing doc
- Add rpmdevtools and python-unittest2 to the list of packages
  required to set up a testing environment

Signed-off-by: Robert Marshall <rmarshall@redhat.com>
2018-04-06 19:27:22 -04:00
Lubomír Sedlář
f38770c67d pkgset: Construct UID for PDC modules
We can't rely on the UID to be correctly joined with colons. There may
be historical data that still uses dashes.

Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2018-04-06 10:47:22 +02:00
Lubomír Sedlář
b3a3575ecf gather: Simplify creating temporary directory
There is no need to create the directory in work/, as it will get
deleted immediately. Let's move it to /tmp and use the context manager
to clean it up.

Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2018-04-05 15:21:39 +02:00
Lubomír Sedlář
d9e2101b08 buildinstall: Add extra repos
A new configuration option is added that allows users to point lorax to
extra repositories. This can be handy if some tools to create the
bootable image are not part of the product itself.

Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
JIRA: COMPOSE-2253
2018-04-05 07:56:20 +02:00
Lubomír Sedlář
1436ea2b03 tests: Use dummy modulesdir for DNF
Otherwise it tries to ensure it exists, and since the default is
/etc/dnf/modules.d, it's causing problems if the directory does not
exist and user does not have permissions to create it.

Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2018-04-04 12:23:43 +02:00
Ondrej Nosek
1f0739831c Update tests for Python 2.6
Signed-off-by: Ondrej Nosek <onosek@redhat.com>
2018-03-29 16:34:52 +02:00
Ondrej Nosek
f3b5a66614 4.1.23 release
Signed-off-by: Ondrej Nosek <onosek@redhat.com>
2018-03-29 14:11:58 +02:00
Ondrej Nosek
9b46377fb6 Update documentation section 'contributing'
Signed-off-by: Ondrej Nosek <onosek@redhat.com>
2018-03-29 11:23:57 +02:00
Ondrej Nosek
e3aa2f769b Write module metadata
Signed-off-by: Ondrej Nosek <onosek@redhat.com>
2018-03-29 09:47:55 +02:00
Jan Kaluza
c6d507582a Support multilib in GatherSourceModule
Signed-off-by: Jan Kaluza <jkaluza@redhat.com>
2018-03-28 13:38:46 +02:00
Lubomír Sedlář
071792bdd0 ostree: Always substitute basearch
When ref is not modified via pungi config, we read it from the treefile
and substitute in basearch.

When pungi is configured to replace it, it modifies the treefile and
then used the value from config to avoid parsing the file. This however
did not substitute the basearch value.

We can simply use one code path for getting the value. This will work
for both cases.

Fixes: https://pagure.io/pungi/issue/866
Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2018-03-21 15:37:15 +01:00
Patrick Uiterwijk
f814651d91 If sigkeys is specified, require at least one
Merges: https://pagure.io/pungi/pull-request/880
Signed-off-by: Patrick Uiterwijk <puiterwijk@redhat.com>
2018-03-21 15:34:58 +01:00
Jan Kaluza
9be2d6a920 Allow setting <kojitag/> in <modules/> in variants.xml to get the modules from this Koji tag.
Signed-off-by: Jan Kaluza <jkaluza@redhat.com>
2018-03-21 14:33:45 +01:00
Jan Kaluza
1574f306c7 Move Modulemd import to pungi/__init__.py to remove duplicated code.
Signed-off-by: Jan Kaluza <jkaluza@redhat.com>
2018-03-20 12:59:17 +01:00
Jan Kaluza
3f71cdd384 Use Modulemd.Module for 'variant.arch_mmds' instead of yaml dump
Signed-off-by: Jan Kaluza <jkaluza@redhat.com>
Merges: https://pagure.io/pungi/pull-request/872
2018-03-19 14:47:03 +01:00
Lubomír Sedlář
6bff4bd10e Fix modular content in non-modular variant
When allowing empty list of modules, the check for variant tags got
broken, causing Everything to no longer have an associated list of
allowed packages.

Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
Relates: https://pagure.io/pungi/issue/862
2018-03-16 14:47:10 +01:00
Jan Kaluza
fedce5dff1 Remove the filtered RPMs from module metadata even in case all RPMs are filtered out.
Signed-off-by: Jan Kaluza <jkaluza@redhat.com>
2018-03-15 11:13:39 +01:00
Lubomír Sedlář
5c902592ae pkgset: Allow empty list of modules
This should indicate that it's a modular variant, but there is no
modular content yet. We don't want to treat that as Everything.

The end result will be an empty repository.

Fixes: https://pagure.io/pungi/issue/871
Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2018-03-14 14:49:09 +01:00
Lubomír Sedlář
95bb147015 buildinstall: Add option to disable it
Fixes: https://pagure.io/pungi/issue/854
Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2018-03-13 15:54:52 +01:00
Jan Kaluza
340ae4d286 Use libmodulemd instead of modulemd Python module
Merges: https://pagure.io/pungi/pull-request/851
Signed-off-by: Jan Kaluza <jkaluza@redhat.com>
2018-03-12 13:07:33 +01:00
Lubomír Sedlář
56e00505e0 gather: Fix package set whitelist
We need to include all relevant arches, not just the base one (including
noarch and src). However the list can be shortened by only listing
NEVRs, because that should be unique.

Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2018-03-09 15:53:31 +01:00
Lubomír Sedlář
c83316da31 pkgset: Merge initial package set without checks
For the first pass we don't need to filter out exclusive architectures,
and we don't need to exclude source packages without any binary
packages. We just want to merge the two package sets as fast as
possible.

Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2018-03-08 14:29:23 +01:00
Lubomír Sedlář
b393a4246b pkgset: Remove check for unique name
We now have a way to select even older version of package (since the
newer one can be left out of the whitelist), so we can include multiple
versions of the same package into global package set.

Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2018-03-08 14:29:23 +01:00
Lubomír Sedlář
a03a46a078 gather: Honor package whitelist
Basically everything not on the list is excluded. This has to be applied
before we filter only the latest versions (otherwise we could lose
packages that are on the whitelist).

Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2018-03-08 14:29:23 +01:00
Lubomír Sedlář
41d0139b39 Write package whitelist for each variant
If we have a package set for the variant (which happens if there are
modules), include a list of all NEVRAs in the pungi kickstart.

This can be used to make sure only packages from correct tag get into
the compose. If two packages with same name but different version get
into the compose, this can help get even older version into a particular
variant.

Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2018-03-08 14:29:23 +01:00
Lubomír Sedlář
11c2af3246 image-build: Accept tar.xz extension for docker images
Fixes: https://pagure.io/pungi/issue/863
Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2018-03-08 09:07:48 +01:00
Lubomír Sedlář
6514dc85f3 pkgset: Correctly detect single tag for variant
We need to check tags for the variant, not for the whole compose. This
results in merge always being done even if there is a single tag. For
f29 tag in Fedora this takes about 2 hours for each variant.

Relates: https://pagure.io/pungi/issue/860
Relates: https://bugzilla.redhat.com/show_bug.cgi?id=1551653
Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2018-03-06 09:56:31 +01:00
Lubomír Sedlář
bd852f4059 Remove comps groups from purely modular variants
The comps source should not return all groups when there are only
modules defined. This fixes part of the problem: non-modular packages
will not go in by default.

The second part is the comps file in the created repository. It will be
filtered to not contain any groups (because packages from there will not
be in the repo).

Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2018-03-02 08:46:23 +01:00
Lubomír Sedlář
3201648c37 gather: Allow filtering debuginfo packages
This already works on YUM backend, and this patch makes it work for DNF
as well.

Both native and multilib debuginfo and debugsource packages will be
excluded. This matches the yum behavior.

Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2018-02-28 10:07:42 +01:00
Ondrej Nosek
660c04368b Move ostree phase and pipelines for running phases
Signed-off-by: Ondrej Nosek <onosek@redhat.com>

Related: https://pagure.io/pungi/issue/778
2018-02-26 13:43:44 +01:00
Ondrej Nosek
5c081cb545 Other repo for OstreeInstaller
OstreeInstaller phase will be moved to a different timeslot
and therefore needs different repo not to depend on Gather
phase which runs at the same time.

Related: https://pagure.io/pungi/issue/778

Signed-off-by: Ondrej Nosek <onosek@redhat.com>
2018-02-26 13:10:36 +01:00
Jan Kaluza
18d005e593 Add modulemd metadata to repo even without components
There is a valid use case for modules without any RPMs in them. This
patch makes it possible to include such modules in the repodata.

Merges: https://pagure.io/pungi/pull-request/856
Signed-off-by: Jan Kaluza <jkaluza@redhat.com>
2018-02-26 07:22:41 +01:00
Adam Williamson
a1d559fb93 Correct fix for volume ID substition sorting by length
The previous attempt - caed78e - is not really correct. It sorts
the dict item tuples according to the alphabetical sort order of
the first item of each tuple (reversed). This will always work
when both substitutions *start* with the same characters, as in
the case of two strings that start with the same characters but
have a different length, the shorter one sorts alphabetically
first, and we reverse that. But it is not safe if the shorter
substitution doesn't start with the same characters, as in the
case I put in the tests: we should sort 'zzzaaaaaazzz' before
'aaaaaa' (and hence apply the 'zzzaaaaaazzz' substitution to a
volume ID that contains that string and not the 'aaaaaa' one),
but the previous commit did not.

Signed-off-by: Adam Williamson <awilliam@redhat.com>
2018-02-23 14:48:04 -08:00
Ondrej Nosek
caed78e11a Ordering processing for volume ID substitutions
Related: https://pagure.io/pungi/issue/840

Signed-off-by: Ondrej Nosek <onosek@redhat.com>
2018-02-22 16:46:58 +01:00
Jan Kaluza
7ee920a085 Disable multilib for modules
Signed-off-by: Jan Kaluza <jkaluza@redhat.com>
2018-02-22 11:54:02 +01:00
Lubomír Sedlář
a49704b2b8 scm: Stop decoding output of post-clone command
There is no guarantee that it will print any text. We don't even need
the output, we just print it to error log if there is a problem.

Fixes: https://pagure.io/pungi/issue/847
Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2018-02-20 12:18:48 +01:00
Lubomír Sedlář
e557dfd61a Remove useless shebang
The module is not executable. This will remove a warning from rpmlint at
RPM build time.

Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2018-02-20 10:13:09 +01:00
Owen W. Taylor
303fb29a6c source_koji.py: Properly handle unset pkgset_koji_tag
In one place, there was an explicit check if pkgset_koji_tag was set,
in another it was blindly referenced and assumed to be a list (with
accidental semi-success for a scalar.)

Signed-off-by: Owen W. Taylor <otaylor@fishsoup.net>
2018-02-15 15:55:13 -05:00
Lubomír Sedlář
cc8c7a702c pkgset: Only use package whitelist if enabled
Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2018-02-14 10:33:36 +01:00
Jan Kaluza
ef058d1f9b Fail early if input packages are unsigned
Use 'get_packages_to_gather' to fail early if these packages are not
signed with right key. This prevents us from having to wait for the
repo to be created and depsolving to finish. Unsigned dependencies will
still be reported later than previously.

Signed-off-by: Jan Kaluza <jkaluza@redhat.com>
2018-02-13 12:35:55 +01:00
Jan Kaluza
c75f4a1e96 Allow composing from tag with unsigned packages
There can be packages in the tag that will not end up in the compose.
Instead of failing immediately with error, this patch delays the check
until after depsolving finishes and only checks packages that will
really be included.

This is not an issue for nodeps compose, as that already pulls in only
packages that will be composed and nothing else.

Merges: https://pagure.io/pungi/pull-request/843
Signed-off-by: Jan Kaluza <jkaluza@redhat.com>
2018-02-13 12:35:17 +01:00
Ondrej Nosek
c7cc200246 Ostree can use pkgset repos
Related: https://pagure.io/pungi/issue/778

Signed-off-by: Ondrej Nosek <onosek@redhat.com>
2018-02-08 15:23:15 +01:00
Lubomír Sedlář
364d7f5229 Support multiple sources in one variant
With this patch the gather_source option is no longer used. Instead, all
sources are always used. If they return at least some input packages,
then a configured method is used and the returned lists of packages from
all sources are merged.

The method used for gathering can be configured for each variant and
gather source separately.

Additional packages are only added to the comps source.

Each gathering step is logged separately. All the logs are preserved for
later inspection.

Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2018-02-01 14:31:09 +01:00
Lubomír Sedlář
0074fe3f2c gather: Set lookaside flag focorrectly
For sources and debuginfo package the flag should be set based on the
repo we pull that particular RPM from, not for the corresponding binary
package.

There could be a case where they come from different repos, so this
would cause problems.

Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2018-01-25 15:54:00 +01:00
Lubomír Sedlář
e8fa2a13b1 gather: Try getting srpm from the same repo as rpm
When the same package is contained in the main repo for depsolving as
well as in a lookaside repo, there was a chance that we would pick a
package from main repo, but corresponding source from lookaside.
This would cause a crash when trying to link the packages into the
compose.

A solution is to try to get source rpm from the same repo as the binary
package. Only when it's not available there we get some other one.

Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2018-01-25 13:52:55 +01:00
Ondrej Nosek
2ae056e021 Minor correction for python backward compatibility
Signed-off-by: Ondrej Nosek <onosek@redhat.com>
2018-01-25 13:28:08 +01:00
Ondrej Nosek
f1f6ca74f1 4.1.22 release
Signed-off-by: Ondrej Nosek <onosek@redhat.com>
2018-01-24 10:11:30 +01:00
Ondrej Nosek
fbeb14344f Better INFO messages about modules
Relates: https://pagure.io/pungi/issue/779

Signed-off-by: Ondrej Nosek <onosek@redhat.com>
2018-01-22 17:23:31 +01:00
Lubomír Sedlář
778dbaef73 Updates composes should be marked as supported
Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2018-01-19 13:13:42 +01:00
Lubomír Sedlář
121ffb403f pkgset: Only add missing packages from global tag
Background story: if a compose is combining modular and traditional
compose, the configuration will contain multiple Koji tags to build
package set from (one tag for each module, plus at least one tag for the
traditional content). However some packages might be present in multiple
tags, and if the package set contains both, there's no way to control
which one will end up in the compose.

The solution for this is to give preference to the modular compose. If a
package with the same name exists in multiple tags, we only take the
first one we find. This relies on ordering of collected tags: modular
ones are always first, and traditional tags are at the end of the list.

If there are multiple modules that contain the same package, only one of
them will be used, which is not correct. Allegedly this should not
happen. In any case such use case does not work without this patch
either, so we're not losing anything.

Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2018-01-17 16:57:22 +01:00
Ondrej Nosek
f301158974 ostree/utils: Drop timestamps from generated repo names - tests
Issue: https://pagure.io/pungi/issue/811

Signed-off-by: Ondrej Nosek <onosek@redhat.com>
2018-01-17 16:48:22 +01:00
Colin Walters
3427d6abe2 ostree/utils: Generate a single pungi.repo file, use repo-<num> IDs
Ideally, pungi would generate repository IDs like `fedora-updates`
or so, and we'd have versioning inside the rpm-md.  But for now
let's do this to avoid invalidating rpm-ostree's change detection.

Closes: https://pagure.io/pungi/issue/811
Signed-off-by: Colin Walters <walters@verbum.org>
2018-01-17 16:48:22 +01:00
Colin Walters
b2bdc8a608 ostree/utils: Drop timestamps from generated repo names
Since we drop these files in a separate workdir each time,
there's no need to datestamp them.  Doing so is part of the
cause for invalidating's rpm-ostree input change hashing.

Issue: https://pagure.io/pungi/issue/811
Signed-off-by: Colin Walters <walters@verbum.org>
2018-01-17 16:48:22 +01:00
Lubomír Sedlář
5cc612f966 gather: Do not require variant for module source
Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2018-01-17 14:06:56 +01:00
Lubomír Sedlář
df27164c1c gather: Comps source should not crash without comps file
There just isn't anything to return.

Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2018-01-17 14:02:46 +01:00
Lubomír Sedlář
670a68a5b8 gather: JSON source returns nothing without configuration
Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2018-01-17 14:02:46 +01:00
Lubomír Sedlář
61a3be2307 buildinstall: Fix treeinfo generating on failure
When buildinstall fails, there will be no lorax generated files copied
into the compose directory. However they may still be mentioned in the
.treefile in work/ subdirectory where lorax runs.

To avoid possible issues, we should use the lorax created .treeinfo only
if the run was successful.

Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2018-01-17 13:57:49 +01:00
Jan Kaluza
930c2f1a42 Add buildinstall_use_guestmount boolean option
Signed-off-by: Jan Kaluza <jkaluza@redhat.com>
2018-01-16 09:18:35 +01:00
Lubomír Sedlář
68a1370036 gather: Use arch packages in nodeps method
We already filtered a list of packages compatible with the architecture.
There's no need to do that again (with bugs). Instead of using the
global package set we should just restrict the code to an arch package
set.

This should not break anything. If a package is included such that it's
in global but not arch package set, the compose would crash as linking
packages takes paths from the arch package set.

Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2018-01-15 09:55:51 +01:00
Lubomír Sedlář
f4c3d2423d pkgset: Always use global tag if specified
Use global koji tag for populating package set even for modular
composes. To preserve backwards compatibility value "not-used" is
ignored. This should however be fixed in the configuration to simply not
specify the option at all.

Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2018-01-12 15:50:21 +01:00
Lubomír Sedlář
03293c725b config: Make pkgset_koji_tag optional
There are valid use cases for not specifying this option: specifically a
modular compose will get the tags to use from modules listed in the
variants file.

Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2018-01-12 15:50:21 +01:00
Ondrej Nosek
51cd359057 ostree: Add force_new_commit option - test added
Relates: https://pagure.io/pungi/issue/811

Signed-off-by: Ondrej Nosek <onosek@redhat.com>
2018-01-11 15:08:07 +01:00
Colin Walters
161b7f974b ostree: Add force_new_commit option
Followup from discussion in: https://pagure.io/pungi/issue/811

It's likely now that for Fedora Atomic Host we'll use this, to work
around other issues, after we fix the FAW change detection.

Signed-off-by: Colin Walters <walters@verbum.org>
2018-01-11 15:03:36 +01:00
Lubomír Sedlář
5cc54cd587 gather: Fix checking string type
There is no unicode on Python 3, we should use six to hide this detail.

Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2018-01-10 13:50:21 +01:00
Ondrej Nosek
d4d264eb33 Improve logging for unsigned packages
Relates: https://pagure.io/pungi/issue/820

Signed-off-by: Ondrej Nosek <onosek@redhat.com>
2018-01-03 11:08:00 +01:00
Ondrej Nosek
2152e7ea26 Fall back to mount if guestmount is not available
Relates: https://pagure.io/pungi/issue/803

Signed-off-by: Ondrej Nosek <onosek@redhat.com>
2018-01-02 17:13:47 +01:00
Ondrej Nosek
116e7ca3bd El-Torito boot information on s390x
Relates: https://github.com/rhinstaller/lorax/pull/236

Signed-off-by: Ondrej Nosek <onosek@redhat.com>
2017-12-14 10:08:30 +01:00
Ondrej Nosek
59c162d46f Remove strace from buildinstall runroot
The package is not really needed.

Relates: https://pagure.io/pungi/issue/799

Signed-off-by: Ondrej Nosek <onosek@redhat.com>
2017-12-11 17:36:28 +01:00
Ondrej Nosek
ba3adf9bc4 Merge #818 doc: move "Phases" up, "Contributing" down 2017-12-11 08:54:32 +00:00
Ken Dreyer
6c3245bdee doc: fix "Miscellaneous" spelling in Config section
Signed-off-by: Ken Dreyer <kdreyer@redhat.com>
2017-12-08 13:46:14 -07:00
Ken Dreyer
d66abc3aea doc: move "Phases" up, "Contributing" down
The "Phases" section breaks down what Pungi does in detail. Place it
towards the top of the documentation table of contents.

The "Contributing" and "Testing" sections are relevant to developers,
not all users, so move them to the end.

Signed-off-by: Ken Dreyer <kdreyer@redhat.com>
2017-12-08 13:43:39 -07:00
Lubomír Sedlář
25907f61ce 4.1.21 release
Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2017-12-06 13:43:10 +01:00
Lubomír Sedlář
e15a49defd tests: Use correct python version for config validation test
When tests are running using Py3, the script should be called with Py3
as well.

Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2017-12-06 13:26:43 +01:00
Lubomír Sedlář
d5a0316877 Use dnf backend for repoclosure on PY3
When yum is not available, it makes no sense to offer it as an option.

Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2017-12-06 13:26:43 +01:00
Lubomír Sedlář
60cc3e5d55 Drop checks for git and cvs
This essentially forces everyone to install cvs even though they most
likely don't need it. There is no easy way to check what is actually
going to be needed, so let's just put the responsibility of decoding a
potential error message to users.

Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2017-12-06 13:26:43 +01:00
Lubomír Sedlář
fa4d728230 Relax check for gettext
It's only used in productimg phase. We don't have to check for it on
every run.

Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2017-12-06 13:26:43 +01:00
Lubomír Sedlář
aa9c137412 Drop check for repoquery command
There is no place that would possibly call it, so we can drop the check
and function for generating cli.

Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2017-12-06 13:26:43 +01:00
Lubomír Sedlář
001ae1d7b4 Use modifyrepo_c if possible
When configured to use createrepo_c, we should also use modifyrepo_c.
That allows us to relax the check for createrepo package.

Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2017-12-06 13:26:43 +01:00
Lubomír Sedlář
970143e59f pkgset: Add SRPMs to whitelist
When cherry picking packages from Koji tag, we need to make sure that
for every binary package we always have a corresponding source package.
Even if it does not go into the compose, we need it to get values for
Exclusive or Exclude Arch tags.

This means we need to process the binary packages first and only then
look at source ones. Instead of sorting a potentially very long list,
let's just iterate twice.

Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2017-12-06 13:23:31 +01:00
Lubomír Sedlář
cf77a6e413 modules: Allow multilib
The list of RPMs in a module can contain multilib packages, but they are
never included because we only ask for compatible arches without
multilib. For x86_64 that only adds noarch, but not i686.

Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2017-12-06 13:17:53 +01:00
Ondrej Nosek
9642c1171c add ability to specify ostree ref in OSTREE phase - update
Additionally ostree_ref (if parameter is given) should be placed into treefile.

Relates: https://pagure.io/pungi/issue/777

Signed-off-by: Ondrej Nosek <onosek@redhat.com>
2017-12-04 18:07:36 +01:00
Ondrej Nosek
a6c65e026a add ability to specify ostree ref in OSTREE phase
It allows specify what ref we want this compose to commit to.
New parameter 'ostree_ref' overrides the default value from the treefile json.

Relates: https://pagure.io/pungi/issue/777

Signed-off-by: Ondrej Nosek <onosek@redhat.com>
2017-12-04 09:27:19 +01:00
Jan Kaluza
953fb4c54c buildinstall: Allow using external dire for runroot task
A new `buildinstall_topdir` option allows using buildinstall even when
the compose is created on a different volume that Koji is using.

The files are created in this external directory and then copies into
the usual location.

Merges: https://pagure.io/pungi/pull-request/807
Signed-off-by: Jan Kaluza <jkaluza@redhat.com>
2017-11-30 10:55:52 +01:00
Lubomír Sedlář
cf114a7fab pkgset: Remove package skip optimization for bootable products
If buildinstall is supposed to run, we can't pick only some packages
from the tag. The temporary repo is used as a source for lorax. There
could very well be packages not meant to be shipped in the compose that
are still essential for building the bootable images.

Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2017-11-27 08:18:12 +01:00
Lubomír Sedlář
b068514471 Add documentation for modular composes
List all available configuration options and go into some detail on how
modules should be specified. This would probably deserver a more
thorough explanation, but it's still bit in a flux.

Fixes: https://pagure.io/pungi/issue/767
Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2017-11-21 08:47:19 +01:00
Lubomír Sedlář
0f104cea40 osbs: Get correct path to repo for addons
We need to use `repository`, not `os_tree` path. For any non-addon
variant they are the same, but for addons the original path does not
work as it points to the parent really.

Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2017-11-20 12:58:49 +01:00
Ondrej Nosek
91ee1fb854 Remove deprecated options
Options that are currently marked as deprecated do not have any effect
anymore (other than printing warning). We should remove them and update
the message so that we can mark options as deprecated even when they
still work.

Signed-off-by: Ondrej Nosek <onosek@redhat.com>
2017-11-16 11:12:34 +01:00
Lubomír Sedlář
2bd3b85bb7 module-source: Log details about what packages are gathered
Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2017-11-13 09:18:48 +01:00
Lubomír Sedlář
48d155d304 gather: Log details about nodeps method
Without this there is almost no information on what's happening. This
patch should provide basic debugging capabilities.

Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2017-11-13 09:18:48 +01:00
Lubomír Sedlář
69adf35e84 gather: get_packages_to_gather returns a tuple
It always needs to return a tuple, otherwise there would be crashes.

Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2017-11-13 09:04:34 +01:00
Lubomír Sedlář
d2804b5d89 iso-wrapper: Fix calling wrong logger method
The mounting function receives logger as an argument, and its method is
called just error.

Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2017-11-13 09:04:34 +01:00
Patrick Uiterwijk
8181c5be48 Turn COMPOSE_ID version generator into DATE_RESPIN
Signed-off-by: Patrick Uiterwijk <puiterwijk@redhat.com>
2017-11-10 11:14:11 +01:00
Lubomír Sedlář
388be481ea iso-wrapper: Remove hacks for sorting
We can use a key function instead of relying to the deprecated cmp. This
makes the code work on Python 2.6 and on recent versions it makes it
faster.

Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2017-11-08 15:35:29 +01:00
Lubomír Sedlář
cb740f063e Report missing module dependencies earlier
Fixes: https://pagure.io/pungi/issue/768
Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2017-11-07 08:51:00 +01:00
Patrick Uiterwijk
1dbd0248d4 Implement version.compose_id version generator
Signed-off-by: Patrick Uiterwijk <patrick@puiterwijk.org>
2017-11-06 16:14:44 +01:00
Patrick Uiterwijk
1a10a1fe83 Optionally do old_compose per release type
This would make sure that e.g. "updates" composes don't try to use "updates-testing" as an
old_compose_path, which would create practically useless deltarpms and for no repodata
reuse at all.

Signed-off-by: Patrick Uiterwijk <patrick@puiterwijk.org>
2017-11-06 15:17:33 +01:00
Lubomír Sedlář
385002fe94 4.1.20 release
Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2017-11-01 15:01:02 +01:00
Lubomír Sedlář
cdfa3cb45f image-build: Drop suffixes from configuration
The file extension in configuration is only used to tell Pungi which
files from the task results should be downloaded. The user has to get it
right or the phase will fail. Each format has a single valid suffix.

Pungi should not require users to specify the suffix, since it can just
as well just know the right value.

The old configuration will continue working, only the extension will be
ignored.

Fixes: https://pagure.io/pungi/issue/753
Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2017-11-01 12:47:36 +01:00
Lubomír Sedlář
026ba10987 kojiwrapper: Deal with multiple values for image-build
When the config for image-build command contains multiple values, they
should be joined with commas into a single value.

Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2017-11-01 12:47:36 +01:00
Patrick Uiterwijk
333045fb87 Add modulemd to the missing module error
Signed-off-by: Patrick Uiterwijk <patrick@puiterwijk.org>
2017-11-01 12:41:23 +01:00
Lubomír Sedlář
390dff52ae notification: Add more info into the messages
Fixes: https://pagure.io/pungi/issue/771
Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2017-10-31 11:11:04 +01:00
Lubomír Sedlář
28c3bc6268 notification: Fix running on Python 3
The input is given as unicode value, not a bytestring. We need universal
newlines to handle the conversion as needed.

Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2017-10-31 11:10:27 +01:00
Ondrej Nosek
e0308a74ff remove remaining hard coded createrepo threads
To be more precise, new createrepo parameter "workers" was customized and
new default value was set. This fixes issue #752.

Signed-off-by: Ondrej Nosek <onosek@redhat.com>
2017-10-30 10:37:10 +01:00
Lubomír Sedlář
6d6cf6e233 tests: Fix remaining missing assertions
Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2017-10-30 09:29:28 +01:00
Lubomír Sedlář
f21e3a2d6d tests: Work with older unittest2
RHEL has an older version of the library which does not backport all the
assertions that we used. In order for the tests to pass there we need to
use names that exist everywhere.

Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2017-10-30 09:16:18 +01:00
Lubomír Sedlář
6f21576921 tests: Skip testing pdc logs if dependencies are not installed
On EPEL 6 modulemd is not available, so the test fails with an import
error. We should just skip this particular tests, as the rest of the
functionality is still perfectly fine.

Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2017-10-30 08:21:21 +01:00
Dong Wang
463fb961bc Log PDC communications and info for modular composes
Fixes: https://pagure.io/pungi/issue/664
Merges: https://pagure.io/pungi/pull-request/723
Signed-off-by: Dong Wang <dowang@redhat.com>
2017-10-27 16:20:21 +02:00
Ondrej Nosek
4ff3190935 Update documentation section "Contributing to Pungi".
Signed-off-by: Ondrej Nosek <onosek@redhat.com>
2017-10-25 10:28:08 +02:00
Lubomír Sedlář
daf162503c Reject yum gather backend on Python 3
It will not run, and having a nice error message is better than a
cryptic crash.

Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2017-10-24 15:15:31 +02:00
Lubomír Sedlář
f3806f7c77 Stop using deprecated pipes.quote
Instead use the definition from python-six. Once we drop Py 2 support
completely, we'll just swap underscores with dots.

Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2017-10-24 15:15:31 +02:00
Lubomír Sedlář
797b13b34a Convert configparser values to string
On Python 3, configparser will reject non string values, and
theoretically we could have some in the configuration.

Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2017-10-24 15:15:31 +02:00
Lubomír Sedlář
2efc4d8561 Explicitly decode test files as UTF-8
This way the test does not fail if run in a non-UTF-8 locale.

Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2017-10-24 15:15:31 +02:00
Lubomír Sedlář
ed9d7f69a6 Use universal_newlines when running other commands
This will automatically convert the output to unicode/str and we will
not have to worry about decoding ourselves.

Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2017-10-24 15:15:31 +02:00
Lubomír Sedlář
ed22e07ef9 Port to Python 3
This should make all tests pass on both Python 2 and Python 3.

Unittest2 is required on Py 2.6 and Py 3.

Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2017-10-24 15:15:31 +02:00
Patrick Uiterwijk
3088df8e60 checks: Use list of release types from productmd
Let's not duplicate the list. Productmd exports a list of valid values,
so Pungi should just pick and use that.

Closes: https://pagure.io/pungi/pull-request/773
Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2017-10-24 15:05:08 +02:00
Patrick Uiterwijk
274f8b4e56 Add an option to make pungi-koji print its compose_dir to stdout
Signed-off-by: Patrick Uiterwijk <patrick@puiterwijk.org>
2017-10-24 03:58:36 +02:00
Lubomír Sedlář
be39dc3caf buildinstall: Expose template arguments for lorax
This would be useful for modularity. The templates can be added now and
variables set via the existing `lorax_option`.

It's not possible to use custom templates not shipped with lorax, as
passing the path to a random directory is a little bit more tricky.

Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2017-10-23 16:08:09 +02:00
Jan Kaluza
894a5a11a4 Add support for new modules naming policy with colon delimiter
Signed-off-by: Jan Kaluza <jkaluza@redhat.com>
2017-10-20 10:42:09 +02:00
Jan Kaluza
8951e90882 Catch the issue when PDC does not contain RPMs, but the module definition says there should be some.
Signed-off-by: Jan Kaluza <jkaluza@redhat.com>
2017-10-19 13:47:03 +02:00
Jan Kaluza
6208dae869 pkgset: Cherry-pick packages from Koji when we know already what packages will end up in compose
Merges: https://pagure.io/pungi/pull-request/763
Signed-off-by: Jan Kaluza <jkaluza@redhat.com>
2017-10-19 13:43:59 +02:00
Lubomír Sedlář
2819311d6e config: Allow comps_file for any gather_source
It only affects gathering packages when gather_source is set to comps,
but it could still make sense to include the file in the repository even
if the not used for gathering.

Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2017-10-18 15:24:24 +02:00
Lubomír Sedlář
68fdef451c pkgset: Allow unsigned packages by empty key
Currently `None` has to be included to allow using unsigned packages.
ODCS has trouble with including non-string value in the list though, so
we can treat empty string the same way (it's not a valid key ID anyway).

Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2017-10-16 13:48:27 +02:00
Lubomír Sedlář
b79ff7d8dd gather: Nodeps should allow noarch packages
If the package name matches, we should take the package either if
architecture matches or the package is noarch.

Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2017-10-16 13:45:35 +02:00
Lubomír Sedlář
bb6c5da7af pkgset: Clean up path generation
The path prefix for packages is identical for all architectures. There's
no reason to compute it multiple times and check the directory existence
repeatedly.

Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2017-10-16 09:17:24 +02:00
Lubomír Sedlář
f2a2a5a0b6 createiso: Fix logging for media split
When splitting is not possible, we should not print a huge number as
free space on single media. This patch also adds more information so
that the numbers can actually be connected to variant and architecture.
The list of ignored files will only be printed now if not empty.

Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2017-10-13 09:10:39 +02:00
Randy Barlow
e117c904c7
Raise the Exception when a symlink cannot be created.
Signed-off-by: Randy Barlow <randy@electronsweatshop.com>
2017-10-12 16:39:41 -04:00
Lubomír Sedlář
da590d559e Use variant UID for subvariant fallback
The name can contains spaces, which would potentially cause problems.
Also this is not consistent with how it works in other phases.

Relates: https://pagure.io/pungi-fedora/pull-request/354
Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2017-10-11 08:59:13 +02:00
Lubomír Sedlář
a3b90f7474 Fixup for opening config dumps
Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2017-10-11 08:55:46 +02:00
Ralph Bean
97d52d03c8 Open and close file descriptors.
We noticed this when working on the Bodhi integration.

Signed-off-by: Ralph Bean <rbean@redhat.com>
2017-10-10 13:22:19 -04:00
Lubomír Sedlář
c89f033457 live-images: Honor global settings for target
Instead of the old default value and custom handling introduce new
option `live_images_target` (for consistency with other phases) and use
the usual inheritance rules.

Fixes: https://pagure.io/pungi/issue/749
Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2017-10-09 13:46:54 +02:00
Lubomír Sedlář
842e2e810e unified-isos: Stop erasing metadata on failure
When saving new metadata fails, the images.json file would be left
empty. Instead we should not touch it at all.

Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2017-10-06 08:37:56 +02:00
Dennis Gilmore
b51a639277 Merge #743 Make ostree installer before cloud images 2017-10-06 00:18:46 +00:00
Lubomír Sedlář
9ab3840085 Add directory name for checksum file
Fixes: https://pagure.io/pungi/issue/745
Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2017-10-05 16:08:27 +02:00
Lubomír Sedlář
dec00fe2f4 createrepo: Allow customizing number of threads
The default is now to use one thread per CPU.

Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2017-10-03 15:21:37 +02:00
Lubomír Sedlář
19436c66b2 Make ostree installer before cloud images
Fixes: https://pagure.io/pungi/issue/742
Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2017-09-20 08:33:40 +02:00
Lubomír Sedlář
44c523339c 4.1.19 release
Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2017-09-18 13:17:18 +02:00
Lubomír Sedlář
04836cfa9f docs: Mention how input package list are interpreted
It's really just an RPM name, not any random provide or source package
name.

Fixes: https://pagure.io/pungi/issue/725
Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2017-09-18 12:06:03 +02:00
Dong Wang
adaab46bf7 Fix pungi-koji --version
Signed-off-by: dowang <dowang@redhat.com>
2017-09-18 17:04:05 +08:00
Lubomír Sedlář
3ef2a65275 profiler: Fix sorting on Python 3
Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2017-09-13 09:55:51 +02:00
Lubomír Sedlář
9dbf231080 util: Fix timezone offset
We need to negate the value: the values are in seconds west of UTC, but
ISO 8601 wants the offset to be negative for times behind UTC (i.e. to
the west).

Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2017-09-12 09:41:53 +02:00
Lubomír Sedlář
d34c0a2777 gather(dnf): Remove dead code
Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2017-09-12 08:38:08 +02:00
Lubomír Sedlář
239e6b4301 gather(dnf): Don't exclude packages from lookaside
Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2017-09-12 08:38:08 +02:00
Lubomír Sedlář
eead6ccc44 gather(yum): Don't exclude packages from lookaside
Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2017-09-12 08:38:08 +02:00
Lubomír Sedlář
ed0a8249b1 gather: Add tests for excluding packages from lookaside
Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2017-09-12 08:38:08 +02:00
Lubomír Sedlář
4b40a1258a gather: Capture broken deps in test
This will help test more aspects of depsolving.

Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2017-09-12 08:38:08 +02:00
Lubomír Sedlář
816ab917da gather-dnf: Warn about unresolvable dependencies
Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2017-09-12 08:38:08 +02:00
Lubomír Sedlář
6a425ee891 Fix formatting timezone offset
Displaying the offset in seconds makes very little sense. We should
adhere to ISO 8601 format of `+HH:MM` which is much easier to
understand.

Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2017-09-11 10:24:33 +02:00
Lubomír Sedlář
87884b6412 Add timezone info into logs
Timestamps in the main log are currently printed in local time. This
patch adds UTC offset to the top of the log so it's possible to find out
exactly when events happen.

Fixes: https://pagure.io/pungi/issue/710
Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2017-09-08 11:05:57 +02:00
Qixiang Wan
2fa89c061b log: save imported config files too
Save the config files which are imported by the following syntax:

    from some_config import *

Note: This requires kobo >= 0.6
Signed-off-by: Qixiang Wan <qwan@redhat.com>
2017-09-08 16:39:38 +08:00
Lubomír Sedlář
c98f0a88d8 ostree-installer: Only run on empty variants
If the variant is not empty, it buildinstall will run lorax on it and
create some files that would otherwise be overwritten by the ostree
installer.

The validation script is updated to load variants file as it needs a
list of variants to find out if the config is wrong.

Fixes: https://pagure.io/pungi/issue/695
Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2017-09-07 15:57:54 +02:00
Ralph Bean
5b6e468952 Allow extracting profiling information from pungi-gather.
`pungi-gather` (the tool that underlies both the `pkgset` and `gather`
phases) contains profiling code that will log statistics about how long
different function calls take.  However, pungi-koji did not contain a
way to pass the ``--profiler`` argument to enable this.

This change adds a new configuration option ``gather_profiler`` which,
when set to true, simply passes the argument to `pungi-koji`.  Hopefully
this can help shed some light on what is happening in some of our
longer-running composes.

Merges: https://pagure.io/pungi/pull-request/727
Signed-off-by: Ralph Bean <rbean@redhat.com>
2017-09-04 10:25:11 +02:00
Lubomír Sedlář
40796c04f4 createrepo: Only consider successful compose for deltas
If the compose failed, it may not have repos to compute deltas against,
and even if it has them, they were never shipped so no one will have the
older version of the package. We should instead go deeper in history and
pick a successful compose.

Relates: https://pagure.io/pungi/issue/715
Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2017-09-04 09:15:20 +02:00
Lubomír Sedlář
e21a27bdc9 createrepo: Allow selecting variants for delta RPMs
The configuration needs to be more granular than a single global option.
With this patch each tree can enable deltas separately.

Fixes: https://pagure.io/pungi/issue/715
Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2017-09-04 09:15:20 +02:00
Lubomír Sedlář
90be25c14c createrepo: Only create delta RPMs for binary repos
It does not make much sense to have deltas for source and debug repos.
No one benefits from it really and it takes a long time.

Relates: https://pagure.io/pungi/issue/715
Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2017-09-04 09:15:20 +02:00
Qixiang Wan
b81e94e808 image-build: add arch name(s) in image config file name
Pungi write image config file with name of <format>-<name>.cfg, if there
are two or more image configs present for different arches under the same
variant and with same format & name, the config file can be overwritten,
and result in invalid image conf file.

Example:

image_build = {
    '^Server$': [
        {
            'image-build': {
                'format': [('qcow2', 'qcow2'),],
                'name': 'fedora-guest-image',
                'target': 'guest-fedora-26-image',
                'version': '26',
                'ksurl': "git://git.example.com/ks.git?fedora#HEAD",
                'kickstart': "fedora-26-kvm.ks",
                'ksversion': 'f26',
                'distro': 'fedora-26',
                'disk-size': '10',
                'arches': ['x86_64'],
                'repo': ["http://example.com/linux/fedora/26/Everything/x86_64/os", ]
            }
        },
        {
           'image-build': {
                'format': [('qcow2', 'qcow2'),],
                'name': 'fedora-guest-image',
                'target': 'guest-fedora-26-image',
                'version': '26',
                'ksurl': "git://git.example.com/ks.git?fedora#HEAD",
                'kickstart': "fedora-26-kvm.ks",
                'ksversion': 'f26',
                'distro': 'fedora-26',
                'disk-size': '10',
                'arches': ['ppc64le'],
            }
        },
    ],
}

In this case, config file "qcow2_guest-fedora-26-image.cfg" will be
created for both x86_64 and ppc64le under the same variant dir, and
there is a high chance it will be over-written while Pungi creating the
koji task. We can add arch name(s) in config filename to avoid that.

Signed-off-by: Qixiang Wan <qwan@redhat.com>
2017-09-03 23:51:08 +08:00
Lubomír Sedlář
5379fb5e28 Check for correct string class
Use python-six and check against correct string class on both Python 2
and Python 3.

Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2017-08-28 14:31:09 +02:00
Lubomír Sedlář
65910f2c33 Open files as binary where needed
In many cases we need to open files as binary to avoid errors on Py3
about writing binary data to file opened in text mode.

Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2017-08-28 13:47:18 +02:00
Lubomír Sedlář
fcbc3ed4ae buildinstall: No copy if task fails
Even a failed lorax task can leave behind some in-progress images. Pungi
needs to copy the files into compose/ subdirectory only if the task
finished successfully.

Fixes: https://bugzilla.redhat.com/show_bug.cgi?id=1485021
Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2017-08-28 13:43:32 +02:00
Lubomír Sedlář
2e3a9385a3 config: Allow setting default compose type
The config can change the default compose type. This can still be
overwritten by a CLI argument. A `--production` option is now added to
CLI (because that was the default before).

Fixes: https://pagure.io/pungi/issue/694
Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2017-08-25 10:07:33 +02:00
Lubomír Sedlář
439a7ce348 Use Py3-compatible exception handling
In once case we can completely drop try-except statements: it only
logs the exception details but that will be logged again anyway.

Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2017-08-24 14:51:27 +02:00
Lubomír Sedlář
ec39514fba Use Python 3 print function
This is updated in all files for consistency, even the modules that will
never be ported to Py 3 completely due to dependency on Yum.

Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2017-08-23 09:41:22 +02:00
Lubomír Sedlář
c14c28a157 docs: Abort update script on error
If building documentation fails, there's no point in trying to update
the repo.

Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2017-08-22 10:28:38 +02:00
Lubomír Sedlář
c9d95f5f6f 4.1.18 release
Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2017-08-22 10:22:27 +02:00
Owen W. Taylor
49c6abcfea KojiWrapper: include serverca in session_opts
If we have a custom server CA certificate, it needs to be generally
available, and not just used when logging in so that SSL verification
works.

Signed-off-by: Owen W. Taylor <otaylor@fishsoup.net>
2017-08-21 14:16:40 -04:00
Lubomír Sedlář
a63e4746c9 Report warning when config sections are not used
It's possible a variant is excluded via tree_variants option and the
section does not match anything. It can be confusing to users why
nothing is happening. This patch lets Pungi log all unmatched patterns.

Fixes: https://pagure.io/pungi/issue/692
Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2017-08-21 09:07:10 +02:00
Lubomír Sedlář
c3b49f7ffb pkgset: Download packages with dnf
When using repos as gather_source, we should use DNF backend even for
constructing initial package set and to download the packages from
source repos. Without this the repos source would not be usable on
Python 3.

Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2017-08-16 14:32:26 +02:00
Lubomír Sedlář
be4501c54b gather: Fix duplicated log line
Due to overwriting an existing variable the logs are getting duplicated
line about missing comps packages instead of announcement of gathering
being finished. Rename the variable to fix the problem.

Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2017-08-16 13:14:21 +02:00
Lubomír Sedlář
a8cd78faf9 gather: Add fulltree-exclude flag to DNF backend
This is needed for correct trimming of addons and optional. A package
pulled in as a dependency but that matches something on fulltree exclude
list should have this flag. It will then be moved from addon to base
variant and therefore excluded from optional.

Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2017-08-16 13:06:55 +02:00
Lubomír Sedlář
23ca2fe5d2 checks: Stop looking for imports
We can't reliably tell user what system packages are missing as the name
might be different on different systems. Addiotionally there's no reason
why not rely on the packaging to be correct.

Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2017-08-14 14:57:06 +02:00
Lubomír Sedlář
804a0049f6 ostree: Simplify configuration
It makes no sense to repeat the same configuration for multiple
architectures. Instead we should just list the architectures as another
key in the mapping. There is an option to specify multiple config dicts.

This preserves full backwards compatibility, the old config format is
still accepted.

Fixes: https://pagure.io/pungi/issue/678
Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2017-08-14 14:53:22 +02:00
Lubomír Sedlář
9780f36e37 config: Reduce duplication in schema
This patch adds a helper function for easy creation of a structure where
either X or list of Xs is accepted.

Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2017-08-14 14:53:22 +02:00
Lubomír Sedlář
c12bad295f config: Add option for dumping config schema
This makes it easier to compare changes to the schema in different
versions.

Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2017-08-14 14:53:22 +02:00
Lubomír Sedlář
22fdd59ca4 scm: Accept unicode as local path
Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2017-08-14 14:36:47 +02:00
Lubomír Sedlář
7e03133c8f docs: Add documentation for scm_dict
Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2017-08-10 15:32:24 +02:00
Lubomír Sedlář
cae202c17b scm-wrapper: Allow running command after git clone
When a file should be obtained from a git repository, allow running an
arbitrary command (like `make`) after clone but before copying the files
out. This only works for the Git backend.

The downside is that a clone is needed and we can no longer use `git
archive` to speed things up.

Fixes: https://pagure.io/pungi/issue/5
Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2017-08-10 15:32:24 +02:00
Lubomír Sedlář
f9640ae0b4 scm-wrapper: Test correct file lists are returned
Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2017-08-10 15:32:24 +02:00
Lubomír Sedlář
470b3e4923 tests: Fix test_compose.sh paths
The paths need to be absolute so that subprocesses started during the
compose with a modified cwd will still work.

Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2017-08-10 09:28:36 +02:00
Lubomír Sedlář
c9f34b6684 gather: Only parse pungi log once
No need to read the file three times, we can just get all the data in
one go.

Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2017-08-09 11:04:14 +02:00
Lubomír Sedlář
cef8650c3e gather: Report missing comps packages
When a package mentioned in comps is not available in the package set,
print a warning about this. Additionally there is a config option that
allows to turn this warning into a fatal error.

Fixes: https://pagure.io/pungi/issue/50
Fixes: https://pagure.io/pungi/issue/683
Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2017-08-09 11:04:14 +02:00
Lubomír Sedlář
1d7617f783 gather: Avoid reading whole log into memory
There's no reason for reading the whole log of depsolving into memory
just to split it into lines and process one line at a time.

We can just as well read it in chunks.

Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2017-08-09 11:04:14 +02:00
Lubomír Sedlář
e2962dc547 repoclosure: Allow aborting compose when repoclosure fails
Alternatively the call to repoclosure can be turned off. This is
customizable per variant and architecture.

Fixes: https://pagure.io/pungi/issue/676
Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2017-08-07 15:17:33 +02:00
Lubomír Sedlář
056ae31ef9 repoclosure: Fix logging errors
Instead of just printing the error directly to stderr, capture the
output and use proper logger. This makes sure the error is included in
the log file and also fixes `--quiet` option which was not properly
honored originally.

Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2017-08-07 15:17:33 +02:00
Lubomír Sedlář
99204bb695 tests: Make test-compose cwd independent
With this patch it is possible to run the test compose script from the
top level directory. This makes it slightly easier to use.

Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2017-08-07 15:17:33 +02:00
Ralph Bean
381d08a810 Make strict the only option.
Signed-off-by: Ralph Bean <rbean@redhat.com>
2017-08-07 14:56:59 +02:00
Ralph Bean
58fe997e29 Raise a ValueError with details if module not found in PDC.
Currently, this will fail two lines later when we try to access
`pdc_module['modulemd']` with an unhelpful `TypeError` since
`pdc_module` is `None`.

Signed-off-by: Ralph Bean <rbean@redhat.com>
2017-08-07 08:34:45 -04:00
Lubomír Sedlář
c66f2228b5 unified-iso: Only link to non-empty variants
Instead of adding images to metadata and then creating hardlinks in a
separate step, do it immediately while we still have accurate
information about what variants it should be linked to.

Fixes: https://pagure.io/pungi/issue/670
Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2017-07-31 15:15:17 +02:00
Lubomír Sedlář
471e369d23 gather: Fix excluding debugsource packages from input list
Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2017-07-27 08:50:21 +02:00
Lubomír Sedlář
e1eacd456e gather: Add debugsource package to tests
Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2017-07-27 08:31:39 +02:00
Till Maas
b26547ae77 Use only one list of patterns/rules for debug packages
Signed-off-by: Till Maas <opensource@till.name>
2017-07-26 23:18:29 +02:00
Till Maas
938531e2b2 Do not match "*-debugsource-*" as debuginfo package
These kind of packages are not expected to exist in the wild.

Signed-off-by: Till Maas <opensource@till.name>
2017-07-26 23:18:24 +02:00
Till Maas
29bedf2ccc Use pungi.util.pkg_is_debug() instead of pungi.gather.is_debug()
There is no reason to have two functions for the same job.

Signed-off-by: Till Maas <opensource@till.name>
2017-07-26 23:18:15 +02:00
Qixiang Wan
0a3e5b27bf remove the dependency of rpmUtils
The rpmUtils module is provided yum-utils package, which is only
available for Python 2. There is no replacement for the functionality in
DNF.

There is a proposal to add this functionality to rpm itself, but it's
not really moving forward very much:
https://bugzilla.redhat.com/show_bug.cgi?id=1072972

As a short term solution let's copy the needed parts of rpmUtils.arch
module directly to pungi code base.

Fixes: https://pagure.io/pungi/issue/533
Signed-off-by: Qixiang Wan <qwan@redhat.com>
2017-07-26 11:23:16 +02:00
Lubomír Sedlář
d92390b80b Add support for debugsource packages
These packages should behave like regular debuginfo packages (at least
for now).

Fixes: https://pagure.io/pungi/issue/684
Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2017-07-26 10:34:18 +02:00
Lubomír Sedlář
65078ef9cf gather: Don't pull multiple debuginfo packages
When there is a noarch subpackage, all compatible debuginfo would be
pulled in, which is not desirable.

Example: Server.x86_64 needs pkg.x86_64 and pkg-data.noarch. We only
want pkg-debuginfo.x86_64, but without this patch even
pkg-debuginfo.i686 would get in.

Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2017-07-20 15:00:09 +02:00
Jan Kaluza
5dd6b1b0e7 GatherSourceModule: return rpm_obj instead of the rpm_obj.name
Merges: https://pagure.io/pungi/pull-request/680
Signed-off-by: Jan Kaluza <jkaluza@redhat.com>
2017-07-20 14:58:58 +02:00
Lubomír Sedlář
32ca02efd6 gather: Stop requiring comps file in nodeps
When there are no groups, we shouldn't try to read comps file (because
it may very well not be there).

Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2017-07-20 13:11:06 +02:00
Lubomír Sedlář
c0bac63f4d 4.1.17 release
Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2017-07-17 09:58:35 +02:00
Lubomír Sedlář
6cf912f555 docs: Convert phases diagram to PNG
Sphinx and Latex are unable to include SVG apparently:
https://github.com/sphinx-doc/sphinx/issues/1907

Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2017-07-17 09:58:35 +02:00
Lubomír Sedlář
482181f52a setup: Update manifest to include doc images
Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2017-07-17 09:26:20 +02:00
Lubomír Sedlář
085a8ef7c7 checksum: Checksum each image only once
There is no point in reading the same image multiple times. This happens
for at least source ISOs.

Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2017-07-17 08:26:51 +02:00
Lubomír Sedlář
81cb0952ca checksum: Refactor creating checksum files
Instead of iterating over the images metadata and appending the checksum
to relevant files immediately, we should store them and write only once.

This avoid an issue when the same image is mentioned in the metadata
multiple times. This happens for source images that are listed under
each binary arch.

The unified isos script is updated to use the exact same logic and code.
This also uncovered a problem with the metadata for debuginfo unified
isos: their paths in metadata were incorrect, which lead to missing
checksums.

Fixes: https://pagure.io/pungi/issue/667
Fixes: https://pagure.io/pungi/issue/668
Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2017-07-17 08:26:51 +02:00
Lubomír Sedlář
a831d65c40 createrepo: Don't use existing metadata with deltas
When creating the final repo, we reuse metadata from arch repo used for
depsolving. This however breaks creating deltas with createrepo_c.

Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2017-07-14 14:29:16 +02:00
Lubomír Sedlář
4d117d17f8 util: Fix finding older compose
When there are composes with two digit respin, the code would prefer 9
over 10 as latest. Respin needs to be treated as a number.

Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2017-07-14 10:42:35 +02:00
Lubomír Sedlář
910f816be4 createrepo: Use correct paths for old package dirs
Createrepo expects to be pointed to a directory with the actual RPM
files, not the previous repo. This means that when hashed directories
are used, we need to pass in a lot of directories.

Fixes: https://pagure.io/pungi/issue/344
Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2017-07-14 10:40:44 +02:00
Lubomír Sedlář
5c5708afe3 spec: Add missing ostree signature waiting handler
Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2017-07-13 14:45:11 +02:00
Lubomír Sedlář
543c184e0d docs: Minor improvements to documentation
* add description for `gather_method`
 * fix typo in `createrepo_deltas`

Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2017-07-13 10:03:54 +02:00
Lubomír Sedlář
f7a9c77626 ostree: Add notification handler to wait for signature
This script can be used as a notification handler. For most messages it
does nothing, but when it sees a new commit in an ostree repo, it will
wait for a signature of the new commit to appear.

This is useful for building images later so that they include the
signature as well.

Fixes: https://pagure.io/pungi/issue/650
Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2017-07-11 10:24:49 +02:00
Lubomír Sedlář
e246aef5f6 ostree: Add URL to repo to message
The message announcing new ostree commit contains hash of the commit,
the ref it's for, but there is no information about where the repo
actually is.

This patch adds `repo_path` key into the message with URL of the repo
and `local_repo_path` with path to the repo on local filesystem.

Relates: https://pagure.io/pungi/issue/650
Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2017-07-11 10:24:49 +02:00
Lubomír Sedlář
8c48dfb93a gather: nodeps should take packages from comps groups
When gather_method is set to nodeps, we should not ignore the comps
group that the method received. Instead it should find out which
packages are in those groups and take them into the compose.

In order for this to be of any reasonable use, the comps file needs to
include all dependencies for the packages.

Fixes: #653
Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2017-07-11 10:21:13 +02:00
Ken Dreyer
0350b715dd unified-iso: handle empty arch
Prior to this change, when running pungi-create-unified-iso on a compose
with zero builds present for an arch, unified-iso crashes.

The problem is that unified-iso does not set up the arch's debuginfo
destination directory at all before trying to dump the productmd
treeinfo for that arch's debuginfo. productmd tries to write to the
destination directory that does not exist.

Signed-off-by: Ken Dreyer <kdreyer@redhat.com>
2017-07-10 12:14:34 -06:00
Ken Dreyer
5acfb90b23 createrepo: handle missing product ids scm dir
Prior to this change, if the entire product IDs SCM directory was missing, pungi would crash with an error.

For example, if "ceph-3" was missing from the SCM:

    OSError: [Errno 2] No such file or directory: '/tmp/tmpMb9O6r/product_ids/ceph-3'

This occurred even if product_id_allow_missing was set to True.

Make product_id_allow_missing cover this case as well, and gracefully
skip all product IDs.

We now see the following warning in the logs instead:

    [WARNING ] No product IDs in {'scm': 'git', 'repo': 'git://example.com/rcm/rcm-metadata.git', 'dir': 'product_ids/ceph-3'}

and the compose succeeds.

Signed-off-by: Ken Dreyer <kdreyer@redhat.com>
2017-07-07 09:59:17 -06:00
Lubomír Sedlář
afffb27f94 comps_wrapper: Code clean up
* Remove explicit option requirement. Argparse can take care of that
  while also making this information visible in help output.
* Simplify writing resulting comps.
* Remove unused code.

Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2017-06-29 15:51:48 +02:00
Pavel Holica
9a3d04c305 comps_filter: Filter environments by arch
If the environment has arch attribute, the environment should be removed
from the file on all other arches. This mirrors similar behaviour for
groups and packages.

Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2017-06-29 14:45:59 +02:00
Lubomír Sedlář
a21c8a555d notification: Allow specifying multiple scripts
The notification hooks can be useful for doing other things than just
announcing status on message bus. For this to be truly usable, we need
the ability to use multiple scripts.

This patch allows the command line option to be specified multiple
times. Each given script will be called. Even if the script fails, it
does not block the compose.

Additionally the output of the notification scripts is logged now to
make it possible to debug possible failure.

Relates: https://pagure.io/pungi/issue/650
Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2017-06-29 08:30:56 +02:00
Qixiang Wan
18bd37ff2c pkgset: Allow populating packages from multiple koji tags
One of the use cases is https://pagure.io/odcs/issue/7.

Merges: #660
Signed-off-by: Qixiang Wan <qwan@redhat.com>
2017-06-29 08:27:34 +02:00
Lubomír Sedlář
9193a6902e pungi: Port to argparse
And fix PEP8 violations while modifying the file.

Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2017-06-27 09:37:03 +02:00
Lubomír Sedlář
87c485f2d0 comps_filter: Port to argparse
Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2017-06-27 09:37:03 +02:00
Lubomír Sedlář
ecbb43ab86 variants-wrapper: Remove main() function
Nothing is calling this code, and it's only really useful for manual
testing of parsing.

Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2017-06-27 09:36:48 +02:00
Lubomír Sedlář
69a6046bf8 multilib_yum: Remove main() function
Nothing is calling this file as an executable, so there is no reason to
have logic for parsing arguments.

Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2017-06-27 09:36:39 +02:00
Lubomír Sedlář
01026858f7 pungi-koji: Port to argparse
Optparse is deprecated since Python 2.7, long live argparse.

This also allows us to remove some of the manual error checking and make
the library check required or conflicting options.

Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2017-06-27 09:36:23 +02:00
Lubomír Sedlář
68098bec37 ostree: Update tests for no ostree init
Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2017-06-27 07:46:35 +02:00
Colin Walters
af631f560e ostree: Don't automatically create a repo
Creating an OSTree repository is a notable event; the general
expectation is that rather than having lots of repositories,
one has branches inside a single repository.

For $reasons, Fedora is not currently doing this, but we will
change it to do so.

The reason I'm making this change is we discovered that
it looked like Fedora had somehow made a repo inside a repo,
presumably due to a configuration error.

https://lists.fedoraproject.org/archives/list/cloud@lists.fedoraproject.org/message/GBFSOLULGGZFGEFCIW6FG23NZZV5VH4K/
Signed-off-by: Colin Walters <walters@verbum.org>
2017-06-26 17:47:35 -04:00
Lubomír Sedlář
bfc1cebbc4 osbs: Config validation should accept a list
There can be multiple images listed for a single variant, the config
validation should not reject it.

The syntax with a single config object is still accepted. The price for
that is less descriptive error message when there are errors.

Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2017-06-23 12:39:48 +02:00
Martin Curlej
079454c502 pkgset: Use release number of a module
Signed-off-by: Martin Curlej <mcurlej@redhat.com>

updated regex, added comment, pep8 fix
2017-06-21 15:53:39 +02:00
Lubomír Sedlář
65bc6969e2 docs: Add a basic info about gathering packages
Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2017-06-21 09:55:29 +02:00
Dennis Gilmore
65b75e7049 Merge #646 ostree-installer: Clean up output dir 2017-06-20 15:31:09 +00:00
Dennis Gilmore
8e89168ad3 Merge #647 gather: Log tag from which we pulled a package 2017-06-20 15:27:38 +00:00
Lubomír Sedlář
3e64238fca docs: Kobo can be installed via pip now
Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2017-06-20 11:11:16 +02:00
Dennis Gilmore
72081a3a35 Merge #649 docs: Add overview of what each phase does 2017-06-19 17:22:43 +00:00
Lubomír Sedlář
9ab3dc89b2 docs: Add overview of what each phase does
Fixes: #520
Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2017-06-19 10:58:01 +02:00
Lubomír Sedlář
b2554ce663 gather: Log tag from which we pulled a package
For each tag we ask Koji about (there might be more than one in
modularity case), we create a log file with list of RPMs and details
about which tag they were pulled from. This makes it easier to find out
where the package is inherited from.

Fixes: #547
Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2017-06-19 10:51:37 +02:00
Lubomír Sedlář
2a8d7f8843 docs: Document config file format
Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2017-06-19 10:51:31 +02:00
Lubomír Sedlář
bef573d222 docs: Move logo to _static subdir
Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2017-06-19 10:51:23 +02:00
Lubomír Sedlář
d586368515 Add dropped livemedia phase
After the patch to ensure that all phases are stopped the livemedia
phase was apparently dropped by accident.

Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2017-06-19 08:58:53 +02:00
Lubomír Sedlář
4fb28979cf gather: Display source repo of packages
When multiple repos are configured in pkgset_repos, the logs should
contain information on where exactly the package was pulled from. The
log file in question should be in
`logs/<arch>/pkgset_source.<arch>.log`.

Fixes: #545
Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2017-06-16 12:39:04 +02:00
Lubomír Sedlář
c337018294 pkgset: Use descriptive name for log file
When repos are used as pkgset source, the logs are stored in a file that
should have a better name than `fooo.<arch>.log`.

Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2017-06-16 09:57:49 +02:00
Lubomír Sedlář
6e6e250cec ostree-installer: Clean up output dir
The Koji task can be restarted and lorax will fail if the output
directory already exists. Let's start the work in runroot by removing
the output directory.

Relates: #641
Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2017-06-15 08:17:07 +02:00
Lubomír Sedlář
1c3637c48f Ignore more pycodestyle warnings
These warnings are ignored by default, but setting our own ignore list
removes these defaults.

Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2017-06-14 13:21:31 +02:00
Jan Kaluza
f7197ddbcc Allow gather source classes to return SimpleRpmWrapper objects from pkgset phase directly.
Signed-off-by: Jan Kaluza <jkaluza@redhat.com>
2017-06-14 08:51:37 +02:00
Lubomír Sedlář
a54b68d08b tests: use unittest2 if available
This fixes a test failure on RHEL 6.

Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2017-06-13 08:55:41 +02:00
Lubomír Sedlář
81b71b9ed3 koji-wrapper: Handle failed subtasks
If a subtask fails, we can't ask about it's results as that would raise
an exception. We can safely assume that since the parent succeeded, any
failed child is actually allowed to fail.

Fixes: #641
Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2017-06-12 18:15:29 +02:00
Lubomír Sedlář
d3dd7aa7ce 4.1.16 release
Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2017-06-09 13:12:19 +02:00
Lubomír Sedlář
3a59e8f266 Fix changelog generator script
* Correctly exclude merge commits (there's a git log option for it)
 * Stop mangling log lines with @ symbol. This should only be cut for
   author of a change.
 * Fix PEP8 issues
 * Remove unused code
 * Port to argparse (optparse is deprecated)

Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2017-06-08 11:00:22 +02:00
Lubomír Sedlář
0cdf996e6e util: Retry resolving git branches
When there's a temporary network issue, Pungi will fail to turn a branch
into a commit hash. This would abort the whole compose. Instead we
should just retry a few times.

Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2017-06-06 15:31:39 +02:00
Lubomír Sedlář
700106facf arch: Move exclu(de|sive)arch check to a function
Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2017-06-06 15:28:12 +02:00
Jan Kaluza
3601d6d1a8 gather-source: Check arch in module source
Skip the RPM if it is excluded on this arch or exclusive for different
arch.

Signed-off-by: Jan Kaluza <jkaluza@redhat.com>
2017-06-06 15:25:41 +02:00
Lubomír Sedlář
1db1abbb82 koji-wrapper: Stop mangling env variables
When koji is authenticated with a keytab, by setting the private
directory we erased rest of existing environment. In non-keytab path,
the environment variables got removed as well.

This patch makes sure that the environment will not be modified more
than necessary (by setting KRB5CCNAME if needed).

Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2017-06-05 12:46:45 +02:00
Dennis Gilmore
3ddfd4d172 Merge #621 gather: Don't resolve dependencies in lookaside 2017-06-02 14:01:46 +00:00
Lubomír Sedlář
247a1a71ba Ensure all phases are stopped
If a phase is started successfully, it needs to be stopped as well. In
most cases when `stop` is called immediately after `start`, this is not
a problem.

Only when something else happens while a phase is runnning and this
something fails, Pungi will deadlock and never exit. This something
could be another phase or just main thread raising an exception.

Fixes: #625
Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2017-06-02 09:52:18 +02:00
Lubomír Sedlář
8c237b78c2 comps-wrapper: Report unknown package types
When there is a typo in the comps file, instead of crashing with a
non-descript KeyError we should raise a nice error with details about
the problem.

Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2017-06-01 09:59:41 +02:00
Jan Kaluza
118444a311 Generate proper modular metadata when there are different versions of the same package in the variant
Merges: #629
Signed-off-by: Jan Kaluza <jkaluza@redhat.com>
2017-05-30 15:18:09 +02:00
Lubomír Sedlář
58a6affd65 checks: Make gpgkey a boolean option
This option is currently only checked in the ostree phase, and it does
not make sense as a string. When any non-empty string was given, it
enabled the check.

Relates: #590
Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2017-05-29 13:31:47 +02:00
Lubomír Sedlář
a2c42aee3c ostree: Refactor writing repo file
Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2017-05-29 13:26:49 +02:00
Lubomír Sedlář
63c0bbc5c9 iso-wrapper: Capture debug information for mounting
Occasionally we have seen the mount command fail. The default error
message says to set some environment variables and try again. We can
just always set the environment and only print the output on failure.

Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2017-05-29 13:18:07 +02:00
Lubomír Sedlář
77ee882c21 comps-wrapper: Fix crash on conditional packages
A `requires` attribute is taken from a wrong package (because of a wrong
variable used: `pkg` vs. `package`). On RHEL 6 this actually leads to a
crash. Let's use only one name to avoid such problems.

Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2017-05-29 13:11:49 +02:00
Lubomír Sedlář
3130d837c0 gather: Don't resolve dependencies in lookaside
When looking at a package in a lookaside repo, it does not make much
sense to process its dependencies. We should just assume that the
lookaside can satisfy them.

In the worst case, this could result in packages being pulled into the
compose just so that they could satisfy a dep of something in lookaside.

Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2017-05-29 12:55:38 +02:00
Lubomír Sedlář
f27f3ce4ba koji-wrapper: Run all blocking commands with fresh ccache
If keytab is used for authentication, other commands than runroot can
possibly fail due to the credentials cache being overwritten.

Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2017-05-29 12:53:29 +02:00
Jan Kaluza
68351fa5a8 Add @retry decorator and use it to retry connection on PDC on IOError and in SCM's retry_run.
Signed-off-by: Jan Kaluza <jkaluza@redhat.com>
2017-05-29 11:33:23 +02:00
Lubomír Sedlář
dc410b58b5 Remove shebang from non-executable files
This fixes an rpmlint error on built package.

Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2017-05-10 09:07:16 +02:00
Lubomír Sedlář
e549c732a4 4.1.15 release
Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2017-05-05 08:16:11 +02:00
Lubomír Sedlář
7b880af0ad pkgset: Remove use of undefined variable
As long as the assertion is not violated, this would not be a problem as
the second argument is not evaluated. However if the condition was
broken, a NameError would be raised instead of AssertionError with a
nice message.

Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2017-05-05 07:54:32 +02:00
Jan Kaluza
d037d61521 Store RPM artifacts in resulting repository in modulemd metadata.
Signed-off-by: Jan Kaluza <jkaluza@redhat.com>
2017-05-04 21:12:30 +02:00
Lubomír Sedlář
6ce88630ec variants: Remove redundant check
This situation is handled by schema validation already, so this
condition can never really fire.

Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2017-05-03 14:51:39 +02:00
Lubomír Sedlář
ad120f2608 compose: Stop duplicating variant types
Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2017-05-03 14:40:32 +02:00
Lubomír Sedlář
c784dab4aa gather: Remove handling of impossible state
The get_system_release_packages function can never be called without a
variant, so it makes no sense to check for that condition.

Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2017-05-02 10:12:16 +02:00
Lubomír Sedlář
834445e7d0 gather: Clean up code
* add comments explaining what's going on
 * break too long lines
 * simplify the logic where possible
 * use with statement to work with files
 * remove commented out and unused code
 * introduce helpers to reduce code duplication

Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2017-05-02 10:12:14 +02:00
Lubomír Sedlář
feb87077b3 gather: Add tests for gather phase
And also all helper functions in the module.

Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2017-05-02 10:11:27 +02:00
Dennis Gilmore
ccbd246edb Merge #605 gather: Process dependencies sorted 2017-04-27 15:31:28 +00:00
Dennis Gilmore
b396e8273f Merge #608 Add exact Requires to depsolving log 2017-04-27 15:30:54 +00:00
Dennis Gilmore
dce44410b4 Merge #609 Add info about name to docs 2017-04-27 15:30:17 +00:00
Lubomír Sedlář
55058f1590 scm-wrapper: Remove unused arguments
There are a couple arguments that are never used. We can just remove
them. This also fixes a bug where temporary files would be left
undeleted in tests.

Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2017-04-27 15:59:26 +02:00
Lubomír Sedlář
be0c1e1964 tests: Avoid creating unused temporary files
Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2017-04-27 15:59:19 +02:00
Lubomír Sedlář
24c32831a1 tests: Clean up persistent temporary data
Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2017-04-27 15:56:03 +02:00
Lubomír Sedlář
68a1051f14 docs: Add a logo on the About page
Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2017-04-26 10:46:57 +02:00
Lubomír Sedlář
a2c3274585 docs: Document origin of the name
Fixes: #600
Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2017-04-26 10:46:57 +02:00
Lubomír Sedlář
29c339d659 gather-dnf: Log exact Requires pulling a package in
This is useful for debugging.

Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2017-04-26 10:04:26 +02:00
Lubomír Sedlář
ebe25a3717 gather: Print specific Requires which pulls a package in
When dependencies are pulled in, it's useful to know not only the
package that requires them, but also the specific requires.

This patch only implement this for the YUM version.

Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2017-04-26 09:52:07 +02:00
Lubomír Sedlář
75430a95b9 gather: Process dependencies sorted
Instead of going in random order, we should do it deterministically and
process the dependencies in order.

This should actually fix a problem where `glibc-langpack` packages are
missing on some architectures for Fedora Rawhide.

Fixes: https://pagure.io/pungi-fedora/issue/214
Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2017-04-26 09:49:00 +02:00
Lubomír Sedlář
059449e140 koji-wrapper: Run koji runroot with fresh credentials cache
If the koji profile we are using is configured to use keytab, we should
run koji executable with a fresh credentials cache. Otherwise we risk a
race condition as multiple processes will trample over the same
directory in /tmp/krbcc_0.

This is currently only implemented for calling `koji runroot`. We might
need to do it for other commands as well (currently there is a sleep to
avoid the race condition for other commands).

Fixes: https://pagure.io/releng/issue/6715
Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2017-04-25 15:45:00 +02:00
Lubomír Sedlář
7028399403 util: Move get_buildroot_rpms to koji wrapper
This way the util module does not import the particular wrapper.

Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2017-04-25 15:22:41 +02:00
Lubomír Sedlář
bab2a125d4 osbs: Make git_branch required option
In order to avoid conflicting tags, OSBS allows only one build for a
repo/branch pair at the same time. To avoid race conditions, we should
make sure we always pass in the branch. This commit makes it a required
option.

Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2017-04-24 10:05:25 +02:00
Lubomír Sedlář
21952955ad docs: Update createrepo_checksum allowed values
Relates: #591
Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2017-04-20 15:22:58 +02:00
Lubomír Sedlář
c293a1e147 extra-files: Allow configuring used checksums
Instead of adding a new config option, we can just reuse the existing
`media_checksums` value. If the value is good for image checksums, it
should work for extra files as well.

Relates: #591
Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2017-04-20 09:28:09 +02:00
Lubomír Sedlář
532b6b1fbc doc: Document options for media checksums
Pungi does not really care about the values as long as hashlib supports
them.

Relates: #591
Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2017-04-20 09:28:09 +02:00
Lubomír Sedlář
460a8dea0e config: Add sha512 as valid createrepo checksum
Relates: #591
Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2017-04-20 09:28:09 +02:00
Lubomír Sedlář
610c4ec596 util: Report better error on resolving non-existing branch
When the config contains a git url pointing to a non-existing branch,
pungi will fail to get commit hash from that branch and die with a
confusing error message.

Fixes: #583
Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2017-04-19 15:37:15 +02:00
Lubomír Sedlář
2bc719a33a util: Show choices for volid if all are too long
When we fail to generate a volume ID that fits in 32 characters, the
error message should include the options that were considered. It could
show that there might be a substitution that could fix the problem.

Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2017-04-18 16:13:55 +02:00
Qixiang Wan
63327e7d88 checks: Fix anyOf validator yield ValidationError on ConfigOptionWarning
We have some hooks yield ConfigOptionWarning. When it happens within
anyOf validator, anyOf validator yield ValidationError and reports the
config as incorrect. We need to overwrite it to pass not break.

Fixes: #598
Merges: #599
Signed-off-by: Qixiang Wan <qwan@redhat.com>
2017-04-18 10:05:03 +02:00
Lubomír Sedlář
180a5b94a9 comps-wrapper: Reduce duplication in code
Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2017-04-13 11:45:23 +02:00
Lubomír Sedlář
3861be3e08 comps-wrapper: Port to libcomps
Instead of replacing yum.comps with an something from DNF, we can go
directly to libcomps. DNF does not have the equivalent functionality
(particularly it's impossible to load comps from file directly).

We would have depended on libcomps anyway transitively, so this is not a
big deal.

Fixes: #587
Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2017-04-13 11:45:23 +02:00
Lubomír Sedlář
39c3f42f77 comps-wrapper: Sort langpacks by name
Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2017-04-13 11:45:23 +02:00
Lubomír Sedlář
e5dc69cd41 comps-wrapper: Minor code cleanup
Use context manager for opening file, reduce duplication in creating
nodes with boolean values.

Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2017-04-13 11:45:23 +02:00
Lubomír Sedlář
fbf189d9c7 comps-wrapper: Add tests
This tests pretty much all the code that parses, filters and then writes
comps back to a file.

Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2017-04-13 11:45:23 +02:00
Lubomír Sedlář
daf3628594 comps-wrapper: Fix uservisible not being modifiable
The group uservisible attribute can now be modified in variants XML.

Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2017-04-13 10:28:26 +02:00
Lubomír Sedlář
20005adb98 comps-wrapper: Return IDs instead of yum.comps.Group
We never need anything more than the ID, so passing around a big
complicated object is not necessary.

Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2017-04-13 10:28:26 +02:00
Lubomír Sedlář
c5fcab2aa5 comps-wrapper: Remove unused code
There are a couple methods that are never used in the codebase. We don't
support using this module as a library from other programs either, so we
can just drop this.

Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2017-04-13 10:28:26 +02:00
Lubomír Sedlář
f6d07c1651 Be explicit about generating release for images
The config now uses similar logic what previous commit did for OSTree.
Also we should report error when an unknown generator is used.

Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2017-04-13 10:17:59 +02:00
Lubomír Sedlář
0f4b6b1947 docs: Add examples for generated versions
Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2017-04-13 10:17:59 +02:00
Lubomír Sedlář
98f40f6138 ostree: Autogenerate a version
If the value is a particular magic string, we will expand it to a proper
value.

Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2017-04-13 10:17:59 +02:00
Ralph Bean
01607602c6 Expand compatible arches when gathering from modules.
Fixes #596.

Signed-off-by: Ralph Bean <rbean@redhat.com>
2017-04-12 14:35:46 -04:00
Lubomír Sedlář
dcc1750df2 gather: Clean up method deps
* Remove unused arguments
 * Remove duplication

Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2017-04-11 15:46:34 +02:00
Lubomír Sedlář
0168388492 gather: Report error if there is no input
Running depsolving with no requested inputs will only lead to a hard to
decipher error. We should instead explicitly tell the user that there is
a problem.

Unit tests are added to add to test this functionality.

Relates: #585
Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2017-04-11 15:46:34 +02:00
Lubomír Sedlář
b5efb67ff1 init: Warn when variants mentions non-existing comps group
When variants XML lists a group that does not match any known group in
input comps, report a warning. This is not necessarily a problem in
itself, but having this information in the log can help debug problems.

Relates: #585
Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2017-04-11 15:46:34 +02:00
Jan Kaluza
621f1e2247 Fix createrepo issue for modular compose when multiple threads tried to use the same tmp directory.
Signed-off-by: Jan Kaluza <jkaluza@redhat.com>
2017-04-11 15:16:44 +02:00
Lubomír Sedlář
d4b7293acb unified-iso: Use different type for debuginfo iso
This requires productmd>=1.6.

Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2017-04-06 09:08:08 +02:00
Lubomír Sedlář
f6121f0887 unified-iso: Handle missing paths in metadata
For empty variants the path is no longer stored, so we need to handle
the possible exception. This has no effect on the actual result, as if
the path was empty, we would bail anyway on missing .treeinfo.

Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2017-04-06 08:24:03 +02:00
Qixiang Wan
2f5d6d7dcd unify repo and repo_from options
Config option 'repo' and 'repo_from' are used in several phases, merge
them with one option 'repo'. 'append' in schema is used for appending
the values from deprecated options to 'repo', so it won't break on any
existing config files that have the old options of 'repo_from' and
'source_repo_from' (which is an alias of 'repo_from').

And 'repo' schema is updated to support repo dict as the value or an
item in the values, a repo dict is just a dict contains repo options,
'baseurl' is required in the dict, like:

{"baseurl": "http://example.com/url/to/repo"}

or:

{"baseurl": "Serer"}

currently this is used in ostree phase to support extra repo options
like:

{"baseurl": "Server", "exclude": "systemd-container"}

Signed-off-by: Qixiang Wan <qwan@redhat.com>
2017-03-29 10:12:32 +08:00
Qixiang Wan
0ee2189d9c Fix some PEP8 errors in util.py
Signed-off-by: Qixiang Wan <qwan@redhat.com>
2017-03-29 10:12:32 +08:00
Qixiang Wan
0f508e2228 move translate_path from paths.py to util.py
So translate_path can be used in util.py, or it will result in
circular import error.

Signed-off-by: Qixiang Wan <qwan@redhat.com>
2017-03-29 10:12:32 +08:00
Qixiang Wan
d1763fca7e checks.py: support 'append' option
If 'append' is defined for a property, append the values from append
options to the property. Note: The property must support to be a list
of values.

For example:

with schema:

    schema = {
        "$schema": "http://json-schema.org/draft-04/schema#",
        "title": "Pungi Configuration",
        "type": "object",
        "definitions": {
            "list_of_strings": {
                "type": "array",
                "items": {"type": "string"},
            },
            "strings": {
                "anyOf": [
                    {"type": "string"},
                    {"$ref": "#/definitions/list_of_strings"},
                ]
            },
        },
        "properties": {
            "release_name": {"type": "string"},
            "repo": {"$ref": "#/definitions/strings", "append": "repo_from"}
        },
        "additionalProperties": False,
    }

and config:

    repo = "http://url/to/repo"
    repo_from = "Server"

config will be updated to:

    repo = ["http://url/to/repo", "Server"]

It supports multiple append options too, like:

    "repo": {
        "$ref": "#/definitions/strings",
        "append": ["repo_from", "source_repo_from"],
    }

Signed-off-by: Qixiang Wan <qwan@redhat.com>
2017-03-29 10:12:32 +08:00
Qixiang Wan
2aacefd9cd checks.py: show warning message for alias option
Show warning message for any alias option find in config instance.
Example warning message:

WARNING: Config option 'product_name' is deprecated and now an alias to
'release_name', please use 'release_name' instead. In:
{'release_name': 'dummy product', 'product_name': 'dummy product'}

Signed-off-by: Qixiang Wan <qwan@redhat.com>
2017-03-29 10:12:32 +08:00
Lubomír Sedlář
9784961568 4.1.14 release
Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2017-03-27 18:04:26 +02:00
Qixiang Wan
258d716a71 Not create empty skeleton dirs for empty variants
Do not create empty skeleton dirs for empty variants which we do for rpm
variants in some phases (some others already have the check):
1. createiso phase
2. extra_files phase
3. gather phase

In addtion to this, compose metadata (composeinfo.json) doesn't include
variant paths which don't exist or are just empty dirs now.

Fixes: #497
Merges: #572
Signed-off-by: Qixiang Wan <qwan@redhat.com>
2017-03-27 17:55:54 +02:00
Lubomír Sedlář
d0974d5c6a Merge #578 Save modules metadata as full yaml object and query only active modules from PDC 2017-03-27 13:33:30 +00:00
Jan Kaluza
be9a63c42f Query only active modules in PDC.
Signed-off-by: Jan Kaluza <jkaluza@redhat.com>
2017-03-27 15:30:06 +02:00
Jan Kaluza
1575ed28ea Save modules metadata as full yaml object
Signed-off-by: Jan Kaluza <jkaluza@redhat.com>
2017-03-27 15:28:18 +02:00
Lubomír Sedlář
2b21e13aad Skip DNF tests if there are import problems
If there are import errors for DNF, multilib or other related package,
we can assume the tests are running on EPEL. The DNF tests should be
skipped in that case.

Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2017-03-27 09:42:58 +02:00
Lubomír Sedlář
5dd2b3947d Rename option to switch gather backend
Calling it gather_backend is similar to repoclosure_backend we already
have. It's also more obvious what it does.

Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2017-03-24 09:24:50 +01:00
Lubomír Sedlář
76cf4a7540 Update to use python-multilib
We also rename the old multilib module used by dnf code to multilib_yum
to make it clear what is imported where.

Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2017-03-24 09:24:50 +01:00
Lubomír Sedlář
7bdaa3bd5b Update spec file with new dependencies and files
Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2017-03-24 09:24:50 +01:00
Lubomír Sedlář
77673e1eac Improve documentation
Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2017-03-24 09:24:50 +01:00
Lubomír Sedlář
fcd4c231c4 Stop importing hawkey directly
It's API is considered deprecated.

Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2017-03-24 09:24:50 +01:00
Lubomír Sedlář
27b24a489f Handle noarch debuginfo packages
Pull debuginfo packages for noarch packages as well, but only when the
debuginfo is noarch as well.

Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2017-03-24 09:24:50 +01:00
Lubomír Sedlář
d23a2f4548 Fix multilib exclude pattern to not match noarch
Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2017-03-24 09:24:50 +01:00
Lubomír Sedlář
5533bf7ca3 Simplify add_binary_package_deps
Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2017-03-24 09:24:50 +01:00
Lubomír Sedlář
c32bdce46d Work around a bug in DNF
https://bugzilla.redhat.com/show_bug.cgi?id=1418298

Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2017-03-24 09:24:50 +01:00
Lubomír Sedlář
73b8928013 Expand multilib blacklist and whitelist
This way we pay once for the expansion, and lookups are then done in
constant time instead of iterating over the list over and over again.

Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2017-03-24 09:24:50 +01:00
Lubomír Sedlář
ba57e6ee60 multilib devel should match only suffixes of provides
Otherwise bullet-devel-doc would be considered a multilib package by
this method.

Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2017-03-24 09:24:50 +01:00
Lubomír Sedlář
5c1d04eb00 Add matching multilib method to log
Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2017-03-24 09:24:50 +01:00
Lubomír Sedlář
08fbdec494 Add detailed reason why package is added
Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2017-03-24 09:24:49 +01:00
Lubomír Sedlář
919e4d748e Remove extra section for adding greedy=build packages
It does not change any result for tests, and makes it work a lot faster.

Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2017-03-24 09:24:49 +01:00
Lubomír Sedlář
35e72df99f Explicitly remove all temporary files
There is no guarantee __del__ will ever be called, and we were leaving a
ton of stuff in /tmp. With this patch we pass the temporary directories
explictly and make sure they are deleted at the end.

Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2017-03-24 09:24:49 +01:00
Lubomír Sedlář
fe026bb588 Handle Requires(pre|post)
These requires are accessible from a separate attribute, but we want to
handle them the same ways as regular Requires.

Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2017-03-24 09:24:49 +01:00
Lubomír Sedlář
2f40a45708 Honor multilib_blacklist for initial packages matching a glob
We want to exclude all multilib packages matching the blacklist (that
are not noarch) from the package set.

Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2017-03-24 09:24:49 +01:00
Lubomír Sedlář
d4f8e32a80 Fix handling globs in input packages
Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2017-03-24 09:24:49 +01:00
Lubomír Sedlář
a9415eb0e5 Simplify add_multilib_package method
Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2017-03-24 09:24:49 +01:00
Lubomír Sedlář
cd80d6ef5a Stop caching provides of added packages
This only works in non-greedy mode. When greedy, the same provides can
be linked to multiple packages that should be pulled in.

Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2017-03-24 09:24:49 +01:00
Lubomír Sedlář
7343daba24 Clean up logging excluded packages
Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2017-03-24 09:24:49 +01:00
Lubomír Sedlář
e06e9165fc Add checking of flags for dnf depsolving
Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2017-03-24 09:24:49 +01:00
Lubomír Sedlář
8cc912c5aa Install new executable
Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2017-03-24 09:24:49 +01:00
Lubomír Sedlář
ec67eac1cc Use enum for flags
This adds an extra dependency on python-enum34.

Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2017-03-24 09:24:49 +01:00
Lubomír Sedlář
d5e6639a6d Reduce duplication in code
Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2017-03-24 09:24:49 +01:00
Lubomír Sedlář
9fd8e6319f Handle fulltree_excludes list
Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2017-03-24 09:24:49 +01:00
Lubomír Sedlář
9a1674f3bf Improve error message for non-matching patterns
Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2017-03-24 09:24:48 +01:00
Lubomír Sedlář
b53e4a84d3 Fix fulltree when greedy
When greedy, fulltree should pull in all native and multilib packages.

Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2017-03-24 09:24:48 +01:00
Lubomír Sedlář
3a6653fbc2 Clean up main loop
Greatly reduce duplication by moving common code into a method.

Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2017-03-24 09:24:48 +01:00
Lubomír Sedlář
0a44b2fd07 Filter source packages
Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2017-03-24 09:24:48 +01:00
Lubomír Sedlář
5ef630d6d4 Simplify code
Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2017-03-24 09:24:48 +01:00
Lubomír Sedlář
99699b85aa Use same tests for yum and dnf depsolving
Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2017-03-24 09:24:48 +01:00
Lubomír Sedlář
a155674269 Set persistdir to a temporary location
We don't want to even touch any system directory.

Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2017-03-24 09:24:48 +01:00
Lubomír Sedlář
9b2f0349de Define dnf_gather option in schema
Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2017-03-24 09:24:48 +01:00
Lubomír Sedlář
e753891e27 Remove FSF address from copyright headers
Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2017-03-24 09:24:48 +01:00
Lubomír Sedlář
b9fd755a05 Add only one handler to logger
Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2017-03-24 09:24:48 +01:00
Lubomír Sedlář
4f4fd845d9 Fix PEP8 complaints
* Remove dead imports
* Remove dead code
* Fix extra empty lines
* Fix formatting
* Break too long lines

Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2017-03-24 09:24:48 +01:00
Daniel Mach
fdda8fe491 Fix multilib blacklist/whitelist when no multilib_method is set.
Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2017-03-24 09:24:48 +01:00
Daniel Mach
22a6291c8a Remove hardcoded blacklists and whitelists from multilib_dnf.
Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2017-03-24 09:24:48 +01:00
Daniel Mach
26cac77639 Add default logging handler to gather_dnf.
Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2017-03-24 09:24:47 +01:00
Daniel Mach
94d16d8c32 Rewrite gathering to use new hawkey code that's part of libhif.
Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2017-03-24 09:24:47 +01:00
Lubos Kocman
dfef1837ea gather_dnf: don't add srpm deps if --nodeps is set
Signed-off-by: Lubos Kocman <lkocman@redhat.com>
2017-03-24 09:24:47 +01:00
Lubos Kocman
14784847d4 add dnf_arch wrapper to workaround dnf.arch.basearch -> dnf.rpm.basearch change
Signed-off-by: Lubos Kocman <lkocman@redhat.com>
2017-03-24 09:24:47 +01:00
Lubos Kocman
1a8f0bb0f9 gather_dnf.py: use self.logger for printing output
Signed-off-by: Lubos Kocman <lkocman@redhat.com>
2017-03-24 09:24:47 +01:00
Daniel Mach
320d2a8ae2 Boost add_initial_packages() by using query cache for 'build' greedy method.
Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2017-03-24 09:24:47 +01:00
Daniel Mach
c02d801988 Boost prepopulate by using query cache.
Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2017-03-24 09:24:47 +01:00
Daniel Mach
321d471125 Additional profiling in Gather.add_initial_packages().
Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2017-03-24 09:24:47 +01:00
Daniel Mach
5a2c4f5e0f Improve working with query cache.
Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2017-03-24 09:24:47 +01:00
Daniel Mach
06635a3917 Add profiler to pungi-gather.
Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2017-03-24 09:24:47 +01:00
Daniel Mach
61e76d5824 Improve depsolving speed by pre-computing provides query.
Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2017-03-24 09:24:47 +01:00
Michael Mraka
026e49e259 speedup filter(sourcerpm=XXX)
originally 6519 calls 18, i.e. 2% out of 15 mins

Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2017-03-24 09:24:47 +01:00
Michael Mraka
835460ce8f speedup filter(name=XXX, version=YYY, release=ZZZ)
originally 3109 calls 54s, i.e. 6% out of 15 mins

Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2017-03-24 09:24:47 +01:00
Michael Mraka
110fe7647c speedup filter(pkg=XXX, arch__neq=WWW)
originally 17976 calls 157s, i.e. 17% out of 15 mins

Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2017-03-24 09:24:46 +01:00
Michael Mraka
ec56ee75e2 speedup filter(name=XXX, version=YYY, release=ZZZ, arch__neq=WWW)
the second most demanding filter
it is called 8297 times and gets 189s out of 15min run which is 21%
spent here

Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2017-03-24 09:24:46 +01:00
Michael Mraka
d8fcaf95f7 speedup filter(sourcerpm=XXX, arch__neq=YYY)
this is most demanding filter
it is called 10826 times and gets 210.277010s out of 15min run which is
23% spent here

Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2017-03-24 09:24:46 +01:00
Lubomír Sedlář
36f57b26b8 Add scripts to compare YUM and DNF gathering
There are scripts to re-run depsolving with any backend based on config
and log file.

There is a new script to compare logs from two runs and report
differences. This script will be installed system wide in final RPM.

Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2017-03-24 09:24:46 +01:00
Daniel Mach
99b68ca96b Simplify ks group handling.
Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2017-03-24 09:12:23 +01:00
Daniel Mach
7cb9e9dc20 Add support for mirrorlists in DNF gathering code.
Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2017-03-24 09:12:23 +01:00
Daniel Mach
ddba26edd7 Don't run fulltree on packages added via fulltree.
Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2017-03-24 09:12:23 +01:00
Daniel Mach
a5d302d036 Enable --fulltree, --selfhosting and --nodeps in pungi-gather.
Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2017-03-24 09:12:23 +01:00
Daniel Mach
aff6ac906c Enable langpack gathering in DNF gather.
Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2017-03-24 09:12:23 +01:00
Daniel Mach
43d8d02cb1 Integrate DNF gathering code with Pungi.
Set 'dnf_gather = True' (temporary option) in config file to enable DNF
gathering.

Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2017-03-24 09:12:23 +01:00
Daniel Mach
9764acbc4d Cache pkg.sourcerpm to get additional >5% boost.
Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2017-03-24 08:51:38 +01:00
Daniel Mach
13ed3f2b1d Performance improvements of DNF gathering.
Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2017-03-24 08:51:38 +01:00
Daniel Mach
caf11f55d4 New gathering (depsolving) module based on DNF.
Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2017-03-24 08:51:38 +01:00
Jan Kaluza
9fcd71f831 Add support for modular composes
Signed-off-by: Jan Kaluza <jkaluza@redhat.com>
2017-03-22 15:55:52 +01:00
Lubomír Sedlář
4b90822115 Add a script for modifying ISO images
With this script it's possible to add additional files into an ISO file.
If the file happens to be ks.cfg, the boot configs are tweaked so that
the kickstart is actually used.

Resolves: #503
Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2017-03-21 07:55:19 +01:00
Lubomír Sedlář
ae5ee3d856 iso-wrapper: Refactor functions
Split the function for getting implant MD5 into two functions, so that
we can have access to other information retrieved by checkisomd5
command. A test case is added for both functions.

Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2017-03-21 07:55:19 +01:00
Lubomír Sedlář
306f7e69b0 iso-wrapper: Add utility for mounting images
This patch refactors logic for creating a temporary mount point,
mounting an image, running arbitrary code on it, unmounting the image
and removing the mount point. It immediately uses it in the buildinstall
phase.

Similar mounting is present in product_img phase as well, but due to
different usage pattern it's not changed yet.

Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2017-03-21 07:55:19 +01:00
Lubomír Sedlář
05a666fb3b buildinstall: Move tweaking configs into a function
This will allow us to more easily test the code and also reuse it in
other places.

Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2017-03-21 07:55:19 +01:00
Lubomír Sedlář
55035487de image-build: Correctly write can_fail option
Koji expects the value as comma separated list, otherwise it will ignore
it. This makes it possible for the image building to fail on per arch
basis.

Relates: #128
Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2017-03-20 09:05:03 +01:00
Qixiang Wan
79e97dc845 pungi-koji: new cmd option '--latest-link-status'
Add a new option 'latest-link-status' to pungi-koji, if this is
specified, pungi will only create the latest symbol link to the compose
when compose's status matches the specified statuses. The status name is
case insensitive. If the option is not specified it will act as before.

Example:

pungi-koji --target-dir=_composes --config=data/dummy-pungi.conf \
--test --latest-link-status=finished --latest-link-status=finished_incomplete

Signed-off-by: Qixiang Wan <qwan@redhat.com>
2017-03-20 11:15:30 +08:00
Lubomír Sedlář
23e53219eb live-cd: Print task ID on success
Relates: #570
Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2017-03-15 17:37:00 +01:00
Lubomír Sedlář
69af0a6a65 ostree-installer: Print task ID on success
Relates: #570
Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2017-03-15 17:37:00 +01:00
Lubomír Sedlář
263a990489 ostree: Print task ID on success
Relates: #570
Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2017-03-15 17:37:00 +01:00
Lubomír Sedlář
5ee285cc24 live-media: Print task ID on success
Relates: #570
Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2017-03-15 17:37:00 +01:00
Lubomír Sedlář
b10d275745 image-build: Print task ID on success
Relates: #570
Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2017-03-15 17:37:00 +01:00
Dennis Gilmore
b09641a708 Merge #568 buildinstall: Print debug info if unmount fails 2017-03-15 16:07:33 +00:00
Lubomír Sedlář
94b1159829 ostree-installer: Fix logging directory
Currently if there are multiple ostree installers for the same
architecture, the logfiles all end up in the same location and overwrite
each other.

This patch moves the logs to logs/<arch>/<variant>/ostree_installer-X/
for a unique value of X so that there can be multiple runs even for the
same tree.

Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2017-03-15 15:54:45 +01:00
Lubomír Sedlář
f0dc15bdc6 buildinstall: Print debug info if unmount fails
When even after retries the unmounting still fails, this patch runs `ls
-lA`, `fuser -vm` and `lsof +D` on the directory to give some idea of
what's blocking it.

Relates: #559
Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2017-03-14 15:06:20 +01:00
Qixiang Wan
d081a4eda8 pkgset: report all unsigned packages
Fixes: #552
Merges: #567
Signed-off-by: Qixiang Wan <qwan@redhat.com>
2017-03-14 09:50:28 +01:00
Qixiang Wan
ee21663c8b default createrepo_checksum to sha256
Signed-off-by: Qixiang Wan <qwan@redhat.com>
2017-03-14 13:15:43 +08:00
Lubomír Sedlář
a1214525f5 unified-iso: Log better error when linking fails
When linking files fails due to target path already existing, we should
print details about the conflict.

Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2017-03-13 14:45:13 +01:00
Lubomír Sedlář
08b9d275a8 unified-iso: Blacklist extra files metadata
The file is in each variant that has extra files, and would create a
conflict when linking the files.

Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2017-03-13 14:45:13 +01:00
Lubomír Sedlář
5cd1c22e2d buildinstall: Retry unmounting image
If the image can not be unmounted because the device is busy, we should
retry. There will be increasing pauses between the attempts. At most 10
attempts will be done before giving up.

Fixes: #559
Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2017-03-10 08:29:54 +01:00
Lubomír Sedlář
9041ccccc4 Remove indices from documentation
They are not generated as we don't actually document code. The search
page is removed as well (because it does not seem to work).

Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
Fixes: #462
2017-03-09 12:47:12 +01:00
Lubomír Sedlář
cd805a1e6d iso-wrapper: Handle wrong implant md5
If the checkisomd5 command exits successfully but returns a wrong value,
we should catch and log that. In theory this should be impossible, but
we have seen it in production.

Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2017-03-07 09:58:14 +01:00
Lubomír Sedlář
1647f7612a image-build: Remove check for number of images
If task does not produce the expected number of images, it should fail
at Koji level. Also, this check does not really work when some
architectures are allowed to fail.

Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2017-03-06 19:31:08 +01:00
Lubomír Sedlář
63a3b6ccaa Merge #538 consolidate repo option names 2017-03-06 12:55:44 +00:00
Lubomír Sedlář
fa3d94bae3 Merge #554 osbs: write manifest for scratch osbs 2017-03-06 12:52:47 +00:00
Lubomír Sedlář
d3a2ceb8ce Extract only first version from specfile
When tagging a new version, rpm will give us the version twice, one for
main package and one for the -utils subpackage. We should only use the
first one (they should be the same anyway).

Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2017-03-06 09:08:13 +01:00
Qixiang Wan
2ae8710934 consolidate repo option names
live_images:            additional_repos        -> repo
ostree:                 source_repo_from        -> repo_from
                        extra_source_repos      -> repo
ostree_installer:       source_repo_from        -> repo_from

With the change, the phases have consolidate option names for variant
repos and external repos.

Old option names will continue to work, old names will be converted
to new names after validation automatically if new options are not
specified in config.

Signed-off-by: Qixiang Wan <qwan@redhat.com>
2017-03-06 09:26:42 +08:00
Qixiang Wan
c93207addb checks: extend validator with 'alias'
When a property has 'alias' defined, and it's not present in instance,
if the alias property is present, add the property with value from alias
property before remove the alias property from instance.

Examples:

with schema:
{
        "$schema": "http://json-schema.org/draft-04/schema#",
        "title": "Pungi Configuration",
        "type": "object",
        "properties": {
            "release_name": {"type": "string", "alias": "product_name"},
        },
        "required": ["release_name"],
        "additionalProperties": False,
}

1. config = {"release_name": "dummy product"}:

   validate pass, config not changed after validation.

2. config = {"product_name": "dummy product"}:

   validate pass, config updated to the following after validation:

   config: {"release_name": "dummy product"}

3. config = {"name": "dummy product"}:

   validate fail, errror message is "Failed validation in : 'release_name' is a required property",
   and warning message is "WARNING: Unrecognized config option: name."

4. config = {"product_name": "dummy product", "release_name": "dummy product"}

   validate fail, error message is "Failed validation in : product_name is an alias of release_name, only one can be used."

Signed-off-by: Qixiang Wan <qwan@redhat.com>
2017-03-06 09:26:42 +08:00
Qixiang Wan
40e2874676 osbs: write manifest for scratch osbs
FIXES: #485

Signed-off-by: Qixiang Wan <qwan@redhat.com>
2017-03-06 09:26:01 +08:00
Lubomír Sedlář
345308464f 4.1.13 release
Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2017-03-03 14:34:45 +01:00
Lubomír Sedlář
069ee8d3df Merge #555 Make MANIFEST.in stricter 2017-03-03 11:56:41 +00:00
Qixiang Wan
a52561da6d Make MANIFEST.in stricter
Global exclude python bytecode files.
Global exclude vim & emace temporary files.
Only include specs dir under tests/data, there will be other dirs
generated for testing, we don't want them.

FIXES: #427

Signed-off-by: Qixiang Wan <qwan@redhat.com>
2017-03-03 14:01:50 +08:00
Qixiang Wan
f43d3584c5 Remove one line of log print
The line of log printing can result in "No handlers could be found for
logger" warning in quiet mode when custom paths module is enabled,
because file handler is setup after that, since this line is only
printed to screen (when pungi-koji is not ran in quiet mode) and doesn't
contain important info, it doesn't hurt to remove it.

Signed-off-by: Qixiang Wan <qwan@redhat.com>
2017-03-02 11:46:33 +08:00
Lubomír Sedlář
a49bf3d74e gather: Filter comps group on depsolving input of optional
This is a follow up of 8bc65a8be5. When
resolving packages that go into optional variant, we only want to skip
filtering groups when working on a top-level variant.

Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2017-02-27 12:54:12 +01:00
Dennis Gilmore
8b1fb287d3 Merge #539 comps: Filter comps groups for optional variants 2017-02-23 20:13:39 +00:00
Lubomír Sedlář
4ea1916a87 Enable customizing runroot task weight
For different cases where runroot is used it's now possible to set
custom weight. The usecase for this is to avoid one builder taking too
many tasks. Especially buildinstall is quite resource intensive, so one
builder taking multiple tasks at the same time leads to very slow
compose time.

Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2017-02-23 12:44:27 +01:00
Lubomír Sedlář
8bc65a8be5 comps: Filter comps groups for optional variants
The optional variant can defined by just adding has_optional=True into
variant xml. In such case it has no comps groups and Pungi would copy
the original file unmodified. This leads to extra packages being pulled
into the optional variant.

In this case the correct solution is to filter the comps and remove all
groups.

Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2017-02-23 12:44:20 +01:00
Lubomír Sedlář
d9ab899920 Rename main logger
The name is not displayed anywhere. Changing it to lowercase will
however avoid possible problem if we create a sublogger somewhere else
in the codebase with name based on module name. Such logger would not
have any handlers defined.

Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2017-02-23 11:08:31 +01:00
Lubomír Sedlář
9e020c2782 ostree: Silence logger in tests
Instead of creating and configuring the logger at module import time, we
can only get the logger if it's actually needed and configure it from
the main script.

Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2017-02-23 11:08:31 +01:00
Lubomír Sedlář
3162fea60d ostree: Fix crash when extra repos are missing
The default needs to be an empty list, not `None`.

Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2017-02-22 15:48:06 +01:00
Lubomír Sedlář
857aee05c1 util: Add a utility for managing temporary files
In multiple situations we need to create temporary files or directories
that should not be preserved after compose is finished. Let's add
context managers that ensure these get cleaned up.

This fixes tests leaving garbage around in /tmp.

Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2017-02-20 09:14:25 +01:00
Qixiang Wan
a57bc13e30 Add --quiet option to pungi-koji
log will not be printed to screen when quiet mode is enabled.

Signed-off-by: Qixiang Wan <qwan@redhat.com>
2017-02-20 15:00:03 +08:00
Qixiang Wan
d496eeb090 handle opening empty images.json while re-running pungi-koji in debug mode
If there is an empty images.json file exists, re-running pungi-koji
in debug-mode will fail with exception. We can just ignore the exception
in such cases, pungi-koji will create a correct images.json later.

Signed-off-by: Qixiang Wan <qwan@redhat.com>
2017-02-16 17:00:14 +08:00
Qixiang Wan
8d41a004c3 minor change: remove an always true condition
Signed-off-by: Qixiang Wan <qwan@redhat.com>
2017-02-14 16:36:47 +08:00
Daniel Mach
ad23efd323 Refactor depsolving tests
This adds a new test for Requires(pre) and (post). The general structure
of the test now makes it easy to use the same test scenarios for
different backend.

Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2017-02-13 12:32:07 +01:00
Lubomír Sedlář
e00776a413 multilib: Remove FileMultilibMethod class
In order to do something meaningful, the class needs to be instantiated
with arguments pointing the blacklist and whitelist.

The `file` multilib method used via `pungi-koji` or `pungi` directly has
no way to pass those in.

The only way this class can be useful would be if someone actually
imported the class directly in their own code. Pungi is not meant to be
used as a library though, so this is not really a supported use case.

Not to mention that the `select` method always returned `False`.

Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2017-02-10 12:32:45 +01:00
Lubomír Sedlář
c3cf09a2f7 pkgset: Use additional packages for initial pull
We call pungi to get the packages from external repos if
pkgset_source=repos. In this case we need to look at additional packages
as well.

Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
Fixes: #528
2017-02-09 13:50:09 +01:00
Lubomír Sedlář
b5cfeaa6ca metadata: Fix .treeinfo paths for addons
Currently .treeinfo sections for addons are missing paths to packages
and repository.

Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2017-02-07 15:50:33 +01:00
Lubomír Sedlář
9533fca96c koji_wrapper: Always use --profile option with koji
This patch adds this option to all invoked koji commands.

Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2017-01-30 13:00:25 +01:00
Dennis Gilmore
42cdf047cc add missing koji_profile from test compose setting
Signed-off-by: Dennis Gilmore <dennis@ausil.us>
2017-01-30 05:06:46 -06:00
Dennis Gilmore
5a498f80b6 use koji --profile when calling koji for livemedia
take the profile from the koji config and apply it to the koji cli
when building livemedia

Signed-off-by: Dennis Gilmore <dennis@ausil.us>
2017-01-30 04:44:31 -06:00
Dennis Gilmore
c650f04d0b Revert "live-media: Call correct koji alias"
This was accidently merged and is not correct
This reverts commit 02beb35e67.

Signed-off-by: Dennis Gilmore <dennis@ausil.us>
2017-01-30 04:44:17 -06:00
Lubomír Sedlář
dc7d3b36ab repoclosure: Don't run build deps check
Fixes: #521
Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2017-01-30 10:16:03 +01:00
Dennis Gilmore
7feadb14ba Merge #518 Migrate test phase to dnf repoclosure 2017-01-28 16:49:10 +00:00
Lubomír Sedlář
02beb35e67 live-media: Call correct koji alias
We need call whatever command is configured in koji_profile. It's not
always `koji`.

Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2017-01-26 15:32:21 +01:00
Lubomír Sedlář
e3fe67be53 repoclosure: add option to use dnf backend
This adds a new option repoclosure_backend that changes what tool is
used for repoclosure.

Checking build dependencies is currently not supported, as `dnf` does
not have the corresponding option.

Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2017-01-26 13:39:12 +01:00
Lubomír Sedlář
95fc0fa4ab repoclosure: Add test for repoclosure in test phase
Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2017-01-26 13:27:48 +01:00
Lubomír Sedlář
56932f9067 repoclosure: Remove duplicated code
Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2017-01-26 10:55:23 +01:00
Lubomír Sedlář
7a8fa87172 repoclosure: Remove useless wrapper class
We already get namespacing from being in a separate module.

Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2017-01-26 10:55:23 +01:00
Lubomír Sedlář
5693bf9925 repoclosure: Remove unused code
There are a lot of options that are not used by any code path in Pungi.
There is not reason to provide access to them.

Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2017-01-26 10:55:23 +01:00
Lubomír Sedlář
9af0cca9eb repoclosure: Add a test for the wrapper
Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2017-01-26 10:55:23 +01:00
Lubomír Sedlář
8418b68fb0 image-build: Pass arches around as a list
Instead of joining the arches as a comma separated string and splitting
it again later. Ultimately we do need the original format to pass to
koji wrapper, but we can produce that value later.

Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2017-01-24 08:50:21 +01:00
Lubomír Sedlář
6c708549c8 image-build: Expand arches for can_fail
We need to work with a list of strings, not a comma-delimited single
string.

Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2017-01-24 08:50:21 +01:00
Qixiang Wan
40df2034a8 image_checksum: add file sizes to checksum files
Write file sizes of images in checksum files with comment lines,
checksum files are in BSD-style which supports comments by starting
a line with '#'.

Example:

$ cat RHEL-7.4-20170123.n.4/compose/Server/x86_64/iso/RHEL-Server-7.4-x86_64-20170123.n.4-CHECKSUM
 # RHEL-7.4-20170123.n.4-Server-x86_64-dvd1.iso: 3725590528 bytes
 # RHEL-7.4-20170123.n.4-Server-x86_64-boot.iso: 377487360 bytes
 SHA256 (RHEL-7.4-20170123.n.4-Server-x86_64-dvd1.iso) = fa3de37fe4b859a0285f16ea1123f44f15aec169aea84bf010aa3821bd58fc41
 SHA256 (RHEL-7.4-20170123.n.4-Server-x86_64-boot.iso) = 74bf68c54665328adb08b09daf773c67e633b5907e3e2797338ab3c1b58fdf48

(No space at the start of line, because git commit message drops lines
start with '#', added one space to avoid that.)

When there are multiple checksum types specified and checksums are
written to individual files, file size of the image will also be
written to every checksum files.

Fixes: #493

Signed-off-by: Qixiang Wan <qwan@redhat.com>
2017-01-23 18:20:21 +08:00
Lubomír Sedlář
4f011fbd45 Add documentation and example for greedy_method
Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2017-01-19 09:24:54 +01:00
Dennis Gilmore
59dd4dbcd8 replace ${basearch} when updating the ref
pungi-make-ostree has to run on the target arch so that rpm
scriptlets can be ran. as a reult we can ask rpm what the
basearch is for the running environment. For notifications
we have to pass in the arch we are running for.

Signed-off-by: Dennis Gilmore <dennis@ausil.us>
2017-01-18 21:21:26 -06:00
Patrick Uiterwijk
4edf567bd4 Add some debugging about ref updating
Signed-off-by: Patrick Uiterwijk <puiterwijk@redhat.com>
2017-01-18 14:09:15 -06:00
Lubomír Sedlář
d3e701e10f 4.1.12 release
Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2017-01-18 08:07:42 +01:00
Lubomír Sedlář
2c76313382 unified-iso: Fall back to default config
When the configuration can not be read from the compose, we should use
default values instead of aborting. This allows us to work with composes
produced by Distill.

Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2017-01-17 08:15:13 +01:00
Qixiang Wan
a9b275f13b osbs: optionally check GPG signatures
If gpgkey option is defined in config, set gpgcheck=1 and set
gpgkey=<value> in variant repo files.

Fixes: #487
Signed-off-by: Qixiang Wan <qwan@redhat.com>
2017-01-17 13:08:58 +08:00
Qixiang Wan
5d241d316a ostree-installer: Allow multiple repos in ostree installer
Add new key 'repo' to allow specifying multiple repos as the source
repositories. And change 'source_repo_from' to allow specifying multiple
vairant names to use variant repos as source repositories.

Doc of 'source_repo_from' is updated to not mention URL is supported,
though we still support that in code. User should add url of repos in
'repo' key instead of 'source_repo_from'.

Fixes: #508

Signed-off-by: Qixiang Wan <qwan@redhat.com>
2017-01-13 16:57:30 +08:00
Lubomír Sedlář
aa5487d544 Update tox.ini
Add more useless pycodestyle checks, and explain what the codes mean.

Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2017-01-11 14:37:41 +01:00
Lubomír Sedlář
afaa0e025e unified-iso: Create isos with debuginfo packages
When creating unified ISOs, the script will now also create one iso per
architecture containing a repo with debuginfo packages.

There is no switch to turn this off. The images can simply not be
shipped if not wanted.

Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2017-01-11 14:36:25 +01:00
Qixiang Wan
6fbf1e8f59 Create temporary dirs under compose's workdir
Add compose.mkdtemp which creates and returns a unique temporary
directory under <compose_topdir>/work/{global,<arch>}/tmp[-<variant>]/

Change tempfile.mkdtemp in code to compose.mkdtemp, so temporary
dirs are created under the compose's workdir, this makes it more
easier to maintain the temporary dirs/files especially when compose
fails with amount of temporary files left there.

Signed-off-by: Qixiang Wan <qwan@redhat.com>
2017-01-11 15:25:47 +08:00
Dennis Gilmore
f6f84de1fb Merge #499 Fix for running tests out of source tarball 2017-01-05 12:53:32 +00:00
Lubomír Sedlář
b25d7e7153 spec: Update upstream and source URL
Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2017-01-05 13:26:52 +01:00
Lubomír Sedlář
dc19363a5c unified-iso: Create work/ dir if missing
In theory the directory could be deleted before generating the isos.
This patch will recreate it when needed.

Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2017-01-05 13:21:49 +01:00
Lubomír Sedlář
b93e0fd4ab spec: Copy %check section from Fedora
It runs the tests only once, runs the expensive preparation of RPMs only
if unit tests succeeded and does not compute coverage (which could not
be examined anyway).

Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2017-01-05 13:21:49 +01:00
Lubomír Sedlář
9306ee6357 Update MANIFEST.in to include test data
Running tests in tarball would fail without this.

Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2017-01-05 13:21:49 +01:00
Lubomír Sedlář
ce218288db osbs: Add better example to documentation
Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2017-01-05 09:32:22 +01:00
Dennis Gilmore
baca306edf Merge #495 osbs: Enable specifying extra repos 2017-01-04 14:44:13 +00:00
Dennis Gilmore
46f77403df Merge #475 Allow failure for some arches 2017-01-04 14:43:22 +00:00
Dennis Gilmore
345432ac90 Merge #444 Add script to generate unified ISOs 2017-01-04 14:42:23 +00:00
Lubomír Sedlář
63bd9de744 metadata: Correctly parse lorax .treeinfo
Productmd does validation on the parsed value. There is a long list of
rules to populate `short` name in the productmd code.

There is a shim in pungi to make sure the short is populated if no rule
matches. After renaming product to release, the shim stopped working.

Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2017-01-04 15:18:56 +01:00
Lubomír Sedlář
20d035befa spec: Add a separate subpackage for extra utils
This subpackage currently includes:

 * pungi-config-validate
 * pungi-create-unified-isos
 * pungi-fedmsg-notification

Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2017-01-04 10:22:20 +01:00
Lubomír Sedlář
e260fe5581 Add script to generate unified ISOs
This a standalone script that will look into a compose and create
unified ISO for each architecture. The ISO contains RPM repositories for
all variants that have the arch.

Known issues:
 * The filename does not respect settings. This is tricky because the
   name could include variant name, which we don't have here (by design
   of unified ISO).
 * The same is true for volume id.

In order to test the feature without running actual compose, we need to
add essentially a big chunk of compose. Most of the files are empty, as
their content is never accessed.

Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2017-01-04 10:22:20 +01:00
Lubomír Sedlář
e7c8b2affd osbs: Validate config in tests
This makes sure the test configurations will be accepted in real usage.
It also enables us to remove some manual error checking that will be
performed by validator.

Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2017-01-04 09:47:26 +01:00
Lubomír Sedlář
61a4c43db0 osbs: Verify the .repo files contain correct URL
Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2017-01-04 09:47:26 +01:00
Lubomír Sedlář
814bf4484b osbs: Enable specifying extra repos
The same way live_media and image_build accept additional external repos
or variants list, there is now a `repo` and `repo_from` configuration
key to add these.

Fixes: #486
Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2017-01-04 09:47:19 +01:00
Qixiang Wan
2d404c88e6 [pungi-make-ostree] change 'tree' command '--log-dir' arg to be required
Signed-off-by: Qixiang Wan <qwan@redhat.com>
2016-12-15 18:55:04 +08:00
Patrick Uiterwijk
c64f75d1b4 Add test for krb_login with principal and keytab
Signed-off-by: Patrick Uiterwijk <puiterwijk@redhat.com>
2016-12-14 12:58:23 +00:00
Patrick Uiterwijk
cb4b5cc54d Make sure that the profile name is parsed correctly
Signed-off-by: Patrick Uiterwijk <puiterwijk@redhat.com>
2016-12-14 12:58:23 +00:00
Patrick Uiterwijk
c0c3e2e79d Make KojiWrapper support krb_login with keytab
Using getattr so we also work with versions of koji that do not
read principal and keytab from the config file.

Signed-off-by: Patrick Uiterwijk <puiterwijk@redhat.com>
2016-12-14 12:58:23 +00:00
Patrick Uiterwijk
c41c46403a Make KojiWrapper parse krb_rdns
Signed-off-by: Patrick Uiterwijk <puiterwijk@redhat.com>
2016-12-14 12:58:23 +00:00
Lubomír Sedlář
17a5f2841c Update documentation
Also remove the TODO comment from live images phase: the appliances are
already submitted one task per single arch, so this change is not
necessary.

Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2016-12-14 10:14:30 +01:00
Lubomír Sedlář
356b78d440 image-build: Allow failure only on some arches
This uses the --can-fail option in koji. Failing an optional image will
not abort whole task. If the whole task fails (or there is a problem on
the compose side), we abort unless all arches are optional.

Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2016-12-14 10:14:30 +01:00
Lubomír Sedlář
7f56b978ce live-media: Allow some arches to fail
This patch uses the `--can-fail` option of koji command line. If only
optional arches fail, the task will report as success. Failures on
compose box side are ignored if and only if all architectures are
optional.

Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2016-12-14 10:14:30 +01:00
Lubomír Sedlář
721932a573 image-build: Use install_tree from parent for nested variants
Buildinstall only runs for top-level variants. Addons, optionals and
integrated layered products must reuse install tree from their parent,
because otherwise there would be no boot.iso.

Fixes: #472
Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2016-12-14 10:04:01 +01:00
Lubomír Sedlář
c338219ef0 config: Report unknown options as warnings
Given the way config files can include other files, it is entirely
possible to use the same config file for both Pungi and Distill. Pungi
will however complain about unknown options.

This patch reverts part of c38bb480 and moves deprecation handling back
into schema validation. The validation method then returns a list of
errors and a list of warnings.

Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2016-12-13 11:58:08 +01:00
Lubomír Sedlář
ec6206b064 pungi: Fix --nosource option
When running with this option, if a debuginfo package is included in the
final package set, there would be a crash due to missing SRPM. To
replicate this issue, just use the argument with input kickstart listing
a single package which has debuginfo.

This is not an issue for Pungi 4, as it never uses the option in the
first place.

Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2016-12-13 10:45:05 +01:00
Lubomír Sedlář
56147f2e4d pungi: Handle missing SRPM
Source packages can be excluded while binary packages should still go
into the compose. This patch makes it so that the mapping from binary
packages to source packages contains None in such case. The code is
already capable of handling that. A warning will be emitted for each
binary package without source.

This also allows us to remove some code from `createSourceHashes` that
is now unused.

A test for excluding source package is added as well.

Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2016-12-13 10:45:04 +01:00
Qixiang Wan
83428a06bf [ostree-installer] Add 'installer' sub-command to pungi-make-ostree
The new sub-command 'installer' is added to support build OSTree
installer image with pungi-make-ostree. It can take an optional argument
'--extra-config' to read some of configurations from a json file. The
content of the json file can contains the configuration which are
supported in OSTree installer phase, the difference is variant UID is
not supported as a repo url in this case. A valid json file can be like
the following:

{
    "source_repo_from": "http://www.example.com/repo/workstation/os",
    "installpkgs": [
        "fedora-productimg-workstation"
    ],
    "add_template": [
        "/path/to/installer/template/lorax-configure-repo.tmpl"
    ],
    "add_template_var": [
        "ostree_osname=fedora-workstation",
        "ostree_ref=fedora/25/x86_64/workstation"
    ],
    "add_arch_template": [
        "/path/to/installer/template/lorax-embed-repo.tmpl"
    ],
    "add_arch_template_var": [
        "ostree_repo=https://www.example.com/compose/ostree",
        "ostree_osname=fedora-workstation",
        "ostree_ref=fedora/25/x86_64/workstation"
    ]
}

Signed-off-by: Qixiang Wan <qwan@redhat.com>
2016-12-12 19:30:35 +08:00
Qixiang Wan
e043604822 [ostree] Add 'tree' sub-command to pungi-make-ostree script
Update pungi-make-ostree to supourt sub-command 'tree', which is just
as the original feature of pungi-make-ostree to compose OSTree tree.
With the change we can add other sub commands later to build other
OSTree artifacts, like the installer image.

Inaddtional to the change, now the the 'tree' command can accept an
optional '--extra-config' parameter to update the original tree
configuration with extra configurations specified in a json file
before composing the OSTree tree.

Example:

pungi-make-ostree tree --repo=/ostree --treefile=/path/to/treefile \
--log-dir=/path/to/log --extra-config=/path/to/extra-config.json

The extra-config file can contains the same configuration as OSTree
phase, the difference is it doesn't understand variant UID as source
repo since it's not ran in the chain of phases. A valid configuration
can be like:

{
    "source_repo_from": "http://example.com/repo/x86_64/Server",
    "extra_source_repos": [
        {
            "name": "optional",
            "baseurl": "http://example.com/repo/x86_64/optional",
            "exclude": "systemd-container",
            "gpgcheck": False
        },
        {
            "name": "extra",
            "baseurl": "http://example.com/repo/x86_64/extra",
        }
    ],
    "keep_original_sources": True
}

The OSTree phase is updated to move out the task of updating treefile,
instead of that, it writes the extra configurations to a json file,
then 'pungi-make-ostree tree' will take it by option '--extra-config'.

Signed-off-by: Qixiang Wan <qwan@redhat.com>
2016-12-12 19:30:35 +08:00
Lubomír Sedlář
d3cad4795c metadata: Allow creating internal releases
The internal flag in productmd is meant to indicate that a compose is
not meant for publishing. This is potentially useful to allow filtering
in PDC or similar service.

Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2016-12-06 12:49:33 +01:00
Lubomír Sedlář
e66d8dd190 Add CLI option to create ci compose
Fixes: #476
Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2016-11-30 12:30:09 +01:00
Qixiang Wan
75934f20e5 Fix PhaseLoggerMixin in case of compose has _logger = None
80fa723 breaks pungi-config-validate that using ValidationCompose
with _logger set to None.

Signed-off-by: Qixiang Wan <qwan@redhat.com>
2016-11-30 14:41:02 +08:00
Lubomír Sedlář
dd814a5f4d ostree-installer: Use dvd-ostree as type in metadata
This depends on python-productmd >= 1.3 that understands this format.

Fixes: #417
Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2016-11-28 10:32:50 +01:00
Lubomír Sedlář
2bd18b1b03 image-build: Reduce duplication
All tests should print complete diffs on failure, so there is no need to
define this in each test separately.

Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2016-11-28 09:28:46 +01:00
Lubomír Sedlář
5148adf233 createrepo: Add tests for adding product certificates
If the certificate is enabled and exists, it will currently be added to
all rpm repositories.

Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2016-11-23 11:17:04 +01:00
Lubomír Sedlář
96fc6fb11e createrepo: Add tests for retrieving product certificates
Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2016-11-23 11:17:04 +01:00
Qixiang Wan
80fa723b1d Include phase name in log for some phases
Phases createiso, liveimages, image_build, ostree_installer and osbs are
done in parallel, logs from these phases are mixed and and it's not
obvious which log message belongs to which phase. This change adds phase
name in log message for these phases.

The new mixin 'PhaseLoggerMixin' is added to extend a Pungi phase with a
logging logger which copy handlers from compose's logger but with
formatter changed.

Fixes: #58
Signed-off-by: Qixiang Wan <qwan@redhat.com>
2016-11-23 16:47:22 +08:00
Dennis Gilmore
9e52c68c82 Merge #465 media-split: Print sensible message for unlimited size 2016-11-17 23:14:44 +00:00
Dennis Gilmore
6c89f86c53 Merge #466 pungi: Include noarch debuginfo 2016-11-17 23:14:03 +00:00
Colin Walters
7bcbe30fd2 Expose lorax's --rootfs-size argument
This is going to be necessary for reworking the Atomic Host ISO,
see: https://pagure.io/fedora-lorax-templates/pull-request/6

Signed-off-by: Colin Walters <walters@verbum.org>
2016-11-17 10:17:39 -05:00
Lubomír Sedlář
deb8623bd1 pungi: Include noarch debuginfo
The check for arch compatibility should not be performed if the
debuginfo package is noarch. Such packages should be included
unconditionally.

Fixes: #450
Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2016-11-16 14:50:03 +01:00
Lubomír Sedlář
6203541ac6 media-split: Print sensible message for unlimited size
If the media is bootable, we can not split it. The limit is not used in
that case and we may overflow it with an warning message. The warning
should correctly mention what is going on instead of printing a
non-sensical message about free space on media being some huge number.

Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2016-11-16 14:49:46 +01:00
Lubomír Sedlář
b7813d34ac pungi: Fix incorrectly skipped tests
The test was not correctly being skipped in Koji build, causing build
failure.

Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2016-11-16 09:43:19 +01:00
Lubomír Sedlář
3c1e2fba66 pungi: Fix tests on non-x86_64 arches
If the test did not specify an arch explicitly, it fell back on whatever
arch the current machine has. This was causing failures when building
RPM.

Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2016-11-16 09:20:10 +01:00
Lubomír Sedlář
b85d7ae787 Include test data in tarball
The repodata for pungi tests should be shipped in the tarball.

Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2016-11-16 08:53:10 +01:00
Dennis Gilmore
13c1c4da69 4.1.11 release
Signed-off-by: Dennis Gilmore <dennis@ausil.us>
2016-11-15 15:12:02 -06:00
Dennis Gilmore
69d949aaf9 Merge #463 [ostree] Allow extra repos to get packages for composing OSTree repository 2016-11-15 21:06:05 +00:00
Dennis Gilmore
3953914bd1 Merge #461 extra-files: Nice error message on missing RPM 2016-11-15 21:01:42 +00:00
Dennis Gilmore
d4a78a1553 Merge #459 Fix building images and live media for addons 2016-11-15 21:00:50 +00:00
Dennis Gilmore
5dc8132fa4 Merge #456 Add tests for dependency solving 2016-11-15 20:58:40 +00:00
Qixiang Wan
68e121e421 [ostree] Allow extra repos to get packages for composing OSTree repository
Sometimes addtional repos are required to get necessary packages for
composing OSTree repository. For example, RHEL doesn't have an 'Everyting'
variant, so composing OSTree repository from any of the RHEL variants
won't work, addtional source repos need to be enabled to achieve that.
The new option "extra_source_repos" enable the ability of allowing extra
source repos.

And a new option 'keep_original_sources' is introduced to keep the
original repos found in tree config file, if this is enabled, Pungi
will not remove the existing source repos from the tree config file,
just add new repos of "source_repo_from" + "extra_source_repos" to
the existing repos.

Signed-off-by: Qixiang Wan <qwan@redhat.com>
2016-11-15 18:56:06 +08:00
Lubomír Sedlář
0cdef2d8e3 pungi: Run in-process for testing
Instead of spawning a separate process for each test, move the code to
run in the main process. This gives us correct coverage information and
makes the tests a lot faster.

The input is still provided in a kickstart file. The output also goes
into a log file that is later parsed.

There is some extra work needed with logging setup to make the logs go
to standard output so that nose can correctly capture them.

Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2016-11-10 13:28:02 +01:00
Lubomír Sedlář
ea1bcf625b pungi: Only add logger once
The Pungi object reuses the same logger for all its instances. Every
time a new instance is created, a stream handler would be added. This
means that a second instance will print everything twice. When running
tests, tens of instances would be created.

This patch only adds the handler if there are no handlers configured
yet.

Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2016-11-10 13:28:02 +01:00
Lubomír Sedlář
4a7257f550 pungi: Connect yum callback to logger
This patch changes the format a little and makes sure the output goes to
the same logger as the rest of the output. The output no longer contains
control characters.

Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2016-11-10 13:27:58 +01:00
Lubomír Sedlář
88dbf8f849 extra-files: Nice error message on missing RPM
When a file is exported from an RPM in the compose, and there is no
matching RPM in the package set, we want a nice error message.

Fixes: #460
Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2016-11-10 09:38:50 +01:00
Lubomír Sedlář
13871b64fb compose: Drop unused argument
The `get_variants()` method had a `recursive` argument with default
value of `False. However, this argument had no effect and the method
always returned all variants recursively.

We can just drop the argument. All callers are updated to not supply the
argument. Should any need for getting the top-level variants only arise,
they can be accessed as the `variants` attribute directly on the Compose
object.

Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2016-11-09 13:39:01 +01:00
Lubomír Sedlář
bd00920c62 compose: Search all nested variants
The code to search for install tree and repo for image-build and
live-media was only looking at top-level variants. Addons, optional or
integrated layered products could not have been found. This would lead
to error messages such as "There is no variant Server-optional to get
repo from when building live image for Client" even though the variant
exists.

Various tests are updated to exercise this edge case.

Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2016-11-09 13:18:34 +01:00
Lubomír Sedlář
99ba369901 ostree-installer: Capture all lorax logs
Fixes: #457
Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2016-11-09 09:37:00 +01:00
Lubomír Sedlář
9a72ea8f6d lorax-wrapper: Put all log files into compose logs
Tell lorax to use a specific directory for log files so that we preserve
them despite koji not having any idea about them.

Fixes: #457
Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2016-11-09 09:37:00 +01:00
Lubomír Sedlář
079cc46458 pungi: Fix reading multilib config files
When running from git, the files should be found relative to the python
module, not executable itself. This change makes it possible to load the
files when running tests.

Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2016-11-09 09:36:23 +01:00
Lubomír Sedlář
adaed6345c pungi: Fulltree should not apply for input multilib package
When the input explicitly lists a package as multilib, we should not
automatically add native version just because of fulltree.

The tests for this use case are now enabled and passing.

Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2016-11-09 09:36:23 +01:00
Lubomír Sedlář
8e5b197e3f pungi: Add tests for depsolving
These are tests written by Daniel Mach originally for Distill-NG. They
are ported to current Pungi. The test repositories are committed in the
tests/fixtures/ directory. This is the same data that is used for test
compose, but the actual RPM files are not present. Some tests are
adapted from dmach's fork of Pungi.

Some of the packages are marked with a comment saying they are
important. These are the packages that the test is specifically trying
to get included in the package set. There are also explicit tests for
packages that should not be included.

Two tests are skipped for now as there is a bug preventing them from
passing. This is related to fulltree being done for packages that are
explicitly multilib.

The depsolver is called by invoking a separate executable, so the
coverage data is wrong.

Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2016-11-09 09:36:23 +01:00
Lubomír Sedlář
4427769f6a Update ostree phase documentation
The message and the new option were not documented.

Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2016-11-04 09:35:08 +01:00
Qixiang Wan
fa3c5aff63 [ostree] Allow adding versioning metadata
Added new option '--version' to pungi-make-ostree, and this can be
enabled in ostree settings with 'version'. The version string will be
added as versioning metadata if this is specified.

Signed-off-by: Qixiang Wan <qwan@redhat.com>
2016-11-04 16:07:26 +08:00
Lubomír Sedlář
133b6a5cf5 Merge #453 [ostree] New option to enable generating ostree summary file 2016-11-04 07:08:09 +00:00
Qixiang Wan
06ba3b8551 [ostree] New option to enable generating ostree summary file
Added new option '--update-summary' to pungi-make-ostree, and this can
be enabled in ostree settings with 'update_summary'. A summary file will
be generated (or re-generated if it was presented in an existing ostree
repo) when it is enabled.

Signed-off-by: Qixiang Wan <qwan@redhat.com>
2016-11-03 21:02:05 +08:00
Lubomír Sedlář
a3a415e398 pungi: Avoid removing from list
Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2016-10-26 12:51:02 +02:00
Daniel Mach
48bd3e6d2d pungi: Allow globs in %multilib-whitelist
Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2016-10-26 12:51:02 +02:00
Daniel Mach
2cd2e0e15f pungi: Exclude RPMs that are in lookaside
Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2016-10-26 12:51:02 +02:00
Daniel Mach
3e7f2dfa9d pungi: Fix excluding SRPMs
Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2016-10-26 12:51:02 +02:00
Daniel Mach
e6342ede18 pungi: Speed up blacklist processing
Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2016-10-26 12:51:02 +02:00
Patrick Uiterwijk
a49510a9fb Update tests to use ostree write-commit-id
Signed-off-by: Patrick Uiterwijk <puiterwijk@redhat.com>
2016-10-26 09:52:12 +00:00
Patrick Uiterwijk
754458823c ostree: Use the write-commitid-to feature rather than parsing ostree logs
This depends on an rpm-ostree release with
98332a3be4

Signed-off-by: Patrick Uiterwijk <puiterwijk@redhat.com>
2016-10-26 09:52:12 +00:00
Lubomír Sedlář
c5bd99da9e Merge #448 Remove executable permissions on test scripts 2016-10-26 07:31:37 +00:00
Lubomír Sedlář
bfd5a39ce6 checks: Check for createrepo_c
The createrepo package is needed always, but depending on configuration
we should also look for createrepo_c.

Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2016-10-25 16:00:37 +02:00
Lubomír Sedlář
f4cd25450b checks: Update tests to not require python modules
This way the tests are more independent of the system they are running
on.

Merges: #447
Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2016-10-25 15:57:02 +02:00
Patrick Uiterwijk
59dbd9d35f Remove executable permissions on test scripts
Signed-off-by: Patrick Uiterwijk <puiterwijk@redhat.com>
2016-10-25 10:42:16 +00:00
Patrick Uiterwijk
933c2608cd Add more require checks
Signed-off-by: Patrick Uiterwijk <puiterwijk@redhat.com>
2016-10-25 10:37:55 +00:00
Patrick Uiterwijk
51a8f7a7fe Fix package name for createrepo and mergerepo
These binaries are in the createrepo package, not yum-utils.

Signed-off-by: Patrick Uiterwijk <puiterwijk@redhat.com>
2016-10-25 10:29:06 +00:00
Qixiang Wan
d067928a4e not using 'git -C path' which is not supported by git 1.x
'-C path' is new in git 2.x and RHEL 6 has git 1.8 by default

Signed-off-by: Qixiang Wan <qwan@redhat.com>
2016-10-25 15:53:56 +08:00
Qixiang Wan
1345eb87a4 pungi-koji: add option for not creating latest symbol link
Fixes: #53
Signed-off-by: Qixiang Wan <qwan@redhat.com>
2016-10-25 12:45:19 +08:00
Lubomír Sedlář
e02ed6c04b Merge #434 Replace mount/umount cmds with libguestfs tools 2016-10-24 07:52:29 +00:00
Dennis Gilmore
18128623b4 Merge #443 config: Don't abort on deprecated options 2016-10-20 20:26:17 +00:00
Dennis Gilmore
8f974ea109 Merge #442 metadata: Treeinfo should point to packages and repo 2016-10-20 20:25:17 +00:00
Qixiang Wan
a5273dc798 Replace mount/umount with guestfsmount and 'fusermount -u'
'mount -o loop' requires root privileges, guestmount from
libguestfs-tools-c package can work without root privileges.

Fixes: #19
Signed-off-by: Qixiang Wan <qwan@redhat.com>
2016-10-20 19:38:35 +08:00
Lubomír Sedlář
c38bb4809b config: Don't abort on deprecated options
These options are in fact removed and have no effect anymore. This patch
changes the validation to print a warning that the option was removed
and what should be done instead. It no longer stops the whole compose.

The validation script still rejects configuration files with these
removed keys.

This change means we no longer check these removals with the JSON schema
(as that makes it hard to determine where exactly the problem is).

Fixes: #438
Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2016-10-20 12:51:12 +02:00
Lubomír Sedlář
1bb1c2ba28 metadata: Treeinfo should point to packages and repo
Each variant section should contain a path to a directory with packages
and to repodata. There was code to do this, but due to a typo it did not
actually work.

Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2016-10-20 12:05:48 +02:00
Lubomír Sedlář
74aa41f8bd Send notification when compose fails to start
This is tricky as this early in the process we don't know the compose
ID. The new message gives the full command line that was called.

Relates: #439
Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2016-10-20 09:39:18 +02:00
Lubomír Sedlář
6e55cc6419 metadata: Stop crashing for non-bootable products
Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2016-10-20 09:25:39 +02:00
Dennis Gilmore
a7dc4e80a7 Merge #433 createiso: Do not split bootable media 2016-10-19 16:37:25 +00:00
Dennis Gilmore
2f184f9b23 Merge #432 metadata: Correctly clone buildinstall .treeinfo 2016-10-19 16:36:45 +00:00
Lubomír Sedlář
84fcc0083f createiso: Do not split bootable media
If the media is bootable, we can not split it. Instead we will create an
ISO that is too big and issue a warning (aborting the whole compose
would be too much).

Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2016-10-19 18:36:19 +02:00
Dennis Gilmore
ff6c952094 Merge #430 createiso: Include layered product name in iso name 2016-10-19 16:36:07 +00:00
Dennis Gilmore
8194dd0cf0 Merge #428 buildinstall: Only transform arch for lorax 2016-10-19 16:35:03 +00:00
Dennis Gilmore
34d3be35dc Merge #426 iso-wrapper: Remove the class 2016-10-19 16:34:25 +00:00
Dennis Gilmore
bb933c83ae Merge #425 config: Validate variant regular expressions 2016-10-19 16:32:39 +00:00
Lubomír Sedlář
fd08efaa03 doc: Fix a typo in progress notification example
Fixes: #435
Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2016-10-19 15:04:21 +02:00
Lubomír Sedlář
b5e4ea848a Dump images.json after checksumming
Once we have the checksums, nothing else will change in the metadata. We
should make sure it is on disk as soon as possible.

Fixes: #436
Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2016-10-19 15:02:33 +02:00
Lubomír Sedlář
1f4f6ceb08 metadata: Correctly clone buildinstall .treeinfo
Lorax/buildinstall produce .treeinfo file that is cloned into the
compose dir. However since lorax runs separately for each arch, the
files are nested in a subdirectory. With old buildinstall method, this
causes the file to not be found and copied.

Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2016-10-18 09:01:30 +02:00
Lubomír Sedlář
b46af7acbb createiso: Include layered product name in iso name
When creating an ISO for a layered product, the name of the integrated
product should be included in the file name.

Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2016-10-17 15:15:50 +02:00
Lubomír Sedlář
02ddcf7387 buildinstall: Only transform arch for lorax
The older buildinstall method fails if it sees ppc64p7 instead of ppc64.
Nothing changes for composes using Lorax.

Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2016-10-17 13:20:57 +02:00
Lubomír Sedlář
e58c78fd2f iso-wrapper: Remove the class
It really is just a group of independent functions, so we can simplify
it by removing the unused wrapper class. Instead of importing the
wrapper, instantiating it and calling its methods we can import the
module and call its functions directly.

Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2016-10-14 09:14:51 +02:00
Lubomír Sedlář
50e9294057 config: Validate variant regular expressions
When the mapping in configuration specifies incorrect regular expression
to match regular expressions, we should raise an error immediately and
not wait until the part of config is actually used.

This patch does not cover `live_media`, `image_build` and `osbs`
sections, as they use plain dicts and not the list of tuples format.

Fixes: #424
Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2016-10-12 09:38:59 +02:00
Dennis Gilmore
b2b5dd919b 4.1.10 release
Signed-off-by: Dennis Gilmore <dennis@ausil.us>
2016-10-08 12:15:32 -05:00
Mark Montague
4be3c72bd5 pungi: Replace kickstart repo url
Old Pungi should replace yum baseurl/mirrorlist when doing buildinstall.

Fixes: https://bugzilla.redhat.com/show_bug.cgi?id=1264570
Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2016-10-07 07:56:06 +02:00
Lubomír Sedlář
730764e2e7 ostree-installer: Reduce duplication in tests
The assertions were duplicated across multiple test cases. This patch
moves them into shared methods so that they are defined only once.

Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2016-10-06 09:42:31 +02:00
Lubomír Sedlář
32059c57c0 ostree-installer: Generate correct volume ID
The volume ID should be generated in Pungi with the same format as for
other images.

Fixes: #419
Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2016-10-06 09:17:09 +02:00
Lubomír Sedlář
cc559b12f4 ostree-installer: Use ostree as type in filename
Instead of overloading the `dvd` value, use new value `ostree` that can
be overridden by a config change.

Fixes: https://pagure.io/pungi/issue/418
Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2016-10-06 08:41:14 +02:00
Lubomír Sedlář
8880b1ea8a ostree: Use $basearch in repo file
Fixes: #413
Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2016-10-05 18:41:55 +02:00
Lubomír Sedlář
446f21d4d7 config: Accept empty branch in SCM dict
If user sets `branch` to `None`, it should behave as if the branch is
not set at all. Nagging them about removing it is not helping anything.

Fixes: #415
Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2016-10-03 19:37:56 +02:00
Lubomír Sedlář
ac635a0937 Remove duplicated version from pungi script
We can get the version using same logic as we do for pungi-koji. This
means one less place to bump the version during release.

Fixes: https://pagure.io/pungi/issue/406
Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2016-09-29 11:23:30 +02:00
Dennis Gilmore
4e90f81fc1 use --new-chroot when making ostree's
to complement https://pagure.io/koji/pull-request/162 we need to adjust pungi
rpm-ostree uses bublewrap that does not work in mock. --new-chroot to mock
enables the use of systemd-nspawn instead of chroot resulting in working
rpm-ostree again

Signed-off-by: Dennis Gilmore <dennis@ausil.us>
2016-09-28 20:58:17 -05:00
Dennis Gilmore
c0474b6cca Merge #404 Remove FSF address from file headers 2016-09-27 13:33:43 +00:00
Dennis Gilmore
c34817989c Merge #409 Translate paths without double slash 2016-09-27 13:31:44 +00:00
Lubomír Sedlář
d898f00d33 Create git tags without release
For upstream releases we should not need that level of granularity,
major.minor.patch version should be enough. This change will make the
tags simpler for consumers especially by removing the dist tag that adds
no value whatsoever.

Fixes: #407
Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2016-09-27 09:01:13 +02:00
Lubomír Sedlář
7bf12636a0 Translate paths without double slash
If the path in `translate_paths` config ends with a slash, we would
create public path with double slash.

Fixes: https://pagure.io/pungi/issue/408
Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2016-09-26 15:50:49 +02:00
Lubomír Sedlář
c5f878330c Remove shebangs from non-executable files
Some modules can be executed as a sort-of test. However, the files do
not have executable bit set, so there is no need for them to have
shebangs. If someone wants to call them directly, they should do so via
python.

Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2016-09-23 10:26:43 +02:00
Lubomír Sedlář
d6dc269ef4 Remove FSF address from comments
The address is no longer correct. We can just as well simply point to
the web page describing the license.

Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2016-09-23 10:26:43 +02:00
Lubomír Sedlář
160df7f89a Update contributing guide
The instructions for setting up virtualenv were out dated.

Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2016-09-23 10:19:34 +02:00
Lubomír Sedlář
a042906717 init: Remove keep_original_comps option
The same information can be inferred from definitions in variants.xml:
if the variant has no groups defined, we include packages from all
groups. By the same logic we can also include all groups in the comps
file.

The config validation is updated to give a hint on how to remove the
option from the configuration.

Relates: #29
Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2016-09-22 13:35:28 +02:00
Lubomír Sedlář
c118adc705 tests: Use unittest2 consistently
Without importing this module, the tests are going to fail on Python
2.6.

Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2016-09-22 10:28:01 +02:00
Lubomír Sedlář
9a3b0f089e 4.1.9 release
Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2016-09-21 14:07:21 +02:00
Lubomír Sedlář
2ac45a783d ostree_installer: Add --isfinal lorax argument
If the compose is supported, we need to tell lorax to use the option.

Fixes: #399
Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2016-09-21 13:49:35 +02:00
Lubomír Sedlář
bfe1068b8e Recreate JSON dump of configuration
We need both full dump and the copy of original file. Having just the
copy is not sufficient because while it preserves comments and
formatting, there can be include statements for other files and those
are not copied.

With this patch we create the dump in the same way as before, and
additionally create a copy of of the config file specified on command
line.

Fixes: #398
Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2016-09-21 08:31:43 +02:00
Dennis Gilmore
3a68a93532 Merge #385 Test and clean up pungi.linker 2016-09-19 21:27:57 +00:00
Dennis Gilmore
8d1b4dea17 Merge #390 checksums: Never skip checksumming phase 2016-09-19 21:27:10 +00:00
Lubomír Sedlář
6fede3f395 variants: Allow multiple explicit optional variants
When a variant has optional, it is possible to explictly list it in the
XML file and add extra groups. However, the original DTD did not allow
multiple variants with `id="optional"` as `id` attribute has to be
globally unique. This patch changes its type to `CDATA`, which has less
restrictions. This also means we can no longer define `<ref>` as
`IDREF` and instead check the existence of referenced variant in parser.

Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2016-09-19 12:21:19 +02:00
Lubomír Sedlář
f97e9258aa checksums: Never skip checksumming phase
It does not make sense for this phase to be skipped. If there are any
images, we need to generate the checksums so that writing metadata
works. If there are no images, the phase does not do anything and is
therefore very fast.

Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2016-09-19 12:20:34 +02:00
Lubomír Sedlář
bdf968ff3f [linker] Remove dead code
There are big parts of code that can not be reached. Other parts expose
options that are not used anywhere. To keep things simple, all of that
is removed in this patch.

Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2016-09-19 12:19:43 +02:00
Lubomír Sedlář
444c3a21ca [linker] Add tests
These tests are adapted from internal ones.

Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2016-09-19 12:19:43 +02:00
Chenxiong Qi
912f81ca16 Dump original pungi conf
Fix #383

Signed-off-by: Chenxiong Qi <cqi@redhat.com>
2016-09-19 17:31:43 +08:00
Lubomír Sedlář
23e00fd87d ostree: Add tests for sending ostree messages
Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2016-09-15 14:40:46 +02:00
Patrick Uiterwijk
2c401a4a5c Send fedmsg message on ostree compose finishg
This sends a message when we finish composing an ostree.

Signed-off-by: Patrick Uiterwijk <puiterwijk@redhat.com>
2016-09-15 11:16:18 +00:00
Lubomír Sedlář
bf46048cbf createrepo: Add option to use xz compression
This patch adds a new config option createrepo_use_xz, which when set to
true will cause createrepo to compress sqlite databases with xz. The
default setting is False.

Fixes: #387
Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2016-09-12 11:10:43 +02:00
Pat Riehecky
10b93796bd Allow user to set a ~/.pungirc for some defaults
Merges: #64
Signed-off-by: Pat Riehecky <riehecky@fnal.gov>
2016-09-08 15:47:50 +02:00
Lubomír Sedlář
1a16d94dda metadata: Improve error reporting on failed checksum
Instead of using the _doChecksum function, it now uses a function from
kobo which has nicer API. If there is an error, the message now includes
more details.

Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2016-09-07 13:05:11 +02:00
Jeremy Cline
ee1ee0467b extra-files: Write a metadata file enumerating extra files
Introduces a new metadata file to track arbitrary files added during the
extra-files phase. This file is placed in the root of each tree and is
called ``extra_files.json``. It is a JSON file containing a single
object, which contains a "header" key with an object describing the
metadata, and a "data" key, which is an array of objects, where each
object represents a file. Each object contains the "file", "checksums",
and "size" keys. "file" is the relative path from the tree root to the
extra file. "checksums" is an object containing one or more checksums,
where the key is the digest type and the value of that key is the hex
digest. Finally, the size is the size of the file in bytes.

For example:
{
  "header": {"version": "1.0},
  "data": [
    {
      "file": "GPL",
      "checksums": {
        "sha256": "8177f97513213526df2cf6184d8ff986c675afb514d4e68a404010521b880643"
      },
      "size": 18092
    },
    {
      "file": "release-notes/notes.html",
      "checksums": {
        "sha256": "82b1ba8db522aadf101dca6404235fba179e559b95ea24ff39ee1e5d9a53bdcb"
      },
      "size": 1120
    }
  ]
}

Signed-off-by: Jeremy Cline <jeremy@jcline.org>
Fixes: #295
2016-09-07 13:02:48 +02:00
Dennis Gilmore
6aeab9ee9d Merge #381 Automatically generate missing image version 2016-09-06 15:19:55 +00:00
Lubomír Sedlář
223a015898 Automatically generate missing image version
If the configuration does not specify version for images or live media,
Pungi will create a default value based on `release_version`. If label
is used for the compose, the milestone from it will be appended to the
version (unless it's RC).

This change is backwards compatible: nothing changes when version is set
in configuration. If the version was missing before, building the
artifacts would fail. With this patch, default values will be supplied.

Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2016-09-01 15:13:04 +02:00
Lubomír Sedlář
f9a6c8418f Add JSON Schema for configuration
The schema is written in Python to reduce duplication. When
configuration is loaded, the validation checks if it's correct and fills
in default values.

There is a custom extension to the schema to report deprecated options.

The config dependencies are implemented as a separate pass. While it's
technically possible to express the dependencies in the schema itself,
the error messages are not very helpful and it makes the schema much
harder to read.

Phases no longer define `config_options`. New options should be added to
the schema. Since the default values are populated automatically during
validation, there is no need to duplicate them into the code.

The `pungi-config-validate` script is updated to use the schema and
report errors even for deeply nested fields.

The dependencies are updated: pungi now depends on `python-jsonschema`
(which is already available in Fedora).

Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2016-09-01 10:56:15 +02:00
Lubomír Sedlář
5534fda192 Allow arbitrary arguments in make test
This can be helpful to enable additional nose plugin.

Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2016-09-01 10:49:36 +02:00
Lubomír Sedlář
1881bf740d createiso: Report nice error when tag does not exist
Instead of failing with generic `AttributeError`, we can easily report
the actual problem.

Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2016-09-01 09:09:31 +02:00
Lubomír Sedlář
a31be0a3c4 Fix test data build script
It uses bash specific features, so it should not claim /bin/sh in
shebang. We also want to use `set -e` to catch possible errors instead
of claiming success every time.

Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2016-09-01 08:46:23 +02:00
Lubomír Sedlář
f43b8736b7 [osbs] Add NVRA of created image into main log
Currently the main log only says the phase started and finished. With
this patch each created image will be mentioned by its name, version,
release and arch.

Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2016-08-30 10:37:17 +02:00
Lubomír Sedlář
d3b9ae79a5 [createiso] Remove unused script
The pungi-createiso script should have been removed in f37a14fb, but was
forgotten. The script is obsoleted by a new method in which ISOs are
created. It's now broken as it calls methods that no longer exist.

Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2016-08-30 10:28:18 +02:00
Lubomír Sedlář
f507b14954 Update doc about generating release value
It is taken from compose label if provided, and only then falls back to
date, type and respin.

Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2016-08-26 10:05:25 +02:00
Lubomír Sedlář
43fda1e9ef Use label to populate image release
When release for an image is specified as explicit `None`, we can
generate the value based on compose label. For example for `Alpha-1.2`
the release would be `1.2` instead of the date based one.

Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2016-08-25 15:24:36 +02:00
Lubomír Sedlář
d90dba9312 doc: Fix example for image_build
The example configuration can now be copy-pasted into real configuration
file and will parse without any issues.

Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2016-08-25 14:21:03 +02:00
Lubomír Sedlář
7fd5403495 Ignore module imports not at top of file
In multiple places we need to set up import paths before importing
modules. This Flake8 warning is just noise.

Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2016-08-22 10:55:48 +02:00
Dennis Gilmore
76f3f909ec Merge #367 Remove unused imports 2016-08-18 13:16:53 +00:00
Lubomír Sedlář
b862fc5a50 [buildinstall] Fix cleaning output dir
Before the task is started, the output directory is checked and if it
exists and is not empty, the runroot task will be skipped. This is meant
for debugging when restarting the same compose. Under usual
circumstances, the directory will not be created in the first place.

The runroot task will start by removing the output directory. This way,
if koji restarts the task, lorax will not fail.

Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2016-08-18 09:11:30 +02:00
Lubomír Sedlář
f0f236ac5e Remove unused imports
After duplicated functions were removed, some imports were left behind.

Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2016-08-17 08:20:01 +02:00
Dennis Gilmore
1238aaa2e6 Merge #360 [osbs] Convert build_id to int 2016-08-16 20:54:10 +00:00
Dennis Gilmore
cd747ac065 Merge #361 Fix config validation script 2016-08-16 20:53:50 +00:00
Dennis Gilmore
492cdec719 Merge #365 Make image test at end of compose less strict 2016-08-16 20:53:23 +00:00
Lubomír Sedlář
91b2f6e941 [test] Make image test at end of compose less strict
Originally, the idea was to remove non-blocking images that failed the
check. They were only removed from the manifest, which creates some
confusion as to what is going on. With this patch, a failed check on
non-blocking deliverable will only print an error message.

Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2016-08-16 10:18:12 +02:00
Lubomír Sedlář
b4765459f3 [iso] Fix check on failable ISO
When ISO is marked as failable and check fails, the compose would still
be aborted. This patch fixes that

Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2016-08-16 10:10:16 +02:00
Lubomír Sedlář
a72a38b278 Add full Pungi version to log output
This should help with debugging by providing better information on which
Pungi version created the compose. In development, the version will show
output of git describe, in production it asks which version is installed
in site-packages/. The egg-info directory must be installed for this to
work.

It is no longer necessary to synchronize version in `setup.py` with
`pungi/__init__.py`.

Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2016-08-16 08:12:40 +02:00
Lubomír Sedlář
3de6d094be Fix config validation script
It got broken in commit 8323a735 which added a requirement for a compose
to have valid paths. This patch adds that with somewhat dummy values.

Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2016-08-12 14:08:11 +02:00
Lubomír Sedlář
c05282be44 [osbs] Convert build_id to int
The getBuild API call expects either an integer or string NVR, otherwise
it will crash.

Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2016-08-12 14:07:58 +02:00
Lubomír Sedlář
1a4e1b211c [image-build] Get failable config from correct place
The key should be nested in `image-build` block.

Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2016-08-11 14:41:04 +02:00
Dennis Gilmore
fc23ca5fdf 4.1.8 release
Signed-off-by: Dennis Gilmore <dennis@ausil.us>
2016-08-10 07:21:40 -05:00
Lubomír Sedlář
f37a14fb60 [createiso] Use shell script for runroot
Instead of installing pungi itself in the runroot, we can prepare the
commands to be run on compose box, write the shell script into work/
directory, which is mounted in the chroot, and execute that. This way
there is no business logic in runroot (except for finding lorax
templates).

The main advantage of this approach is that we don't need to pull any
extra dependencies into buildroot.

Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2016-08-10 13:39:50 +02:00
Dennis Gilmore
6a682f64fe Merge #357 Improve error messages for gathering packages 2016-08-10 11:36:18 +00:00
Lubomír Sedlář
ef99e28849 [test] Only check bootability for images on x86_64 and i386
Current check does not really work for other arches.

Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2016-08-10 13:02:56 +02:00
Lubomír Sedlář
761a0ef40e Improve error messages for gathering packages
When package has incompatible arch for a tree, the same error message
could be raised from two different places. This patch adds more
information to the message, so that it is easier to find the actual
problem.

Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2016-08-10 09:32:39 +02:00
Dennis Gilmore
247149d4e1 Merge #339 Refactor failables, step 1 2016-08-03 07:36:34 +00:00
Lubomír Sedlář
463088d580 Refactor failables
This is a breaking change as big part of current failable_deliverables
options will be ignored.

There is no change for buildinstall and creatiso phase.

Failability for artifacts in other phases is now configured per
artifact. It already works correctly for ostree and ostree_installer
phases (even per-arch). For OSBS phase there is currently only a binary
switch as it does not handle multiple arches yet. When it gains that
support, the option should contain list of non-blocking architectures.

For live images, live media and image build phases each config block can
configure list of failable arches. If the list is not empty, it can
fail. Once we have a way to fail only some arches, the config will not
need to change.

Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2016-07-27 13:06:01 +02:00
Lubomír Sedlář
7d0ee41f23 Stop setting release in OSBS phase
Atomic Reactor does not honor this option. In the future we might need
to reintroduce this feature, but given that it does not work in the
current form it is better removed.

Fixes: #348
Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2016-07-27 09:52:06 +02:00
Dennis Gilmore
664c5e54a3 Merge #351 Remove ambiguous imports 2016-07-26 13:54:44 +00:00
Lubomír Sedlář
22e94caf3c [test] Correctly check bootable ISOs
ISO image without MBR and GPT can still be bootable if it has an El
Torito boot catalog. The test phase must accept such images.

This slightly defeats the point of the check: to verify the ISO is
hybrid. However, based on the metadata we have no way to actually tell
if the image is supposed to be hybrid.

Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2016-07-22 14:11:06 +02:00
Lubomír Sedlář
d51550da84 Remove ambiguous imports
Make all imports either use full package name starting with `pungi` or
use explicitly relative import. This will avoid issues when importing a
module that shadows another module on PYTHONPATH.

Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2016-07-20 13:36:42 +02:00
Lubomír Sedlář
f0dca7687e Merge #347 Remove duplicate definition of find_old_composes. 2016-07-20 08:43:47 +00:00
Dennis Gilmore
9861e80c80 Merge #342 Simplify naming format placeholders 2016-07-01 00:04:17 +00:00
Dennis Gilmore
5ae58b6d46 Merge #345 createrepo: use separate logs for different pkg_type 2016-07-01 00:03:46 +00:00
Ralph Bean
ad44ef4695 Remove duplicate definition of find_old_composes...
This lives now in pungi.util.  It was copied there long ago and all the
places that reference it reference it in that location.

I think this code in pungi.phases.pkgset is unused and can be removed.

The other function moved to the common module.

Signed-off-by: Ralph Bean <rbean@redhat.com>
2016-06-30 16:43:34 -04:00
Qixiang Wan
c32080e7f9 [createrepo] fix 'createrepo_deltas' option
'createrepo_deltas = False' in configuration doesn't work

Signed-off-by: Qixiang Wan <qwan@redhat.com>
2016-06-30 18:44:25 +08:00
Lubomír Sedlář
a1b86b93ea createrepo: use separate logs for different pkg_type
Instead of overwriting the same log file, make sure we keep all the logs
for debuginfo, source and binary packages.

Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2016-06-29 07:46:33 +02:00
Lubomír Sedlář
a72182c817 Simplify naming format placeholders
This patch makes it possible to use different style format placeholders.
Instead of the percent encoding it is now possible to use simple curly
braces.

    %(foo)s -> {foo}

The old format is still available.

Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2016-06-28 13:03:36 +02:00
Lubomír Sedlář
11bbbae2ed Treat variants without comps groups as having all of them
If the `<groups></groups>` section is not specified in the variants XML
file, all groups will be used in this variant. The section must be
omitted completely, not just empty. This is (and was) correct according
to the DTD, it just lead to crash before.

Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2016-06-28 09:01:30 +02:00
Lubomír Sedlář
8323a735e7 Always generate rpms.json file
Even if gather phase is skipped, it will still generate a rpms.json
metadata file. It will have no payload, but the header structure is
there.

Createrepo phase had to be updated to ignore variants that have no RPMs
listed in metadata.

There is one more fix for writing treeinfo files: if repomd.xml files
are not generated, it will no longer crash.

Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2016-06-27 08:50:19 +02:00
Dennis Gilmore
00e11b2f51 4.1.7 release
Signed-off-by: Dennis Gilmore <dennis@ausil.us>
2016-06-23 05:14:21 -05:00
Lubomír Sedlář
e1ab519542 [scm] Add logging for exporting local files
This will avoid confusion when the file can not be found, but previous
export from remote location worked well. In such case the log said:

    Exporting from SCM...
    Boom, no files found...

This commit changes it into:

    Exporting from SCM...
    Exporting file from current working dir...
    Boom, no files found...

Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2016-06-23 08:07:23 +02:00
Lubomír Sedlář
8e4b1e278c [extra-files] Only copy files when there is a config
Instead of running the copy function for all variant.arch pairs
unconditionally, only do it if there is something to do. This makes the
log more understandable.

Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2016-06-23 07:25:52 +02:00
Lubomír Sedlář
170cd8f72d [extra-files] Refactoring
* remove duplicated function arguments
 * move logic into smaller and well documented functions

Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2016-06-23 07:25:52 +02:00
Lubomír Sedlář
74001d5aa5 [extra-files] Skip whole phase if not configured
This checks the configuration in one place rather than doing it for each
variant/arch combination.

Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2016-06-23 07:25:52 +02:00
Lubomír Sedlář
b67f6369db [extra-files] Copy files using existing function
Instead of calling cp as a system command. This will help debug problems
if something fails.

Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2016-06-23 07:25:52 +02:00
Lubomír Sedlář
d3b2fbe387 [extra-files] Add tests
Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2016-06-23 07:25:52 +02:00
Lubomír Sedlář
b4fc97be03 [osbs] Add a phase to build images in OSBS
It will take RPM repo from a variant in this compose and a Dockerfile
from configured git and use it to build an image.

The build images are uploaded to some a Docker registry by OSBS and are
not directly part of compose (because there is no export function).
There is a new metadata file `osbs.json` that has some information that
can be used to find the image.

Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2016-06-22 10:02:03 +02:00
Lubomír Sedlář
95cfbfb3fe Setup global log file before logging anything
This should fix the issue with only printing information about automatic
toggling of `supported` flag to standard output and not to a file.

Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2016-06-14 08:48:36 +02:00
Lubomír Sedlář
658ef90458 [metadata] Correctly save final flag
Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2016-06-13 19:01:38 +02:00
Dennis Gilmore
11d5ca8342 Merge #326 add missing dependencies 2016-06-08 07:57:39 +00:00
Lubomír Sedlář
9429c40b13 [createiso] Add test for adding source iso to metadata
Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2016-06-06 16:04:54 +02:00
Dennis Gilmore
6800501217 Merge #325 Fix checking optional ISO images in test phase 2016-06-06 11:56:51 +00:00
Dennis Gilmore
469c275670 Merge #321 Add support for top-level variant IDs with dashes. 2016-06-06 11:56:27 +00:00
Dennis Gilmore
5b5f9b7460 Merge #320 images.json: Move src images under binary arches. 2016-06-06 11:56:11 +00:00
Nils Philippsen
698805f62b add missing dependencies
... which are available from pypi.python.org

Signed-off-by: Nils Philippsen <nils@redhat.com>
2016-06-06 11:39:53 +02:00
Lubomír Sedlář
b2a266c3e4 Fix checking optional ISO images in test phase
Instead of iterating over image manifest, loop through all variants and
arches and see if there are any images. This avoids a crash for variants
nested under other variants (layered products, optionals or addons).

Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2016-06-06 10:41:06 +02:00
Nils Philippsen
53f93b27c2 add lxml dependency
Signed-off-by: Nils Philippsen <nils@redhat.com>
2016-06-03 14:28:35 +02:00
Daniel Mach
f78709aaf9 images.json: Move src images under binary arches.
Signed-off-by: Daniel Mach <dmach@redhat.com>
2016-06-02 10:17:06 -04:00
Daniel Mach
f0aecf6744 Add support for top-level variant IDs with dashes.
This is for layered products that have a variant mapped
to multiple variants in a base product, for example:
 * Foo-Tools (id: FooTools, uid: Foo-Tools, name: Tools)
 * Bar-Tools (id: BarTools, uid: Bar-Tools, name: Tools)

Requires productmd >= 1.2.

Signed-off-by: Daniel Mach <dmach@redhat.com>
2016-06-02 10:16:16 -04:00
Daniel Mach
4582e635f6 Fix PYTHONPATH usage in test_compose.sh.
Signed-off-by: Daniel Mach <dmach@redhat.com>
2016-06-02 10:16:02 -04:00
Lubomír Sedlář
b62b468ccf [createiso] Enable customizing media reserve
Add a documented and tested config options for setting ISO parameters
instead of hardcoding magic values.

Fixes: #256
Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2016-06-02 08:34:49 +02:00
Lubomír Sedlář
a8d7f8a63e [createiso] Add test for splitting media
This patch also fixes a bug where packages in hashed directories would
not be recognized as such and would not be placed after other files.

Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2016-06-02 08:34:49 +02:00
Lubomír Sedlář
7655756a4f [media-split] Remove commented-out code
Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2016-06-01 14:11:56 +02:00
Lubomír Sedlář
e5454a23eb [media-split] Simplify code
Some parts can be written in a more straight-forward way. This also
fixes the issue with not raising error on adding to big file.

Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2016-06-01 14:06:25 +02:00
Lubomír Sedlář
79035ea7e6 [media-split] Add code documentation
Add a docstring to MediaSplitter class explaining what it does and how
to use it.

Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2016-06-01 14:05:49 +02:00
Lubomír Sedlář
97f9cc9abc [media-split] Add unit tests
The tests do not pass with current code - an error on too big file is
not raised.

Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2016-06-01 14:03:23 +02:00
Lubomír Sedlář
5cc7dc204f Add missing documentation
There a couple config options that are not even mentioned in the
documentation. This patch adds them with a basic introduction of what
they do.

Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2016-05-31 13:34:04 +02:00
Lubomír Sedlář
961648819f [buildinstall] Fix bad error message
Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2016-05-27 12:18:16 +02:00
Dennis Gilmore
264c7b1ddf Merge #309 Add compatibility for Python 2.6 2016-05-27 01:23:34 +00:00
Dennis Gilmore
0e0e333982 Merge #293 Add tests for generating discinfo and media.repo files 2016-05-27 01:23:22 +00:00
Dennis Gilmore
e2ee4b0cc1 Merge #287 Use koji profiles to list RPMs in buildroot 2016-05-27 01:23:03 +00:00
Lubomír Sedlář
022a4d36f5 [ostree-installer] Put images to os/ directory
Instead of putting everything to <variant>/<arch>/iso, move images/,
EFI/ and isolinux/ subdirs to <variant>/<arch>/os. The nicely named ISO
image is still in the original location.

Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2016-05-26 09:58:56 +02:00
Lubomír Sedlář
5698a9727e [ostree] Rename duplicated test
Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2016-05-26 09:55:48 +02:00
Lubomír Sedlář
9eb85c481c [util] Use koji profile for getting RPMs from buildroot
Instead of having a separate config option, just use the koji profile.
According to release notes, this should have already been done.

Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2016-05-26 09:50:57 +02:00
Lubomír Sedlář
75d71ebbe1 [util] Add test for getting list of buildroot RPMs
Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2016-05-26 09:50:57 +02:00
Dennis Gilmore
d13f655300 pungi-koji: fix up latest symlink creation
If release_version does not have a . in it the current logic gives us
and empty result. in those cases, such as 23 or Rawhide use the value
of release_version as is.

Signed-off-by: Dennis Gilmore <dennis@ausil.us>
2016-05-26 09:46:44 +02:00
Lubomír Sedlář
d5512fd6ff Use unittest2 if available
The module backports features to Python 2.6 and 2.7. If it is available,
the tests will use it. If it is not available, it will fall back to
regular unittest. On Python 2.7, the tests pass anyway. On Python 2.6,
there are failures with Python 2.6.

Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2016-05-25 13:41:49 +02:00
Lubomír Sedlář
b634a18a7f Stop using str.format
On Python 2.6, it requires the format placeholder to have explicit index
of argument, so using % formatting is easier.

There are a couple places where the method is still used because the
same argument is used twice.

Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2016-05-25 13:41:49 +02:00
Lubomír Sedlář
b55f8abd29 Stop using functools.total_ordering
It is only available since 2.7, and only saves us from defining three
trivial methods.

Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2016-05-25 13:28:56 +02:00
Lubomír Sedlář
9ab9aaf8d9 The message attribute on exception is deprecated
One should rather use str(exception) to get the text message.

Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2016-05-25 13:28:56 +02:00
Lubomír Sedlář
6e10d8c713 [ostree] Rename duplicated test
Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2016-05-25 12:30:17 +02:00
Dennis Gilmore
8de7d685d9 4.1.6 release
Signed-off-by: Dennis Gilmore <dennis@ausil.us>
2016-05-24 16:36:07 -05:00
Lubomír Sedlář
c8341e1806 [ostree-installer] Allow using external repos as source
Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2016-05-24 10:06:06 +02:00
Lubomír Sedlář
17bb3d2122 [metadata] Simplify writing media.repo
This commit also removes the ability to generate timestamp. It must now
always be passed explicitly. The feature was not used anywhere and it
actually did not work.

Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2016-05-23 18:34:04 +02:00
Lubomír Sedlář
5d849cd050 [metadata] Add test for writing media.repo
Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2016-05-23 18:34:04 +02:00
Lubomír Sedlář
8ef9478879 [discinfo] Use context manager for file access
Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2016-05-23 18:34:04 +02:00
Lubomír Sedlář
2113b6475c [metadata] Add tests for discinfo files
This tests writing and reading them.

Also, it makes sure the description for layered products is correct:
there was a missing space.

Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2016-05-23 18:34:04 +02:00
Lubomír Sedlář
bb4afea4f1 [image-build] Allow using external install trees
This is needed for the twoweek Fedora atomic release to point to regular
nightly composes.

Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2016-05-23 18:30:14 +02:00
Lubomír Sedlář
385f0e950c Add type to base product for layered releases
Default value is "ga", can be overwritten by `base_product_type` config
option.

Fixes: #305
Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2016-05-23 14:12:23 +02:00
Dennis Gilmore
fcfdb36352 Merge #303 [ostree] Use unique work and log paths 2016-05-18 16:30:44 +00:00
Lubomír Sedlář
9dce30a78d [ostree] Use unique work and log paths
Each variant.arch combination can have multiple ostree repos configured,
so we need to make sure the filesystem paths don't clash.

The paths used now are:

    logs/<arch>/<variant>/ostree-<x>/
    work/ostree-<x>/config_repo

The x stands for a number identifying the task. It has no relation to
actual contents of the repo.

Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2016-05-18 08:03:31 +02:00
Lubomír Sedlář
b43e35f7f2 [arch] Add mock rpmUtils module
Use a mock instead of relying on the real module in tests. This fixes
test failures on RHEL-7 (caused by different configuration).

Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2016-05-17 12:10:45 +02:00
Dennis Gilmore
00f2e24bce 4.1.5 release
Signed-off-by: Dennis Gilmore <dennis@ausil.us>
2016-05-16 20:56:48 -05:00
Lubomír Sedlář
eeacb5b9f1 [ostree] Put variant name in ostree log dir
This will prevent log files from being mangled when multiple ostree
repos are created.

Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2016-05-16 18:29:09 +02:00
Dennis Gilmore
e998bbe436 Merge #294 [ostree] Initialize empty repo 2016-05-16 13:39:55 +00:00
Lubomír Sedlář
d3900296af [util] Resolve git+https URLs
Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2016-05-16 08:01:50 +02:00
Lubomír Sedlář
12652ad1fa [ostree] Initialize empty repo
Make sure the directory exists before calling Koji (because otherwise
the mounting will fail). Update the runroot script to initialize the
repo when there are no files in the target destination.

Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2016-05-10 08:27:43 +02:00
Lubomír Sedlář
4e3d87e658 [test] Add checks for created images
The performed checks:
 * If format is ISO, the file must have correct magic string
 * If it's bootable, there must be MBR or GPT

When a check fails on any failable deliverable, it will be logged and
the file removed from metadata (it will still remain on the disk). This
required a change to write the images.json file later (after test
phase).

Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2016-05-05 15:38:00 +02:00
Lubomír Sedlář
5aadf4ac39 Fix caching global ksurl
The config object from Kobo does not allow keys starting with
underscore, so we prefix it with `private_` instead.

Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2016-05-05 10:44:27 +02:00
Dennis Gilmore
3064a6f0fe include tests/fixtures in manifest
Signed-off-by: Dennis Gilmore <dennis@ausil.us>
2016-04-29 21:11:01 -05:00
Dennis Gilmore
d8272bd0fa 4.1.4 release
Signed-off-by: Dennis Gilmore <dennis@ausil.us>
2016-04-29 15:36:41 -05:00
Dennis Gilmore
c80b7c6894 Merge #273 Deduplicate configuration a bit 2016-04-29 12:26:51 +00:00
Dennis Gilmore
8615c96624 Merge #280 [createrepo] Use more verbose output 2016-04-29 12:26:15 +00:00
Dennis Gilmore
f9498744af Merge #283 Pungi should log when it tries to publish notifications. 2016-04-29 12:25:57 +00:00
Dennis Gilmore
5c4d3a5196 [createiso] Add back running isohybrid on x86 disk images
rhbz#1331317 when we refactored how we make dvds in
df400002d8 we lost the ability to boot
the dvd as a disk image.

Signed-off-by: Dennis Gilmore <dennis@ausil.us>
2016-04-29 09:00:44 +02:00
Lubomír Sedlář
b949bfd615 [createiso] Remove chdir()
Explicitly pass workdir to all invoked command. This is easier to follow
and test.

Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2016-04-29 08:25:49 +02:00
Lubomír Sedlář
d4effc1610 [pkgset] Fix caching RPMs
The test mock did not actually match what is provided by Kobo.

Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2016-04-28 09:05:03 +02:00
Lubomír Sedlář
4da77c5e5d [createrepo] Use more verbose output
Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2016-04-27 18:35:43 +02:00
Ralph Bean
dafeb613c6 Pungi should log when it tries to publish notifications.
Signed-off-by: Ralph Bean <rbean@redhat.com>
2016-04-27 12:09:57 -04:00
Lubomír Sedlář
9f3408fec0 [pkgset] Use context manager for opening file list
Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2016-04-26 14:58:18 +02:00
Lubomír Sedlář
377fcb6948 [pkgset] Add tests for writing filelists
Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2016-04-26 14:58:09 +02:00
Lubomír Sedlář
d7012c442a [pkgset] Simplify finding RPM in koji buildroot
Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2016-04-26 14:44:29 +02:00
Lubomír Sedlář
0c8eb6c0fb [pkgset] Clean up koji package set
* break too long lines
 * remove unneeded code
 * call parent methods with super()

Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2016-04-26 14:43:43 +02:00
Lubomír Sedlář
ffcb3684de [pkgset] Add test for pkgset merging
Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2016-04-22 14:06:06 +02:00
Lubomír Sedlář
2bb65408ee [pkgset] Add tests for KojiPackageSet
There is a lot of mock objects needed: we bypass calls to Koji, use a
mock FileCache that does not need valid RPMs on disk and avoid any
multithreading.

The test data in tests/fixtures/tagged-rpms.json comes from Koji. It is
filtered down to only a few packages to make it manageable.

Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2016-04-22 13:35:17 +02:00
Lubomír Sedlář
65697a7526 [pkgset] Clean up Koji source
* Remove unused imports and variables
 * Simplify code where possible
 * Break too long lines

Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2016-04-22 09:44:20 +02:00
Lubomír Sedlář
01422983cb [pkgset] Add tests for Koji source
This patch also fixes the bug where using a preconfigured Koji event
would not actually work and instead the latest event would be used.

Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2016-04-22 09:44:20 +02:00
Lubomír Sedlář
084994538b Add common global settings for images
The live_images, live_media and image_build phases have same options
that need to be specified on each image. This leads to a lot of
duplication in the config file. This patch adds global settings and
phase-level settings that allow to significantly reduce duplication.

Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2016-04-18 18:11:29 +02:00
Lubomír Sedlář
a8ff48ce92 Remove duplicated and dead code
in checking whether a phase should be skipped.

Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2016-04-18 18:11:29 +02:00
Lubomír Sedlář
91119d7d17 [live-media] Add check for live_media_version option
It was used, but the type was not validated.

Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2016-04-18 18:11:29 +02:00
Lubomír Sedlář
2abf9511c9 [scm-wrapper] Remove unused method
It should have raised NotImplementedError, but we better remove it
altogher since we are missing export_dir anyway.

Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2016-04-18 14:24:43 +02:00
Lubomír Sedlář
29a2b45fb4 [scm-wrapper] Report when file wrapper did not match anything
Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2016-04-18 14:24:43 +02:00
Lubomír Sedlář
3ac7148b38 [scm-wrapper] Use context manager for managing temp dir
This is a sure way to have it removed, without having to duplicate the
logic in all places where it is used.

Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2016-04-18 14:24:43 +02:00
Lubomír Sedlář
6daf43f72e [scm-wrapper] Reduce code duplication in RPM wrapper
The logic for expanding the list of patterns into a list of actual RPM
paths was duplicated for both exporting a directory and file.

Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2016-04-18 14:24:43 +02:00
Lubomír Sedlář
770ca9c202 [scm-wrapper] Copy files directly
Instead of spawning `cp x/* y` there is now Python code to the same
thing. This should help with debugging if something fails as the
traceback will be more informative (rather than saying a command
failed). As another benefit the tests get much simpler.

Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2016-04-18 14:24:43 +02:00
Lubomír Sedlář
5d14304dd1 [scm-wrapper] Reduce code duplication
Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2016-04-18 14:24:43 +02:00
Lubomír Sedlář
bb9cbe88db [scm-wrapper] Add tests for SCM wrappers
All four methods are not somewhat tested.

Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2016-04-18 14:24:43 +02:00
Lubomír Sedlář
46ab1cb6f6 [ostree] Set each repo to point to current compose
Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2016-04-15 08:17:40 +02:00
Lubomír Sedlář
e6079e4c85 [ostree-installer] Drop filename setting
This should just use the global default format. Other phases don't have
their own setting either.

Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2016-04-14 14:45:36 +02:00
Dennis Gilmore
ffd054d262 Merge #269 Improve logging of failable deliverables 2016-04-13 14:56:28 +00:00
Lubomír Sedlář
a83a34fd40 [ostree-installer] Fix example documentation
There is no `compose_date`, the field is called just `date`.

Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2016-04-13 15:12:28 +02:00
Lubomír Sedlář
18b6020ac5 Improve logging of failable deliverables
The pungi.global.log should show subvariant for each failed deliverable
(if available). When the compose finishes, there is a new log file in
logs/global/deliverables.json containing details about all deliverables
as triples of (variant, arch, subvariant).

 * `required` lists all deliverables that can not fail
 * `attempted` lists all failable deliverables that were started
 * `failed` is a subset of `attempted` and only contains deliverables
   that failed

If the compose fails, the lists may be incomplete.

Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2016-04-13 13:45:30 +02:00
Lubomír Sedlář
ad32b73918 [ostree-installer] Install ostree in runroot
Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2016-04-12 12:47:02 +02:00
Lubomír Sedlář
31d922692f [pkgset] Print more detailed logs when rpm is not found
Fixes: #265
Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2016-04-11 15:34:52 +02:00
Lubomír Sedlář
a696eb4f3a [ostree-installer] Clone repo with templates
We can't assume the templates will just be available. This patch adds a
configuration option to point to the git repo with them. It will be
cloned at compose box and relative paths to templates will be made
absolute respective to this clone.

Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2016-04-11 10:25:10 +02:00
Dennis Gilmore
4f76425c9f 4.1.3 release
Signed-off-by: Dennis Gilmore <dennis@ausil.us>
2016-04-08 07:34:57 -05:00
Dennis Gilmore
cb271dc5ac enable the compose test
Signed-off-by: Dennis Gilmore <dennis@ausil.us>
2016-04-08 06:47:00 -05:00
Lubomír Sedlář
f17b5e13ad [ostree-installer] Copy all lorax outputs
Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2016-04-08 12:48:42 +02:00
Lubomír Sedlář
1bf4bec32c [ostree] Log to stdout as well
Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2016-04-08 11:37:16 +02:00
Lubomír Sedlář
8799d4cd85 [ostree-installer] Use separate directory for logs
Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2016-04-08 11:36:06 +02:00
Dennis Gilmore
09222a87a0 Merge #260 Maybe fix ostree? 2016-04-08 09:26:11 +00:00
Lubomír Sedlář
81d84a030b [ostree-installer] Put lorax output into work dir
Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2016-04-08 09:40:41 +02:00
Lubomír Sedlář
8c381e33aa [ostree] Add test check for modified repo baseurl
Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2016-04-07 15:42:41 +02:00
Lubomír Sedlář
e705cdd165 [ostree] Move cloning repo back to compose box
and pass absolute path to the config into runroot. This could avoid the
problem of not being able to clone the repo in runroot.

Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2016-04-07 15:28:15 +02:00
Lubomír Sedlář
b7948f2d65 [ostree] Mount ostree directory in koji
Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2016-04-07 14:04:50 +02:00
Dennis Gilmore
36e7279a5e 4.1.2 release
Signed-off-by: Dennis Gilmore <dennis@ra.ausil.us>
2016-04-06 17:44:40 -05:00
Dennis Gilmore
5f12c8c9ce Merge #257 [ostree] Enable marking ostree phase as failable 2016-04-06 18:36:31 +00:00
Lubomír Sedlář
ed12a64a84 [ostree] Enable marking ostree phase as failable
Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2016-04-06 16:12:29 +02:00
Lubomír Sedlář
7516fbd690 [koji-wrapper] Initialize wrappers sequentially
When multiple threads call `get_profile_module` at the same time, some
of them may get an exception from koji. This should prevent the problem.

Fixes: #253
Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2016-04-06 15:54:58 +02:00
Lubomír Sedlář
3e1a6edecc [createiso] Simplify code, test phase
A couple arguments passed from phase to worker threads were not
duplicated. Only one copy is passed now.

A test case was added both for the phase itself and for worker thread as
well.

Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2016-04-06 13:25:49 +02:00
Lubomír Sedlář
df400002d8 [createiso] Move runroot work to separate script
Instead of running a long command line in the runroot (or locally), move
all that work into a separate script that will be installed. This means
chroot will need to install pungi.

Everything should work as it did before. The only exception to this is
that there is logic to find lorax templates instead of harcoding the
location. This is done using a separate script.

Related: #230
Fixes: #231
Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2016-04-06 13:25:49 +02:00
Lubomír Sedlář
5b1b6c1c4f [ostree] Use explicit work directory
Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2016-04-05 12:46:59 +02:00
Lubomír Sedlář
96e7ddd3ea [ostree] Rename atomic to ostree
Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2016-04-05 09:14:00 +02:00
Lubomír Sedlář
ad87ea2d28 [ostree] Move cloning config repo to chroot
Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2016-04-05 09:13:55 +02:00
Lubomír Sedlář
5ff2d9f957 [ostree] Fix call to kobo.shortcuts.run
Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2016-04-04 15:39:38 +02:00
Lubomír Sedlář
2ddaea5387 [atomic] Stop creating the os directory
The output directory for Lorax can not exist beforehand, or the process
will fail.

Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2016-04-04 15:39:38 +02:00
Lubomír Sedlář
1ebb9d1773 [checksum] Add arch to file name
This allows the checksum file to include the architecture.

Fixes: #243
Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2016-04-04 09:38:48 +02:00
Dennis Gilmore
861a4f5823 fix up spec
Signed-off-by: Dennis Gilmore <dennis@ausil.us>
2016-04-01 09:43:18 -05:00
Dennis Gilmore
f69ca2c5fa 4.1.1 release
Signed-off-by: Dennis Gilmore <dennis@ausil.us>
2016-04-01 09:42:24 -05:00
Dennis Gilmore
6b07dcead3 install scripts
pungi-config-validate
pungi-make-ostree

Signed-off-by: Dennis Gilmore <dennis@ausil.us>
2016-04-01 09:13:19 -05:00
Dennis Gilmore
428af17cb1 Merge #242 Fix wrong file permissions 2016-04-01 13:19:04 +00:00
Lubomír Sedlář
4af6a8f438 Add a utility to validate config
This script will create all phases and run all validation methods.

Fixes #244
Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2016-04-01 09:41:34 +02:00
Lubomír Sedlář
620cecc409 [variants] Stop printing stuff to stderr unconditionally
Instead of looking for the DTD at module load time do it only when
required. Use a logger (if supplied) to print the warning.

Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2016-04-01 09:25:08 +02:00
Lubomír Sedlář
e5f37016e0 Fix atomic/ostree config validations
Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2016-04-01 07:42:49 +02:00
Lubomír Sedlář
c5c2261489 [pungi-wrapper] Remove duplicated code
This is almost exact duplicate of util.makedirs. One copy should be
enough.

Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2016-03-31 10:10:18 +02:00
Lubomír Sedlář
490514e263 [checks] Add a check for too restrictive umask
If umask is set to something too high (>0022), a warning will be
printed. It does not abort the compose though.

Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2016-03-31 10:10:18 +02:00
Lubomír Sedlář
69316d827a [util] Remove umask manipulation from makedirs
This causes a race condition: umask is process-wide setting, so any file
created by another thread while the umask is set to 0 will have wrong
permissions. This also removes the possible problem of not resetting the
umask if exception is raised.

Fixes: #239
Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2016-03-31 10:10:10 +02:00
Dennis Gilmore
4ec8ad5de8 Merge #240 Filter variants and architectures 2016-03-29 15:36:49 +00:00
Lubomír Sedlář
d383e6c5c0 Filter variants and architectures
There already were config options tree_arches and tree_variants, but the
filtering was done at the compose level and there was not interaction
between the two options. This led to problems when a variant would have
all its arches filtered out.

This patch moves the filtering to the variant loader. It adds better
logging, so whenever a variant is filtered (for any reason), it will be
explicitly stated in the logs.

Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2016-03-29 16:15:30 +02:00
Lubomír Sedlář
98f7ef739e Refactor checking for failable deliverables
This uses a new common function that will ensure consistent logging
without duplicating the functionality all over the place.

A couple tests are updated to verify that correct data is logged.

Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2016-03-24 10:12:20 +01:00
Lubomír Sedlář
bb0267bc7c [buildinstall] Do not crash on failure
When the koji tasks fails but produces some output (e.g. .discinfo),
copying the artifacts would crash the compose. That should not happen if
the variant/arch is marked as failable.

Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2016-03-24 09:17:38 +01:00
Lubomír Sedlář
652987f2cc Reuse helper in all tests
Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2016-03-23 12:00:06 +01:00
Lubomír Sedlář
8d224b206b [atomic] Add atomic_installer phase
This phase runs lorax with extra templates in Koji runroot task, links
the boot.iso to proper location in compose directory and adds the
installer iso to image manifest. This phase runs concurrently with live
media etc.

Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2016-03-23 12:00:06 +01:00
Lubomír Sedlář
536c6c85b7 [ostree] Add ostree phase
This phase runs the script to make ostree repository in koji runroot
task. It runs right after regular yum repos are created.

Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2016-03-23 10:58:35 +01:00
Lubomír Sedlář
282058dafe [atomic] Add a script to create ostree repo
This is a wrapper over ostree and rpm-ostree. It is intended to be run
in either Koji or Mock chroot.

Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2016-03-23 10:28:08 +01:00
Dennis Gilmore
6230b0ff3e Merge #232 Improve logging by adding subvariants 2016-03-22 14:15:26 +00:00
Lubomír Sedlář
ecbf08c6f8 Add compose type to release for images
Move getting of the precomputed value to a single place in Compose
class. The value now has format `date[.type_suffix].respin`.

Resolves: rhbz#1319924
Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2016-03-22 08:57:40 +01:00
Lubomír Sedlář
1a1cfc65ce [image-build] Add traceback on failure
Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2016-03-17 10:21:21 +01:00
Lubomír Sedlář
ea7f98ef4e [image-build] Use subvariants in logging output
Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2016-03-17 10:19:28 +01:00
Lubomír Sedlář
f1974d3f03 [live-media] Use subvariants in logging
Print the subvariant together with variant UID and arches. This should
make the global log easier to understand.

The output of koji command should now be split into multiple files in
logs/{arch}/livemedia-{variant}-{subvariant}.{arch}.log instead of
having them all in one file.

The tests were updated to use more sensible value for the subvariant
field.

Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2016-03-17 09:04:50 +01:00
Lubomír Sedlář
4afd21952c Add tracebacks to all failable phases
Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2016-03-16 18:47:12 +01:00
Peter Robinson
c4baf51b98 ppc no longer needs magic bits in the iso
Signed-off-by: Peter Robinson <pbrobinson@fedoraproject.org>
2016-03-16 17:22:55 +00:00
Lubomír Sedlář
0759c7fb48 [buildinstall] Add more debugging output
When it fails, a traceback will be printed.

Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2016-03-16 18:16:24 +01:00
Lubomír Sedlář
f5897eccbb [metadata] Stop crashing on empty path from .treeinfo
Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2016-03-16 15:24:37 +01:00
Lubomír Sedlář
aab22b6f9f [checksums] Add label to file name
Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2016-03-16 08:49:44 +01:00
Lubomír Sedlář
aa38eb1fd7 [buildinstall] Use customized dvd disc type
This should generate the same volume id in buildinstall and createiso
phases, with isolinux.cfg being consistent as well.

Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2016-03-14 08:20:43 +01:00
Adam Williamson
c321bca8ef image_build: fix subvariant handling
Dennis added a 'subvariant' property to the Docker image config,
but we weren't using it, we were just hard-coding the variant
as the subvariant...and doing it wrong, as well, using the
variant object rather than its uid property.

This fixes both problems: we'll now use the explicitly set
image config 'subvariant' property if there is one, otherwise
we use the variant.uid as the subvariant.

Note this is a high priority fix, as it broke F24 compose today.

Signed-off-by: Adam Williamson <awilliam@redhat.com>
2016-03-13 09:18:08 -07:00
Lubomír Sedlář
be8605ac91 Remove check for disc type
This will get validated in productmd anyway, no need to duplicate the
check in Pungi itself.

Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2016-03-11 08:55:21 +01:00
Lubomír Sedlář
c1b8fbe4f9 Update tests to match the subvariant
Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2016-03-10 16:59:34 -06:00
Adam Williamson
254bfb8ca4 add 'subvariant' image property, create live/appliance names
This adds the new 'subvariant' property to all images produced by Pungi.
For most image types this is the same as the variant, for now. For
live_images and livemedia_phase, the image config may specify
'subvariant' and the value will be used if present, otherwise the
variant name will be used.

We also now synthesize the Koji image 'name' for live and appliance
images if the image config doesn't specify it, and use a name that
complies better with the naming policy for ARM disk images (partially
resolving https://pagure.io/pungi-fedora/issue/7 ).

This is completely untested as yet, just bashing stuff out on a Sunday,
will work more on it tomorrow.

Signed-off-by: Adam Williamson <awilliam@redhat.com>
2016-03-10 16:59:34 -06:00
Lubomír Sedlář
2fd117367e Simplify koji pkgset
Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2016-03-10 19:13:51 +01:00
Lubomír Sedlář
07f5da5d4f [checks] Fix tests to never use real real arch
Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2016-03-10 18:54:14 +01:00
Lubomír Sedlář
e77821987c [init] Update documentation
Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2016-03-10 15:42:21 +01:00
Lubomír Sedlář
619e5323d6 [init] Iterate over arches just once
We can create the repos in one loop together with writing the comps
files.

Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2016-03-10 15:30:05 +01:00
Lubomír Sedlář
1efd4a9873 [init] Remove duplicated checks for comps
Check once before iterating through the variants. This greatly
simplifies the tests as each function now has one less code path.

Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2016-03-10 15:30:05 +01:00
Lubomír Sedlář
1c84dc6ea0 [init] Break long lines
Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2016-03-10 15:30:03 +01:00
Lubomír Sedlář
41cdf54c05 [init] Don't overwrite the same log file
When creating the comps repo, use a separate log file for each variant
instead of overwriting the same global file again and again.

Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2016-03-10 15:29:40 +01:00
Lubomír Sedlář
2ca002d602 [init] Add config option for keeping original comps
The configuration can specify a list of variants for which the original
comps file will be copied without any modification.

Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2016-03-10 15:22:21 +01:00
Lubomír Sedlář
6f9f84c4d4 [init] Add tests for the init phase
Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2016-03-10 15:22:09 +01:00
Lubomír Sedlář
3174f06fd5 [checks] Test printing in all cases
Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2016-03-10 12:47:49 +01:00
Lubomír Sedlář
19468dda77 [checks] Reduce code duplication
Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2016-03-10 12:35:08 +01:00
Lubomír Sedlář
0f3bfbbddf [checks] Relax check for genisoimage
The rules are similar to isohybrid, but there are no checks for
architecture.

Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2016-03-10 11:23:45 +01:00
Lubomír Sedlář
d8f685000d [checks] Remove duplicate msgfmt line
Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2016-03-10 11:20:10 +01:00
Lubomír Sedlář
2d9dd0e535 [checks] Relax check for isohybrid command
It is used only in createiso and productimg phases.

For productimg, it needs to be present only when the compose is bootable
and productimg phase is explicitly enabled.

For createiso, it is only needed if runroot is not enabled.

Additionally, if we detect pungi running on arch for which syslinux is
not available, a warning is printed, but the compose is allowed to
continue (and possibly crash later).

Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2016-03-10 11:20:10 +01:00
Lubomír Sedlář
62b73944da [checks] Add tests for dependency checking
Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2016-03-10 10:43:04 +01:00
Lubomír Sedlář
337d2a999c [checks] Don't always require jigdo
If the configuration specifically requests no jigdos, there is no point
in checking for the binary existence.

This is not 100% reliable. The jigdo option defaults to True, so if the
option is not specified the binary is required even if there are no
images configured.

Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2016-03-10 09:08:19 +01:00
Lubomír Sedlář
d909adf26c [pkgset] Respect inherit setting
It's logged, but not really used...

Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2016-03-09 19:23:37 +01:00
Dennis Gilmore
0c13908864 update the script to make docs to make 4.0 version also. update the master docs for 4.1
Signed-off-by: Dennis Gilmore <dennis@ausil.us>
2016-03-09 08:06:11 -06:00
Lubomír Sedlář
7e2cd28fb8 [live-media] Support release set to None globally
Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2016-03-09 13:08:22 +01:00
Lubomír Sedlář
4bc126979b Add README
This is based on the about.rst documentation.

Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2016-03-08 16:38:40 +01:00
Dennis Gilmore
0e7ea91d9d Merge #206 Add option to customize disc type 2016-03-08 13:40:43 +00:00
Dennis Gilmore
003efef2cf Merge #205 [gather] Fix documentation of multilib white- and blacklist 2016-03-08 13:39:16 +00:00
Dennis Gilmore
182c39669d Merge #204 [paths] Document and test translate_path 2016-03-08 13:38:53 +00:00
Dennis Gilmore
f898c7ca7d Merge #203 Simplify common live media options 2016-03-08 13:38:39 +00:00
Lubomír Sedlář
103b0eb590 [doc] Fix formatting
Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2016-03-08 13:27:43 +01:00
Lubomír Sedlář
72f9819779 [createiso] Add customizing disc type
Relates: #105
Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2016-03-08 13:04:34 +01:00
Lubomír Sedlář
44d7b31a80 [live-images] Add customizing disc type
Relates: #105
Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2016-03-08 13:04:34 +01:00
Lubomír Sedlář
0c9ad96a31 [buildinstall] Add customizing disc type
This patch adds configuration option to change disc type used in file
name. So far this can only be changed for link to images/boot.iso.

Resolves: #109
Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2016-03-08 13:04:28 +01:00
Lubomír Sedlář
ad104f994a [buildinstall] Rename method to not mention symlinks
It is either hardlinking or copying, so the name is quite misleading.

Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2016-03-08 11:26:14 +01:00
Lubomír Sedlář
935931b812 [gather] Fix documentation of multilib white- and blacklist
For blacklist the matching is done using shell-style globs. For
whitelists there is no matching at all and package names must be
configured exactly.

Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2016-03-08 09:31:33 +01:00
Lubomír Sedlář
8e20f216f1 [paths] Document and test translate_path
The documentation was inaccurate.

Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2016-03-07 15:18:57 +01:00
Lubomír Sedlář
27375788c2 [createrepo] Compute delta RPMS against old compose
Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2016-03-07 14:49:17 +01:00
Lubomír Sedlář
19c3707aee [util] Add function to search for old composes
This was already implemented as part of pkgset phase. It is now moved to
the util module and covered with tests.

Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2016-03-07 14:49:17 +01:00
Lubomír Sedlář
86bb816417 [live-media] Add global settings
These can be overriden for a particular image, but in general case they
can simplify the config.

Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2016-03-04 08:15:25 +01:00
Lubomír Sedlář
595845e104 [live-media] Rename test case
Originally it was copied from image build phase, and was not renamed.

Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2016-03-04 08:15:25 +01:00
Dennis Gilmore
f202d24961 Limit the variants with config option 'tree_variants'
'tree_variants' in configuration should be able to limit the tree
variants, just like the config option 'tree_arches' which is used to
limited the arches.

For example, if there is configuration (refer to doc/configuration.rst)
go with:

        tree_variants = ["Server"]

then only "Server" variants will be composed, and any other variants in
variants.xml will be ignored.

Signed-off-by: Qixiang Wan <qwan@redhat.com>

Rebased on master

Signed-off-by: Dennis Gilmore <dennis@ausil.us>
2016-03-03 13:00:52 -06:00
Lubomír Sedlář
9aed3364a6 [createrepo] Refactor code
This patch tries to simplify the code by:

 * breaking up too long lines
 * simplifying the loop to start createrepo jobs
 * removing duplication
 * general clean up

Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2016-03-02 16:11:25 +01:00
Lubomír Sedlář
223344e04a [createrepo] Add tests
Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2016-03-02 16:11:25 +01:00
Lubomír Sedlář
055b5e431b [paths] Use variant.uid explicitly
Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2016-03-02 16:11:25 +01:00
Lubomír Sedlář
6ae48e2bf5 [createrepo-wrapper] Refactor code
Simplify the code a bit by removing conditions that don't help in any
way: executing a loop zero times is the same as not executing it at all.

Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2016-03-02 16:11:25 +01:00
Lubomír Sedlář
d619f14dbf [createrepo-wrapper] Fix --deltas argument
There is no value, the flag is there or it is not there.

Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2016-03-02 16:11:25 +01:00
Lubomír Sedlář
c93772ade8 [createrepo-wrapper] Add tests
Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2016-03-02 16:11:25 +01:00
Lubomír Sedlář
a813e926dc [koji-wrapper] Retry watching on connection errors
With this patch Pungi should be more tolerant of network failures when
running a blocking command (creating live media or live images).

If the connection drops and the output indicates network problems, Pungi
will try to watch the task with `koji watch-task`. This will be retried
until it finishes (successfully or with some other failure). There is an
increasing timeout after each retry. Currently the maximum number of
retries is not limited.

Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2016-03-02 14:01:17 +01:00
Lubomír Sedlář
44c4ef5c41 [testphase] Don't run repoclosure for empty variants
As a side effect, the non-existing repositories are no longer passed to
global repoclosure.

Fixes: #196
Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2016-03-01 12:44:07 +01:00
Lubomír Sedlář
4a4ef23e3c [image-build] Fix resolving git urls
After config was modified to work with sections, the resolving broke.
This patch fixes it and adds a test to catch this problem in the future.

Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2016-02-29 08:23:26 +01:00
Lubomír Sedlář
73a560d63c [live-images] No manifest for appliances
Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2016-02-26 19:48:52 +01:00
Dennis Gilmore
e6596d818c Merge #190 [live-images] Rename log file 2016-02-26 13:54:01 +00:00
Dennis Gilmore
8670452b6b Merge #189 [buildinstall] Use -dvd- in volume ids instead of -boot- 2016-02-26 13:53:43 +00:00
Lubomír Sedlář
abb27ac7d7 [live-images] Rename log file
The log file started with createiso-, which is utterly confusing. With
this patch, the logs are named with liveimage- prefix.

Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2016-02-26 12:05:58 +01:00
Lubomír Sedlář
452da86649 [buildinstall] Use -dvd- in volume ids instead of -boot-
Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2016-02-26 11:42:41 +01:00
Lubomír Sedlář
636ac79186 [buildinstall] Hardlink boot isos
Instead of creating a symlink, try to hardlink the image, and copy it if
hardlinking fails.

Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2016-02-26 10:58:03 +01:00
Lubomír Sedlář
ab30fe0cef [doc] Write documentation for kickstart Git URLs
Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2016-02-25 20:26:22 +01:00
Lubomír Sedlář
60d820d4fd [util] Resolve branches in git urls
Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2016-02-25 08:39:01 +01:00
Lubomír Sedlář
6e8970e648 [live-images] Fix crash when repo_from is not a list
Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2016-02-24 19:33:28 +01:00
Lubomír Sedlář
98a9e02b1b [buildinstall] Don't copy files for empty variants
They are not there in the first place.

Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2016-02-24 07:31:13 +01:00
Dennis Gilmore
133cb97aa0 4.1.0 dev start
Signed-off-by: Dennis Gilmore <dennis@ausil.us>
2016-02-23 12:19:59 -06:00
Dennis Gilmore
f6c4f166bf 4.0.5 release
Signed-off-by: Dennis Gilmore <dennis@ausil.us>
2016-02-23 12:08:33 -06:00
Lubomír Sedlář
48979a4979 [tests] Fix wrong checks in buildinstall tests
There were asserts that actually did not test anything. They should have
checked that koji is called with correct arguments.

Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2016-02-23 15:30:49 +01:00
Lubomír Sedlář
c61abac137 [tests] Use temporary files for buildinstall
Instead of mocking open just write to the temporary file and then check
its content.

Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2016-02-23 15:30:49 +01:00
Lubomír Sedlář
3ff1d3e21f [tests] Do not mock open for koji wrapper tests
Instead create a temporary file and write into it, then check its
contents.

Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2016-02-23 15:30:49 +01:00
Dennis Gilmore
a3044f4381 Merge #179 Update makefile targets for testing 2016-02-23 13:43:19 +00:00
Lubomír Sedlář
44d6f7d708 Update makefile targets for testing
Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2016-02-23 13:03:11 +01:00
Lubomír Sedlář
ca7c78d98c [live-images] Set type to raw-xz for appliances
Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2016-02-23 09:41:03 +01:00
Lubomír Sedlář
456fbb8812 [live-images] Correctly create format
Extracting extensions from the file name is not reliable as there is no
way to determine where extensions start. There can very well be a
version.release separated by dot. To bypass this, just use hardcoded
list of possible formats.

Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2016-02-23 09:35:50 +01:00
Lubomír Sedlář
e9292fc942 [tests] Dummy compose is no longer private
Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2016-02-22 19:11:04 +01:00
Lubomír Sedlář
385b52041c [tests] Move buildinstall tests to new infrastructure
This test case now uses the same mocks as other tests, it only restricts
the variants used.

Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2016-02-22 19:11:04 +01:00
Lubomír Sedlář
90954ddf0e [tests] Use real paths module in testing
This avoids problems of mock paths having different API that the real
ones.

Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2016-02-22 19:11:04 +01:00
Lubomír Sedlář
8661d294ab [tests] Move dummy testing compose into separate module
This greatly reduces duplication, as a single copy is now shared among
all test cases.

Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2016-02-22 19:10:12 +01:00
Lubomír Sedlář
75b57ac25a [live-images] Create image dir if needed
We can't copy an image to a non-existing directory.

Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2016-02-22 18:59:31 +01:00
Lubomír Sedlář
7734ddf57e [live-images] Add images to manifest
The type is either "live" or "appliance", the format is set based on
filename extension.

Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2016-02-22 14:27:51 +01:00
Lubomír Sedlář
f80c97e3ec [live-images] Fix path processing
* Add option to keep filenames generated by Koji.
 * Put results of spin-appliance into image dir
 * On failure images are no longer deleted.

Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2016-02-22 14:27:26 +01:00
Lubomír Sedlář
4a1e029c1d [live-images] Move repo calculation to separate method
Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2016-02-22 12:27:26 +01:00
Lubomír Sedlář
9b748f752e [koji-wrapper] Fix getting results from spin-appliance
Also don't create new client proxy when one already exists.

Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2016-02-22 12:27:22 +01:00
Lubomír Sedlář
ab44f3539e [live-images] Filter non-image results
Only keep results that have known extension.

Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2016-02-22 12:27:17 +01:00
Lubomír Sedlář
1044fb01f8 [live-images] Rename repos_from to repo_from
It should be consistent with live media and image build.

Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2016-02-22 08:48:12 +01:00
Lubomír Sedlář
33d5440a8a [koji-wrapper] Add test for passing release to image-build
Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2016-02-22 08:42:24 +01:00
Lubomír Sedlář
7c81c5aa9c [live-images] Automatically populate release with date and respin
This is the same feature that is already available for image-build and
live-media.

Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2016-02-22 08:38:19 +01:00
Lubomír Sedlář
ec03a8685a [live-media] Respect release set in configuration
Apparently just processing the config is not sufficient we don't pass
the value to Koji.

Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2016-02-22 08:32:27 +01:00
Lubomír Sedlář
32a966fc91 [live-images] Build all images specified in config
Not just the first one.

Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2016-02-22 08:21:51 +01:00
Lubomír Sedlář
8ed44dd153 [live-media] Don't create $basedir arch
Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2016-02-19 09:01:45 +01:00
Lubomír Sedlář
0fb8049fdd Update tests
Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2016-02-19 08:51:03 +01:00
Dennis Gilmore
b4a008f86a do not ad to image build and live tasks the variant if it is empty
Signed-off-by: Dennis Gilmore <dennis@ausil.us>
2016-02-19 08:51:03 +01:00
Dennis Gilmore
466a0eb24f when a variant is empty do not add it to the repolist for livemedia
Signed-off-by: Dennis Gilmore <dennis@ausil.us>
2016-02-19 08:47:05 +01:00
Lubomír Sedlář
37ac0d7bfe [live-media] Update tests to use $basearch
Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2016-02-18 16:17:30 +01:00
Lubomír Sedlář
1b6688d22c [buildinstall] Don't run lorax for empty variants
Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2016-02-18 16:12:44 +01:00
Lubomír Sedlář
71369c7690 Merge #159 use $basearch not $arch in livemedia tasks 2016-02-18 13:56:15 +00:00
Lubomír Sedlář
921664c3b5 Merge #158 do not uses pipes.quotes in livemedia tasks 2016-02-18 13:55:14 +00:00
Tomas Mlcoch
0c85e549e2 Add documentation for signing support that was added by previous commit
Signed-off-by: Tomáš Mlčoch <tmlcoch@redhat.com>
2016-02-18 13:37:00 +01:00
Tomas Mlcoch
5bffca5037 Support signing of rpm wrapped live images
With this patch, you can specify a command for
signing of koji builds. For example:

    signing_key_password_file = '~/file_with_password_for_key_fedora-24'
    signing_key_id = '81b46521'
    signing_command = '~/git/releng/scripts/sigulsign_unsigned.py -vv --password=%(signing_key_password)s fedora-24'

'signing_key_password_file' is a path to a file which contains
a password that will be formatted into 'signing_command' string
via '%(signing_key_password)s' string format syntax (if used).
Because pungi config is usualy stored in git and part of compose
logs we don't want password to be included directly in the config.
Note: If '-' is used instead of a filename, then you will be asked
for the password interactivelly right after pungi starts.

'signing_key_id' is ID of the key that will be used for the signing.
This ID will be used when crafting koji paths to signed files
(kojipkgs.fedoraproject.org/packages/NAME/VER/REL/data/signed/KEYID/..).

'signing_command' a command that will be run with a build as a single
argument. This command mustn't require any user interaction.
If you need to pass a password for a signing key to the command,
do this via command line option of the command with use of string
formatting syntax '%(signing_key_password)s' (see details
about 'signing_key_password_file').

Signed-off-by: Tomáš Mlčoch <tmlcoch@redhat.com>
2016-02-18 13:36:38 +01:00
Tomas Mlcoch
be4d596c36 Fix terminology - Koji uses sigkey not level
Signed-off-by: Tomáš Mlčoch <tmlcoch@redhat.com>
2016-02-18 13:35:27 +01:00
Dennis Gilmore
1616de1e1e use $basearch not $arch in livemedia tasks
koji for livemedia acts different to image builds and does
not translate $arch to x86_64, i386, etc so we need to just pass
in $basearch so that yum/dnf will translate it for us

Signed-off-by: Dennis Gilmore <dennis@ausil.us>
2016-02-17 17:03:46 -06:00
Dennis Gilmore
2858b1aa54 do not uses pipes.quotes in livemedia tasks
Signed-off-by: Dennis Gilmore <dennis@ausil.us>
2016-02-17 14:39:51 -06:00
Lubomír Sedlář
bf5196af4a [live-images] Don't tweak kickstarts
Instead of downloading the kickstart file in Pungi and modifying it,
just pass it to Koji.

Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2016-02-17 14:35:28 +01:00
Lubomír Sedlář
454363fba8 Allow specifying empty variants
The variants.xml file can list a variant with is_empty="true" and no
groups. If such variant is found, not package gathering will be run for
it, and no repos will be created.

This only makes sense for a variant that will have some other
deliverables like live media or images.

Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2016-02-16 15:08:15 +01:00
Lubomír Sedlář
adbc772fd0 [createrepo] Remove dead assignments
Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2016-02-16 15:08:15 +01:00
Lubomír Sedlář
826afdc162 Keep empty query string in resolved git url
Pagure: #152
Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2016-02-16 10:42:59 +01:00
Lubomír Sedlář
284d3a3510 [image-build] Use dashes as arch separator in log
Since multiple images are created in a single Koji task, the path to log
file contains a list of arches. These used to be separated with comma.
For consistency with live-media they are now separated by dashes.

Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2016-02-15 09:04:03 +01:00
Lubomír Sedlář
abcc51fb85 [buildinstall] Stop parsing task_id
KojiWrapper returns the task id as an integer already (if at all). There
is no need to parse it again.

Pagure: #148
Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2016-02-12 12:39:50 +01:00
Lubomír Sedlář
e1895bff26 [koji-wrapper] Get task id from failed runroot
Even when runroot task fails, it can emit task_id.

Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2016-02-12 12:38:45 +01:00
Lubomír Sedlář
93015d679c [live-media] Pass ksurl to koji
Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2016-02-11 17:09:30 +01:00
Dennis Gilmore
96489a1e78 Merge #146 [live-media] Properly calculate iso dir 2016-02-11 13:07:30 +00:00
Lubomír Sedlář
8ef2e7e308 [live-media] Properly calculate iso dir
The method expects to be called with a arch, not just variant.

Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2016-02-11 13:58:42 +01:00
Lubomír Sedlář
e9a42ad54f [image-build] Fix tests
This patch updates tests so that they pass, and fixes a couple places in
image build that did not work correctly with the nested configuration.
The documentation is reformatted so that it horizontal scrolling is less
likely.

Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2016-02-11 13:22:26 +01:00
Lubos Kocman
f067f38df0 add image-build sections
allows to use factory-parameters ...

Signed-off-by: Lubos Kocman <lkocman@redhat.com>
2016-02-11 13:22:16 +01:00
Lubomír Sedlář
39c688f7ef [koji-wrapper] Add tests for get_create_image_cmd
Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2016-02-11 12:23:54 +01:00
Lubomír Sedlář
5138a9b6e6 [live-images] Add support for spin-appliance
The config can specify type=appliance so that koji uses spin-appliance
instead of spin-livecd.

Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2016-02-11 12:08:48 +01:00
Lubomír Sedlář
ac29bf05ee [live-media] Koji option is ksfile, not kickstart
In config, it is still called kickstart to be consistent with how
image-build calls it.

Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2016-02-11 10:40:04 +01:00
Lubomír Sedlář
6ec151cde2 [live-media] Use install tree from another variant
Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2016-02-11 10:24:12 +01:00
Lubomír Sedlář
0c4bd42f80 [live-media] Put images into iso dir
Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2016-02-11 10:11:38 +01:00
Lubomír Sedlář
91faa0fafe [image-build] Koji expects arches as a comma separated string
Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2016-02-11 07:50:02 +01:00
Dennis Gilmore
8bf1b09641 Merge #139 Log more details when any deliverable fails 2016-02-10 21:03:32 +00:00
Lubomír Sedlář
b35264cfba [live-media] Version is required argument
Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2016-02-10 18:29:29 +01:00
Lubomír Sedlář
aec57dc72b [koji-wrapper] Only parse output on success
If Koji fails runroot task for some reason, the output will most likely
not have the required format and will crash Pungi.

Pagure: #140
Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2016-02-10 09:08:21 +01:00
Lubomír Sedlář
8e5e893e5c [koji-wrapper] Add tests for runroot wrapper
Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2016-02-08 13:27:18 +01:00
Lubomír Sedlář
f57665f963 [buildinstall] Improve logging
This patch fixes how logs are stored if lorax is used as buildinstall
method. The logs for each variant are in a separate file now. If failure
is allowed, the global log will now show why it failed.

A couple tests are added as well.

Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2016-02-08 13:17:08 +01:00
Lubomír Sedlář
d661de3e73 Log more details about failed deliverable
Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2016-02-08 12:07:04 +01:00
Lubomír Sedlář
3baa386ed4 [image-build] Fix failable tests
A missing input value was causing tests to not check the expected
condition (even though they were still passing).

Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2016-02-08 10:54:24 +01:00
Dennis Gilmore
2b897ec6ea Merge #135 Add live media support 2016-02-02 10:15:56 +00:00
Dennis Gilmore
a2ea84934b Merge #133 media_split: add logger support. Helps with debugging space issues on dvd media 2016-02-02 10:11:46 +00:00
Lubomír Sedlář
439622d576 [live-media] Add live media phase
This phase builds live media in Koji using the Live Media Creator. It
runs in parallel with current live images, create ISO and image build
phases.

The documentation is updated to explain how to configure this.

Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2016-02-01 13:28:49 +01:00
Lubomír Sedlář
a5a0f3d69f [koji-wrapper] Add support for spin-livemedia
This patch adds support for live media creator in Koji. The intended
workflow is to create a command , run it and finally collect built
artifacts.

    get_live_media_cmd()
    run_blocking_cmd()
    get_image_paths()

Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2016-01-29 09:02:02 +01:00
Lubomír Sedlář
ae30c07553 [koji-wrapper] Use more descriptive method names
The methods mentioning image build are generic and can work for other
task types.

get_image_build_paths -> get_image_paths
run_create_image_cmd -> run_blocking_cmd

Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2016-01-29 09:02:02 +01:00
Lubomír Sedlář
d85f00818d [image-build] Remove dead code
There are no mounts when running image-build tasks in Koji. This looks
like a copy-paste error.

Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2016-01-29 09:02:02 +01:00
Lubos Kocman
f0a8899ea7 media_split: add logger support. Helps with debugging space issues on dvd media
Signed-off-by: Lubos Kocman <lkocman@redhat.com>
2016-01-26 13:02:14 +00:00
Lubomír Sedlář
a698c7cc0a [image-build] Allow running image build scratch tasks
Issue #130

Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2016-01-26 12:47:59 +01:00
Lubomír Sedlář
dc4d502f2a [image-build] Allow dynamic release for images
When the release is explicitly set to None, generate a value from date
and respin. The documentation is updated to explain how it works.

Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2016-01-21 14:32:29 +01:00
Dennis Gilmore
39ce2556c3 4.0.4 release
Signed-off-by: Dennis Gilmore <dennis@ausil.us>
2016-01-20 09:41:18 -06:00
Dennis Gilmore
c77e78c4f1 Merge #123 Live images: add repo from another variant 2016-01-20 15:37:36 +00:00
Dennis Gilmore
09aebd3db9 Merge #125 [image-build] Stop creating wrong arch dirs 2016-01-20 15:37:27 +00:00
Lubomír Sedlář
8b4ad1ea02 Toggle multilib per variant
There is now a single option `multilib`, that maps variants and arches
to multilib methods. This replaces old `multilib_methods` option.

Multilib arches are implicitly deduced instead of using the
`multilib_arches` option.

The test compose is updated to only enable multilib on Server and its
addons.

Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2016-01-20 12:53:08 +01:00
Lubomír Sedlář
6d7fff5d1b [live-images] Code cleanup
This patch removes some duplicated variables that get passed on to the
build thread. It also moves creation of the command for generating image
manifest closer to where it is used. Finally it adds tests for the
thread.

Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2016-01-19 08:26:59 +01:00
Lubomír Sedlář
b16699ddfc [live-images] Add documentation
Add basic documentation for live-images phases. So far, there are no
examples, just a listing of accepted options.

Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2016-01-19 08:26:59 +01:00
Lubomír Sedlář
9059852ab5 [live-images] Add repos from other variants
This patch adds option for adding repositories from other variants to
the koji task for building images.

Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2016-01-19 08:26:59 +01:00
Lubomír Sedlář
e016015cf3 [image-build] Stop creating wrong arch dirs
There is no such arch as $arch or %(arch)s.

Pagure: #124
Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2016-01-19 08:24:02 +01:00
Lubomír Sedlář
6e0f6ee73e Enable identifying variants in exception traces
When pungi crashes, the logs will often contain useless description of
a variant. With this patch, the traceback will have details on the
variant.

Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2016-01-15 08:41:08 +01:00
Lubomír Sedlář
5f0675dd66 Store which deliverables failed
When compose is finished successfully, and there are some failed
deliverables, modify the final status to FINISHED_INCOMPLETE and log
what failed for which variants/arches.

This means the failures are logged twice, first time immediately after
it failed, second time in the summary at the end.

Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2016-01-15 08:41:08 +01:00
Lubos Kocman
7ec409a236 scm.py: use git clone instead git archive for http(s)://
Signed-off-by: Lubos Kocman <lkocman@redhat.com>
2016-01-14 06:42:57 -05:00
Lubomír Sedlář
f3f0ce0d35 Fix filtering of system release packages
The code was inconsistent with the documentation: the logic was
inverted.

Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2016-01-13 08:52:06 +01:00
Dennis Gilmore
5f7f23ed96 Merge #114 Use install tree/repo from another variant for image build 2016-01-12 17:56:38 +00:00
Lubomír Sedlář
b78878ac69 Make system release package filtering optional
Fedora variants needs both general fedora-release and
fedora-release-$variant packages installed. This patch disables the code
that would throw fedora-release away (assuming correct config is set).

Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2016-01-12 17:04:37 +01:00
Lubomír Sedlář
5688f1cbae [image-build] Optionally do not break whole compose
The configuration can now specify image-build as a deliverable that can
fail but not abort the whole compose.

Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2016-01-12 08:39:30 +01:00
Lubomír Sedlář
af11bebf1b [image-build] Refactoring
* Move getting arches to separate method.
 * Modify git url only if there is going to be a build. This is not very
   likely to happen, but could save a bit of time if it really does
   happen.

Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2016-01-11 16:42:05 +01:00
Lubomír Sedlář
d2ea1dd288 [image-build] Use repo from another variant
The config can now additionally specify other variants whose repos will
be passed on to koji. The previous way of specifying extra repos is
still available, as is the automatic adding of repo for current variant.

Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2016-01-11 16:42:05 +01:00
Lubomír Sedlář
7f815d80f5 [image-build] Take install tree from another variant
Add a configuration option to use install tree from another variant.

Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2016-01-11 16:42:05 +01:00
Lubomír Sedlář
195b13d434 Add missing formats to volumeid and image name
Also, when the format uses something unrecognized, die with more
descriptive error message.

Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2016-01-11 16:28:10 +01:00
Lubomír Sedlář
9c1418eb0a [image-build] Use single koji task per variant
Given a list of arches, koji can build multiple images in one go
(automatically starting children tasks for each one).

This causes a bunch of changes:
 * The configuration no longer allows changing config based on
   architecture, only variants are allowed. It is however possible to
   filter which arches are used for the building in the variant.
 * The configuration files for koji image-build are stored in
   work/image-build/$variant (not split based on arch).

This patch also changes the option name that is passed to koji
image-build: the repos should be specified under key `repo` (without the
trailing slash).

Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2016-01-08 14:33:54 +01:00
Lubomír Sedlář
88bb6ac3d7 Fix image-build modifying config
The code modifies the config in place, so it only works in the first
iteration. The fix is to create a copy which can be safely modified and
next iteration will still see the original data.

Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2016-01-06 16:53:00 +01:00
Lubomír Sedlář
a1384b60f4 Fix missing checksums in .treeinfo
The images listed in the file are obtained from .treeinfo files created
during buildinstall phase. However, the files are not stored directly in
buildinstall dir `work/$arch/buildinstall/` but in variant subdirectory
`work/$arch/buildinstall/$variant`.

Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2016-01-06 13:36:44 +01:00
Lubomír Sedlář
770a81b76c Don't crash on generating volid without variant
First, this fixes the crash when volume id requires variant uid, but it
is not specified. This happened in buildinstall phase.

When lorax is used, it is run once for each variant, so we can actually
specify the variant and get the correct variant.

When using buildinstall, no volume id will be generated and pungi will
possibly crash later on.

Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2016-01-04 19:27:11 +01:00
Dennis Gilmore
1af17a5262 Merge #99 Add option to specify non-failing stuff 2015-12-17 18:18:12 +00:00
Lubomír Sedlář
0222d4dc6d Add repo from current compose
This gets added together with the any repos from configuration.

Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2015-12-17 12:15:17 -06:00
Lubomír Sedlář
7a965bcb83 Fix getting compose topdir in CreateImage build thread
Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2015-12-17 12:15:13 -06:00
Lubomír Sedlář
a6b673dbdd Add option to specify non-failing stuff
There is a new configuration option that allows listing what can fail
without aborting the whole compose. So far, only buildinstall, createiso
and liveimages phases react to this option.

Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2015-12-17 11:15:47 +01:00
Lubomír Sedlář
0e237db5f6 Allow customizing image name and volume id
The computation of image name has been moved to a separate function.
This allowed simplification in how work dir for isos is computed, but
the result is not changed.

The live image phase has some special casing for names of RPM wrapped
ISOs. This is moved to the actual phase. Since this is (and has been)
undocumented, there should not be many users of this special case.

The documentation is updated to describe how image names and volume ids
are determined and how the process can be customized.

Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2015-12-14 14:39:21 +01:00
Lubomír Sedlář
719ec458f4 Fix notifier tests
Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2015-12-14 14:35:00 +01:00
Ralph Bean
f552eae2bf Publish a url instead of a file path.
Signed-off-by: Ralph Bean <rbean@redhat.com>
2015-12-09 17:07:43 -05:00
Ralph Bean
df0304095d Add 'topdir' to all fedmsg/notifier messages.
This will be useful for fedmsg recipients so they can construct URLs
back to the compose.  They may need to know the compose topdir to
distinguish between https://kojipkgs.fedoraproject.org/compose/rawhide/
and https://kojipkgs.fedoraproject.org/compose/f24/

Signed-off-by: Ralph Bean <rbean@redhat.com>
2015-12-09 14:58:20 -05:00
Dennis Gilmore
10a90f97b4 Merge #75 Start of development guide 2015-12-08 17:41:00 +00:00
Dennis Gilmore
81e90eb780 Merge #88 Resolve HEAD in ksurl to actual hash 2015-12-08 17:37:09 +00:00
Dennis Gilmore
f5862deea7 Merge #87 Add support for customizing lorax options 2015-12-08 17:36:18 +00:00
Ralph Bean
95761c69e1 Update fedmsg notification hook to use appropriate config.
Signed-off-by: Ralph Bean <rbean@redhat.com>
2015-12-08 12:30:16 -05:00
Dennis Gilmore
4b374278e4 we need to ensure that we send all the tasks to koji on the correct arch
Signed-off-by: Dennis Gilmore <dennis@ausil.us>
2015-12-08 09:04:32 -06:00
Lubomír Sedlář
fe95221f10 Resolve HEAD in ksurl to actual hash
When the image build configuration specifies kickstart URL as a HEAD of
a git repo, pungi now figures out what the actual hash of that commit is
and uses that hash instead. This might make logs clearer and should
prevent potential problems if someone pushes to that repo during
composing.

Documentation is updated to mention this.

Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2015-12-08 14:29:18 +01:00
Lubomír Sedlář
716b2d521a Add support for customizing lorax options
The config file can now specify options for lorax per variant and arch.
This is needed for Fedora to set x86_64 images as bootable on mac.

The old config option `buildinstall_upgrade_image` was deprecated, as
the same can be specified via new `lorax_options`.

Documentation and tests are updated.

Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2015-12-08 12:47:21 +01:00
Lubomír Sedlář
4a96e8e313 Run lorax in separate dirs for each variant
Lorax fails when run on an existing non-empty directory. This patch runs
it in separate subdirectiories base on variant. Running with
buildinstall should not be changed at all.

Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2015-12-07 09:45:33 +01:00
Dennis Gilmore
bdb1bcb35c Merge #84 Allow specifying --installpkgs for lorax 2015-12-04 19:41:28 +00:00
Dennis Gilmore
4a26b99a24 Merge #83 Fix recently discovered bugs 2015-12-04 19:39:49 +00:00
Dennis Gilmore
31fe85038b Merge #82 indentation fixs correcting dvd creation 2015-12-04 19:39:05 +00:00
Dennis Gilmore
77aca8a00a Merge #69 Move messaging into cli options and simplify it 2015-12-04 19:38:07 +00:00
Lubomír Sedlář
cdec198b6d Start lorax for each variant separately
The buildinstall phase now starts lorax for each variant separately.
Running with buildinstall should not be affected in any way.

Only variants of type=variant are considered. The side-effect of this is
that if an architecture is only used by variants of other types, lorax
will not be called at all.

Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2015-12-03 15:19:12 +01:00
Lubomír Sedlář
94f519d01c Update lorax wrapper to use --installpkgs
The lorax wrapper class now understands the --installpkgs argument and
can use it to pass multiple package names to the command.

There is a simple test to make sure the commands includes all specified
options. A bug is fixed where the bug URL would not be correctly
included.

Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2015-12-03 15:19:12 +01:00
Lubomír Sedlář
791448cc32 Allow specifying which packages to install in variants xml
This patch updates the variants DTD and parsing to allow specifying
multiple build install packages for each variant.

Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2015-12-03 15:19:12 +01:00
Lubomír Sedlář
cfda99e6fe Add basic tests for buildinstall phase
The test only checks that commands are created with correct arguments
and that a proper number of threads is started. There is no validation
for what the threads are actually doing.

Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2015-12-03 15:19:12 +01:00
Lubomír Sedlář
b6d9b5632e Fix generating checksum files
This patch modifies how checksums are stored - it uses BSD-style
checksums.

The filename with the checksum can now be customized depending on actual
compose run and metadata. This required adding another option to the
checksumming phase. Documentation is updated and includes example for
creating names used in Fedora.

Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2015-12-03 10:54:09 +01:00
Lubomír Sedlář
539736a11e Use lowercase hashed directories
On case-insensitive filesystems it is not such a good idea to have
directories that only differ in case. Packages should be always split
into lowercased directories.

The test data is modified to include some packages starting with
uppercase letters. The example in code can be verified by running
`nosetests --with-doctest`.

Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2015-12-03 09:08:15 +01:00
Dennis Gilmore
290f8f6540 indentation fixs correcting dvd creation
getting the commands together to run the iso creation process was
incorrectly moved when jigdo creation was made optional, patch fixes
https://pagure.io/pungi/issue/77

Signed-off-by: Dennis Gilmore <dennis@ausil.us>
2015-12-02 13:00:06 -06:00
Dennis Gilmore
e9699b7327 remove glibc32 from the runroot tasks
a workaround has been put in place on os's that need it. dnf errors
when a package is listed that is not available. breaking rawhide
composes.

Signed-off-by: Dennis Gilmore <dennis@ausil.us>
2015-12-02 08:51:18 -06:00
Dennis Gilmore
a2ace9e05c fix up the pungi-fedmesg-notification script name
fix up spec so that the package builds
2015-12-02 08:50:32 -06:00
Lubomír Sedlář
211bd6eef7 Add overview of Pungi to documentation
Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2015-12-02 10:28:11 +01:00
Dennis Gilmore
1ab4144dfb fix up the paths to the docs
Signed-off-by: Dennis Gilmore <dennis@ausil.us>
2015-12-01 11:27:24 -06:00
Dennis Gilmore
fd5d3ababb add a script to update the docs repo
Signed-off-by: Dennis Gilmore <dennis@ausil.us>
2015-12-01 11:24:11 -06:00
Lubomír Sedlář
bd8d814230 Move messaging into cli options
The messaging is not really part of compose settings. It is an
infrastructure part. As such, it should really be set up as part of
pungi invocation, not compose configuration.

The documentation is updated to reflect this. Some updates to the
documentation are done as well: listing messages about ISOs and minor
formatting updates.

The test_compose.sh script can now accept additional command line
options and pass them on to pungi-koji to simplify testing.

Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2015-11-27 10:35:08 +01:00
Lubomír Sedlář
ba396ea401 Extend contributing guide
Add information on setting up development environment, running tests and
generating documentation.

Also update .gitignore to list files that will be generated during
testing.

Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2015-11-27 10:27:43 +01:00
Lubomír Sedlář
496563aaef Load multilib configuration from local dir in development
It doesn't have to be installed during development.

Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2015-11-27 10:27:43 +01:00
Lubomír Sedlář
ba8ae15eb1 Allow running scripts with any python in PATH
Instead of hardcoding /usr/bin/python in shebangs, use /usr/bin/env.
This allows Pungi to work with dependencies installed in virtualenv.

Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2015-11-27 08:38:47 +01:00
Dennis Gilmore
6f00f20b3d Merge #68 Add support for sending messages 2015-11-25 14:56:51 +00:00
Lubomír Sedlář
7ce5c76673 Send more messages in createiso phase
When phase starts, a message is sent with list of images that are going
to be built. As each images is finished (or fails), another message
announces that status.

Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2015-11-25 15:46:50 +01:00
Lubomír Sedlář
066855a039 Add ability to send messages about progress
With this patch, Pungi can invoke an arbitrary command on various
moments of the compose process. The invoked command can the decide on
what message to send (and using what messaging system).

The actual command is specified in the config file.

There is a script provided that sends the messages via fedmsg.

The documentation is updated to have details about the new config option
as well as the interface for the messaging script.

Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2015-11-25 15:46:50 +01:00
Lubomír Sedlář
129e654690 Compute checksums in ImageChecksumPhase
The phase goes through all images declared in image manifest, computes
their checksums, stores them in appropriate files and updates the
manifest so that it includes the actual checksums.

The documentation contains details about new configuration options.

The test suite now needs Python's mock package.

Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2015-11-24 09:36:22 +01:00
Lubomír Sedlář
660c8bc2b3 Remove computing checksums from phases
These phases were computing checksums for images:

 * buildinstall
 * createiso
 * image_build
 * live_images
 * product_img

In each phase the checksummed thing would ultimately end-up in image
manifest.

Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2015-11-24 09:36:19 +01:00
Lubomír Sedlář
359eb444e5 Move image checksum collecting to separate phase
The checksums are still generated in the ImageBuild and CreatISO phases,
but collecting of them into single file is moved from pungi-koji script
into a separate phase.

Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2015-11-24 09:36:13 +01:00
Dennis Gilmore
5ff5ffc259 compose.config is in self
Signed-off-by: Dennis Gilmore <dennis@ausil.us>
2015-10-28 21:18:15 -05:00
Daniel Mach
3897671190 Merge #60 fix conditional deps (this can't be easily covered with unit tests; tested on huge package set using various in-place YUM hacks) 2015-09-10 09:38:09 -04:00
Jon Disnard
fd537e5070 Merge #61 make jigdo optional (iii) 2015-09-15 13:39:15 -05:00
Jon Disnard
656b081565 insignificant white space fix
Signed-off-by: Jon Disnard <jdisnard@redhat.com>
2015-09-15 13:39:15 -05:00
Jon Disnard
9798454cb3 Upodate config docs for jigdo
Signed-off-by: Jon Disnard <jdisnard@redhat.com>
2015-09-15 13:37:27 -05:00
Jon Disnard
2114369e9c Default True for configurable jigdo ISOs.
Signed-off-by: Jon Disnard <jdisnard@redhat.com>
2015-09-15 13:23:54 -05:00
Daniel Mach
15811107bb gather: Check if txmbr.isDep is set for conditional deps. 2015-09-10 09:38:09 -04:00
Tomas Mlcoch
5c8694b286 Merge #57 Initialize phases in their usage order 2015-09-09 08:00:21 -04:00
Tomas Mlcoch
ecc6b0f62a Initialize phases in their usage order 2015-09-09 08:00:21 -04:00
Tomas Mlcoch
36fff71059 Merge #56 doc/contributing.rst update 2015-09-09 03:58:30 -04:00
Tomas Mlcoch
4d93221005 Add missing config check for phases: createrepo, extrafiles, liveimages and imate_build 2015-09-10 07:12:08 -04:00
Tomas Mlcoch
1d97ce5ea1 Add live_images option to live_images phase 2015-09-10 07:10:41 -04:00
Tomas Mlcoch
b4fd280d80 Fix expected type of createrepo_checksum config option 2015-09-10 07:09:37 -04:00
Tomas Mlcoch
291c509c2f Doc: Replace fetch & fetch tags & merge combo with pull --rebase
$ git pull --rebase upstream master
will work also when there are commits on master branch - it will
just rebase the changes seamlessly in opposite to git merge.

Moreover by using git pull --rebase we will save two calls of git.
2015-09-09 03:58:30 -04:00
Tomas Mlcoch
3df5a11a89 Fix KojiWrapper initialization in live_images phase 2015-09-09 03:40:30 -04:00
Tomas Mlcoch
02e55b67b3 Remove createiso phase's dependency on pkgset_koji_url config option 2015-09-09 03:40:29 -04:00
Dennis Gilmore
2599a42a14 4.0.3 release
Signed-off-by: Dennis Gilmore <dennis@ausil.us>
2015-09-08 22:06:45 -05:00
Lubos Kocman
fd64bba4dd Merge #54 fix log_info for image_build (fails if image_build is skipped) 2015-09-07 15:41:27 +00:00
Lubos Kocman
3efd29e465 image_build: self.log_info -> self.compose.log_info 2015-09-07 15:41:27 +00:00
Dennis Gilmore
da0405a0f5 Revert "Added params needed for Atomic compose to LoraxWrapper"
This reverts commit 919a4fc619.
2015-09-04 12:12:36 -05:00
Dennis Gilmore
d982cd585f Revert "fix up if/elif in _handle_optional_arg_type"
This reverts commit 1373fe5178.
2015-09-04 12:12:28 -05:00
Jon Disnard
6e773f8676 Disable jigdo by default, saves a lot of time.
Signed-off-by: Jon Disnard <jdisnard@redhat.com>
2015-09-01 17:14:46 -05:00
Lubos Kocman
abb2ff1584 live_images: replace hardcoded path substition with translate_path() call
Signed-off-by: Lubos Kocman <lkocman@redhat.com>
2015-09-01 08:23:42 +00:00
Lubos Kocman
158d1834a6 live_images fix reference from koji to koji_wrapper
Signed-off-by: Lubos Kocman <lkocman@redhat.com>
2015-09-01 08:23:24 +00:00
Lubos Kocman
8e90a2a32a Add image-build support
Signed-off-by: Lubos Kocman <lkocman@redhat.com>
2015-09-01 08:03:34 +00:00
Lubos Kocman
4fb20198db Add translate path support. Useful for passing pungi repos to image-build
Signed-off-by: Lubos Kocman <lkocman@redhat.com>
2015-09-01 08:01:37 +00:00
Lubos Kocman
449b4e4c87 import duplicate import of errno from buildinstall
Signed-off-by: Lubos Kocman <lkocman@redhat.com>
2015-08-31 22:51:22 -05:00
Lubos Kocman
831352b2ea handle openning missing images.json (image-less compose re-run)
Signed-off-by: Lubos Kocman <lkocman@redhat.com>
2015-08-31 22:51:22 -05:00
Lubos Kocman
0e18ffcf31 compose: Add compose_label_major_version(). 2015-08-25 08:20:52 -04:00
Pavol Babincak
853c27d1be pungi-koji: Don't print traceback if error occurred.
If compose directory was created and logger setup properly traceback is
written in traceback.log. Otherwise traceback is printed on stdout.
2015-08-25 08:11:14 -04:00
Tomas Kopecek
9235844529 More detailed message for unsigned rpms. 2015-08-25 08:07:05 -04:00
Daniel Mach
ba9df6dc5e New config option: product_type (default is 'ga'); Set to 'updates' for updates composes. 2015-08-25 08:04:06 -04:00
Tomas Mlcoch
219af0c904 kojiwrapper: Add get_signed_wrapped_rpms_paths() and get_build_nvrs() methods. 2015-08-25 08:01:02 -04:00
Tomas Mlcoch
d9d9db3e5d live_images: Copy built wrapped rpms from koji into compose. 2015-08-25 07:57:51 -04:00
Tomas Mlcoch
df1415b3f5 kojiwrapper: Add get_wrapped_rpm_path() function. 2015-08-25 07:57:40 -04:00
Tomas Mlcoch
44ebf5eedc live_images: Allow custom name prefix for live ISOs. 2015-08-25 07:49:29 -04:00
Tomas Mlcoch
39c073abf9 Do not require enabled runroot option for live_images phase. 2015-08-25 07:48:19 -04:00
Tomas Mlcoch
ba39435bf6 Support for rpm wrapped live images. 2015-08-25 07:42:05 -04:00
Tomas Mlcoch
ea751bb119 Remove redundant line in variants wrapper. 2015-08-25 07:40:11 -04:00
Adam Miller
05e9bbab9c Merge #36 Add params needed for Atomic compose to LoraxWrapper 2015-08-18 15:50:16 -05:00
Adam Miller
1373fe5178 fix up if/elif in _handle_optional_arg_type 2015-08-18 15:50:16 -05:00
Adam Miller
919a4fc619 Added params needed for Atomic compose to LoraxWrapper
Add add_template, add_template_var, add_arch_template, and
add_arch_template_var to the call for lorax.get_lorax_cmd for the Atomic
ISO composes.

Remove duplicate if statement for add_template_var in lorax wrapper
2015-08-18 15:47:41 -05:00
Daniel Mach
1089847cd7 Merge #24 Fix empty repodata when hash directories were enabled. 2015-07-24 18:18:03 -04:00
Daniel Mach
5238e1cc99 createrepo: Fix empty repodata when hash directories were enabled. 2015-07-24 18:18:03 -04:00
Dennis Gilmore
8b1d5ab9b2 4.0.2 release
Signed-off-by: Dennis Gilmore <dennis@ausil.us>
2015-07-24 12:39:14 -05:00
Daniel Mach
19a7394974 Fix treeinfo checksums. 2015-07-24 10:49:28 -04:00
Daniel Mach
5432d3fa74 Merge #23 fix treeinfo checksums 2015-07-24 10:49:28 -04:00
Dennis Gilmore
4dc7079bd2 add basic setup for making arm iso's
Signed-off-by: Dennis Gilmore <dennis@ausil.us>
2015-07-24 07:47:29 -05:00
Daniel Mach
0d8ad9a111 gather: Implement hashed directories.
Set 'hashed_directories = True' config option to enable the feature.
2015-07-24 04:40:55 -04:00
Daniel Mach
1f313b39ad createiso: Add createiso_skip options to skip createiso on any variant/arch. 2015-07-23 10:58:35 -04:00
Daniel Mach
b85307c683 Fix buildinstall for armhfp.
armhfp is not a valid RPM arch, it's only a tree arch or basearch.
Lorax requires valid RPM arch as --buildarch.
2015-07-22 13:00:36 -04:00
Daniel Mach
63338a9689 Fix and document productimg phase. 2015-07-22 12:57:39 -04:00
Daniel Mach
e80879a4fe Add armhfp arch tests. 2015-07-22 08:27:56 -04:00
Daniel Mach
ca5aeb3106 Document configuration options. 2015-07-10 07:47:29 -04:00
Daniel Mach
63c631a99b Add dependency of 'runroot' config option on 'koji_profile'. 2015-07-10 07:31:57 -04:00
Daniel Mach
72302bd98e Rename product_* to release_*.
CHANGE: Rename product_* config options to release_* for consistency with productmd.
ACTION: Rename product_name, product_short, product_version, product_is_layered to release_* in config files.
        Rename //variant/product to //variant/release in variants XML.
2015-07-09 06:58:30 -04:00
Daniel Mach
afa05021f0 Implement koji profiles.
CHANGE: pkgset_koji_url and pkgset_koji_path_prefix config options replaced with koji_profile.
ACTION: Add 'koji_profile = "<profile_name>"' (use "koji" for Fedora) to config files.
        You can safely remove and pkgset_koji_url and pkgset_koji_path_prefix from config files.
2015-07-09 04:57:27 -04:00
Daniel Mach
017bc76093 Drop repoclosure-%arch tests.
These tests frequently report false-positives,
because package set may contain broken dependencies,
while compose doesn't.
Removing the tests will also reduce compose time a bit.
2015-07-08 09:08:45 -04:00
Daniel Mach
6286e87d3b Config option create_optional_isos now defaults to False.
CHANGE: create_optional_isos config option now defaults to False.
ACTION: You can safely remove 'create_optional_isos = False' from config files.
2015-07-08 09:00:30 -04:00
Daniel Mach
90918dc34d Change createrepo config options defaults.
CHANGE: createrepo_c is config option now defaults to True.
ACTION: You can safely remove 'createrepo_c = True' from config files.
        Set 'createrepo_c = False' if you need legacy createrepo.

CHANGE: createrepo_checksum config option is now mandatory.
ACTION: Add 'createrepo_checksum = "sha256"' (or "sha") to config files.
2015-07-08 08:57:50 -04:00
Daniel Mach
a3d46f5393 Rewrite documentation to Sphinx. 2015-07-02 09:18:49 -04:00
Daniel Mach
81e935fe0e Fix test data, improve Makefile.
Previous test data was insufficient for proper testing.
Test compose runs and depsolving tests require precisely
set NVRs, dependencies, sub-packages, etc.
Using rpmfluff for these would be an overkill, it's better
to create RPMs directly from specs.
2015-06-25 08:02:57 -04:00
Daniel Mach
51cdd94379 Update GPL to latest version from https://www.gnu.org/licenses/gpl-2.0.txt 2015-06-25 07:50:03 -04:00
Dennis Gilmore
b53f2ba9bf 4.0.1 release
Signed-off-by: Dennis Gilmore <dennis@ausil.us>
2015-06-11 22:12:58 -05:00
Dennis Gilmore
11a80ddbda wrap check for selinux enforcing in a try except
Signed-off-by: Dennis Gilmore <dennis@ausil.us>
2015-06-11 22:04:35 -05:00
Adam Miller
e8f4b7334e pull in gather.py patches from dmach for test compose 2015-06-10 10:03:57 -05:00
Adam Miller
793e9f3d06 Add some basic testing, dummy rpm creation, and a testing README 2015-06-10 09:53:31 -05:00
Lubos Kocman
7d714e49f3 pungi-koji: use logger instead of print when it's available 2015-06-07 18:28:15 +00:00
Lubos Kocman
e3e60c75a2 fix incorrect reference to variable 'product_is_layered' 2015-06-07 18:28:08 +00:00
Lubos Kocman
008d80186e pungi-koji: fix bad module path to verify_label() 2015-06-07 18:27:58 +00:00
Dennis Gilmore
0da05a8682 update the package Requires to ensure we have everything installed to run pungi-koji
Signed-off-by: Dennis Gilmore <dennis@ausil.us>
2015-06-07 10:57:26 -05:00
Dennis Gilmore
913494d889 update the package to be installed for productmd to python-productmd
Signed-off-by: Dennis Gilmore <dennis@ausil.us>
2015-06-07 10:55:10 -05:00
Dennis Gilmore
ef7c78cd38 prep for 4.0-0.9 snapshot release
Signed-off-by: Dennis Gilmore <dennis@ausil.us>
2015-06-07 10:31:55 -05:00
Peter Robinson
ac24cfa1f9 update docs now devel-4-pungi is merged to master, minor spelling fixes 2015-06-07 00:28:28 +01:00
Daniel Mach
fd8cd62e79 Fix remaining productmd issues. 2015-06-06 13:46:20 -05:00
Daniel Mach
6b34cb98d2 Revert "refactor metadata.py to use productmd's compose.dump for composeinfo"
This reverts commit 40b8ccb3acdc7dd869e4aa32f1ad672ff01bd0ea.
2015-06-06 13:46:19 -05:00
Daniel Mach
977ad66995 Fix LoraxTreeInfo class inheritance. 2015-06-06 13:46:19 -05:00
Daniel Mach
ec7424395d Fix pungi -> pungi_wrapper namespace issue. 2015-06-06 13:46:19 -05:00
Adam Miller
f633c04497 fix arg order for checksums.add 2015-06-06 13:46:19 -05:00
Adam Miller
cc48f6522a update for productmd checksums.add to TreeInfo 2015-06-06 13:46:19 -05:00
Adam Miller
989b018090 fix product -> release namespace change for productmd 2015-06-06 13:46:19 -05:00
Adam Miller
8d50f89e6e update arch manifest.add config order for productmd api call 2015-06-06 13:46:19 -05:00
Adam Miller
654ac5fbaa update for new productmd named args to rpms 2015-06-06 13:46:19 -05:00
Adam Miller
dc9cfffbb9 fix pungi vs pungi_wrapper namespacing in method_deps.py 2015-06-06 13:46:19 -05:00
Adam Miller
f85fabba8f add createrepo_c Requires to pungi.spec 2015-06-06 13:46:19 -05:00
Adam Miller
e71f8026fc add comps_filter 2015-06-06 13:45:48 -05:00
Adam Miller
59ca987233 refactor metadata.py to use productmd's compose.dump for composeinfo
instead of pungi compose_to_composeinfo
2015-06-06 13:45:48 -05:00
Adam Miller
5fa5fcdd06 Update compose, phases{buildinstall,createiso,gather/__ini__} to use correct productmd API calls 2015-06-06 13:45:48 -05:00
Luke Macken
4e8e1d4d90 Use libselinux-python instead of subprocess 2015-06-05 10:19:39 -04:00
Adam Miller
37b7a23505 Add README for contributors 2015-06-04 08:42:30 -05:00
Dennis Gilmore
ff77a9209c - fix up bad += from early test of implementing different iso labels based on
if there is a variant or not (dennis)

Signed-off-by: Dennis Gilmore <dennis@ausil.us>
2015-05-20 16:38:26 -05:00
Dennis Gilmore
1d87fca380 fix up bad += from early test of implementing different iso labels
based on if there is a variant or not

Signed-off-by: Dennis Gilmore <dennis@ausil.us>
2015-05-20 16:33:54 -05:00
Dennis Gilmore
dc1be3eecc prep new snapshot 4.0-0.7 release 2015-05-20 15:23:17 -05:00
Dennis Gilmore
ca17987de9 make sure we treat the isfinal option as a boolean when fetching it
It will make sure that we only pass --isfinal to lorax when it is
passed in on the CLI

Signed-off-by: Dennis Gilmore <dennis@ausil.us>
2015-05-20 15:14:39 -05:00
Dennis Gilmore
f5eaa7326f if there is a variant use it in the volume id and shorten it. this
will make each producst install tree have different volume ids for
their isos

Signed-off-by: Dennis Gilmore <dennis@ausil.us>
2015-05-20 15:14:00 -05:00
Dennis Gilmore
b6825f3471 fix up productmd import in the executable
Signed-off-by: Dennis Gilmore <dennis@ausil.us>
2015-04-24 17:58:59 -05:00
Dennis Gilmore
771ed2efcb fixup productmd imports for changes with open sourcing
Signed-off-by: Dennis Gilmore <dennis@ausil.us>
2015-04-24 17:55:56 -05:00
Dennis Gilmore
f828850466 tell the scm wrapper to do an absolute import otherwise we hit a
circular dep issue and things go wonky

Signed-off-by: Dennis Gilmore <dennis@ausil.us>
2015-04-24 17:51:28 -05:00
Dennis Gilmore
eba5a8bd96 include the dtd files in /usr/share/pungi
Signed-off-by: Dennis Gilmore <dennis@ausil.us>
2015-03-14 15:03:32 -05:00
Dennis Gilmore
5197fed16a add missing ) causing a syntax error
Signed-off-by: Dennis Gilmore <dennis@ausil.us>
2015-03-14 14:20:31 -05:00
Dennis Gilmore
d337c34b2a fix up the productmd imports to import the function from the common module
Signed-off-by: Dennis Gilmore <dennis@ausil.us>
2015-03-14 12:21:27 -05:00
Dennis Gilmore
ad18e21d1a fix up typo in getting arch for the lorax log file
Signed-off-by: Dennis Gilmore <dennis@ausil.us>
2015-03-14 12:20:44 -05:00
Dennis Gilmore
012c749cdb fix up Requires on productmd, it needed renaming to meeting fedora
naming guidelines
2015-03-14 11:58:51 -05:00
Dennis Gilmore
18d4d2ecf8 fix up the pungi logging by putting the arch in the log file name 2015-03-12 17:29:59 -05:00
Dennis Gilmore
07e90f0f96 change pypungi imports to pungi 2015-03-12 16:12:38 -05:00
Dennis Gilmore
fdc7901127 spec file cleanups 2015-03-12 16:09:23 -05:00
Dennis Gilmore
a3158ec144 rename binaries
rename the pungi binary to pungi-koji since it does is tasks in koji
rename pungi-gather to pungi as it is the standalone old pungi binary

there is scripts that expect pungi to be the old pungi, the new binary
is not yet in use, pungi-koji semes to make sense, open to better ideas
2015-03-12 13:15:29 -05:00
Brian C. Lane
320724ed98 Add the option to pass a custom path for the multilib config files
The default is /usr/share/pungi/multilib/, pass --multilibconf to
override this.

This also adds multilib.init() so that an import of multilib doesn't
immediately setup the classes.

(cherry picked from commit 234524296fd53871aed64690cf6a7d5849ca154a)
2015-03-12 11:40:23 -05:00
Brian C. Lane
13526d1c49 Call lorax as a process not a library
Doing this allows lorax to move to DNF (and Python3) without needing to
wait for pungi to be updated.
2015-03-12 11:29:58 -05:00
Brian C. Lane
9947c7e0cd Close child fds when using subprocess 2015-03-12 11:13:51 -05:00
Dennis Gilmore
dfd0cc947b fixup setup.py and MANIFEST.in to make a useable tarball 2015-03-12 11:03:48 -05:00
Dennis Gilmore
64b6c8065c switch to BSD style hashes for the iso checksums 2015-03-12 10:16:09 -05:00
Dennis Gilmore
0633eb29d3 refactor to get better data into .treeinfo
for https://fedorahosted.org/rel-eng/ticket/6008 refacter how we deal
with the data that feeds into .treeinfo
Deprecate --name for --family
Deprecate --flavor for --variant
rather than using --name as the iso base name use the value of
family if there is a variant add it with a - as the seperator
2015-03-12 10:15:55 -05:00
Daniel Mach
f116d9384f Initial code merge for Pungi 4.0. 2015-02-10 08:19:34 -05:00
Daniel Mach
f5c6d44000 Initial changes for Pungi 4.0. 2015-02-10 06:47:16 -05:00
Connie Sieh
274236a3f3 Add --nomacboot option
sotime an OS would want to disable booting on mac machines. For
instance when buildinga RHEL clone where there is no hfs support.
The option disables mac support
2015-01-16 12:29:59 -06:00
Dennis Gilmore
fedc440159 3.13 release 2014-12-12 20:21:03 -06:00
Brian C. Lane
c4dd0e75ed Add support for --installpkgs
This allows the user to add specific packages, or package globs, to the
installer's root via lorax. For example, to build a server product with
the correct product.img you would pass --installpkgs
fedora-productimg-server

This removes the need for the kickstart to use --exclude on the repo
lines and makes it more explicit as to what is being built. This command
mirrors the same command in lorax.
2014-12-09 11:52:53 -06:00
Brian C. Lane
2221f66ff5 Add a cmdline option to set the lorax config file
Add --lorax-conf which will be used to point lorax to a INI style
config file. Useful for running things from a git checkout instead of
installed system.
2014-12-09 11:52:53 -06:00
Brian C. Lane
1bd069683c Add python-lockfile requires and drop python-devel 2014-12-09 11:52:53 -06:00
Peter Jones
33ebc4e11f Make our OS iso bootable on aarch64.
Aarch64 needs to get the el torito image generation code x86 has for
UEFI as well.

Signed-off-by: Peter Jones <pjones@redhat.com>
2014-12-09 11:51:41 -06:00
Dennis Gilmore
d865c94330 fix up typo 2014-12-09 11:51:30 -06:00
Dennis Gilmore
add538d7b4 replace tabs with spaces 2014-09-19 15:28:05 -05:00
Dennis Gilmore
21021f521a 3.12 release 2014-09-11 11:09:13 -05:00
Mark Hamzy
e3c8c3b7e0 Remove magic parameter to mkisofs
Instead of supplying a backlevel magic file, do not pass the file in at all.
2014-09-11 10:53:33 -05:00
Pat Riehecky
55c00f6d60 Added option for setting release note files 2014-08-22 14:41:41 -05:00
Dennis Gilmore
1175551e2c 3.11 release3.11 release3.11 release3.11 release3.11 release3.11 release3.11 release3.11 release3.11 release3.11 release3.11 release 2014-07-31 06:04:25 -05:00
Dennis Gilmore
6a26176c23 make sure that the dvd/cd is using the shortened volumeid 2014-07-31 06:02:12 -05:00
Dennis Gilmore
2bb948fce7 3.10 release 2014-07-31 04:25:26 -05:00
Dennis Gilmore
6177cf6f88 fix up volume shortening substituions to actually work 2014-07-31 04:23:17 -05:00
Dennis Gilmore
ea8f3909ac 3.09 release 2014-07-30 11:36:11 -05:00
Dennis Gilmore
76ba16d4a6 implement nameing scheme from
https://fedoraproject.org/wiki/User:Adamwill/Draft_fedora_image_naming_policy
2014-07-30 11:25:44 -05:00
Dennis Gilmore
a5aa03f58c implement shortening of the volumeid which has a 32 character limit 2014-07-30 11:25:44 -05:00
Dennis Gilmore
af9f7520f4 3.08 release 2014-07-23 11:19:20 -05:00
Dennis Gilmore
5c9d28dc9f fix up some issues with --no-dvd and --workbasedir 2014-07-23 07:43:14 -05:00
Dennis Gilmore
9d339e774b 3.07 release 2014-07-20 12:04:58 -05:00
Dennis Gilmore
a313fa8214 add a flag to turn off making install DVD's 2014-07-18 14:30:52 -05:00
Dennis Gilmore
6820ad7c23 3.06 release 2014-07-14 15:42:54 -05:00
Dennis Gilmore
f57a4ac5ee allow the base work directory to be configurable. 2014-07-14 15:39:57 -05:00
Dennis Gilmore
fb3d4ca185 3.05 release 2014-07-09 01:27:55 -05:00
Peter Jones
170ca88549 Don't emit media labels with spaces in them.
Spaces cause various bugs like #923374 and #855849 , and it would be
better if we just didn't use them.

Note that there's a corresponding lorax change to go with this.

Signed-off-by: Peter Jones <pjones@redhat.com>
2014-07-08 15:49:41 -05:00
Dennis Gilmore
1ba64d6e6b 3.04 release 2014-04-29 16:29:34 -05:00
Ralph Bean
224463030b Use a lockfile around things that modify the cachedir. 2014-04-29 13:51:15 -05:00
Ralph Bean
94235b093e Improve logging for missing srpms. 2014-04-29 13:50:36 -05:00
Dennis Gilmore
6ceadebaa9 honour the --nosource option
Patch by Barry Scott https://lists.fedoraproject.org/pipermail/buildsys/2014-January/004238.html
2014-04-29 13:36:03 -05:00
Mark Hamzy
76c8941456 support ppc64le in pungi
Add support for the ppc64le architecture in pungi.
2014-04-29 13:29:50 -05:00
Ralph Bean
9acb9c58c5 Add configurable compression type to pungi (default to xz)
This is for https://fedorahosted.org/rel-eng/ticket/5362#comment:17
2014-04-29 13:28:31 -05:00
Dennis Gilmore
293143d8f1 revert to the old way of doing versioning as the change in 3.01 did not work 2013-10-31 20:22:35 -05:00
Dennis Gilmore
e7d19b70ee 3.02 release 2013-10-31 19:05:59 -05:00
Dennis Gilmore
23977a90de fix typo in call to __version__ 2013-10-31 18:58:45 -05:00
Daniel Mach
cdf9916906 3.01 release 2013-10-27 15:44:10 -04:00
Daniel Mach
03efbfd62b Add 'make log' command to print changelog for spec. 2013-10-27 15:44:09 -04:00
Daniel Mach
8b1c2433c9 Implement %prepopulate config section as an additional package input. 2013-10-27 15:44:09 -04:00
Daniel Mach
43c9185323 Don't automatically apply fulltree on input multilib packages. 2013-10-27 15:44:09 -04:00
Daniel Mach
cb6f1dbe17 Implement %multilib-blacklist and %multilib-whitelist config sections. 2013-10-27 15:44:09 -04:00
Daniel Mach
e1f1231bb1 Turn off fulltree for multilib packages. 2013-10-27 15:44:09 -04:00
Daniel Mach
9a09cf9df3 Return package flags: input, fulltree-exclude, langpack, multilib, fulltree 2013-10-27 15:44:09 -04:00
Daniel Mach
2f0b9fc616 Exclude srpms from conditional deps. 2013-10-27 15:44:09 -04:00
Daniel Mach
754a1bb59b Improve greedy methods: none, all, build. 2013-10-27 15:44:09 -04:00
Daniel Mach
3b71b8b457 Add .gitignore. 2013-10-27 15:44:09 -04:00
Daniel Mach
448cb84305 Add 'yaboot' multilib method.
mash commit: d84a71415c6a79c2587d320b0ce6e9eb5251c942
2013-10-27 15:44:08 -04:00
Daniel Mach
e1f71d828d Drop pulseaudio-utils from runtime whitelist
mash commit: f96209ff9daa6d5d16efa13d76c8779b95ec7a61
2013-10-27 15:44:08 -04:00
Daniel Mach
663ea07c08 Remove packages which are in lookaside repos from regular repos.
This makes depsolving more deterministic and keeps resolved package set minimal.
2013-10-27 15:44:08 -04:00
Daniel Mach
5dc0913ef1 Print repoid to make clear from which repo a package came. 2013-10-27 15:44:08 -04:00
Daniel Mach
c363b7242a Don't pull conditional deps in when --nodeps is used. 2013-10-27 15:44:08 -04:00
Daniel Mach
6a68c139c8 Multilib fix - consider only *.so* libs which are also listed in Provides. 2013-10-27 15:44:08 -04:00
Daniel Mach
14ffefd376 Fix --nodeps by setting Pungi.is_resolve_deps according to config. 2013-10-27 15:44:08 -04:00
Daniel Mach
f9f9e6a151 Add test_arch.py. 2013-10-27 15:44:08 -04:00
Dennis Gilmore
e04fcc4441 remove if that breaks makefiles 2013-08-20 11:42:51 -05:00
Dennis Gilmore
09ebeccd4d 3.00 release 2013-08-20 11:41:56 -05:00
Dennis Gilmore
44cd5ff806 fixup things to use new arch module 2013-08-20 11:33:44 -05:00
Daniel Mach
3b6146abc7 Drop dependency on anaconda. Don't depend on lorax and repoview on RHEL. 2013-08-20 11:22:24 -05:00
Daniel Mach
cb45400298 Add --nodeps option which turns dependency resolving off. 2013-08-20 11:22:24 -05:00
Daniel Mach
854899344c Implement %fulltree-excludes kickstart section to exclude packages from --fulltree processing. 2013-08-20 11:22:24 -05:00
Daniel Mach
17221a33f3 Major rewrite to gain performance boost in nogreedy mode. 2013-08-20 11:22:24 -05:00
Daniel Mach
60803f32f3 Fix getting SRPMs for nosrc arch. 2013-08-20 11:22:24 -05:00
Daniel Mach
9776e3cd9d Don't pull @core and @base groups by default. 2013-08-20 11:22:24 -05:00
Daniel Mach
a9581e2056 Stop pulling unnecessary multilib packages on completing package set (fulltree). 2013-08-20 11:22:24 -05:00
Daniel Mach
30c0f358d9 Resolve multilib packages. Controlled by the --multilib option. 2013-08-20 11:22:24 -05:00
Daniel Mach
91f70cbb43 Handle a special case, when system-release virtual provide is specified in the greedy mode. 2013-08-20 11:22:24 -05:00
Daniel Mach
bd35d6bc03 Support for multilib packages (pattern: <package_name>.+) 2013-08-20 11:20:29 -05:00
Daniel Mach
c047fe570b Improve debuginfo lookup. 2013-08-20 11:20:29 -05:00
Daniel Mach
5451453f6f Refactor how pungi works with arches. 2013-08-20 11:20:04 -05:00
Daniel Mach
c076de2e9f Lookaside repo support. 2013-08-09 10:21:09 -05:00
Dennis Gilmore
2d2a3e8083 make sure mac support is only enabled on x86 2013-08-08 09:32:05 -05:00
Daniel Mach
cd75bc4875 Add langpacks support. 2013-05-03 20:09:33 -05:00
Daniel Mach
5069eb8b09 Check each package's deps only once. 2013-05-03 20:09:14 -05:00
Daniel Mach
77dea0ec92 Suppress duplicate depsolving log messages. 2013-05-03 20:08:56 -05:00
Daniel Mach
dd6a68eb7c Speed depsolving up by providing pre-computed pkg_refs.
Requires: yum >= 3.4.3-28
2013-05-03 20:08:36 -05:00
Daniel Mach
50c1d46c7e Delete the 'anaruntime' variable, it's no longer needed. 2013-05-03 20:07:00 -05:00
Dennis Gilmore
49b530b1f8 make sure deltarpm is disabled 2013-02-28 10:38:19 -06:00
Dennis Gilmore
eea89a2b78 remove sparc support 2013-02-25 06:04:50 -06:00
Dennis Gilmore
4ae5a8c18b dont use uname when working out the arch it breaks arm basearch detection 2012-12-22 02:23:42 -06:00
Dennis Gilmore
d978ca3fa8 2.13 release 2012-12-21 14:57:01 -06:00
Dennis Gilmore
45bb97ba97 get ppc images for ppc and ppc64 bz#888517 2012-12-21 14:55:16 -06:00
Dennis Gilmore
b7c6c80949 reset the arch to ppc64 when making lorax calls so that the iso will run everywhere 2012-12-21 09:25:26 -06:00
Dennis Gilmore
8d54c4be1b there is no point making isos on arm, lets log and move on. 2012-12-21 09:23:14 -06:00
Dennis Gilmore
6cbf093f8e Only include groups that are specified in the kickstart. Remove any environments that use groups not on the media.
patch from notting http://lists.fedoraproject.org/pipermail/buildsys/2012-December/004033.html
include langpack in comps
2012-12-20 22:06:16 -06:00
Dennis Gilmore
feadeaadb8 We need to reset the arch to ppc64p7 for both ppc and ppc64 2012-09-22 08:51:52 -05:00
Dennis Gilmore
ee88779bb6 prep 2.12 release 2012-08-31 00:43:51 -05:00
Dennis Gilmore
5cd88a47e6 add 32 bit arm base arches 2012-08-31 00:41:12 -05:00
Dennis Gilmore
4b7685daaa ppc fixes for bz#849731 also set the arch to ppc64p7 so that power7 optimised rpms get included on the install disk 2012-08-31 00:39:48 -05:00
Dennis Gilmore
2d37fb2fa9 do not run isohybrid on the source iso it doesnt work so well 2012-05-25 09:31:01 -05:00
Dennis Gilmore
989462bf86 don't include s390 packages when composing s390x image
Signed-off-by: Dan Horák <dan@danny.cz>
2012-04-16 15:54:08 -05:00
Dennis Gilmore
cd1ec8f6ed Prep 2.11 release 2012-04-16 14:59:45 -05:00
Dennis Gilmore
8ed9aafb78 fix up doing hashed directories for Packages 2012-04-16 14:54:24 -05:00
Daniel Mach
72b9333abd Run yumbase.arch.setup_arch() to set arch correctly. 2012-04-03 10:17:07 -05:00
Daniel Mach
aa401cc49b Find %name-debuginfo-common-%arch debuginfo files. 2012-04-03 10:13:15 -05:00
Daniel Mach
9d7f82d91a Handle excludes during depsolving.
Prefiously, packages were excluded from the initial package list,
but could have been pulled in during depsolving. This patch excludes
selected packages for good. Supported syntax is -$name or -%name.%arch
including wildchars.
2012-03-12 10:50:59 -05:00
Daniel Mach
8ccc24e106 Improve --nogreedy behaviour to select only the best packages for target arch. Also exact package arch can be selected by specifying $name.$arch in the config file. 2012-03-12 10:50:59 -05:00
Daniel Mach
80454a89b2 Revamp optparse error handling. 2012-03-12 10:50:59 -05:00
Daniel Mach
1623bbe936 Implement arch override.
Using the --arch option, it is possible to run depsolving
(Gather stage) on any host regardless the architecture.
2012-03-12 10:50:59 -05:00
Daniel Mach
83a22bd5ea Add --full-archlist option to include i686 packages in x86_64 trees.
Pungi limits x86_64 package architectures to x86_64 and noarch only,
which renders depsolving in multiarch repos impossible.
This patch adds --full-archlist option which removes the limitation.
2012-03-12 10:50:59 -05:00
Tomas Mlcoch
44cda03261 Fix indentation. 2012-03-12 10:50:58 -05:00
Tomas Mlcoch
cd9797de71 Add --norelnotes option to skip getting release notes. 2012-03-12 10:50:58 -05:00
Daniel Mach
249efe1d75 Add --nodownload option to print packages instead of downloading them.
This allows other tools to use Pungi for depsolving and process
packages in their own way.
2012-03-12 10:50:58 -05:00
Dennis Gilmore
9cf7418cd5 Build in the Mac el-torito if present
Patch from Matthew Garrett <mjg@redhat.com>
2012-03-12 10:50:20 -05:00
Dennis Gilmore
0857d30f82 prep 2.10 release 2012-02-09 18:06:46 -06:00
Dennis Gilmore
7ab8ee1443 set the default for nohash to False 2012-02-09 14:44:37 -06:00
Dennis Gilmore
45964282af hash the Packages tree by default, adding a --nohash option for old style layout 2012-02-09 09:12:55 -06:00
Will Woods
32eacf5eec Use a predictable ISO Volume ID (#732298)
Since the new lorax branch needs to know the iso Volume ID to be able to
boot, we need to make sure we're using the same Volume ID that lorax
sets up the bootloaders to expect.
2011-10-29 13:26:44 -05:00
Will Woods
0ff7275349 Fix DVD building on ppc64
ppc64 systems used to have arch == 'ppc', so pungi was only checking to
see if arch == 'ppc'. Now that ppc64 is separate from ppc, we need to
check if arch.startswith('ppc') instead.
2011-10-29 13:26:44 -05:00
Dennis Gilmore
59ff9f9068 prep for 2.9 release 2011-07-27 11:48:13 -05:00
Dennis Gilmore
e70fa6c60f lorax and anaconda now use isfinal, it simplifies things for us. 2011-07-27 11:40:57 -05:00
Jesse Keating
e215694a6b Prep for 2.8 release 2011-07-18 15:26:22 -07:00
Jesse Keating
d6490ebf6e Always re-init the yum object (#717089) 2011-07-18 15:24:17 -07:00
Tom "spot" Callaway
7e65e60fc6 proper isohybrid support 2011-05-26 10:09:00 -05:00
Dennis Gilmore
76c3cd9309 bump to 2.7 2011-05-26 10:08:43 -05:00
Dennis Gilmore
ebedace49d 2.7 release 2011-05-16 18:04:03 -05:00
Dennis Gilmore
80120d1e53 add commandline option --isfinal for ga releases. defaulting to a beta
for https://bugzilla.redhat.com/show_bug.cgi?id=703815
2011-05-16 17:59:23 -05:00
Jesse Keating
6e05f8162f New release 2011-04-29 01:45:29 -07:00
Jesse Keating
0c8b9d268e Only init yum if we haven't already
And fix where the import goes
2011-04-29 01:45:28 -07:00
Jesse Keating
e3a59fe484 Add the repo from topdir to our yumobject for lorax.
This allows lorax to make use of the local low cost repo to fetch
packages from.  Buildinstall would previously get passed this repo as a
runtime argument.
2011-04-29 01:45:28 -07:00
Jesse Keating
7a8ab8817a Add a function for adding repos to the yum object.
This allows us to re-use the code if we add repos later, like the repo
we just gathered and createrepod
2011-04-29 01:45:28 -07:00
Dennis Gilmore
4002565f53 only filter the arch list on x86_64 we cant do it on sparc and ppc.
it really only makes sense on x86_64.
2011-04-11 14:03:01 -05:00
Dennis Gilmore
4bc181ed4a allow source isos to be generated, there is no split media support 2011-02-21 18:28:39 -06:00
Bill Nottingham
b4e40a079e Add an option to allow only grabbing the best provides for a particular depenedency, instead of all. 2011-02-10 15:30:02 -05:00
Jesse Keating
27cf6a26b4 Release 2.5 2011-01-12 13:52:34 -08:00
Martin Gracik
7deae5840c Lorax patch
Use lorax instead of buildinstall
2011-01-12 13:50:39 -08:00
Jesse Keating
6d480f0896 Prep for release 2010-12-21 14:26:25 -08:00
Jesse Keating
5b0c9715a5 Enable efi booting on x86_64 isos
This was requested by Peter Jones.
2010-12-20 13:54:38 -08:00
Martin Gracik
19993ef780 Let the yumconf.persistdir be as the default
This path gets appended to the installroot every time,
even if it's an absolute path, so it ends up being inside
the installroot everytime. We don't want it to be in some
path depending on a temporary workdir. This will put all
the yum files in a standard /var/lib/yum directory inside
the installroot.
2010-11-30 15:11:51 -08:00
Jesse Keating
31d6c3d6ef Prep for release 2010-11-15 16:44:47 -08:00
Jesse Keating
6e28466560 Remove code to generate media:// repodata
This is no longer necessary when doing single media composes
2010-11-15 16:39:27 -08:00
Jesse Keating
cbba0e4cd7 Remove unneeded files now that we don't split 2010-11-12 09:28:15 -08:00
Jesse Keating
d5ef2c25ff Remove ability to generate split media 2010-11-12 09:27:10 -08:00
Jesse Keating
9976438e31 Remove options to do split media composes 2010-11-12 09:18:04 -08:00
Jesse Keating
9b221ec535 Prep for release and further fix pkgorder issue 2010-10-14 10:52:44 -07:00
Jesse Keating
95a8aaa0c1 Add the full boat of possible initrd items 2010-10-14 10:52:02 -07:00
Jesse Keating
18143a47a1 Prep for release 2010-10-13 15:40:40 -07:00
Jesse Keating
17070c0887 Make sure lvm shows up on the first disk (#642557) 2010-10-13 15:39:02 -07:00
Jesse Keating
06c5a94b5b prep for release 2010-06-29 16:00:34 -07:00
Jesse Keating
a7a43e413b Fix a traceback (#609247) 2010-06-29 15:58:55 -07:00
Jesse Keating
39326ef54a Clean up white space. 2010-06-11 08:29:31 -07:00
npetrov
f3dafc4446 adding support to exclude groups (-@fonts) from a default ks file. 2010-06-11 08:28:31 -07:00
npetrov
6703e700ba check for broken symlinks when using --force 2010-06-09 08:34:34 -07:00
Jesse Keating
c6f01468c3 Prep for release 2010-06-04 11:32:05 -07:00
Jesse Keating
7099d39f24 Don't do multilib gathering.
Anaconda won't install them, so why gather them?  Thanks to Seth Vidal
for the code.
2010-06-04 10:29:01 -07:00
npetrov
7dd898cbad fixes --force when compose fails during split-tree process. 2010-05-17 14:38:58 -07:00
npetrov
9f6fe74826 remove anaconda_log 2010-04-29 14:16:51 -07:00
Jesse Keating
ab0b3aa369 Prep for release 2010-04-14 16:14:43 -07:00
Jesse Keating
6ed01b8852 Patch for new anaconda path
This patch came from Chris Lumens via RHBZ 579873
2010-04-14 16:11:10 -07:00
Jesse Keating
be078f9850 Leave some breadcrumbs about the checksum. 2010-04-14 16:01:17 -07:00
Brian C. Lane
38d41ad0be Add proxy support from the repo line in the kickstart file 2010-03-08 17:18:35 -08:00
Jesse Keating
d4fc805857 Catch all kernel packages (#505420) 2009-12-22 12:08:22 -08:00
Jesse Keating
b79b50b669 Prep for release 2009-09-15 16:55:12 -07:00
Jesse Keating
9aed6d9656 rhpl is no longer forced by anaconda 2009-09-15 16:54:27 -07:00
Jesse Keating
d30edb8b6a Prep for release 2009-09-15 14:51:19 -07:00
Jesse Keating
d9a294aee5 Be tolerant of missing package names in pkgorder, helps with small composes 2009-09-15 14:51:19 -07:00
Dennis Gilmore
fe23e1f65a setthe yum arch to sparc64v when making sparc images. We need this since we only have a sparc64 kernel 2009-09-15 14:51:19 -07:00
Bill Nottingham
f8865c35e2 pungi: Fix dependency resolution to recurse properly.
It wasn't properly recusing in the --selfhosting or --fulltree cases
before, leading to potenial broken deps.

Bill

Signed-off-by: Bill Nottingham <notting@redhat.com>
2009-09-15 14:51:19 -07:00
Jesse Keating
acdac6a2be Patch from dgregor for #522371 (no package left behind) 2009-09-15 14:51:19 -07:00
Jesse Keating
1991a09a48 Prep for release 2009-09-15 14:51:18 -07:00
Jesse Keating
0ace77f6c6 mkinitrd isn't being used anymore, dracut is. 2009-09-15 14:51:18 -07:00
Bill Nottingham
f099500663 Fix man page option listing. 2009-09-15 11:12:52 -04:00
Bill Nottingham
51f03b32e4 Add corresponding RHEL version check to spec. 2009-09-03 16:18:26 -04:00
Jesse Keating
e434cf4876 Prep for release 2009-08-10 15:00:03 -07:00
Jesse Keating
7f0cd87c4f pychecker clean up, don't overload 'file' 2009-08-04 14:40:32 -07:00
Jesse Keating
05c51e4b96 Cleanup from pychecker, remove unused items. 2009-08-04 14:36:17 -07:00
Jesse Keating
eb3caa4161 Kill extra whitespace 2009-08-04 14:23:55 -07:00
Jesse Keating
cd466ce546 Remove unused functions in splittree 2009-08-04 14:21:59 -07:00
Jesse Keating
af347fd6a3 Avoid conflicting with yum internals 2009-08-04 14:03:40 -07:00
Jesse Keating
5d6fc5c543 Prepare for release 2009-05-21 10:34:00 -07:00
Jesse Keating
179d3cd678 Fix boot.iso showing up on DVD and potentially split media. 2009-05-21 10:31:35 -07:00
Jesse Keating
a859efe4a9 Prep for release 2009-05-19 11:27:48 -07:00
Jesse Keating
8a15ecca80 Use the new splittree method of dynamic srpm cd splitting 2009-05-18 15:37:31 -07:00
Jesse Keating
a73e976bc8 Create a new function to create the splitSRPM dirs
Use this function to create split SRPM dirs on the fly
2009-05-18 14:33:18 -07:00
Jesse Keating
ff3b72a97e Don't set the number of discs we have until after splittree is done.
Splittree now splits as needed, so we can't possible know how many
discs we'll be making until it is done.  This also means that
splittree requires less input from us.
2009-05-15 13:00:40 -07:00
Jesse Keating
e377f015df Use the new function to create the first split dir only. 2009-05-15 12:22:04 -07:00
Jesse Keating
038a98a2d3 Make splits on demand rather than pre-create a hard set of splits. 2009-05-15 11:19:26 -07:00
Jesse Keating
9012c9fd41 Add two new functions to help with creating split dirs on demand.
createFirstSplitDir is called for the first split.
createSplitDir is called for all other splits.
2009-05-15 11:17:23 -07:00
Jesse Keating
076ba206cb Prep for release again 2009-04-13 16:17:35 -07:00
Bill Nottingham
26f9fad9a5 Wire in support for composing 'full' trees with all subpackages.
Since full trees and build-solved trees can affect each other, if we're
doing both we need to loop between them until there are no new packages
added.

Signed-off-by: Bill Nottingham <notting@redhat.com>
2009-04-13 16:16:45 -07:00
Bill Nottingham
0074f79e5d Add a method that completes the package set with all subpackages of currently used source rpms.
In other places, this method could be called No Package Left Behind.

Signed-off-by: Bill Nottingham <notting@redhat.com>
2009-04-13 16:16:31 -07:00
Bill Nottingham
63adcfcc7c Create dicts to map between source and binary packages.
This avoids repeating the operation many times later if we do it
on demand each time.

Signed-off-by: Bill Nottingham <notting@redhat.com>
2009-04-13 16:16:20 -07:00
Bill Nottingham
e437dd7f7f Remove obsolete code.
Signed-off-by: Bill Nottingham <notting@redhat.com>
2009-04-13 16:16:07 -07:00
Bill Nottingham
2c2a1178ae Wire up a commandline option for selfhosting support.
Signed-off-by: Bill Nottingham <notting@redhat.com>
2009-04-13 16:15:54 -07:00
Bill Nottingham
28412ffc8f Resolve package build dependencies.
Since each package we add for build dependencies may add a new source rpm
to our list, this needs to recurse.

Signed-off-by: Bill Nottingham <notting@redhat.com>
2009-04-13 16:15:40 -07:00
Bill Nottingham
f46d84ed73 Operate on source rpm package objects, not a list that is then turned into package objects.
Signed-off-by: Bill Nottingham <notting@redhat.com>
2009-04-13 16:15:21 -07:00
Bill Nottingham
9ecb4c5dc3 Allow ignoring of group metadata from repos.
Signed-off-by: Bill Nottingham <notting@redhat.com>
2009-04-13 16:15:05 -07:00
Jesse Keating
b28d842bec Prep for release 2009-04-13 16:12:25 -07:00
Jesse Keating
c484a26f44 Pad the ppc bootable disks by 15 megs, lots of isofs overhead. 2009-04-07 18:09:00 -07:00
Jesse Keating
44c4028447 Add a function to deselect packages, stolen from Anaconda.
Use deselectPackage to deslect things marked with - in kickstart.
More in line with how anaconda treats them.
2009-04-07 15:03:46 -07:00
Jesse Keating
979c0b5e94 Prep for release 2009-03-24 10:04:00 -07:00
Jesse Keating
db54e3dbfd Add the online-docs group into pkgorder so that they get properly ordered. 2009-03-24 10:02:52 -07:00
Jesse Keating
9d831bc470 Prep for release 2009-03-11 17:51:57 -07:00
Jesse Keating
050c8da46b Use a more future proof doLoggingSetup override. 2009-03-11 17:50:51 -07:00
Jesse Keating
ff70fea3ed Remove the MANIFEST file so that it gets created fresh each time 2009-03-09 15:34:59 -07:00
Jesse Keating
2688d1c397 Fix the Changelog target 2009-03-09 15:22:44 -07:00
Jesse Keating
ea148b8b1c Prep for release 2009-03-09 10:56:43 -07:00
Jesse Keating
e3d6cf508d Disable arch test for now, it was tripping i386/i586 for no good reason. 2009-03-04 13:45:44 -08:00
Jesse Keating
bdf3b118aa Fix size estimation in splittree.
This while file needs a major rework, but this gets us correct
size estimations when building up discs.
2009-02-12 11:26:48 -08:00
Jesse Keating
923a0c9392 Prep for release 2009-02-11 17:15:13 -08:00
Jesse Keating
5216793a69 Count all copies of a hardlink when determining CD size for now,
until bug #485167 is fixed.
2009-02-11 17:09:04 -08:00
Jesse Keating
6843a12485 Fix unique md file config setting. 2009-02-10 16:21:17 -08:00
Jesse Keating
7dc76be687 Name the checksum file after the isos being generated. 2009-02-10 16:21:11 -08:00
Jesse Keating
9b77cea3b7 Use sha256 in the treeinfo file 2009-02-10 14:52:01 -08:00
Jesse Keating
90ef65f192 Use sha256 for iso checksums 2009-02-10 14:50:46 -08:00
Jesse Keating
e073e0a032 More generisizing of _doIsoChecksum 2009-02-10 14:49:59 -08:00
Jesse Keating
c0e7d8afe5 Rename _doIsoSha1 to _doIsoChecksum to future proof. 2009-02-10 14:47:37 -08:00
Jesse Keating
074879de5c Use unique md file names for repodata. 2009-02-05 14:24:32 -08:00
Jeroen van Meeuwen (Fedora Unity)
dee9472d0c Do not include boot.iso on any disc 2009-02-05 14:22:35 -08:00
Jeroen van Meeuwen (Fedora Unity)
c4004dd307 Prevent errors from happening by accidently inserting a line between two extraargs.append() calls with options that belong together 2009-01-29 17:56:57 -08:00
Jesse Keating
972240b972 Don't ship boot.iso on cd1 or the DVD. It just wastes space. 2009-01-28 16:02:48 -08:00
Jesse Keating
353600eb98 Add the packages that anaconda forces to be installed into the pkgorder 2009-01-28 14:22:32 -08:00
Jesse Keating
5a00b479b7 Update from ivasquez for python version changes. 2008-12-04 16:39:12 -08:00
Jesse Keating
dbf82cce09 Prep for release 2008-12-04 16:36:14 -08:00
Jesse Keating
3ca7a26682 'default' is now a reserved config section. We can't use it anymore. 2008-12-04 15:44:34 -08:00
Jesse Keating
208fe34cc5 Make sure that split SRPMS have the right working size to match that
of the binary splits.
2008-11-24 15:49:44 -08:00
Jesse Keating
a8a1aa0149 Prep for another release 2008-11-04 15:32:29 -08:00
Jesse Keating
056cf18c10 Set the default disc size to 695 which is more appropriate given today's media
and the splittree bug that was just fixed.
2008-11-04 15:30:45 -08:00
Jesse Keating
14771fb5ef Prep for release 2008-11-04 15:13:30 -08:00
Jesse Keating
3c30592dab Use disc_size in splittree as splittree.main() will reset target_size based on it.
Set comps size to 0 as we don't create a comps package anymore.

Longer term we need to stop calling main() from splittree, and instead just
call the functions we need manually.  A bit late for that change for the F10
cycle though.
2008-11-04 14:48:27 -08:00
Jesse Keating
4d01eb4785 Use the https url to bugzilla, otherwise people think they need to re-log in. 2008-10-31 13:09:27 -08:00
Jesse Keating
d77a180f29 Prep for release 2008-10-09 13:19:51 -07:00
Jesse Keating
dc3dbc2bdf Use --default in %packages to grab the default groups from the repos. 2008-10-06 11:53:07 -07:00
Jesse Keating
b929b89835 Handle %packages --default to pick up the default groups. 2008-10-03 15:32:06 -07:00
Jesse Keating
15efef64fa Fix a typo in a comment 2008-10-03 14:23:30 -07:00
Jesse Keating
2fca7f7405 When setting name via /usr/bin/pungi, also set the iso basename. Allow API
callers to still set them differently though.
2008-10-03 11:35:50 -07:00
Jesse Keating
dcf4d90e69 Subclass ConfigParser so that we can store path names as config options
verbatim and avoid having the files be lowercase.
2008-10-03 10:11:00 -07:00
Jesse Keating
c550c16f62 Make sure we don't include the 'sha1:' in the iso SHA1SUM file. 2008-09-30 15:46:59 -07:00
Jesse Keating
a157c94252 Add more lang groups we support. 2008-09-17 15:45:54 -07:00
Jesse Keating
94828b34fb New release 2008-09-12 14:07:35 -07:00
Jesse Keating
08fc496a36 Revert "Yum api changed with regard to adding conditionals. Need to pass in just a name"
This reverts commit bc18a1d4f3.

Reverting because yum api reverted back to the way it was.
2008-09-11 13:32:01 -07:00
Jesse Keating
a82d29ccaa Add input-methods. It's a new group, need to get ordering right. 2008-09-11 13:25:39 -07:00
Jesse Keating
e101067357 Make sure we output sha1sums in binary mode. This helps windows. 2008-09-10 15:36:49 -07:00
Jesse Keating
9ca05af1e9 Yum api changed, follow so that we don't break. 2008-08-29 10:55:25 -07:00
Jesse Keating
bc18a1d4f3 Yum api changed with regard to adding conditionals. Need to pass in just a name
rather than a package object.  Also call searchName since that's all we care about.
2008-08-11 22:47:39 -04:00
Jesse Keating
6fc3d4ff79 Prep for release 2008-08-11 11:24:13 -04:00
Jesse Keating
768ab66ee6 isolist is already relative, there is no need to call mkrelative. 2008-08-05 23:25:14 -04:00
Jesse Keating
7326b388c3 Fix up some references due to moving the yum init into it's own function. 2008-08-05 22:49:05 -04:00
Jesse Keating
e9e0a1880c Move the yum object initialization to it's own function.
This is necessary so that we can get a pypungi object without having to
init the repositories.
2008-08-05 15:36:08 -04:00
Jesse Keating
bdaf3a662a Grab ppc images checksums too for our info file. 2008-08-05 14:34:37 -04:00
Jesse Keating
f253e2e8bb Make sure we write out relative paths for the infofile 2008-08-04 17:57:53 -04:00
Jesse Keating
5beb34227e Change slightly the output of _doCheckSum so that it's type:hash for easier parsing. 2008-08-04 17:04:19 -04:00
Jesse Keating
be8b06d523 Make sure we get relative paths to the images. 2008-08-04 16:57:05 -04:00
Jesse Keating
7d92748838 Don't try to make debuginfo repos for source arch. 2008-07-16 13:31:17 -04:00
Jesse Keating
8331ae9e0f Remove the unused discs option. We determine disc number on the fly. 2008-07-15 23:09:57 -04:00
Jesse Keating
6ae28edb54 Prep for release 2008-07-15 19:03:53 -04:00
Jesse Keating
2b5ed26466 Remove some debugging code... 2008-07-15 18:36:07 -04:00
Jesse Keating
116a0df898 Don't read the entire file at once. This will run machines out of memory.
Also, always use binary mode on the files, or else our hashes will be odd.
2008-07-15 18:10:19 -04:00
Jesse Keating
74e014707a Checksum various files from buildinstall output and put them in .treeinfo
This will be used by a verify-tree like tool that will ensure that the
content on disk matches what the compose tool thinks it should.
2008-07-15 15:53:11 -04:00
Jesse Keating
ec8b64e6cf Use new hashsum utility to generate sha1sums of isos.
Call a generic function each time we create an iso file.
2008-07-14 23:27:40 -04:00
Jesse Keating
38bd19ea9a Add a utility to generate a hashsum of a file 2008-07-14 23:26:52 -04:00
Jesse Keating
0517ef0782 Prep for release 2008-07-11 14:31:28 -04:00
Jesse Keating
3e62130a6c Create debuginfo metadata when creating metadata, if we've gathered debuginfo
Move cachedir to a variable definition since we use it more than once.
2008-07-09 18:08:12 -04:00
Jesse Keating
7c2e8593c8 Add a function to download the debuginfo packages we found. 2008-07-09 18:07:50 -04:00
Jesse Keating
26795667ac Add a function to get debuginfo packages to match the other packages we've gathered.
This has a couple hardcoded special cases for kernel and glibc for the -common debuginfo
Try to match the original po as close as possible.
2008-07-09 18:07:42 -04:00
Jesse Keating
cbe47772c9 Change _filtersrc to _filtersrcdebug and call it appropriately.
We now need to filter out debuginfo packages so that we can add the
debuginfo repos to the ks file
2008-07-09 18:07:13 -04:00
Jesse Keating
3cc980b49d Add a config item for debuginfo
We need this as a config object so that we can use it later when
making repodata.
2008-07-09 18:07:13 -04:00
Jesse Keating
874853e78b Add a nodebuginfo option to handle gathering or not gathering of debuginfo packages
Set a config item for it so that we can use it later when creating repodata
Discover and gather debuginfo packages if necessary.
2008-07-09 18:07:05 -04:00
Jesse Keating
3c979842b4 Prep for release 2008-06-24 10:30:41 -04:00
Jesse Keating
af2d5a1e58 Fix setup.py and pungi.spec for pkgorder.
Test first, then commit.  *sigh*
2008-06-23 10:54:45 -04:00
Jesse Keating
0670212e14 Add pkgorder script to setup.py 2008-06-23 10:29:31 -04:00
Jesse Keating
15c5b80e87 Take ownership of pkgorder and splittree.py; call appropriately
These two files have been removed from anaconda sources, so we
are taking ownership of them.  We will likely rewrite some of these
but the plan is to keep them as 'utility' type tools so that they
can be used without creating full pungi objects.
2008-06-23 10:27:30 -04:00
Jesse Keating
897f97ee59 Remove compose tools from manifest. We don't need them any more now that anaconda
can get to the repos we use to get the things it needs.
2008-06-17 10:29:39 -04:00
Jesse Keating
953ee3addf Prepare for 2.0.0 release. woo! 2008-06-13 18:26:36 -04:00
Jesse Keating
151e3b134e We use sys here too 2008-06-13 13:48:09 -04:00
Jesse Keating
3b955cc823 Fix some typos and handle the fact that baseurl is a list, where as mirrorlist isn't. 2008-06-13 13:47:31 -04:00
Jesse Keating
379020e5c5 Add functionality to pass multiple repos, mirrorlists, and output directory to buildinstall. 2008-06-13 12:56:45 -04:00
Jesse Keating
64e5734178 Add our util.py file with all the "utility" functions. 2008-06-12 11:43:57 -04:00
Jesse Keating
a81ead6181 Move utility functions to util.py; call appropriately.
Also fix some whitespace issues (hey, it's my project, I can do whitespace changes)
2008-06-12 11:36:47 -04:00
Jesse Keating
a9249e3c31 Don't import the files that I've removed. 2008-06-12 11:24:54 -04:00
Jesse Keating
043a799b25 Adjust calls to the single class, only create the object once. 2008-06-12 09:06:19 -04:00
Jesse Keating
4627931835 remove pungi.py 2008-06-12 09:00:53 -04:00
Jesse Keating
3b89e4586b Collapse all of pungi.py to __init__.py 2008-06-12 09:00:43 -04:00
Jesse Keating
4ae0dc35e8 Change permissions on pungi.py, remove gather.py 2008-06-12 08:56:43 -04:00
Jesse Keating
b45c700be8 Collapse all of Gather and Pungi into one class/file. 2008-06-12 08:55:42 -04:00
Jesse Keating
1b58d024a3 Repo cost is now actually referenced as 'cost'. 2008-06-04 16:28:35 -04:00
Jesse Keating
baa1ce8ee1 Add admin-tools to the manifest. 2008-05-14 14:27:31 -04:00
Jesse Keating
203f152239 Prep for release 2008-05-06 12:39:24 -04:00
Jesse Keating
554310a690 Exclude syslog-ng from the media. We don't want it. 2008-05-06 12:37:37 -04:00
Jesse Keating
58c08e04eb prep for release 2008-05-01 11:48:50 -04:00
Jesse Keating
8aa4e5ce55 Add a Fedora 9 config file 2008-05-01 11:25:10 -04:00
Jesse Keating
0befc4d3f3 Remove some items to make PPC DVD fit on a DVD 2008-04-23 22:46:51 -04:00
Jesse Keating
2455411091 Require a sufficient version of createrepo (Jeroen van Meeuwen) 2008-04-17 07:25:57 -04:00
Jesse Keating
24641ddfbe Fix another problem with src repo generation, handle flavor. 2008-04-16 23:04:25 -04:00
Jesse Keating
e7430529af Prep for release. 2008-04-16 22:23:24 -04:00
Jesse Keating
b71ae43cc5 Add back changes I missed somehow:
Fix srpm repodata making
2008-04-16 22:22:14 -04:00
Jesse Keating
c0d44a06a6 Prepare for release. 2008-04-16 18:27:26 -04:00
Jesse Keating
178e217eca Add new languages 2008-04-16 11:12:58 -04:00
Jesse Keating
ed1e80c6da Adjust manifest, block the kernels we don't want, pull in the right flash stuff. 2008-04-15 07:09:02 -05:00
Jesse Keating
b1bd3c7a46 Support repo costs. (pykickstart calls this priority for now) 2008-04-15 07:08:35 -05:00
Jesse Keating
5d33519dbf Disable the comps cleanup until it works again. 2008-04-14 21:33:45 -05:00
Jesse Keating
2ddaea50a9 Fix output message from make archive, we do tar.bz2 not gz. 2008-04-01 14:58:38 -04:00
Jesse Keating
4b69164797 Update Makefile for git. Remove changelog, create it from git. 2008-04-01 14:58:05 -04:00
Jesse Keating
ac609004b2 Prep for new release 2008-04-01 14:34:38 -04:00
Jesse Keating
13d6ed35ee Correct the api call to comps. 2008-03-25 17:14:11 -04:00
Jesse Keating
65c7bdf6de Use yum's method to write out a unified comps. 2008-03-25 17:06:21 -04:00
Jesse Keating
51f5969e49 handle shared source dirs when gathering. 2008-03-21 15:56:22 -04:00
Jesse Keating
ed5d17207f pungi-1.2.12-1.fc9 2008-03-14 16:56:37 -04:00
Jesse Keating
007effec74 Prep for release 2008-03-14 16:56:33 -04:00
Jesse Keating
aa358c1517 Fix srpm stuff 2008-03-14 16:55:28 -04:00
Jesse Keating
bd4eea43d0 - Don't pass --prodpath to buildinstall. It won't like it. 2008-03-14 13:12:12 -04:00
Jesse Keating
3f9479029c pungi-1.2.11-1.fc9 2008-03-13 23:02:34 -04:00
Jesse Keating
6373d57d22 Make CDs fit again by default 2008-03-13 23:02:29 -04:00
Jesse Keating
f29a4ca8b1 Make CDs fit again 2008-03-12 16:46:23 -04:00
Jesse Keating
5c106b05d8 Use the right link call. 2008-03-12 16:44:03 -04:00
Jesse Keating
ecc53ba291 pungi-1.2.10-1.fc9 2008-03-11 14:42:44 -04:00
Jesse Keating
66a6d6eafd More chnages for netinst.iso/boot.iso 2008-03-11 14:42:41 -04:00
Jesse Keating
0a4fdfe767 pungi-1.2.9-1.fc9 2008-03-05 22:28:04 -05:00
Jesse Keating
0a9dffe2a5 Prep for release 2008-03-05 22:27:59 -05:00
Jesse Keating
a08871a741 Exclude repoview from isos. 2008-03-05 22:26:43 -05:00
Jesse Keating
7405122981 Fix ppc split iso generation 2008-03-05 13:45:17 -05:00
Jesse Keating
e2f79e49f6 Handle netinst.iso files. 2008-03-03 16:09:53 -05:00
Jesse Keating
8a89242100 pungi-1.2.8-1.fc8 2008-02-28 17:14:09 -05:00
Jesse Keating
b623f31621 Prep for release. 2008-02-28 17:13:56 -05:00
Jesse Keating
7b27cd5c8b Don't traceback when moving repodata out for split media. 2008-02-28 16:29:46 -05:00
Jesse Keating
706184a97f Don't force clean the repodata, some of it can be reused.
Always make sure we get a clean repomd.xml to compare against the rest of the files.
2008-02-28 12:23:33 -05:00
Jesse Keating
eb1a47579f Handle gzipped comps files. 2008-02-21 18:04:39 -05:00
Jesse Keating
1a5e874d84 Commit spec change that I forgot to a while ago. 2008-02-08 15:05:58 -05:00
Jesse Keating
923ea6fa1a Fix comps issue for older repos. 2008-02-08 15:04:56 -05:00
Jesse Keating
4a55747832 pungi-1.2.7-1.fc8 2008-01-22 15:10:00 -05:00
Jesse Keating
6f8c7be932 Prep for release 2008-01-22 15:06:43 -05:00
Jesse Keating
b2cf9776ea Rework how repodata gets generated for media.
Necessary as anaconda doesn't handle split metadata being on the
DVD anymore.
2008-01-22 14:44:14 -05:00
Jesse Keating
3ce7826b06 Don't try to close() a file that gets autoclosed due to readlines(). 2008-01-21 17:32:37 -05:00
Jesse Keating
34bb3d57fc Don't fiddle with editing the .discinfo file. It's just confusing for no good reason. 2008-01-21 17:32:08 -05:00
Jesse Keating
bbbcc1dff8 Always use the discinfo file from the exploaded tree. It doesn't change. Also, close the file when we're done. 2008-01-21 17:13:54 -05:00
Jesse Keating
7de5f15356 use createrepo api 2008-01-21 17:09:02 -05:00
Jesse Keating
202059224a Force cracklib-python to be pulled in. 2008-01-15 17:53:40 -05:00
Jesse Keating
59c189438a pungi-1.2.6-1.fc8 2008-01-02 17:42:07 -05:00
Jesse Keating
6d0d5e5839 prep for dist.
Use bzip2 (so trac can see it)
2008-01-02 17:41:54 -05:00
Jesse Keating
e81d4b8e51 Add k3b to the manifest. 2008-01-02 17:19:31 -05:00
Jesse Keating
d36d3a32e0 Add more eclipse files to be ignored. 2007-12-17 15:13:09 -05:00
Jesse Keating
1402ef4414 - Always add the core comps group. 2007-12-17 15:12:25 -05:00
Jesse Keating
49eb1f853e Ignore eclipse files. 2007-12-14 23:16:10 -05:00
Jesse Keating
a18974c12c Fix up for file moves. 2007-12-14 23:14:21 -05:00
Jesse Keating
2cb4e338f7 Adjust layout, will help with using eclipse 2007-12-14 22:41:08 -05:00
Jesse Keating
b94b37422a We don't need relnote directories since relnotes aren't being used. 2007-12-11 10:35:59 -05:00
Jesse Keating
6299545b10 Correct mistake with cache dir ensurance. 2007-12-11 10:34:18 -05:00
Jesse Keating
c91524b39b pungi-1.2.4-1.fc8 2007-12-10 18:29:19 -05:00
Jesse Keating
fa1fc86b8d Remove extra files from tarball 2007-12-10 18:29:15 -05:00
Jesse Keating
15f0b6b682 pungi-1.2.3-1.fc8 2007-12-10 18:18:44 -05:00
Jesse Keating
eb3083c94a Third time's the charm... 2007-12-10 18:18:40 -05:00
Jesse Keating
cf2469d7fa pungi-1.2.2-1.fc8 2007-12-10 18:05:49 -05:00
Jesse Keating
1c76dd3722 Handle egg generation in the spec file. 2007-12-10 18:04:55 -05:00
Jesse Keating
5bfbdb1a47 pungi-1.2.1-1.fc8 2007-12-10 17:20:15 -05:00
Jesse Keating
302a5ab5db Prepare for release 2007-12-10 17:17:19 -05:00
Jesse Keating
b7b45d59c1 Change path to isomd5sum 2007-12-10 15:17:56 -05:00
Jesse Keating
5abaa9b226 Use a repoview cache.
Make sure the cache dirs exist before using them.
2007-12-10 14:14:06 -05:00
Jesse Keating
fb6c4402a2 Enable a createrepo cache. 2007-12-08 10:42:31 -05:00
Jesse Keating
8ca20d2fa7 Remove all the release notes files that we don't display in the installer. 2007-12-07 17:44:35 -05:00
Jesse Keating
9c11eec79a pungi-1.2.0-1.fc8 2007-12-04 10:06:18 -05:00
Jesse Keating
5e0fad1742 Prepare for release
Drop the f8 file, add a rawhide ks file.
2007-12-04 10:05:58 -05:00
Jesse Keating
0d2d9e55f5 Quiet down the selinux check. 2007-12-04 09:31:40 -05:00
Jesse Keating
591f65c982 Make the cd size a nice even number. 2007-12-04 07:58:43 -05:00
Jesse Keating
4929567859 Adjust the size so that we fit on all disks. splittree kind of sucks this way. 2007-12-03 23:17:21 -05:00
Jesse Keating
d9a840c863 Remove previous splittree workdirs when reusing a tree. 2007-12-03 23:09:47 -05:00
Jesse Keating
91a9edceb7 Default to 690 for a cd size. 2007-12-03 20:41:42 -05:00
Jesse Keating
9be2c94dc6 Make the logged command output useable in a shell. 2007-12-03 20:38:02 -05:00
Jesse Keating
43c0267445 Support includes and excludes from repos. 2007-12-03 15:37:15 -05:00
Jesse Keating
3248639f9b Disable TMPDIR use in buildinstall. Still broken :/ 2007-12-03 14:52:47 -05:00
Jesse Keating
8df58b56cb Bump version to 1.2.0
Allow our default flavor of '' to be used.
2007-12-03 13:49:11 -05:00
Jesse Keating
a9c124e7e0 Only allow alphanumeric in flavor. 2007-12-03 11:56:03 -05:00
Jesse Keating
33a2ec8508 Check for selinux enforcing. Warn if it is. 2007-12-03 11:40:41 -05:00
Jesse Keating
67df99833a Do release notes first. 2007-12-02 23:02:51 -05:00
Jesse Keating
dcf069a017 Fix logging during _ensuredir.
Some fixups for re-using dirs
2007-12-02 22:24:11 -05:00
Jesse Keating
6748133646 Support re-using existing destdirs better, with a --force option. 2007-12-02 14:31:26 -05:00
jkeating
aef1db89aa Only check root when necessary. 2007-11-30 15:41:58 -05:00
Jesse Keating
a09b885fd8 Flip the default for nosource. 2007-11-30 10:36:28 -05:00
Jesse Keating
669fd7e62b Add joe, tcsh, thunderbird to the manifest
exclude any debug kernels from winding up in the tree
2007-11-29 17:49:23 -05:00
Jesse Keating
f499bc4f8d Add a split option to the iso creation function
Fix a SRPMS SRPMs typo
Handle source iso creation better
2007-11-29 17:46:58 -05:00
Jesse Keating
1116fcc4b0 Call the logger correctly 2007-11-28 22:14:20 -05:00
Jesse Keating
1c6ac68a59 Remove non-op checks in splittree and pkgorder. They're only called now if we want more than one iso.
Make tree size check quiet.
2007-11-28 17:11:18 -05:00
Jesse Keating
8733a990ec - Figure out number of isos on the fly, based on tree size
- Add command line option to disable creation of split media
- Remove -S -P options, as splittree and packageorder are now
called from createIsos, if needed.
2007-11-28 17:10:02 -05:00
Jesse Keating
3260c78f53 - Use downloadPkgs() from yum instead of a homebrew download function.
- Add a callback to show download progress
- Add a force option to _link, removes existing target file
2007-11-27 21:42:37 -05:00
Jesse Keating
d99c9048c4 Clarify package not found slightly 2007-11-27 14:54:17 -05:00
Jesse Keating
8e5e261774 Enable TMPDIR again so that anconda-runtime working files go to the working dir. 2007-11-27 14:40:36 -05:00
Jesse Keating
333255c35c pungi-1.1.10-1.fc8 2007-11-22 09:31:22 -05:00
Jesse Keating
c60c9b443e Prep for release 2007-11-22 09:31:15 -05:00
Jesse Keating
a621cdc5c5 Need to import shutil in order to use it. 2007-11-21 09:17:14 -05:00
Jesse Keating
cf54262dee Use the released repos, not rawhide. 2007-11-20 20:31:28 -05:00
Jesse Keating
0334c92f11 Correct a man page typo 2007-11-20 17:44:11 -05:00
Jesse Keating
87f914e814 Fix up some tabs/spaces. 2007-11-20 17:29:57 -05:00
Jesse Keating
7bf5e3d458 Print usage if we don't have a correct option. (Ticket #61) 2007-11-20 17:29:18 -05:00
Jesse Keating
47b32e3c2d Move the _link function to the __init__ of pypungi to be used by both gather and pungi.
Attempt to hardlink release note files instead of copy them. (helps preserve timestamps)
2007-11-07 19:44:12 -05:00
Jesse Keating
ab3bcf6194 pungi-1.1.9-1.fc8 2007-10-29 16:59:44 -04:00
Jesse Keating
33a28f0c0a Fix reget better. Don't try to stat a nonexistant file 2007-10-29 16:59:06 -04:00
Jesse Keating
83aec9363a pungi-1.1.9-1.fc8 2007-10-29 16:26:47 -04:00
Jesse Keating
930f0f2667 Fix regets. 2007-10-29 16:26:42 -04:00
Jesse Keating
cc9bb72726 pungi-1.1.8-1.fc8 2007-10-27 12:17:56 -04:00
Jesse Keating
53301b5313 Add eclipse 2007-10-27 12:17:39 -04:00
Jesse Keating
c28af6c5ea Add eclipse group to the media. 2007-10-24 09:50:20 -04:00
Jesse Keating
2aeafff418 pungi-1.1.7-1.fc8 2007-10-23 17:20:10 -04:00
Jesse Keating
400ff52477 - Add java-development to the group set. 2007-10-23 17:20:01 -04:00
Jesse Keating
24a52f5cb6 pungi-1.1.6-1.fc8 2007-10-19 14:33:46 -04:00
Jesse Keating
4b4a2d2f32 Prep for release. 2007-10-19 14:33:26 -04:00
notting@nostromo.devel.redhat.com
076706ead6 sync langsupport with comps 2007-10-18 11:10:13 -04:00
notting@nostromo.devel.redhat.com
06ace11bfd add java support for icedtea-plugin (#326911) 2007-10-18 10:52:06 -04:00
Jesse Keating
4ca3248d0a pungi-1.1.5-1.fc8 2007-10-11 14:00:53 -04:00
Jesse Keating
adbc4c787c prep for release. 2007-10-11 14:00:47 -04:00
Jesse Keating
6119a75069 Add a cost to the media repo file. 2007-10-11 13:58:50 -04:00
Jesse Keating
7795c25583 Make sure esc gets into the media even though it's not default. 2007-10-05 10:48:39 -04:00
Jesse Keating
420f9a59aa pungi-1.1.4-1.fc8 2007-10-02 15:50:13 -04:00
Jesse Keating
6c4913c169 Make a release 2007-10-02 15:50:02 -04:00
Jesse Keating
149a6a8929 One more try.. *sigh* 2007-10-02 08:35:30 -04:00
Jesse Keating
b80ab86a7a Use correct glob for pida stuff. 2007-10-02 08:34:37 -04:00
Jesse Keating
db5c76a807 Ignore pida related stuff. 2007-10-02 08:33:30 -04:00
Jesse Keating
bd41b1c239 Update the log. 2007-10-02 08:30:46 -04:00
Jesse Keating
5e467d0cb5 Make sure we are stuffing a string into the ConfigParser. 2007-10-02 08:29:11 -04:00
Jesse Keating
ddab468b43 Make a release 2007-09-26 14:59:36 -04:00
Jesse Keating
51d96f80e1 don't expire metadata from the media.repo 2007-09-26 14:58:34 -04:00
Jesse Keating
00487ea9c8 Pull in the optional virt stuff 2007-09-26 14:56:37 -04:00
Jesse Keating
dcb7376ff2 pungi-1.1.2-1.fc8 2007-09-25 21:27:09 -04:00
Jesse Keating
835188ac2c - Fix location of media.repo file. 2007-09-25 21:26:59 -04:00
Jesse Keating
c4b27ff703 pungi-1.1.1-1.fc8 2007-09-18 16:32:01 -04:00
Jesse Keating
371c782b81 prep for release 2007-09-18 16:31:52 -04:00
jkeating@localhost.localdomain
c2d4e9ed34 Write out a repo file for the media 2007-09-18 15:12:31 -04:00
Jesse Keating
ec1ecc368d pungi-1.1.0-1.fc8 2007-09-17 17:31:09 -04:00
Jesse Keating
93ad1c3f57 Release 1.1.0 2007-09-17 17:31:03 -04:00
Jesse Keating
5fafe9c962 - Move the .composeinfo file into the directory we actually publish 2007-09-14 18:22:25 -04:00
Jesse Keating
ee22bb65ae - Create repoview content in the tree 2007-09-14 17:48:56 -04:00
Jesse Keating
f074a600de Use a better method to get the ks method into a repo.
Requires a newer version of pykickstart, indicate such in the spec.
2007-09-12 17:38:01 -04:00
Jesse Keating
4cb9239814 Use url line in kickstart files as a repo 2007-09-12 16:42:06 -04:00
Jesse Keating
788105f59b - Create a config class that can make using pungi modules easier. (Mark McLoughlin) 2007-09-12 14:36:28 -04:00
Jesse Keating
28c0eca953 Make base pungi class inherit from object, this makes things
better on older pythons.  (toshio)
2007-09-12 10:16:08 -04:00
Jesse Keating
9e4cc8ad1a Update with things I'd like to ignore. 2007-09-12 10:11:38 -04:00
Jesse Keating
5af01719d3 Consolidate the download code (Mark McLoughlin)
Some whitespace fixes.
2007-09-12 10:08:04 -04:00
Jesse Keating
180564aadc Remove python2.5 needs (Mark McLoughlin) 2007-09-12 09:57:54 -04:00
Jesse Keating
0d888052c4 Fix a bug with file:// repos. 2007-09-11 18:18:46 -04:00
Jesse Keating
e7779582c3 Install the man page in the spec file
reference new README location
2007-09-11 17:32:34 -04:00
Jesse Keating
33d983e8b6 Fix a bug with default destdir
Add a man page
Move documentation into doc
2007-09-11 17:07:37 -04:00
Jesse Keating
b3e1040798 We want vnc-server to do vnc installs. 2007-09-11 16:33:26 -04:00
Jesse Keating
2c785b0ba4 pungi-1.0.2-1.fc8 2007-08-31 19:19:22 -04:00
Jesse Keating
b428a139f2 Forgot to add this file to the scm 2007-08-31 19:18:30 -04:00
Jesse Keating
9322210a93 pungi-1.0.2-1.fc8 2007-08-30 16:56:15 -04:00
Jesse Keating
c88e50ee5e Fix creation of source isos.
Add source repo to kickstart file
End %packages section with %end per new pykickstart api
2007-08-30 16:56:08 -04:00
Jesse Keating
e6438b5daa pungi-1.0.1-1.fc8.1 2007-08-28 23:42:28 -04:00
Jesse Keating
ae78aea673 Default the flavor to blank. 2007-08-28 23:42:25 -04:00
Jesse Keating
72fdba8821 Unused code snippit 2007-08-27 17:12:32 -04:00
Jesse Keating
0a029cbb14 Oops, wrong help output. 2007-08-27 16:59:31 -04:00
Jesse Keating
5321a6e321 pungi-1.0.0-2.fc8 2007-08-27 15:42:26 -04:00
Jesse Keating
9f1523cb7e pungi-1.0.0-1.fc8 2007-08-27 15:34:51 -04:00
Jesse Keating
d8e95fffa3 Simplify the README file 2007-08-27 15:02:53 -04:00
Jesse Keating
736951231e s/livecd-creator/pungi/. Stole that code a little /too/ well. 2007-08-27 14:21:14 -04:00
Jesse Keating
b8457e64d5 1.0.0 release. Woohoo!
Remove dead config files.  No longer use an /etc directory.
2007-08-27 14:17:42 -04:00
Jesse Keating
29d033e838 Almost there now! 2007-08-27 12:48:54 -04:00
Jesse Keating
1357a05145 Fix issues with $basearch and mirrorlist usage. 2007-08-27 12:41:26 -04:00
Jesse Keating
d5aea6b8b2 Add a ks file for composing Fedora 8 "Fedora" 2007-08-27 11:00:11 -04:00
Jesse Keating
54737ebb70 - Set arch using rpmUtils, and do it in /usr/bin/pungi 2007-08-27 10:39:12 -04:00
Jesse Keating
c53ff26201 - Add support for $releasever in repo uris. 2007-08-27 10:33:28 -04:00
Jesse Keating
5c70f43906 Move arch setup to __init__.py so that it is done if
gather is not used.
2007-08-27 10:02:03 -04:00
Jesse Keating
a578d93a9e Add a rootcheck, stolen from livecd-creator 2007-08-26 19:48:49 -04:00
Jesse Keating
85620199c0 more done! 2007-08-26 19:45:23 -04:00
Jesse Keating
b8b7d763f9 - Add a cache dir for pungi (/var/cache/pungi) and a cli option to override
- Fix some typos
- Handle cache dir not being on same file system
2007-08-26 19:44:38 -04:00
Jesse Keating
666fb84064 Use native pykickstart for %packages handling. 2007-08-26 14:42:59 -04:00
Jesse Keating
38ff3cef53 - Pass gather a ksparser object instead, needed for yum repos
and more advanced package handling.
- Use ksparser to get repo(s) from kickstart config.
- Don't rely upon a yum conf, do all setup ourselves.
2007-08-26 14:08:27 -04:00
Jesse Keating
0b3221eafa - Pass gather a ksparser object instead, needed for yum repos
and more advanced package handling.
2007-08-25 10:04:25 -04:00
Jesse Keating
c6986f49a8 hurray for more things done. 2007-08-25 08:56:49 -04:00
Jesse Keating
cc68ffa5d8 - Use a kickstart file as input now (for cdsize and package manifest)
- Turn pkglist into a pre-parsed package dictionary
- Arrange config setting logically
- Error out on usage if no config file passed
2007-08-25 08:56:16 -04:00
Jesse Keating
cfdfdbbabe Fix a typo. Only supply logger once. 2007-08-24 21:08:13 -04:00
Jesse Keating
885dae0818 More updates for reality 2007-08-24 20:51:21 -04:00
Jesse Keating
6feda08320 - Get group files out of configured repos and create a mashup
of the comps.  Filter it and make use of it when creating repos.
- Move _doRunCommand into pypungi/__init__.py so that it can be
  easily used by all modules.  Also pass in a logger for correct
  logging
- Quiet down creatrepo calls
2007-08-24 20:45:54 -04:00
Jesse Keating
9c757202c2 Get group data from the repos instead of our own comps file.
Update ToDo with status and remove things that don't belong
2007-08-24 13:50:05 -04:00
Jesse Keating
e1d532cfc0 - hard set product_path to 'Packages' 2007-08-24 09:41:06 -04:00
Jesse Keating
c8beac9215 product_name -> name. KISS 2007-08-24 09:15:58 -04:00
Jesse Keating
54d3d6b809 - Remove a lot of configurable items and hard set them
- Move some items to cli flags only (part of moving to pykickstart)
2007-08-24 09:13:53 -04:00
Jesse Keating
9c64c98c8f destdir needs to be a cli option. 2007-08-23 23:02:09 -04:00
Jesse Keating
6c313fe24a Update the ToDo file to reflect reality 2007-08-23 22:47:20 -04:00
Jesse Keating
af625b2b9c Add a source config for Fedora spins 2007-08-23 12:59:11 -04:00
Jesse Keating
27d0a9808f Fix a tab/space issue 2007-08-21 22:11:08 -04:00
Jesse Keating
fa3f75b16d pungi-0.5.0-1.fc8 2007-08-21 22:07:19 -04:00
Jesse Keating
edf1389443 Whoops wrong version 2007-08-21 22:07:16 -04:00
Jesse Keating
0390e7d04e pungi-0.5.0-1.fc8 2007-08-21 22:06:49 -04:00
Jesse Keating
4d270948dd Prep for release 2007-08-21 22:04:07 -04:00
Jesse Keating
823e578ff0 Hurray for line feed. 2007-08-21 12:47:40 -04:00
Jesse Keating
2221c0fb66 Remove commented code that is not needed anymore. Yay! 2007-08-21 12:42:33 -04:00
Jesse Keating
c7e5e94eac - Rework how source rpms are pulled in
Always pull in 'src' packages, filter when not needed
2007-08-21 12:40:44 -04:00
Jesse Keating
6612ec39ba Move the stream handler to be in the named loggers, not the root logger
This prevents double messages to the stream coming from Pungi.
2007-08-17 09:14:18 -04:00
Jesse Keating
7aea97468c workdir is defined in the parent PungiBase class 2007-08-16 15:43:58 -04:00
Jesse Keating
3abfe92500 Fix indent issue. We're not done downloading packages at each and every package (: 2007-08-16 14:16:48 -04:00
Jesse Keating
0a7c6f4683 Fix indentation issue. 2007-08-16 10:03:13 -04:00
Jesse Keating
25fa13f329 Drop some hints as to when we're done with various tasks 2007-08-16 10:02:43 -04:00
Jesse Keating
a83f26efbd Only log debug output if there is content to log 2007-08-15 22:14:46 -04:00
Jesse Keating
55d398b5b4 set a proper format for the console output 2007-08-15 22:14:09 -04:00
jkeating@localhost.localdomain
1f85a11293 Create a PungiBase class
Make Gather and Pungi subclasses of this base class
Adjust logging to use the facility in PungiBase
Adjust logging levels to be appropriate
Drop a note when the compose is finished.
2007-08-15 19:19:13 -04:00
Jesse Keating
9cb130eb8d Create a subclass of yum to work around logging fun 2007-08-08 23:50:33 -04:00
Jesse Keating
d98fe83e7a Be verbose about what we clean 2007-08-08 21:03:11 -04:00
Jesse Keating
33a542f60b We set debuglevel when creating the yum object. 2007-08-08 10:25:51 -04:00
Jesse Keating
24cb8d04cf Make Gather() no longer a subclass of yum
Create an 'ayum' object to manipulate
rename source yum object to 'syum'
2007-08-08 10:08:47 -04:00
Jesse Keating
5fecaeb9dd pungi-0.4.1-1.fc8 2007-08-01 16:39:06 -04:00
Jesse Keating
1b1a81b2c7 - Create a new yum object for source downloads as yum
Fixes a problem where yum object resetting is not currently working
2007-08-01 16:38:57 -04:00
Jesse Keating
eee5556f50 pungi-0.4.0-1.fc8 2007-07-28 11:19:07 -04:00
Jesse Keating
829f90aa5f When reising an error, print the error too.
bump for release
2007-07-28 11:02:20 -04:00
Jesse Keating
36c629a262 split createrepo to it's own call 2007-07-28 10:59:14 -04:00
Jesse Keating
99e2ac017e pungi-0.3.9-1.fc8 2007-07-24 14:37:39 -04:00
Jesse Keating
7eff6de180 release 0.3.9 2007-07-24 12:43:08 -04:00
Jesse Keating
b04defc8e1 Removed the version number from the wrong manifest 2007-07-24 11:52:41 -04:00
Jesse Keating
228ea17bdd Remove the unused files 2007-07-24 10:54:31 -04:00
Jesse Keating
516bffb56b Update content for F8 Test1 spin 2007-07-24 10:16:02 -04:00
Jesse Keating
c6bc2d2de5 Rename things for F8 2007-07-24 10:01:10 -04:00
Jesse Keating
cabdee9e92 - Add a few more desktopy things to manifest 2007-07-24 09:40:49 -04:00
Jesse Keating
14e3a3922b Always log stdout before checking for stderr output 2007-07-20 16:59:09 -04:00
Jesse Keating
8dd1c2aa93 - Don't quote things passed to mkisofs, not a shell 2007-07-20 14:40:32 -04:00
Jesse Keating
6e819ae0f1 Add memtest86+ to manifest 2007-07-06 13:02:00 -04:00
Jesse Keating
5e4077d3eb pungi-0.3.8-1.fc8 2007-06-20 14:04:11 -04:00
Jesse Keating
d612ffdfb3 Release 0.3.8 2007-06-20 14:04:02 -04:00
Jesse Keating
7a16c58d83 Create a little package sack out of dep providers to grab just the newest ones 2007-06-19 22:19:19 -04:00
Jesse Keating
7c88b058e1 Point to the right manifest file in pungi.conf 2007-06-13 18:04:20 -04:00
Jesse Keating
51b7c6d81a Don't use flavor for a log file if no flavor set (Trac #48) 2007-06-13 18:03:29 -04:00
Jesse Keating
a5fdee3d55 An empty list doesn't equate to None. Who knew (:
Fixes broken dep logging
2007-06-11 20:45:32 -04:00
Jesse Keating
d507bed1b2 Use universal newlines in getting process output (Trac #44) 2007-06-11 14:59:18 -04:00
Jesse Keating
02539d5d9e Enable the source repo in yum configs (Trac #47) 2007-06-11 14:56:43 -04:00
Jesse Keating
20d68be58d Add a install target to make (Trac #37) 2007-06-11 14:37:35 -04:00
Jesse Keating
ec285d1c32 Added tag f7 for changeset 49ffb6153da1 2007-06-11 14:34:32 -04:00
Jesse Keating
0487c7aadd pungi-0.3.7-1.fc7 2007-05-30 10:46:58 -04:00
Jesse Keating
1eb9ea938f prep for release and update comps file 2007-05-30 10:46:55 -04:00
Jesse Keating
a300431630 When setting default cdsize, value must be string. 2007-05-25 18:56:09 -04:00
Jesse Keating
c8e8f436b5 Remove leftover size comparison code snippit. 2007-05-25 18:50:37 -04:00
Jesse Keating
55f643eb7d pungi-0.3.6-1.fc7 2007-05-25 14:30:21 -04:00
Jesse Keating
0e7a34a453 prep for dist 2007-05-25 14:30:13 -04:00
Jesse Keating
69bf86d8a6 Better handle CD size variable (float vs string and comments) 2007-05-25 14:28:38 -04:00
Jesse Keating
3ca782105d pungi-0.3.5-1.fc7 2007-05-24 08:56:22 -04:00
Jesse Keating
5c6905f6ff Change the version correctly 2007-05-24 08:56:16 -04:00
Jesse Keating
e111bec37b pungi-0.3.4-1.fc7 2007-05-24 08:52:08 -04:00
Jesse Keating
1dfca44ec1 Prep for release 2007-05-24 08:52:02 -04:00
Jesse Keating
c0f3f63202 - Use the right flavor in the Everything configs 2007-05-24 08:51:51 -04:00
Jesse Keating
30b9b6bfa6 pungi-0.3.4-1.fc7 2007-05-24 02:06:48 -04:00
Jesse Keating
defce836a2 Prep for release 2007-05-24 02:06:33 -04:00
Jesse Keating
804be3f018 Use a packages checksum to validate cached download
Using a package size is not good enough, fails to see
a changed gpg sig.
2007-05-24 02:06:25 -04:00
Jesse Keating
01d756a34a Wireshark-gnome deserves to be optional on the Fedora spin 2007-05-23 16:17:46 -04:00
Jesse Keating
f0500348f3 pungi-0.3.3-1.fc7 2007-05-23 12:45:29 -04:00
Jesse Keating
7baf239914 Prepare for release 2007-05-23 12:44:08 -04:00
Jesse Keating
c77150cc11 Even more files, and a README because this is a lot of files. 2007-05-23 11:53:24 -04:00
Jesse Keating
f3924cd7f9 Add some more files that we use 2007-05-23 11:29:18 -04:00
Jesse Keating
565938526e - Commit config files used for producing Fedora 7
- Default pungi.conf file to using Fedora 7 stuff
2007-05-23 11:20:17 -04:00
Jesse Keating
ef38a79664 pungi-0.3.2-1.fc7 2007-05-21 12:09:00 -04:00
458 changed files with 88087 additions and 15148 deletions

19
.gitignore vendored Normal file
View File

@ -0,0 +1,19 @@
*.py[co]
*~
*.egg-info
MANIFEST
build/*
dist/*
doc/_build
noarch/*
tests/data/repo
tests/data/repo-krb5-lookaside
tests/_composes
htmlcov/
.coverage
.eggs
.idea/
.tox
.venv
.kdev4/
pungi.kdev4

View File

@ -1,4 +0,0 @@
syntax: glob
*.pyc
*~
build/*

28
.hgtags
View File

@ -1,28 +0,0 @@
e80b96291cfe23c4c21b2e668d8d80a8998c7cfc pungi--
f755487fdd539c3a68296c0dc7b6c6dc49dccb98 pungi-0.1.0-1%{?dist}
d9bda840074f8f5e7b8844007e9951cd55ad9c1d pungi--
baa55b9774642535467104c3f6b268671cc35e08 pungi-0.1.0-1
902402e675943d6c3186b924a9cff89d539b06f9 pungi-0.1.0-1
14a5e625d91034b7dcb1f2b26486827929e87e24 pungi-0.1.0-1
b13071d9363851d2766e9efaf80e9e13feec7a0c pungi-0.1.0-1
00326e01cc7dd77f527d1a70e97fa907f35ce669 pungi-0.1.0-1
591cf30beec90deb8b01aaef07e042d8878f4f09 pungi-0.1.1-1
9f954716abd9c8db453b9f1b56f64e0defd8fa1d FC-6
f0cbd4fbc9e7915fa94588237827e0a1379ec823 pungi--
c5e81c8e1adc642b15e5aac713ae2e58a386c9b9 pungi-0.2.0-1
f90b645121cb2f794ceda3c4be050c53d36a7bec pungi-0.2.0-1
ebfe0e963db6d7b652f63f99aaec121e7ff19074 pungi-0.2.1-1
769a8e08d77a2234295449282b16ca38ff4d846e pungi-0.2.2-1
ba049c3454d5dae9326d8050bb0d7d8116982ca4 f7-test1
780520383876b76dd06fa013e1a41ddd6bf0901e pungi-0.2.3-1
158bd9a170892b43645caed12bddc3602ef3be4d pungi-0.2.3-1
6659955ccfdf29ecd6027bd3770f80d815720af0 pungi-0.2.3-1
9f7b5877c32c533d00ea6baa67057ce424a40a61 pungi-0.2.3-1
7ea08753383766ce36bb49fef6d4fcf44158ad26 pungi-0.2.3-1
65596b024b8380bd72c6faec00d37820ada1444d pungi-0.2.4-1
5e3332cfa2bb723f438507313836c299fcc99cff pungi-0.2.5-1
61146ab008d70cb4ce294d14a8465c05613e91e5 pungi-0.2.6-1
6de1d8a07c7b75fc069c72eaa9b3cb4ecaa5ad5a pungi-0.2.7-1
c150a9d7a125e6c25384fbbf8080d7532191b587 f7-test2
9c5cdf9e045ab0c804d85a50b24107b108aa2da5 pungi-0.2.8-1
f1ee949b238b004ee53c6b30915e69352274f583 pungi-0.3.0-1

41
1715.patch Normal file
View File

@ -0,0 +1,41 @@
From 432b0bce0401c4bbcd1a958a89305c475a794f26 Mon Sep 17 00:00:00 2001
From: Adam Williamson <awilliam@redhat.com>
Date: Jan 19 2024 07:25:09 +0000
Subject: checks: don't require "repo" in the "ostree" schema
Per @siosm in https://pagure.io/pungi-fedora/pull-request/1227
this option "is deprecated and not needed anymore", so Pungi
should not be requiring it.
Merges: https://pagure.io/pungi/pull-request/1714
Signed-off-by: Adam Williamson <awilliam@redhat.com>
---
diff --git a/pungi/checks.py b/pungi/checks.py
index a340f93..db8b297 100644
--- a/pungi/checks.py
+++ b/pungi/checks.py
@@ -1066,7 +1066,6 @@ def make_schema():
"required": [
"treefile",
"config_url",
- "repo",
"ostree_repo",
],
"additionalProperties": False,
diff --git a/pungi/phases/ostree.py b/pungi/phases/ostree.py
index 90578ae..2649cdb 100644
--- a/pungi/phases/ostree.py
+++ b/pungi/phases/ostree.py
@@ -85,7 +85,7 @@ class OSTreeThread(WorkerThread):
comps_repo = compose.paths.work.comps_repo(
"$basearch", variant=variant, create_dir=False
)
- repos = shortcuts.force_list(config["repo"]) + self.repos
+ repos = shortcuts.force_list(config.get("repo", [])) + self.repos
if compose.has_comps:
repos.append(translate_path(compose, comps_repo))
repos = get_repo_dicts(repos, logger=self.pool)

View File

@ -1,6 +1,8 @@
Authors:
Jesse Keating <jkeating at redhat dot com>
Dennis Gilmore <dennis at ausil dot us>
Daniel Mach <dmach at redhat dot com>
Contributors:
@ -9,3 +11,6 @@ Essien Ita Essien <essien at wazobialinux dot com>
James Bowes <jbowes at redhat dot com>
Tom Callaway <tcallawa at redhat dot com>
Joel Andres Granados <jgranado at redhat dot com>
<proski at fedoraproject dot org>
Mark McLoughlin <markmc at redhat dot com>
Jeremy Cline <jcline at redhat dot com>

View File

@ -1,5 +1,5 @@
Pungi - a Fedora release compose tool
Copyright (C) 2006 Jesse Keating
Pungi - Distribution compose tool
Copyright (C) 2006-2015 Red Hat, Inc.
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
@ -11,6 +11,4 @@
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., 675 Mass Ave, Cambridge, MA 02139, USA.
along with this program; if not, see <https://gnu.org/licenses/>.

185
Changelog
View File

@ -1,185 +0,0 @@
* Tue May 15 2007 Jesse Keating <jkeating@redhat.com>
- Don't quote ISO label, not running mkisofs in shell
- Apply sparc patches (spot)
- Fix cached downloads comparing correctly
- Shorten 'development' to 'devel' in default config, more space for mkisofs
- Handle config file missing better (jgranado)
* Fri Apr 06 2007 Jesse Keating <jkeating@redhat.com>
- Fix comments in config file
* Mon Apr 02 2007 Jesse Keating <jkeating@redhat.com>
- Remove incompatible fc6 config files
- Update default config file with comments / new options
- Update comps file
* Mon Mar 26 2007 Jesse Keating <jkeating@redhat.com>
- Enable source iso building again.
* Fri Mar 23 2007 Jesse Keating <jkeating@redhat.com>
- Don't try a rescue if the script doesn't exist (prarit)
* Thu Mar 22 2007 Jesse Keating <jkeating@redhat.com>
- Pass flavor off to buildinstall if it is set (wwoods)
* Fri Mar 16 2007 Jesse Keating <jkeating@redhat.com>
- Fix a logic flaw in the depsolving loop
* Thu Mar 15 2007 Jesse Keating <jkeating@redhat.com>
- Use yum's built in exclude handling
- Use yum's built in conditional handling for things from comps
- Do excludes before group handling.
- Get all potential matches for deps, let install time figure
the best one to use.
- Work around false positive 'unmatched' packages (globs are fun)
- Change how depsolving is done
- Get all potential matches for a dep, instead of our 'best'
our 'best' may not be the same as install time best.
- Remove anaconda code, use direct yum functions to get deps
- Use a True/False flag to depsolve instead of iterating over
a dict.
- Log what packages are being added for which reasons.
* Tue Mar 14 2007 Jesse Keating <jkeating@redhat.com>
- Do things faster/smarter if we've only asked for one disc
* Tue Mar 13 2007 Jesse Keating <jkeating@redhat.com>
- log the rpm2cpio stuff for release notes
- correctly capture errors from subprocess
* Wed Mar 07 2007 Jesse Keating <jkeating@redhat.com>
- Call createrepo ourselves for the tree, not buildinstall's job
* Tue Mar 06 2007 Jesse Keating <jkeating@redhat.com>
- Convert from commands to subprocess for things we call out
* Fri Mar 02 2007 Jesse Keating <jkeating@redhat.com>
- Add kickstart %packages syntax support to package manifest
- Make the list we hand off to yum to search for as unique as we can
* Wed Feb 28 2007 Jesse Keating <jkeating@redhat.com>
- Update Fedora 7 comps file.
- Tag for F7 Test2
* Mon Feb 26 2007 Jesse Keating <jkeating@redhat.com>
- Fix gathering of srpms (thanks skvidal)
* Wed Feb 21 2007 Jesse Keating <jkeating@redhat.com>
- Don't use TMPDIR with buildinstall for now
* Fri Feb 16 2007 Jesse Keating <jkeating@redhat.com>
- Make use of anaconda's TMPDIR support
- Put yum tempdirs in the workdir
- Add a version option to cli arguments
- Make cdsize a config option
* Thu Feb 15 2007 Jesse Keating <jkeating@redhat.com>
- Various logging tweaks
- Use -d flag in createrepo for sqlite blobs
- Add pydoc stuff to various functions
- Support comments in the package manifest
* Wed Feb 14 2007 Jesse Keating <jkeating@redhat.com>
- Add logging patch from jbowes
* Tue Feb 13 2007 Jesse Keating <jkeating@redhat.com>
- Fix part of the patch from Essien
- Add Contributors to the Authors file
- Adjust the Makefile so that srpm doesn't cause a tag
- Merged changes from Will Woods
- Write out some tree description files
- Don't traceback on existing files in download area (not sure this will stay)
- Style fixed some stuff from Will
* Mon Feb 12 2007 Jesse Keating <jkeating@redhat.com>
- Add new Make targets (Essien Ita Essien)
- Add runtime flags for doing specific stages of the compose (Essien Ita Essien)
- Add ability to define destdir on the cli to override conf file
- Clean up optionparse stuff, print usage if arg list is too small
* Thu Feb 08 2007 Jesse Keating <jkeating@redhat.com>
- Add support for globbing in manifest
* Tue Feb 06 2007 Jesse Keating <jkeating@redhat.com>
- yum bestPackagesFromList takes an arch argument. Fixes ppc64 bug
- Don't use 'returnSimple' anymore, deprecated in yum api
- Speed up depsolving a bit by tracking solved deps
* Sat Feb 03 2007 Jesse Keating <jkeating@redhat.com>
- Be able to opt-out of a bugurl since buildinstall supports this
- Make isodir an object of pungi (wwoods)
* Tue Jan 30 2007 Jesse Keating <jkeating@redhat.com>
- implantmd5 _then_ sha1sum.
* Mon Jan 29 2007 Jesse Keating <jkeating@redhat.com>
- Update the comps file again from F7
- Fix the ppc boot flags
- Clean up SRPM-disc junk
- add bugurl config option for anaconda betanag
* Thu Jan 25 2007 Jesse Keating <jkeating@redhat.com>
- Update the comps file from F7
* Wed Jan 24 2007 Jesse Keating <jkeating@redhat.com>
- Add a "flavor" option (such as Desktop)
- Move packageorder file into workdir
- Use some anaconda code to depsolve, gets better (and more common) results
* Tue Jan 23 2007 Jesse Keating <jkeating@redhat.com>
- Now use a manifest to determine what to pull in, not comps itself
- Add a minimal-manifest for test composes
- Add current F7 comps file for test composes
- Bump the iso size to what was used in FC6
* Wed Jan 17 2007 Jesse Keating <jkeating@redhat.com>
- Move splittree workdirs into work/ at the end of the run
* Tue Jan 16 2007 Jesse Keating <jkeating@redhat.com>
- Remove our splittree for rawhide
- Remove old main() sections from pungi.py and gather.py
- Require yum 3.0.3 or newer
- Add rescueCD support
* Wed Dec 13 2006 Jesse Keating <jkeating@redhat.com>
- Fix a bug in DVD repodata
- Add correct ppc boot args
- Set ppc arch correctly
* Mon Dec 11 2006 Jesse Keating <jkeating@redhat.com>
- Now able to get release note files from release note packages.
- Add a config file for the source run
* Sat Dec 9 2006 Jesse Keating <jkeating@redhat.com>
- Now able to do srpms, lots of changes
* Fri Nov 17 2006 Jesse Keating <jkeating@redhat.com>
- First pass at a config file, lots of changes
* Wed Nov 8 2006 Jesse Keating <jkeating@redhat.com>
- Shuffle things around for dist-utils
- Add setup.py and such to do installs
* Tue Nov 7 2006 Jesse Keating <jkeating@redhat.com>
- pungi.py
Turn on split repo creation
Add iso creation code
Add DVD creation code
- __init.py__
Turn on split repo creation
Turn on iso creation
* Mon Nov 6 2006 Jesse Keating <jkeating@redhat.com>
- pungi.py
use splittree.py as a module rather than a script
use same layout as current fedora trees
- gather.py
use same layout as current fedora trees
* Wed Nov 1 2006 Jesse Keating <jkeating@redhat.com>
- First changelog entry
- pungi.py
Code up splittree, use our own for now with patches
Code up createSplitRepodata
- Now able to create installable tree and create split CD dirs suitable for
mkisofs

521
GPL
View File

@ -1,272 +1,339 @@
GNU GENERAL PUBLIC LICENSE
Version 2, June 1991
The GNU General Public License (GPL)
Version 2, June 1991
Copyright (C) 1989, 1991 Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.
Copyright (C) 1989, 1991 Free Software Foundation, Inc.
59 Temple Place, Suite 330, 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
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 Lesser General Public License instead.) You can apply it to
your programs, too.
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.
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.
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.
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.
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.
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.
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.
The precise terms and conditions for copying, distribution and
modification follow.
GNU GENERAL PUBLIC LICENSE
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
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".
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.
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.
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.
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:
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.
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.
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.)
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.
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.
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.
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:
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,
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,
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.)
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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
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.
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.
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
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 Street, Fifth Floor, Boston, MA 02110-1301 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 Lesser General
Public License instead of this License.

View File

@ -1,10 +1,16 @@
include Authors
include Changelog
include AUTHORS
include COPYING
include GPL
include PLAN.*
include README
include TESTING
include ToDo
include pungi.spec
include config/*
include setup.cfg
include tox.ini
include share/*
include share/multilib/*
include doc/*
include doc/_static/*
include tests/*
include tests/data/*
include tests/data/specs/*
recursive-include tests/fixtures *
global-exclude *.py[co]
global-exclude *~ *.sw? \#*\#

View File

@ -1,44 +1,113 @@
.PHONY: all clean doc log test
PKGNAME=pungi
VERSION=$(shell rpm -q --qf "%{VERSION}\n" --specfile ${PKGNAME}.spec)
RELEASE=$(shell rpm -q --qf "%{RELEASE}\n" --specfile ${PKGNAME}.spec)
HGTAG=${PKGNAME}-$(VERSION)-$(RELEASE)
VERSION=$(shell rpm -q --qf "%{VERSION}\n" --specfile ${PKGNAME}.spec | head -n1)
RELEASE=$(shell rpm -q --qf "%{RELEASE}\n" --specfile ${PKGNAME}.spec | head -n1)
GITTAG=${PKGNAME}-$(VERSION)
PKGRPMFLAGS=--define "_topdir ${PWD}" --define "_specdir ${PWD}" --define "_sourcedir ${PWD}/dist" --define "_srcrpmdir ${PWD}" --define "_rpmdir ${PWD}" --define "_builddir ${PWD}"
RPM="noarch/${PKGNAME}-$(VERSION)-$(RELEASE).noarch.rpm"
SRPM="${PKGNAME}-$(VERSION)-$(RELEASE).src.rpm"
PYTEST=pytest
default: all
all:
@echo "Nothing to do"
all: help
help:
@echo "Usage: make <target>"
@echo
@echo "Available targets are:"
@echo " help show this text"
@echo " clean remove python bytecode and temp files"
@echo " doc build documentation"
@echo " install install program on current system"
@echo " test run tests"
@echo " test-coverage run tests and generate a coverage report"
@echo " test-compose run a small teest compose (requires test data)"
@echo " test-data build test data (requirement for running tests)"
@echo
@echo "Available rel-eng targets are:"
@echo " archive create source tarball"
@echo " log display changelog for spec file"
@echo " tag create a git tag according to version and release from spec file"
@echo " rpm build rpm"
@echo " srpm build srpm"
@echo " rpminstall build rpm and install it"
@echo " release build srpm and create git tag"
tag:
@hg tag -m "$(HGTAG)" $(HGTAG)
# @hg push
@git tag -a -m "Tag as $(GITTAG)" -f $(GITTAG)
@echo "Tagged as $(GITTAG)"
Changelog:
(GIT_DIR=.git git log > .changelog.tmp && mv .changelog.tmp Changelog; rm -f .changelog.tmp) || (touch Changelog; echo 'git directory not found: installing possibly empty changelog.' >&2)
log:
@(LC_ALL=C date +"* %a %b %e %Y `git config --get user.name` <`git config --get user.email`> - VERSION"; git log --pretty="format:- %s (%ae)" | sed -r 's/ \(([^@]+)@[^)]+\)/ (\1)/g' | cat) | less
archive:
@rm -f Changelog
@rm -f MANIFEST
@make Changelog
@rm -rf ${PKGNAME}-$(VERSION)/
@python setup.py sdist > /dev/null
@echo "The archive is in dist/${PKGNAME}-$(VERSION).tar.gz"
@python setup.py sdist --formats=bztar > /dev/null
@echo "The archive is in dist/${PKGNAME}-$(VERSION).tar.bz2"
srpm: archive
@rm -f $(SRPM)
@rpmbuild -bs ${PKGRPMFLAGS} ${PKGNAME}.spec
@echo "The srpm is in $(SRPM)"
rpm: archive
@rpmbuild --clean -bb ${PKGRPMFLAGS} ${PKGNAME}.spec
@echo "The rpm is in $(RPM)"
rpminstall: rpm
@rpm -ivh --force $(RPM)
release: tag srpm
install:
@python setup.py install
clean:
@rm -f *.rpm
@rm -rf noarch
@rm -f *.tar.gz
@rm -rf dist
@rm -f MANIFEST
@python setup.py clean
@rm -vf *.rpm
@rm -vrf noarch
@rm -vf *.tar.gz
@rm -vrf dist
@rm -vf MANIFEST
@rm -vf Changelog
@find . -\( -name "*.pyc" -o -name '*.pyo' -o -name "*~" -o -name "__pycache__" -\) -delete
@find . -depth -type d -a -name '*.egg-info' -exec rm -rf {} \;
test:
$(PYTEST) $(PYTEST_OPTS)
test-coverage:
$(PYTEST) --cov=pungi --cov-report term --cov-report html --cov-config tox.ini $(PYTEST_OPTS)
test-data:
./tests/data/specs/build.sh
test-compose:
cd tests && ./test_compose.sh
test-multi-compose:
PYTHONPATH=$$(pwd) PATH=$$(pwd)/bin:$$PATH pungi-orchestrate --debug start tests/data/multi-compose.conf
doc:
cd doc; make html

9
README
View File

@ -1,9 +0,0 @@
Pungi
An anaconda based installation spin tool
This project is aimed at making a public / free tool to spin installation
trees/isos of Fedora. It will be written in python (for many obvious
reasons). Code style I hope will be of a simple "master" process that can
call any number of subprocesses depending on a configuration set.
See http://hosted.fedoraproject.org/projects/pungi for more information.

39
README.md Normal file
View File

@ -0,0 +1,39 @@
# Pungi
*Pungi* is a distribution compose tool.
Composes are release snapshots that contain release deliverables such as:
- installation trees
- RPMs
- repodata
- comps
- (bootable) ISOs
- kickstart trees
- anaconda images
- images for PXE boot
## Tool overview
*Pungi* consists of multiple separate executables backed by a common library.
The main entry-point is the `pungi-koji` script. It loads the compose
configuration and kicks off the process. Composing itself is done in phases.
Each phase is responsible for generating some artifacts on disk and updating
the `compose` object that is threaded through all the phases.
*Pungi* itself does not actually do that much. Most of the actual work is
delegated to separate executables. *Pungi* just makes sure that all the
commands are invoked in the appropriate order and with correct arguments. It
also moves the artifacts to correct locations.
## Links
- Documentation: https://docs.pagure.org/pungi/
- Upstream GIT: https://pagure.io/pungi/
- Issue tracker: https://pagure.io/pungi/issues
- Questions can be asked in the *#fedora-releng* IRC channel on irc.libera.chat
or in the matrix room
[`#releng:fedoraproject.org`](https://matrix.to/#/#releng:fedoraproject.org)

74
TODO Normal file
View File

@ -0,0 +1,74 @@
Random thoughts on what needs to be done before Pungi 4.0 is completed.
Define building blocks and their metadata
=========================================
* rpms in yum repos
* comps
* kickstart trees
* isos
* kickstart trees
* bootable images
* readme files
* license(s)
Compose structure
=================
* topdir
* work, logs, etc.
* compose
* $variant
* $arch
* $content_type (rpms, isos, kickstart trees, etc.)
* actual content
Split Pungi into smaller well-defined tools
===========================================
* process initial packages
* comps
* json mapping
* ???
* grab initial package set
* yum repos
* koji instance (basically what mash does today)
* resolve deps (gather)
* self-hosting
* fulltree
* multilib
* langpacks
* create repos
* create install images
* lorax
* create isos
* isos
* bootable
* hybrid
* implant md5sum
* jigdo
* checksums
* run tests
* just quick sanity tests
* notification
* email
* messagebus
Unsorted
========
* run any tasks in koji or local host
* support for non-rpm content? (java artifacts, etc.)
* docs!
* unit tests!
* use productmd for metadata: https://github.com/release-engineering/productmd/
* use next-gen tools: createrepo_c, mergerepo_c, dnf, hawkey, libcomps

5
ToDo
View File

@ -1,5 +0,0 @@
Drop release notes files in the tree
Make pungi use the Fedora layout, composedir/topdir/os/<arch>/Fedora, composedir/topdir/<arch>/iso/, composedir/topdir/<arch>/debug/
Get debuginfo packages?
Put working items in composedir/work
Create a logging system, log to composedir/logs/

File diff suppressed because it is too large Load Diff

View File

@ -1,12 +0,0 @@
kernel
xorg-x11-fonts-ISO8859-1-75dpi
busybox-anaconda
dejavu-lgc-fonts
xorg-x11-fonts-base
memtest86+
xorg-x11-drivers
selinux-policy-targeted
anaconda-runtime
man
joe
grub

View File

@ -1,21 +0,0 @@
# Pungi config file
#
# # or ; can be used at the start of a line, ; only to comment inline.
[default]
product_name = Fedora ; The name used during install
product_path = Fedora ; The directory where RPMS go
iso_basename = F ; The first part of the iso file name
bugurl = http://bugzilla.redhat.com ; Used for betanag
comps = /etc/pungi/comps-fc7.xml ; Used to define package groupings and default installs
manifest = /etc/pungi/minimal-manifest ; Used to determine what to bring in. Supports Kickstart syntax
yumconf = /etc/pungi/yum.conf.x86_64 ; Used to determine where to gather packages from
destdir = /srv/pungi/Fedora ; Top level compose directory, must be clean
cachedir = /srv/pungi/cache ; Cache used for repeat runs
arch = x86_64 ; What arch to compose (must be same arch as system)
version = devel ; Used both in install and part of the dest tree
flavor = Custom ; Further define a given cut of the package set
discs = 1 ; Number of discs needed to fit data.
#cdsize = 4608.0 ; Not used if disc count is 1
getsource = Yes ; Used to determine if we want source packages or not

View File

@ -1,30 +0,0 @@
[main]
#keepcache=0
#debuglevel=2
pkgpolicy=newest
distroverpkg=redhat-release
tolerant=1
exactarch=1
obsoletes=1
gpgcheck=1
reposdir=./
#plugins=1
metadata_expire=1800
#exclude=\*.i?86
# PUT YOUR REPOS HERE OR IN separate files named file.repo
# in /etc/yum.repos.d
[development]
name=Fedora Core - Development
#baseurl=http://download.fedora.redhat.com/pub/fedora/linux/core/development/$basearch/os/
mirrorlist=http://mirrors.fedoraproject.org/mirrorlist?repo=rawhide&arch=i386
enabled=1
gpgcheck=0
[development-source]
name=Fedora Core - Development Source
#baseurl=http://download.fedora.redhat.com/pub/fedora/linux/core/development/source/SRPMS
mirrorlist=http://mirrors.fedoraproject.org/mirrorlist?repo=rawhide-source&arch=i386
enabled=1
gpgcheck=0

View File

@ -1,30 +0,0 @@
[main]
#keepcache=0
#debuglevel=2
pkgpolicy=newest
distroverpkg=redhat-release
tolerant=1
exactarch=1
obsoletes=1
gpgcheck=1
reposdir=./
#plugins=1
metadata_expire=1800
#exclude=\*.i?86
# PUT YOUR REPOS HERE OR IN separate files named file.repo
# in /etc/yum.repos.d
[development]
name=Fedora Core - Development
#baseurl=http://download.fedora.redhat.com/pub/fedora/linux/core/development/x86_64/os/
mirrorlist=http://mirrors.fedoraproject.org/mirrorlist?repo=rawhide&arch=x86_64
enabled=1
gpgcheck=0
[development-source]
name=Fedora Core - Development Source
#baseurl=http://download.fedora.redhat.com/pub/fedora/linux/core/development/x86_64/os/
mirrorlist=http://mirrors.fedoraproject.org/mirrorlist?repo=rawhide-source&arch=x86_64
enabled=1
gpgcheck=0

View File

@ -0,0 +1,2 @@
# Clean up pungi cache
d /var/cache/pungi/createrepo_c/ - - - 30d

View File

@ -0,0 +1,19 @@
This directory contains scripts to compare YUM and DNF based gathering code in
Pungi.
There are two scripts to help re-run the depsolving on existing code. As input
they need .conf and .log file from an existing compose. They collect correct
command line options from them and run the respective tool.
Run:
$ run-dnf.sh Server.x86_64.conf
$ run-yum.sh Server.x86_64.conf
The results are stored in a file with .log.dnf or .log.yum extensions. When
--interactive is used as second argument of the scripts, the output is printed
to terminal (useful for running in debugger).
To compare the RPM package lists, run:
$ ./pungi-compare-depsolving Server.x86_64.log.yum Server.x86_64.log.dnf

View File

@ -0,0 +1,63 @@
#!/usr/bin/python
from __future__ import print_function
import argparse
import os
import sys
here = sys.path[0]
if here != '/usr/bin':
# Git checkout
sys.path.insert(0, os.path.abspath(os.path.join(os.path.dirname(__file__), "..", "..")))
from kobo.rpmlib import parse_nvra, make_nvra
from pungi.wrappers.pungi import PungiWrapper
def read_rpms(fn):
pw = PungiWrapper()
with open(fn, "r") as f:
data, _, _ = pw.parse_log(f)
result = set()
for i in data["rpm"]:
nvra = parse_nvra(i["path"])
result.add(make_nvra(nvra, add_rpm=True))
return result
parser = argparse.ArgumentParser()
parser.add_argument('old', metavar='OLD', default='pungi-yum.log')
parser.add_argument('new', metavar='NEW', default='pungi-dnf.log')
args = parser.parse_args()
yum_rpms = read_rpms(args.old)
dnf_rpms = read_rpms(args.new)
removed = yum_rpms - dnf_rpms
added = dnf_rpms - yum_rpms
print("ADDED: %s" % len(added))
for i in sorted(added):
print(" %s" % i)
print()
print("REMOVED: %s" % len(removed))
for i in sorted(removed):
print(" %s" % i)
print()
print("ADDED: %6s" % len(added))
print("REMOVED: %6s" % len(removed))
print("YUM RPMS: %6s" % len(yum_rpms))
print("DNF RPMS: %6s" % len(dnf_rpms))
print("ALL RPMS: %6s" % len(yum_rpms | dnf_rpms))
if added or removed:
sys.exit(1)

View File

@ -0,0 +1,24 @@
#!/bin/bash
set -e
set -u
set -o pipefail
HERE=$(dirname "$0")
PATH=$HERE/../../bin:$PATH
PYTHONPATH=$HERE/../../:${PYTHONPATH:-}
export PATH PYTHONPATH
CONF=$1
LOG=${CONF%%.conf}.log
ARCH=$(head -n1 "$LOG" | tr ' ' '\n' | grep -- '--arch=')
CMD=(pungi-gather "--config=$CONF" "$ARCH" $(head -n1 "$LOG" | tr ' ' '\n' | grep '^--\(selfhosting\|fulltree\|greedy\|multilib\)'))
echo "${CMD[@]}"
if [ $# -le 1 ] || [ "$2" != "--interactive" ]; then
exec >"$LOG.dnf"
fi
exec 2>&1
exec "${CMD[@]}"

View File

@ -0,0 +1,28 @@
#!/bin/sh
set -e
set -o pipefail
set -u
export LANG=C
HERE=$(dirname "$0")
PATH=$HERE/../../bin:$PATH
PYTHONPATH=$HERE/../../
export PATH PYTHONPATH
CONF="$1"
LOG=${CONF%%.conf}.log
tempdir=$(mktemp -d)
trap 'rm -rf $tempdir' EXIT
cmd=$(head -n1 "$LOG" | cut -d' ' -f2- | sed "s@--\(destdir\|cachedir\)=\(/[^/ ]*\)*@--\1=$tempdir/\1@g" | sed 's/^pungi3/pungi/' | sed "s@--config=/\([^/]*/\)*work/[^/]*/pungi/\([^ ]*\)@--config=$1@g")
echo "$cmd"
if [ $# -le 1 ] || [ "$2" != "--interactive" ]; then
exec >"$LOG.yum"
fi
exec 2>&1
$cmd

177
doc/Makefile Normal file
View File

@ -0,0 +1,177 @@
# Makefile for Sphinx documentation
#
# You can set these variables from the command line.
SPHINXOPTS =
SPHINXBUILD = sphinx-build
PAPER =
BUILDDIR = _build
# User-friendly check for sphinx-build
ifeq ($(shell which $(SPHINXBUILD) >/dev/null 2>&1; echo $$?), 1)
$(error The '$(SPHINXBUILD)' command was not found. Make sure you have Sphinx installed, then set the SPHINXBUILD environment variable to point to the full path of the '$(SPHINXBUILD)' executable. Alternatively you can add the directory with the executable to your PATH. If you don't have Sphinx installed, grab it from http://sphinx-doc.org/)
endif
# Internal variables.
PAPEROPT_a4 = -D latex_paper_size=a4
PAPEROPT_letter = -D latex_paper_size=letter
ALLSPHINXOPTS = -d $(BUILDDIR)/doctrees $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) .
# the i18n builder cannot share the environment and doctrees with the others
I18NSPHINXOPTS = $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) .
.PHONY: help clean html dirhtml singlehtml pickle json htmlhelp qthelp devhelp epub latex latexpdf text man changes linkcheck doctest gettext
help:
@echo "Please use \`make <target>' where <target> is one of"
@echo " html to make standalone HTML files"
@echo " dirhtml to make HTML files named index.html in directories"
@echo " singlehtml to make a single large HTML file"
@echo " pickle to make pickle files"
@echo " json to make JSON files"
@echo " htmlhelp to make HTML files and a HTML help project"
@echo " qthelp to make HTML files and a qthelp project"
@echo " devhelp to make HTML files and a Devhelp project"
@echo " epub to make an epub"
@echo " latex to make LaTeX files, you can set PAPER=a4 or PAPER=letter"
@echo " latexpdf to make LaTeX files and run them through pdflatex"
@echo " latexpdfja to make LaTeX files and run them through platex/dvipdfmx"
@echo " text to make text files"
@echo " man to make manual pages"
@echo " texinfo to make Texinfo files"
@echo " info to make Texinfo files and run them through makeinfo"
@echo " gettext to make PO message catalogs"
@echo " changes to make an overview of all changed/added/deprecated items"
@echo " xml to make Docutils-native XML files"
@echo " pseudoxml to make pseudoxml-XML files for display purposes"
@echo " linkcheck to check all external links for integrity"
@echo " doctest to run all doctests embedded in the documentation (if enabled)"
clean:
rm -rf $(BUILDDIR)/*
html:
$(SPHINXBUILD) -b html $(ALLSPHINXOPTS) $(BUILDDIR)/html
@echo
@echo "Build finished. The HTML pages are in $(BUILDDIR)/html."
dirhtml:
$(SPHINXBUILD) -b dirhtml $(ALLSPHINXOPTS) $(BUILDDIR)/dirhtml
@echo
@echo "Build finished. The HTML pages are in $(BUILDDIR)/dirhtml."
singlehtml:
$(SPHINXBUILD) -b singlehtml $(ALLSPHINXOPTS) $(BUILDDIR)/singlehtml
@echo
@echo "Build finished. The HTML page is in $(BUILDDIR)/singlehtml."
pickle:
$(SPHINXBUILD) -b pickle $(ALLSPHINXOPTS) $(BUILDDIR)/pickle
@echo
@echo "Build finished; now you can process the pickle files."
json:
$(SPHINXBUILD) -b json $(ALLSPHINXOPTS) $(BUILDDIR)/json
@echo
@echo "Build finished; now you can process the JSON files."
htmlhelp:
$(SPHINXBUILD) -b htmlhelp $(ALLSPHINXOPTS) $(BUILDDIR)/htmlhelp
@echo
@echo "Build finished; now you can run HTML Help Workshop with the" \
".hhp project file in $(BUILDDIR)/htmlhelp."
qthelp:
$(SPHINXBUILD) -b qthelp $(ALLSPHINXOPTS) $(BUILDDIR)/qthelp
@echo
@echo "Build finished; now you can run "qcollectiongenerator" with the" \
".qhcp project file in $(BUILDDIR)/qthelp, like this:"
@echo "# qcollectiongenerator $(BUILDDIR)/qthelp/Pungi.qhcp"
@echo "To view the help file:"
@echo "# assistant -collectionFile $(BUILDDIR)/qthelp/Pungi.qhc"
devhelp:
$(SPHINXBUILD) -b devhelp $(ALLSPHINXOPTS) $(BUILDDIR)/devhelp
@echo
@echo "Build finished."
@echo "To view the help file:"
@echo "# mkdir -p $$HOME/.local/share/devhelp/Pungi"
@echo "# ln -s $(BUILDDIR)/devhelp $$HOME/.local/share/devhelp/Pungi"
@echo "# devhelp"
epub:
$(SPHINXBUILD) -b epub $(ALLSPHINXOPTS) $(BUILDDIR)/epub
@echo
@echo "Build finished. The epub file is in $(BUILDDIR)/epub."
latex:
$(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex
@echo
@echo "Build finished; the LaTeX files are in $(BUILDDIR)/latex."
@echo "Run \`make' in that directory to run these through (pdf)latex" \
"(use \`make latexpdf' here to do that automatically)."
latexpdf:
$(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex
@echo "Running LaTeX files through pdflatex..."
$(MAKE) -C $(BUILDDIR)/latex all-pdf
@echo "pdflatex finished; the PDF files are in $(BUILDDIR)/latex."
latexpdfja:
$(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex
@echo "Running LaTeX files through platex and dvipdfmx..."
$(MAKE) -C $(BUILDDIR)/latex all-pdf-ja
@echo "pdflatex finished; the PDF files are in $(BUILDDIR)/latex."
text:
$(SPHINXBUILD) -b text $(ALLSPHINXOPTS) $(BUILDDIR)/text
@echo
@echo "Build finished. The text files are in $(BUILDDIR)/text."
man:
$(SPHINXBUILD) -b man $(ALLSPHINXOPTS) $(BUILDDIR)/man
@echo
@echo "Build finished. The manual pages are in $(BUILDDIR)/man."
texinfo:
$(SPHINXBUILD) -b texinfo $(ALLSPHINXOPTS) $(BUILDDIR)/texinfo
@echo
@echo "Build finished. The Texinfo files are in $(BUILDDIR)/texinfo."
@echo "Run \`make' in that directory to run these through makeinfo" \
"(use \`make info' here to do that automatically)."
info:
$(SPHINXBUILD) -b texinfo $(ALLSPHINXOPTS) $(BUILDDIR)/texinfo
@echo "Running Texinfo files through makeinfo..."
make -C $(BUILDDIR)/texinfo info
@echo "makeinfo finished; the Info files are in $(BUILDDIR)/texinfo."
gettext:
$(SPHINXBUILD) -b gettext $(I18NSPHINXOPTS) $(BUILDDIR)/locale
@echo
@echo "Build finished. The message catalogs are in $(BUILDDIR)/locale."
changes:
$(SPHINXBUILD) -b changes $(ALLSPHINXOPTS) $(BUILDDIR)/changes
@echo
@echo "The overview file is in $(BUILDDIR)/changes."
linkcheck:
$(SPHINXBUILD) -b linkcheck $(ALLSPHINXOPTS) $(BUILDDIR)/linkcheck
@echo
@echo "Link check complete; look for any errors in the above output " \
"or in $(BUILDDIR)/linkcheck/output.txt."
doctest:
$(SPHINXBUILD) -b doctest $(ALLSPHINXOPTS) $(BUILDDIR)/doctest
@echo "Testing of doctests in the sources finished, look at the " \
"results in $(BUILDDIR)/doctest/output.txt."
xml:
$(SPHINXBUILD) -b xml $(ALLSPHINXOPTS) $(BUILDDIR)/xml
@echo
@echo "Build finished. The XML files are in $(BUILDDIR)/xml."
pseudoxml:
$(SPHINXBUILD) -b pseudoxml $(ALLSPHINXOPTS) $(BUILDDIR)/pseudoxml
@echo
@echo "Build finished. The pseudo-XML files are in $(BUILDDIR)/pseudoxml."

557
doc/_static/phases.svg vendored Normal file
View File

@ -0,0 +1,557 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg
width="610.46454"
height="327.16599"
viewBox="0 0 610.46457 327.16599"
id="svg2"
version="1.1"
inkscape:version="1.3.2 (091e20e, 2023-11-25)"
sodipodi:docname="phases.svg"
inkscape:export-filename="/home/lsedlar/repos/pungi/doc/_static/phases.png"
inkscape:export-xdpi="90"
inkscape:export-ydpi="90"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns="http://www.w3.org/2000/svg"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:dc="http://purl.org/dc/elements/1.1/">
<sodipodi:namedview
id="base"
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1.0"
inkscape:pageopacity="1"
inkscape:pageshadow="2"
inkscape:zoom="1.5"
inkscape:cx="268"
inkscape:cy="260.66667"
inkscape:document-units="px"
inkscape:current-layer="layer1"
showgrid="false"
inkscape:window-width="1920"
inkscape:window-height="1027"
inkscape:window-x="0"
inkscape:window-y="25"
inkscape:window-maximized="1"
units="px"
inkscape:document-rotation="0"
showguides="true"
inkscape:guide-bbox="true"
fit-margin-top="7.4"
fit-margin-left="7.4"
fit-margin-right="7.4"
fit-margin-bottom="7.4"
lock-margins="true"
inkscape:showpageshadow="2"
inkscape:pagecheckerboard="0"
inkscape:deskcolor="#d1d1d1" />
<defs
id="defs4">
<marker
inkscape:isstock="true"
style="overflow:visible"
id="Arrow1Lend"
refX="0"
refY="0"
orient="auto"
inkscape:stockid="Arrow1Lend">
<path
inkscape:connector-curvature="0"
transform="matrix(-0.8,0,0,-0.8,-10,0)"
style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1pt;stroke-opacity:1"
d="M 0,0 5,-5 -12.5,0 5,5 Z"
id="path4451" />
</marker>
</defs>
<metadata
id="metadata7">
<rdf:RDF>
<cc:Work
rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
</cc:Work>
</rdf:RDF>
</metadata>
<g
transform="matrix(1.066667,0,0,1.066667,-99.07321,-903.45239)"
id="layer1"
inkscape:groupmode="layer"
inkscape:label="Vrstva 1">
<g
transform="translate(98.243246,-80.817124)"
id="g3411">
<rect
style="fill:#8ae234;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
id="rect3340"
width="26.295755"
height="49.214859"
x="953.49097"
y="49.250374"
transform="matrix(0,1,1,0,0,0)" />
<text
xml:space="preserve"
style="font-style:normal;font-weight:normal;line-height:0%;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
x="51.554729"
y="970.26605"
id="text3360"><tspan
sodipodi:role="line"
id="tspan3362"
x="51.554729"
y="970.26605"
style="font-size:13.1479px;line-height:1.25">Pkgset</tspan></text>
</g>
<g
transform="translate(56.378954,-80.817124)"
id="g3398">
<rect
y="553.98242"
x="953.49097"
height="46.01757"
width="26.295755"
id="rect3400"
style="fill:#3465a4;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
transform="matrix(0,1,1,0,0,0)" />
<text
xml:space="preserve"
style="font-style:normal;font-weight:normal;line-height:0%;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#ffffff;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
x="557.61566"
y="971.33813"
id="text3396"><tspan
sodipodi:role="line"
id="tspan3398"
x="557.61566"
y="971.33813"
style="font-size:13.1479px;line-height:1.25">Test</tspan></text>
</g>
<g
id="g3720"
transform="translate(97.49995,-0.34404039)">
<rect
style="fill:#fce94f;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
id="rect3336"
width="26.295755"
height="39.669899"
x="873.01788"
y="2.3186533"
transform="matrix(0,1,1,0,0,0)" />
<text
xml:space="preserve"
style="font-style:normal;font-weight:normal;line-height:0%;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
x="6.2600794"
y="891.1604"
id="text3356"><tspan
sodipodi:role="line"
id="tspan3358"
x="6.2600794"
y="891.1604"
style="font-size:13.1479px;line-height:1.25">Init</tspan></text>
</g>
<path
inkscape:connector-curvature="0"
id="path3642"
d="M 100.90864,859.8891 H 654.22706"
style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:1.17467px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;marker-end:url(#Arrow1Lend)" />
<g
transform="translate(26.249988)"
id="g262">
<g
id="g234">
<rect
transform="matrix(0,1,1,0,0,0)"
y="179.38934"
x="872.67383"
height="162.72726"
width="26.295755"
id="rect3342"
style="fill:#fcaf3e;fill-rule:evenodd;stroke:none;stroke-width:0.838448px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" />
<text
id="text3364"
y="890.72327"
x="181.69368"
style="font-style:normal;font-weight:normal;line-height:0%;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
xml:space="preserve"><tspan
style="font-size:13.1479px;line-height:1.25"
y="890.72327"
x="181.69368"
id="tspan3366"
sodipodi:role="line">Buildinstall</tspan></text>
</g>
<g
id="g3639"
transform="translate(75.925692,-0.34404039)">
<rect
transform="matrix(0,1,1,0,0,0)"
y="103.28194"
x="905.2099"
height="54.197887"
width="26.295755"
id="rect3344"
style="fill:#729fcf;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" />
<text
id="text3368"
y="923.25934"
x="106.1384"
style="font-style:normal;font-weight:normal;line-height:0%;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
xml:space="preserve"><tspan
style="font-size:13.1479px;line-height:1.25"
y="923.25934"
x="106.1384"
id="tspan3370"
sodipodi:role="line">Gather</tspan></text>
</g>
<g
transform="translate(15.925722,63.405928)"
id="g3647">
<g
id="g3644">
<rect
style="fill:#ad7fa8;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
id="rect3346"
width="26.295755"
height="72.729973"
x="905.2099"
y="162.92607"
transform="matrix(0,1,1,0,0,0)" />
</g>
<text
id="text3372"
y="923.25934"
x="165.23042"
style="font-style:normal;font-weight:normal;line-height:0%;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
xml:space="preserve"><tspan
style="font-size:13.1479px;line-height:1.25"
y="923.25934"
x="165.23042"
id="tspan3374"
sodipodi:role="line">ExtraFiles</tspan></text>
</g>
<g
transform="translate(-2.824268,-0.34404039)"
id="g3658">
<rect
transform="matrix(0,1,1,0,0,0)"
y="241.10229"
x="905.2099"
height="78.636055"
width="26.295755"
id="rect3348"
style="fill:#e9b96e;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" />
<text
id="text3376"
y="921.86945"
x="243.95874"
style="font-style:normal;font-weight:normal;line-height:0%;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
xml:space="preserve"><tspan
style="font-size:13.1479px;line-height:1.25"
y="921.86945"
x="243.95874"
id="tspan3378"
sodipodi:role="line">Createrepo</tspan></text>
</g>
<g
id="g3408"
transform="translate(-74.638308,113.77258)">
<rect
transform="matrix(0,1,1,0,0,0)"
y="254.60153"
x="823.54675"
height="53.653927"
width="26.295755"
id="rect3350-3"
style="fill:#729fcf;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" />
<text
id="text3380-2"
y="840.3219"
x="256.90588"
style="font-style:normal;font-weight:normal;line-height:0%;font-family:sans-serif;text-align:start;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#ffffff;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
xml:space="preserve"><tspan
style="font-size:13.1479px;line-height:1.25"
id="tspan3406"
sodipodi:role="line"
x="256.90588"
y="840.3219">OSTree</tspan></text>
</g>
<g
transform="translate(-252.46536,-85.861863)"
id="g288">
<g
transform="translate(0.56706579)"
id="g3653">
<rect
style="fill:#fcaf3e;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
id="rect3428"
width="26.295755"
height="101.85102"
x="1022.637"
y="490.33765"
transform="matrix(0,1,1,0,0,0)" />
<text
xml:space="preserve"
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;line-height:0%;font-family:sans-serif;-inkscape-font-specification:'sans-serif, Normal';text-align:start;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
x="492.642"
y="1039.4121"
id="text3430"><tspan
id="tspan283"
sodipodi:role="line"
x="492.642"
y="1039.4121"
style="font-size:12px;line-height:0">OSTreeInstaller</tspan></text>
</g>
</g>
</g>
<g
id="g2"
transform="translate(-1.4062678e-8,9.3749966)">
<rect
transform="matrix(0,1,1,0,0,0)"
style="fill:#e9b96e;fill-rule:evenodd;stroke:none;stroke-width:1.85901px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
id="rect3338-1"
width="103.12497"
height="115.80065"
x="863.29883"
y="486.55563" />
<text
id="text3384-0"
y="921.73846"
x="489.56451"
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;line-height:0%;font-family:sans-serif;-inkscape-font-specification:'sans-serif, Normal';text-align:start;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
xml:space="preserve"><tspan
style="font-size:13.1475px;line-height:1.25"
id="tspan3391"
sodipodi:role="line"
x="489.56451"
y="921.73846">ImageChecksum</tspan></text>
</g>
<g
transform="translate(-42.209584,-80.817124)"
id="g3458">
<rect
transform="matrix(0,1,1,0,0,0)"
style="fill:#edd400;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
id="rect3338"
width="26.295755"
height="102.36562"
x="953.49097"
y="420.13605" />
<text
id="text3384"
y="971.54041"
x="422.99252"
style="font-style:normal;font-weight:normal;line-height:0%;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
xml:space="preserve"><tspan
y="971.54041"
x="422.99252"
id="tspan3386"
sodipodi:role="line"
style="font-size:13.1479px;line-height:1.25">Createiso</tspan></text>
</g>
<g
id="g3453"
transform="translate(-42.466031,-84.525321)">
<rect
transform="matrix(0,1,1,0,0,0)"
y="420.39337"
x="989.65247"
height="101.85102"
width="26.295755"
id="rect3352"
style="fill:#73d216;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" />
<text
id="text3388"
y="1006.4276"
x="422.69772"
style="font-style:normal;font-weight:normal;line-height:0%;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
xml:space="preserve"><tspan
y="1006.4276"
x="422.69772"
id="tspan3390"
sodipodi:role="line"
style="font-size:13.1479px;line-height:1.25">LiveImages</tspan></text>
</g>
<g
id="g3448"
transform="translate(-42.466031,-88.485966)">
<rect
transform="matrix(0,1,1,0,0,0)"
y="420.39337"
x="1026.0664"
height="101.85102"
width="26.295755"
id="rect3354"
style="fill:#f57900;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" />
<text
id="text3392"
y="1042.8416"
x="422.69772"
style="font-style:normal;font-weight:normal;line-height:0%;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
xml:space="preserve"><tspan
y="1042.8416"
x="422.69772"
id="tspan3394"
sodipodi:role="line"
style="font-size:13.1479px;line-height:1.25">ImageBuild</tspan></text>
</g>
<g
id="g3443"
transform="translate(-43.173123,-92.80219)">
<rect
style="fill:#edd400;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
id="rect3422"
width="26.295755"
height="101.85102"
x="1062.8359"
y="421.10046"
transform="matrix(0,1,1,0,0,0)" />
<text
xml:space="preserve"
style="font-style:normal;font-weight:normal;line-height:0%;font-family:sans-serif;text-align:start;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
x="423.40482"
y="1079.6111"
id="text3424"><tspan
id="tspan3434"
sodipodi:role="line"
x="423.40482"
y="1079.6111"
style="font-size:13.1479px;line-height:1.25">LiveMedia</tspan></text>
</g>
<rect
style="fill:#c17d11;fill-rule:evenodd;stroke:none;stroke-width:1.48416px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
id="rect290"
width="26.295755"
height="224.35098"
x="1091.7223"
y="378.43698"
transform="matrix(0,1,1,0,0,0)" />
<text
xml:space="preserve"
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;line-height:0%;font-family:sans-serif;-inkscape-font-specification:'sans-serif, Normal';text-align:start;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
x="380.74133"
y="1106.6223"
id="text294"><tspan
y="1106.6223"
x="380.74133"
sodipodi:role="line"
id="tspan301"
style="font-size:12px;line-height:0">OSBS</tspan></text>
<g
transform="translate(-70.933542,-51.043149)"
id="g3819">
<rect
style="fill:#73d216;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
id="rect3801"
width="26.295755"
height="101.85102"
x="1052.2335"
y="448.86087"
transform="matrix(0,1,1,0,0,0)" />
<text
xml:space="preserve"
style="font-style:normal;font-weight:normal;line-height:0%;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
x="451.16522"
y="1069.0087"
id="text3805"><tspan
style="font-size:13.1479px;line-height:1.25"
sodipodi:role="line"
x="451.16522"
y="1069.0087"
id="tspan3812">ExtraIsos</tspan></text>
</g>
<rect
y="377.92242"
x="1122.3463"
height="224.24059"
width="26.295755"
id="rect87"
style="fill:#5ed4ec;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1.48006px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
transform="matrix(0,1,1,0,0,0)" />
<text
xml:space="preserve"
style="font-style:normal;font-weight:normal;line-height:0%;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
x="380.7789"
y="1140.3958"
id="text91"><tspan
style="font-size:13.1479px;line-height:1.25"
sodipodi:role="line"
id="tspan89"
x="380.7789"
y="1140.3958">Repoclosure</tspan></text>
<g
id="g206"
transform="translate(0,-1.8749994)">
<rect
style="fill:#fcd9a4;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1.00033px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
id="rect290-6"
width="26.295755"
height="101.91849"
x="1032.3469"
y="377.92731"
transform="matrix(0,1,1,0,0,0)" />
<text
xml:space="preserve"
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;line-height:0%;font-family:sans-serif;-inkscape-font-specification:'sans-serif, Normal';text-align:start;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
x="380.23166"
y="1049.1219"
id="text294-7"><tspan
y="1049.1219"
x="380.23166"
sodipodi:role="line"
id="tspan301-5"
style="font-size:12px;line-height:0">KiwiBuild</tspan></text>
</g>
<g
id="g3">
<g
id="g1">
<g
id="g4">
<rect
transform="matrix(0,1,1,0,0,0)"
style="fill:#729fcf;fill-rule:evenodd;stroke:none;stroke-width:1.83502px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
id="rect3338-1-3"
width="103.12497"
height="115.80065"
x="983.44263"
y="486.55563" />
<text
id="text3384-0-6"
y="1038.8422"
x="489.56451"
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;line-height:0%;font-family:sans-serif;-inkscape-font-specification:'sans-serif, Normal';text-align:start;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
xml:space="preserve"><tspan
style="font-size:13.1475px;line-height:1.25"
id="tspan3391-7"
sodipodi:role="line"
x="489.56451"
y="1038.8422">ImageContainer</tspan></text>
</g>
</g>
</g>
<g
id="g206-1"
transform="translate(-0.04628921,28.701853)">
<rect
style="fill:#fcaf3e;fill-rule:evenodd;stroke:none;stroke-width:1.00033px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
id="rect290-6-7"
width="26.295755"
height="101.91849"
x="1032.3469"
y="377.92731"
transform="matrix(0,1,1,0,0,0)" />
<text
xml:space="preserve"
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;line-height:0%;font-family:sans-serif;-inkscape-font-specification:'sans-serif, Normal';text-align:start;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
x="380.23166"
y="1049.1219"
id="text294-7-5"><tspan
y="1049.1219"
x="380.23166"
sodipodi:role="line"
id="tspan301-5-5"
style="font-size:12px;line-height:0">OSBuild</tspan></text>
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 23 KiB

BIN
doc/_static/pungi_snake-sm-dark.png vendored Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 13 KiB

0
doc/_templates/.keep vendored Normal file
View File

70
doc/about.rst Normal file
View File

@ -0,0 +1,70 @@
=============
About Pungi
=============
.. figure:: _static/pungi_snake-sm-dark.png
:align: right
:alt: Pungi Logo
*Pungi* is a distribution compose tool.
Composes are release snapshots that contain release deliverables such as:
- installation trees
- RPMs
- repodata
- comps
- (bootable) ISOs
- kickstart trees
- anaconda images
- images for PXE boot
Tool overview
=============
*Pungi* consists of multiple separate executables backed by a common library.
The main entry-point is the ``pungi-koji`` script. It loads the compose
configuration and kicks off the process. Composing itself is done in phases.
Each phase is responsible for generating some artifacts on disk and updating
the ``compose`` object that is threaded through all the phases.
*Pungi* itself does not actually do that much. Most of the actual work is
delegated to separate executables. *Pungi* just makes sure that all the
commands are invoked in the appropriate order and with correct arguments. It
also moves the artifacts to correct locations.
The executable name ``pungi-koji`` comes from the fact that most of those
separate executables submit tasks to Koji that does the actual work in an
auditable way.
However unlike doing everything manually in Koji, Pungi will make sure you are
building all images from the same package set, and will produce even
deliverables that Koji can not create like YUM repos and installer ISOs.
Links
=====
- Upstream GIT: https://pagure.io/pungi/
- Issue tracker: https://pagure.io/pungi/issues
- Questions can be asked on *#fedora-releng* IRC channel on FreeNode
Origin of name
==============
The name *Pungi* comes from the instrument used to charm snakes. *Anaconda*
being the software Pungi was manipulating, and anaconda being a snake, led to
the referential naming.
The first name, which was suggested by Seth Vidal, was *FIST*, *Fedora
Installation <Something> Tool*. That name was quickly discarded and replaced
with Pungi.
There was also a bit of an inside joke that when said aloud, it could sound
like punji, which is `a sharpened stick at the bottom of a
trap <https://en.wikipedia.org/wiki/Punji_stick>`_. Kind of like software…

27
doc/comps.rst Normal file
View File

@ -0,0 +1,27 @@
.. _comps:
Processing comps files
======================
The comps file that Pungi takes as input is not really pure comps as used by
tools like DNF. There are extensions used to customize how the file is processed.
The first step of Pungi processing is to retrieve the actual file. This can use
anything that :ref:`scm_support` supports.
Pungi extensions are ``arch`` attribute on ``packageref``, ``group`` and
``environment`` tags. The value of this attribute is a comma separated list of
architectures.
Second step Pungi performs is creating a file for each architecture. This is
done by removing all elements with incompatible ``arch`` attribute. No
additional clean up is performed on this file. The resulting file is only used
internally for the rest of the compose process.
Third and final step is to create comps file for each Variant.Arch combination.
This is the actual file that will be included in the compose. The start file is
the original input file, from which all elements with incompatible architecture
are removed. Then clean up is performed by removing all empty groups, removing
non-existing groups from environments and categories and finally removing empty
environments and categories. As a last step groups not listed in the variants
file are removed.

258
doc/conf.py Normal file
View File

@ -0,0 +1,258 @@
# -*- coding: utf-8 -*-
#
# Pungi documentation build configuration file, created by
# sphinx-quickstart on Thu Jul 2 08:11:04 2015.
#
# This file is execfile()d with the current directory set to its
# containing dir.
#
# Note that not all possible configuration values are present in this
# autogenerated file.
#
# All configuration values have a default; values that are commented out
# serve to show the default.
import sys
import os
# If extensions (or modules to document with autodoc) are in another directory,
# add these directories to sys.path here. If the directory is relative to the
# documentation root, use os.path.abspath to make it absolute, like shown here.
# sys.path.insert(0, os.path.abspath('.'))
# -- General configuration ------------------------------------------------
# If your documentation needs a minimal Sphinx version, state it here.
# needs_sphinx = '1.0'
# Add any Sphinx extension module names here, as strings. They can be
# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom
# ones.
extensions = []
# Add any paths that contain templates here, relative to this directory.
templates_path = ["_templates"]
# The suffix of source filenames.
source_suffix = ".rst"
# The encoding of source files.
# source_encoding = 'utf-8-sig'
# The master toctree document.
master_doc = "index"
# General information about the project.
project = "Pungi"
copyright = "2016, Red Hat, Inc."
# The version info for the project you're documenting, acts as replacement for
# |version| and |release|, also used in various other places throughout the
# built documents.
#
# The short X.Y version.
version = "4.7"
# The full version, including alpha/beta/rc tags.
release = "4.7.0"
# The language for content autogenerated by Sphinx. Refer to documentation
# for a list of supported languages.
# language = None
# There are two options for replacing |today|: either, you set today to some
# non-false value, then it is used:
# today = ''
# Else, today_fmt is used as the format for a strftime call.
# today_fmt = '%B %d, %Y'
# List of patterns, relative to source directory, that match files and
# directories to ignore when looking for source files.
exclude_patterns = ["_build"]
# The reST default role (used for this markup: `text`) to use for all
# documents.
# default_role = None
# If true, '()' will be appended to :func: etc. cross-reference text.
# add_function_parentheses = True
# If true, the current module name will be prepended to all description
# unit titles (such as .. function::).
# add_module_names = True
# If true, sectionauthor and moduleauthor directives will be shown in the
# output. They are ignored by default.
# show_authors = False
# The name of the Pygments (syntax highlighting) style to use.
pygments_style = "sphinx"
# A list of ignored prefixes for module index sorting.
# modindex_common_prefix = []
# If true, keep warnings as "system message" paragraphs in the built documents.
# keep_warnings = False
# -- Options for HTML output ----------------------------------------------
# The theme to use for HTML and HTML Help pages. See the documentation for
# a list of builtin themes.
html_theme = "default"
# Theme options are theme-specific and customize the look and feel of a theme
# further. For a list of options available for each theme, see the
# documentation.
# html_theme_options = {}
# Add any paths that contain custom themes here, relative to this directory.
# html_theme_path = []
# The name for this set of Sphinx documents. If None, it defaults to
# "<project> v<release> documentation".
# html_title = None
# A shorter title for the navigation bar. Default is the same as html_title.
# html_short_title = None
# The name of an image file (relative to this directory) to place at the top
# of the sidebar.
# html_logo = None
# The name of an image file (within the static path) to use as favicon of the
# docs. This file should be a Windows icon file (.ico) being 16x16 or 32x32
# pixels large.
# html_favicon = None
# Add any paths that contain custom static files (such as style sheets) here,
# relative to this directory. They are copied after the builtin static files,
# so a file named "default.css" will overwrite the builtin "default.css".
html_static_path = ["_static"]
# Add any extra paths that contain custom files (such as robots.txt or
# .htaccess) here, relative to this directory. These files are copied
# directly to the root of the documentation.
# html_extra_path = []
# If not '', a 'Last updated on:' timestamp is inserted at every page bottom,
# using the given strftime format.
# html_last_updated_fmt = '%b %d, %Y'
# If true, SmartyPants will be used to convert quotes and dashes to
# typographically correct entities.
# html_use_smartypants = True
# Custom sidebar templates, maps document names to template names.
# html_sidebars = {}
# Additional templates that should be rendered to pages, maps page names to
# template names.
# html_additional_pages = {}
# If false, no module index is generated.
# html_domain_indices = True
# If false, no index is generated.
# html_use_index = True
# If true, the index is split into individual pages for each letter.
# html_split_index = False
# If true, links to the reST sources are added to the pages.
# html_show_sourcelink = True
# If true, "Created using Sphinx" is shown in the HTML footer. Default is True.
# html_show_sphinx = True
# If true, "(C) Copyright ..." is shown in the HTML footer. Default is True.
# html_show_copyright = True
# If true, an OpenSearch description file will be output, and all pages will
# contain a <link> tag referring to it. The value of this option must be the
# base URL from which the finished HTML is served.
# html_use_opensearch = ''
# This is the file name suffix for HTML files (e.g. ".xhtml").
# html_file_suffix = None
# Output file base name for HTML help builder.
htmlhelp_basename = "Pungidoc"
# -- Options for LaTeX output ---------------------------------------------
latex_elements = {
# The paper size ('letterpaper' or 'a4paper').
#'papersize': 'letterpaper',
# The font size ('10pt', '11pt' or '12pt').
#'pointsize': '10pt',
# Additional stuff for the LaTeX preamble.
#'preamble': '',
}
# Grouping the document tree into LaTeX files. List of tuples
# (source start file, target name, title,
# author, documentclass [howto, manual, or own class]).
latex_documents = [
("index", "Pungi.tex", "Pungi Documentation", "Daniel Mach", "manual"),
]
# The name of an image file (relative to this directory) to place at the top of
# the title page.
# latex_logo = None
# For "manual" documents, if this is true, then toplevel headings are parts,
# not chapters.
# latex_use_parts = False
# If true, show page references after internal links.
# latex_show_pagerefs = False
# If true, show URL addresses after external links.
# latex_show_urls = False
# Documents to append as an appendix to all manuals.
# latex_appendices = []
# If false, no module index is generated.
# latex_domain_indices = True
# -- Options for manual page output ---------------------------------------
# One entry per manual page. List of tuples
# (source start file, name, description, authors, manual section).
man_pages = [("index", "pungi", "Pungi Documentation", ["Daniel Mach"], 1)]
# If true, show URL addresses after external links.
# man_show_urls = False
# -- Options for Texinfo output -------------------------------------------
# Grouping the document tree into Texinfo files. List of tuples
# (source start file, target name, title, author,
# dir menu entry, description, category)
texinfo_documents = [
(
"index",
"Pungi",
"Pungi Documentation",
"Daniel Mach",
"Pungi",
"One line description of project.",
"Miscellaneous",
),
]
# Documents to append as an appendix to all manuals.
# texinfo_appendices = []
# If false, no module index is generated.
# texinfo_domain_indices = True
# How to display URL addresses: 'footnote', 'no', or 'inline'.
# texinfo_show_urls = 'footnote'
# If true, do not generate a @detailmenu in the "Top" node's menu.
# texinfo_no_detailmenu = False

2278
doc/configuration.rst Normal file

File diff suppressed because it is too large Load Diff

166
doc/contributing.rst Normal file
View File

@ -0,0 +1,166 @@
=====================
Contributing to Pungi
=====================
Set up development environment
==============================
In order to work on *Pungi*, you should install recent version of *Fedora*.
Python2
-------
Fedora 29 is recommended because some packages are not available in newer Fedora release, e.g. python2-libcomps.
Install required packages ::
$ sudo dnf install -y krb5-devel gcc make libcurl-devel python2-devel python2-createrepo_c kobo-rpmlib yum python2-libcomps python2-libselinx
Python3
-------
Install required packages ::
$ sudo dnf install -y krb5-devel gcc make libcurl-devel python3-devel python3-createrepo_c python3-libcomps
Developing
==========
Currently the development workflow for Pungi is on master branch:
- Make your own fork at https://pagure.io/pungi
- Clone your fork locally (replacing $USERNAME with your own)::
git clone git@pagure.io:forks/$USERNAME/pungi.git
- cd into your local clone and add the remote upstream for rebasing::
cd pungi
git remote add upstream git@pagure.io:pungi.git
.. note::
This workflow assumes that you never ``git commit`` directly to the master
branch of your fork. This will make more sense when we cover rebasing
below.
- create a topic branch based on master::
git branch my_topic_branch master
git checkout my_topic_branch
- Make edits, changes, add new features, etc. and then make sure to pull
from upstream master and rebase before submitting a pull request::
# lets just say you edited setup.py for sake of argument
git checkout my_topic_branch
# make changes to setup.py
black setup.py
tox
git add setup.py
git commit -s -m "added awesome feature to setup.py"
# now we rebase
git checkout master
git pull --rebase upstream master
git push origin master
git push origin --tags
git checkout my_topic_branch
git rebase master
# resolve merge conflicts if any as a result of your development in
# your topic branch
git push origin my_topic_branch
.. note::
In order to for your commit to be merged:
- you must sign-off on it. Use ``-s`` option when running ``git commit``.
- The code must be well formatted via ``black`` and pass ``flake8`` checking. Run ``tox -e black,flake8`` to do the check.
- Create pull request in the pagure.io web UI
- For convenience, here is a bash shell function that can be placed in your
~/.bashrc and called such as ``pullupstream pungi-4-devel`` that will
automate a large portion of the rebase steps from above::
pullupstream () {
if [[ -z "$1" ]]; then
printf "Error: must specify a branch name (e.g. - master, devel)\n"
else
pullup_startbranch=$(git describe --contains --all HEAD)
git checkout $1
git pull --rebase upstream master
git push origin $1
git push origin --tags
git checkout ${pullup_startbranch}
fi
}
Testing
=======
You must write unit tests for any new code (except for trivial changes). Any
code without sufficient test coverage may not be merged.
To run all existing tests, suggested method is to use *tox*. ::
$ sudo dnf install python3-tox -y
$ tox -e py3
$ tox -e py27
Alternatively you could create a vitualenv, install deps and run tests
manually if you don't want to use tox. ::
$ sudo dnf install python3-virtualenvwrapper -y
$ mkvirtualenv --system-site-packages py3
$ workon py3
$ pip install -r requirements.txt -r test-requirements.txt
$ make test
# or with coverage
$ make test-coverage
If you need to run specified tests, *pytest* is recommended. ::
# Activate virtualenv first
# Run tests
$ pytest tests/test_config.py
$ pytest tests/test_config.py -k test_pkgset_mismatch_repos
In the ``tests/`` directory there is a shell script ``test_compose.sh`` that
you can use to try and create a miniature compose on dummy data. The actual
data will be created by running ``make test-data`` in project root. ::
$ sudo dnf -y install rpm-build createrepo_c isomd5sum genisoimage syslinux
# Activate virtualenv (the one created by tox could be used)
$ source .tox/py3/bin/activate
$ python setup.py develop
$ make test-data
$ make test-compose
This testing compose does not actually use all phases that are available, and
there is no checking that the result is correct. It only tells you whether it
crashed or not.
.. note::
Even when it finishes successfully, it may print errors about
``repoclosure`` on *Server-Gluster.x86_64* in *test* phase. This is not a
bug.
Documenting
===========
You must write documentation for any new features and functional changes.
Any code without sufficient documentation may not be merged.
To generate the documentation, run ``make doc`` in project root.

480
doc/examples.rst Normal file
View File

@ -0,0 +1,480 @@
.. _examples:
Big picture examples
====================
Actual Pungi configuration files can get very large. This pages brings two
examples of (almost) full configuration for two different composes.
Fedora Rawhide compose
----------------------
This is a shortened configuration for Fedora Radhide compose as of 2019-10-14.
::
release_name = 'Fedora'
release_short = 'Fedora'
release_version = 'Rawhide'
release_is_layered = False
bootable = True
comps_file = {
'scm': 'git',
'repo': 'https://pagure.io/fedora-comps.git',
'branch': 'master',
'file': 'comps-rawhide.xml',
# Merge translations by running make. This command will generate the file.
'command': 'make comps-rawhide.xml'
}
module_defaults_dir = {
'scm': 'git',
'repo': 'https://pagure.io/releng/fedora-module-defaults.git',
'branch': 'main',
'dir': '.'
}
# Optional module obsoletes configuration which is merged
# into the module index and gets resolved
module_obsoletes_dir = {
'scm': 'git',
'repo': 'https://pagure.io/releng/fedora-module-defaults.git',
'branch': 'main',
'dir': 'obsoletes'
}
variants_file='variants-fedora.xml'
sigkeys = ['12C944D0']
# Put packages into subdirectories hashed by their initial letter.
hashed_directories = True
# There is a special profile for use with compose. It makes Pungi
# authenticate automatically as rel-eng user.
koji_profile = 'compose_koji'
# RUNROOT settings
runroot = True
runroot_channel = 'compose'
runroot_tag = 'f32-build'
# PKGSET
pkgset_source = 'koji'
pkgset_koji_tag = 'f32'
pkgset_koji_inherit = False
filter_system_release_packages = False
# GATHER
gather_method = {
'^.*': { # For all variants
'comps': 'deps', # resolve dependencies for packages from comps file
'module': 'nodeps', # but not for packages from modules
}
}
gather_backend = 'dnf'
gather_profiler = True
check_deps = False
greedy_method = 'build'
repoclosure_backend = 'dnf'
# CREATEREPO
createrepo_deltas = False
createrepo_database = True
createrepo_use_xz = True
createrepo_extra_args = ['--zck', '--zck-dict-dir=/usr/share/fedora-repo-zdicts/rawhide']
# CHECKSUMS
media_checksums = ['sha256']
media_checksum_one_file = True
media_checksum_base_filename = '%(release_short)s-%(variant)s-%(version)s-%(arch)s-%(date)s%(type_suffix)s.%(respin)s'
# CREATEISO
iso_hfs_ppc64le_compatible = False
# BUILDINSTALL
buildinstall_method = 'lorax'
buildinstall_skip = [
# No installer for Modular variant
('^Modular$', {'*': True}),
# No 32 bit installer for Everything.
('^Everything$', {'i386': True}),
]
# Enables macboot on x86_64 for all variants and disables upgrade image building
# everywhere.
lorax_options = [
('^.*$', {
'x86_64': {
'nomacboot': False
},
'ppc64le': {
# Use 3GB image size for ppc64le.
'rootfs_size': 3
},
'*': {
'noupgrade': True
}
})
]
additional_packages = [
('^(Server|Everything)$', {
'*': [
# Add all architectures of dracut package.
'dracut.*',
# All all packages matching this pattern
'autocorr-*',
],
}),
('^Everything$', {
# Everything should include all packages from the tag. This only
# applies to the native arch. Multilib will still be pulled in
# according to multilib rules.
'*': ['*'],
}),
]
filter_packages = [
("^.*$", {"*": ["glibc32", "libgcc32"]}),
('(Server)$', {
'*': [
'kernel*debug*',
'kernel-kdump*',
]
}),
]
multilib = [
('^Everything$', {
'x86_64': ['devel', 'runtime'],
})
]
# These packages should never be multilib on any arch.
multilib_blacklist = {
'*': [
'kernel', 'kernel-PAE*', 'kernel*debug*', 'java-*', 'php*', 'mod_*', 'ghc-*'
],
}
# These should be multilib even if they don't match the rules defined above.
multilib_whitelist = {
'*': ['wine', '*-static'],
}
createiso_skip = [
# Keep binary ISOs for Server, but not source ones.
('^Server$', {'src': True}),
# Remove all other ISOs.
('^Everything$', {'*': True, 'src': True}),
('^Modular$', {'*': True, 'src': True}),
]
# Image name respecting Fedora's image naming policy
image_name_format = '%(release_short)s-%(variant)s-%(disc_type)s-%(arch)s-%(version)s-%(date)s%(type_suffix)s.%(respin)s.iso'
# Use the same format for volume id
image_volid_formats = [
'%(release_short)s-%(variant)s-%(disc_type)s-%(arch)s-%(version)s'
]
# Used by Pungi to replace 'Cloud' with 'C' (etc.) in ISO volume IDs.
# There is a hard 32-character limit on ISO volume IDs, so we use
# these to try and produce short enough but legible IDs. Note this is
# duplicated in Koji for live images, as livemedia-creator does not
# allow Pungi to tell it what volume ID to use. Note:
# https://fedoraproject.org/wiki/User:Adamwill/Draft_fedora_image_naming_policy
volume_id_substitutions = {
'Beta': 'B',
'Rawhide': 'rawh',
'Silverblue': 'SB',
'Cinnamon': 'Cinn',
'Cloud': 'C',
'Design_suite': 'Dsgn',
'Electronic_Lab': 'Elec',
'Everything': 'E',
'Scientific_KDE': 'SciK',
'Security': 'Sec',
'Server': 'S',
'Workstation': 'WS',
}
disc_types = {
'boot': 'netinst',
'live': 'Live',
}
translate_paths = [
('/mnt/koji/compose/', 'https://kojipkgs.fedoraproject.org/compose/'),
]
# These will be inherited by live_media, live_images and image_build
global_ksurl = 'git+https://pagure.io/fedora-kickstarts.git?#HEAD'
global_release = '!RELEASE_FROM_LABEL_DATE_TYPE_RESPIN'
global_version = 'Rawhide'
# live_images ignores this in favor of live_target
global_target = 'f32'
image_build = {
'^Container$': [
{
'image-build': {
'format': [('docker', 'tar.xz')],
'name': 'Fedora-Container-Base',
'kickstart': 'fedora-container-base.ks',
'distro': 'Fedora-22',
'disk_size': 5,
'arches': ['armhfp', 'aarch64', 'ppc64le', 's390x', 'x86_64'],
'repo': 'Everything',
'install_tree_from': 'Everything',
'subvariant': 'Container_Base',
'failable': ['*'],
},
'factory-parameters': {
'dockerversion': "1.10.1",
'docker_cmd': '[ "/bin/bash" ]',
'docker_env': '[ "DISTTAG=f32container", "FGC=f32", "container=oci" ]',
'docker_label': '{ "name": "fedora", "license": "MIT", "vendor": "Fedora Project", "version": "32"}',
},
},
],
}
live_media = {
'^Workstation$': [
{
'name': 'Fedora-Workstation-Live',
'kickstart': 'fedora-live-workstation.ks',
# Variants.xml also contains aarch64 and armhfp, but there
# should be no live media for those arches.
'arches': ['x86_64', 'ppc64le'],
'failable': ['ppc64le'],
# Take packages and install tree from Everything repo.
'repo': 'Everything',
'install_tree_from': 'Everything',
}
],
'^Spins': [
# There are multiple media for Spins variant. They use subvariant
# field so that they can be identified in the metadata.
{
'name': 'Fedora-KDE-Live',
'kickstart': 'fedora-live-kde.ks',
'arches': ['x86_64'],
'repo': 'Everything',
'install_tree_from': 'Everything',
'subvariant': 'KDE'
},
{
'name': 'Fedora-Xfce-Live',
'kickstart': 'fedora-live-xfce.ks',
'arches': ['x86_64'],
'failable': ['*'],
'repo': 'Everything',
'install_tree_from': 'Everything',
'subvariant': 'Xfce'
},
],
}
failable_deliverables = [
# Installer and ISOs for server failing do not abort the compose.
('^Server$', {
'*': ['buildinstall', 'iso'],
}),
('^.*$', {
# Buildinstall is not blocking
'src': ['buildinstall'],
# Nothing on i386, ppc64le blocks the compose
'i386': ['buildinstall', 'iso'],
'ppc64le': ['buildinstall', 'iso'],
's390x': ['buildinstall', 'iso'],
})
]
ostree = {
"^Silverblue$": {
"version": "!OSTREE_VERSION_FROM_LABEL_DATE_TYPE_RESPIN",
# To get config, clone master branch from this repo and take
# treefile from there.
"treefile": "fedora-silverblue.yaml",
"config_url": "https://pagure.io/workstation-ostree-config.git",
"config_branch": "master",
# Consume packages from Everything
"repo": "Everything",
# Don't create a reference in the ostree repo (signing automation does that).
"tag_ref": False,
# Don't use change detection in ostree.
"force_new_commit": True,
# Use unified core mode for rpm-ostree composes
"unified_core": True,
# This is the location for the repo where new commit will be
# created. Note that this is outside of the compose dir.
"ostree_repo": "/mnt/koji/compose/ostree/repo/",
"ostree_ref": "fedora/rawhide/${basearch}/silverblue",
"arches": ["x86_64", "ppc64le", "aarch64"],
"failable": ['*'],
}
}
ostree_container = {
"^Sagano$": {
"treefile": "fedora-tier-0-38.yaml",
"config_url": "https://gitlab.com/CentOS/cloud/sagano.git",
"config_branch": "main",
# Consume packages from Everything
"repo": "Everything",
# Automatically generate a reasonable version
"version": "!OSTREE_VERSION_FROM_LABEL_DATE_TYPE_RESPIN",
# Only run this for x86_64 even if Sagano has more arches
"arches": ["x86_64"],
}
}
ostree_installer = [
("^Silverblue$", {
"x86_64": {
"repo": "Everything",
"release": None,
"rootfs_size": "8",
# Take templates from this repository.
'template_repo': 'https://pagure.io/fedora-lorax-templates.git',
'template_branch': 'master',
# Use following templates.
"add_template": ["ostree-based-installer/lorax-configure-repo.tmpl",
"ostree-based-installer/lorax-embed-repo.tmpl",
"ostree-based-installer/lorax-embed-flatpaks.tmpl"],
# And add these variables for the templates.
"add_template_var": [
"ostree_install_repo=https://kojipkgs.fedoraproject.org/compose/ostree/repo/",
"ostree_update_repo=https://ostree.fedoraproject.org",
"ostree_osname=fedora",
"ostree_oskey=fedora-32-primary",
"ostree_contenturl=mirrorlist=https://ostree.fedoraproject.org/mirrorlist",
"ostree_install_ref=fedora/rawhide/x86_64/silverblue",
"ostree_update_ref=fedora/rawhide/x86_64/silverblue",
"flatpak_remote_name=fedora",
"flatpak_remote_url=oci+https://registry.fedoraproject.org",
"flatpak_remote_refs=runtime/org.fedoraproject.Platform/x86_64/f30 app/org.gnome.Baobab/x86_64/stable",
],
'failable': ['*'],
},
})
]
RCM Tools compose
-----------------
This is a small compose used to deliver packages to Red Hat internal users. The
configuration is split into two files.
::
# rcmtools-common.conf
release_name = "RCM Tools"
release_short = "RCMTOOLS"
release_version = "2.0"
release_type = "updates"
release_is_layered = True
createrepo_c = True
createrepo_checksum = "sha256"
# PKGSET
pkgset_source = "koji"
koji_profile = "brew"
pkgset_koji_inherit = True
# GENERAL SETTINGS
bootable = False
comps_file = "rcmtools-comps.xml"
variants_file = "rcmtools-variants.xml"
sigkeys = ["3A3A33A3"]
# RUNROOT settings
runroot = False
# GATHER
gather_method = "deps"
check_deps = True
additional_packages = [
('.*', {
'*': ['puddle', 'rcm-nexus'],
}
),
]
# Set repoclosure_strictness to fatal to avoid installation dependency
# issues in production composes
repoclosure_strictness = [
("^.*$", {
"*": "fatal"
})
]
Configuration specific for different base products is split into separate files.
::
# rcmtools-common.conf
from rcmtools-common import *
# BASE PRODUCT
base_product_name = "Red Hat Enterprise Linux"
base_product_short = "RHEL"
base_product_version = "7"
# PKGSET
pkgset_koji_tag = "rcmtools-rhel-7-compose"
# remove i386 arch on rhel7
tree_arches = ["aarch64", "ppc64le", "s390x", "x86_64"]
check_deps = False
# Packages in these repos are available to satisfy dependencies inside the
# compose, but will not be pulled in.
gather_lookaside_repos = [
("^Client|Client-optional$", {
"x86_64": [
"http://example.redhat.com/rhel/7/Client/x86_64/os/",
"http://example.redhat.com/rhel/7/Client/x86_64/optional/os/",
],
}),
("^Workstation|Workstation-optional$", {
"x86_64": [
"http://example.redhat.com/rhel/7/Workstation/x86_64/os/",
"http://example.redhat.com/rhel/7/Workstation/x86_64/optional/os/",
],
}),
("^Server|Server-optional$", {
"aarch64": [
"http://example.redhat.com/rhel/7/Server/aarch64/os/",
"http://example.redhat.com/rhel/7/Server/aarch64/optional/os/",
],
"ppc64": [
"http://example.redhat.com/rhel/7/Server/ppc64/os/",
"http://example.redhat.com/rhel/7/Server/ppc64/optional/os/",
],
"ppc64le": [
"http://example.redhat.com/rhel/7/Server/ppc64le/os/",
"http://example.redhat.com/rhel/7/Server/ppc64le/optional/os/",
],
"s390x": [
"http://example.redhat.com/rhel/7/Server/s390x/os/",
"http://example.redhat.com/rhel/7/Server/s390x/optional/os/",
],
"x86_64": [
"http://example.redhat.com/rhel/7/Server/x86_64/os/",
"http://example.redhat.com/rhel/7/Server/x86_64/optional/os/",
],
})
]

90
doc/format.rst Normal file
View File

@ -0,0 +1,90 @@
==================
Config file format
==================
The configuration file parser is provided by `kobo
<https://github.com/release-engineering/kobo>`_
The file follows a Python-like format. It consists of a sequence of variables
that have a value assigned to them. ::
variable = value
The variable names must follow the same convention as Python code: start with a
letter and consist of letters, digits and underscores only.
The values can be either an integer, float, boolean (``True`` or ``False``), a
string or ``None``. Strings must be enclosed in either single or double quotes.
Complex types are supported as well.
A list is enclosed in square brackets and items are separated with commas.
There can be a comma after the last item as well. ::
a_list = [1,
2,
3,
]
A tuple works like a list, but is enclosed in parenthesis. ::
a_tuple = (1, "one")
A dictionary is wrapped in brackets, and consists of ``key: value`` pairs
separated by commas. The keys can only be formed from basic types (int, float,
string). ::
a_dict = {
'foo': 'bar',
1: None
}
The value assigned to a variable can also be taken from another variable. ::
one = 1
another = one
Anything on a line after a ``#`` symbol is ignored and functions as a comment.
Importing other files
=====================
It is possible to include another configuration file. The files are looked up
relative to the currently processed file.
The general structure of import is: ::
from FILENAME import WHAT
The ``FILENAME`` should be just the base name of the file without extension
(which must be ``.conf``). ``WHAT`` can either be a comma separated list of
variables or ``*``. ::
# Opens constants.conf and brings PI and E into current scope.
from constants import PI, E
# Opens common.conf and brings everything defined in that file into current
# file as well.
from common import *
.. note::
Pungi will copy the configuration file given on command line into the
``logs/`` directory. Only this single file will be copied, not any included
ones. (Copying included files requires a fix in kobo library.)
The JSON-formatted dump of configuration is correct though.
Formatting strings
==================
String interpolation is available as well. It uses a ``%``-encoded format. See
Python documentation for more details. ::
joined = "%s %s" % (var_a, var_b)
a_dict = {
"fst": 1,
"snd": 2,
}
another = "%(fst)s %(snd)s" % a_dict

102
doc/gathering.rst Normal file
View File

@ -0,0 +1,102 @@
==================
Gathering packages
==================
A compose created by Pungi consists of one or more variants. A variant contains
a subset of the content targeted at a particular use case.
There are different types of variants. The type affects how packages are
gathered into the variant.
The inputs for gathering are defined by various gather sources. Packages from
all sources are collected to create a big list of package names, comps groups
names and a list of packages that should be filtered out.
.. note::
The inputs for both explicit package list and comps file are interpreted as
RPM names, not any arbitrary provides nor source package name.
Next, ``gather_method`` defines how the list is processed. For ``nodeps``, the
results from source are used pretty much as is [#]_. For ``deps`` method, a
process will be launched to figure out what dependencies are needed and those
will be pulled in.
.. [#] The lists are filtered based on what packages are available in the
package set, but nothing else will be pulled in.
Variant types
=============
*Variant*
is a base type that has no special behaviour.
*Addon*
is built on top of a regular variant. Any packages that should go to both
the addon and its parent will be removed from addon. Packages that are only
in addon but pulled in because of ``gather_fulltree`` option will be moved
to parent.
*Integrated Layered Product*
works similarly to *addon*. Additionally, all packages from addons on the
same parent variant are removed integrated layered products.
The main difference between an *addon* and *integrated layered product* is
that *integrated layered product* has its own identity in the metadata
(defined with product name and version).
.. note::
There's also *Layered Product* as a term, but this is not related to
variants. It's used to describe a product that is not a standalone
operating system and is instead meant to be used on some other base
system.
*Optional*
contains packages that complete the base variants' package set. It always
has ``fulltree`` and ``selfhosting`` enabled, so it contains build
dependencies and packages which were not specifically requested for base
variant.
Some configuration options are overridden for particular variant types.
.. table:: Depsolving configuration
+-----------+--------------+--------------+
| Variant | Fulltree | Selfhosting |
+===========+==============+==============+
| base | configurable | configurable |
+-----------+--------------+--------------+
| addon/ILP | enabled | disabled |
+-----------+--------------+--------------+
| optional | enabled | enabled |
+-----------+--------------+--------------+
Profiling
=========
Profiling data on the ``pungi-gather`` tool can be enabled by setting the
``gather_profiler`` configuration option to ``True``.
Modular compose
===============
A compose with ``gather_source`` set to ``module`` is called *modular*. The
package list is determined by a list of modules.
The list of modules that will be put into a variant is defined in the
``variants.xml`` file. The file can contain either *Name:Stream* or
*Name:Stream:Version* references. See `Module Naming Policy
<https://pagure.io/modularity/blob/master/f/source/development/building-modules/naming-policy.rst>`_
for details. When *Version* is missing from the specification, Pungi will ask
PDC for the latest one.
The module metadata in PDC contains a list of RPMs in the module as well as
Koji tag from which the packages can be retrieved.
Restrictions
------------
* A modular compose must always use Koji as a package set source.

25
doc/index.rst Normal file
View File

@ -0,0 +1,25 @@
.. Pungi documentation master file, created by
sphinx-quickstart on Thu Jul 2 08:11:04 2015.
You can adapt this file completely to your liking, but it should at least
contain the root `toctree` directive.
Welcome to Pungi's documentation!
=================================
Contents:
.. toctree::
:maxdepth: 2
about
phases
format
configuration
examples
scm_support
messaging
gathering
koji
comps
contributing
testing

105
doc/koji.rst Normal file
View File

@ -0,0 +1,105 @@
======================
Getting data from koji
======================
When Pungi is configured to get packages from a Koji tag, it somehow needs to
access the actual RPM files.
Historically, this required the storage used by Koji to be directly available
on the host where Pungi was running. This was usually achieved by using NFS for
the Koji volume, and mounting it on the compose host.
The compose could be created directly on the same volume. In such case the
packages would be hardlinked, significantly reducing space consumption.
The compose could also be created on a different storage, in which case the
packages would either need to be copied over or symlinked. Using symlinks
requires that anything that accesses the compose (e.g. a download server) would
also need to mount the Koji volume in the same location.
There is also a risk with symlinks that the package in Koji can change (due to
being resigned for example), which would invalidate composes linking to it.
Using Koji without direct mount
===============================
It is possible now to run a compose from a Koji tag without direct access to
Koji storage.
Pungi can download the packages over HTTP protocol, store them in a local
cache, and consume them from there.
The local cache has similar structure to what is on the Koji volume.
When Pungi needs some package, it has a path on Koji volume. It will replace
the ``topdir`` with the cache location. If such file exists, it will be used.
If it doesn't exist, it will be downloaded from Koji (by replacing the
``topdir`` with ``topurl``).
::
Koji path /mnt/koji/packages/foo/1/1.fc38/data/signed/abcdef/noarch/foo-1-1.fc38.noarch.rpm
Koji URL https://kojipkgs.fedoraproject.org/packages/foo/1/1.fc38/data/signed/abcdef/noarch/foo-1-1.fc38.noarch.rpm
Local path /mnt/compose/cache/packages/foo/1/1.fc38/data/signed/abcdef/noarch/foo-1-1.fc38.noarch.rpm
The packages can be hardlinked from this cache directory.
Cleanup
-------
While the approach above allows each RPM to be downloaded only once, it will
eventually result in the Koji volume being mirrored locally. Most of the
packages will however no longer be needed.
There is a script ``pungi-cache-cleanup`` that can help with that. It can find
and remove files from the cache that are no longer needed.
A file is no longer needed if it has a single link (meaning it is only in the
cache, not in any compose), and it has mtime older than a given threshold.
It doesn't make sense to delete files that are hardlinked in an existing
compose as it would not save any space anyway.
The mtime check is meant to preserve files that are downloaded but not actually
used in a compose, like a subpackage that is not included in any variant. Every
time its existence in the local cache is checked, the mtime is updated.
Race conditions?
----------------
It should be safe to have multiple compose hosts share the same storage volume
for generated composes and local cache.
If a cache file is accessed and it exists, there's no risk of race condition.
If two composes need the same file at the same time and it is not present yet,
one of them will take a lock on it and start downloading. The other will wait
until the download is finished.
The lock is only valid for a set amount of time (5 minutes) to avoid issues
where the downloading process is killed in a way that blocks it from releasing
the lock.
If the file is large and network slow, the limit may not be enough finish
downloading. In that case the second process will steal the lock while the
first process is still downloading. This will result in the same file being
downloaded twice.
When the first process finishes the download, it will put the file into the
local cache location. When the second process finishes, it will atomically
replace it, but since it's the same file it will be the same file.
If the first compose already managed to hardlink the file before it gets
replaced, there will be two copies of the file present locally.
Integrity checking
------------------
There is minimal integrity checking. RPM packages belonging to real builds will
be check to match the checksum provided by Koji hub.
There is no checking for scratch builds or any images.

45
doc/messaging.rst Normal file
View File

@ -0,0 +1,45 @@
.. _messaging:
Progress notification
=====================
*Pungi* has the ability to emit notification messages about progress and
general status of the compose. These can be used to e.g. send messages to
*fedmsg*. This is implemented by actually calling a separate script.
The script will be called with one argument describing action that just
happened. A JSON-encoded object will be passed to standard input to provide
more information about the event. At the very least, the object will contain a
``compose_id`` key.
The notification script inherits working directory from the parent process and it
can be called from the same directory ``pungi-koji`` is called from. The working directory
is listed at the start of main log.
Currently these messages are sent:
* ``status-change`` -- when composing starts, finishes or fails; a ``status``
key is provided to indicate details
* ``phase-start`` -- on start of a phase
* ``phase-stop`` -- when phase is finished
* ``createiso-targets`` -- with a list of images to be created
* ``createiso-imagedone`` -- when any single image is finished
* ``createiso-imagefail`` -- when any single image fails to create
* ``fail-to-start`` -- when there are incorrect CLI options or errors in
configuration file; this message does not contain ``compose_id`` nor is it
started in the compose directory (which does not exist yet)
* ``ostree`` -- when a new commit is created, this message will announce its
hash and the name of ref it is meant for.
For phase related messages ``phase_name`` key is provided as well.
A ``pungi-fedmsg-notification`` script is provided and understands this
interface.
Setting it up
-------------
The script should be provided as a command line argument
``--notification-script``. ::
--notification-script=pungi-fedmsg-notification

175
doc/phases.rst Normal file
View File

@ -0,0 +1,175 @@
.. _phases:
Phases
======
Each invocation of ``pungi-koji`` consists of a set of phases.
.. image:: _static/phases.svg
:alt: phase diagram
Most of the phases run sequentially (left-to-right in the diagram), but there
are use cases where multiple phases run in parallel. This happens for phases
whose main point is to wait for a Koji task to finish.
Init
----
The first phase to ever run. Can not be skipped. It prepares the comps files
for variants (by filtering out groups and packages that should not be there).
See :doc:`comps` for details about how this is done.
Pkgset
------
This phase loads a set of packages that should be composed. It has two separate
results: it prepares repos with packages in ``work/`` directory (one per arch)
for further processing, and it returns a data structure with mapping of
packages to architectures.
Buildinstall
------------
Spawns a bunch of threads, each of which runs the ``lorax`` command. The
commands create ``boot.iso`` and other boot configuration files. The image is
finally linked into the ``compose/`` directory as netinstall media.
The created images are also needed for creating live media or other images in
later phases.
With ``lorax`` this phase runs one task per variant.arch combination.
Gather
------
This phase uses data collected by ``pkgset`` phase and figures out what
packages should be in each variant. The basic mapping can come from comps file,
a JSON mapping or ``additional_packages`` config option. This inputs can then
be enriched by adding all dependencies. See :doc:`gathering` for details.
Once the mapping is finalized, the packages are linked to appropriate places
and the ``rpms.json`` manifest is created.
ExtraFiles
----------
This phase collects extra files from the configuration and copies them to the
compose directory. The files are described by a JSON file in the compose
subtree where the files are copied. This metadata is meant to be distributed
with the data (on ISO images).
Createrepo
----------
This phase creates RPM repositories for each variant.arch tree. It is actually
reading the ``rpms.json`` manifest to figure out which packages should be
included.
OSTree
------
Updates an ostree repository with a new commit with packages from the compose.
The repository lives outside of the compose and is updated immediately. If the
compose fails in a later stage, the commit will not be reverted.
Implementation wise, this phase runs ``rpm-ostree`` command in Koji runroot (to
allow running on different arches).
Createiso
---------
Generates ISO files and accumulates enough metadata to be able to create
``image.json`` manifest. The file is however not created in this phase, instead
it is dumped in the ``pungi-koji`` script itself.
The files include a repository with all RPMs from the variant. There will be
multiple images if the packages do not fit on a single image.
The image will be bootable if ``buildinstall`` phase is enabled and the
packages fit on a single image.
There can also be images with source repositories. These are never bootable.
ExtraIsos
---------
This phase is very similar to ``createiso``, except it combines content from
multiple variants onto a single image. Packages, repodata and extra files from
each configured variant are put into a subdirectory. Additional extra files can
be put into top level of the image. The image will be bootable if the main
variant is bootable.
LiveImages, LiveMedia
---------------------
Creates media in Koji with ``koji spin-livecd``, ``koji spin-appliance`` or
``koji spin-livemedia`` command. When the media are finished, the images are
copied into the ``compose/`` directory and metadata for images is updated.
ImageBuild
----------
This phase wraps up ``koji image-build``. It also updates the metadata
ultimately responsible for ``images.json`` manifest.
KiwiBuild
---------
Similarly to image build, this phases creates a koji `kiwiBuild` task. In the
background it uses Kiwi to create images.
OSBuild
-------
Similarly to image build, this phases creates a koji `osbuild` task. In the
background it uses OSBuild Composer to create images.
OSBS
----
This phase builds container base images in `OSBS
<http://osbs.readthedocs.io/en/latest/index.html>`_.
The finished images are available in registry provided by OSBS, but not
downloaded directly into the compose. The is metadata about the created image
in ``compose/metadata/osbs.json``.
ImageContainer
--------------
This phase builds a container image in OSBS, and stores the metadata in the
same file as OSBS phase. The container produced here wraps a different image,
created it ImageBuild or OSBuild phase. It can be useful to deliver a VM image
to containerized environments.
OSTreeInstaller
---------------
Creates bootable media that carry an ostree repository as a payload. These
images are created by running ``lorax`` with special templates. Again it runs
in Koji runroot.
Repoclosure
-----------
Run ``repoclosure`` on each repository. By default errors are only reported
in the log, the compose will still be considered a success. The actual error
has to be looked up in the compose logs directory. Configuration allows customizing this.
ImageChecksum
-------------
Responsible for generating checksums for the images. The checksums are stored
in image manifest as well as files on disk. The list of images to be processed
is obtained from the image manifest. This way all images will get the same
checksums irrespective of the phase that created them.
Test
----
This phase is supposed to run some sanity checks on the finished compose.
The only test is to check all images listed the metadata and verify that they
look sane. For ISO files headers are checked to verify the format is correct,
and for bootable media a check is run to verify they have properties that allow
booting.

100
doc/scm_support.rst Normal file
View File

@ -0,0 +1,100 @@
.. _scm_support:
Exporting files from SCM
========================
Multiple places in Pungi can use files from external storage. The configuration
is similar independently of the backend that is used, although some features
may be different.
The so-called ``scm_dict`` is always put into configuration as a dictionary,
which can contain following keys.
* ``scm`` -- indicates which SCM system is used. This is always required.
Allowed values are:
* ``file`` -- copies files from local filesystem
* ``git`` -- copies files from a Git repository
* ``cvs`` -- copies files from a CVS repository
* ``rpm`` -- copies files from a package in the compose
* ``koji`` -- downloads archives from a given build in Koji build system
* ``repo``
* for Git and CVS backends this should be URL to the repository
* for RPM backend this should be a shell style glob matching package names
(or a list of such globs)
* for file backend this should be empty
* for Koji backend this should be an NVR or package name
* ``branch``
* branch name for Git and CVS backends, with ``master`` and ``HEAD`` as defaults
* Koji tag for koji backend if only package name is given
* otherwise should not be specified
* ``file`` -- a list of files that should be exported.
* ``dir`` -- a directory that should be exported. All its contents will be
exported. This option is mutually exclusive with ``file``.
* ``command`` -- defines a shell command to run after Git clone to generate the
needed file (for example to run ``make``). Only supported in Git backend.
* ``options`` -- a dictionary of additional configuration options. These are
specific to different backends.
Currently supported values for Git:
* ``credential_helper`` -- path to a credential helper used to supply
username/password for remotes that require authentication.
Koji examples
-------------
There are two different ways how to configure the Koji backend. ::
{
# Download all *.tar files from build my-image-1.0-1.
"scm": "koji",
"repo": "my-image-1.0-1",
"file": "*.tar",
}
{
# Find latest build of my-image in tag my-tag and take files from
# there.
"scm": "koji",
"repo": "my-image",
"branch": "my-tag",
"file": "*.tar",
}
Using both tag name and exact NVR will result in error: the NVR would be
interpreted as a package name, and would not match anything.
``file`` vs. ``dir``
--------------------
Exactly one of these two options has to be specified. Documentation for each
configuration option should specify whether it expects a file or a directory.
For ``extra_files`` phase either key is valid and should be chosen depending on
what the actual use case.
Caveats
-------
The ``rpm`` backend can only be used in phases that would extract the files
after ``pkgset`` phase finished. You can't get comps file from a package.
Depending on Git repository URL configuration Pungi can only export the
requested content using ``git archive``. When a command should run this is not
possible and a clone is always needed.
When using ``koji`` backend, it is required to provide configuration for Koji
profile to be used (``koji_profile``). It is not possible to contact multiple
different Koji instances.

42
doc/testing.rst Normal file
View File

@ -0,0 +1,42 @@
===============
Testing Pungi
===============
Test Data
=========
Tests require test data and not all of it is available in git.
You must create test repositories before running the tests::
make test-data
Requirements: createrepo_c, rpmbuild
Unit Tests
==========
Unit tests cover functionality of Pungi python modules.
You can run all of them at once::
make test
which is shortcut to::
python2 setup.py test
python3 setup.py test
You can alternatively run individual tests::
cd tests
./<test>.py [<class>[.<test>]]
Functional Tests
================
Because compose is quite complex process and not everything is covered with
unit tests yet, the easiest way how to test if your changes did not break
anything badly is to start a compose on a relatively small and well defined
package set::
cd tests
./test_compose.sh

40
doc/update-docs.sh Executable file
View File

@ -0,0 +1,40 @@
#!/bin/bash
# Copyright (C) 2015 Red Hat, Inc.
# SPDX-License-Identifier: GPL-2.0
trap cleanup EXIT
function cleanup() {
printf "Run cleanup\\n"
rm -rf "$dir_pungi" "$dir_pungi_doc"
}
if [ -z "$1" ]; then
printf "Usage:\\n"
printf "\\t%s release_version\\n" "$0"
exit 1
fi
set -e
dir_pungi=$(mktemp -d /tmp/pungi.XXX) || { echo "Failed to create temp directory"; exit 1; }
git clone https://pagure.io/pungi.git "$dir_pungi"
pushd "$dir_pungi"/doc
make html
popd
dir_pungi_doc=$(mktemp -d /tmp/pungi-doc.XXX) || { echo "Failed to create temp directory"; exit 1; }
git clone ssh://git@pagure.io/docs/pungi.git "$dir_pungi_doc"
pushd "$dir_pungi_doc"
git rm -fr ./*
cp -r "$dir_pungi"/doc/_build/html/* ./
pushd "$dir_pungi"/doc
git checkout 4.0.x
make html
popd
mkdir 4.0
cp -r "$dir_pungi"/doc/_build/html/* ./4.0/
git add .
git commit -s -m "update rendered pungi docs for release $1"
git push origin master
popd

105
git-changelog Executable file
View File

@ -0,0 +1,105 @@
#!/usr/bin/env python
#
# git-changelog - Output a rpm changelog
#
# Copyright (C) 2009-2010 Red Hat, Inc.
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU Lesser General Public License as published
# by the Free Software Foundation; either version 2.1 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 Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
# Author: David Cantrell <dcantrell@redhat.com>
# Author: Brian C. Lane <bcl@redhat.com>
from __future__ import print_function
import subprocess
import textwrap
from argparse import ArgumentParser
class ChangeLog:
def __init__(self, name, version):
self.name = name
self.version = version
def _getCommitDetail(self, commit, field):
proc = subprocess.Popen(
["git", "log", "-1", "--pretty=format:%s" % field, commit],
stdout=subprocess.PIPE,
stderr=subprocess.PIPE,
universal_newlines=True,
).communicate()
ret = proc[0].strip('\n').split('\n')
if field == '%aE' and len(ret) == 1 and ret[0].find('@') != -1:
ret = ret[0].split('@')[0]
elif len(ret) == 1:
ret = ret[0]
else:
ret = filter(lambda x: x != '', ret)
return ret
def getLog(self):
if not self.name:
range = "%s.." % (self.version)
else:
range = "%s-%s.." % (self.name, self.version)
proc = subprocess.Popen(
["git", "log", "--pretty=oneline", "--no-merges", range],
stdout=subprocess.PIPE,
stderr=subprocess.PIPE,
universal_newlines=True,
).communicate()
lines = filter(lambda x: x.find('l10n: ') != 41,
proc[0].strip('\n').split('\n'))
log = []
for line in lines:
fields = line.split(' ')
commit = fields[0]
summary = self._getCommitDetail(commit, "%s")
author = self._getCommitDetail(commit, "%aE")
log.append(("%s (%s)" % (summary.strip(), author)))
return log
def formatLog(self):
s = ""
for msg in self.getLog():
sublines = textwrap.wrap(msg, 77)
s = s + "- %s\n" % sublines[0]
if len(sublines) > 1:
for subline in sublines[1:]:
s = s + " %s\n" % subline
return s
def main():
parser = ArgumentParser()
parser.add_argument("-n", "--name",
help="Name of package used in tags")
parser.add_argument("-v", "--version",
help="Last version, changelog is commits after this tag")
args = parser.parse_args()
cl = ChangeLog(args.name, args.version)
print(cl.formatLog())
if __name__ == "__main__":
main()

187
pungi
View File

@ -1,187 +0,0 @@
#!/usr/bin/python -tt
# 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; version 2 of the License.
#
# 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 Library 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
import os
import pypungi.gather
import pypungi.pungi
import yum
from ConfigParser import SafeConfigParser
def main():
# Set some default variables, can be overrided in config file
# Turn this into a dict someday, to iterate over when setting defaults
flavor = ""
osdir = "os"
sourcedir = "source"
debugdir = "debug"
isodir = "iso"
cdsize = "685.0"
relnotefilere = "eula.txt fedora.css GPL README-BURNING-ISOS-en_US.txt RELEASE-NOTES-en_US.html ^RPM-GPG"
relnotedirre = "images stylesheet-images"
relnotepkgs = "fedora-release fedora-release-notes"
(opts, args) = get_arguments()
config = SafeConfigParser()
config.read(opts.config)
if "default" not in config.sections():
print ("Check that the file %s exists and that it has a 'default' section" % opts.config)
sys.exit(1)
if not config.has_option('default', 'flavor'):
config.set('default', 'flavor', flavor)
if not config.has_option('default', 'osdir'):
config.set('default', 'osdir', osdir)
if not config.has_option('default', 'sourcedir'):
config.set('default', 'sourcedir', sourcedir)
if not config.has_option('default', 'debugdir'):
config.set('default', 'debugdir', debugdir)
if not config.has_option('default', 'isodir'):
config.set('default', 'isodir', isodir)
if not config.has_option('default', 'cdsize'):
config.set('default', 'cdsize', cdsize)
if not config.has_option('default', 'relnotefilere'):
config.set('default', 'relnotefilere', relnotefilere)
if not config.has_option('default', 'relnotedirre'):
config.set('default', 'relnotedirre', relnotedirre)
if not config.has_option('default', 'relnotepkgs'):
config.set('default', 'relnotepkgs', relnotepkgs)
# set some other defaults
if not config.has_option('default', 'product_path'):
config.set('default', 'product_path', config.get('default', 'product_name'))
if not config.has_option('default', 'iso_basename'):
config.set('default', 'iso_basename', config.get('default', 'product_name'))
pkglist = get_packagelist(config.get('default', 'manifest'))
if not opts.destdir == "*CONFFILE*":
config.set('default', 'destdir', opts.destdir)
destdir = config.get('default', 'destdir')
if not os.path.exists(destdir):
try:
os.makedirs(destdir)
except OSError, e:
print >> sys.stderr, "Error: Cannot create destination dir %s" % destdir
sys.exit(1)
cachedir = config.get('default', 'cachedir')
if not os.path.exists(cachedir):
try:
os.makedirs(cachedir)
except OSError, e:
print >> sys.stderr, "Error: Cannot create cache dir %s" % cachedir
sys.exit(1)
# Actually do work.
if not config.get('default', 'arch') == 'source':
if opts.do_all or opts.do_gather:
mygather = pypungi.gather.Gather(config, pkglist)
mygather.getPackageObjects()
mygather.downloadPackages()
if config.getboolean('default', 'getsource'):
mygather.getSRPMList()
mygather.downloadSRPMs()
mypungi = pypungi.pungi.Pungi(config)
if opts.do_all or opts.do_buildinstall:
mypungi.doBuildinstall()
mypungi.doGetRelnotes()
if opts.do_all or opts.do_packageorder:
mypungi.doPackageorder()
if opts.do_all or opts.do_splittree:
mypungi.doSplittree()
if opts.do_all or opts.do_createiso:
mypungi.doCreateSplitrepo()
mypungi.doCreateIsos()
# Do things slightly different for src.
if config.get('default', 'arch') == 'source':
# we already have all the content gathered
mypungi = pypungi.pungi.Pungi(config)
mypungi.topdir = os.path.join(config.get('default', 'destdir'),
config.get('default', 'version'),
config.get('default', 'flavor'),
'source', 'SRPM')
if opts.do_all or opts.do_splittree:
mypungi.doSplitSRPMs()
if opts.do_all or opts.do_createiso:
mypungi.doCreateIsos()
if __name__ == '__main__':
from optparse import OptionParser
import sys
def get_arguments():
parser = OptionParser(version="%prog 0.3.2")
parser.add_option("--destdir", default="*CONFFILE*", dest="destdir",
help='destination directory (defaults to current directory)')
parser.add_option("-c", "--conf", default='/etc/pungi/pungi.conf', dest="config",
help='Config file to use')
parser.add_option("--all-stages", action="store_true", default=True, dest="do_all",
help="Enable ALL stages")
parser.add_option("-G", action="store_true", default=False, dest="do_gather",
help="Flag to enable processing the Gather stage")
parser.add_option("-B", action="store_true", default=False, dest="do_buildinstall",
help="Flag to enable processing the BuildInstall stage")
parser.add_option("-P", action="store_true", default=False, dest="do_packageorder",
help="Flag to enable processing the Package Order stage")
parser.add_option("-S", action="store_true", default=False, dest="do_splittree",
help="Flag to enable processing the SplitTree stage")
parser.add_option("-I", action="store_true", default=False, dest="do_createiso",
help="Flag to enable processing the CreateISO stage")
(opts, args) = parser.parse_args()
if opts.do_gather or opts.do_buildinstall or opts.do_packageorder or opts.do_splittree or opts.do_createiso:
opts.do_all = False
if len(sys.argv) < 2:
parser.print_help()
sys.exit(0)
return (opts, args)
def get_packagelist(manifest):
# Get the list of packages from the manifest file
try:
manifestfile = open(manifest, 'r')
except IOError:
print >> sys.stderr, "pungi: No such file:\'%s\'" % manifest
sys.exit(1)
pkglist = manifestfile.readlines()
manifestfile.close()
return pkglist
main()

2623
pungi.spec

File diff suppressed because it is too large Load Diff

33
pungi/__init__.py Normal file
View File

@ -0,0 +1,33 @@
# -*- coding: utf-8 -*-
import os
import re
def get_full_version():
"""
Find full version of Pungi: if running from git, this will return cleaned
output of `git describe`, otherwise it will look for installed version.
"""
location = os.path.join(os.path.dirname(os.path.realpath(__file__)), "..")
if os.path.isdir(os.path.join(location, ".git")):
import subprocess
proc = subprocess.Popen(
["git", "--git-dir=%s/.git" % location, "describe", "--tags"],
stdout=subprocess.PIPE,
universal_newlines=True,
)
output, _ = proc.communicate()
return re.sub(r"-1.fc\d\d?", "", output.strip().replace("pungi-", ""))
else:
import subprocess
proc = subprocess.Popen(
["rpm", "-q", "pungi"], stdout=subprocess.PIPE, universal_newlines=True
)
(output, err) = proc.communicate()
if not err:
return output.rstrip()
else:
return "unknown"

115
pungi/arch.py Normal file
View File

@ -0,0 +1,115 @@
# -*- coding: utf-8 -*-
# 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; version 2 of the License.
#
# 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 Library General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, see <https://gnu.org/licenses/>.
from .arch_utils import arches as ALL_ARCHES
from .arch_utils import getBaseArch, getMultiArchInfo, getArchList
TREE_ARCH_YUM_ARCH_MAP = {
"i386": "i686",
"sparc": "sparc64v",
"arm": "armv7l",
"armhfp": "armv7hnl",
}
def tree_arch_to_yum_arch(tree_arch):
# this is basically an opposite to pungi.arch_utils.getBaseArch()
yum_arch = TREE_ARCH_YUM_ARCH_MAP.get(tree_arch, tree_arch)
return yum_arch
def get_multilib_arch(yum_arch):
arch_info = getMultiArchInfo(yum_arch)
if arch_info is None:
return None
return arch_info[0]
def get_valid_multilib_arches(tree_arch):
yum_arch = tree_arch_to_yum_arch(tree_arch)
multilib_arch = get_multilib_arch(yum_arch)
if not multilib_arch:
return []
return [i for i in getArchList(multilib_arch) if i not in ("noarch", "src")]
def get_valid_arches(tree_arch, multilib=True, add_noarch=True, add_src=False):
result = []
yum_arch = tree_arch_to_yum_arch(tree_arch)
for arch in getArchList(yum_arch):
if arch not in result:
result.append(arch)
if not multilib:
for i in get_valid_multilib_arches(tree_arch):
while i in result:
result.remove(i)
if add_noarch and "noarch" not in result:
result.append("noarch")
if add_src and "src" not in result:
result.append("src")
return result
def get_compatible_arches(arch, multilib=False):
tree_arch = getBaseArch(arch)
compatible_arches = get_valid_arches(tree_arch, multilib=multilib)
return compatible_arches
def is_valid_arch(arch):
if arch in ("noarch", "src", "nosrc"):
return True
if arch in ALL_ARCHES:
return True
return False
def split_name_arch(name_arch):
if "." in name_arch:
name, arch = name_arch.rsplit(".", 1)
if not is_valid_arch(arch):
name, arch = name_arch, None
else:
name, arch = name_arch, None
return name, arch
def is_excluded(package, arches, logger=None):
"""Check if package is excluded from given architectures."""
if any(
getBaseArch(exc_arch) == 'x86_64' for exc_arch in package.exclusivearch
) and 'x86_64_v2' not in package.exclusivearch:
package.exclusivearch.append('x86_64_v2')
if package.excludearch and set(package.excludearch) & set(arches):
if logger:
logger.debug(
"Excluding (EXCLUDEARCH: %s): %s"
% (sorted(set(package.excludearch)), package.file_name)
)
return True
if package.exclusivearch and not (set(package.exclusivearch) & set(arches)):
if logger:
logger.debug(
"Excluding (EXCLUSIVEARCH: %s): %s"
% (sorted(set(package.exclusivearch)), package.file_name)
)
return True
return False

368
pungi/arch_utils.py Normal file
View File

@ -0,0 +1,368 @@
# A copy of some necessary parts from yum.rpmUtils.arch, with slightly changes:
# 1. _ppc64_native_is_best changed to True
# 2. code style fixes for flake8 reported errors
import os
import rpm
import ctypes
import struct
# _ppc64_native_is_best is False in yum's source code, but patched with a
# separate patch when built from source rpm, so we set it to True here.
_ppc64_native_is_best = True
# dict mapping arch -> ( multicompat, best personality, biarch personality )
multilibArches = {
"x86_64": ("athlon", "x86_64", "athlon"),
"sparc64v": ("sparcv9v", "sparcv9v", "sparc64v"),
"sparc64": ("sparcv9", "sparcv9", "sparc64"),
"ppc64": ("ppc", "ppc", "ppc64"),
"s390x": ("s390", "s390x", "s390"),
}
if _ppc64_native_is_best:
multilibArches["ppc64"] = ("ppc", "ppc64", "ppc64")
arches = {
# ia32
"athlon": "i686",
"i686": "i586",
"geode": "i586",
"i586": "i486",
"i486": "i386",
"i386": "noarch",
# amd64
"x86_64": "athlon",
"amd64": "x86_64",
"ia32e": "x86_64",
# x86-64-v2
"x86_64_v2": "noarch",
# ppc64le
"ppc64le": "noarch",
# ppc
"ppc64p7": "ppc64",
"ppc64pseries": "ppc64",
"ppc64iseries": "ppc64",
"ppc64": "ppc",
"ppc": "noarch",
# s390{,x}
"s390x": "s390",
"s390": "noarch",
# sparc
"sparc64v": "sparcv9v",
"sparc64": "sparcv9",
"sparcv9v": "sparcv9",
"sparcv9": "sparcv8",
"sparcv8": "sparc",
"sparc": "noarch",
# alpha
"alphaev7": "alphaev68",
"alphaev68": "alphaev67",
"alphaev67": "alphaev6",
"alphaev6": "alphapca56",
"alphapca56": "alphaev56",
"alphaev56": "alphaev5",
"alphaev5": "alphaev45",
"alphaev45": "alphaev4",
"alphaev4": "alpha",
"alpha": "noarch",
# arm
"armv7l": "armv6l",
"armv6l": "armv5tejl",
"armv5tejl": "armv5tel",
"armv5tel": "noarch",
# arm hardware floating point
"armv7hnl": "armv7hl",
"armv7hl": "armv6hl",
"armv6hl": "noarch",
# arm64
"arm64": "noarch",
# aarch64
"aarch64": "noarch",
# super-h
"sh4a": "sh4",
"sh4": "noarch",
"sh3": "noarch",
# itanium
"ia64": "noarch",
}
# Will contain information parsed from /proc/self/auxv via _parse_auxv().
# Should move into rpm really.
_aux_vector = {
"platform": "",
"hwcap": 0,
}
def isMultiLibArch(arch=None): # pragma: no cover
"""returns true if arch is a multilib arch, false if not"""
if arch is None:
arch = canonArch
if arch not in arches: # or we could check if it is noarch
return 0
if arch in multilibArches:
return 1
if arches[arch] in multilibArches:
return 1
return 0
def getArchList(thisarch=None): # pragma: no cover
# this returns a list of archs that are compatible with arch given
if not thisarch:
thisarch = canonArch
archlist = [thisarch]
while thisarch in arches:
thisarch = arches[thisarch]
archlist.append(thisarch)
# hack hack hack
# sparc64v is also sparc64 compat
if archlist[0] == "sparc64v":
archlist.insert(1, "sparc64")
# if we're a weirdo arch - add noarch on there.
if len(archlist) == 1 and archlist[0] == thisarch:
archlist.append("noarch")
return archlist
def _try_read_cpuinfo(): # pragma: no cover
"""Try to read /proc/cpuinfo ... if we can't ignore errors (ie. proc not
mounted)."""
try:
with open("/proc/cpuinfo", "r") as f:
return f.readlines()
except Exception:
return []
def _parse_auxv(): # pragma: no cover
"""Read /proc/self/auxv and parse it into global dict for easier access
later on, very similar to what rpm does."""
# In case we can't open and read /proc/self/auxv, just return
try:
with open("/proc/self/auxv", "rb") as f:
data = f.read()
except Exception:
return
# Define values from /usr/include/elf.h
AT_PLATFORM = 15
AT_HWCAP = 16
fmtlen = struct.calcsize("LL")
offset = 0
platform = ctypes.c_char_p()
# Parse the data and fill in _aux_vector dict
while offset <= len(data) - fmtlen:
at_type, at_val = struct.unpack_from("LL", data, offset)
if at_type == AT_PLATFORM:
platform.value = at_val
_aux_vector["platform"] = platform.value
if at_type == AT_HWCAP:
_aux_vector["hwcap"] = at_val
offset = offset + fmtlen
def getCanonX86Arch(arch): # pragma: no cover
if arch == "i586":
for line in _try_read_cpuinfo():
if line.startswith("model name"):
if line.find("Geode(TM)") != -1:
return "geode"
break
return arch
# only athlon vs i686 isn't handled with uname currently
if arch != "i686":
return arch
# if we're i686 and AuthenticAMD, then we should be an athlon
for line in _try_read_cpuinfo():
if line.startswith("vendor") and line.find("AuthenticAMD") != -1:
return "athlon"
elif line.startswith("vendor") and line.find("HygonGenuine") != -1:
return "athlon"
# i686 doesn't guarantee cmov, but we depend on it
elif line.startswith("flags"):
if line.find("cmov") == -1:
return "i586"
break
return arch
def getCanonARMArch(arch): # pragma: no cover
# the %{_target_arch} macro in rpm will let us know the abi we are using
target = rpm.expandMacro("%{_target_cpu}")
if target.startswith("armv6h"):
return target
if target.startswith("armv7h"):
return target
return arch
def getCanonPPCArch(arch): # pragma: no cover
# FIXME: should I do better handling for mac, etc?
if arch != "ppc64":
return arch
machine = None
for line in _try_read_cpuinfo():
if line.find("machine") != -1:
machine = line.split(":")[1]
break
platform = _aux_vector["platform"]
if machine is None and not platform:
return arch
try:
if platform.startswith("power") and int(platform[5:].rstrip("+")) >= 7:
return "ppc64p7"
except Exception:
pass
if machine is None:
return arch
if machine.find("CHRP IBM") != -1:
return "ppc64pseries"
if machine.find("iSeries") != -1:
return "ppc64iseries"
return arch
def getCanonSPARCArch(arch): # pragma: no cover
# Deal with sun4v, sun4u, sun4m cases
SPARCtype = None
for line in _try_read_cpuinfo():
if line.startswith("type"):
SPARCtype = line.split(":")[1]
break
if SPARCtype is None:
return arch
if SPARCtype.find("sun4v") != -1:
if arch.startswith("sparc64"):
return "sparc64v"
else:
return "sparcv9v"
if SPARCtype.find("sun4u") != -1:
if arch.startswith("sparc64"):
return "sparc64"
else:
return "sparcv9"
if SPARCtype.find("sun4m") != -1:
return "sparcv8"
return arch
def getCanonX86_64Arch(arch): # pragma: no cover
if arch != "x86_64":
return arch
vendor = None
for line in _try_read_cpuinfo():
if line.startswith("vendor_id"):
vendor = line.split(":")[1]
break
if vendor is None:
return arch
if vendor.find("Authentic AMD") != -1 or vendor.find("AuthenticAMD") != -1:
return "amd64"
if vendor.find("HygonGenuine") != -1:
return "amd64"
if vendor.find("GenuineIntel") != -1:
return "ia32e"
return arch
def getCanonArch(skipRpmPlatform=0): # pragma: no cover
if not skipRpmPlatform and os.access("/etc/rpm/platform", os.R_OK):
try:
f = open("/etc/rpm/platform", "r")
line = f.readline()
f.close()
(arch, vendor, opersys) = line.split("-", 2)
return arch
except Exception:
pass
arch = os.uname()[4]
_parse_auxv()
if len(arch) == 4 and arch[0] == "i" and arch[2:4] == "86":
return getCanonX86Arch(arch)
if arch.startswith("arm"):
return getCanonARMArch(arch)
if arch.startswith("ppc"):
return getCanonPPCArch(arch)
if arch.startswith("sparc"):
return getCanonSPARCArch(arch)
if arch == "x86_64":
return getCanonX86_64Arch(arch)
return arch
canonArch = getCanonArch()
# this gets you the "compat" arch of a biarch pair
def getMultiArchInfo(arch=canonArch): # pragma: no cover
if arch in multilibArches:
return multilibArches[arch]
if arch in arches and arches[arch] != "noarch":
return getMultiArchInfo(arch=arches[arch])
return None
def getBaseArch(myarch=None): # pragma: no cover
"""returns 'base' arch for myarch, if specified, or canonArch if not.
base arch is the arch before noarch in the arches dict if myarch is not
a key in the multilibArches."""
if not myarch:
myarch = canonArch
if myarch not in arches: # this is dumb, but <shrug>
return myarch
if myarch.startswith("sparc64"):
return "sparc"
elif myarch == "ppc64le":
return "ppc64le"
elif myarch.startswith("ppc64") and not _ppc64_native_is_best:
return "ppc"
elif myarch.startswith("arm64"):
return "arm64"
elif myarch.startswith("armv6h"):
return "armhfp"
elif myarch.startswith("armv7h"):
return "armhfp"
elif myarch.startswith("arm"):
return "arm"
if isMultiLibArch(arch=myarch):
if myarch in multilibArches:
return myarch
else:
return arches[myarch]
if myarch in arches:
basearch = myarch
value = arches[basearch]
while value != "noarch":
basearch = value
value = arches[basearch]
return basearch

1622
pungi/checks.py Normal file

File diff suppressed because it is too large Load Diff

34
pungi/common.py Normal file
View File

@ -0,0 +1,34 @@
# -*- coding: utf-8 -*-
# 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; version 2 of the License.
#
# 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 Library General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, see <https://gnu.org/licenses/>.
class OptionsBase(object):
def __init__(self, **kwargs):
"""
inherit and initialize attributes
call self.merge_options(**kwargs) at the end
"""
pass
def merge_options(self, **kwargs):
"""
override defaults with user defined values
"""
for key, value in kwargs.items():
if not hasattr(self, key):
raise ValueError(
"Invalid option in %s: %s" % (self.__class__.__name__, key)
)
setattr(self, key, value)

779
pungi/compose.py Normal file
View File

@ -0,0 +1,779 @@
# -*- coding: utf-8 -*-
# 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; version 2 of the License.
#
# 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 Library General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, see <https://gnu.org/licenses/>.
__all__ = ("Compose",)
import contextlib
import errno
import logging
import os
import time
import tempfile
import shutil
import json
import socket
import kobo.log
import kobo.tback
import requests
from requests.exceptions import RequestException
from productmd.composeinfo import ComposeInfo
from productmd.images import Images
from dogpile.cache import make_region
from pungi.graph import SimpleAcyclicOrientedGraph
from pungi.wrappers.variants import VariantsXmlParser
from pungi.paths import Paths
from pungi.wrappers.kojiwrapper import KojiDownloadProxy
from pungi.wrappers.scm import get_file_from_scm
from pungi.util import (
makedirs,
get_arch_variant_data,
get_format_substs,
get_variant_data,
retry,
translate_path_raw,
)
from pungi.metadata import compose_to_composeinfo
try:
# This is available since productmd >= 1.18
# TODO: remove this once the version is distributed widely enough
from productmd.composeinfo import SUPPORTED_MILESTONES
except ImportError:
SUPPORTED_MILESTONES = ["RC", "Update", "SecurityFix"]
def is_status_fatal(status_code):
"""Check if status code returned from CTS reports an error that is unlikely
to be fixed by retrying. Generally client errors (4XX) are fatal, with the
exception of 401 Unauthorized which could be caused by transient network
issue between compose host and KDC.
"""
if status_code == 401:
return False
return status_code >= 400 and status_code < 500
@retry(wait_on=RequestException)
def retry_request(method, url, data=None, json_data=None, auth=None):
"""
:param str method: Reqest method.
:param str url: Target URL.
:param dict data: form-urlencoded data to send in the body of the request.
:param dict json_data: json data to send in the body of the request.
"""
request_method = getattr(requests, method)
rv = request_method(url, data=data, json=json_data, auth=auth)
if is_status_fatal(rv.status_code):
try:
error = rv.json()
except ValueError:
error = rv.text
raise RuntimeError("%s responded with %d: %s" % (url, rv.status_code, error))
rv.raise_for_status()
return rv
class BearerAuth(requests.auth.AuthBase):
def __init__(self, token):
self.token = token
def __call__(self, r):
r.headers["authorization"] = "Bearer " + self.token
return r
@contextlib.contextmanager
def cts_auth(pungi_conf):
"""
:param dict pungi_conf: dict obj of pungi.json config.
"""
auth = None
token = None
cts_keytab = pungi_conf.get("cts_keytab")
cts_oidc_token_url = os.environ.get("CTS_OIDC_TOKEN_URL", "") or pungi_conf.get(
"cts_oidc_token_url"
)
try:
if cts_keytab:
# requests-kerberos cannot accept custom keytab, we need to use
# environment variable for this. But we need to change environment
# only temporarily just for this single requests.post.
# So at first backup the current environment and revert to it
# after the requests call.
from requests_kerberos import HTTPKerberosAuth
auth = HTTPKerberosAuth()
environ_copy = dict(os.environ)
if "$HOSTNAME" in cts_keytab:
cts_keytab = cts_keytab.replace("$HOSTNAME", socket.gethostname())
os.environ["KRB5_CLIENT_KTNAME"] = cts_keytab
os.environ["KRB5CCNAME"] = "DIR:%s" % tempfile.mkdtemp()
elif cts_oidc_token_url:
cts_oidc_client_id = os.environ.get(
"CTS_OIDC_CLIENT_ID", ""
) or pungi_conf.get("cts_oidc_client_id", "")
token = retry_request(
"post",
cts_oidc_token_url,
data={
"grant_type": "client_credentials",
"client_id": cts_oidc_client_id,
"client_secret": os.environ.get("CTS_OIDC_CLIENT_SECRET", ""),
},
).json()["access_token"]
auth = BearerAuth(token)
del token
yield auth
except Exception as e:
# Avoid leaking client secret in trackback
e.show_locals = False
raise e
finally:
if cts_keytab:
shutil.rmtree(os.environ["KRB5CCNAME"].split(":", 1)[1])
os.environ.clear()
os.environ.update(environ_copy)
def get_compose_info(
conf,
compose_type="production",
compose_date=None,
compose_respin=None,
compose_label=None,
parent_compose_ids=None,
respin_of=None,
):
"""
Creates inncomplete ComposeInfo to generate Compose ID
"""
ci = ComposeInfo()
ci.release.name = conf["release_name"]
ci.release.short = conf["release_short"]
ci.release.version = conf["release_version"]
ci.release.is_layered = True if conf.get("base_product_name", "") else False
ci.release.type = conf.get("release_type", "ga").lower()
ci.release.internal = bool(conf.get("release_internal", False))
if ci.release.is_layered:
ci.base_product.name = conf["base_product_name"]
ci.base_product.short = conf["base_product_short"]
ci.base_product.version = conf["base_product_version"]
ci.base_product.type = conf.get("base_product_type", "ga").lower()
ci.compose.label = compose_label
ci.compose.type = compose_type
ci.compose.date = compose_date or time.strftime("%Y%m%d", time.localtime())
ci.compose.respin = compose_respin or 0
ci.compose.id = ci.create_compose_id()
cts_url = conf.get("cts_url")
if cts_url:
# Create compose in CTS and get the reserved compose ID.
url = os.path.join(cts_url, "api/1/composes/")
data = {
"compose_info": json.loads(ci.dumps()),
"parent_compose_ids": parent_compose_ids,
"respin_of": respin_of,
}
with cts_auth(conf) as authentication:
rv = retry_request("post", url, json_data=data, auth=authentication)
# Update local ComposeInfo with received ComposeInfo.
cts_ci = ComposeInfo()
cts_ci.loads(rv.text)
ci.compose.respin = cts_ci.compose.respin
ci.compose.id = cts_ci.compose.id
return ci
def write_compose_info(compose_dir, ci):
"""
Write ComposeInfo `ci` to `compose_dir` subdirectories.
"""
makedirs(compose_dir)
with open(os.path.join(compose_dir, "COMPOSE_ID"), "w") as f:
f.write(ci.compose.id)
work_dir = os.path.join(compose_dir, "work", "global")
makedirs(work_dir)
ci.dump(os.path.join(work_dir, "composeinfo-base.json"))
def update_compose_url(compose_id, compose_dir, conf):
cts_url = conf.get("cts_url", None)
if cts_url:
url = os.path.join(cts_url, "api/1/composes", compose_id)
tp = conf.get("translate_paths", None)
compose_url = translate_path_raw(tp, compose_dir)
if compose_url == compose_dir:
# We do not have a URL, do not attempt the update.
return
data = {
"action": "set_url",
"compose_url": compose_url,
}
with cts_auth(conf) as authentication:
return retry_request("patch", url, json_data=data, auth=authentication)
def get_compose_dir(
topdir,
conf,
compose_type="production",
compose_date=None,
compose_respin=None,
compose_label=None,
already_exists_callbacks=None,
parent_compose_ids=None,
respin_of=None,
):
already_exists_callbacks = already_exists_callbacks or []
ci = get_compose_info(
conf,
compose_type,
compose_date,
compose_respin,
compose_label,
parent_compose_ids,
respin_of,
)
cts_url = conf.get("cts_url", None)
if cts_url:
# Create compose directory.
compose_dir = os.path.join(topdir, ci.compose.id)
os.makedirs(compose_dir)
else:
while 1:
ci.compose.id = ci.create_compose_id()
compose_dir = os.path.join(topdir, ci.compose.id)
exists = False
# TODO: callbacks to determine if a composeid was already used
# for callback in already_exists_callbacks:
# if callback(data):
# exists = True
# break
# already_exists_callbacks fallback: does target compose_dir exist?
try:
os.makedirs(compose_dir)
except OSError as ex:
if ex.errno == errno.EEXIST:
exists = True
else:
raise
if exists:
ci = get_compose_info(
conf,
compose_type,
compose_date,
ci.compose.respin + 1,
compose_label,
)
continue
break
write_compose_info(compose_dir, ci)
return compose_dir
class Compose(kobo.log.LoggingBase):
def __init__(
self,
conf,
topdir,
skip_phases=None,
just_phases=None,
old_composes=None,
koji_event=None,
supported=False,
logger=None,
notifier=None,
):
kobo.log.LoggingBase.__init__(self, logger)
# TODO: check if minimal conf values are set
self.conf = conf
# This is a dict mapping UID to Variant objects. It only contains top
# level variants.
self.variants = {}
# This is a similar mapping, but contains even nested variants.
self.all_variants = {}
self.topdir = os.path.abspath(topdir)
self.skip_phases = skip_phases or []
self.just_phases = just_phases or []
self.old_composes = old_composes or []
self.koji_event = koji_event or conf.get("koji_event")
self.notifier = notifier
self._old_config = None
# path definitions
self.paths = Paths(self)
# Set up logging to file
if logger:
kobo.log.add_file_logger(
logger, self.paths.log.log_file("global", "pungi.log")
)
kobo.log.add_file_logger(
logger, self.paths.log.log_file("global", "excluding-arch.log")
)
class PungiLogFilter(logging.Filter):
def filter(self, record):
return (
False
if record.funcName and record.funcName == "is_excluded"
else True
)
class ExcludingArchLogFilter(logging.Filter):
def filter(self, record):
message = record.getMessage()
if "Populating package set for arch:" in message or (
record.funcName and record.funcName == "is_excluded"
):
return True
else:
return False
for handler in logger.handlers:
if isinstance(handler, logging.FileHandler):
log_file_name = os.path.basename(handler.stream.name)
if log_file_name == "pungi.global.log":
handler.addFilter(PungiLogFilter())
elif log_file_name == "excluding-arch.global.log":
handler.addFilter(ExcludingArchLogFilter())
# to provide compose_id, compose_date and compose_respin
self.ci_base = ComposeInfo()
self.ci_base.load(
os.path.join(self.paths.work.topdir(arch="global"), "composeinfo-base.json")
)
self.supported = supported
if (
self.compose_label
and self.compose_label.split("-")[0] in SUPPORTED_MILESTONES
):
self.log_info(
"Automatically setting 'supported' flag due to label: %s."
% self.compose_label
)
self.supported = True
self.im = Images()
self.im.compose.id = self.compose_id
self.im.compose.type = self.compose_type
self.im.compose.date = self.compose_date
self.im.compose.respin = self.compose_respin
self.im.metadata_path = self.paths.compose.metadata()
self.containers_metadata = {}
# Stores list of deliverables that failed, but did not abort the
# compose.
# {deliverable: [(Variant.uid, arch, subvariant)]}
self.failed_deliverables = {}
self.attempted_deliverables = {}
self.required_deliverables = {}
if self.conf.get("dogpile_cache_backend", None):
self.cache_region = make_region().configure(
self.conf.get("dogpile_cache_backend"),
expiration_time=self.conf.get("dogpile_cache_expiration_time", 3600),
arguments=self.conf.get("dogpile_cache_arguments", {}),
)
else:
self.cache_region = make_region().configure("dogpile.cache.null")
self.koji_downloader = KojiDownloadProxy.from_config(self.conf, self._logger)
get_compose_info = staticmethod(get_compose_info)
write_compose_info = staticmethod(write_compose_info)
get_compose_dir = staticmethod(get_compose_dir)
update_compose_url = staticmethod(update_compose_url)
def __getitem__(self, name):
return self.variants[name]
@property
def compose_id(self):
return self.ci_base.compose.id
@property
def compose_date(self):
return self.ci_base.compose.date
@property
def compose_respin(self):
return self.ci_base.compose.respin
@property
def compose_type(self):
return self.ci_base.compose.type
@property
def compose_type_suffix(self):
return self.ci_base.compose.type_suffix
@property
def compose_label(self):
return self.ci_base.compose.label
@property
def compose_label_major_version(self):
return self.ci_base.compose.label_major_version
@property
def has_comps(self):
return bool(self.conf.get("comps_file", False))
@property
def has_module_defaults(self):
return bool(self.conf.get("module_defaults_dir", False))
@property
def has_module_obsoletes(self):
return bool(self.conf.get("module_obsoletes_dir", False))
@property
def config_dir(self):
return os.path.dirname(self.conf._open_file or "")
@property
def should_create_yum_database(self):
"""Explicit configuration trumps all. Otherwise check gather backend
and only create it for Yum.
"""
config = self.conf.get("createrepo_database")
if config is not None:
return config
return self.conf["gather_backend"] == "yum"
def read_variants(self):
# TODO: move to phases/init ?
variants_file = self.paths.work.variants_file(arch="global")
scm_dict = self.conf["variants_file"]
if isinstance(scm_dict, dict):
file_name = os.path.basename(scm_dict["file"])
if scm_dict["scm"] == "file":
scm_dict["file"] = os.path.join(
self.config_dir, os.path.basename(scm_dict["file"])
)
else:
file_name = os.path.basename(scm_dict)
scm_dict = os.path.join(self.config_dir, scm_dict)
self.log_debug("Writing variants file: %s", variants_file)
tmp_dir = self.mkdtemp(prefix="variants_file_")
get_file_from_scm(scm_dict, tmp_dir, compose=self)
shutil.copy2(os.path.join(tmp_dir, file_name), variants_file)
shutil.rmtree(tmp_dir)
tree_arches = self.conf.get("tree_arches", None)
tree_variants = self.conf.get("tree_variants", None)
with open(variants_file, "r") as file_obj:
parser = VariantsXmlParser(
file_obj, tree_arches, tree_variants, logger=self._logger
)
self.variants = parser.parse()
self.all_variants = {}
for variant in self.get_variants():
self.all_variants[variant.uid] = variant
# populate ci_base with variants - needed for layered-products (compose_id)
# FIXME - compose_to_composeinfo is no longer needed and has been
# removed, but I'm not entirely sure what this is needed for
# or if it is at all
self.ci_base = compose_to_composeinfo(self)
def get_variants(self, types=None, arch=None):
result = []
for i in self.variants.values():
if (not types or i.type in types) and (not arch or arch in i.arches):
result.append(i)
result.extend(i.get_variants(types=types, arch=arch))
return sorted(set(result))
def get_arches(self):
result = set()
for variant in self.get_variants():
for arch in variant.arches:
result.add(arch)
return sorted(result)
@property
def status_file(self):
"""Path to file where the compose status will be stored."""
if not hasattr(self, "_status_file"):
self._status_file = os.path.join(self.topdir, "STATUS")
return self._status_file
def _log_failed_deliverables(self):
for kind, data in self.failed_deliverables.items():
for variant, arch, subvariant in data:
self.log_info(
"Failed %s on variant <%s>, arch <%s>, subvariant <%s>."
% (kind, variant, arch, subvariant)
)
log = os.path.join(self.paths.log.topdir("global"), "deliverables.json")
with open(log, "w") as f:
json.dump(
{
"required": self.required_deliverables,
"failed": self.failed_deliverables,
"attempted": self.attempted_deliverables,
},
f,
indent=4,
)
def write_status(self, stat_msg):
if stat_msg not in ("STARTED", "FINISHED", "DOOMED", "TERMINATED"):
self.log_warning("Writing nonstandard compose status: %s" % stat_msg)
old_status = self.get_status()
if stat_msg == old_status:
return
if old_status == "FINISHED":
msg = "Could not modify a FINISHED compose: %s" % self.topdir
self.log_error(msg)
raise RuntimeError(msg)
if stat_msg == "FINISHED" and self.failed_deliverables:
stat_msg = "FINISHED_INCOMPLETE"
self._log_failed_deliverables()
with open(self.status_file, "w") as f:
f.write(stat_msg + "\n")
if self.notifier:
self.notifier.send("status-change", status=stat_msg)
def get_status(self):
if not os.path.isfile(self.status_file):
return
return open(self.status_file, "r").read().strip()
def get_image_name(
self, arch, variant, disc_type="dvd", disc_num=1, suffix=".iso", format=None
):
"""Create a filename for image with given parameters.
:raises RuntimeError: when unknown ``disc_type`` is given
"""
default_format = "{compose_id}-{variant}-{arch}-{disc_type}{disc_num}{suffix}"
format = format or self.conf.get("image_name_format", default_format)
if isinstance(format, dict):
conf = get_variant_data(self.conf, "image_name_format", variant)
format = conf[0] if conf else default_format
if arch == "src":
arch = "source"
if disc_num:
disc_num = int(disc_num)
else:
disc_num = ""
kwargs = {
"arch": arch,
"disc_type": disc_type,
"disc_num": disc_num,
"suffix": suffix,
}
if variant.type == "layered-product":
variant_uid = variant.parent.uid
kwargs["compose_id"] = self.ci_base[variant.uid].compose_id
else:
variant_uid = variant.uid
args = get_format_substs(self, variant=variant_uid, **kwargs)
try:
return (format % args).format(**args)
except KeyError as err:
raise RuntimeError(
"Failed to create image name: unknown format element: %s" % err
)
def can_fail(self, variant, arch, deliverable):
"""Figure out if deliverable can fail on variant.arch.
Variant can be None.
"""
failable = get_arch_variant_data(
self.conf, "failable_deliverables", arch, variant
)
return deliverable in failable
def attempt_deliverable(self, variant, arch, kind, subvariant=None):
"""Log information about attempted deliverable."""
variant_uid = variant.uid if variant else ""
self.attempted_deliverables.setdefault(kind, []).append(
(variant_uid, arch, subvariant)
)
def require_deliverable(self, variant, arch, kind, subvariant=None):
"""Log information about attempted deliverable."""
variant_uid = variant.uid if variant else ""
self.required_deliverables.setdefault(kind, []).append(
(variant_uid, arch, subvariant)
)
def fail_deliverable(self, variant, arch, kind, subvariant=None):
"""Log information about failed deliverable."""
variant_uid = variant.uid if variant else ""
self.failed_deliverables.setdefault(kind, []).append(
(variant_uid, arch, subvariant)
)
@property
def image_release(self):
"""Generate a value to pass to Koji as image release.
If this compose has a label, the version from it will be used,
otherwise we will create a string with date, compose type and respin.
"""
if self.compose_label:
milestone, release = self.compose_label.split("-")
return release
return "%s%s.%s" % (
self.compose_date,
self.ci_base.compose.type_suffix,
self.compose_respin,
)
@property
def image_version(self):
"""Generate a value to pass to Koji as image version.
The value is based on release version. If compose has a label, the
milestone from it is appended to the version (unless it is RC).
"""
version = self.ci_base.release.version
if self.compose_label and not self.compose_label.startswith("RC-"):
milestone, release = self.compose_label.split("-")
return "%s_%s" % (version, milestone)
return version
def mkdtemp(self, arch=None, variant=None, suffix="", prefix="tmp"):
"""
Create and return a unique temporary directory under dir of
<compose_topdir>/work/{global,<arch>}/tmp[-<variant>]/
"""
path = os.path.join(self.paths.work.tmp_dir(arch=arch, variant=variant))
tmpdir = tempfile.mkdtemp(suffix=suffix, prefix=prefix, dir=path)
os.chmod(tmpdir, 0o755)
return tmpdir
def dump_containers_metadata(self):
"""Create a file with container metadata if there are any containers."""
if not self.containers_metadata:
return
with open(self.paths.compose.metadata("osbs.json"), "w") as f:
json.dump(
self.containers_metadata,
f,
indent=4,
sort_keys=True,
separators=(",", ": "),
)
def traceback(self, detail=None, show_locals=True):
"""Store an extended traceback. This method should only be called when
handling an exception.
:param str detail: Extra information appended to the filename
"""
basename = "traceback"
if detail:
basename += "-" + detail
tb_path = self.paths.log.log_file("global", basename)
self.log_error("Extended traceback in: %s", tb_path)
tback = kobo.tback.Traceback(show_locals=show_locals).get_traceback()
# Kobo 0.36.0 returns traceback as str, older versions return bytes
with open(tb_path, "wb" if isinstance(tback, bytes) else "w") as f:
f.write(tback)
def load_old_compose_config(self):
"""
Helper method to load Pungi config dump from old compose.
"""
if not self._old_config:
config_dump_full = self.paths.log.log_file("global", "config-dump")
config_dump_full = self.paths.old_compose_path(config_dump_full)
if not config_dump_full:
return None
self.log_info("Loading old config file: %s", config_dump_full)
with open(config_dump_full, "r") as f:
self._old_config = json.load(f)
return self._old_config
def get_ordered_variant_uids(compose):
if not hasattr(compose, "_ordered_variant_uids"):
ordered_variant_uids = _prepare_variant_as_lookaside(compose)
# Some variants were not mentioned in configuration value
# 'variant_as_lookaside' and its run order is not crucial (that
# means there are no dependencies inside this group). They will be
# processed first. A-Z sorting is for reproducibility.
unordered_variant_uids = sorted(
set(compose.all_variants.keys()) - set(ordered_variant_uids)
)
setattr(
compose,
"_ordered_variant_uids",
unordered_variant_uids + ordered_variant_uids,
)
return getattr(compose, "_ordered_variant_uids")
def _prepare_variant_as_lookaside(compose):
"""
Configuration value 'variant_as_lookaside' contains variant pairs <variant,
its lookaside>. In that pair lookaside variant have to be processed first.
Structure can be represented as a oriented graph. Its spanning line shows
order how to process this set of variants.
"""
variant_as_lookaside = compose.conf.get("variant_as_lookaside", [])
graph = SimpleAcyclicOrientedGraph()
for variant, lookaside_variant in variant_as_lookaside:
try:
graph.add_edge(variant, lookaside_variant)
except ValueError as e:
raise ValueError(
"There is a bad configuration in 'variant_as_lookaside': %s" % e
)
variant_processing_order = reversed(graph.prune_graph())
return list(variant_processing_order)

View File

View File

@ -0,0 +1,93 @@
# -*- coding: utf-8 -*-
# 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; version 2 of the License.
#
# 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 Library General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, see <https://gnu.org/licenses/>.
"""
The .discinfo file contains metadata about media.
Following fields are part of the .discinfo file,
one record per line:
- timestamp
- release
- architecture
- disc number (optional)
"""
__all__ = (
"read_discinfo",
"write_discinfo",
"write_media_repo",
)
import os
import time
def write_discinfo(file_path, description, arch, disc_numbers=None, timestamp=None):
"""
Write a .discinfo file:
"""
disc_numbers = disc_numbers or ["ALL"]
if not isinstance(disc_numbers, list):
raise TypeError(
"Invalid type: disc_numbers type is %s; expected: <list>"
% type(disc_numbers)
)
if not timestamp:
timestamp = os.environ.get("SOURCE_DATE_EPOCH", "%f" % time.time())
with open(file_path, "w") as f:
f.write("%s\n" % timestamp)
f.write("%s\n" % description)
f.write("%s\n" % arch)
if disc_numbers:
f.write("%s\n" % ",".join([str(i) for i in disc_numbers]))
return timestamp
def read_discinfo(file_path):
result = {}
with open(file_path, "r") as f:
result["timestamp"] = f.readline().strip()
result["description"] = f.readline().strip()
result["arch"] = f.readline().strip()
disc_numbers = f.readline().strip()
if not disc_numbers:
result["disc_numbers"] = None
elif disc_numbers == "ALL":
result["disc_numbers"] = ["ALL"]
else:
result["disc_numbers"] = [int(i) for i in disc_numbers.split(",")]
return result
def write_media_repo(file_path, description, timestamp):
"""
Write media.repo file for the disc to be used on installed system.
PackageKit uses this.
"""
data = [
"[InstallMedia]",
"name=%s" % description,
"mediaid=%s" % timestamp,
"metadata_expire=-1",
"gpgcheck=0",
"cost=500",
"",
]
with open(file_path, "w") as repo_file:
repo_file.write("\n".join(data))
return timestamp

79
pungi/config.py Normal file
View File

@ -0,0 +1,79 @@
# -*- coding: utf-8 -*-
# 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; version 2 of the License.
#
# 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 Library General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, see <https://gnu.org/licenses/>.
import os
import sys
import time
from ConfigParser import SafeConfigParser
from .arch_utils import getBaseArch
# In development, `here` will point to the bin/ directory with scripts.
here = sys.path[0]
MULTILIBCONF = (
os.path.join(os.path.dirname(__file__), "..", "share", "multilib")
if here != "/usr/bin"
else "/usr/share/pungi/multilib"
)
class Config(SafeConfigParser):
def __init__(self, pungirc=None):
SafeConfigParser.__init__(self)
self.add_section("pungi")
self.add_section("lorax")
self.set("pungi", "osdir", "os")
self.set("pungi", "sourcedir", "source")
self.set("pungi", "debugdir", "debug")
self.set("pungi", "isodir", "iso")
self.set("pungi", "multilibconf", MULTILIBCONF)
self.set(
"pungi", "relnotefilere", "LICENSE README-BURNING-ISOS-en_US.txt ^RPM-GPG"
)
self.set("pungi", "relnotedirre", "")
self.set(
"pungi", "relnotepkgs", "fedora-repos fedora-release fedora-release-notes"
)
self.set("pungi", "product_path", "Packages")
self.set("pungi", "cachedir", "/var/cache/pungi")
self.set("pungi", "compress_type", "xz")
self.set("pungi", "arch", getBaseArch())
self.set("pungi", "family", "Fedora")
self.set("pungi", "iso_basename", "Fedora")
self.set("pungi", "version", time.strftime("%Y%m%d", time.localtime()))
self.set("pungi", "variant", "")
self.set("pungi", "destdir", os.getcwd())
self.set("pungi", "workdirbase", "/work")
self.set("pungi", "bugurl", "https://bugzilla.redhat.com")
self.set("pungi", "cdsize", "695.0")
self.set("pungi", "debuginfo", "True")
self.set("pungi", "alldeps", "True")
self.set("pungi", "isfinal", "False")
self.set("pungi", "nohash", "False")
self.set("pungi", "full_archlist", "False")
self.set("pungi", "multilib", "")
self.set("pungi", "lookaside_repos", "")
self.set("pungi", "resolve_deps", "True")
self.set("pungi", "no_dvd", "False")
self.set("pungi", "nomacboot", "False")
self.set("pungi", "rootfs_size", "False")
# if missing, self.read() is a noop, else change 'defaults'
if pungirc:
self.read(os.path.expanduser(pungirc))

201
pungi/createiso.py Normal file
View File

@ -0,0 +1,201 @@
# -*- coding: utf-8 -*-
from __future__ import print_function
import os
import six
from collections import namedtuple
from kobo.shortcuts import run
from six.moves import shlex_quote
from .wrappers import iso
from .wrappers.jigdo import JigdoWrapper
from .phases.buildinstall import BOOT_CONFIGS, BOOT_IMAGES
CreateIsoOpts = namedtuple(
"CreateIsoOpts",
[
"buildinstall_method",
"boot_iso",
"arch",
"output_dir",
"jigdo_dir",
"iso_name",
"volid",
"graft_points",
"supported",
"os_tree",
"hfs_compat",
"use_xorrisofs",
"iso_level",
"script_dir",
],
)
CreateIsoOpts.__new__.__defaults__ = (None,) * len(CreateIsoOpts._fields)
def quote(str):
"""Quote an argument for shell, but make sure $TEMPLATE variable will be
expanded.
"""
if str.startswith("$TEMPLATE"):
return "$TEMPLATE%s" % shlex_quote(str.replace("$TEMPLATE", "", 1))
return shlex_quote(str)
def emit(f, cmd):
"""Print line of shell code into the stream."""
if isinstance(cmd, six.string_types):
print(cmd, file=f)
else:
print(" ".join([quote(x) for x in cmd]), file=f)
FIND_TEMPLATE_SNIPPET = """if ! TEMPLATE="$($(head -n1 $(which lorax) | cut -c3-) -c 'import pylorax; print(pylorax.find_templates())')"; then TEMPLATE=/usr/share/lorax; fi""" # noqa: E501
def make_image(f, opts):
mkisofs_kwargs = {}
if opts.buildinstall_method:
if opts.buildinstall_method == "lorax":
emit(f, FIND_TEMPLATE_SNIPPET)
mkisofs_kwargs["boot_args"] = iso.get_boot_options(
opts.arch,
os.path.join("$TEMPLATE", "config_files/ppc"),
hfs_compat=opts.hfs_compat,
)
# ppc(64) doesn't seem to support utf-8
if opts.arch in ("ppc", "ppc64", "ppc64le"):
mkisofs_kwargs["input_charset"] = None
cmd = iso.get_mkisofs_cmd(
opts.iso_name,
None,
volid=opts.volid,
exclude=["./lost+found"],
graft_points=opts.graft_points,
use_xorrisofs=opts.use_xorrisofs,
iso_level=opts.iso_level,
**mkisofs_kwargs
)
emit(f, cmd)
def implant_md5(f, opts):
cmd = iso.get_implantisomd5_cmd(opts.iso_name, opts.supported)
emit(f, cmd)
def run_isohybrid(f, opts):
"""If the image is bootable, it should include an MBR or GPT so that it can
be booted when written to USB disk. This is done by running isohybrid on
the image.
"""
if opts.buildinstall_method and opts.arch in ["x86_64", "i386"]:
cmd = iso.get_isohybrid_cmd(opts.iso_name, opts.arch)
emit(f, cmd)
def make_manifest(f, opts):
emit(f, iso.get_manifest_cmd(opts.iso_name, opts.use_xorrisofs))
def make_jigdo(f, opts):
jigdo = JigdoWrapper()
files = [{"path": opts.os_tree, "label": None, "uri": None}]
cmd = jigdo.get_jigdo_cmd(
os.path.join(opts.output_dir, opts.iso_name),
files,
output_dir=opts.jigdo_dir,
no_servers=True,
report="noprogress",
)
emit(f, cmd)
def _get_perms(fs_path):
"""Compute proper permissions for a file.
This mimicks what -rational-rock option of genisoimage does. All read bits
are set, so that files and directories are globally readable. If any
execute bit is set for a file, set them all. No writes are allowed and
special bits are erased too.
"""
statinfo = os.stat(fs_path)
perms = 0o444
if statinfo.st_mode & 0o111:
perms |= 0o111
return perms
def write_xorriso_commands(opts):
# Create manifest for the boot.iso listing all contents
boot_iso_manifest = "%s.manifest" % os.path.join(
opts.script_dir, os.path.basename(opts.boot_iso)
)
run(
iso.get_manifest_cmd(
opts.boot_iso, opts.use_xorrisofs, output_file=boot_iso_manifest
)
)
# Find which files may have been updated by pungi. This only includes a few
# files from tweaking buildinstall and .discinfo metadata. There's no good
# way to detect whether the boot config files actually changed, so we may
# be updating files in the ISO with the same data.
UPDATEABLE_FILES = set(BOOT_IMAGES + BOOT_CONFIGS + [".discinfo"])
updated_files = set()
excluded_files = set()
with open(boot_iso_manifest) as f:
for line in f:
path = line.lstrip("/").rstrip("\n")
if path in UPDATEABLE_FILES:
updated_files.add(path)
else:
excluded_files.add(path)
script = os.path.join(opts.script_dir, "xorriso-%s.txt" % id(opts))
with open(script, "w") as f:
for cmd in iso.xorriso_commands(
opts.arch, opts.boot_iso, os.path.join(opts.output_dir, opts.iso_name)
):
emit(f, " ".join(cmd))
emit(f, "-volid %s" % opts.volid)
with open(opts.graft_points) as gp:
for line in gp:
iso_path, fs_path = line.strip().split("=", 1)
if iso_path in excluded_files:
continue
cmd = "-update" if iso_path in updated_files else "-map"
emit(f, "%s %s %s" % (cmd, fs_path, iso_path))
emit(f, "-chmod 0%o %s" % (_get_perms(fs_path), iso_path))
emit(f, "-chown_r 0 /")
emit(f, "-chgrp_r 0 /")
emit(f, "-end")
return script
def write_script(opts, f):
if bool(opts.jigdo_dir) != bool(opts.os_tree):
raise RuntimeError("jigdo_dir must be used together with os_tree")
emit(f, "#!/bin/bash")
emit(f, "set -ex")
emit(f, "cd %s" % opts.output_dir)
if opts.use_xorrisofs and opts.buildinstall_method:
script = write_xorriso_commands(opts)
emit(f, "xorriso -dialog on <%s" % script)
else:
make_image(f, opts)
run_isohybrid(f, opts)
implant_md5(f, opts)
make_manifest(f, opts)
if opts.jigdo_dir:
make_jigdo(f, opts)

155
pungi/dnf_wrapper.py Normal file
View File

@ -0,0 +1,155 @@
# -*- coding: utf-8 -*-
# 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; version 2 of the License.
#
# 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 Library General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, see <https://gnu.org/licenses/>.
# TODO: remove all DNF hacks, possibly this whole file
import dnf
import dnf.conf
import dnf.repo
import dnf.sack
import pungi.arch
try:
import dnf.rpm as dnf_arch
except ImportError:
import dnf.arch as dnf_arch
class Conf(dnf.conf.Conf):
# This is only modified to get our custom Substitutions class in.
def __init__(self, arch, *args, **kwargs):
super(Conf, self).__init__(*args, **kwargs)
self.substitutions = Substitutions(arch)
class Substitutions(dict):
# DNF version of Substitutions detects host arch. We don't want that.
def __init__(self, arch):
super(Substitutions, self).__init__()
self["arch"] = arch
self["basearch"] = dnf_arch.basearch(arch)
class DnfWrapper(dnf.Base):
def __init__(self, *args, **kwargs):
super(DnfWrapper, self).__init__(*args, **kwargs)
self.arch_wrapper = ArchWrapper(self.conf.substitutions["arch"])
self.comps_wrapper = CompsWrapper(self)
def add_repo(
self, repoid, baseurl=None, enablegroups=True, lookaside=False, **kwargs
):
self.repos.add_new_repo(
repoid,
self.conf,
baseurl=[baseurl],
enabledgroups=enablegroups,
priority=10 if lookaside else 20,
module_hotfixes=True,
**kwargs
)
class CompsWrapper(object):
def __init__(self, dnf_obj):
self.dnf = dnf_obj
def __getitem__(self, name):
return self.groups[name]
@property
def comps(self):
return self.dnf.comps
@property
def groups(self):
result = {}
for i in self.comps.groups:
result[i.id] = i
return result
def get_packages_from_group(
self,
group_id,
include_default=True,
include_optional=True,
include_conditional=True,
):
packages = []
conditional = []
group = self.groups[group_id]
# add mandatory packages
packages.extend([i.name for i in group.mandatory_packages])
# add default packages
if include_default:
packages.extend([i.name for i in group.default_packages])
# add optional packages
if include_optional:
packages.extend([i.name for i in group.optional_packages])
for package in group.conditional_packages:
conditional.append({"name": package.requires, "install": package.name})
return packages, conditional
def get_comps_packages(self, groups, exclude_groups):
packages = set()
conditional = []
if isinstance(groups, list):
groups = dict([(i, 1) for i in groups])
for group_id, group_include in sorted(groups.items()):
if group_id in exclude_groups:
continue
include_default = group_include in (1, 2)
include_optional = group_include in (2,)
include_conditional = True
pkgs, cond = self.get_packages_from_group(
group_id, include_default, include_optional, include_conditional
)
packages.update(pkgs)
for i in cond:
if i not in conditional:
conditional.append(i)
return list(packages), conditional
def get_langpacks(self):
result = []
for name, install in self.comps._i.langpacks.items():
result.append({"name": name, "install": install})
return result
class ArchWrapper(object):
def __init__(self, arch):
self.base_arch = dnf_arch.basearch(arch)
self.all_arches = pungi.arch.get_valid_arches(
self.base_arch, multilib=True, add_noarch=True
)
self.native_arches = pungi.arch.get_valid_arches(
self.base_arch, multilib=False, add_noarch=True
)
self.multilib_arches = pungi.arch.get_valid_multilib_arches(self.base_arch)
self.source_arches = ["src", "nosrc"]

20
pungi/errors.py Normal file
View File

@ -0,0 +1,20 @@
# -*- coding: utf-8 -*-
# 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; version 2 of the License.
#
# 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 Library General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, see <https://gnu.org/licenses/>.
class UnsignedPackagesError(RuntimeError):
"""Raised when package set fails to find a properly signed copy of an
RPM."""
pass

2297
pungi/gather.py Normal file

File diff suppressed because it is too large Load Diff

1099
pungi/gather_dnf.py Normal file

File diff suppressed because it is too large Load Diff

105
pungi/graph.py Executable file
View File

@ -0,0 +1,105 @@
# -*- coding: utf-8 -*-
class SimpleAcyclicOrientedGraph(object):
"""
Stores a graph data structure and allows operation with it.
Example data: {'P1': ['P2'], 'P3': ['P4', 'P5'], 'P2': 'P3'}
Graph is constructed by adding oriented edges one by one. It can not contain cycles.
Main result is spanning line, it determines ordering of the nodes.
"""
def __init__(self):
self._graph = {}
self._all_nodes = set()
def add_edge(self, start, end):
"""
Add one edge from node 'start' to node 'end'.
This operation must not create a cycle in the graph.
"""
if start == end:
raise ValueError(
"Can not add this kind of edge into graph: %s-%s" % (start, end)
)
self._graph.setdefault(start, [])
if end not in self._graph[start]:
self._graph[start].append(end)
self._all_nodes.add(start)
self._all_nodes.add(end)
# try to find opposite direction path (from end to start)
# to detect newly created cycle
path = SimpleAcyclicOrientedGraph.find_path(self._graph, end, start)
if path:
raise ValueError("There is a cycle in the graph: %s" % path)
def get_active_nodes(self):
"""
nodes connected to any edge
"""
active_nodes = set()
for start, ends in self._graph.items():
active_nodes.add(start)
active_nodes.update(ends)
return active_nodes
def is_final_endpoint(self, node):
"""
edge(s) ends in this node; no other edge starts in this node
"""
if node not in self._all_nodes:
return ValueError("This node is not found in the graph: %s" % node)
if node not in self.get_active_nodes():
return False
return False if node in self._graph else True
def remove_final_endpoint(self, node):
""""""
remove_start_points = []
for start, ends in self._graph.items():
if node in ends:
ends.remove(node)
if not ends:
remove_start_points.append(start)
for start in remove_start_points:
del self._graph[start]
@staticmethod
def find_path(graph, start, end, path=[]):
"""
find path among nodes 'start' and 'end' recursively
"""
path = path + [start]
if start == end:
return path
if start not in graph:
return None
for node in graph[start]:
if node not in path:
newpath = SimpleAcyclicOrientedGraph.find_path(graph, node, end, path)
if newpath:
return newpath
return None
def prune_graph(self):
"""
Construct spanning_line by pruning the graph.
Looking for endpoints and remove them one by one until graph is empty.
"""
spanning_line = []
while self._graph:
for node in sorted(self._all_nodes):
if self.is_final_endpoint(node):
self.remove_final_endpoint(node)
spanning_line.insert(0, node)
# orphan node = no edge is connected with this node
orphans = self._all_nodes - self.get_active_nodes()
if orphans:
# restart iteration not to set size self._all_nodes
# during iteration
break
for orphan in orphans:
if orphan not in spanning_line:
spanning_line.insert(0, orphan)
self._all_nodes.remove(orphan)
return spanning_line

223
pungi/ks.py Normal file
View File

@ -0,0 +1,223 @@
# -*- coding: utf-8 -*-
# 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; version 2 of the License.
#
# 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 Library General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, see <https://gnu.org/licenses/>.
"""
Pungi adds several new sections to kickstarts.
FULLTREE EXCLUDES
-----------------
Fulltree excludes allow us to define SRPM names
we don't want to be part of fulltree processing.
Syntax:
%fulltree-excludes
<srpm_name>
<srpm_name>
...
%end
MULTILIB BLACKLIST
------------------
List of RPMs which are prevented from becoming multilib.
Syntax:
%multilib-blacklist
<rpm_name>
<rpm_name>
...
%end
MULTILIB WHITELIST
------------------
List of RPMs which will become multilib (but only if native package is pulled in).
Syntax:
%multilib-whitelist
<rpm_name>
<rpm_name>
...
%end
PREPOPULATE
-----------
To make sure no package is left behind between 2 composes,
we can explicitly add <name>.<arch> records to the %prepopulate section.
These will be added to the input list and marked with 'prepopulate' flag.
Syntax:
%prepopulate
<rpm_name>.<rpm_arch>
<rpm_name>.<rpm_arch>
...
%end
"""
import pykickstart.parser
import pykickstart.sections
from pykickstart.constants import GROUP_REQUIRED, GROUP_DEFAULT
class FulltreeExcludesSection(pykickstart.sections.Section):
sectionOpen = "%fulltree-excludes"
def handleLine(self, line):
if not self.handler:
return
(h, s, t) = line.partition("#")
line = h.rstrip()
self.handler.fulltree_excludes.add(line)
class MultilibBlacklistSection(pykickstart.sections.Section):
sectionOpen = "%multilib-blacklist"
def handleLine(self, line):
if not self.handler:
return
(h, s, t) = line.partition("#")
line = h.rstrip()
self.handler.multilib_blacklist.add(line)
class MultilibWhitelistSection(pykickstart.sections.Section):
sectionOpen = "%multilib-whitelist"
def handleLine(self, line):
if not self.handler:
return
(h, s, t) = line.partition("#")
line = h.rstrip()
self.handler.multilib_whitelist.add(line)
class PrepopulateSection(pykickstart.sections.Section):
sectionOpen = "%prepopulate"
def handleLine(self, line):
if not self.handler:
return
(h, s, t) = line.partition("#")
line = h.rstrip()
self.handler.prepopulate.add(line)
class KickstartParser(pykickstart.parser.KickstartParser):
def setupSections(self):
pykickstart.parser.KickstartParser.setupSections(self)
self.registerSection(FulltreeExcludesSection(self.handler))
self.registerSection(MultilibBlacklistSection(self.handler))
self.registerSection(MultilibWhitelistSection(self.handler))
self.registerSection(PrepopulateSection(self.handler))
def get_packages(self, dnf_obj):
packages = set()
conditional_packages = []
packages.update(self.handler.packages.packageList)
for ks_group in self.handler.packages.groupList:
group_id = ks_group.name
if ks_group.include == GROUP_REQUIRED:
include_default = False
include_optional = False
elif ks_group.include == GROUP_DEFAULT:
include_default = True
include_optional = False
else:
include_default = True
include_optional = True
(
group_packages,
group_conditional_packages,
) = dnf_obj.comps_wrapper.get_packages_from_group(
group_id,
include_default=include_default,
include_optional=include_optional,
include_conditional=True,
)
packages.update(group_packages)
for i in group_conditional_packages:
if i not in conditional_packages:
conditional_packages.append(i)
return packages, conditional_packages
def get_excluded_packages(self, dnf_obj):
excluded = set()
excluded.update(self.handler.packages.excludedList)
for ks_group in self.handler.packages.excludedGroupList:
group_id = ks_group.name
include_default = False
include_optional = False
if ks_group.include == 1:
include_default = True
if ks_group.include == 2:
include_default = True
include_optional = True
(
group_packages,
group_conditional_packages,
) = dnf_obj.comps_wrapper.get_packages_from_group(
group_id,
include_default=include_default,
include_optional=include_optional,
include_conditional=False,
)
excluded.update(group_packages)
return excluded
HandlerClass = pykickstart.version.returnClassForVersion()
class PungiHandler(HandlerClass):
def __init__(self, *args, **kwargs):
HandlerClass.__init__(self, *args, **kwargs)
self.fulltree_excludes = set()
self.multilib_blacklist = set()
self.multilib_whitelist = set()
self.prepopulate = set()
def get_ksparser(ks_path=None):
"""
Return a kickstart parser instance.
Read kickstart if ks_path provided.
"""
ksparser = KickstartParser(PungiHandler())
if ks_path:
ksparser.readKickstart(ks_path)
return ksparser

247
pungi/linker.py Normal file
View File

@ -0,0 +1,247 @@
# -*- coding: utf-8 -*-
# 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; version 2 of the License.
#
# 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 Library General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, see <https://gnu.org/licenses/>.
import contextlib
import errno
import os
import shutil
import kobo.log
from kobo.shortcuts import relative_path
from kobo.threads import WorkerThread, ThreadPool
from pungi.util import makedirs
class LinkerPool(ThreadPool):
def __init__(self, link_type="hardlink-or-copy", logger=None):
ThreadPool.__init__(self, logger)
self.link_type = link_type
self.linker = Linker()
@classmethod
def with_workers(cls, num_workers, *args, **kwargs):
pool = cls(*args, **kwargs)
for _ in range(num_workers):
pool.add(LinkerThread(pool))
return pool
@contextlib.contextmanager
def linker_pool(link_type="hardlink-or-copy", num_workers=10):
"""Create a linker and make sure it is stopped no matter what."""
linker = LinkerPool.with_workers(num_workers=num_workers, link_type=link_type)
linker.start()
try:
yield linker
finally:
linker.stop()
class LinkerThread(WorkerThread):
def process(self, item, num):
src, dst = item
if (num % 100 == 0) or (num == self.pool.queue_total):
self.pool.log_debug(
"Linked %s out of %s packages" % (num, self.pool.queue_total)
)
directory = os.path.dirname(dst)
makedirs(directory)
self.pool.linker.link(src, dst, link_type=self.pool.link_type)
class Linker(kobo.log.LoggingBase):
def __init__(self, always_copy=None, test=False, logger=None):
kobo.log.LoggingBase.__init__(self, logger=logger)
self.always_copy = always_copy or []
self.test = test
self._inode_map = {}
def _is_same_type(self, path1, path2):
if not os.path.islink(path1) == os.path.islink(path2):
return False
if not os.path.isdir(path1) == os.path.isdir(path2):
return False
if not os.path.isfile(path1) == os.path.isfile(path2):
return False
return True
def _is_same(self, path1, path2):
if path1 == path2:
return True
if os.path.islink(path2) and not os.path.exists(path2):
# Broken symlink
return True
if os.path.getsize(path1) != os.path.getsize(path2):
return False
if int(os.path.getmtime(path1)) != int(os.path.getmtime(path2)):
return False
return True
def symlink(self, src, dst, relative=True):
if src == dst:
return
# Always hardlink or copy scratch builds
if "/work/tasks/" in src:
self._link_file(src, dst, "hardlink-or-copy")
old_src = src
if relative:
src = relative_path(src, dst)
msg = "Symlinking %s -> %s" % (dst, src)
if self.test:
self.log_info("TEST: %s" % msg)
return
self.log_info(msg)
try:
os.symlink(src, dst)
except OSError as ex:
if ex.errno != errno.EEXIST:
raise
if os.path.islink(dst) and self._is_same(old_src, dst):
if os.readlink(dst) != src:
raise
self.log_debug(
"The same file already exists, skipping symlink %s -> %s"
% (dst, src)
)
else:
raise
def hardlink(self, src, dst):
if src == dst:
return
msg = "Hardlinking %s to %s" % (src, dst)
if self.test:
self.log_info("TEST: %s" % msg)
return
self.log_info(msg)
try:
os.link(src, dst)
except OSError as ex:
if ex.errno != errno.EEXIST:
raise
if self._is_same(src, dst):
if not self._is_same_type(src, dst):
self.log_error(
"File %s already exists but has different type than %s"
% (dst, src)
)
raise
self.log_debug(
"The same file already exists, skipping hardlink %s to %s"
% (src, dst)
)
else:
raise
def copy(self, src, dst):
if src == dst:
return True
if os.path.islink(src):
msg = "Copying symlink %s to %s" % (src, dst)
else:
msg = "Copying file %s to %s" % (src, dst)
if self.test:
self.log_info("TEST: %s" % msg)
return
self.log_info(msg)
if os.path.exists(dst):
if self._is_same(src, dst):
if not self._is_same_type(src, dst):
self.log_error(
"File %s already exists but has different type than %s"
% (dst, src)
)
raise OSError(errno.EEXIST, "File exists")
self.log_debug(
"The same file already exists, skipping copy %s to %s" % (src, dst)
)
return
else:
raise OSError(errno.EEXIST, "File exists")
if os.path.islink(src):
if not os.path.islink(dst):
os.symlink(os.readlink(src), dst)
return
return
src_stat = os.stat(src)
src_key = (src_stat.st_dev, src_stat.st_ino)
if src_key in self._inode_map:
# (st_dev, st_ino) found in the mapping
self.log_debug(
"Harlink detected, hardlinking in destination %s to %s"
% (self._inode_map[src_key], dst)
)
os.link(self._inode_map[src_key], dst)
return
# BEWARE: shutil.copy2 automatically *rewrites* existing files
shutil.copy2(src, dst)
self._inode_map[src_key] = dst
def _link_file(self, src, dst, link_type):
if link_type == "hardlink":
self.hardlink(src, dst)
elif link_type == "copy":
self.copy(src, dst)
elif link_type in ("symlink", "abspath-symlink"):
if os.path.islink(src):
self.copy(src, dst)
else:
relative = link_type != "abspath-symlink"
self.symlink(src, dst, relative)
elif link_type == "hardlink-or-copy":
try:
self.hardlink(src, dst)
except OSError as ex:
if ex.errno == errno.EXDEV:
self.copy(src, dst)
else:
raise
else:
raise ValueError("Unknown link_type: %s" % link_type)
def link(self, src, dst, link_type="hardlink-or-copy"):
"""Link directories recursively."""
if os.path.isfile(src) or os.path.islink(src):
self._link_file(src, dst, link_type)
return
if os.path.isfile(dst):
raise OSError(errno.EEXIST, "File exists")
if not self.test:
if not os.path.exists(dst):
makedirs(dst)
shutil.copystat(src, dst)
for i in os.listdir(src):
src_path = os.path.join(src, i)
dst_path = os.path.join(dst, i)
self.link(src_path, dst_path, link_type)

127
pungi/media_split.py Normal file
View File

@ -0,0 +1,127 @@
# -*- coding: utf-8 -*-
# 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; version 2 of the License.
#
# 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 Library General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, see <https://gnu.org/licenses/>.
import os
SIZE_UNITS = {
"b": 1,
"k": 1024,
"M": 1024**2,
"G": 1024**3,
}
def convert_media_size(size):
if isinstance(size, str):
if size[-1] in SIZE_UNITS:
num = int(size[:-1])
units = size[-1]
else:
num = int(size)
units = "b"
result = num * SIZE_UNITS[units]
else:
result = int(size)
if result <= 0:
raise ValueError("Media size must be a positive number: %s" % size)
return result
def convert_file_size(size, block_size=2048):
"""round file size to block"""
blocks = int(size / block_size)
if size % block_size:
blocks += 1
return blocks * block_size
class MediaSplitter(object):
"""
MediaSplitter splits files so that they fit on a media of given size.
Each file added to the spliter has a size in bytes that will be rounded to
the nearest multiple of block size. If the file is sticky, it will be
included on each disk. The files will be on disks in the same order they
are added; there is no re-ordering. The number of disk is thus not the
possible minimum.
"""
def __init__(self, media_size, compose=None, logger=None):
self.media_size = media_size
self.files = [] # to preserve order
self.file_sizes = {}
self.sticky_files = set()
self.compose = compose
self.logger = logger
if not self.logger and self.compose:
self.logger = self.compose._logger
def add_file(self, name, size, sticky=False):
name = os.path.normpath(name)
size = int(size)
old_size = self.file_sizes.get(name, None)
if old_size is not None and old_size != size:
raise ValueError(
"File size mismatch; file: %s; sizes: %s vs %s" % (name, old_size, size)
)
if self.media_size and size > self.media_size:
raise ValueError("File is larger than media size: %s" % name)
self.files.append(name)
self.file_sizes[name] = size
if sticky:
self.sticky_files.add(name)
@property
def total_size(self):
return sum(self.file_sizes.values())
@property
def total_size_in_blocks(self):
return sum([convert_file_size(i) for i in list(self.file_sizes.values())])
def split(self, first_disk=0, all_disks=0):
all_files = []
sticky_files = []
sticky_files_size = 0
for name in self.files:
if name in self.sticky_files:
sticky_files.append(name)
sticky_files_size += convert_file_size(self.file_sizes[name])
else:
all_files.append(name)
disks = []
disk = {}
# as it would be on single medium (sticky_files just once)
total_size_single = sticky_files_size
while all_files:
name = all_files.pop(0)
size = convert_file_size(self.file_sizes[name])
if not disks or (self.media_size and disk["size"] + size > self.media_size):
disk = {"size": sticky_files_size, "files": sticky_files[:]}
disks.append(disk)
disk["files"].append(name)
disk["size"] += size
total_size_single += size
return disks

537
pungi/metadata.py Normal file
View File

@ -0,0 +1,537 @@
# -*- coding: utf-8 -*-
# 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; version 2 of the License.
#
# 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 Library General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, see <https://gnu.org/licenses/>.
import copy
import os
import time
import productmd.composeinfo
import productmd.treeinfo
from productmd.common import get_major_version
from kobo.shortcuts import relative_path, compute_file_checksums
from pungi.compose_metadata.discinfo import write_discinfo as create_discinfo
from pungi.compose_metadata.discinfo import write_media_repo as create_media_repo
def get_description(compose, variant, arch):
if "release_discinfo_description" in compose.conf:
result = compose.conf["release_discinfo_description"]
elif variant.type == "layered-product":
# we need to make sure the layered product behaves as it was composed separately
result = "%s %s for %s %s" % (
variant.release_name,
variant.release_version,
compose.conf["release_name"],
get_major_version(compose.conf["release_version"]),
)
else:
result = "%s %s" % (
compose.conf["release_name"],
compose.conf["release_version"],
)
if compose.conf.get("base_product_name", ""):
result += " for %s %s" % (
compose.conf["base_product_name"],
compose.conf["base_product_version"],
)
result = result % {"variant_name": variant.name, "arch": arch}
return result
def write_discinfo(compose, arch, variant):
if variant.type == "addon":
return
os_tree = compose.paths.compose.os_tree(arch, variant)
path = os.path.join(os_tree, ".discinfo")
# description = get_volid(compose, arch, variant)
description = get_description(compose, variant, arch)
return create_discinfo(path, description, arch)
def write_media_repo(compose, arch, variant, timestamp=None):
if variant.type == "addon":
return
os_tree = compose.paths.compose.os_tree(arch, variant)
path = os.path.join(os_tree, "media.repo")
# description = get_volid(compose, arch, variant)
description = get_description(compose, variant, arch)
return create_media_repo(path, description, timestamp)
def compose_to_composeinfo(compose):
ci = productmd.composeinfo.ComposeInfo()
# compose
ci.compose.id = compose.compose_id
ci.compose.type = compose.compose_type
ci.compose.date = compose.compose_date
ci.compose.respin = compose.compose_respin
ci.compose.label = compose.compose_label
ci.compose.final = compose.supported
# product
ci.release.name = compose.conf["release_name"]
ci.release.version = compose.conf["release_version"]
ci.release.short = compose.conf["release_short"]
ci.release.is_layered = True if compose.conf.get("base_product_name", "") else False
ci.release.type = compose.conf["release_type"].lower()
ci.release.internal = bool(compose.conf["release_internal"])
# base product
if ci.release.is_layered:
ci.base_product.name = compose.conf["base_product_name"]
ci.base_product.version = compose.conf["base_product_version"]
ci.base_product.short = compose.conf["base_product_short"]
ci.base_product.type = compose.conf["base_product_type"].lower()
def dump_variant(variant, parent=None):
var = productmd.composeinfo.Variant(ci)
tree_arches = compose.conf.get("tree_arches")
if tree_arches and not (set(variant.arches) & set(tree_arches)):
return None
# variant details
# remove dashes from variant ID, rely on productmd verification
var.id = variant.id.replace("-", "")
var.uid = variant.uid
var.name = variant.name
var.type = variant.type
var.arches = set(variant.arches)
if var.type == "layered-product":
var.release.name = variant.release_name
var.release.short = variant.release_short
var.release.version = variant.release_version
var.release.is_layered = True
var.release.type = ci.release.type
for arch in variant.arches:
# paths: binaries
var.paths.os_tree[arch] = relative_path(
compose.paths.compose.os_tree(
arch=arch, variant=variant, create_dir=False
).rstrip("/")
+ "/",
compose.paths.compose.topdir().rstrip("/") + "/",
).rstrip("/")
var.paths.repository[arch] = relative_path(
compose.paths.compose.repository(
arch=arch, variant=variant, create_dir=False
).rstrip("/")
+ "/",
compose.paths.compose.topdir().rstrip("/") + "/",
).rstrip("/")
var.paths.packages[arch] = relative_path(
compose.paths.compose.packages(
arch=arch, variant=variant, create_dir=False
).rstrip("/")
+ "/",
compose.paths.compose.topdir().rstrip("/") + "/",
).rstrip("/")
iso_dir = (
compose.paths.compose.iso_dir(
arch=arch, variant=variant, create_dir=False
)
or ""
)
if iso_dir and os.path.isdir(
os.path.join(compose.paths.compose.topdir(), iso_dir)
):
var.paths.isos[arch] = relative_path(
iso_dir, compose.paths.compose.topdir().rstrip("/") + "/"
).rstrip("/")
image_dir = compose.paths.compose.image_dir(variant=variant) or ""
if image_dir:
image_dir = image_dir % {"arch": arch}
if os.path.isdir(image_dir):
var.paths.images[arch] = relative_path(
image_dir, compose.paths.compose.topdir().rstrip("/") + "/"
).rstrip("/")
jigdo_dir = (
compose.paths.compose.jigdo_dir(
arch=arch, variant=variant, create_dir=False
)
or ""
)
if jigdo_dir and os.path.isdir(
os.path.join(compose.paths.compose.topdir(), jigdo_dir)
):
var.paths.jigdos[arch] = relative_path(
jigdo_dir, compose.paths.compose.topdir().rstrip("/") + "/"
).rstrip("/")
# paths: sources
var.paths.source_tree[arch] = relative_path(
compose.paths.compose.os_tree(
arch="source", variant=variant, create_dir=False
).rstrip("/")
+ "/",
compose.paths.compose.topdir().rstrip("/") + "/",
).rstrip("/")
var.paths.source_repository[arch] = relative_path(
compose.paths.compose.repository(
arch="source", variant=variant, create_dir=False
).rstrip("/")
+ "/",
compose.paths.compose.topdir().rstrip("/") + "/",
).rstrip("/")
var.paths.source_packages[arch] = relative_path(
compose.paths.compose.packages(
arch="source", variant=variant, create_dir=False
).rstrip("/")
+ "/",
compose.paths.compose.topdir().rstrip("/") + "/",
).rstrip("/")
source_iso_dir = (
compose.paths.compose.iso_dir(
arch="source", variant=variant, create_dir=False
)
or ""
)
if source_iso_dir and os.path.isdir(
os.path.join(compose.paths.compose.topdir(), source_iso_dir)
):
var.paths.source_isos[arch] = relative_path(
source_iso_dir, compose.paths.compose.topdir().rstrip("/") + "/"
).rstrip("/")
source_jigdo_dir = (
compose.paths.compose.jigdo_dir(
arch="source", variant=variant, create_dir=False
)
or ""
)
if source_jigdo_dir and os.path.isdir(
os.path.join(compose.paths.compose.topdir(), source_jigdo_dir)
):
var.paths.source_jigdos[arch] = relative_path(
source_jigdo_dir, compose.paths.compose.topdir().rstrip("/") + "/"
).rstrip("/")
# paths: debug
var.paths.debug_tree[arch] = relative_path(
compose.paths.compose.debug_tree(
arch=arch, variant=variant, create_dir=False
).rstrip("/")
+ "/",
compose.paths.compose.topdir().rstrip("/") + "/",
).rstrip("/")
var.paths.debug_repository[arch] = relative_path(
compose.paths.compose.debug_repository(
arch=arch, variant=variant, create_dir=False
).rstrip("/")
+ "/",
compose.paths.compose.topdir().rstrip("/") + "/",
).rstrip("/")
var.paths.debug_packages[arch] = relative_path(
compose.paths.compose.debug_packages(
arch=arch, variant=variant, create_dir=False
).rstrip("/")
+ "/",
compose.paths.compose.topdir().rstrip("/") + "/",
).rstrip("/")
"""
# XXX: not supported (yet?)
debug_iso_dir = (
compose.paths.compose.debug_iso_dir(arch=arch, variant=variant) or ""
)
if debug_iso_dir:
var.debug_iso_dir[arch] = relative_path(
debug_iso_dir, compose.paths.compose.topdir().rstrip("/") + "/"
).rstrip("/")
debug_jigdo_dir = (
compose.paths.compose.debug_jigdo_dir(arch=arch, variant=variant) or ""
)
if debug_jigdo_dir:
var.debug_jigdo_dir[arch] = relative_path(
debug_jigdo_dir, compose.paths.compose.topdir().rstrip("/") + "/"
).rstrip("/")
"""
for v in variant.get_variants(recursive=False):
x = dump_variant(v, parent=variant)
if x is not None:
var.add(x)
return var
for variant_id in sorted(compose.variants):
variant = compose.variants[variant_id]
v = dump_variant(variant)
if v is not None:
ci.variants.add(v)
return ci
def write_compose_info(compose):
ci = compose_to_composeinfo(compose)
msg = "Writing composeinfo"
compose.log_info("[BEGIN] %s" % msg)
path = compose.paths.compose.metadata("composeinfo.json")
# make a copy of composeinfo and modify the copy
# if any path in variant paths doesn't exist or just an empty
# dir, set it to None, then it won't be dumped.
ci_copy = copy.deepcopy(ci)
for variant in ci_copy.variants.variants.values():
for field in variant.paths._fields:
field_paths = getattr(variant.paths, field)
for arch, dirpath in field_paths.items():
dirpath = os.path.join(compose.paths.compose.topdir(), dirpath)
if not os.path.isdir(dirpath):
# If the directory does not exist, do not include the path
# in metadata.
field_paths[arch] = None
ci_copy.dump(path)
compose.log_info("[DONE ] %s" % msg)
def write_tree_info(compose, arch, variant, timestamp=None, bi=None):
if variant.type in ("addon",) or variant.is_empty:
return
if not timestamp:
timestamp = int(time.time())
else:
timestamp = int(timestamp)
os_tree = (
compose.paths.compose.os_tree(arch=arch, variant=variant).rstrip("/") + "/"
)
ti = productmd.treeinfo.TreeInfo()
# load from buildinstall .treeinfo
if variant.type == "layered-product":
# we need to make sure the layered product behaves as it was composed separately
# release
# TODO: read from variants.xml
ti.release.name = variant.release_name
ti.release.version = variant.release_version
ti.release.short = variant.release_short
ti.release.is_layered = True
ti.release.type = compose.conf["release_type"].lower()
# base product
ti.base_product.name = compose.conf["release_name"]
if "." in compose.conf["release_version"]:
# remove minor version if present
ti.base_product.version = get_major_version(compose.conf["release_version"])
else:
ti.base_product.version = compose.conf["release_version"]
ti.base_product.short = compose.conf["release_short"]
else:
# release
ti.release.name = compose.conf["release_name"]
ti.release.version = compose.conf.get(
"treeinfo_version", compose.conf["release_version"]
)
ti.release.short = compose.conf["release_short"]
ti.release.is_layered = (
True if compose.conf.get("base_product_name", "") else False
)
ti.release.type = compose.conf["release_type"].lower()
# base product
if ti.release.is_layered:
ti.base_product.name = compose.conf["base_product_name"]
ti.base_product.version = compose.conf["base_product_version"]
ti.base_product.short = compose.conf["base_product_short"]
# tree
ti.tree.arch = arch
ti.tree.build_timestamp = timestamp
# ti.platforms
# main variant
var = productmd.treeinfo.Variant(ti)
if variant.type == "layered-product":
var.id = variant.parent.id
var.uid = variant.parent.uid
var.name = variant.parent.name
var.type = "variant"
else:
# remove dashes from variant ID, rely on productmd verification
var.id = variant.id.replace("-", "")
var.uid = variant.uid
var.name = variant.name
var.type = variant.type
var.paths.packages = (
relative_path(
compose.paths.compose.packages(
arch=arch, variant=variant, create_dir=False
).rstrip("/")
+ "/",
os_tree,
).rstrip("/")
or "."
)
var.paths.repository = (
relative_path(
compose.paths.compose.repository(
arch=arch, variant=variant, create_dir=False
).rstrip("/")
+ "/",
os_tree,
).rstrip("/")
or "."
)
ti.variants.add(var)
repomd_path = os.path.join(var.paths.repository, "repodata", "repomd.xml")
createrepo_checksum = compose.conf["createrepo_checksum"]
if os.path.isfile(repomd_path):
ti.checksums.add(repomd_path, createrepo_checksum, root_dir=os_tree)
for i in variant.get_variants(types=["addon"], arch=arch):
addon = productmd.treeinfo.Variant(ti)
addon.id = i.id
addon.uid = i.uid
addon.name = i.name
addon.type = i.type
compose.log_debug(
"variant '%s' inserting addon uid '%s' type '%s'"
% (variant, addon.uid, addon.type)
)
os_tree = compose.paths.compose.os_tree(arch=arch, variant=i).rstrip("/") + "/"
addon.paths.packages = (
relative_path(
compose.paths.compose.packages(
arch=arch, variant=i, create_dir=False
).rstrip("/")
+ "/",
os_tree,
).rstrip("/")
or "."
)
addon.paths.repository = (
relative_path(
compose.paths.compose.repository(
arch=arch, variant=i, create_dir=False
).rstrip("/")
+ "/",
os_tree,
).rstrip("/")
or "."
)
var.add(addon)
repomd_path = os.path.join(addon.paths.repository, "repodata", "repomd.xml")
if os.path.isfile(repomd_path):
ti.checksums.add(repomd_path, createrepo_checksum, root_dir=os_tree)
class LoraxProduct(productmd.treeinfo.Release):
def _validate_short(self):
# HACK: set self.short so .treeinfo produced by lorax can be read
if not self.short:
self.short = compose.conf["release_short"]
class LoraxTreeInfo(productmd.treeinfo.TreeInfo):
def __init__(self, *args, **kwargs):
super(LoraxTreeInfo, self).__init__(*args, **kwargs)
self.release = LoraxProduct(self)
# images
if variant.type == "variant" and bi.succeeded(variant, arch):
os_tree = compose.paths.compose.os_tree(arch, variant)
# clone all but 'general' sections from buildinstall .treeinfo
bi_dir = compose.paths.work.buildinstall_dir(arch)
if compose.conf.get("buildinstall_method") == "lorax":
# The .treeinfo file produced by lorax is nested in variant
# subdirectory. Legacy buildinstall runs once per arch, so there is
# only one file.
bi_dir = os.path.join(bi_dir, variant.uid)
bi_treeinfo = os.path.join(bi_dir, ".treeinfo")
if os.path.exists(bi_treeinfo):
bi_ti = LoraxTreeInfo()
bi_ti.load(bi_treeinfo)
# stage2 - mainimage
if bi_ti.stage2.mainimage:
ti.stage2.mainimage = bi_ti.stage2.mainimage
ti.checksums.add(
ti.stage2.mainimage, createrepo_checksum, root_dir=os_tree
)
# stage2 - instimage
if bi_ti.stage2.instimage:
ti.stage2.instimage = bi_ti.stage2.instimage
ti.checksums.add(
ti.stage2.instimage, createrepo_checksum, root_dir=os_tree
)
# images
for platform in bi_ti.images.images:
ti.images.images[platform] = {}
ti.tree.platforms.add(platform)
for image, path in bi_ti.images.images[platform].items():
if not path:
# The .treeinfo file contains an image without a path.
# We can't add that.
continue
ti.images.images[platform][image] = path
ti.checksums.add(path, createrepo_checksum, root_dir=os_tree)
path = os.path.join(
compose.paths.compose.os_tree(arch=arch, variant=variant), ".treeinfo"
)
compose.log_info("Writing treeinfo: %s" % path)
ti.dump(path)
def populate_extra_files_metadata(
metadata, variant, arch, topdir, files, checksum_types, relative_root=None
):
"""
:param metadata: an instance of productmd.extra_files.ExtraFiles to
populate with the current files
:param Variant variant: under which variant should the files be listed
:param str arch: under which arch should the files be listed
:param topdir: directory where files are located
:param files: list of file paths relative to topdir
:param checksum_types: list of checksums to compute
:param relative_root: ancestor directory of topdir, this will be removed
from paths written to local metadata file
"""
for copied_file in files:
full_path = os.path.join(topdir, copied_file)
size = os.path.getsize(full_path)
try:
checksums = compute_file_checksums(full_path, checksum_types)
except IOError as exc:
raise RuntimeError(
"Failed to calculate checksum for %s: %s" % (full_path, exc)
)
if relative_root:
copied_file = os.path.relpath(full_path, relative_root)
metadata.add(variant.uid, arch, copied_file, size, checksums)
strip_prefix = (
(os.path.relpath(topdir, relative_root) + "/") if relative_root else ""
)
with open(os.path.join(topdir, "extra_files.json"), "w") as f:
metadata.dump_for_tree(f, variant.uid, arch, strip_prefix)

118
pungi/module_util.py Normal file
View File

@ -0,0 +1,118 @@
# -*- coding: utf-8 -*-
# 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; version 2 of the License.
#
# 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 Library General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, see <https://gnu.org/licenses/>.
import glob
import os
try:
import gi
gi.require_version("Modulemd", "2.0") # noqa
from gi.repository import Modulemd
except (ImportError, ValueError):
Modulemd = None
def iter_module_defaults(path):
"""Given a path to a directory with yaml files, yield each module default
in there as a pair (module_name, ModuleDefaults instance).
"""
# It is really tempting to merge all the module indexes into a single one
# and work with it. However that does not allow for detecting conflicting
# defaults. That should not happen in practice, but better safe than sorry.
# Once libmodulemd can report the error, this code can be simplifed by a
# lot. It was implemented in
# https://github.com/fedora-modularity/libmodulemd/commit/3087e4a5c38a331041fec9b6b8f1a372f9ffe64d
# and released in 2.6.0, but 2.8.0 added the need to merge overrides and
# that breaks this use case again.
for file in glob.glob(os.path.join(path, "*.yaml")):
index = Modulemd.ModuleIndex()
index.update_from_file(file, strict=False)
for module_name in index.get_module_names():
yield module_name, index.get_module(module_name).get_defaults()
def get_module_obsoletes_idx(path, mod_list):
"""Given a path to a directory with yaml files, return Index with
merged all obsoletes.
"""
merger = Modulemd.ModuleIndexMerger.new()
md_idxs = []
# associate_index does NOT copy it's argument (nor increases a
# reference counter on the object). It only stores a pointer.
for file in glob.glob(os.path.join(path, "*.yaml")):
index = Modulemd.ModuleIndex()
index.update_from_file(file, strict=False)
mod_name = index.get_module_names()[0]
if mod_name and (mod_name in mod_list or not mod_list):
md_idxs.append(index)
merger.associate_index(md_idxs[-1], 0)
merged_idx = merger.resolve()
return merged_idx
def collect_module_defaults(
defaults_dir, modules_to_load=None, mod_index=None, overrides_dir=None
):
"""Load module defaults into index.
If `modules_to_load` is passed in, it should be a set of module names. Only
defaults for these modules will be loaded.
If `mod_index` is passed in, it will be updated and returned. If it was
not, a new ModuleIndex will be created and returned
"""
mod_index = mod_index or Modulemd.ModuleIndex()
temp_index = Modulemd.ModuleIndex.new()
temp_index.update_from_defaults_directory(
defaults_dir, overrides_path=overrides_dir, strict=False
)
for module_name in temp_index.get_module_names():
defaults = temp_index.get_module(module_name).get_defaults()
if not modules_to_load or module_name in modules_to_load:
mod_index.add_defaults(defaults)
return mod_index
def collect_module_obsoletes(obsoletes_dir, modules_to_load, mod_index=None):
"""Load module obsoletes into index.
This works in a similar fashion as collect_module_defaults except it
merges indexes together instead of adding them during iteration.
Additionally if modules_to_load is not empty returned Index will include
only obsoletes for those modules.
"""
obsoletes_index = get_module_obsoletes_idx(obsoletes_dir, modules_to_load)
# Merge Obsoletes with Modules Index.
if mod_index:
merger = Modulemd.ModuleIndexMerger.new()
merger.associate_index(mod_index, 0)
merger.associate_index(obsoletes_index, 0)
merged_idx = merger.resolve()
obsoletes_index = merged_idx
return obsoletes_index

67
pungi/multilib_dnf.py Normal file
View File

@ -0,0 +1,67 @@
# -*- coding: utf-8 -*-
# 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; version 2 of the License.
#
# 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 Library General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, see <https://gnu.org/licenses/>.
from multilib import multilib
class Multilib(object):
"""This class decides whether a package should be multilib.
To use it, create an instance and call the ``is_multilib`` method on it.
The blacklist and whitelist in constructor should be sets of package names.
It may be more convenient to create the instance with the ``from_globs``
method that accepts a DNF sach and an iterable of globs that will be used
to find package names.
"""
def __init__(self, methods, blacklist, whitelist):
self.methods = {}
self.blacklist = blacklist
self.whitelist = whitelist
self.all_methods = {
"none": multilib.NoMultilibMethod(None),
"all": multilib.AllMultilibMethod(None),
"devel": multilib.DevelMultilibMethod(None),
"runtime": multilib.RuntimeMultilibMethod(None),
}
for method in methods:
self.methods[method] = self.all_methods[method]
@classmethod
def from_globs(cls, sack, methods, blacklist=None, whitelist=None):
"""Create a Multilib instance with expanded blacklist and whitelist."""
return cls(
methods,
_expand_list(sack, blacklist or []),
_expand_list(sack, whitelist or []),
)
def is_multilib(self, pkg):
if pkg.name in self.blacklist:
return False
if pkg.name in self.whitelist:
return "whitelist"
for method, cls in self.methods.items():
if cls.select(pkg):
return method
return False
def _expand_list(sack, patterns):
"""Find all package names that match any of the provided patterns."""
return set(pkg.name for pkg in sack.query().filter(name__glob=list(patterns)))

295
pungi/multilib_yum.py Executable file
View File

@ -0,0 +1,295 @@
# -*- coding: utf-8 -*-
# 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; version 2 of the License.
#
# 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 Library General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, see <https://gnu.org/licenses/>.
import re
import fnmatch
import pungi.pathmatch
import pungi.gather
import pungi.util
LINE_PATTERN_RE = re.compile(r"^\s*(?P<line>[^#]+)(:?\s+(?P<comment>#.*))?$")
RUNTIME_PATTERN_SPLIT_RE = re.compile(
r"^\s*(?P<path>[^\s]+)\s+(?P<pattern>[^\s]+)(:?\s+(?P<comment>#.*))?$"
)
SONAME_PATTERN_RE = re.compile(r"^(.+\.so\.[a-zA-Z0-9_\.]+).*$")
def read_lines(lines):
result = []
for i in lines:
i = i.strip()
if not i:
continue
# skip comments
if i.startswith("#"):
continue
match = LINE_PATTERN_RE.match(i)
if match is None:
raise ValueError("Couldn't parse line: %s" % i)
gd = match.groupdict()
result.append(gd["line"])
return result
def read_lines_from_file(path):
lines = open(path, "r").readlines()
lines = read_lines(lines)
return lines
def read_runtime_patterns(lines):
result = []
for i in read_lines(lines):
match = RUNTIME_PATTERN_SPLIT_RE.match(i)
if match is None:
raise ValueError("Couldn't parse pattern: %s" % i)
gd = match.groupdict()
result.append((gd["path"], gd["pattern"]))
return result
def read_runtime_patterns_from_file(path):
lines = open(path, "r").readlines()
return read_runtime_patterns(lines)
def expand_runtime_patterns(patterns):
pm = pungi.pathmatch.PathMatch()
for path, pattern in patterns:
for root in ("", "/opt/*/*/root"):
# include Software Collections: /opt/<vendor>/<scl_name>/root/...
if "$LIBDIR" in path:
for lib_dir in ("/lib", "/lib64", "/usr/lib", "/usr/lib64"):
path_pattern = path.replace("$LIBDIR", lib_dir)
path_pattern = "%s/%s" % (root, path_pattern.lstrip("/"))
pm[path_pattern] = (path_pattern, pattern)
else:
path_pattern = "%s/%s" % (root, path.lstrip("/"))
pm[path_pattern] = (path_pattern, pattern)
return pm
class MultilibMethodBase(object):
"""a base class for multilib methods"""
name = "base"
def __init__(self, config_path):
self.config_path = config_path
def select(self, po):
raise NotImplementedError
def skip(self, po):
if (
pungi.gather.is_noarch(po)
or pungi.gather.is_source(po)
or pungi.util.pkg_is_debug(po)
):
return True
return False
def is_kernel(self, po):
for p_name, p_flag, (p_e, p_v, p_r) in po.provides:
if p_name == "kernel":
return True
return False
def is_kernel_devel(self, po):
for p_name, p_flag, (p_e, p_v, p_r) in po.provides:
if p_name == "kernel-devel":
return True
return False
def is_kernel_or_kernel_devel(self, po):
for p_name, p_flag, (p_e, p_v, p_r) in po.provides:
if p_name in ("kernel", "kernel-devel"):
return True
return False
class NoneMultilibMethod(MultilibMethodBase):
"""multilib disabled"""
name = "none"
def select(self, po):
return False
class AllMultilibMethod(MultilibMethodBase):
"""all packages are multilib"""
name = "all"
def select(self, po):
if self.skip(po):
return False
return True
class RuntimeMultilibMethod(MultilibMethodBase):
"""pre-defined paths to libs"""
name = "runtime"
def __init__(self, *args, **kwargs):
super(RuntimeMultilibMethod, self).__init__(*args, **kwargs)
self.blacklist = read_lines_from_file(
self.config_path + "runtime-blacklist.conf"
)
self.whitelist = read_lines_from_file(
self.config_path + "runtime-whitelist.conf"
)
self.patterns = expand_runtime_patterns(
read_runtime_patterns_from_file(self.config_path + "runtime-patterns.conf")
)
def select(self, po):
if self.skip(po):
return False
if po.name in self.blacklist:
return False
if po.name in self.whitelist:
return True
if self.is_kernel(po):
return False
# gather all *.so.* provides from the RPM header
provides = set()
for i in po.provides:
match = SONAME_PATTERN_RE.match(i[0])
if match is not None:
provides.add(match.group(1))
for path in po.returnFileEntries() + po.returnFileEntries("ghost"):
dirname, filename = path.rsplit("/", 1)
dirname = dirname.rstrip("/")
patterns = self.patterns[dirname]
if not patterns:
continue
for dir_pattern, file_pattern in patterns:
if file_pattern == "-":
return True
if fnmatch.fnmatch(filename, file_pattern):
if ".so.*" in file_pattern:
if filename in provides:
# return only if the lib is provided in RPM header
# (some libs may be private, hence not exposed in Provides)
return True
else:
return True
return False
class KernelMultilibMethod(MultilibMethodBase):
"""kernel and kernel-devel"""
name = "kernel"
def __init__(self, *args, **kwargs):
super(KernelMultilibMethod, self).__init__(*args, **kwargs)
def select(self, po):
if self.is_kernel_or_kernel_devel(po):
return True
return False
class YabootMultilibMethod(MultilibMethodBase):
"""yaboot on ppc"""
name = "yaboot"
def __init__(self, *args, **kwargs):
super(YabootMultilibMethod, self).__init__(*args, **kwargs)
def select(self, po):
if po.arch in ["ppc"]:
if po.name.startswith("yaboot"):
return True
return False
class DevelMultilibMethod(MultilibMethodBase):
"""all -devel and -static packages"""
name = "devel"
def __init__(self, *args, **kwargs):
super(DevelMultilibMethod, self).__init__(*args, **kwargs)
self.blacklist = read_lines_from_file(self.config_path + "devel-blacklist.conf")
self.whitelist = read_lines_from_file(self.config_path + "devel-whitelist.conf")
def select(self, po):
if self.skip(po):
return False
if po.name in self.blacklist:
return False
if po.name in self.whitelist:
return True
if self.is_kernel_devel(po):
return False
# HACK: exclude ghc*
if po.name.startswith("ghc-"):
return False
if po.name.endswith("-devel"):
return True
if po.name.endswith("-static"):
return True
for p_name, p_flag, (p_e, p_v, p_r) in po.provides:
if p_name.endswith("-devel"):
return True
if p_name.endswith("-static"):
return True
return False
DEFAULT_METHODS = ["devel", "runtime"]
METHOD_MAP = {}
def init(config_path="/usr/share/pungi/multilib/"):
global METHOD_MAP
if not config_path.endswith("/"):
config_path += "/"
for cls in (
AllMultilibMethod,
DevelMultilibMethod,
KernelMultilibMethod,
NoneMultilibMethod,
RuntimeMultilibMethod,
YabootMultilibMethod,
):
method = cls(config_path)
METHOD_MAP[method.name] = method
def po_is_multilib(po, methods):
for method_name in methods:
if not method_name:
continue
method = METHOD_MAP[method_name]
if method.select(po):
return method_name
return None

112
pungi/notifier.py Normal file
View File

@ -0,0 +1,112 @@
# -*- coding: utf-8 -*-
# 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; version 2 of the License.
#
# 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 Library General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, see <https://gnu.org/licenses/>.
from datetime import datetime
import json
import os
import threading
import pungi.util
from kobo import shortcuts
class PungiNotifier(object):
"""Wrapper around an external script for sending messages.
If no script is configured, the messages are just silently ignored. If the
script fails, a warning will be logged, but the compose process will not be
interrupted.
"""
def __init__(self, cmds):
self.cmds = cmds
self.lock = threading.Lock()
self.compose = None
def _update_args(self, data):
"""Add compose related information to the data."""
if not self.compose:
return
data.setdefault("compose_id", self.compose.compose_id)
# Publish where in the world this compose will end up living
location = pungi.util.translate_path(
self.compose, self.compose.paths.compose.topdir()
)
data.setdefault("location", location)
# Add information about the compose itself.
data.setdefault("compose_date", self.compose.compose_date)
data.setdefault("compose_type", self.compose.compose_type)
data.setdefault("compose_respin", self.compose.compose_respin)
data.setdefault("compose_label", self.compose.compose_label)
data.setdefault("compose_path", self.compose.topdir)
data.setdefault("release_short", self.compose.conf["release_short"])
data.setdefault("release_name", self.compose.conf["release_name"])
data.setdefault("release_version", self.compose.conf["release_version"])
data.setdefault("release_type", self.compose.conf["release_type"].lower())
data.setdefault("release_is_layered", False)
if self.compose.conf.get("base_product_name", ""):
data["release_is_layered"] = True
data["base_product_name"] = self.compose.conf["base_product_name"]
data["base_product_version"] = self.compose.conf["base_product_version"]
data["base_product_short"] = self.compose.conf["base_product_short"]
data["base_product_type"] = self.compose.conf["base_product_type"].lower()
def send(self, msg, workdir=None, **kwargs):
"""Send a message.
The actual meaning of ``msg`` depends on what the notification script
will be doing. The keyword arguments will be JSON-encoded and passed on
to standard input of the notification process.
Unless you specify it manually, a ``compose_id`` key with appropriate
value will be automatically added.
"""
if not self.cmds:
return
self._update_args(kwargs)
with self.lock:
for cmd in self.cmds:
self._run_script(cmd, msg, workdir, kwargs)
def _run_script(self, cmd, msg, workdir, kwargs):
"""Run a single notification script with proper logging."""
logfile = None
if self.compose:
self.compose.log_debug("Notification: %r %r, %r" % (cmd, msg, kwargs))
logfile = os.path.join(
self.compose.paths.log.topdir(),
"notifications",
"notification-%s.log" % datetime.utcnow().strftime("%Y-%m-%d_%H-%M-%S"),
)
pungi.util.makedirs(os.path.dirname(logfile))
ret, _ = shortcuts.run(
(cmd, msg),
stdin_data=json.dumps(kwargs),
can_fail=True,
workdir=workdir,
return_stdout=False,
show_cmd=True,
universal_newlines=True,
logfile=logfile,
)
if ret != 0:
if self.compose:
self.compose.log_warning("Failed to invoke notification script.")

202
pungi/ostree/__init__.py Normal file
View File

@ -0,0 +1,202 @@
# -*- coding: utf-8 -*-
# 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; version 2 of the License.
#
# 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 Library General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, see <https://gnu.org/licenses/>.
import argparse
import logging
from .tree import Tree
from .installer import Installer
from .container import Container
def main(args=None):
parser = argparse.ArgumentParser()
subparser = parser.add_subparsers(help="Sub commands")
treep = subparser.add_parser("tree", help="Compose OSTree repository")
treep.set_defaults(_class=Tree, func="run")
treep.add_argument(
"--repo",
metavar="PATH",
required=True,
help="where to put the OSTree repo (required)",
)
treep.add_argument(
"--treefile",
metavar="FILE",
required=True,
help="treefile for rpm-ostree (required)",
)
treep.add_argument(
"--log-dir",
metavar="DIR",
required=True,
help="where to log output and commitid (required). \
Note: commitid file will be written to this dir",
)
treep.add_argument(
"--extra-config", metavar="FILE", help="JSON file contains extra configurations"
)
treep.add_argument(
"--version",
metavar="VERSION",
help="version string to be added as versioning metadata",
)
treep.add_argument(
"--update-summary", action="store_true", help="update summary metadata"
)
treep.add_argument(
"--ostree-ref", metavar="PATH", help="override ref value from treefile"
)
treep.add_argument(
"--force-new-commit",
action="store_true",
help="do not use rpm-ostree's built-in change detection",
)
treep.add_argument(
"--unified-core",
action="store_true",
help="use unified core mode in rpm-ostree",
)
container = subparser.add_parser(
"container", help="Compose OSTree native container"
)
container.set_defaults(_class=Container, func="run")
container.add_argument(
"--name",
required=True,
help="the name of the the OCI archive (required)",
)
container.add_argument(
"--path",
required=True,
help="where to output the OCI archive (required)",
)
container.add_argument(
"--treefile",
metavar="FILE",
required=True,
help="treefile for rpm-ostree (required)",
)
container.add_argument(
"--log-dir",
metavar="DIR",
required=True,
help="where to log output (required).",
)
container.add_argument(
"--extra-config", metavar="FILE", help="JSON file contains extra configurations"
)
container.add_argument(
"-v",
"--version",
metavar="VERSION",
required=True,
help="version identifier (required)",
)
installerp = subparser.add_parser(
"installer", help="Create an OSTree installer image"
)
installerp.set_defaults(_class=Installer, func="run")
installerp.add_argument(
"-p",
"--product",
metavar="PRODUCT",
required=True,
help="product name (required)",
)
installerp.add_argument(
"-v",
"--version",
metavar="VERSION",
required=True,
help="version identifier (required)",
)
installerp.add_argument(
"-r",
"--release",
metavar="RELEASE",
required=True,
help="release information (required)",
)
installerp.add_argument(
"-s",
"--source",
metavar="REPOSITORY",
required=True,
action="append",
help="source repository (required)",
)
installerp.add_argument(
"-o",
"--output",
metavar="DIR",
required=True,
help="path to image output directory (required)",
)
installerp.add_argument("--log-dir", metavar="DIR", help="path to log directory")
installerp.add_argument("--volid", metavar="VOLID", help="volume id")
installerp.add_argument("--variant", metavar="VARIANT", help="variant name")
installerp.add_argument("--rootfs-size", metavar="SIZE")
installerp.add_argument("--nomacboot", action="store_true", default=False)
installerp.add_argument("--noupgrade", action="store_true", default=False)
installerp.add_argument("--isfinal", action="store_true", default=False)
installerp.add_argument(
"--installpkgs",
metavar="PACKAGE",
action="append",
help="package glob to install before runtime-install.tmpl",
)
installerp.add_argument(
"--add-template",
metavar="FILE",
action="append",
help="Additional template for runtime image",
)
installerp.add_argument(
"--add-template-var",
metavar="ADD_TEMPLATE_VARS",
action="append",
help="Set variable for runtime image template",
)
installerp.add_argument(
"--add-arch-template",
metavar="FILE",
action="append",
help="Additional template for architecture-specific image",
)
installerp.add_argument(
"--add-arch-template-var",
metavar="ADD_ARCH_TEMPLATE_VARS",
action="append",
help="Set variable for architecture-specific image",
)
installerp.add_argument(
"--extra-config", metavar="FILE", help="JSON file contains extra configurations"
)
args = parser.parse_args(args)
logging.basicConfig(format="%(message)s", level=logging.DEBUG)
_class = args._class()
_class.set_args(args)
func = getattr(_class, args.func)
func()

19
pungi/ostree/base.py Normal file
View File

@ -0,0 +1,19 @@
# -*- coding: utf-8 -*-
# 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; version 2 of the License.
#
# 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 Library General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, see <https://gnu.org/licenses/>.
class OSTree(object):
def set_args(self, args):
self.args = args

86
pungi/ostree/container.py Normal file
View File

@ -0,0 +1,86 @@
# -*- coding: utf-8 -*-
# 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; version 2 of the License.
#
# 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 Library General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, see <https://gnu.org/licenses/>.
import os
import json
import six
from six.moves import shlex_quote
from .base import OSTree
from .utils import tweak_treeconf
def emit(cmd):
"""Print line of shell code into the stream."""
if isinstance(cmd, six.string_types):
print(cmd)
else:
print(" ".join([shlex_quote(x) for x in cmd]))
class Container(OSTree):
def _make_container(self):
"""Compose OSTree Container Native image"""
stamp_file = os.path.join(self.logdir, "%s.stamp" % self.name)
cmd = [
"rpm-ostree",
"compose",
"image",
# Always initialize for now
"--initialize",
# Touch the file if a new commit was created. This can help us tell
# if the commitid file is missing because no commit was created or
# because something went wrong.
"--touch-if-changed=%s" % stamp_file,
self.treefile,
]
fullpath = os.path.join(self.path, "%s.ociarchive" % self.name)
cmd.append(fullpath)
# Set the umask to be more permissive so directories get group write
# permissions. See https://pagure.io/releng/issue/8811#comment-629051
emit("umask 0002")
emit(cmd)
def run(self):
self.name = self.args.name
self.path = self.args.path
self.treefile = self.args.treefile
self.logdir = self.args.log_dir
self.extra_config = self.args.extra_config
if self.extra_config:
self.extra_config = json.load(open(self.extra_config, "r"))
repos = self.extra_config.get("repo", [])
keep_original_sources = self.extra_config.get(
"keep_original_sources", False
)
else:
# missing extra_config mustn't affect tweak_treeconf call
repos = []
keep_original_sources = True
update_dict = {"automatic-version-prefix": self.args.version}
self.treefile = tweak_treeconf(
self.treefile,
source_repos=repos,
keep_original_sources=keep_original_sources,
update_dict=update_dict,
)
self._make_container()

77
pungi/ostree/installer.py Normal file
View File

@ -0,0 +1,77 @@
# -*- coding: utf-8 -*-
# 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; version 2 of the License.
#
# 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 Library General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, see <https://gnu.org/licenses/>.
import json
from kobo import shortcuts
from .base import OSTree
from ..wrappers import lorax
class Installer(OSTree):
def _merge_config(self, config):
self.installpkgs.extend(config.get("installpkgs", []))
self.add_template.extend(config.get("add_template", []))
self.add_template_var.extend(config.get("add_template_var"))
self.add_arch_template.extend(config.get("add_arch_template", []))
self.add_arch_template_var.extend(config.get("add_arch_template_var", []))
def run(self):
self.product = self.args.product
self.version = self.args.version
self.release = self.args.release
self.sources = self.args.source
self.output = self.args.output
self.logdir = self.args.log_dir
self.volid = self.args.volid
self.variant = self.args.variant
self.rootfs_size = self.args.rootfs_size
self.nomacboot = self.args.nomacboot
self.noupgrade = self.args.noupgrade
self.isfinal = self.args.isfinal
self.installpkgs = self.args.installpkgs or []
self.add_template = self.args.add_template or []
self.add_template_var = self.args.add_template_var or []
self.add_arch_template = self.args.add_arch_template or []
self.add_arch_template_var = self.args.add_arch_template_var or []
self.extra_config = self.args.extra_config
if self.extra_config:
self.extra_config = json.load(open(self.extra_config, "r"))
self._merge_config(self.extra_config)
lorax_wrapper = lorax.LoraxWrapper()
cmd = lorax_wrapper.get_lorax_cmd(
self.product,
self.version,
self.release,
self.sources,
self.output,
variant=self.variant,
nomacboot=self.nomacboot,
volid=self.volid,
buildinstallpackages=self.installpkgs,
add_template=self.add_template,
add_template_var=self.add_template_var,
add_arch_template=self.add_arch_template,
add_arch_template_var=self.add_arch_template_var,
rootfs_size=self.rootfs_size,
is_final=self.isfinal,
log_dir=self.logdir,
)
shortcuts.run(cmd)

158
pungi/ostree/tree.py Normal file
View File

@ -0,0 +1,158 @@
# -*- coding: utf-8 -*-
# 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; version 2 of the License.
#
# 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 Library General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, see <https://gnu.org/licenses/>.
import os
import json
from kobo import shortcuts
from pungi.util import makedirs
from .base import OSTree
from .utils import (
make_log_file,
tweak_treeconf,
get_ref_from_treefile,
get_commitid_from_commitid_file,
)
class Tree(OSTree):
def _make_tree(self):
"""Compose OSTree tree"""
log_file = make_log_file(self.logdir, "create-ostree-repo")
cmd = [
"rpm-ostree",
"compose",
"tree",
"--repo=%s" % self.repo,
"--write-commitid-to=%s" % self.commitid_file,
# Touch the file if a new commit was created. This can help us tell
# if the commitid file is missing because no commit was created or
# because something went wrong.
"--touch-if-changed=%s.stamp" % self.commitid_file,
]
if self.unified_core:
# See https://github.com/coreos/rpm-ostree/issues/729
cmd.append("--unified-core")
if self.version:
# Add versioning metadata
cmd.append("--add-metadata-string=version=%s" % self.version)
# Note renamed from rpm-ostree --force-nocache since it's a better
# name; more clearly describes what we're doing here.
if self.force_new_commit:
cmd.append("--force-nocache")
cmd.append(self.treefile)
# Set the umask to be more permissive so directories get group write
# permissions. See https://pagure.io/releng/issue/8811#comment-629051
oldumask = os.umask(0o0002)
try:
shortcuts.run(
cmd,
show_cmd=True,
stdout=True,
logfile=log_file,
universal_newlines=True,
)
finally:
os.umask(oldumask)
def _update_summary(self):
"""Update summary metadata"""
log_file = make_log_file(self.logdir, "ostree-summary")
shortcuts.run(
["ostree", "summary", "-u", "--repo=%s" % self.repo],
show_cmd=True,
stdout=True,
logfile=log_file,
universal_newlines=True,
)
def _update_ref(self):
"""
Update the ref.
'--write-commitid-to' is specified when compose the tree, so we need
to update the ref by ourselves. ref is retrieved from treefile and
commitid is retrieved from the committid file.
"""
tag_ref = True
if self.extra_config:
tag_ref = self.extra_config.get("tag_ref", True)
if not tag_ref:
print("Not updating ref as configured")
return
ref = get_ref_from_treefile(self.treefile)
commitid = get_commitid_from_commitid_file(self.commitid_file)
print("Ref: %r, Commit ID: %r" % (ref, commitid))
if ref and commitid:
print("Updating ref")
# Let's write the tag out ourselves
heads_dir = os.path.join(self.repo, "refs", "heads")
if not os.path.exists(heads_dir):
raise RuntimeError("Refs/heads did not exist in ostree repo")
ref_path = os.path.join(heads_dir, ref)
# Set the umask to be more permissive so directories get group write
# permissions. See https://pagure.io/releng/issue/8811#comment-629051
oldumask = os.umask(0o0002)
try:
makedirs(os.path.dirname(ref_path))
finally:
os.umask(oldumask)
with open(ref_path, "w") as f:
f.write(commitid + "\n")
def run(self):
self.repo = self.args.repo
self.treefile = self.args.treefile
self.version = self.args.version
self.logdir = self.args.log_dir
self.update_summary = self.args.update_summary
self.extra_config = self.args.extra_config
self.ostree_ref = self.args.ostree_ref
self.force_new_commit = self.args.force_new_commit
self.unified_core = self.args.unified_core
if self.extra_config or self.ostree_ref:
if self.extra_config:
self.extra_config = json.load(open(self.extra_config, "r"))
repos = self.extra_config.get("repo", [])
keep_original_sources = self.extra_config.get(
"keep_original_sources", False
)
else:
# missing extra_config mustn't affect tweak_treeconf call
repos = []
keep_original_sources = True
update_dict = {}
if self.ostree_ref:
# override ref value in treefile
update_dict["ref"] = self.ostree_ref
self.treefile = tweak_treeconf(
self.treefile,
source_repos=repos,
keep_original_sources=keep_original_sources,
update_dict=update_dict,
)
self.commitid_file = make_log_file(self.logdir, "commitid")
self._make_tree()
self._update_ref()
if self.update_summary:
self._update_summary()

126
pungi/ostree/utils.py Normal file
View File

@ -0,0 +1,126 @@
# -*- coding: utf-8 -*-
# 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; version 2 of the License.
#
# 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 Library General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, see <https://gnu.org/licenses/>.
import json
import logging
import os
import shutil
import yaml
from pungi.arch_utils import getBaseArch
from pungi.util import makedirs
def make_log_file(log_dir, filename):
"""Return path to log file with given name, if log_dir is set."""
if not log_dir:
return None
makedirs(log_dir)
return os.path.join(log_dir, "%s.log" % filename)
def get_ref_from_treefile(treefile, arch=None, logger=None):
"""
Return ref name by parsing the tree config file. Replacing ${basearch} with
the basearch of the architecture we are running on or of the passed in arch.
"""
logger = logger or logging.getLogger(__name__)
if os.path.isfile(treefile):
with open(treefile, "r") as f:
try:
# rpm-ostree now supports YAML
# https://github.com/projectatomic/rpm-ostree/pull/1377
if treefile.endswith(".yaml"):
parsed = yaml.safe_load(f)
else:
parsed = json.load(f)
return parsed["ref"].replace("${basearch}", getBaseArch(arch))
except Exception as e:
logger.error("Unable to get ref from treefile: %s" % e)
else:
logger.error("Unable to open treefile")
return None
def get_commitid_from_commitid_file(commitid_file):
"""Return commit id which is read from the commitid file"""
if not os.path.exists(commitid_file + ".stamp"):
# The stamp does not exist, so no new commit.
return None
with open(commitid_file, "r") as f:
return f.read().replace("\n", "")
def tweak_treeconf(
treeconf, source_repos=None, keep_original_sources=False, update_dict=None
):
"""
Update tree config file by adding new repos, and remove existing repos
from the tree config file if 'keep_original_sources' is not enabled.
Additionally, other values can be passed to method by 'update_dict' parameter to
update treefile content.
"""
# backup the old tree config
shutil.copy2(treeconf, "{0}.bak".format(treeconf))
treeconf_dir = os.path.dirname(treeconf)
with open(treeconf, "r") as f:
# rpm-ostree now supports YAML, but we'll end up converting it to JSON.
# https://github.com/projectatomic/rpm-ostree/pull/1377
if treeconf.endswith(".yaml"):
treeconf_content = yaml.safe_load(f)
treeconf = treeconf.replace(".yaml", ".json")
else:
treeconf_content = json.load(f)
repos = []
if source_repos:
# Sort to ensure reliable ordering
source_repos = sorted(source_repos, key=lambda x: x["name"])
# Now, since pungi includes timestamps in the repo names which
# currently defeats rpm-ostree's change detection, let's just
# use repos named 'repo-<number>'.
# https://pagure.io/pungi/issue/811
with open("{0}/pungi.repo".format(treeconf_dir), "w") as f:
for i, repo in enumerate(source_repos):
name = "repo-{0}".format(i)
f.write("[%s]\n" % name)
f.write("name=%s\n" % name)
f.write("baseurl=%s\n" % repo["baseurl"])
exclude = repo.get("exclude", None)
if exclude:
f.write("exclude=%s\n" % exclude)
gpgcheck = "1" if repo.get("gpgcheck", False) else "0"
f.write("gpgcheck=%s\n" % gpgcheck)
repos.append(name)
original_repos = treeconf_content.get("repos", [])
if keep_original_sources:
treeconf_content["repos"] = original_repos + repos
else:
treeconf_content["repos"] = repos
# update content with config values from dictionary (for example 'ref')
if isinstance(update_dict, dict):
treeconf_content.update(update_dict)
# update tree config to add new repos
with open(treeconf, "w") as f:
json.dump(treeconf_content, f, indent=4)
return treeconf

73
pungi/pathmatch.py Normal file
View File

@ -0,0 +1,73 @@
# -*- coding: utf-8 -*-
# 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; version 2 of the License.
#
# 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 Library General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, see <https://gnu.org/licenses/>.
import fnmatch
def head_tail_split(name):
name_split = name.strip("/").split("/", 1)
if len(name_split) == 2:
head = name_split[0]
tail = name_split[1].strip("/")
else:
head, tail = name_split[0], None
return head, tail
class PathMatch(object):
def __init__(self, parent=None, desc=None):
self._patterns = {}
self._final_patterns = {}
self._values = []
def __setitem__(self, name, value):
head, tail = head_tail_split(name)
if tail is not None:
# recursion
if head not in self._patterns:
self._patterns[head] = PathMatch(parent=self, desc=head)
self._patterns[head][tail] = value
else:
if head not in self._final_patterns:
self._final_patterns[head] = PathMatch(parent=self, desc=head)
if value not in self._final_patterns[head]._values:
self._final_patterns[head]._values.append(value)
def __getitem__(self, name):
result = []
head, tail = head_tail_split(name)
for pattern in self._patterns:
if fnmatch.fnmatch(head, pattern):
if tail is None:
values = self._patterns[pattern]._values
else:
values = self._patterns[pattern][tail]
for value in values:
if value not in result:
result.append(value)
for pattern in self._final_patterns:
if tail is None:
x = head
else:
x = "%s/%s" % (head, tail)
if fnmatch.fnmatch(x, pattern):
values = self._final_patterns[pattern]._values
for value in values:
if value not in result:
result.append(value)
return result

841
pungi/paths.py Normal file
View File

@ -0,0 +1,841 @@
# -*- coding: utf-8 -*-
# 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; version 2 of the License.
#
# 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 Library General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, see <https://gnu.org/licenses/>.
__all__ = ("Paths",)
import errno
import os
from kobo.shortcuts import relative_path
from pungi.util import makedirs, find_old_compose
class Paths(object):
def __init__(self, compose):
self._compose = compose
paths_module_name = compose.conf.get("paths_module")
if paths_module_name:
# custom paths
paths_module = __import__(
paths_module_name,
globals(),
locals(),
["LogPaths", "WorkPaths", "ComposePaths"],
)
self.compose = paths_module.ComposePaths(compose)
self.log = paths_module.LogPaths(compose)
self.work = paths_module.WorkPaths(compose)
else:
# default paths
self.compose = ComposePaths(compose)
self.log = LogPaths(compose)
self.work = WorkPaths(compose)
# self.metadata ?
def get_old_compose_topdir(self, **kwargs):
"""
Finds old compose using the `find_old_compose` function and returns
the path to it. The `kwargs` are passed to `find_old_compose`.
"""
is_layered = self._compose.ci_base.release.is_layered
return find_old_compose(
self._compose.old_composes,
self._compose.ci_base.release.short,
self._compose.ci_base.release.version,
self._compose.ci_base.release.type_suffix,
self._compose.ci_base.base_product.short if is_layered else None,
self._compose.ci_base.base_product.version if is_layered else None,
**kwargs
)
def old_compose_path(self, path, **kwargs):
"""
Translates `path` to the topdir of old compose.
:param str path: Path to translate.
:param kwargs: The kwargs passed to `find_old_compose` function.
:return: None if old compose cannot be used or if `path` does not exist
in the old compose topdir. Otherwise path translated to old_compose
topdir.
Example:
old_repo_dir = compose.old_compose_path(
compose.paths.work.pkgset_repo(pkgset.name, arch="global"))
"""
old_compose_topdir = self.get_old_compose_topdir(**kwargs)
if not old_compose_topdir:
return None
rel_path = relative_path(path, self._compose.topdir.rstrip("/") + "/")
old_path = os.path.join(old_compose_topdir, rel_path)
if not os.path.exists(old_path):
return None
return old_path
class LogPaths(object):
def __init__(self, compose):
self.compose = compose
def topdir(self, arch=None, create_dir=True):
"""
Examples:
log/global
log/x86_64
"""
arch = arch or "global"
path = os.path.join(self.compose.topdir, "logs", arch)
if create_dir:
makedirs(path)
return path
def koji_tasks_dir(self, create_dir=True):
"""
Examples:
logs/global/koji-tasks
"""
path = os.path.join(self.topdir(create_dir=create_dir), "koji-tasks")
if create_dir:
makedirs(path)
return path
def log_file(self, arch, log_name, create_dir=True, ext=None):
ext = ext or "log"
arch = arch or "global"
if log_name.endswith(".log"):
log_name = log_name[:-4]
return os.path.join(
self.topdir(arch, create_dir=create_dir), "%s.%s.%s" % (log_name, arch, ext)
)
class WorkPaths(object):
def __init__(self, compose):
self.compose = compose
def topdir(self, arch=None, create_dir=True):
"""
Examples:
work/global
work/x86_64
"""
arch = arch or "global"
path = os.path.join(self.compose.topdir, "work", arch)
if create_dir:
makedirs(path)
return path
def variants_file(self, arch=None, create_dir=True):
"""
Examples:
work/global/variants.xml
"""
arch = "global"
path = os.path.join(self.topdir(arch, create_dir=create_dir), "variants.xml")
return path
def comps(self, arch=None, variant=None, create_dir=True):
"""
Examples:
work/x86_64/comps/comps-86_64.xml
work/x86_64/comps/comps-Server.x86_64.xml
"""
arch = arch or "global"
if variant is None:
file_name = "comps-%s.xml" % arch
else:
file_name = "comps-%s.%s.xml" % (variant.uid, arch)
path = os.path.join(self.topdir(arch, create_dir=create_dir), "comps")
if create_dir:
makedirs(path)
path = os.path.join(path, file_name)
return path
def gather_result(self, arch=None, variant=None, create_dir=True):
"""
Examples:
work/x86_64/gather_result/x86_64.result
work/x86_64/gather_result/Server.x86_64.result
"""
arch = arch or "global"
file_name = ""
if variant:
file_name += variant.uid + "."
file_name += arch + "."
file_name += "result"
path = os.path.join(self.topdir(arch, create_dir=create_dir), "gather_result")
if create_dir:
makedirs(path)
path = os.path.join(path, file_name)
return path
def pungi_conf(self, arch=None, variant=None, create_dir=True, source_name=None):
"""
Examples:
work/x86_64/pungi/x86_64.conf
work/x86_64/pungi/Server.x86_64.conf
"""
arch = arch or "global"
file_name = ""
if variant:
file_name += variant.uid + "."
file_name += arch + "."
if source_name:
file_name += source_name + "."
file_name += "conf"
path = os.path.join(self.topdir(arch, create_dir=create_dir), "pungi")
if create_dir:
makedirs(path)
path = os.path.join(path, file_name)
return path
def fus_conf(self, arch, variant, iteration, create_dir=True):
"""
Examples:
work/x86_64/fus/Server-solvables.x86_64.conf
"""
file_name = "%s-solvables-%d.%s.conf" % (variant.uid, iteration, arch)
path = os.path.join(self.topdir(arch, create_dir=create_dir), "fus")
if create_dir:
makedirs(path)
return os.path.join(path, file_name)
def pungi_log(self, arch=None, variant=None, create_dir=True, source_name=None):
"""
Examples:
work/x86_64/pungi/x86_64.log
work/x86_64/pungi/Server.x86_64.log
"""
path = self.pungi_conf(arch, variant, create_dir=create_dir)
path = path[:-5]
if source_name:
path += "." + source_name
return path + ".log"
def pungi_cache_dir(self, arch, variant=None, create_dir=True):
"""
Examples:
work/global/pungi-cache
"""
# WARNING: Using the same cache dir with repos of the same names
# may lead to a race condition.
# We should use per arch variant cache dirs to workaround this.
path = os.path.join(self.topdir(arch, create_dir=create_dir), "pungi-cache")
if variant:
path = os.path.join(path, variant.uid)
if create_dir:
makedirs(path)
return path
def _repo(self, type, arch=None, variant=None, create_dir=True):
arch = arch or "global"
path = os.path.join(self.topdir(arch, create_dir=create_dir), "%s_repo" % type)
if variant:
path += "_" + variant.uid
if create_dir:
makedirs(path)
return path
def comps_repo(self, arch=None, variant=None, create_dir=True):
"""
Examples:
work/x86_64/comps_repo_Server
work/global/comps_repo
"""
return self._repo("comps", arch, variant, create_dir=create_dir)
def pkgset_repo(self, pkgset_name, arch=None, create_dir=True):
"""
Examples:
work/x86_64/repo/f30-compose
work/global/repo/f30-compose
"""
arch = arch or "global"
path = os.path.join(
self.topdir(arch, create_dir=create_dir), "repo", pkgset_name
)
if create_dir:
makedirs(path)
return path
def lookaside_repo(self, arch, variant, create_dir=True):
"""
Examples:
work/x86_64/Server/lookaside_repo
"""
path = os.path.join(
self.topdir(arch, create_dir=create_dir), variant.uid, "lookaside_repo"
)
if create_dir:
makedirs(path)
return path
def package_list(
self, arch=None, variant=None, pkgset=None, pkg_type=None, create_dir=True
):
"""
Examples:
work/x86_64/package_list/x86_64.conf
work/x86_64/package_list/Server.x86_64.conf
work/x86_64/package_list/Server.x86_64.rpm.conf
"""
arch = arch or "global"
if variant is not None:
file_name = "%s.%s" % (variant, arch)
else:
file_name = "%s" % arch
if pkgset:
file_name += "." + pkgset.name
if pkg_type is not None:
file_name += ".%s" % pkg_type
file_name += ".conf"
path = os.path.join(self.topdir(arch, create_dir=create_dir), "package_list")
if create_dir:
makedirs(path)
path = os.path.join(path, file_name)
return path
def lookaside_package_list(self, arch, variant, create_dir=True):
"""
Examples:
work/x86_64/package_list/Server.x86_64.lookaside.conf
"""
return self.package_list(
arch, variant, pkg_type="lookaside", create_dir=create_dir
)
def pungi_download_dir(self, arch, create_dir=True):
"""
Examples:
work/x86_64/pungi_download
"""
path = os.path.join(self.topdir(arch, create_dir=create_dir), "pungi_download")
if create_dir:
makedirs(path)
return path
def buildinstall_dir(
self, arch, create_dir=True, allow_topdir_override=False, variant=None
):
"""
:param bool allow_topdir_override: When True, the
"buildinstall_topdir" will be used (if set) instead of real
"topdir".
Examples:
work/x86_64/buildinstall
"""
if arch == "global":
raise RuntimeError("Global buildinstall dir makes no sense.")
buildinstall_topdir = self.compose.conf.get("buildinstall_topdir", "")
if allow_topdir_override and buildinstall_topdir:
topdir_basename = os.path.basename(self.compose.topdir)
path = os.path.join(
buildinstall_topdir, "buildinstall-%s" % topdir_basename, arch
)
else:
path = os.path.join(
self.topdir(arch, create_dir=create_dir), "buildinstall"
)
if variant:
path = os.path.join(path, variant.uid)
return path
def extra_files_dir(self, arch, variant, create_dir=True):
"""
Examples:
work/x86_64/Server/extra-files
"""
if arch == "global":
raise RuntimeError("Global extra files dir makes no sense.")
path = os.path.join(
self.topdir(arch, create_dir=create_dir), variant.uid, "extra-files"
)
if create_dir:
makedirs(path)
return path
def extra_iso_extra_files_dir(self, arch, variant, create_dir=True):
"""
Examples:
work/x86_64/Server/extra-iso-extra-files
"""
if arch == "global":
raise RuntimeError("Global extra files dir makes no sense.")
path = os.path.join(
self.topdir(arch, create_dir=create_dir),
variant.uid,
"extra-iso-extra-files",
)
if create_dir:
makedirs(path)
return path
def iso_staging_dir(self, arch, variant, filename, create_dir=True):
"""
Examples:
work/x86_64/Server/iso-staging-dir/file.iso/
"""
path = os.path.join(
self.topdir(arch, create_dir=create_dir),
variant.uid,
"iso-staging-dir",
filename,
)
if create_dir:
makedirs(path)
return path
def repo_package_list(self, arch, variant, pkg_type=None, create_dir=True):
"""
Examples:
work/x86_64/repo_package_list/Server.x86_64.rpm.conf
"""
file_name = "%s.%s" % (variant.uid, arch)
if pkg_type is not None:
file_name += ".%s" % pkg_type
file_name += ".conf"
path = os.path.join(
self.topdir(arch, create_dir=create_dir), "repo_package_list"
)
if create_dir:
makedirs(path)
path = os.path.join(path, file_name)
return path
def iso_dir(self, arch, filename, create_dir=True):
"""
Examples:
work/x86_64/iso/Project-1.0-20151203.0-Client-x86_64-dvd1.iso
"""
path = os.path.join(self.topdir(arch, create_dir=create_dir), "iso", filename)
if create_dir:
makedirs(path)
return path
def tmp_dir(self, arch=None, variant=None, create_dir=True):
"""
Examples:
work/global/tmp
work/x86_64/tmp
work/x86_64/tmp-Server
"""
dir_name = "tmp"
if variant:
dir_name += "-%s" % variant.uid
path = os.path.join(self.topdir(arch=arch, create_dir=create_dir), dir_name)
if create_dir:
makedirs(path)
return path
def product_id(self, arch, variant, create_dir=True):
"""
Examples:
work/x86_64/product_id/productid-Server.x86_64.pem/productid
"""
# file_name = "%s.%s.pem" % (variant, arch)
# HACK: modifyrepo doesn't handle renames -> $dir/productid
file_name = "productid"
path = os.path.join(
self.topdir(arch, create_dir=create_dir),
"product_id",
"%s.%s.pem" % (variant, arch),
)
if create_dir:
makedirs(path)
path = os.path.join(path, file_name)
return path
def image_build_dir(self, variant, create_dir=True):
"""
@param variant
@param create_dir=True
Examples:
work/image-build/Server
"""
path = os.path.join(
self.topdir("image-build", create_dir=create_dir), variant.uid
)
if create_dir:
makedirs(path)
return path
def image_build_conf(
self, variant, image_name, image_type, arches=None, create_dir=True
):
"""
@param variant
@param image-name
@param image-type (e.g docker)
@param arches
@param create_dir=True
Examples:
work/image-build/Server/docker_rhel-server-docker.cfg
work/image-build/Server/docker_rhel-server-docker_x86_64.cfg
work/image-build/Server/docker_rhel-server-docker_x86_64-ppc64le.cfg
"""
path = os.path.join(
self.image_build_dir(variant), "%s_%s" % (image_type, image_name)
)
if arches is not None:
path = "%s_%s" % (path, "-".join(list(arches)))
path = "%s.cfg" % path
return path
def module_defaults_dir(self, create_dir=True):
"""
Example:
work/global/module_defaults
"""
path = os.path.join(self.topdir(create_dir=create_dir), "module_defaults")
if create_dir:
makedirs(path)
return path
def module_obsoletes_dir(self, create_dir=True):
"""
Example:
work/global/module_obsoletes
"""
path = os.path.join(self.topdir(create_dir=create_dir), "module_obsoletes")
if create_dir:
makedirs(path)
return path
def pkgset_file_cache(self, pkgset_name):
"""
Returns the path to file in which the cached version of
PackageSetBase.file_cache should be stored.
Example:
work/global/pkgset_f33-compose_file_cache.pickle
"""
filename = "pkgset_%s_file_cache.pickle" % pkgset_name
return os.path.join(self.topdir(arch="global"), filename)
def pkgset_reuse_file(self, pkgset_name):
"""
Example:
work/global/pkgset_f30-compose_reuse.pickle
"""
filename = "pkgset_%s_reuse.pickle" % pkgset_name
return os.path.join(self.topdir(arch="global", create_dir=False), filename)
class ComposePaths(object):
def __init__(self, compose):
self.compose = compose
# TODO: TREES?
def topdir(self, arch=None, variant=None, create_dir=True, relative=False):
"""
Examples:
compose
compose/Server/x86_64
"""
if bool(arch) != bool(variant):
raise TypeError("topdir(): either none or 2 arguments are expected")
path = ""
if not relative:
path = os.path.join(self.compose.topdir, "compose")
if arch or variant:
if variant.type == "addon":
return self.topdir(
arch, variant.parent, create_dir=create_dir, relative=relative
)
path = os.path.join(path, variant.uid, arch)
if create_dir and not relative:
makedirs(path)
return path
def tree_dir(self, arch, variant, create_dir=True, relative=False):
"""
Examples:
compose/Server/x86_64/os
compose/Server-optional/x86_64/os
"""
if arch == "src":
arch = "source"
if arch == "source":
tree_dir = "tree"
else:
# use 'os' dir due to historical reasons
tree_dir = "os"
path = os.path.join(
self.topdir(arch, variant, create_dir=create_dir, relative=relative),
tree_dir,
)
if create_dir and not relative:
makedirs(path)
return path
def os_tree(self, arch, variant, create_dir=True, relative=False):
return self.tree_dir(arch, variant, create_dir=create_dir, relative=relative)
def repository(self, arch, variant, create_dir=True, relative=False):
"""
Examples:
compose/Server/x86_64/os
compose/Server/x86_64/addons/LoadBalancer
"""
if variant.type == "addon":
path = self.packages(
arch, variant, create_dir=create_dir, relative=relative
)
else:
path = self.tree_dir(
arch, variant, create_dir=create_dir, relative=relative
)
if create_dir and not relative:
makedirs(path)
return path
def packages(self, arch, variant, create_dir=True, relative=False):
"""
Examples:
compose/Server/x86_64/os/Packages
compose/Server/x86_64/os/addons/LoadBalancer
compose/Server-optional/x86_64/os/Packages
"""
if variant.type == "addon":
path = os.path.join(
self.tree_dir(arch, variant, create_dir=create_dir, relative=relative),
"addons",
variant.id,
)
else:
path = os.path.join(
self.tree_dir(arch, variant, create_dir=create_dir, relative=relative),
"Packages",
)
if create_dir and not relative:
makedirs(path)
return path
def debug_topdir(self, arch, variant, create_dir=True, relative=False):
"""
Examples:
compose/Server/x86_64/debug
compose/Server-optional/x86_64/debug
"""
path = os.path.join(
self.topdir(arch, variant, create_dir=create_dir, relative=relative),
"debug",
)
if create_dir and not relative:
makedirs(path)
return path
def debug_tree(self, arch, variant, create_dir=True, relative=False):
"""
Examples:
compose/Server/x86_64/debug/tree
compose/Server-optional/x86_64/debug/tree
"""
path = os.path.join(
self.debug_topdir(arch, variant, create_dir=create_dir, relative=relative),
"tree",
)
if create_dir and not relative:
makedirs(path)
return path
def debug_packages(self, arch, variant, create_dir=True, relative=False):
"""
Examples:
compose/Server/x86_64/debug/tree/Packages
compose/Server/x86_64/debug/tree/addons/LoadBalancer
compose/Server-optional/x86_64/debug/tree/Packages
"""
if arch in ("source", "src"):
return None
if variant.type == "addon":
path = os.path.join(
self.debug_tree(
arch, variant, create_dir=create_dir, relative=relative
),
"addons",
variant.id,
)
else:
path = os.path.join(
self.debug_tree(
arch, variant, create_dir=create_dir, relative=relative
),
"Packages",
)
if create_dir and not relative:
makedirs(path)
return path
def debug_repository(self, arch, variant, create_dir=True, relative=False):
"""
Examples:
compose/Server/x86_64/debug/tree
compose/Server/x86_64/debug/tree/addons/LoadBalancer
compose/Server-optional/x86_64/debug/tree
"""
if arch in ("source", "src"):
return None
if variant.type == "addon":
path = os.path.join(
self.debug_tree(
arch, variant, create_dir=create_dir, relative=relative
),
"addons",
variant.id,
)
else:
path = self.debug_tree(
arch, variant, create_dir=create_dir, relative=relative
)
if create_dir and not relative:
makedirs(path)
return path
def iso_dir(self, arch, variant, symlink_to=None, create_dir=True, relative=False):
"""
Examples:
compose/Server/x86_64/iso
None
"""
if variant.type == "addon":
return None
if variant.type == "optional":
if not self.compose.conf.get("create_optional_isos", False):
return None
if arch == "src":
arch = "source"
path = os.path.join(
self.topdir(arch, variant, create_dir=create_dir, relative=relative), "iso"
)
if symlink_to:
# TODO: create_dir
topdir = self.compose.topdir.rstrip("/") + "/"
relative_dir = path[len(topdir) :]
target_dir = os.path.join(symlink_to, self.compose.compose_id, relative_dir)
if create_dir and not relative:
makedirs(target_dir)
try:
os.symlink(target_dir, path)
except OSError as ex:
if ex.errno != errno.EEXIST:
raise
msg = "Symlink pointing to '%s' expected: %s" % (target_dir, path)
if not os.path.islink(path):
raise RuntimeError(msg)
if os.path.abspath(os.readlink(path)) != target_dir:
raise RuntimeError(msg)
else:
if create_dir and not relative:
makedirs(path)
return path
def iso_path(
self, arch, variant, filename, symlink_to=None, create_dir=True, relative=False
):
"""
Examples:
compose/Server/x86_64/iso/rhel-7.0-20120127.0-Server-x86_64-dvd1.iso
None
"""
path = self.iso_dir(
arch,
variant,
symlink_to=symlink_to,
create_dir=create_dir,
relative=relative,
)
if path is None:
return None
return os.path.join(path, filename)
def image_dir(self, variant, symlink_to=None, relative=False):
"""
The arch is listed as literal '%(arch)s'
Examples:
compose/Server/%(arch)s/images
None
@param variant
@param symlink_to=None
@param relative=False
"""
path = os.path.join(
self.topdir("%(arch)s", variant, create_dir=False, relative=relative),
"images",
)
if symlink_to:
topdir = self.compose.topdir.rstrip("/") + "/"
relative_dir = path[len(topdir) :]
target_dir = os.path.join(symlink_to, self.compose.compose_id, relative_dir)
try:
os.symlink(target_dir, path)
except OSError as ex:
if ex.errno != errno.EEXIST:
raise
msg = "Symlink pointing to '%s' expected: %s" % (target_dir, path)
if not os.path.islink(path):
raise RuntimeError(msg)
if os.path.abspath(os.readlink(path)) != target_dir:
raise RuntimeError(msg)
return path
def jigdo_dir(self, arch, variant, create_dir=True, relative=False):
"""
Examples:
compose/Server/x86_64/jigdo
None
"""
if variant.type == "addon":
return None
if variant.type == "optional":
if not self.compose.conf.get("create_optional_isos", False):
return None
if arch == "src":
arch = "source"
path = os.path.join(
self.topdir(arch, variant, create_dir=create_dir, relative=relative),
"jigdo",
)
if create_dir and not relative:
makedirs(path)
return path
def metadata(self, file_name=None, create_dir=True, relative=False):
"""
Examples:
compose/metadata
compose/metadata/rpms.json
"""
path = os.path.join(
self.topdir(create_dir=create_dir, relative=relative), "metadata"
)
if create_dir and not relative:
makedirs(path)
if file_name:
path = os.path.join(path, file_name)
return path

44
pungi/phases/__init__.py Normal file
View File

@ -0,0 +1,44 @@
# -*- coding: utf-8 -*-
# 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; version 2 of the License.
#
# 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 Library General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, see <https://gnu.org/licenses/>.
import sys
# phases in runtime order
from .init import InitPhase # noqa
from .weaver import WeaverPhase # noqa
from .pkgset import PkgsetPhase # noqa
from .gather import GatherPhase # noqa
from .createrepo import CreaterepoPhase # noqa
from .buildinstall import BuildinstallPhase # noqa
from .extra_files import ExtraFilesPhase # noqa
from .createiso import CreateisoPhase # noqa
from .extra_isos import ExtraIsosPhase # noqa
from .image_build import ImageBuildPhase # noqa
from .image_container import ImageContainerPhase # noqa
from .kiwibuild import KiwiBuildPhase # noqa
from .osbuild import OSBuildPhase # noqa
from .repoclosure import RepoclosurePhase # noqa
from .test import TestPhase # noqa
from .image_checksum import ImageChecksumPhase # noqa
from .livemedia_phase import LiveMediaPhase # noqa
from .ostree import OSTreePhase # noqa
from .ostree_installer import OstreeInstallerPhase # noqa
from .ostree_container import OSTreeContainerPhase # noqa
from .osbs import OSBSPhase # noqa
from .phases_metadata import gather_phases_metadata # noqa
this_module = sys.modules[__name__]
PHASES_NAMES = gather_phases_metadata(this_module)

224
pungi/phases/base.py Normal file
View File

@ -0,0 +1,224 @@
# -*- coding: utf-8 -*-
# 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; version 2 of the License.
#
# 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 Library General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, see <https://gnu.org/licenses/>.
import logging
import math
import time
from pungi import util
class PhaseBase(object):
def __init__(self, compose):
self.compose = compose
self.msg = "---------- PHASE: %s ----------" % self.name.upper()
self.finished = False
self._skipped = False
# A set of config patterns that were actually used. Starts as None, and
# when config is queried the variable turns into a set of patterns.
self.used_patterns = None
def validate(self):
pass
def conf_assert_str(self, name):
missing = []
invalid = []
if name not in self.compose.conf:
missing.append(name)
elif not isinstance(self.compose.conf[name], str):
invalid.append(name, type(self.compose.conf[name]), str)
return missing, invalid
def skip(self):
if self._skipped:
return True
if self.compose.just_phases and self.name not in self.compose.just_phases:
return True
if self.name in self.compose.skip_phases:
return True
if self.name in self.compose.conf["skip_phases"]:
return True
return False
def start(self):
self._skipped = self.skip()
if self._skipped:
self.compose.log_warning("[SKIP ] %s" % self.msg)
self.finished = True
return
self._start_time = time.time()
self.compose.log_info("[BEGIN] %s" % self.msg)
self.compose.notifier.send("phase-start", phase_name=self.name)
self.run()
def get_config_block(self, variant, arch=None):
"""In config for current phase, find a block corresponding to given
variant and arch. The arch should be given if and only if the config
uses variant/arch mapping.
"""
self.used_patterns = self.used_patterns or set()
if arch is not None:
return util.get_arch_variant_data(
self.compose.conf, self.name, arch, variant, keys=self.used_patterns
)
else:
return util.get_variant_data(
self.compose.conf, self.name, variant, keys=self.used_patterns
)
def get_all_patterns(self):
"""Get all variant patterns from config file for this phase."""
if isinstance(self.compose.conf.get(self.name), dict):
return set(self.compose.conf.get(self.name, {}).keys())
else:
return set(x[0] for x in self.compose.conf.get(self.name, []))
def report_unused_patterns(self):
"""Log warning about unused parts of the config.
This is not technically an error, but can help debug when something
expected is missing.
"""
all_patterns = self.get_all_patterns()
unused_patterns = all_patterns - self.used_patterns
if unused_patterns:
self.compose.log_warning(
"[%s] Patterns in config do not match any variant: %s"
% (self.name.upper(), ", ".join(sorted(unused_patterns)))
)
self.compose.log_info(
"Note that variants can be excluded in configuration file"
)
def stop(self):
if self.finished:
return
if hasattr(self, "pool"):
self.pool.stop()
self.finished = True
self.compose.log_info("[DONE ] %s" % self.msg)
if hasattr(self, "_start_time"):
self.compose.log_info(
"PHASE %s took %d seconds"
% (self.name.upper(), math.ceil(time.time() - self._start_time))
)
if self.used_patterns is not None:
# We only want to report this if the config was actually queried.
self.report_unused_patterns()
self.compose.notifier.send("phase-stop", phase_name=self.name)
def run(self):
raise NotImplementedError
class ConfigGuardedPhase(PhaseBase):
"""A phase that is skipped unless config option is set."""
def skip(self):
if super(ConfigGuardedPhase, self).skip():
return True
if not self.compose.conf.get(self.name):
self.compose.log_info(
"Config section '%s' was not found. Skipping." % self.name
)
return True
return False
class ImageConfigMixin(object):
"""
A mixin for phase that needs to access image related settings: ksurl,
version, target and release.
First, it checks config object given as argument, then it checks
phase-level configuration and finally falls back to global configuration.
"""
def __init__(self, *args, **kwargs):
super(ImageConfigMixin, self).__init__(*args, **kwargs)
def get_config(self, cfg, opt):
return cfg.get(
opt,
self.compose.conf.get(
"%s_%s" % (self.name, opt), self.compose.conf.get("global_%s" % opt)
),
)
def get_version(self, cfg):
"""
Get version from configuration hierarchy or fall back to release
version.
"""
return (
util.version_generator(self.compose, self.get_config(cfg, "version"))
or self.get_config(cfg, "version")
or self.compose.image_version
)
def get_release(self, cfg):
"""
If release is set to a magic string (or explicitly to None -
deprecated), replace it with a generated value. Uses configuration
passed as argument, phase specific settings and global settings.
"""
for key, conf in [
("release", cfg),
("%s_release" % self.name, self.compose.conf),
("global_release", self.compose.conf),
]:
if key in conf:
return (
util.version_generator(self.compose, conf[key])
or self.compose.image_release
)
return None
def get_ksurl(self, cfg):
"""
Get ksurl from `cfg`. If not present, fall back to phase defined one or
global one.
"""
return (
cfg.get("ksurl")
or self.compose.conf.get("%s_ksurl" % self.name)
or self.compose.conf.get("global_ksurl")
)
class PhaseLoggerMixin(object):
"""
A mixin that can extend a phase with a new logging logger that copy
handlers from compose, but with different formatter that includes phase name.
"""
def __init__(self, *args, **kwargs):
super(PhaseLoggerMixin, self).__init__(*args, **kwargs)
self.logger = None
if self.compose._logger and self.compose._logger.handlers:
self.logger = logging.getLogger(self.name.upper())
self.logger.setLevel(logging.DEBUG)
format = "%(asctime)s [%(name)-16s] [%(levelname)-8s] %(message)s"
import copy
for handler in self.compose._logger.handlers:
hl = copy.copy(handler)
hl.setFormatter(logging.Formatter(format, datefmt="%Y-%m-%d %H:%M:%S"))
hl.setLevel(logging.DEBUG)
self.logger.addHandler(hl)

View File

@ -0,0 +1,950 @@
# -*- coding: utf-8 -*-
# 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; version 2 of the License.
#
# 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 Library General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, see <https://gnu.org/licenses/>.
import errno
import os
import time
import shutil
import re
from six.moves import cPickle as pickle
from copy import copy
from kobo.threads import ThreadPool, WorkerThread
from kobo.shortcuts import run, force_list
import kobo.rpmlib
from productmd.images import Image
from six.moves import shlex_quote
from pungi.arch import get_valid_arches
from pungi.util import get_volid, get_arch_variant_data
from pungi.util import get_file_size, get_mtime, failable, makedirs
from pungi.util import copy_all, translate_path
from pungi.wrappers.lorax import LoraxWrapper
from pungi.wrappers import iso
from pungi.wrappers.scm import get_file
from pungi.wrappers.scm import get_file_from_scm
from pungi.wrappers import kojiwrapper
from pungi.phases.base import PhaseBase
from pungi.runroot import Runroot, download_and_extract_archive
class BuildinstallPhase(PhaseBase):
name = "buildinstall"
def __init__(self, compose, pkgset_phase=None):
PhaseBase.__init__(self, compose)
self.pool = ThreadPool(logger=self.compose._logger)
# A set of (variant_uid, arch) pairs that completed successfully. This
# is needed to skip copying files for failed tasks.
self.pool.finished_tasks = set()
# A set of (variant_uid, arch) pairs that were reused from previous
# compose.
self.pool.reused_tasks = set()
self.buildinstall_method = self.compose.conf.get("buildinstall_method")
self.lorax_use_koji_plugin = self.compose.conf.get("lorax_use_koji_plugin")
self.used_lorax = self.buildinstall_method == "lorax"
self.pkgset_phase = pkgset_phase
self.warned_skipped = False
def skip(self):
if PhaseBase.skip(self):
return True
if not self.compose.conf.get("buildinstall_method"):
if not self.warned_skipped:
msg = "Not a bootable product. Skipping buildinstall."
self.compose.log_debug(msg)
self.warned_skipped = True
return True
return False
def _get_lorax_cmd(
self,
repo_baseurl,
output_dir,
variant,
arch,
buildarch,
volid,
final_output_dir,
):
noupgrade = True
bugurl = None
nomacboot = True
add_template = []
add_arch_template = []
add_template_var = []
add_arch_template_var = []
dracut_args = []
rootfs_size = None
skip_branding = False
squashfs_only = False
configuration_file = None
configuration_file_source = None
version = self.compose.conf.get(
"treeinfo_version", self.compose.conf["release_version"]
)
for data in get_arch_variant_data(
self.compose.conf, "lorax_options", arch, variant
):
if not data.get("noupgrade", True):
noupgrade = False
if data.get("bugurl"):
bugurl = data.get("bugurl")
if not data.get("nomacboot", True):
nomacboot = False
if "rootfs_size" in data:
rootfs_size = data.get("rootfs_size")
add_template.extend(data.get("add_template", []))
add_arch_template.extend(data.get("add_arch_template", []))
add_template_var.extend(data.get("add_template_var", []))
add_arch_template_var.extend(data.get("add_arch_template_var", []))
dracut_args.extend(data.get("dracut_args", []))
skip_branding = data.get("skip_branding", False)
configuration_file_source = data.get("configuration_file")
squashfs_only = data.get("squashfs_only", False)
if "version" in data:
version = data["version"]
output_dir = os.path.join(output_dir, variant.uid)
output_topdir = output_dir
# The paths module will modify the filename (by inserting arch). But we
# only care about the directory anyway.
log_dir = _get_log_dir(self.compose, variant, arch)
# Place the lorax.conf as specified by
# the configuration_file parameter of lorax_options to the log directory.
if configuration_file_source:
configuration_file_destination = os.path.join(log_dir, "lorax.conf")
# Obtain lorax.conf for the buildInstall phase
get_file(
configuration_file_source,
configuration_file_destination,
compose=self.compose,
)
configuration_file = configuration_file_destination
repos = repo_baseurl[:]
repos.extend(
get_arch_variant_data(
self.compose.conf, "lorax_extra_sources", arch, variant
)
)
if self.compose.has_comps:
comps_repo = self.compose.paths.work.comps_repo(arch, variant)
if final_output_dir != output_dir or self.lorax_use_koji_plugin:
comps_repo = translate_path(self.compose, comps_repo)
repos.append(comps_repo)
if self.lorax_use_koji_plugin:
return {
"product": self.compose.conf["release_name"],
"version": version,
"release": version,
"sources": force_list(repos),
"variant": variant.uid,
"installpkgs": variant.buildinstallpackages,
"isfinal": self.compose.supported,
"buildarch": buildarch,
"volid": volid,
"nomacboot": nomacboot,
"bugurl": bugurl,
"add-template": add_template,
"add-arch-template": add_arch_template,
"add-template-var": add_template_var,
"add-arch-template-var": add_arch_template_var,
"noupgrade": noupgrade,
"rootfs-size": rootfs_size,
"dracut-args": dracut_args,
"skip_branding": skip_branding,
"squashfs_only": squashfs_only,
"configuration_file": configuration_file,
}
else:
# If the buildinstall_topdir is set, it means Koji is used for
# buildinstall phase and the filesystem with Koji is read-only.
# In that case, we have to write logs to buildinstall_topdir and
# later copy them back to our local log directory.
if self.compose.conf.get("buildinstall_topdir", None):
output_dir = os.path.join(output_dir, "results")
lorax = LoraxWrapper()
lorax_cmd = lorax.get_lorax_cmd(
self.compose.conf["release_name"],
version,
version,
repos,
output_dir,
variant=variant.uid,
buildinstallpackages=variant.buildinstallpackages,
is_final=self.compose.supported,
buildarch=buildarch,
volid=volid,
nomacboot=nomacboot,
bugurl=bugurl,
add_template=add_template,
add_arch_template=add_arch_template,
add_template_var=add_template_var,
add_arch_template_var=add_arch_template_var,
noupgrade=noupgrade,
rootfs_size=rootfs_size,
log_dir=log_dir,
dracut_args=dracut_args,
skip_branding=skip_branding,
squashfs_only=squashfs_only,
configuration_file=configuration_file,
)
return "rm -rf %s && %s" % (
shlex_quote(output_topdir),
" ".join([shlex_quote(x) for x in lorax_cmd]),
)
def get_repos(self, arch):
repos = []
for pkgset in self.pkgset_phase.package_sets:
repos.append(pkgset.paths[arch])
return repos
def run(self):
disc_type = self.compose.conf["disc_types"].get("dvd", "dvd")
# Prepare kickstart file for final images.
self.pool.kickstart_file = get_kickstart_file(self.compose)
for arch in self.compose.get_arches():
commands = []
output_dir = self.compose.paths.work.buildinstall_dir(
arch, allow_topdir_override=True
)
final_output_dir = self.compose.paths.work.buildinstall_dir(
arch, allow_topdir_override=False
)
makedirs(final_output_dir)
repo_baseurls = self.get_repos(arch)
if final_output_dir != output_dir or self.lorax_use_koji_plugin:
repo_baseurls = [translate_path(self.compose, r) for r in repo_baseurls]
if self.buildinstall_method == "lorax":
buildarch = get_valid_arches(arch)[0]
for variant in self.compose.get_variants(arch=arch, types=["variant"]):
if variant.is_empty:
continue
skip = get_arch_variant_data(
self.compose.conf, "buildinstall_skip", arch, variant
)
if skip == [True]:
self.compose.log_info(
"Skipping buildinstall for %s.%s due to config option"
% (variant, arch)
)
continue
volid = get_volid(
self.compose, arch, variant=variant, disc_type=disc_type
)
commands.append(
(
variant,
self._get_lorax_cmd(
repo_baseurls,
output_dir,
variant,
arch,
buildarch,
volid,
final_output_dir,
),
)
)
else:
raise ValueError(
"Unsupported buildinstall method: %s" % self.buildinstall_method
)
for variant, cmd in commands:
self.pool.add(BuildinstallThread(self.pool))
self.pool.queue_put(
(self.compose, arch, variant, cmd, self.pkgset_phase)
)
self.pool.start()
def succeeded(self, variant, arch):
# If the phase is skipped, we can treat it as successful. Either there
# will be no output, or it's a debug run of compose where anything can
# happen.
return (
super(BuildinstallPhase, self).skip()
or (variant.uid if self.used_lorax else None, arch)
in self.pool.finished_tasks
)
def reused(self, variant, arch):
"""
Check if buildinstall phase reused previous results for given variant
and arch. If the phase is skipped, the results will be considered
reused as well.
"""
return (
super(BuildinstallPhase, self).skip()
or (variant.uid if self.used_lorax else None, arch)
in self.pool.reused_tasks
)
def get_kickstart_file(compose):
scm_dict = compose.conf.get("buildinstall_kickstart")
if not scm_dict:
compose.log_debug("Path to ks.cfg (buildinstall_kickstart) not specified.")
return
msg = "Getting ks.cfg"
kickstart_path = os.path.join(compose.paths.work.topdir(arch="global"), "ks.cfg")
if os.path.exists(kickstart_path):
compose.log_warning("[SKIP ] %s" % msg)
return kickstart_path
compose.log_info("[BEGIN] %s" % msg)
if isinstance(scm_dict, dict):
kickstart_name = os.path.basename(scm_dict["file"])
if scm_dict["scm"] == "file":
scm_dict["file"] = os.path.join(compose.config_dir, scm_dict["file"])
else:
kickstart_name = os.path.basename(scm_dict)
scm_dict = os.path.join(compose.config_dir, scm_dict)
tmp_dir = compose.mkdtemp(prefix="buildinstall_kickstart_")
get_file_from_scm(scm_dict, tmp_dir, compose=compose)
src = os.path.join(tmp_dir, kickstart_name)
shutil.copy2(src, kickstart_path)
compose.log_info("[DONE ] %s" % msg)
return kickstart_path
BOOT_CONFIGS = [
"isolinux/isolinux.cfg",
"etc/yaboot.conf",
"ppc/ppc64/yaboot.conf",
"EFI/BOOT/BOOTX64.conf",
"EFI/BOOT/grub.cfg",
]
BOOT_IMAGES = [
"images/efiboot.img",
]
def tweak_configs(path, volid, ks_file, configs=BOOT_CONFIGS, logger=None):
"""
Put escaped volume ID and possibly kickstart file into the boot
configuration files.
:returns: list of paths to modified config files
"""
volid_escaped = volid.replace(" ", r"\x20").replace("\\", "\\\\")
volid_escaped_2 = volid_escaped.replace("\\", "\\\\")
found_configs = []
for config in configs:
config_path = os.path.join(path, config)
if not os.path.exists(config_path):
continue
with open(config_path, "r") as f:
data = original_data = f.read()
os.unlink(config_path) # break hadlink by removing file writing a new one
# double-escape volid in yaboot.conf
new_volid = volid_escaped_2 if "yaboot" in config else volid_escaped
ks = (" inst.ks=hd:LABEL=%s:/ks.cfg" % new_volid) if ks_file else ""
# pre-f18
data = re.sub(r":CDLABEL=[^ \n]*", r":CDLABEL=%s%s" % (new_volid, ks), data)
# f18+
data = re.sub(r":LABEL=[^ \n]*", r":LABEL=%s%s" % (new_volid, ks), data)
data = re.sub(r"(search .* -l) '[^'\n]*'", r"\1 '%s'" % volid, data)
with open(config_path, "w") as f:
f.write(data)
if data != original_data:
found_configs.append(config)
if logger:
# Generally lorax should create file with correct volume id
# already. If we don't have a kickstart, this function should
# be a no-op.
logger.info("Boot config %s changed" % config_path)
return found_configs
# HACK: this is a hack!
# * it's quite trivial to replace volids
# * it's not easy to replace menu titles
# * we probably need to get this into lorax
def tweak_buildinstall(
compose, src, dst, arch, variant, label, volid, kickstart_file=None
):
tmp_dir = compose.mkdtemp(prefix="tweak_buildinstall_")
# verify src
if not os.path.isdir(src):
raise OSError(errno.ENOENT, "Directory does not exist: %s" % src)
# create dst
try:
os.makedirs(dst)
except OSError as ex:
if ex.errno != errno.EEXIST:
raise
# copy src to temp
# TODO: place temp on the same device as buildinstall dir so we can hardlink
cmd = "cp -dRv --preserve=mode,links,timestamps --remove-destination %s/* %s/" % (
shlex_quote(src),
shlex_quote(tmp_dir),
)
run(cmd)
found_configs = tweak_configs(
tmp_dir, volid, kickstart_file, logger=compose._logger
)
if kickstart_file and found_configs:
shutil.copy2(kickstart_file, os.path.join(dst, "ks.cfg"))
images = [os.path.join(tmp_dir, img) for img in BOOT_IMAGES]
if found_configs:
for image in images:
if not os.path.isfile(image):
continue
with iso.mount(
image,
logger=compose._logger,
use_guestmount=compose.conf.get("buildinstall_use_guestmount"),
) as mount_tmp_dir:
for config in found_configs:
# Put each modified config file into the image (overwriting the
# original).
config_path = os.path.join(tmp_dir, config)
config_in_image = os.path.join(mount_tmp_dir, config)
if os.path.isfile(config_in_image):
cmd = [
"cp",
"-v",
"--remove-destination",
config_path,
config_in_image,
]
run(cmd)
# HACK: make buildinstall files world readable
run("chmod -R a+rX %s" % shlex_quote(tmp_dir))
# copy temp to dst
cmd = "cp -dRv --preserve=mode,links,timestamps --remove-destination %s/* %s/" % (
shlex_quote(tmp_dir),
shlex_quote(dst),
)
run(cmd)
shutil.rmtree(tmp_dir)
def link_boot_iso(compose, arch, variant, can_fail):
if arch == "src":
return
disc_type = compose.conf["disc_types"].get("boot", "boot")
symlink_isos_to = compose.conf.get("symlink_isos_to")
os_tree = compose.paths.compose.os_tree(arch, variant)
# TODO: find in treeinfo?
boot_iso_path = os.path.join(os_tree, "images", "boot.iso")
if not os.path.isfile(boot_iso_path):
return
msg = "Linking boot.iso (arch: %s, variant: %s)" % (arch, variant)
filename = compose.get_image_name(
arch, variant, disc_type=disc_type, disc_num=None, suffix=".iso"
)
new_boot_iso_path = compose.paths.compose.iso_path(
arch, variant, filename, symlink_to=symlink_isos_to
)
new_boot_iso_relative_path = compose.paths.compose.iso_path(
arch, variant, filename, relative=True
)
if os.path.exists(new_boot_iso_path):
# TODO: log
compose.log_warning("[SKIP ] %s" % msg)
return
compose.log_info("[BEGIN] %s" % msg)
# Try to hardlink, and copy if that fails
try:
os.link(boot_iso_path, new_boot_iso_path)
except OSError:
shutil.copy2(boot_iso_path, new_boot_iso_path)
implant_md5 = iso.get_implanted_md5(new_boot_iso_path)
iso_name = os.path.basename(new_boot_iso_path)
iso_dir = os.path.dirname(new_boot_iso_path)
# create iso manifest
run(iso.get_manifest_cmd(iso_name), workdir=iso_dir)
img = Image(compose.im)
img.path = new_boot_iso_relative_path
img.mtime = get_mtime(new_boot_iso_path)
img.size = get_file_size(new_boot_iso_path)
img.arch = arch
img.type = "boot"
img.format = "iso"
img.disc_number = 1
img.disc_count = 1
img.bootable = True
img.subvariant = variant.uid
img.implant_md5 = implant_md5
setattr(img, "can_fail", can_fail)
setattr(img, "deliverable", "buildinstall")
try:
img.volume_id = iso.get_volume_id(
new_boot_iso_path,
compose.conf.get("createiso_use_xorrisofs"),
)
except RuntimeError:
pass
# In this phase we should add to compose only the images that
# will be used only as netinstall.
# On this step lorax generates environment
# for creating isos and create them.
# On step `extra_isos` we overwrite the not needed iso `boot Minimal` by
# new iso. It already contains necessary packages from incldued variants.
if variant.uid in compose.conf['netinstall_variants']:
compose.im.add(variant.uid, arch, img)
compose.log_info("[DONE ] %s" % msg)
class BuildinstallThread(WorkerThread):
def process(self, item, num):
# The variant is None unless lorax is used as buildinstall method.
compose, arch, variant, cmd, pkgset_phase = item
can_fail = compose.can_fail(variant, arch, "buildinstall")
with failable(compose, can_fail, variant, arch, "buildinstall"):
try:
self.worker(compose, arch, variant, cmd, pkgset_phase, num)
except RuntimeError:
self._print_depsolve_error(compose, arch, variant)
raise
def _print_depsolve_error(self, compose, arch, variant):
try:
log_file = os.path.join(_get_log_dir(compose, variant, arch), "pylorax.log")
with open(log_file) as f:
matched = False
for line in f:
if re.match("Dependency check failed", line):
matched = True
if matched:
compose.log_error(line.rstrip())
except Exception:
pass
def _generate_buildinstall_metadata(
self, compose, arch, variant, cmd, buildroot_rpms, pkgset_phase
):
"""
Generate buildinstall.metadata dict.
:param Compose compose: Current compose.
:param str arch: Current architecture.
:param Variant variant: Compose variant.
:param list cmd: List of command line arguments passed to buildinstall task.
:param list buildroot_rpms: List of NVRAs of all RPMs installed in the
buildinstall task's buildroot.
:param PkgsetPhase pkgset_phase: Package set phase instance.
:return: The buildinstall.metadata dict.
"""
# Load the list of packages installed in the boot.iso.
# The list of installed packages is logged by Lorax in the "pkglists"
# directory. There is one file for each installed RPM and the name
# of the file is the name of the RPM.
# We need to resolve the name of each RPM back to its NVRA.
installed_rpms = []
log_fname = "buildinstall-%s-logs/dummy" % variant.uid
log_dir = os.path.dirname(compose.paths.log.log_file(arch, log_fname, False))
pkglists_dir = os.path.join(log_dir, "pkglists")
if os.path.exists(pkglists_dir):
for pkg_name in os.listdir(pkglists_dir):
for pkgset in pkgset_phase.package_sets:
global_pkgset = pkgset["global"]
# We actually do not care from which package_set the RPM
# came from or if there are multiple versions/release of
# the single RPM in more packages sets. We simply include
# all RPMs with this name in the metadata.
# Later when deciding if the buildinstall phase results
# can be reused, we check that all the RPMs with this name
# are still the same in old/new compose.
for rpm_path, rpm_obj in global_pkgset.file_cache.items():
if rpm_obj.name == pkg_name:
installed_rpms.append(rpm_path)
# Store the metadata in `buildinstall.metadata`.
metadata = {
"cmd": cmd,
"buildroot_rpms": sorted(buildroot_rpms),
"installed_rpms": sorted(installed_rpms),
}
return metadata
def _write_buildinstall_metadata(
self, compose, arch, variant, cmd, buildroot_rpms, pkgset_phase
):
"""
Write buildinstall.metadata file containing all the information about
buildinstall phase input and environment.
This file is later used to decide whether old buildinstall results can
be reused instead of generating them again.
:param Compose compose: Current compose.
:param str arch: Current architecture.
:param Variant variant: Compose variant.
:param list cmd: List of command line arguments passed to buildinstall task.
:param list buildroot_rpms: List of NVRAs of all RPMs installed in the
buildinstall task's buildroot.
:param PkgsetPhase pkgset_phase: Package set phase instance.
"""
# Generate the list of `*-RPMs` log file.
log_filename = ("buildinstall-%s" % variant.uid) if variant else "buildinstall"
log_file = compose.paths.log.log_file(arch, log_filename + "-RPMs")
with open(log_file, "w") as f:
f.write("\n".join(buildroot_rpms))
# Write buildinstall.metadata only if particular variant is defined.
# The `variant` is `None` only if old "buildinstall" method is used.
if not variant:
return
metadata = self._generate_buildinstall_metadata(
compose, arch, variant, cmd, buildroot_rpms, pkgset_phase
)
log_fname = "buildinstall-%s-logs/dummy" % variant.uid
log_dir = os.path.dirname(compose.paths.log.log_file(arch, log_fname))
metadata_path = os.path.join(log_dir, "buildinstall.metadata")
with open(metadata_path, "wb") as f:
pickle.dump(metadata, f, protocol=pickle.HIGHEST_PROTOCOL)
def _load_old_buildinstall_metadata(self, compose, arch, variant):
"""
Helper method to load "buildinstall.metadata" from old compose.
:param Compose compose: Current compose.
:param str arch: Current architecture.
:param Variant variant: Compose variant.
"""
if not variant:
return None
log_fname = "buildinstall-%s-logs/dummy" % variant.uid
metadata = os.path.join(
os.path.dirname(compose.paths.log.log_file(arch, log_fname)),
"buildinstall.metadata",
)
old_metadata = compose.paths.old_compose_path(metadata)
if not old_metadata:
return None
compose.log_info("Loading old BUILDINSTALL phase metadata: %s", old_metadata)
try:
with open(old_metadata, "rb") as f:
old_result = pickle.load(f)
return old_result
except Exception as e:
compose.log_debug(
"Failed to load old BUILDINSTALL phase metadata %s : %s"
% (old_metadata, str(e))
)
return None
def _reuse_old_buildinstall_result(self, compose, arch, variant, cmd, pkgset_phase):
"""
Try to reuse old buildinstall results.
:param Compose compose: Current compose.
:param str arch: Current architecture.
:param Variant variant: Compose variant.
:param list cmd: List of command line arguments passed to buildinstall task.
:param list buildroot_rpms: List of NVRAs of all RPMs installed in the
buildinstall task's buildroot.
:param PkgsetPhase pkgset_phase: Package set phase instance.
:return: True if old buildinstall phase results have been reused.
"""
log_msg = "Cannot reuse old BUILDINSTALL phase results - %s"
if not compose.conf["buildinstall_allow_reuse"]:
compose.log_info(log_msg % "reuse of old buildinstall results is disabled.")
return
# Load the old buildinstall.metadata.
old_metadata = self._load_old_buildinstall_metadata(compose, arch, variant)
if old_metadata is None:
compose.log_info(log_msg % "no old BUILDINSTALL metadata.")
return
# For now try to reuse only if pungi_buildinstall plugin is used.
# This is the easiest approach, because we later need to filter out
# some parts of `cmd` and for pungi_buildinstall, the `cmd` is a dict
# which makes this easy.
if not isinstance(old_metadata["cmd"], dict) or not isinstance(cmd, dict):
compose.log_info(log_msg % "pungi_buildinstall plugin is not used.")
return
# Filter out "outputdir" and "sources" because they change every time.
# The "sources" are not important, because we check the buildinstall
# input on RPM level.
cmd_copy = copy(cmd)
for key in ["outputdir", "sources"]:
cmd_copy.pop(key, None)
old_metadata["cmd"].pop(key, None)
# Do not reuse if command line arguments are not the same.
if old_metadata["cmd"] != cmd_copy:
compose.log_info(log_msg % "lorax command line arguments differ.")
return
# Check that the RPMs installed in the old boot.iso exists in the very
# same versions/releases in this compose.
for rpm_path in old_metadata["installed_rpms"]:
found = False
for pkgset in pkgset_phase.package_sets:
global_pkgset = pkgset["global"]
if rpm_path in global_pkgset.file_cache:
found = True
break
if not found:
compose.log_info(
log_msg % "RPM %s does not exist in new compose." % rpm_path
)
return
# Ask Koji for all the RPMs in the `runroot_tag` and check that
# those installed in the old buildinstall buildroot are still in the
# very same versions/releases.
koji_wrapper = kojiwrapper.KojiWrapper(compose)
rpms = koji_wrapper.koji_proxy.listTaggedRPMS(
compose.conf.get("runroot_tag"), inherit=True, latest=True
)[0]
rpm_nvras = set()
for rpm in rpms:
rpm_nvras.add(kobo.rpmlib.make_nvra(rpm, add_rpm=False, force_epoch=False))
for old_nvra in old_metadata["buildroot_rpms"]:
if old_nvra not in rpm_nvras:
compose.log_info(
log_msg % "RPM %s does not exist in new buildroot." % old_nvra
)
return
# We can reuse the old buildinstall results!
compose.log_info("Reusing old BUILDINSTALL phase output")
# Copy old buildinstall output to this this compose.
final_output_dir = compose.paths.work.buildinstall_dir(arch, variant=variant)
old_final_output_dir = compose.paths.old_compose_path(final_output_dir)
copy_all(old_final_output_dir, final_output_dir)
# Copy old buildinstall logs to this compose.
log_fname = "buildinstall-%s-logs/dummy" % variant.uid
final_log_dir = os.path.dirname(compose.paths.log.log_file(arch, log_fname))
old_final_log_dir = compose.paths.old_compose_path(final_log_dir)
if not os.path.exists(final_log_dir):
makedirs(final_log_dir)
copy_all(old_final_log_dir, final_log_dir)
# Write the buildinstall metadata so next compose can reuse this compose.
self._write_buildinstall_metadata(
compose, arch, variant, cmd, old_metadata["buildroot_rpms"], pkgset_phase
)
return True
def worker(self, compose, arch, variant, cmd, pkgset_phase, num):
buildinstall_method = compose.conf["buildinstall_method"]
lorax_use_koji_plugin = compose.conf["lorax_use_koji_plugin"]
log_filename = ("buildinstall-%s" % variant.uid) if variant else "buildinstall"
log_file = compose.paths.log.log_file(arch, log_filename)
msg = "Running buildinstall for arch %s, variant %s" % (arch, variant)
output_dir = compose.paths.work.buildinstall_dir(
arch, allow_topdir_override=True, variant=variant
)
final_output_dir = compose.paths.work.buildinstall_dir(arch, variant=variant)
if (
os.path.isdir(output_dir)
and os.listdir(output_dir)
or os.path.isdir(final_output_dir)
and os.listdir(final_output_dir)
):
# output dir is *not* empty -> SKIP
self.pool.log_warning(
"[SKIP ] Buildinstall for arch %s, variant %s" % (arch, variant)
)
return
self.pool.log_info("[BEGIN] %s" % msg)
# Get list of packages which are needed in runroot.
packages = []
chown_paths = [output_dir]
if buildinstall_method == "lorax":
packages += ["lorax"]
chown_paths.append(_get_log_dir(compose, variant, arch))
packages += get_arch_variant_data(
compose.conf, "buildinstall_packages", arch, variant
)
if self._reuse_old_buildinstall_result(
compose, arch, variant, cmd, pkgset_phase
):
self.copy_files(compose, variant, arch)
self.pool.finished_tasks.add((variant.uid if variant else None, arch))
self.pool.reused_tasks.add((variant.uid if variant else None, arch))
self.pool.log_info("[DONE ] %s" % msg)
return
# This should avoid a possible race condition with multiple processes
# trying to get a kerberos ticket at the same time.
# Kerberos authentication failed:
# Permission denied in replay cache code (-1765328215)
time.sleep(num * 3)
# Start the runroot task.
runroot = Runroot(compose, phase="buildinstall")
task_id = None
if buildinstall_method == "lorax" and lorax_use_koji_plugin:
task_id = runroot.run_pungi_buildinstall(
cmd,
log_file=log_file,
arch=arch,
packages=packages,
weight=compose.conf["runroot_weights"].get("buildinstall"),
)
else:
try:
lorax_log_dir = _get_log_dir(compose, variant, arch)
except Exception:
lorax_log_dir = None
runroot.run(
cmd,
log_file=log_file,
arch=arch,
packages=packages,
mounts=[compose.topdir],
weight=compose.conf["runroot_weights"].get("buildinstall"),
chown_paths=chown_paths,
log_dir=lorax_log_dir,
)
if final_output_dir != output_dir:
if not os.path.exists(final_output_dir):
makedirs(final_output_dir)
results_dir = os.path.join(output_dir, "results")
copy_all(results_dir, final_output_dir)
# Get the log_dir into which we should copy the resulting log files.
log_fname = "buildinstall-%s-logs/dummy" % variant.uid
final_log_dir = os.path.dirname(compose.paths.log.log_file(arch, log_fname))
if not os.path.exists(final_log_dir):
makedirs(final_log_dir)
log_dir = os.path.join(output_dir, "logs")
copy_all(log_dir, final_log_dir)
elif lorax_use_koji_plugin:
# If Koji pungi-buildinstall is used, then the buildinstall results
# are attached as outputs to the Koji task. Download and unpack
# them to the correct location.
download_and_extract_archive(
compose, task_id, "results.tar.gz", final_output_dir
)
# Download the logs into proper location too.
log_fname = "buildinstall-%s-logs/dummy" % variant.uid
final_log_dir = os.path.dirname(compose.paths.log.log_file(arch, log_fname))
download_and_extract_archive(compose, task_id, "logs.tar.gz", final_log_dir)
rpms = runroot.get_buildroot_rpms()
self._write_buildinstall_metadata(
compose, arch, variant, cmd, rpms, pkgset_phase
)
self.copy_files(compose, variant, arch)
self.pool.finished_tasks.add((variant.uid if variant else None, arch))
self.pool.log_info("[DONE ] %s" % msg)
def copy_files(self, compose, variant, arch):
disc_type = compose.conf["disc_types"].get("dvd", "dvd")
buildinstall_dir = compose.paths.work.buildinstall_dir(arch)
# Lorax runs per-variant, so we need to tweak the source path
# to include variant.
if variant:
buildinstall_dir = os.path.join(buildinstall_dir, variant.uid)
# Find all relevant variants if lorax is not used.
variants = (
[variant]
if variant
else compose.get_variants(arch=arch, types=["self", "variant"])
)
for var in variants:
os_tree = compose.paths.compose.os_tree(arch, var)
# TODO: label is not used
label = ""
volid = get_volid(compose, arch, var, disc_type=disc_type)
can_fail = compose.can_fail(var, arch, "buildinstall")
tweak_buildinstall(
compose,
buildinstall_dir,
os_tree,
arch,
var.uid,
label,
volid,
self.pool.kickstart_file,
)
link_boot_iso(compose, arch, var, can_fail)
def _get_log_dir(compose, variant, arch):
"""Find directory where to store lorax logs in. If it's inside the compose,
create the directory.
"""
if compose.conf.get("buildinstall_topdir"):
log_dir = compose.paths.work.buildinstall_dir(
arch, allow_topdir_override=True, variant=variant
)
return os.path.join(log_dir, "logs")
# The paths module will modify the filename (by inserting arch). But we
# only care about the directory anyway.
log_filename = "buildinstall-%s-logs/dummy" % variant.uid
log_dir = os.path.dirname(compose.paths.log.log_file(arch, log_filename))
makedirs(log_dir)
return log_dir

932
pungi/phases/createiso.py Normal file
View File

@ -0,0 +1,932 @@
# -*- coding: utf-8 -*-
# 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; version 2 of the License.
#
# 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 Library General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, see <https://gnu.org/licenses/>.
import itertools
import os
import random
import shutil
import stat
import json
import productmd.treeinfo
from productmd.images import Image
from kobo.threads import ThreadPool, WorkerThread
from kobo.shortcuts import run, relative_path, compute_file_checksums
from six.moves import shlex_quote
from pungi.wrappers import iso
from pungi.wrappers.createrepo import CreaterepoWrapper
from pungi.wrappers import kojiwrapper
from pungi.phases.base import PhaseBase, PhaseLoggerMixin
from pungi.util import (
makedirs,
get_volid,
get_arch_variant_data,
failable,
get_file_size,
get_mtime,
read_json_file,
)
from pungi.media_split import MediaSplitter, convert_media_size
from pungi.compose_metadata.discinfo import read_discinfo, write_discinfo
from pungi.runroot import Runroot
from .. import createiso
class CreateisoPhase(PhaseLoggerMixin, PhaseBase):
name = "createiso"
def __init__(self, compose, buildinstall_phase):
super(CreateisoPhase, self).__init__(compose)
self.pool = ThreadPool(logger=self.logger)
self.bi = buildinstall_phase
def _find_rpms(self, path):
"""Check if there are some RPMs in the path."""
for _, _, files in os.walk(path):
for fn in files:
if fn.endswith(".rpm"):
return True
return False
def _is_bootable(self, variant, arch):
if arch == "src":
return False
if variant.type != "variant":
return False
skip = get_arch_variant_data(
self.compose.conf, "buildinstall_skip", arch, variant
)
if skip == [True]:
# Buildinstall is skipped for this tree. Can't create a bootable ISO.
return False
return bool(self.compose.conf.get("buildinstall_method", ""))
def _metadata_path(self, variant, arch, disc_num, disc_count):
return self.compose.paths.log.log_file(
arch,
"createiso-%s-%d-%d" % (variant.uid, disc_num, disc_count),
ext="json",
)
def save_reuse_metadata(self, cmd, variant, arch, opts):
"""Save metadata for future composes to verify if the compose can be reused."""
metadata = {
"cmd": cmd,
"opts": opts._asdict(),
}
metadata_path = self._metadata_path(
variant, arch, cmd["disc_num"], cmd["disc_count"]
)
with open(metadata_path, "w") as f:
json.dump(metadata, f, indent=2)
return metadata
def _load_old_metadata(self, cmd, variant, arch):
metadata_path = self._metadata_path(
variant, arch, cmd["disc_num"], cmd["disc_count"]
)
old_path = self.compose.paths.old_compose_path(metadata_path)
self.logger.info(
"Loading old metadata for %s.%s from: %s", variant, arch, old_path
)
try:
return read_json_file(old_path)
except Exception:
return None
def perform_reuse(self, cmd, variant, arch, opts, iso_path):
"""
Copy all related files from old compose to the new one. As a last step
add the new image to metadata.
"""
linker = OldFileLinker(self.logger)
old_file_name = os.path.basename(iso_path)
current_file_name = os.path.basename(cmd["iso_path"])
try:
# Hardlink ISO and manifest
for suffix in ("", ".manifest"):
linker.link(iso_path + suffix, cmd["iso_path"] + suffix)
# Copy log files
# The log file name includes filename of the image, so we need to
# find old file with the old name, and rename it to the new name.
log_file = self.compose.paths.log.log_file(
arch, "createiso-%s" % current_file_name
)
old_log_file = self.compose.paths.old_compose_path(
self.compose.paths.log.log_file(arch, "createiso-%s" % old_file_name)
)
linker.link(old_log_file, log_file)
# Copy jigdo files
if opts.jigdo_dir:
old_jigdo_dir = self.compose.paths.old_compose_path(opts.jigdo_dir)
for suffix in (".template", ".jigdo"):
linker.link(
os.path.join(old_jigdo_dir, old_file_name) + suffix,
os.path.join(opts.jigdo_dir, current_file_name) + suffix,
)
except Exception:
# A problem happened while linking some file, let's clean up
# everything.
linker.abort()
raise
# Add image to manifest
add_iso_to_metadata(
self.compose,
variant,
arch,
cmd["iso_path"],
bootable=cmd["bootable"],
disc_num=cmd["disc_num"],
disc_count=cmd["disc_count"],
)
if self.compose.notifier:
self.compose.notifier.send(
"createiso-imagedone",
file=cmd["iso_path"],
arch=arch,
variant=str(variant),
)
def try_reuse(self, cmd, variant, arch, opts):
"""Try to reuse image from previous compose.
:returns bool: True if reuse was successful, False otherwise
"""
if not self.compose.conf["createiso_allow_reuse"]:
return
log_msg = "Cannot reuse ISO for %s.%s" % (variant, arch)
current_metadata = self.save_reuse_metadata(cmd, variant, arch, opts)
if opts.buildinstall_method and not self.bi.reused(variant, arch):
# If buildinstall phase was not reused for some reason, we can not
# reuse any bootable image. If a package change caused rebuild of
# boot.iso, we would catch it here too, but there could be a
# configuration change in lorax template which would remain
# undetected.
self.logger.info("%s - boot configuration changed", log_msg)
return False
# Check old compose configuration: extra_files and product_ids can be
# reflected on ISO.
old_config = self.compose.load_old_compose_config()
if not old_config:
self.logger.info("%s - no config for old compose", log_msg)
return False
# Disable reuse if unsigned packages are allowed. The older compose
# could have unsigned packages, and those may have been signed since
# then. We want to regenerate the ISO to have signatures.
if None in self.compose.conf["sigkeys"]:
self.logger.info("%s - unsigned packages are allowed", log_msg)
return False
# Convert current configuration to JSON and back to encode it similarly
# to the old one
config = json.loads(json.dumps(self.compose.conf))
for opt in self.compose.conf:
# Skip a selection of options: these affect what packages can be
# included, which we explicitly check later on.
config_whitelist = set(
[
"gather_lookaside_repos",
"pkgset_koji_builds",
"pkgset_koji_scratch_tasks",
"pkgset_koji_module_builds",
]
)
# Skip irrelevant options
config_whitelist.update(["osbs", "osbuild"])
if opt in config_whitelist:
continue
if old_config.get(opt) != config.get(opt):
self.logger.info("%s - option %s differs", log_msg, opt)
return False
old_metadata = self._load_old_metadata(cmd, variant, arch)
if not old_metadata:
self.logger.info("%s - no old metadata found", log_msg)
return False
# Test if volume ID matches - volid can be generated dynamically based on
# other values, and could change even if nothing else is different.
if current_metadata["opts"]["volid"] != old_metadata["opts"]["volid"]:
self.logger.info("%s - volume ID differs", log_msg)
return False
# Compare packages on the ISO.
if compare_packages(
old_metadata["opts"]["graft_points"],
current_metadata["opts"]["graft_points"],
):
self.logger.info("%s - packages differ", log_msg)
return False
try:
self.perform_reuse(
cmd,
variant,
arch,
opts,
old_metadata["cmd"]["iso_path"],
)
return True
except Exception as exc:
self.compose.log_error(
"Error while reusing ISO for %s.%s: %s", variant, arch, exc
)
self.compose.traceback("createiso-reuse-%s-%s" % (variant, arch))
return False
def run(self):
symlink_isos_to = self.compose.conf.get("symlink_isos_to")
disc_type = self.compose.conf["disc_types"].get("dvd", "dvd")
deliverables = []
commands = []
for variant in self.compose.get_variants(
types=["variant", "layered-product", "optional"]
):
if variant.is_empty:
continue
for arch in variant.arches + ["src"]:
skip_iso = get_arch_variant_data(
self.compose.conf, "createiso_skip", arch, variant
)
if skip_iso == [True]:
self.logger.info(
"Skipping createiso for %s.%s due to config option"
% (variant, arch)
)
continue
volid = get_volid(self.compose, arch, variant, disc_type=disc_type)
os_tree = self.compose.paths.compose.os_tree(arch, variant)
iso_dir = self.compose.paths.compose.iso_dir(
arch, variant, symlink_to=symlink_isos_to
)
if not iso_dir:
continue
if not self._find_rpms(os_tree):
self.logger.warning(
"No RPMs found for %s.%s, skipping ISO" % (variant.uid, arch)
)
continue
bootable = self._is_bootable(variant, arch)
if bootable and not self.bi.succeeded(variant, arch):
self.logger.warning(
"ISO should be bootable, but buildinstall failed. "
"Skipping for %s.%s" % (variant, arch)
)
continue
split_iso_data = split_iso(
self.compose, arch, variant, no_split=bootable, logger=self.logger
)
disc_count = len(split_iso_data)
for disc_num, iso_data in enumerate(split_iso_data):
disc_num += 1
filename = self.compose.get_image_name(
arch, variant, disc_type=disc_type, disc_num=disc_num
)
iso_path = self.compose.paths.compose.iso_path(
arch, variant, filename, symlink_to=symlink_isos_to
)
if os.path.isfile(iso_path):
self.logger.warning(
"Skipping mkisofs, image already exists: %s", iso_path
)
continue
deliverables.append(iso_path)
graft_points = prepare_iso(
self.compose,
arch,
variant,
disc_num=disc_num,
disc_count=disc_count,
split_iso_data=iso_data,
)
cmd = {
"iso_path": iso_path,
"bootable": bootable,
"cmd": [],
"label": "", # currently not used
"disc_num": disc_num,
"disc_count": disc_count,
}
if os.path.islink(iso_dir):
cmd["mount"] = os.path.abspath(
os.path.join(os.path.dirname(iso_dir), os.readlink(iso_dir))
)
opts = createiso.CreateIsoOpts(
output_dir=iso_dir,
iso_name=filename,
volid=volid,
graft_points=graft_points,
arch=arch,
supported=self.compose.supported,
hfs_compat=self.compose.conf["iso_hfs_ppc64le_compatible"],
use_xorrisofs=self.compose.conf.get("createiso_use_xorrisofs"),
iso_level=get_iso_level_config(self.compose, variant, arch),
)
if bootable:
opts = opts._replace(
buildinstall_method=self.compose.conf[
"buildinstall_method"
],
boot_iso=os.path.join(os_tree, "images", "boot.iso"),
)
if self.compose.conf["create_jigdo"]:
jigdo_dir = self.compose.paths.compose.jigdo_dir(arch, variant)
opts = opts._replace(jigdo_dir=jigdo_dir, os_tree=os_tree)
# Try to reuse
if self.try_reuse(cmd, variant, arch, opts):
# Reuse was successful, go to next ISO
continue
script_dir = self.compose.paths.work.tmp_dir(arch, variant)
opts = opts._replace(script_dir=script_dir)
script_file = os.path.join(script_dir, "createiso-%s.sh" % filename)
with open(script_file, "w") as f:
createiso.write_script(opts, f)
cmd["cmd"] = ["bash", script_file]
commands.append((cmd, variant, arch))
if self.compose.notifier:
self.compose.notifier.send("createiso-targets", deliverables=deliverables)
for cmd, variant, arch in commands:
self.pool.add(CreateIsoThread(self.pool))
self.pool.queue_put((self.compose, cmd, variant, arch))
self.pool.start()
def read_packages(graft_points):
"""Read packages that were listed in given graft points file.
Only files under Packages directory are considered. Particularly this
excludes .discinfo, .treeinfo and media.repo as well as repodata and
any extra files.
Extra files are easier to check by configuration (same name doesn't
imply same content). Repodata depend entirely on included packages (and
possibly product id certificate), but are affected by current time
which can change checksum despite data being the same.
"""
with open(graft_points) as f:
return set(
line.split("=", 1)[0]
for line in f
if line.startswith("Packages/") or "/Packages/" in line
)
def compare_packages(old_graft_points, new_graft_points):
"""Read packages from the two files and compare them.
:returns bool: True if there are differences, False otherwise
"""
old_files = read_packages(old_graft_points)
new_files = read_packages(new_graft_points)
return old_files != new_files
class CreateIsoThread(WorkerThread):
def fail(self, compose, cmd, variant, arch):
self.pool.log_error("CreateISO failed, removing ISO: %s" % cmd["iso_path"])
try:
# remove incomplete ISO
os.unlink(cmd["iso_path"])
# TODO: remove jigdo & template
except OSError:
pass
if compose.notifier:
compose.notifier.send(
"createiso-imagefail",
file=cmd["iso_path"],
arch=arch,
variant=str(variant),
)
def process(self, item, num):
compose, cmd, variant, arch = item
can_fail = compose.can_fail(variant, arch, "iso")
with failable(
compose, can_fail, variant, arch, "iso", logger=self.pool._logger
):
self.worker(compose, cmd, variant, arch, num)
def worker(self, compose, cmd, variant, arch, num):
mounts = [compose.topdir]
if "mount" in cmd:
mounts.append(cmd["mount"])
bootable = cmd["bootable"]
log_file = compose.paths.log.log_file(
arch, "createiso-%s" % os.path.basename(cmd["iso_path"])
)
msg = "Creating ISO (arch: %s, variant: %s): %s" % (
arch,
variant,
os.path.basename(cmd["iso_path"]),
)
self.pool.log_info("[BEGIN] %s" % msg)
try:
run_createiso_command(
num,
compose,
bootable,
arch,
cmd["cmd"],
mounts,
log_file,
cmd["iso_path"],
)
except Exception:
self.fail(compose, cmd, variant, arch)
raise
add_iso_to_metadata(
compose,
variant,
arch,
cmd["iso_path"],
cmd["bootable"],
cmd["disc_num"],
cmd["disc_count"],
)
# Delete staging directory if present.
staging_dir = compose.paths.work.iso_staging_dir(
arch, variant, filename=os.path.basename(cmd["iso_path"]), create_dir=False
)
if os.path.exists(staging_dir):
try:
shutil.rmtree(staging_dir)
except Exception as e:
self.pool.log_warning(
"Failed to clean up staging dir: %s %s" % (staging_dir, str(e))
)
self.pool.log_info("[DONE ] %s" % msg)
if compose.notifier:
compose.notifier.send(
"createiso-imagedone",
file=cmd["iso_path"],
arch=arch,
variant=str(variant),
)
def add_iso_to_metadata(
compose,
variant,
arch,
iso_path,
bootable,
disc_num=1,
disc_count=1,
additional_variants=None,
):
img = Image(compose.im)
img.path = iso_path.replace(compose.paths.compose.topdir(), "").lstrip("/")
img.mtime = get_mtime(iso_path)
img.size = get_file_size(iso_path)
img.arch = arch
# XXX: HARDCODED
img.type = "dvd"
img.format = "iso"
img.disc_number = disc_num
img.disc_count = disc_count
img.bootable = bootable
img.subvariant = variant.uid
img.implant_md5 = iso.get_implanted_md5(iso_path, logger=compose._logger)
if additional_variants:
img.unified = True
img.additional_variants = additional_variants
setattr(img, "can_fail", compose.can_fail(variant, arch, "iso"))
setattr(img, "deliverable", "iso")
try:
img.volume_id = iso.get_volume_id(
iso_path,
compose.conf.get("createiso_use_xorrisofs"),
)
except RuntimeError:
pass
if arch == "src":
for variant_arch in variant.arches:
compose.im.add(variant.uid, variant_arch, img)
else:
compose.im.add(variant.uid, arch, img)
return img
def run_createiso_command(
num, compose, bootable, arch, cmd, mounts, log_file, iso_path
):
packages = [
"coreutils",
"xorriso" if compose.conf.get("createiso_use_xorrisofs") else "genisoimage",
"isomd5sum",
]
if compose.conf["create_jigdo"]:
packages.append("jigdo")
if bootable:
extra_packages = {
"lorax": ["lorax", "which"],
}
packages.extend(extra_packages[compose.conf["buildinstall_method"]])
runroot = Runroot(compose, phase="createiso")
build_arch = arch
if runroot.runroot_method == "koji" and not bootable:
runroot_tag = compose.conf["runroot_tag"]
koji_wrapper = kojiwrapper.KojiWrapper(compose)
koji_proxy = koji_wrapper.koji_proxy
tag_info = koji_proxy.getTag(runroot_tag)
if not tag_info:
raise RuntimeError('Tag "%s" does not exist.' % runroot_tag)
tag_arches = tag_info["arches"].split(" ")
if "x86_64" in tag_arches:
# assign non-bootable images to x86_64 if possible
build_arch = "x86_64"
elif build_arch == "src":
# pick random arch from available runroot tag arches
build_arch = random.choice(tag_arches)
runroot.run(
cmd,
log_file=log_file,
arch=build_arch,
packages=packages,
mounts=mounts,
weight=compose.conf["runroot_weights"].get("createiso"),
)
if bootable and compose.conf.get("createiso_use_xorrisofs"):
fix_treeinfo_checksums(compose, iso_path, arch)
def fix_treeinfo_checksums(compose, iso_path, arch):
"""It is possible for the ISO to contain a .treefile with incorrect
checksums. By modifying the ISO (adding files) some of the images may
change.
This function fixes that after the fact by looking for incorrect checksums,
recalculating them and updating the .treeinfo file. Since the size of the
file doesn't change, this seems to not change any images.
"""
modified = False
with iso.mount(iso_path, compose._logger) as mountpoint:
ti = productmd.TreeInfo()
ti.load(os.path.join(mountpoint, ".treeinfo"))
for image, (type_, expected) in ti.checksums.checksums.items():
checksums = compute_file_checksums(os.path.join(mountpoint, image), [type_])
actual = checksums[type_]
if actual == expected:
# Everything fine here, skip to next image.
continue
compose.log_debug("%s: %s: checksum mismatch", iso_path, image)
# Update treeinfo with correct checksum
ti.checksums.checksums[image] = (type_, actual)
modified = True
if not modified:
compose.log_debug("%s: All checksums match, nothing to do.", iso_path)
return
try:
tmpdir = compose.mkdtemp(arch, prefix="fix-checksum-")
# Write modified .treeinfo
ti_path = os.path.join(tmpdir, ".treeinfo")
compose.log_debug("Storing modified .treeinfo in %s", ti_path)
ti.dump(ti_path)
# Write a modified DVD into a temporary path, that is atomically moved
# over the original file.
fixed_path = os.path.join(tmpdir, "fixed-checksum-dvd.iso")
cmd = ["xorriso"]
cmd.extend(
itertools.chain.from_iterable(
iso.xorriso_commands(arch, iso_path, fixed_path)
)
)
cmd.extend(["-map", ti_path, ".treeinfo"])
run(
cmd,
logfile=compose.paths.log.log_file(
arch, "checksum-fix_generate_%s" % os.path.basename(iso_path)
),
)
# The modified ISO no longer has implanted MD5, so that needs to be
# fixed again.
compose.log_debug("Implanting new MD5 to %s", fixed_path)
run(
iso.get_implantisomd5_cmd(fixed_path, compose.supported),
logfile=compose.paths.log.log_file(
arch, "checksum-fix_implantisomd5_%s" % os.path.basename(iso_path)
),
)
# All done, move the updated image to the final location.
compose.log_debug("Updating %s", iso_path)
os.rename(fixed_path, iso_path)
finally:
shutil.rmtree(tmpdir)
def split_iso(compose, arch, variant, no_split=False, logger=None):
"""
Split contents of the os/ directory for given tree into chunks fitting on ISO.
All files from the directory are taken except for possible boot.iso image.
Files added in extra_files phase are put on all disks.
If `no_split` is set, we will pretend that the media is practically
infinite so that everything goes on single disc. A warning is printed if
the size is bigger than configured.
"""
if not logger:
logger = compose._logger
media_size = compose.conf["iso_size"]
media_reserve = compose.conf["split_iso_reserve"]
split_size = convert_media_size(media_size) - convert_media_size(media_reserve)
real_size = None if no_split else split_size
ms = MediaSplitter(real_size, compose, logger=logger)
os_tree = compose.paths.compose.os_tree(arch, variant)
extra_files_dir = compose.paths.work.extra_files_dir(arch, variant)
# scan extra files to mark them "sticky" -> they'll be on all media after split
extra_files = set(["media.repo"])
for root, dirs, files in os.walk(extra_files_dir):
for fn in files:
path = os.path.join(root, fn)
rel_path = relative_path(path, extra_files_dir.rstrip("/") + "/")
extra_files.add(rel_path)
packages = []
all_files = []
all_files_ignore = []
ti = productmd.treeinfo.TreeInfo()
ti.load(os.path.join(os_tree, ".treeinfo"))
boot_iso_rpath = ti.images.images.get(arch, {}).get("boot.iso", None)
if boot_iso_rpath:
all_files_ignore.append(boot_iso_rpath)
if all_files_ignore:
logger.debug("split_iso all_files_ignore = %s" % ", ".join(all_files_ignore))
for root, dirs, files in os.walk(os_tree):
for dn in dirs[:]:
repo_dir = os.path.join(root, dn)
if repo_dir == os.path.join(
compose.paths.compose.repository(arch, variant), "repodata"
):
dirs.remove(dn)
for fn in files:
path = os.path.join(root, fn)
rel_path = relative_path(path, os_tree.rstrip("/") + "/")
sticky = rel_path in extra_files
if rel_path in all_files_ignore:
logger.info("split_iso: Skipping %s" % rel_path)
continue
if root.startswith(compose.paths.compose.packages(arch, variant)):
packages.append((path, os.path.getsize(path), sticky))
else:
all_files.append((path, os.path.getsize(path), sticky))
for path, size, sticky in all_files + packages:
ms.add_file(path, size, sticky)
logger.debug("Splitting media for %s.%s:" % (variant.uid, arch))
result = ms.split()
if no_split and result[0]["size"] > split_size:
logger.warning(
"ISO for %s.%s does not fit on single media! It is %s bytes too big. "
"(Total size: %s B)"
% (variant.uid, arch, result[0]["size"] - split_size, result[0]["size"])
)
return result
def prepare_iso(
compose, arch, variant, disc_num=1, disc_count=None, split_iso_data=None
):
tree_dir = compose.paths.compose.os_tree(arch, variant)
filename = compose.get_image_name(arch, variant, disc_num=disc_num)
iso_dir = compose.paths.work.iso_dir(arch, filename)
# modify treeinfo
ti_path = os.path.join(tree_dir, ".treeinfo")
ti = load_and_tweak_treeinfo(ti_path, disc_num, disc_count)
copy_boot_images(tree_dir, iso_dir)
if disc_count > 1:
# remove repodata/repomd.xml from checksums, create a new one later
if "repodata/repomd.xml" in ti.checksums.checksums:
del ti.checksums.checksums["repodata/repomd.xml"]
# rebuild repodata
createrepo_c = compose.conf["createrepo_c"]
createrepo_checksum = compose.conf["createrepo_checksum"]
repo = CreaterepoWrapper(createrepo_c=createrepo_c)
file_list = "%s-file-list" % iso_dir
packages_dir = compose.paths.compose.packages(arch, variant)
file_list_content = []
for i in split_iso_data["files"]:
if not i.endswith(".rpm"):
continue
if not i.startswith(packages_dir):
continue
rel_path = relative_path(i, tree_dir.rstrip("/") + "/")
file_list_content.append(rel_path)
if file_list_content:
# write modified repodata only if there are packages available
run("cp -a %s/repodata %s/" % (shlex_quote(tree_dir), shlex_quote(iso_dir)))
with open(file_list, "w") as f:
f.write("\n".join(file_list_content))
cmd = repo.get_createrepo_cmd(
tree_dir,
update=True,
database=True,
skip_stat=True,
pkglist=file_list,
outputdir=iso_dir,
workers=compose.conf["createrepo_num_workers"],
checksum=createrepo_checksum,
)
run(cmd)
# add repodata/repomd.xml back to checksums
ti.checksums.add(
"repodata/repomd.xml", createrepo_checksum, root_dir=iso_dir
)
new_ti_path = os.path.join(iso_dir, ".treeinfo")
ti.dump(new_ti_path)
# modify discinfo
di_path = os.path.join(tree_dir, ".discinfo")
data = read_discinfo(di_path)
data["disc_numbers"] = [disc_num]
new_di_path = os.path.join(iso_dir, ".discinfo")
write_discinfo(new_di_path, **data)
if not disc_count or disc_count == 1:
data = iso.get_graft_points(compose.paths.compose.topdir(), [tree_dir, iso_dir])
else:
data = iso.get_graft_points(
compose.paths.compose.topdir(),
[iso._paths_from_list(tree_dir, split_iso_data["files"]), iso_dir],
)
if compose.conf["createiso_break_hardlinks"]:
compose.log_debug(
"Breaking hardlinks for ISO %s for %s.%s" % (filename, variant, arch)
)
break_hardlinks(
data, compose.paths.work.iso_staging_dir(arch, variant, filename)
)
# Create hardlinks for files with duplicate contents.
compose.log_debug(
"Creating hardlinks for ISO %s for %s.%s" % (filename, variant, arch)
)
create_hardlinks(
compose.paths.work.iso_staging_dir(arch, variant, filename),
log_file=compose.paths.log.log_file(
arch, "iso-hardlink-%s.log" % variant.uid
),
)
# TODO: /content /graft-points
gp = "%s-graft-points" % iso_dir
iso.write_graft_points(gp, data, exclude=["*/lost+found", "*/boot.iso"])
return gp
def load_and_tweak_treeinfo(ti_path, disc_num=1, disc_count=1):
"""Treeinfo on the media should not contain any reference to boot.iso and
it should also have a valid [media] section.
"""
ti = productmd.treeinfo.TreeInfo()
ti.load(ti_path)
ti.media.totaldiscs = disc_count or 1
ti.media.discnum = disc_num
# remove boot.iso from all sections
paths = set()
for platform in ti.images.images:
if "boot.iso" in ti.images.images[platform]:
paths.add(ti.images.images[platform].pop("boot.iso"))
# remove boot.iso from checksums
for i in paths:
if i in ti.checksums.checksums.keys():
del ti.checksums.checksums[i]
return ti
def copy_boot_images(src, dest):
"""When mkisofs is called it tries to modify isolinux/isolinux.bin and
images/boot.img. Therefore we need to make copies of them.
"""
for i in ("isolinux/isolinux.bin", "images/boot.img"):
src_path = os.path.join(src, i)
dst_path = os.path.join(dest, i)
if os.path.exists(src_path):
makedirs(os.path.dirname(dst_path))
shutil.copy2(src_path, dst_path)
def break_hardlinks(graft_points, staging_dir):
"""Iterate over graft points and copy any file that has more than 1
hardlink into the staging directory. Replace the entry in the dict.
"""
for f in graft_points:
info = os.stat(graft_points[f])
if stat.S_ISREG(info.st_mode) and info.st_nlink > 1:
dest_path = os.path.join(staging_dir, graft_points[f].lstrip("/"))
makedirs(os.path.dirname(dest_path))
shutil.copy2(graft_points[f], dest_path)
graft_points[f] = dest_path
def create_hardlinks(staging_dir, log_file):
"""Create hardlinks within the staging directory.
Should happen after break_hardlinks()
"""
cmd = ["/usr/sbin/hardlink", "-c", "-vv", staging_dir]
run(cmd, logfile=log_file, show_cmd=True)
class OldFileLinker(object):
"""
A wrapper around os.link that remembers which files were linked and can
clean them up.
"""
def __init__(self, logger):
self.logger = logger
self.linked_files = []
def link(self, src, dst):
self.logger.debug("Hardlinking %s to %s", src, dst)
os.link(src, dst)
self.linked_files.append(dst)
def abort(self):
"""Clean up all files created by this instance."""
for f in self.linked_files:
os.unlink(f)
def get_iso_level_config(compose, variant, arch):
"""
Get configured ISO level for this variant and architecture.
"""
level = compose.conf.get("iso_level")
if isinstance(level, list):
level = None
for c in get_arch_variant_data(compose.conf, "iso_level", arch, variant):
level = c
return level

496
pungi/phases/createrepo.py Normal file
View File

@ -0,0 +1,496 @@
# -*- coding: utf-8 -*-
# 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; version 2 of the License.
#
# 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 Library General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, see <https://gnu.org/licenses/>.
__all__ = ("create_variant_repo",)
import copy
import errno
import glob
import os
import shutil
import threading
import xml.dom.minidom
import productmd.modules
import productmd.rpms
from kobo.shortcuts import relative_path, run
from kobo.threads import ThreadPool, WorkerThread
from ..module_util import Modulemd, collect_module_defaults, collect_module_obsoletes
from ..util import (
get_arch_variant_data,
read_single_module_stream_from_file,
temp_dir,
)
from ..wrappers.createrepo import CreaterepoWrapper
from ..wrappers.scm import get_dir_from_scm
from .base import PhaseBase
CACHE_TOPDIR = "/var/cache/pungi/createrepo_c/"
createrepo_lock = threading.Lock()
createrepo_dirs = set()
class CreaterepoPhase(PhaseBase):
name = "createrepo"
def __init__(self, compose, pkgset_phase=None):
PhaseBase.__init__(self, compose)
self.pool = ThreadPool(logger=self.compose._logger)
self.modules_metadata = ModulesMetadata(compose)
self.pkgset_phase = pkgset_phase
def validate(self):
errors = []
if not self.compose.old_composes and self.compose.conf.get("createrepo_deltas"):
errors.append("Can not generate deltas without old compose")
if errors:
raise ValueError("\n".join(errors))
def run(self):
get_productids_from_scm(self.compose)
reference_pkgset = None
if self.pkgset_phase and self.pkgset_phase.package_sets:
reference_pkgset = self.pkgset_phase.package_sets[-1]
for i in range(self.compose.conf["createrepo_num_threads"]):
self.pool.add(
CreaterepoThread(self.pool, reference_pkgset, self.modules_metadata)
)
for variant in self.compose.get_variants():
if variant.is_empty:
continue
if variant.uid in self.compose.conf.get("createrepo_extra_modulemd", {}):
# Clone extra modulemd repository if it's configured.
get_dir_from_scm(
self.compose.conf["createrepo_extra_modulemd"][variant.uid],
self.compose.paths.work.tmp_dir(variant=variant, create_dir=False),
compose=self.compose,
)
self.pool.queue_put((self.compose, None, variant, "srpm"))
for arch in variant.arches:
self.pool.queue_put((self.compose, arch, variant, "rpm"))
self.pool.queue_put((self.compose, arch, variant, "debuginfo"))
self.pool.start()
def stop(self):
super(CreaterepoPhase, self).stop()
self.modules_metadata.write_modules_metadata()
def create_variant_repo(
compose, arch, variant, pkg_type, pkgset, modules_metadata=None
):
types = {
"rpm": (
"binary",
lambda **kwargs: compose.paths.compose.repository(
arch=arch, variant=variant, **kwargs
),
),
"srpm": (
"source",
lambda **kwargs: compose.paths.compose.repository(
arch="src", variant=variant, **kwargs
),
),
"debuginfo": (
"debug",
lambda **kwargs: compose.paths.compose.debug_repository(
arch=arch, variant=variant, **kwargs
),
),
}
if variant.is_empty or (arch is None and pkg_type != "srpm"):
compose.log_info(
"[SKIP ] Creating repo (arch: %s, variant: %s)" % (arch, variant)
)
return
createrepo_c = compose.conf["createrepo_c"]
createrepo_checksum = compose.conf["createrepo_checksum"]
repo = CreaterepoWrapper(createrepo_c=createrepo_c)
repo_dir_arch = None
if pkgset:
repo_dir_arch = pkgset.paths["global" if pkg_type == "srpm" else arch]
try:
repo_dir = types[pkg_type][1]()
except KeyError:
raise ValueError("Unknown package type: %s" % pkg_type)
msg = "Creating repo (arch: %s, variant: %s): %s" % (arch, variant, repo_dir)
# HACK: using global lock
# This is important when addons put packages into parent variant directory.
# There can't be multiple createrepo processes operating on the same
# directory.
with createrepo_lock:
if repo_dir in createrepo_dirs:
compose.log_warning("[SKIP ] Already in progress: %s" % msg)
return
createrepo_dirs.add(repo_dir)
compose.log_info("[BEGIN] %s" % msg)
# We only want delta RPMs for binary repos.
with_deltas = pkg_type == "rpm" and _has_deltas(compose, variant, arch)
rpms = set()
rpm_nevras = set()
# read rpms from metadata rather than guessing it by scanning filesystem
manifest_file = compose.paths.compose.metadata("rpms.json")
manifest = productmd.rpms.Rpms()
manifest.load(manifest_file)
for rpms_arch, data in manifest.rpms.get(variant.uid, {}).items():
if arch is not None and arch != rpms_arch:
continue
for srpm_data in data.values():
for rpm_nevra, rpm_data in srpm_data.items():
if types[pkg_type][0] != rpm_data["category"]:
continue
path = os.path.join(compose.topdir, "compose", rpm_data["path"])
rel_path = relative_path(path, repo_dir.rstrip("/") + "/")
rpms.add(rel_path)
rpm_nevras.add(str(rpm_nevra))
file_list = compose.paths.work.repo_package_list(arch, variant, pkg_type)
with open(file_list, "w") as f:
for rel_path in sorted(rpms):
f.write("%s\n" % rel_path)
# Only find last compose when we actually want delta RPMs.
old_package_dirs = _get_old_package_dirs(compose, repo_dir) if with_deltas else None
if old_package_dirs:
# If we are creating deltas, we can not reuse existing metadata, as
# that would stop deltas from being created.
# This seems to only affect createrepo_c though.
repo_dir_arch = None
comps_path = None
if compose.has_comps and pkg_type == "rpm":
comps_path = compose.paths.work.comps(arch=arch, variant=variant)
if compose.conf["createrepo_enable_cache"]:
cachedir = os.path.join(
CACHE_TOPDIR,
"%s-%s" % (compose.conf["release_short"], os.getuid()),
)
if not os.path.exists(cachedir):
try:
os.makedirs(cachedir)
except Exception as e:
compose.log_warning(
"Cache disabled because cannot create cache dir %s %s"
% (cachedir, str(e))
)
cachedir = None
else:
cachedir = None
cmd = repo.get_createrepo_cmd(
repo_dir,
update=True,
database=compose.should_create_yum_database,
skip_stat=True,
pkglist=file_list,
outputdir=repo_dir,
workers=compose.conf["createrepo_num_workers"],
groupfile=comps_path,
update_md_path=repo_dir_arch,
checksum=createrepo_checksum,
deltas=with_deltas,
oldpackagedirs=old_package_dirs,
use_xz=compose.conf["createrepo_use_xz"],
extra_args=compose.conf["createrepo_extra_args"],
cachedir=cachedir,
)
log_file = compose.paths.log.log_file(
arch, "createrepo-%s.%s" % (variant, pkg_type)
)
run(cmd, logfile=log_file, show_cmd=True)
# call modifyrepo to inject productid
product_id = compose.conf.get("product_id")
if product_id and pkg_type == "rpm":
# add product certificate to base (rpm) repo; skip source and debug
product_id_path = compose.paths.work.product_id(arch, variant)
if os.path.isfile(product_id_path):
cmd = repo.get_modifyrepo_cmd(
os.path.join(repo_dir, "repodata"), product_id_path, compress_type="gz"
)
log_file = compose.paths.log.log_file(arch, "modifyrepo-%s" % variant)
run(cmd, logfile=log_file, show_cmd=True)
# productinfo is not supported by modifyrepo in any way
# this is a HACK to make CDN happy (dmach: at least I think,
# need to confirm with dgregor)
shutil.copy2(
product_id_path, os.path.join(repo_dir, "repodata", "productid")
)
# call modifyrepo to inject modulemd if needed
if pkg_type == "rpm" and arch in variant.arch_mmds and Modulemd is not None:
mod_index = Modulemd.ModuleIndex()
metadata = []
for module_id, mmd in variant.arch_mmds.get(arch, {}).items():
if modules_metadata:
module_rpms = mmd.get_rpm_artifacts()
metadata.append((module_id, module_rpms))
mod_index.add_module_stream(mmd)
module_names = set(mod_index.get_module_names())
defaults_dir = compose.paths.work.module_defaults_dir()
overrides_dir = compose.conf.get("module_defaults_override_dir")
collect_module_defaults(
defaults_dir, module_names, mod_index, overrides_dir=overrides_dir
)
obsoletes_dir = compose.paths.work.module_obsoletes_dir()
mod_index = collect_module_obsoletes(obsoletes_dir, module_names, mod_index)
# Add extra modulemd files
if variant.uid in compose.conf.get("createrepo_extra_modulemd", {}):
compose.log_debug("Adding extra modulemd for %s.%s", variant.uid, arch)
dirname = compose.paths.work.tmp_dir(variant=variant, create_dir=False)
for filepath in glob.glob(os.path.join(dirname, arch) + "/*.yaml"):
module_stream = read_single_module_stream_from_file(filepath)
if not mod_index.add_module_stream(module_stream):
raise RuntimeError(
"Failed parsing modulemd data from %s" % filepath
)
# Add the module to metadata with dummy tag. We can't leave the
# value empty, but we don't know what the correct tag is.
nsvc = module_stream.get_nsvc()
variant.module_uid_to_koji_tag[nsvc] = "DUMMY"
metadata.append((nsvc, []))
log_file = compose.paths.log.log_file(arch, "modifyrepo-modules-%s" % variant)
add_modular_metadata(repo, repo_dir, mod_index, log_file)
for module_id, module_rpms in metadata:
modulemd_path = os.path.join(
types[pkg_type][1](relative=True),
find_file_in_repodata(repo_dir, "modules"),
)
modules_metadata.prepare_module_metadata(
variant,
arch,
module_id,
modulemd_path,
types[pkg_type][0],
list(module_rpms),
)
compose.log_info("[DONE ] %s" % msg)
def add_modular_metadata(repo, repo_path, mod_index, log_file):
"""Add modular metadata into a repository."""
# Dumping empty index fails, we need to check for that.
if not mod_index.get_module_names():
return
with temp_dir() as tmp_dir:
modules_path = os.path.join(tmp_dir, "modules.yaml")
with open(modules_path, "w") as f:
f.write(mod_index.dump_to_string())
cmd = repo.get_modifyrepo_cmd(
os.path.join(repo_path, "repodata"),
modules_path,
mdtype="modules",
compress_type="gz",
)
run(cmd, logfile=log_file, show_cmd=True)
def find_file_in_repodata(repo_path, type_):
dom = xml.dom.minidom.parse(os.path.join(repo_path, "repodata", "repomd.xml"))
for entry in dom.getElementsByTagName("data"):
if entry.getAttribute("type") == type_:
return entry.getElementsByTagName("location")[0].getAttribute("href")
entry.unlink()
raise RuntimeError("No such file in repodata: %s" % type_)
class CreaterepoThread(WorkerThread):
def __init__(self, pool, reference_pkgset, modules_metadata):
super(CreaterepoThread, self).__init__(pool)
self.reference_pkgset = reference_pkgset
self.modules_metadata = modules_metadata
def process(self, item, num):
compose, arch, variant, pkg_type = item
create_variant_repo(
compose,
arch,
variant,
pkg_type=pkg_type,
pkgset=self.reference_pkgset,
modules_metadata=self.modules_metadata,
)
def get_productids_from_scm(compose):
# product_id is a scm_dict: {scm, repo, branch, dir}
# expected file name format: $variant_uid-$arch-*.pem
product_id = compose.conf.get("product_id")
if not product_id:
compose.log_info("No product certificates specified")
return
product_id_allow_missing = compose.conf["product_id_allow_missing"]
msg = "Getting product certificates from SCM..."
compose.log_info("[BEGIN] %s" % msg)
tmp_dir = compose.mkdtemp(prefix="pungi_")
try:
get_dir_from_scm(product_id, tmp_dir, compose=compose)
except OSError as e:
if e.errno == errno.ENOENT and product_id_allow_missing:
compose.log_warning("No product IDs in %s" % product_id)
return
raise
if compose.conf["product_id_allow_name_prefix"]:
pattern = "%s/*%s-%s-*.pem"
else:
pattern = "%s/%s-%s-*.pem"
for arch in compose.get_arches():
for variant in compose.get_variants(arch=arch):
# some layered products may use base product name before variant
pem_files = glob.glob(pattern % (tmp_dir, variant.uid, arch))
if not pem_files:
warning = "No product certificate found (arch: %s, variant: %s)" % (
arch,
variant.uid,
)
if product_id_allow_missing:
compose.log_warning(warning)
continue
else:
shutil.rmtree(tmp_dir)
raise RuntimeError(warning)
if len(pem_files) > 1:
shutil.rmtree(tmp_dir)
raise RuntimeError(
"Multiple product certificates found (arch: %s, variant: %s): %s"
% (
arch,
variant.uid,
", ".join(sorted([os.path.basename(i) for i in pem_files])),
)
)
product_id_path = compose.paths.work.product_id(arch, variant)
shutil.copy2(pem_files[0], product_id_path)
try:
shutil.rmtree(tmp_dir)
except Exception as e:
compose.log_warning("Failed to clean up tmp dir: %s %s" % (tmp_dir, str(e)))
compose.log_info("[DONE ] %s" % msg)
def _get_old_package_dirs(compose, repo_dir):
"""Given a compose and a path to a repo in it, try to find corresponding
repo in an older compose and return a list of paths to directories with
packages in it.
"""
if not compose.conf["createrepo_deltas"]:
return None
old_package_dirs = compose.paths.old_compose_path(
repo_dir, allowed_statuses=["FINISHED", "FINISHED_INCOMPLETE"]
)
if not old_package_dirs:
compose.log_info("No suitable old compose found in: %s" % compose.old_composes)
return None
old_package_dirs = os.path.join(old_package_dirs, "Packages")
if compose.conf["hashed_directories"]:
old_package_dirs = _find_package_dirs(old_package_dirs)
return old_package_dirs
def _find_package_dirs(base):
"""Assuming the packages are in directories hashed by first letter, find
all the buckets in given base.
"""
buckets = set()
try:
for subdir in os.listdir(base):
bucket = os.path.join(base, subdir)
if os.path.isdir(bucket):
buckets.add(bucket)
except OSError:
# The directory does not exist, so no drpms for you!
pass
return sorted(buckets)
def _has_deltas(compose, variant, arch):
"""Check if delta RPMs are enabled for given variant and architecture."""
key = "createrepo_deltas"
if isinstance(compose.conf.get(key), bool):
return compose.conf[key]
return any(get_arch_variant_data(compose.conf, key, arch, variant))
class ModulesMetadata(object):
def __init__(self, compose):
# Prepare empty module metadata
self.compose = compose
self.modules_metadata_file = self.compose.paths.compose.metadata("modules.json")
self.productmd_modules_metadata = productmd.modules.Modules()
self.productmd_modules_metadata.compose.id = copy.copy(self.compose.compose_id)
self.productmd_modules_metadata.compose.type = copy.copy(
self.compose.compose_type
)
self.productmd_modules_metadata.compose.date = copy.copy(
self.compose.compose_date
)
self.productmd_modules_metadata.compose.respin = copy.copy(
self.compose.compose_respin
)
def write_modules_metadata(self):
"""
flush modules metadata into file
"""
self.compose.log_info(
"Writing modules metadata: %s" % self.modules_metadata_file
)
self.productmd_modules_metadata.dump(self.modules_metadata_file)
def prepare_module_metadata(
self, variant, arch, nsvc, modulemd_path, category, module_rpms
):
"""
Find koji tag which corresponds to the module and add record into
module metadata structure.
"""
koji_tag = variant.module_uid_to_koji_tag[nsvc]
self.productmd_modules_metadata.add(
variant.uid, arch, nsvc, koji_tag, modulemd_path, category, module_rpms
)

141
pungi/phases/extra_files.py Normal file
View File

@ -0,0 +1,141 @@
# -*- coding: utf-8 -*-
# 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; version 2 of the License.
#
# 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 Library General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, see <https://gnu.org/licenses/>.
import os
import copy
import fnmatch
from productmd.extra_files import ExtraFiles
from pungi.util import get_arch_variant_data, pkg_is_rpm, copy_all
from pungi.arch import split_name_arch
from pungi.wrappers.scm import get_file_from_scm, get_dir_from_scm
from pungi.phases.base import ConfigGuardedPhase
from pungi import metadata
class ExtraFilesPhase(ConfigGuardedPhase):
"""EXTRA_FILES"""
name = "extra_files"
def __init__(self, compose, pkgset_phase):
super(ExtraFilesPhase, self).__init__(compose)
# pkgset_phase provides package_sets
self.pkgset_phase = pkgset_phase
# Prepare metadata
self.metadata = ExtraFiles()
self.metadata.compose.id = self.compose.compose_id
self.metadata.compose.type = self.compose.compose_type
self.metadata.compose.date = self.compose.compose_date
self.metadata.compose.respin = self.compose.compose_respin
def run(self):
for variant in self.compose.get_variants():
if variant.is_empty:
continue
for arch in variant.arches + ["src"]:
cfg = get_arch_variant_data(self.compose.conf, self.name, arch, variant)
if cfg:
copy_extra_files(
self.compose,
cfg,
arch,
variant,
self.pkgset_phase.package_sets,
self.metadata,
)
else:
self.compose.log_info(
"[SKIP ] No extra files (arch: %s, variant: %s)"
% (arch, variant.uid)
)
metadata_path = self.compose.paths.compose.metadata("extra_files.json")
self.compose.log_info("Writing global extra files metadata: %s" % metadata_path)
self.metadata.dump(metadata_path)
def copy_extra_files(
compose, cfg, arch, variant, package_sets, extra_metadata, checksum_type=None
):
checksum_type = checksum_type or compose.conf["media_checksums"]
var_dict = {
"arch": arch,
"variant_id": variant.id,
"variant_id_lower": variant.id.lower(),
"variant_uid": variant.uid,
"variant_uid_lower": variant.uid.lower(),
}
msg = "Getting extra files (arch: %s, variant: %s)" % (arch, variant)
compose.log_info("[BEGIN] %s" % msg)
os_tree = compose.paths.compose.os_tree(arch, variant)
extra_files_dir = compose.paths.work.extra_files_dir(arch, variant)
for scm_dict in cfg:
scm_dict = copy.deepcopy(scm_dict)
# if scm is "rpm" and repo contains only a package name, find the
# package(s) in package set
if scm_dict["scm"] == "rpm" and not _is_external(scm_dict["repo"]):
rpms = []
pattern = scm_dict["repo"] % var_dict
pkg_name, pkg_arch = split_name_arch(pattern)
for package_set in package_sets:
for pkgset_file in package_set[arch]:
pkg_obj = package_set[arch][pkgset_file]
if pkg_is_rpm(pkg_obj) and _pkg_matches(
pkg_obj, pkg_name, pkg_arch
):
rpms.append(pkg_obj.file_path)
if not rpms:
raise RuntimeError(
"No package matching %s in the package set." % pattern
)
scm_dict["repo"] = rpms
getter = get_file_from_scm if "file" in scm_dict else get_dir_from_scm
target_path = os.path.join(
extra_files_dir, scm_dict.get("target", "").lstrip("/")
)
getter(scm_dict, target_path, compose=compose)
if os.listdir(extra_files_dir):
metadata.populate_extra_files_metadata(
extra_metadata,
variant,
arch,
os_tree,
copy_all(extra_files_dir, os_tree),
compose.conf["media_checksums"],
relative_root=compose.paths.compose.topdir(),
)
compose.log_info("[DONE ] %s" % msg)
def _pkg_matches(pkg_obj, name_glob, arch):
"""Check if `pkg_obj` matches name and arch."""
return fnmatch.fnmatch(pkg_obj.name, name_glob) and (
arch is None or arch == pkg_obj.arch
)
def _is_external(rpm):
"""Check if path to rpm points outside of the compose: i.e. it is an
absolute path or a URL."""
return rpm.startswith("/") or "://" in rpm

554
pungi/phases/extra_isos.py Normal file
View File

@ -0,0 +1,554 @@
# -*- coding: utf-8 -*-
# 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; version 2 of the License.
#
# 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 Library General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, see <https://gnu.org/licenses/>.
import os
import hashlib
import json
from kobo.shortcuts import force_list
from kobo.threads import ThreadPool, WorkerThread
import productmd.treeinfo
from productmd.extra_files import ExtraFiles
from pungi import createiso
from pungi import metadata
from pungi.phases.base import ConfigGuardedPhase, PhaseBase, PhaseLoggerMixin
from pungi.phases.createiso import (
add_iso_to_metadata,
copy_boot_images,
run_createiso_command,
load_and_tweak_treeinfo,
compare_packages,
OldFileLinker,
get_iso_level_config,
)
from pungi.util import (
failable,
get_format_substs,
get_variant_data,
get_volid,
read_json_file,
)
from pungi.wrappers import iso
from pungi.wrappers.scm import get_dir_from_scm, get_file_from_scm
class ExtraIsosPhase(PhaseLoggerMixin, ConfigGuardedPhase, PhaseBase):
name = "extra_isos"
def __init__(self, compose, buildinstall_phase):
super(ExtraIsosPhase, self).__init__(compose)
self.pool = ThreadPool(logger=self.logger)
self.bi = buildinstall_phase
def validate(self):
for variant in self.compose.get_variants(types=["variant"]):
for config in get_variant_data(self.compose.conf, self.name, variant):
extra_arches = set(config.get("arches", [])) - set(variant.arches)
if extra_arches:
self.compose.log_warning(
"Extra iso config for %s mentions non-existing arches: %s"
% (variant, ", ".join(sorted(extra_arches)))
)
def run(self):
commands = []
for variant in self.compose.get_variants(types=["variant"]):
for config in get_variant_data(self.compose.conf, self.name, variant):
arches = set(variant.arches)
if config.get("arches"):
arches &= set(config["arches"])
if not config["skip_src"]:
arches.add("src")
for arch in sorted(arches):
commands.append((config, variant, arch))
for config, variant, arch in commands:
self.pool.add(ExtraIsosThread(self.pool, self.bi))
self.pool.queue_put((self.compose, config, variant, arch))
self.pool.start()
class ExtraIsosThread(WorkerThread):
def __init__(self, pool, buildinstall_phase):
super(ExtraIsosThread, self).__init__(pool)
self.bi = buildinstall_phase
def process(self, item, num):
self.num = num
compose, config, variant, arch = item
can_fail = arch in config.get("failable_arches", [])
with failable(
compose, can_fail, variant, arch, "extra_iso", logger=self.pool._logger
):
self.worker(compose, config, variant, arch)
def worker(self, compose, config, variant, arch):
filename = get_filename(compose, variant, arch, config.get("filename"))
volid = get_volume_id(compose, variant, arch, config.get("volid", []))
iso_dir = compose.paths.compose.iso_dir(arch, variant)
iso_path = os.path.join(iso_dir, filename)
prepare_media_metadata(compose, variant, arch)
msg = "Creating ISO (arch: %s, variant: %s): %s" % (arch, variant, filename)
self.pool.log_info("[BEGIN] %s" % msg)
get_extra_files(compose, variant, arch, config.get("extra_files", []))
bootable = arch != "src" and bool(compose.conf.get("buildinstall_method"))
graft_points = get_iso_contents(
compose,
variant,
arch,
config["include_variants"],
filename,
bootable=bootable,
inherit_extra_files=config.get("inherit_extra_files", False),
)
opts = createiso.CreateIsoOpts(
output_dir=iso_dir,
iso_name=filename,
volid=volid,
graft_points=graft_points,
arch=arch,
supported=compose.supported,
hfs_compat=compose.conf["iso_hfs_ppc64le_compatible"],
use_xorrisofs=compose.conf.get("createiso_use_xorrisofs"),
iso_level=get_iso_level_config(compose, variant, arch),
)
os_tree = compose.paths.compose.os_tree(arch, variant)
if compose.conf["create_jigdo"]:
jigdo_dir = compose.paths.compose.jigdo_dir(arch, variant)
opts = opts._replace(jigdo_dir=jigdo_dir, os_tree=os_tree)
if bootable:
opts = opts._replace(
buildinstall_method=compose.conf["buildinstall_method"],
boot_iso=os.path.join(os_tree, "images", "boot.iso"),
)
# Check if it can be reused.
hash = hashlib.sha256()
hash.update(json.dumps(config, sort_keys=True).encode("utf-8"))
config_hash = hash.hexdigest()
if not self.try_reuse(compose, variant, arch, config_hash, opts):
script_dir = compose.paths.work.tmp_dir(arch, variant)
opts = opts._replace(script_dir=script_dir)
script_file = os.path.join(script_dir, "extraiso-%s.sh" % filename)
with open(script_file, "w") as f:
createiso.write_script(opts, f)
run_createiso_command(
self.num,
compose,
bootable,
arch,
["bash", script_file],
[compose.topdir],
log_file=compose.paths.log.log_file(
arch, "extraiso-%s" % os.path.basename(iso_path)
),
iso_path=iso_path,
)
img = add_iso_to_metadata(
compose,
variant,
arch,
iso_path,
bootable,
additional_variants=config["include_variants"],
)
img._max_size = config.get("max_size")
save_reuse_metadata(compose, variant, arch, config_hash, opts, iso_path)
self.pool.log_info("[DONE ] %s" % msg)
def try_reuse(self, compose, variant, arch, config_hash, opts):
# Check explicit config
if not compose.conf["extraiso_allow_reuse"]:
return
log_msg = "Cannot reuse ISO for %s.%s" % (variant, arch)
if opts.buildinstall_method and not self.bi.reused(variant, arch):
# If buildinstall phase was not reused for some reason, we can not
# reuse any bootable image. If a package change caused rebuild of
# boot.iso, we would catch it here too, but there could be a
# configuration change in lorax template which would remain
# undetected.
self.pool.log_info("%s - boot configuration changed", log_msg)
return False
# Check old compose configuration: extra_files and product_ids can be
# reflected on ISO.
old_config = compose.load_old_compose_config()
if not old_config:
self.pool.log_info("%s - no config for old compose", log_msg)
return False
# Disable reuse if unsigned packages are allowed. The older compose
# could have unsigned packages, and those may have been signed since
# then. We want to regenerate the ISO to have signatures.
if None in compose.conf["sigkeys"]:
self.pool.log_info("%s - unsigned packages are allowed", log_msg)
return False
# Convert current configuration to JSON and back to encode it similarly
# to the old one
config = json.loads(json.dumps(compose.conf))
for opt in compose.conf:
# Skip a selection of options: these affect what packages can be
# included, which we explicitly check later on.
config_whitelist = set(
[
"gather_lookaside_repos",
"pkgset_koji_builds",
"pkgset_koji_scratch_tasks",
"pkgset_koji_module_builds",
]
)
# Skip irrelevant options
config_whitelist.update(["osbs", "osbuild"])
if opt in config_whitelist:
continue
if old_config.get(opt) != config.get(opt):
self.pool.log_info("%s - option %s differs", log_msg, opt)
return False
old_metadata = load_old_metadata(compose, variant, arch, config_hash)
if not old_metadata:
self.pool.log_info("%s - no old metadata found", log_msg)
return False
# Test if volume ID matches - volid can be generated dynamically based on
# other values, and could change even if nothing else is different.
if opts.volid != old_metadata["opts"]["volid"]:
self.pool.log_info("%s - volume ID differs", log_msg)
return False
# Compare packages on the ISO.
if compare_packages(
old_metadata["opts"]["graft_points"],
opts.graft_points,
):
self.pool.log_info("%s - packages differ", log_msg)
return False
try:
self.perform_reuse(
compose,
variant,
arch,
opts,
old_metadata["opts"]["output_dir"],
old_metadata["opts"]["iso_name"],
)
return True
except Exception as exc:
self.pool.log_error(
"Error while reusing ISO for %s.%s: %s", variant, arch, exc
)
compose.traceback("extraiso-reuse-%s-%s-%s" % (variant, arch, config_hash))
return False
def perform_reuse(self, compose, variant, arch, opts, old_iso_dir, old_file_name):
"""
Copy all related files from old compose to the new one. As a last step
add the new image to metadata.
"""
linker = OldFileLinker(self.pool._logger)
old_iso_path = os.path.join(old_iso_dir, old_file_name)
iso_path = os.path.join(opts.output_dir, opts.iso_name)
try:
# Hardlink ISO and manifest
for suffix in ("", ".manifest"):
linker.link(old_iso_path + suffix, iso_path + suffix)
# Copy log files
# The log file name includes filename of the image, so we need to
# find old file with the old name, and rename it to the new name.
log_file = compose.paths.log.log_file(arch, "extraiso-%s" % opts.iso_name)
old_log_file = compose.paths.old_compose_path(
compose.paths.log.log_file(arch, "extraiso-%s" % old_file_name)
)
linker.link(old_log_file, log_file)
# Copy jigdo files
if opts.jigdo_dir:
old_jigdo_dir = compose.paths.old_compose_path(opts.jigdo_dir)
for suffix in (".template", ".jigdo"):
linker.link(
os.path.join(old_jigdo_dir, old_file_name) + suffix,
os.path.join(opts.jigdo_dir, opts.iso_name) + suffix,
)
except Exception:
# A problem happened while linking some file, let's clean up
# everything.
linker.abort()
raise
def save_reuse_metadata(compose, variant, arch, config_hash, opts, iso_path):
"""
Save metadata for possible reuse of this image. The file name is determined
from the hash of a configuration snippet for this image. Any change in that
configuration in next compose will change the hash and thus reuse will be
blocked.
"""
metadata = {"opts": opts._asdict()}
metadata_path = compose.paths.log.log_file(
arch,
"extraiso-reuse-%s-%s-%s" % (variant.uid, arch, config_hash),
ext="json",
)
with open(metadata_path, "w") as f:
json.dump(metadata, f, indent=2)
def load_old_metadata(compose, variant, arch, config_hash):
metadata_path = compose.paths.log.log_file(
arch,
"extraiso-reuse-%s-%s-%s" % (variant.uid, arch, config_hash),
ext="json",
)
old_path = compose.paths.old_compose_path(metadata_path)
try:
return read_json_file(old_path)
except Exception:
return None
def get_extra_files(compose, variant, arch, extra_files):
"""Clone the configured files into a directory from where they can be
included in the ISO.
"""
extra_files_dir = compose.paths.work.extra_iso_extra_files_dir(arch, variant)
filelist = []
for scm_dict in extra_files:
getter = get_file_from_scm if "file" in scm_dict else get_dir_from_scm
target = scm_dict.get("target", "").lstrip("/")
target_path = os.path.join(extra_files_dir, target).rstrip("/")
filelist.extend(
os.path.join(target, f)
for f in getter(scm_dict, target_path, compose=compose)
)
if filelist:
metadata.populate_extra_files_metadata(
ExtraFiles(),
variant,
arch,
extra_files_dir,
filelist,
compose.conf["media_checksums"],
)
def get_iso_contents(
compose, variant, arch, include_variants, filename, bootable, inherit_extra_files
):
"""Find all files that should be on the ISO. For bootable image we start
with the boot configuration. Then for each variant we add packages,
repodata and extra files. Finally we add top-level extra files.
"""
iso_dir = compose.paths.work.iso_dir(arch, filename)
files = {}
if bootable:
buildinstall_dir = compose.paths.work.buildinstall_dir(arch, create_dir=False)
if compose.conf["buildinstall_method"] == "lorax":
buildinstall_dir = os.path.join(buildinstall_dir, variant.uid)
copy_boot_images(buildinstall_dir, iso_dir)
files = iso.get_graft_points(
compose.paths.compose.topdir(), [buildinstall_dir, iso_dir]
)
# We need to point efiboot.img to compose/ tree, because it was
# modified in buildinstall phase and the file in work/ has different
# checksum to what is in the .treeinfo.
if "images/efiboot.img" in files:
files["images/efiboot.img"] = os.path.join(
compose.paths.compose.os_tree(arch, variant), "images/efiboot.img"
)
variants = [variant.uid] + include_variants
for variant_uid in variants:
var = compose.all_variants[variant_uid]
# Get packages...
package_dir = compose.paths.compose.packages(arch, var)
for k, v in iso.get_graft_points(
compose.paths.compose.topdir(), [package_dir]
).items():
files[os.path.join(var.uid, "Packages", k)] = v
# Get repodata...
tree_dir = compose.paths.compose.repository(arch, var)
repo_dir = os.path.join(tree_dir, "repodata")
for k, v in iso.get_graft_points(
compose.paths.compose.topdir(), [repo_dir]
).items():
files[os.path.join(var.uid, "repodata", k)] = v
if inherit_extra_files:
# Get extra files...
extra_files_dir = compose.paths.work.extra_files_dir(arch, var)
for k, v in iso.get_graft_points(
compose.paths.compose.topdir(), [extra_files_dir]
).items():
files[os.path.join(var.uid, k)] = v
extra_files_dir = compose.paths.work.extra_iso_extra_files_dir(arch, variant)
original_treeinfo = os.path.join(
compose.paths.compose.os_tree(arch=arch, variant=variant), ".treeinfo"
)
tweak_treeinfo(
compose,
include_variants,
original_treeinfo,
os.path.join(extra_files_dir, ".treeinfo"),
)
tweak_repo_treeinfo(
compose,
include_variants,
original_treeinfo,
original_treeinfo,
)
# Add extra files specific for the ISO
files.update(
iso.get_graft_points(compose.paths.compose.topdir(), [extra_files_dir])
)
gp = "%s-graft-points" % iso_dir
iso.write_graft_points(gp, files, exclude=["*/lost+found", "*/boot.iso"])
return gp
def tweak_repo_treeinfo(compose, include_variants, source_file, dest_file):
"""
The method includes the variants to file .treeinfo of a variant. It takes
the variants which are described
by options `extra_isos -> include_variants`.
"""
ti = productmd.treeinfo.TreeInfo()
ti.load(source_file)
main_variant = next(iter(ti.variants))
for variant_uid in include_variants:
variant = compose.all_variants[variant_uid]
var = productmd.treeinfo.Variant(ti)
var.id = variant.id
var.uid = variant.uid
var.name = variant.name
var.type = variant.type
ti.variants.add(var)
for variant_id in ti.variants:
var = ti.variants[variant_id]
if variant_id == main_variant:
var.paths.packages = 'Packages'
var.paths.repository = '.'
else:
var.paths.packages = os.path.join(
'../../..',
var.uid,
var.arch,
'os/Packages',
)
var.paths.repository = os.path.join(
'../../..',
var.uid,
var.arch,
'os',
)
ti.dump(dest_file, main_variant=main_variant)
def tweak_treeinfo(compose, include_variants, source_file, dest_file):
ti = load_and_tweak_treeinfo(source_file)
for variant_uid in include_variants:
variant = compose.all_variants[variant_uid]
var = productmd.treeinfo.Variant(ti)
var.id = variant.id
var.uid = variant.uid
var.name = variant.name
var.type = variant.type
ti.variants.add(var)
for variant_id in ti.variants:
var = ti.variants[variant_id]
var.paths.packages = os.path.join(var.uid, "Packages")
var.paths.repository = var.uid
ti.dump(dest_file)
def get_filename(compose, variant, arch, format):
disc_type = compose.conf["disc_types"].get("dvd", "dvd")
base_filename = compose.get_image_name(
arch, variant, disc_type=disc_type, disc_num=1
)
if not format:
return base_filename
kwargs = {
"arch": arch,
"disc_type": disc_type,
"disc_num": 1,
"suffix": ".iso",
"filename": base_filename,
"variant": variant,
}
args = get_format_substs(compose, **kwargs)
try:
return (format % args).format(**args)
except KeyError as err:
raise RuntimeError(
"Failed to create image name: unknown format element: %s" % err
)
def get_volume_id(compose, variant, arch, formats):
disc_type = compose.conf["disc_types"].get("dvd", "dvd")
# Get volume ID for regular ISO so that we can substitute it in.
volid = get_volid(compose, arch, variant, disc_type=disc_type)
return get_volid(
compose,
arch,
variant,
disc_type=disc_type,
formats=force_list(formats),
volid=volid,
)
def prepare_media_metadata(compose, variant, arch):
"""Write a .discinfo and media.repo files to a directory that will be
included on the ISO. It's possible to overwrite the files by using extra
files.
"""
md_dir = compose.paths.work.extra_iso_extra_files_dir(arch, variant)
description = metadata.get_description(compose, variant, arch)
metadata.create_media_repo(
os.path.join(md_dir, "media.repo"), description, timestamp=None
)
metadata.create_discinfo(os.path.join(md_dir, ".discinfo"), description, arch)

File diff suppressed because it is too large Load Diff

167
pungi/phases/gather/link.py Normal file
View File

@ -0,0 +1,167 @@
# -*- coding: utf-8 -*-
# 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; version 2 of the License.
#
# 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 Library General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, see <https://gnu.org/licenses/>.
import os
import kobo.rpmlib
from pungi.linker import LinkerPool
# TODO: global Linker instance - to keep hardlinks on dest?
# DONE: show overall progress, not each file
# TODO: (these should be logged separately)
def _get_src_nevra(compose, pkg_obj, srpm_map):
"""Return source N-E:V-R.A.rpm; guess if necessary."""
result = srpm_map.get(pkg_obj.sourcerpm, None)
if not result:
nvra = kobo.rpmlib.parse_nvra(pkg_obj.sourcerpm)
nvra["epoch"] = pkg_obj.epoch
result = kobo.rpmlib.make_nvra(nvra, add_rpm=True, force_epoch=True)
compose.log_warning(
"Package %s has no SRPM available, guessing epoch: %s"
% (pkg_obj.nevra, result)
)
return result
def get_package_path(filename, hashed_directory=False):
"""Get path for filename. If ``hashed_directory`` is ``True``, the path
will include a prefix based on the initial letter.
>>> get_package_path('my-package.rpm')
'my-package.rpm'
>>> get_package_path('my-package.rpm', True)
'm/my-package.rpm'
>>> get_package_path('My-Package.rpm', True)
'm/My-Package.rpm'
"""
if hashed_directory:
prefix = filename[0].lower()
return os.path.join(prefix, filename)
return filename
def link_files(compose, arch, variant, pkg_map, pkg_sets, manifest, srpm_map={}):
# srpm_map instance is shared between link_files() runs
msg = "Linking packages (arch: %s, variant: %s)" % (arch, variant)
compose.log_info("[BEGIN] %s" % msg)
link_type = compose.conf["link_type"]
pool = LinkerPool.with_workers(10, link_type, logger=compose._logger)
hashed_directories = compose.conf["hashed_directories"]
# Create temporary dict mapping package path to package object from pkgset
# so we do not have to search all pkg_sets for every package in pkg_map.
pkg_by_path = {}
for pkg_set in pkg_sets:
for path in pkg_set[arch]:
pkg_by_path[path] = pkg_set[arch][path]
packages_dir = compose.paths.compose.packages("src", variant)
packages_dir_relpath = compose.paths.compose.packages("src", variant, relative=True)
for pkg in pkg_map["srpm"]:
if "lookaside" in pkg["flags"]:
continue
package_path = get_package_path(
os.path.basename(pkg["path"]), hashed_directories
)
dst = os.path.join(packages_dir, package_path)
dst_relpath = os.path.join(packages_dir_relpath, package_path)
# link file
pool.queue_put((pkg["path"], dst))
# update rpm manifest
pkg_obj = pkg_by_path[pkg["path"]]
nevra = pkg_obj.nevra
manifest.add(
variant.uid,
arch,
nevra,
path=dst_relpath,
sigkey=pkg_obj.signature,
category="source",
)
# update srpm_map
srpm_map.setdefault(pkg_obj.file_name, nevra)
packages_dir = compose.paths.compose.packages(arch, variant)
packages_dir_relpath = compose.paths.compose.packages(arch, variant, relative=True)
for pkg in pkg_map["rpm"]:
if "lookaside" in pkg["flags"]:
continue
package_path = get_package_path(
os.path.basename(pkg["path"]), hashed_directories
)
dst = os.path.join(packages_dir, package_path)
dst_relpath = os.path.join(packages_dir_relpath, package_path)
# link file
pool.queue_put((pkg["path"], dst))
# update rpm manifest
pkg_obj = pkg_by_path[pkg["path"]]
nevra = pkg_obj.nevra
src_nevra = _get_src_nevra(compose, pkg_obj, srpm_map)
manifest.add(
variant.uid,
arch,
nevra,
path=dst_relpath,
sigkey=pkg_obj.signature,
category="binary",
srpm_nevra=src_nevra,
)
packages_dir = compose.paths.compose.debug_packages(arch, variant)
packages_dir_relpath = compose.paths.compose.debug_packages(
arch, variant, relative=True
)
for pkg in pkg_map["debuginfo"]:
if "lookaside" in pkg["flags"]:
continue
package_path = get_package_path(
os.path.basename(pkg["path"]), hashed_directories
)
dst = os.path.join(packages_dir, package_path)
dst_relpath = os.path.join(packages_dir_relpath, package_path)
# link file
pool.queue_put((pkg["path"], dst))
# update rpm manifest
pkg_obj = pkg_by_path[pkg["path"]]
nevra = pkg_obj.nevra
src_nevra = _get_src_nevra(compose, pkg_obj, srpm_map)
manifest.add(
variant.uid,
arch,
nevra,
path=dst_relpath,
sigkey=pkg_obj.signature,
category="debug",
srpm_nevra=src_nevra,
)
pool.start()
pool.stop()
compose.log_info("[DONE ] %s" % msg)

View File

@ -0,0 +1,19 @@
# -*- coding: utf-8 -*-
# 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; version 2 of the License.
#
# 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 Library General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, see <https://gnu.org/licenses/>.
class GatherMethodBase(object):
def __init__(self, compose):
self.compose = compose

View File

@ -0,0 +1,24 @@
# -*- coding: utf-8 -*-
# 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; version 2 of the License.
#
# 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 Library General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, see <https://gnu.org/licenses/>.
from .method_deps import GatherMethodDeps
from .method_nodeps import GatherMethodNodeps
from .method_hybrid import GatherMethodHybrid
ALL_METHODS = {
"deps": GatherMethodDeps,
"nodeps": GatherMethodNodeps,
"hybrid": GatherMethodHybrid,
}

View File

@ -0,0 +1,286 @@
# -*- coding: utf-8 -*-
# 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; version 2 of the License.
#
# 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 Library General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, see <https://gnu.org/licenses/>.
import os
import shutil
from kobo.shortcuts import run
from kobo.pkgset import SimpleRpmWrapper, RpmWrapper
from kobo.rpmlib import parse_nvra
from pungi.util import get_arch_variant_data, temp_dir
from pungi.wrappers.pungi import PungiWrapper
from pungi.arch import tree_arch_to_yum_arch
import pungi.phases.gather
from pungi.phases.pkgset.pkgsets import ExtendedRpmWrapper
import pungi.phases.gather.method
class GatherMethodDeps(pungi.phases.gather.method.GatherMethodBase):
def __call__(
self,
arch,
variant,
packages,
groups,
filter_packages,
multilib_whitelist,
multilib_blacklist,
package_sets,
path_prefix=None,
fulltree_excludes=None,
prepopulate=None,
):
# result = {
# "rpm": [],
# "srpm": [],
# "debuginfo": [],
# }
write_pungi_config(
self.compose,
arch,
variant,
packages,
groups,
filter_packages,
multilib_whitelist,
multilib_blacklist,
fulltree_excludes=fulltree_excludes,
prepopulate=prepopulate,
source_name=self.source_name,
package_sets=package_sets,
)
result, missing_deps = resolve_deps(
self.compose, arch, variant, source_name=self.source_name
)
raise_on_invalid_sigkeys(arch, variant, package_sets, result)
check_deps(self.compose, arch, variant, missing_deps)
return result
def raise_on_invalid_sigkeys(arch, variant, package_sets, result):
"""
Raises RuntimeError if some package in compose is signed with an invalid
sigkey.
"""
invalid_sigkey_rpms = {}
for package in result["rpm"]:
name = parse_nvra(package["path"])["name"]
for pkgset in package_sets:
for forbidden_package in pkgset["global"].invalid_sigkey_rpms:
if name == forbidden_package["name"]:
invalid_sigkey_rpms.setdefault(
pkgset["global"].sigkey_ordering, []
).append(forbidden_package)
if invalid_sigkey_rpms:
package_sets[0]["global"].raise_invalid_sigkeys_exception(invalid_sigkey_rpms)
def _format_packages(pkgs):
"""Sort packages and merge name with arch."""
result = set()
for pkg, pkg_arch in pkgs:
if type(pkg) in [SimpleRpmWrapper, RpmWrapper, ExtendedRpmWrapper]:
pkg_name = pkg.name
else:
pkg_name = pkg
if pkg_arch:
result.add("%s.%s" % (pkg_name, pkg_arch))
else:
result.add(pkg_name)
return sorted(result)
def write_pungi_config(
compose,
arch,
variant,
packages,
groups,
filter_packages,
multilib_whitelist,
multilib_blacklist,
fulltree_excludes=None,
prepopulate=None,
source_name=None,
package_sets=None,
):
"""write pungi config (kickstart) for arch/variant"""
pungi_wrapper = PungiWrapper()
pungi_cfg = compose.paths.work.pungi_conf(
variant=variant, arch=arch, source_name=source_name
)
compose.log_info(
"Writing pungi config (arch: %s, variant: %s): %s", arch, variant, pungi_cfg
)
repos = {}
for i, pkgset in enumerate(package_sets or []):
if not variant.pkgsets or pkgset.name in variant.pkgsets:
repos["pungi-repo-%d" % i] = pkgset.paths[arch]
if compose.has_comps:
repos["comps-repo"] = compose.paths.work.comps_repo(arch=arch, variant=variant)
if variant.type == "optional":
for var in variant.parent.get_variants(
arch=arch, types=["self", "variant", "addon", "layered-product"]
):
repos["%s-comps" % var.uid] = compose.paths.work.comps_repo(
arch=arch, variant=var
)
if variant.type in ["addon", "layered-product"]:
repos["parent-comps"] = compose.paths.work.comps_repo(
arch=arch, variant=variant.parent
)
lookaside_repos = {}
for i, repo_url in enumerate(
pungi.phases.gather.get_lookaside_repos(compose, arch, variant)
):
lookaside_repos["lookaside-repo-%s" % i] = repo_url
packages_str = list(_format_packages(packages))
filter_packages_str = list(_format_packages(filter_packages))
if not groups and not packages_str and not prepopulate:
raise RuntimeError(
"No packages included in %s.%s "
"(no comps groups, no input packages, no prepopulate)" % (variant.uid, arch)
)
pungi_wrapper.write_kickstart(
ks_path=pungi_cfg,
repos=repos,
groups=groups,
packages=packages_str,
exclude_packages=filter_packages_str,
lookaside_repos=lookaside_repos,
fulltree_excludes=fulltree_excludes,
multilib_whitelist=multilib_whitelist,
multilib_blacklist=multilib_blacklist,
prepopulate=prepopulate,
)
def resolve_deps(compose, arch, variant, source_name=None):
pungi_wrapper = PungiWrapper()
pungi_log = compose.paths.work.pungi_log(arch, variant, source_name=source_name)
msg = "Running pungi (arch: %s, variant: %s)" % (arch, variant)
compose.log_info("[BEGIN] %s" % msg)
pungi_conf = compose.paths.work.pungi_conf(arch, variant, source_name=source_name)
multilib_methods = get_arch_variant_data(compose.conf, "multilib", arch, variant)
greedy_method = compose.conf["greedy_method"]
# variant
fulltree = compose.conf["gather_fulltree"]
selfhosting = compose.conf["gather_selfhosting"]
# profiling
profiler = compose.conf["gather_profiler"]
# optional
if variant.type == "optional":
fulltree = True
selfhosting = True
# addon
if variant.type in ["addon", "layered-product"]:
# packages having SRPM in parent variant are excluded from
# fulltree (via %fulltree-excludes)
fulltree = True
selfhosting = False
lookaside_repos = {}
for i, repo_url in enumerate(
pungi.phases.gather.get_lookaside_repos(compose, arch, variant)
):
lookaside_repos["lookaside-repo-%s" % i] = repo_url
yum_arch = tree_arch_to_yum_arch(arch)
tmp_dir = compose.paths.work.tmp_dir(arch, variant)
cache_dir = compose.paths.work.pungi_cache_dir(arch, variant)
# TODO: remove YUM code, fully migrate to DNF
backends = {
"yum": pungi_wrapper.get_pungi_cmd,
"dnf": pungi_wrapper.get_pungi_cmd_dnf,
}
get_cmd = backends[compose.conf["gather_backend"]]
cmd = get_cmd(
pungi_conf,
destdir=tmp_dir,
name=variant.uid,
selfhosting=selfhosting,
fulltree=fulltree,
arch=yum_arch,
full_archlist=True,
greedy=greedy_method,
cache_dir=cache_dir,
lookaside_repos=lookaside_repos,
multilib_methods=multilib_methods,
profiler=profiler,
)
# Use temp working directory directory as workaround for
# https://bugzilla.redhat.com/show_bug.cgi?id=795137
with temp_dir(prefix="pungi_") as work_dir:
run(cmd, logfile=pungi_log, show_cmd=True, workdir=work_dir, env=os.environ)
# Clean up tmp dir
# Workaround for rpm not honoring sgid bit which only appears when yum is used.
yumroot_dir = os.path.join(tmp_dir, "work", arch, "yumroot")
if os.path.isdir(yumroot_dir):
try:
shutil.rmtree(yumroot_dir)
except Exception as e:
compose.log_warning(
"Failed to clean up tmp dir: %s %s" % (yumroot_dir, str(e))
)
with open(pungi_log, "r") as f:
packages, broken_deps, missing_comps_pkgs = pungi_wrapper.parse_log(f)
if missing_comps_pkgs:
log_msg = "Packages mentioned in comps do not exist for %s.%s: %s" % (
variant.uid,
arch,
", ".join(sorted(missing_comps_pkgs)),
)
compose.log_warning(log_msg)
if compose.conf["require_all_comps_packages"]:
raise RuntimeError(log_msg)
compose.log_info("[DONE ] %s" % msg)
return packages, broken_deps
def check_deps(compose, arch, variant, missing_deps):
if not compose.conf["check_deps"]:
return
if missing_deps:
for pkg in sorted(missing_deps):
compose.log_error(
"Unresolved dependencies for %s.%s in package %s: %s"
% (variant, arch, pkg, sorted(missing_deps[pkg]))
)
raise RuntimeError("Unresolved dependencies detected")

View File

@ -0,0 +1,580 @@
# -*- coding: utf-8 -*-
# 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; version 2 of the License.
#
# 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 Library General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, see <https://gnu.org/licenses/>.
import gzip
import os
from collections import defaultdict
from fnmatch import fnmatch
import createrepo_c as cr
import kobo.rpmlib
from kobo.shortcuts import run
import pungi.phases.gather.method
from pungi import multilib_dnf
from pungi.module_util import Modulemd
from pungi.arch import get_valid_arches, tree_arch_to_yum_arch
from pungi.phases.gather import _mk_pkg_map
from pungi.util import get_arch_variant_data, pkg_is_debug, temp_dir, as_local_file
from pungi.wrappers import fus
from pungi.wrappers.comps import CompsWrapper
from .method_nodeps import expand_groups
class FakePackage(object):
"""This imitates a DNF package object and can be passed to python-multilib
library.
"""
def __init__(self, pkg):
self.pkg = pkg
def __getattr__(self, attr):
return getattr(self.pkg, attr)
@property
def files(self):
paths = []
# createrepo_c.Package.files is a tuple, but its length differs across
# versions. The constants define index at which the related value is
# located.
for entry in self.pkg.files:
paths.append(
os.path.join(entry[cr.FILE_ENTRY_PATH], entry[cr.FILE_ENTRY_NAME])
)
return paths
@property
def provides(self):
# This is supposed to match what yum package object returns. It's a
# nested tuple (name, flag, (epoch, version, release)). This code only
# fills in the name, because that's all that python-multilib is using..
return [(p[0].split()[0], None, (None, None, None)) for p in self.pkg.provides]
class GatherMethodHybrid(pungi.phases.gather.method.GatherMethodBase):
def __init__(self, *args, **kwargs):
super(GatherMethodHybrid, self).__init__(*args, **kwargs)
self.package_maps = {}
self.packages = {}
# Mapping from package name to set of langpack packages (stored as
# names).
self.langpacks = {}
# Set of packages for which we already added langpacks.
self.added_langpacks = set()
# Set of NEVRAs of modular packages
self.modular_packages = set()
# Arch -> pkg name -> set of pkg object
self.debuginfo = defaultdict(lambda: defaultdict(set))
# caches for processed packages
self.processed_multilib = set()
self.processed_debuginfo = set()
def _get_pkg_map(self, arch):
"""Create a mapping from NEVRA to actual package object. This will be
done once for each architecture, since the package set is the same for
all variants.
The keys are in NEVRA format and only include the epoch if it's not
zero. This makes it easier to query by results for the depsolver.
"""
if arch not in self.package_maps:
pkg_map = {}
for pkgset in self.package_sets:
for pkg_arch in pkgset.package_sets[arch].rpms_by_arch:
for pkg in pkgset.package_sets[arch].rpms_by_arch[pkg_arch]:
pkg_map[_fmt_nevra(pkg, pkg_arch)] = pkg
self.package_maps[arch] = pkg_map
return self.package_maps[arch]
def _prepare_packages(self):
for repo_path in self.get_repos():
md = cr.Metadata()
md.locate_and_load_xml(repo_path)
for key in md.keys():
pkg = md.get(key)
if pkg.arch in self.valid_arches:
self.packages[_fmt_nevra(pkg, arch=pkg.arch)] = FakePackage(pkg)
def _get_package(self, nevra):
if not self.packages:
self._prepare_packages()
return self.packages[nevra]
def _prepare_debuginfo(self):
"""Prepare cache of debuginfo packages for easy access. The cache is
indexed by package architecture and then by package name. There can be
more than one debuginfo package with the same name.
"""
for pkgset in self.package_sets:
for pkg_arch in pkgset.package_sets[self.arch].rpms_by_arch:
for pkg in pkgset.package_sets[self.arch].rpms_by_arch[pkg_arch]:
self.debuginfo[pkg.arch][pkg.name].add(pkg)
def _get_debuginfo(self, name, arch):
if not self.debuginfo:
self._prepare_debuginfo()
return self.debuginfo.get(arch, {}).get(name, set())
def expand_list(self, patterns):
"""Given a list of globs, create a list of package names matching any
of the pattern.
"""
expanded = set()
for pkgset in self.package_sets:
for pkg_arch in pkgset.package_sets[self.arch].rpms_by_arch:
for pkg in pkgset.package_sets[self.arch].rpms_by_arch[pkg_arch]:
for pattern in patterns:
if fnmatch(pkg.name, pattern):
expanded.add(pkg)
break
return expanded
def prepare_modular_packages(self):
for var in self.compose.all_variants.values():
for mmd in var.arch_mmds.get(self.arch, {}).values():
self.modular_packages.update(mmd.get_rpm_artifacts())
def prepare_langpacks(self, arch, variant):
if not self.compose.has_comps:
return
comps_file = self.compose.paths.work.comps(arch, variant, create_dir=False)
comps = CompsWrapper(comps_file)
for name, install in comps.get_langpacks().items():
# Replace %s with * for fnmatch.
install_match = install % "*"
self.langpacks[name] = set()
for pkgset in self.package_sets:
for pkg_arch in pkgset.package_sets[arch].rpms_by_arch:
for pkg in pkgset.package_sets[arch].rpms_by_arch[pkg_arch]:
if not fnmatch(pkg.name, install_match):
# Does not match the pattern, ignore...
continue
if pkg.name.endswith("-devel") or pkg.name.endswith("-static"):
continue
if pkg_is_debug(pkg):
continue
self.langpacks[name].add(pkg.name)
def __call__(
self,
arch,
variant,
package_sets,
packages=[],
groups=[],
multilib_whitelist=[],
multilib_blacklist=[],
filter_packages=[],
prepopulate=[],
**kwargs
):
self.arch = arch
self.variant = variant
self.valid_arches = get_valid_arches(arch, multilib=True)
self.package_sets = package_sets
self.prepare_langpacks(arch, variant)
self.prepare_modular_packages()
self.multilib_methods = get_arch_variant_data(
self.compose.conf, "multilib", arch, variant
)
self.multilib = multilib_dnf.Multilib(
self.multilib_methods,
set(p.name for p in self.expand_list(multilib_blacklist)),
set(p.name for p in self.expand_list(multilib_whitelist)),
)
platform = get_platform(self.compose, variant, arch)
packages.update(
expand_groups(self.compose, arch, variant, groups, set_pkg_arch=False)
)
packages.update(tuple(pkg.rsplit(".", 1)) for pkg in prepopulate)
# Filters are received as tuples (name, arch), we should convert it to
# strings.
filters = [_fmt_pkg(*p) for p in filter_packages]
cache_prefix = "fus-cache-%s-%s-%s-" % (self.compose.compose_id, variant, arch)
with temp_dir(prefix=cache_prefix) as cache_dir:
nvrs, out_modules = self.run_solver(
variant, arch, packages, platform, filters, cache_dir=cache_dir
)
filter_modules(variant, arch, out_modules)
return expand_packages(
self._get_pkg_map(arch),
pungi.phases.gather.get_lookaside_repos(self.compose, arch, variant),
nvrs,
filter_packages=filter_packages,
)
# maybe check invalid sigkeys
def get_repos(self):
repos = []
for pkgset in self.package_sets:
if self.variant.pkgsets and pkgset.name not in self.variant.pkgsets:
continue
repos.append(pkgset.paths[self.arch])
return repos
def run_solver(self, variant, arch, packages, platform, filter_packages, cache_dir):
repos = self.get_repos()
results = set()
result_modules = set()
modules = []
for mmd in variant.arch_mmds.get(arch, {}).values():
modules.append("%s:%s" % (mmd.get_module_name(), mmd.get_stream_name()))
input_packages = []
for pkg_name, pkg_arch in packages:
input_packages.extend(self._expand_wildcard(pkg_name, pkg_arch))
step = 0
while True:
step += 1
conf_file = self.compose.paths.work.fus_conf(arch, variant, step)
fus.write_config(conf_file, sorted(modules), sorted(input_packages))
cmd = fus.get_cmd(
conf_file,
tree_arch_to_yum_arch(arch),
repos,
pungi.phases.gather.get_lookaside_repos(self.compose, arch, variant),
platform=platform,
filter_packages=filter_packages,
)
logfile = self.compose.paths.log.log_file(
arch, "hybrid-depsolver-%s-iter-%d" % (variant, step)
)
# Adding this environment variable will tell GLib not to prefix
# any log messages with the PID of the fus process (which is quite
# useless for us anyway).
env = os.environ.copy()
env["G_MESSAGES_PREFIXED"] = ""
env["XDG_CACHE_HOME"] = cache_dir
self.compose.log_debug(
"[BEGIN] Running fus (arch: %s, variant: %s)" % (arch, variant)
)
run(cmd, logfile=logfile, show_cmd=True, env=env)
output, out_modules = fus.parse_output(logfile)
self.compose.log_debug(
"[DONE ] Running fus (arch: %s, variant: %s)" % (arch, variant)
)
# No need to resolve modules again. They are not going to change.
modules = []
# Reset input packages as well to only solve newly added things.
input_packages = []
# Preserve the results from this iteration.
results.update(output)
result_modules.update(out_modules)
new_multilib = self.add_multilib(variant, arch, output)
input_packages.extend(
_fmt_pkg(pkg_name, pkg_arch)
for pkg_name, pkg_arch in sorted(new_multilib)
)
new_debuginfo = self.add_debuginfo(arch, output)
input_packages.extend(
_fmt_pkg(pkg_name, pkg_arch)
for pkg_name, pkg_arch in sorted(new_debuginfo)
)
new_langpacks = self.add_langpacks(output)
input_packages.extend(new_langpacks)
if not input_packages:
# Nothing new was added, we can stop now.
break
return results, result_modules
def add_multilib(self, variant, arch, nvrs):
added = set()
if not self.multilib_methods:
return []
for nvr, pkg_arch, flags in nvrs:
if (nvr, pkg_arch) in self.processed_multilib:
continue
self.processed_multilib.add((nvr, pkg_arch))
if "modular" in flags:
continue
if pkg_arch != arch:
# Not a native package, not checking to add multilib
continue
nevr = kobo.rpmlib.parse_nvr(nvr)
for add_arch in self.valid_arches:
if add_arch == arch:
continue
try:
multilib_candidate = self._get_package("%s.%s" % (nvr, add_arch))
except KeyError:
continue
if self.multilib.is_multilib(multilib_candidate):
added.add((nevr["name"], add_arch))
return added
def add_debuginfo(self, arch, nvrs):
added = set()
for nvr, pkg_arch, flags in nvrs:
if (nvr, pkg_arch) in self.processed_debuginfo:
continue
self.processed_debuginfo.add((nvr, pkg_arch))
if "modular" in flags:
continue
pkg = self._get_package("%s.%s" % (nvr, pkg_arch))
# There are two ways how the debuginfo package can be named. We
# want to get them all.
source_name = kobo.rpmlib.parse_nvra(pkg.rpm_sourcerpm)["name"]
for debuginfo_name in [
"%s-debuginfo" % pkg.name,
"%s-debugsource" % source_name,
]:
debuginfo = self._get_debuginfo(debuginfo_name, pkg_arch)
for dbg in debuginfo:
# For each debuginfo package that matches on name and
# architecture, we also need to check if it comes from the
# same build.
if dbg.sourcerpm == pkg.rpm_sourcerpm:
added.add((dbg.name, dbg.arch))
return added
def add_langpacks(self, nvrs):
if not self.langpacks:
return set()
added = set()
for nvr, pkg_arch, flags in nvrs:
if "modular" in flags:
continue
name = nvr.rsplit("-", 2)[0]
if name in self.added_langpacks:
# This package is already processed.
continue
added.update(self.langpacks.get(name, []))
self.added_langpacks.add(name)
return sorted(added)
def _expand_wildcard(self, pkg_name, pkg_arch):
if "*" not in pkg_name:
return [_fmt_pkg(pkg_name, pkg_arch)]
packages = []
for pkg in self.expand_list([pkg_name]):
if pkg_is_debug(pkg):
# No debuginfo
continue
if pkg_arch:
if pkg_arch != pkg.arch:
# Arch is specified and does not match, skip the package.
continue
else:
if pkg.arch not in ("noarch", self.arch):
# No arch specified and package does not match
continue
strict_nevra = "%s-%s:%s-%s.%s" % (
pkg.name,
pkg.epoch or "0",
pkg.version,
pkg.release,
pkg.arch,
)
if strict_nevra in self.modular_packages:
# Wildcards should not match modular packages.
continue
packages.append(_fmt_nevra(pkg, pkg.arch))
return packages
def iter_platforms_in_repo(url):
"""Find all platform streams that any module in give repo requires at runtime.
Yields lists of stream names (possible empty).
"""
repomd = os.path.join(url, "repodata/repomd.xml")
with as_local_file(repomd) as url_:
repomd = cr.Repomd(url_)
for rec in repomd.records:
if rec.type != "modules":
continue
# No with statement on Python 2.6 for GzipFile...
record_url = os.path.join(url, rec.location_href)
with as_local_file(record_url) as url_:
gzipped_file = gzip.GzipFile(url_, "rb")
mod_index = Modulemd.ModuleIndex.new()
mod_index.update_from_string(gzipped_file.read().decode("utf-8"), False)
gzipped_file.close()
for module_name in mod_index.get_module_names():
module = mod_index.get_module(module_name)
for module_stream in module.get_all_streams():
module_stream = module_stream.upgrade(2)
for dep in module_stream.get_dependencies():
yield dep.get_runtime_streams("platform")
def get_platform_from_lookasides(compose, variant, arch):
"""Find a set of all platform dependencies in all lookaside repos."""
platforms = set()
for repo in pungi.phases.gather.get_lookaside_repos(compose, arch, variant):
for ps in iter_platforms_in_repo(fus._prep_path(repo)):
platforms.update(ps)
return platforms
def get_platform(compose, variant, arch):
"""Find platform stream for modules. Raises RuntimeError if there are
conflicting requests.
"""
platforms = get_platform_from_lookasides(compose, variant, arch)
for var in compose.all_variants.values():
for mmd in var.arch_mmds.get(arch, {}).values():
for dep in mmd.get_dependencies():
streams = dep.get_runtime_streams("platform")
if streams:
platforms.update(streams)
if len(platforms) > 1:
raise RuntimeError("There are conflicting requests for platform.")
return list(platforms)[0] if platforms else None
def _fmt_pkg(pkg_name, arch):
if arch:
pkg_name += ".%s" % arch
return pkg_name
def _nevra(**kwargs):
if kwargs.get("epoch") not in (None, "", 0, "0"):
return "%(name)s-%(epoch)s:%(version)s-%(release)s.%(arch)s" % kwargs
return "%(name)s-%(version)s-%(release)s.%(arch)s" % kwargs
def _fmt_nevra(pkg, arch):
return _nevra(
name=pkg.name,
epoch=pkg.epoch,
version=pkg.version,
release=pkg.release,
arch=arch,
)
def _get_srpm_nevra(pkg):
nevra = kobo.rpmlib.parse_nvra(pkg.sourcerpm)
nevra["epoch"] = nevra["epoch"] or pkg.epoch
return _nevra(**nevra)
def _make_result(paths):
return [{"path": path, "flags": []} for path in sorted(paths)]
def get_repo_packages(path):
"""Extract file names of all packages in the given repository."""
packages = set()
def callback(pkg):
packages.add(os.path.basename(pkg.location_href))
repomd = os.path.join(path, "repodata/repomd.xml")
with as_local_file(repomd) as url_:
repomd = cr.Repomd(url_)
for rec in repomd.records:
if rec.type != "primary":
continue
record_url = os.path.join(path, rec.location_href)
with as_local_file(record_url) as url_:
cr.xml_parse_primary(url_, pkgcb=callback, do_files=False)
return packages
def expand_packages(nevra_to_pkg, lookasides, nvrs, filter_packages):
"""For each package add source RPM."""
# This will serve as the final result. We collect sets of paths to the
# packages.
rpms = set()
srpms = set()
debuginfo = set()
filters = set(filter_packages)
lookaside_packages = set()
for repo in lookasides:
lookaside_packages.update(get_repo_packages(repo))
for nvr, pkg_arch, flags in nvrs:
pkg = nevra_to_pkg["%s.%s" % (nvr, pkg_arch)]
if os.path.basename(pkg.file_path) in lookaside_packages:
# Fus can return lookaside package in output if the package is
# explicitly listed as input. This can happen during comps
# expansion.
continue
if pkg_is_debug(pkg):
debuginfo.add(pkg.file_path)
else:
rpms.add(pkg.file_path)
try:
srpm_nevra = _get_srpm_nevra(pkg)
srpm = nevra_to_pkg[srpm_nevra]
if (srpm.name, "src") in filters:
# Filtered package, skipping
continue
if os.path.basename(srpm.file_path) not in lookaside_packages:
srpms.add(srpm.file_path)
except KeyError:
# Didn't find source RPM.. this should be logged
pass
return _mk_pkg_map(_make_result(rpms), _make_result(srpms), _make_result(debuginfo))
def filter_modules(variant, arch, nsvcs_to_keep):
"""Remove any arch-specific module metadata from the module if it's not
listed in the list to keep. This will ultimately cause the module to not be
included in the final repodata and module metadata.
"""
for nsvc in list(variant.arch_mmds.get(arch, {}).keys()):
if nsvc not in nsvcs_to_keep:
del variant.arch_mmds[arch][nsvc]

View File

@ -0,0 +1,184 @@
# -*- coding: utf-8 -*-
# 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; version 2 of the License.
#
# 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 Library General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, see <https://gnu.org/licenses/>.
import os
from pprint import pformat
import re
import six
import pungi.arch
from pungi.util import pkg_is_rpm, pkg_is_srpm, pkg_is_debug
from pungi.wrappers.comps import CompsWrapper
from pungi.phases.pkgset.pkgsets import ExtendedRpmWrapper
import pungi.phases.gather.method
from kobo.pkgset import SimpleRpmWrapper, RpmWrapper
class GatherMethodNodeps(pungi.phases.gather.method.GatherMethodBase):
def __call__(self, arch, variant, *args, **kwargs):
fname = "gather-nodeps-%s" % variant.uid
if self.source_name:
fname += "-" + self.source_name
log_file = self.compose.paths.log.log_file(arch, fname)
with open(log_file, "w") as log:
return self.worker(log, arch, variant, *args, **kwargs)
def worker(
self,
log,
arch,
variant,
pkgs,
groups,
filter_packages,
multilib_whitelist,
multilib_blacklist,
package_sets,
path_prefix=None,
fulltree_excludes=None,
prepopulate=None,
):
result = {
"rpm": [],
"srpm": [],
"debuginfo": [],
}
group_packages = expand_groups(self.compose, arch, variant, groups)
packages = pkgs | group_packages
log.write("Requested packages:\n%s\n" % pformat(packages))
seen_rpms = {}
seen_srpms = {}
valid_arches = pungi.arch.get_valid_arches(arch, multilib=True)
compatible_arches = {}
for i in valid_arches:
compatible_arches[i] = pungi.arch.get_compatible_arches(i)
log.write("\nGathering rpms\n")
for pkg in iterate_packages(package_sets, arch):
if not pkg_is_rpm(pkg):
continue
for gathered_pkg, pkg_arch in packages:
if isinstance(gathered_pkg, six.string_types) and not re.match(
gathered_pkg.replace(".", "\\.")
.replace("+", "\\+")
.replace("*", ".*")
+ "$",
pkg.name,
):
continue
elif (
type(gathered_pkg)
in [SimpleRpmWrapper, RpmWrapper, ExtendedRpmWrapper]
and pkg.nevra != gathered_pkg.nevra
):
continue
if (
pkg_arch is not None
and pkg.arch != pkg_arch
and pkg.arch != "noarch"
):
continue
result["rpm"].append({"path": pkg.file_path, "flags": ["input"]})
seen_rpms.setdefault(pkg.name, set()).add(pkg.arch)
seen_srpms.setdefault(pkg.sourcerpm, set()).add(pkg.arch)
log.write(
"Added %s (matched %s.%s) (sourcerpm: %s)\n"
% (pkg, gathered_pkg, pkg_arch, pkg.sourcerpm)
)
log.write("\nGathering source rpms\n")
for pkg in iterate_packages(package_sets, arch):
if not pkg_is_srpm(pkg):
continue
if pkg.file_name in seen_srpms:
result["srpm"].append({"path": pkg.file_path, "flags": ["input"]})
log.write("Adding %s\n" % pkg)
log.write("\nGathering debuginfo packages\n")
for pkg in iterate_packages(package_sets, arch):
if not pkg_is_debug(pkg):
continue
if pkg.sourcerpm not in seen_srpms:
log.write("Not considering %s: corresponding srpm not included\n" % pkg)
continue
pkg_arches = set(compatible_arches[pkg.arch]) - set(["noarch"])
seen_arches = set(seen_srpms[pkg.sourcerpm]) - set(["noarch"])
if not (pkg_arches & seen_arches):
# We only want to pull in a debuginfo if we have a binary
# package for a compatible arch. Noarch packages should not
# pull debuginfo (they would pull in all architectures).
log.write("Not including %s: no package for this arch\n" % pkg)
continue
result["debuginfo"].append({"path": pkg.file_path, "flags": ["input"]})
log.write("Adding %s\n" % pkg)
return result
def expand_groups(compose, arch, variant, groups, set_pkg_arch=True):
"""Read comps file filtered for given architecture and variant and return
all packages in given groups.
:returns: A set of tuples (pkg_name, arch)
"""
if not groups:
# No groups, nothing to do (this also covers case when there is no
# comps file.
return set()
comps = []
comps_file = compose.paths.work.comps(arch, variant, create_dir=False)
comps.append(CompsWrapper(comps_file))
if variant and variant.parent:
parent_comps_file = compose.paths.work.comps(
arch, variant.parent, create_dir=False
)
comps.append(CompsWrapper(parent_comps_file))
if variant.type == "optional":
for v in variant.parent.variants.values():
if v.id == variant.id:
continue
comps_file = compose.paths.work.comps(arch, v, create_dir=False)
if os.path.exists(comps_file):
comps.append(CompsWrapper(comps_file))
packages = set()
pkg_arch = arch if set_pkg_arch else None
for group in groups:
found = False
ex = None
for c in comps:
try:
packages.update([(pkg, pkg_arch) for pkg in c.get_packages(group)])
found = True
break
except KeyError as e:
ex = e
if not found:
raise ex
return packages
def iterate_packages(package_sets, arch):
for pkgset in package_sets:
for pkg in pkgset[arch]:
yield pkgset[arch][pkg]

View File

@ -0,0 +1,19 @@
# -*- coding: utf-8 -*-
# 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; version 2 of the License.
#
# 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 Library General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, see <https://gnu.org/licenses/>.
class GatherSourceBase(object):
def __init__(self, compose):
self.compose = compose

View File

@ -0,0 +1,26 @@
# -*- coding: utf-8 -*-
# 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; version 2 of the License.
#
# 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 Library General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, see <https://gnu.org/licenses/>.
from .source_comps import GatherSourceComps
from .source_json import GatherSourceJson
from .source_module import GatherSourceModule
from .source_none import GatherSourceNone
ALL_SOURCES = {
"comps": GatherSourceComps,
"json": GatherSourceJson,
"module": GatherSourceModule,
"none": GatherSourceNone,
}

View File

@ -0,0 +1,42 @@
# -*- coding: utf-8 -*-
# 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; version 2 of the License.
#
# 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 Library General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, see <https://gnu.org/licenses/>.
"""
Get a package list based on comps.xml.
Input format:
see comps.dtd
Output:
set([(rpm_name, rpm_arch or None)])
"""
from pungi.wrappers.comps import CompsWrapper
import pungi.phases.gather.source
class GatherSourceComps(pungi.phases.gather.source.GatherSourceBase):
def __call__(self, arch, variant):
groups = set()
if not self.compose.conf.get("comps_file"):
return set(), set()
comps = CompsWrapper(self.compose.paths.work.comps(arch=arch, variant=variant))
for i in comps.get_comps_groups():
groups.add(i)
return set(), groups

View File

@ -0,0 +1,62 @@
# -*- coding: utf-8 -*-
# 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; version 2 of the License.
#
# 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 Library General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, see <https://gnu.org/licenses/>.
"""
Get a package list based on a JSON mapping.
Input format:
{
variant: {
tree_arch: {
rpm_name: [rpm_arch, rpm_arch, ... (or None for any/best arch)],
}
}
}
Output:
set([(rpm_name, rpm_arch or None)])
"""
import json
import os
import pungi.phases.gather.source
class GatherSourceJson(pungi.phases.gather.source.GatherSourceBase):
def __call__(self, arch, variant):
json_path = self.compose.conf.get("gather_source_mapping")
if not json_path:
return set(), set()
with open(os.path.join(self.compose.config_dir, json_path), "r") as f:
mapping = json.load(f)
packages = set()
if variant is None:
# get all packages for all variants
for variant_uid in mapping:
for pkg_name, pkg_arches in mapping[variant_uid].get(arch, {}).items():
for pkg_arch in pkg_arches:
packages.add((pkg_name, pkg_arch))
else:
# get packages for a particular variant
for pkg_name, pkg_arches in (
mapping.get(variant.uid, {}).get(arch, {}).items()
):
for pkg_arch in pkg_arches:
packages.add((pkg_name, pkg_arch))
return packages, set()

View File

@ -0,0 +1,52 @@
# -*- coding: utf-8 -*-
# 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; version 2 of the License.
#
# 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 Library General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, see <https://gnu.org/licenses/>.
"""
Get a package list based on modulemd metadata loaded in pkgset phase. Each
modulemd file contains a list of exact RPM NEVRAs that should be include, so
just go over all modules in a given variant and join all lists together.
"""
import pungi.arch
import pungi.phases.gather.source
class GatherSourceModule(pungi.phases.gather.source.GatherSourceBase):
def __call__(self, arch, variant):
groups = set()
packages = set()
# Check if there is a variant. The method only makes sense for variants.
if variant is None:
return packages, groups
compatible_arches = pungi.arch.get_compatible_arches(arch, multilib=True)
for nsvc, module_stream in variant.arch_mmds.get(arch, {}).items():
available_rpms = sum(
(
variant.nsvc_to_pkgset[nsvc].rpms_by_arch.get(a, [])
for a in compatible_arches
),
[],
)
to_include = set(module_stream.get_rpm_artifacts())
for rpm_obj in available_rpms:
if rpm_obj.nevra in to_include:
packages.add((rpm_obj, None))
return packages, groups

View File

@ -0,0 +1,33 @@
# -*- coding: utf-8 -*-
# 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; version 2 of the License.
#
# 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 Library General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, see <https://gnu.org/licenses/>.
"""
Get an empty package list.
Input:
none
Output:
set()
"""
import pungi.phases.gather.source
class GatherSourceNone(pungi.phases.gather.source.GatherSourceBase):
def __call__(self, arch, variant):
return set(), set()

526
pungi/phases/image_build.py Normal file
View File

@ -0,0 +1,526 @@
# -*- coding: utf-8 -*-
import copy
import hashlib
import json
import os
import shutil
import time
from kobo import shortcuts
from pungi.util import makedirs, get_mtime, get_file_size, failable, log_failed_task
from pungi.util import as_local_file, translate_path, get_repo_urls, version_generator
from pungi.phases import base
from pungi.linker import Linker
from pungi.wrappers.kojiwrapper import KojiWrapper
from kobo.threads import ThreadPool, WorkerThread
from kobo.shortcuts import force_list
from productmd.images import Image
from productmd.rpms import Rpms
# This is a mapping from formats to file extensions. The format is what koji
# image-build command expects as argument, and the extension is what the file
# name will be ending with. The extensions are used to filter out which task
# results will be pulled into the compose.
EXTENSIONS = {
"docker": ["tar.gz", "tar.xz"],
"iso": ["iso"],
"liveimg-squashfs": ["liveimg.squashfs"],
"qcow": ["qcow"],
"qcow2": ["qcow2"],
"raw": ["raw"],
"raw-xz": ["raw.xz"],
"rhevm-ova": ["rhevm.ova"],
"tar-gz": ["tar.gz"],
"vagrant-hyperv": ["vagrant-hyperv.box"],
"vagrant-libvirt": ["vagrant-libvirt.box"],
"vagrant-virtualbox": ["vagrant-virtualbox.box"],
"vagrant-vmware-fusion": ["vagrant-vmware-fusion.box"],
"vdi": ["vdi"],
"vmdk": ["vmdk"],
"vpc": ["vhd"],
"vhd-compressed": ["vhd.gz", "vhd.xz"],
"vsphere-ova": ["vsphere.ova"],
}
class ImageBuildPhase(
base.PhaseLoggerMixin, base.ImageConfigMixin, base.ConfigGuardedPhase
):
"""class for wrapping up koji image-build"""
name = "image_build"
def __init__(self, compose, buildinstall_phase=None):
super(ImageBuildPhase, self).__init__(compose)
self.pool = ThreadPool(logger=self.logger)
self.buildinstall_phase = buildinstall_phase
def _get_install_tree(self, image_conf, variant):
"""
Get a path to os tree for a variant specified in `install_tree_from` or
current variant. If the config is set, it will be removed from the
dict.
"""
if variant.type != "variant":
# Buildinstall only runs for top-level variants. Nested variants
# need to re-use install tree from parent.
variant = variant.parent
install_tree_from = image_conf.pop("install_tree_from", variant.uid)
if "://" in install_tree_from:
# It's a URL, return it unchanged
return install_tree_from
if install_tree_from.startswith("/"):
# It's a path on local filesystem.
return translate_path(self.compose, install_tree_from)
install_tree_source = self.compose.all_variants.get(install_tree_from)
if not install_tree_source:
raise RuntimeError(
"There is no variant %s to get install tree from "
"when building image for %s." % (install_tree_from, variant.uid)
)
return translate_path(
self.compose,
self.compose.paths.compose.os_tree(
"$arch", install_tree_source, create_dir=False
),
)
def _get_repo(self, image_conf, variant):
"""
Get a comma separated list of repos. First included are those
explicitly listed in config, followed by by repo for current variant
if it's not included in the list already.
"""
repos = shortcuts.force_list(image_conf.get("repo", []))
if not variant.is_empty and variant.uid not in repos:
repos.append(variant.uid)
return ",".join(get_repo_urls(self.compose, repos, arch="$arch"))
def _get_arches(self, image_conf, arches):
if "arches" in image_conf["image-build"]:
arches = set(image_conf["image-build"].get("arches", [])) & arches
return sorted(arches)
def _set_release(self, image_conf):
"""If release is set explicitly to None, replace it with date and respin."""
if "release" in image_conf:
image_conf["release"] = (
version_generator(self.compose, image_conf["release"])
or self.compose.image_release
)
def run(self):
for variant in self.compose.get_variants():
arches = set([x for x in variant.arches if x != "src"])
for image_conf in self.get_config_block(variant):
# We will modify the data, so we need to make a copy to
# prevent problems in next iteration where the original
# value is needed.
image_conf = copy.deepcopy(image_conf)
original_image_conf = copy.deepcopy(image_conf)
# image_conf is passed to get_image_build_cmd as dict
image_conf["image-build"]["arches"] = self._get_arches(
image_conf, arches
)
if not image_conf["image-build"]["arches"]:
continue
# Replace possible ambiguous ref name with explicit hash.
ksurl = self.get_ksurl(image_conf["image-build"])
if ksurl:
image_conf["image-build"]["ksurl"] = ksurl
image_conf["image-build"]["variant"] = variant
image_conf["image-build"]["install_tree"] = self._get_install_tree(
image_conf["image-build"], variant
)
release = self.get_release(image_conf["image-build"])
if release:
image_conf["image-build"]["release"] = release
image_conf["image-build"]["version"] = self.get_version(
image_conf["image-build"]
)
image_conf["image-build"]["target"] = self.get_config(
image_conf["image-build"], "target"
)
# Pungi config can either contain old [(format, suffix)], or
# just list of formats, or a single format.
formats = []
for format in force_list(image_conf["image-build"]["format"]):
formats.append(
format[0] if isinstance(format, (tuple, list)) else format
)
image_conf["image-build"]["format"] = formats
image_conf["image-build"]["repo"] = self._get_repo(
image_conf["image-build"], variant
)
can_fail = image_conf["image-build"].pop("failable", [])
if can_fail == ["*"]:
can_fail = image_conf["image-build"]["arches"]
if can_fail:
image_conf["image-build"]["can_fail"] = sorted(can_fail)
cmd = {
"original_image_conf": original_image_conf,
"image_conf": image_conf,
"conf_file": self.compose.paths.work.image_build_conf(
image_conf["image-build"]["variant"],
image_name=image_conf["image-build"]["name"],
image_type="-".join(formats),
arches=image_conf["image-build"]["arches"],
),
"image_dir": self.compose.paths.compose.image_dir(variant),
"relative_image_dir": self.compose.paths.compose.image_dir(
variant, relative=True
),
"link_type": self.compose.conf["link_type"],
"scratch": image_conf["image-build"].pop("scratch", False),
}
self.pool.add(CreateImageBuildThread(self.pool))
self.pool.queue_put((self.compose, cmd, self.buildinstall_phase))
self.pool.start()
class CreateImageBuildThread(WorkerThread):
def fail(self, compose, cmd):
self.pool.log_error("CreateImageBuild failed.")
def process(self, item, num):
compose, cmd, buildinstall_phase = item
variant = cmd["image_conf"]["image-build"]["variant"]
subvariant = cmd["image_conf"]["image-build"].get("subvariant", variant.uid)
self.failable_arches = cmd["image_conf"]["image-build"].get("can_fail", "")
self.can_fail = (
self.failable_arches == cmd["image_conf"]["image-build"]["arches"]
)
with failable(
compose,
self.can_fail,
variant,
"*",
"image-build",
subvariant,
logger=self.pool._logger,
):
self.worker(num, compose, variant, subvariant, cmd, buildinstall_phase)
def worker(self, num, compose, variant, subvariant, cmd, buildinstall_phase):
arches = cmd["image_conf"]["image-build"]["arches"]
formats = "-".join(cmd["image_conf"]["image-build"]["format"])
dash_arches = "-".join(arches)
log_file = compose.paths.log.log_file(
dash_arches, "imagebuild-%s-%s-%s" % (variant.uid, subvariant, formats)
)
metadata_file = log_file[:-4] + ".reuse.json"
external_repo_checksum = {}
try:
for repo in cmd["original_image_conf"]["image-build"]["repo"]:
if repo in compose.all_variants:
continue
with as_local_file(
os.path.join(repo, "repodata/repomd.xml")
) as filename:
with open(filename, "rb") as f:
external_repo_checksum[repo] = hashlib.sha256(
f.read()
).hexdigest()
except Exception as e:
external_repo_checksum = None
self.pool.log_info(
"Can't calculate checksum of repomd.xml of external repo - %s" % str(e)
)
if self._try_to_reuse(
compose,
variant,
subvariant,
metadata_file,
log_file,
cmd,
external_repo_checksum,
buildinstall_phase,
):
return
msg = (
"Creating image (formats: %s, arches: %s, variant: %s, subvariant: %s)"
% (formats, dash_arches, variant, subvariant)
)
self.pool.log_info("[BEGIN] %s" % msg)
koji_wrapper = KojiWrapper(compose)
# writes conf file for koji image-build
self.pool.log_info(
"Writing image-build config for %s.%s into %s"
% (variant, dash_arches, cmd["conf_file"])
)
koji_cmd = koji_wrapper.get_image_build_cmd(
cmd["image_conf"], conf_file_dest=cmd["conf_file"], scratch=cmd["scratch"]
)
# avoid race conditions?
# Kerberos authentication failed:
# Permission denied in replay cache code (-1765328215)
# [workaround] Increased time delay from 3 to 10 sec until the issue in
# koji gets fixed https://pagure.io/koji/issue/2138
time.sleep(num * 10)
output = koji_wrapper.run_blocking_cmd(koji_cmd, log_file=log_file)
self.pool.log_debug("build-image outputs: %s" % (output))
if output["retcode"] != 0:
self.fail(compose, cmd)
raise RuntimeError(
"ImageBuild task failed: %s. See %s for more details."
% (output["task_id"], log_file)
)
# copy image to images/
image_infos = []
paths = koji_wrapper.get_image_paths(
output["task_id"],
callback=lambda arch: log_failed_task(
compose, variant, arch, "image-build", subvariant
),
)
for arch, paths in paths.items():
for path in paths:
for format in cmd["image_conf"]["image-build"]["format"]:
for suffix in EXTENSIONS[format]:
if path.endswith(suffix):
image_infos.append(
{
"path": path,
"suffix": suffix,
"type": format,
"arch": arch,
}
)
break
self._link_images(compose, variant, subvariant, cmd, image_infos)
self._write_reuse_metadata(
compose, metadata_file, cmd, image_infos, external_repo_checksum
)
self.pool.log_info("[DONE ] %s (task id: %s)" % (msg, output["task_id"]))
def _link_images(self, compose, variant, subvariant, cmd, image_infos):
"""Link images to compose and update image manifest.
:param Compose compose: Current compose.
:param Variant variant: Current variant.
:param str subvariant:
:param dict cmd: Dict of params for image-build.
:param dict image_infos: Dict contains image info.
"""
# The usecase here is that you can run koji image-build with multiple --format
# It's ok to do it serialized since we're talking about max 2 images per single
# image_build record
linker = Linker(logger=self.pool._logger)
for image_info in image_infos:
image_dir = cmd["image_dir"] % {"arch": image_info["arch"]}
makedirs(image_dir)
relative_image_dir = cmd["relative_image_dir"] % {
"arch": image_info["arch"]
}
# let's not change filename of koji outputs
image_dest = os.path.join(image_dir, os.path.basename(image_info["path"]))
src_file = compose.koji_downloader.get_file(
os.path.realpath(image_info["path"])
)
linker.link(src_file, image_dest, link_type=cmd["link_type"])
# Update image manifest
img = Image(compose.im)
img.type = image_info["type"]
img.format = image_info["suffix"]
img.path = os.path.join(relative_image_dir, os.path.basename(image_dest))
img.mtime = get_mtime(image_dest)
img.size = get_file_size(image_dest)
img.arch = image_info["arch"]
img.disc_number = 1 # We don't expect multiple disks
img.disc_count = 1
img.bootable = False
img.subvariant = subvariant
setattr(img, "can_fail", self.can_fail)
setattr(img, "deliverable", "image-build")
compose.im.add(variant=variant.uid, arch=image_info["arch"], image=img)
def _try_to_reuse(
self,
compose,
variant,
subvariant,
metadata_file,
log_file,
cmd,
external_repo_checksum,
buildinstall_phase,
):
"""Try to reuse images from old compose.
:param Compose compose: Current compose.
:param Variant variant: Current variant.
:param str subvariant:
:param str metadata_file: Path to reuse metadata file.
:param str log_file: Path to log file.
:param dict cmd: Dict of params for image-build.
:param dict external_repo_checksum: Dict contains checksum of repomd.xml
or None if can't get checksum.
:param BuildinstallPhase buildinstall_phase: buildinstall phase of
current compose.
"""
log_msg = "Cannot reuse old image_build phase results - %s"
if not compose.conf["image_build_allow_reuse"]:
self.pool.log_info(
log_msg % "reuse of old image_build results is disabled."
)
return False
if external_repo_checksum is None:
self.pool.log_info(
log_msg % "Can't ensure that external repo is not changed."
)
return False
old_metadata_file = compose.paths.old_compose_path(metadata_file)
if not old_metadata_file:
self.pool.log_info(log_msg % "Can't find old reuse metadata file")
return False
try:
old_metadata = self._load_reuse_metadata(old_metadata_file)
except Exception as e:
self.pool.log_info(
log_msg % "Can't load old reuse metadata file: %s" % str(e)
)
return False
if old_metadata["cmd"]["original_image_conf"] != cmd["original_image_conf"]:
self.pool.log_info(log_msg % "image_build config changed")
return False
# Make sure external repo does not change
if (
old_metadata["external_repo_checksum"] is None
or old_metadata["external_repo_checksum"] != external_repo_checksum
):
self.pool.log_info(log_msg % "External repo may be changed")
return False
# Make sure buildinstall phase is reused
for arch in cmd["image_conf"]["image-build"]["arches"]:
if buildinstall_phase and not buildinstall_phase.reused(variant, arch):
self.pool.log_info(log_msg % "buildinstall phase changed")
return False
# Make sure packages in variant not change
rpm_manifest_file = compose.paths.compose.metadata("rpms.json")
rpm_manifest = Rpms()
rpm_manifest.load(rpm_manifest_file)
old_rpm_manifest_file = compose.paths.old_compose_path(rpm_manifest_file)
old_rpm_manifest = Rpms()
old_rpm_manifest.load(old_rpm_manifest_file)
for repo in cmd["original_image_conf"]["image-build"]["repo"]:
if repo not in compose.all_variants:
# External repos are checked using other logic.
continue
for arch in cmd["image_conf"]["image-build"]["arches"]:
if (
rpm_manifest.rpms[variant.uid][arch]
!= old_rpm_manifest.rpms[variant.uid][arch]
):
self.pool.log_info(
log_msg % "Packages in %s.%s changed." % (variant.uid, arch)
)
return False
self.pool.log_info(
"Reusing images from old compose for variant %s" % variant.uid
)
try:
self._link_images(
compose, variant, subvariant, cmd, old_metadata["image_infos"]
)
except Exception as e:
self.pool.log_info(log_msg % "Can't link images %s" % str(e))
return False
old_log_file = compose.paths.old_compose_path(log_file)
try:
shutil.copy2(old_log_file, log_file)
except Exception as e:
self.pool.log_info(
log_msg % "Can't copy old log_file: %s %s" % (old_log_file, str(e))
)
return False
self._write_reuse_metadata(
compose,
metadata_file,
cmd,
old_metadata["image_infos"],
external_repo_checksum,
)
return True
def _write_reuse_metadata(
self, compose, metadata_file, cmd, image_infos, external_repo_checksum
):
"""Write metadata file.
:param Compose compose: Current compose.
:param str metadata_file: Path to reuse metadata file.
:param dict cmd: Dict of params for image-build.
:param dict image_infos: Dict contains image info.
:param dict external_repo_checksum: Dict contains checksum of repomd.xml
or None if can't get checksum.
"""
msg = "Writing reuse metadata file: %s" % metadata_file
self.pool.log_info(msg)
cmd_copy = copy.deepcopy(cmd)
del cmd_copy["image_conf"]["image-build"]["variant"]
data = {
"cmd": cmd_copy,
"image_infos": image_infos,
"external_repo_checksum": external_repo_checksum,
}
try:
with open(metadata_file, "w") as f:
json.dump(data, f, indent=4)
except Exception as e:
self.pool.log_info("%s Failed: %s" % (msg, str(e)))
def _load_reuse_metadata(self, metadata_file):
"""Load metadata file.
:param str metadata_file: Path to reuse metadata file.
"""
with open(metadata_file, "r") as f:
return json.load(f)

View File

@ -0,0 +1,206 @@
# -*- coding: utf-8 -*-
import os
from kobo import shortcuts
from collections import defaultdict
import threading
from .base import PhaseBase
from ..util import get_format_substs, get_file_size
MULTIPLE_CHECKSUMS_ERROR = (
'Config option "media_checksum_one_file" requires only one checksum'
' to be configured in "media_checksums".'
)
class ImageChecksumPhase(PhaseBase):
"""Go through images specified in image manifest and generate their
checksums. The manifest will be updated with the checksums.
"""
name = "image_checksum"
def __init__(self, compose):
super(ImageChecksumPhase, self).__init__(compose)
self.checksums = self.compose.conf["media_checksums"]
self.one_file = self.compose.conf["media_checksum_one_file"]
def skip(self):
# Skipping this phase does not make sense:
# * if there are no images, it doesn't do anything and is quick
# * if there are images, they must have checksums computed or else
# writing metadata will fail
return False
def validate(self):
errors = []
if self.one_file and len(self.checksums) != 1:
errors.append(MULTIPLE_CHECKSUMS_ERROR)
if errors:
raise ValueError("\n".join(errors))
def _get_images(self):
"""Returns a mapping from directories to sets of ``Image``s.
The paths to dirs are absolute.
"""
top_dir = self.compose.paths.compose.topdir()
images = {}
for variant in self.compose.im.images:
for arch in self.compose.im.images[variant]:
for image in self.compose.im.images[variant][arch]:
path = os.path.dirname(os.path.join(top_dir, image.path))
images.setdefault((variant, arch, path), set()).add(image)
return images
def _get_base_filename(self, variant, arch, **kwargs):
base_checksum_name = self.compose.conf["media_checksum_base_filename"]
if base_checksum_name:
substs = get_format_substs(
self.compose, variant=variant, arch=arch, **kwargs
)
base_checksum_name = (base_checksum_name % substs).format(**substs)
base_checksum_name += "-"
return base_checksum_name
def run(self):
topdir = self.compose.paths.compose.topdir()
make_checksums(
topdir,
self.compose.im,
self.checksums,
self.one_file,
self._get_base_filename,
)
def _compute_checksums(
results,
cache,
variant,
arch,
path,
images,
checksum_types,
base_checksum_name_gen,
one_file,
results_lock,
cache_lock,
):
for image in images:
filename = os.path.basename(image.path)
full_path = os.path.join(path, filename)
if not os.path.exists(full_path):
continue
filesize = image.size or get_file_size(full_path)
cache_lock.acquire()
if full_path not in cache:
cache_lock.release()
# Source ISO is listed under each binary architecture. There's no
# point in checksumming it twice, so we can just remember the
# digest from first run..
checksum_value = shortcuts.compute_file_checksums(full_path, checksum_types)
with cache_lock:
cache[full_path] = checksum_value
else:
cache_lock.release()
with cache_lock:
digests = cache[full_path]
for checksum, digest in digests.items():
# Update metadata with the checksum
image.add_checksum(None, checksum, digest)
# If not turned of, create the file-specific checksum file
if not one_file:
checksum_filename = os.path.join(
path, "%s.%sSUM" % (filename, checksum.upper())
)
with results_lock:
results[checksum_filename].add(
(filename, filesize, checksum, digest)
)
if one_file:
dirname = os.path.basename(path)
base_checksum_name = base_checksum_name_gen(
variant, arch, dirname=dirname
)
checksum_filename = base_checksum_name + "CHECKSUM"
else:
base_checksum_name = base_checksum_name_gen(variant, arch)
checksum_filename = "%s%sSUM" % (base_checksum_name, checksum.upper())
checksum_path = os.path.join(path, checksum_filename)
with results_lock:
results[checksum_path].add((filename, filesize, checksum, digest))
def make_checksums(topdir, im, checksum_types, one_file, base_checksum_name_gen):
results = defaultdict(set)
cache = {}
threads = []
results_lock = threading.Lock() # lock to synchronize access to the results dict.
cache_lock = threading.Lock() # lock to synchronize access to the cache dict.
# create all worker threads
for (variant, arch, path), images in get_images(topdir, im).items():
threads.append(
threading.Thread(
target=_compute_checksums,
args=[
results,
cache,
variant,
arch,
path,
images,
checksum_types,
base_checksum_name_gen,
one_file,
results_lock,
cache_lock,
],
)
)
threads[-1].start()
# wait for all worker threads to finish
for thread in threads:
thread.join()
for file in results:
dump_checksums(file, results[file])
def dump_checksums(checksum_file, data):
"""Write checksums to file.
:param checksum_file: where to write the checksums
:param data: an iterable of tuples (filename, filesize, checksum_type, hash)
"""
with open(checksum_file, "w") as f:
for filename, filesize, alg, checksum in sorted(data):
f.write("# %s: %s bytes\n" % (filename, filesize))
f.write("%s (%s) = %s\n" % (alg.upper(), filename, checksum))
def get_images(top_dir, manifest):
"""Returns a mapping from directories to sets of ``Image``s.
The paths to dirs are absolute.
"""
images = {}
for variant in manifest.images:
for arch in manifest.images[variant]:
for image in manifest.images[variant][arch]:
path = os.path.dirname(os.path.join(top_dir, image.path))
images.setdefault((variant, arch, path), []).append(image)
return images

Some files were not shown because too many files have changed in this diff Show More