%%EVR macro (for intersubpackage deps) upgraded to include %%disttag (ALT#35930)

%EVR was introduced to be used in spec-files for intersubpackage
(strict) dependencies.

What if we write (when substituting %%EVR) E:V-R:D into dependencies
instead of the previously written E:V-R? Will the interpretation of
these dependencies by rpm change (when installing packages) in a good
or bad way in any cases?

The "dependencies" can be Requires, Conflicts, Obsoletes.

rpm-build already produces packages which include disttags (D), and
Provides in the form of E:V-R:D, and strict intersubpackage
dependencies of such form (Requires; generated automatically).
Intersubpackage Requires in the form "< %EVR" or "> %EVR" don't make
sense. So, the interesting cases this change can affect are:

* Conflicts of the form "< %EVR" or "> %EVR" or "= %EVR" (the last one
must be quite rare);

* Obsoletes of the form "< %EVR" ("= %EVR" makes little sense;
"> %EVR" looks strange because it's about obsoleting packages from future).

The rpm program can be "new" (which knows how to compare E:V-R:Ds with
disttags; since 4.13.0.1-alt5) or "old" (does not yet know it;
4.13.0.1-alt4 or earlier).
(rpm-build already produces "new" packages, i.e., with disttags.)

The "new" rpm program is considered to be the correct reference way to
treat disttags. According to it, the presence of a disttag in a < or >
dependency cannot affect its interpretation (whether it is satisfied
by another package). Adding a disttag to a = dependency would simply
make it more strict (and that's what rpm-build already does under the
hood for intersubpackage deps). So, E:V-R:D deps are OK for the "new"
rpm.

So, what about about the "old" rpm?

Let's pay attention to the cases where the "old" rpm behaves
differently from the "new" rpm.

Such differences can be demonstrated by running
rpminstall-tests-1.0-alt2.M70P.1 in a system with an "old" rpm and a
"new" rpm-build (that can produce packages with disttags).

Here are the interesting failed test cases without disttag in the dependencies
(like before the change made by this commit), i.e. with dependencies
in the form E:V-R written in Conflicts or Obsoletes:

* installable_dummyDisttag_with_conflGreaterEpoch (and similar ones)

$ rpm -qp RPMS/dummyDisttag/noarch/dummy-1-alt1.noarch.rpm --provides
dummy = 1-alt1:zzz+777.66
$ rpm -qp RPMS/conflGreaterEpoch/noarch/conflGreaterEpoch-1-alt1.noarch.rpm --conflicts
dummy > 0:1-alt1
$ rpm -i RPMS/dummyDisttag/noarch/dummy-1-alt1.noarch.rpm RPMS/conflGreaterEpoch/noarch/conflGreaterEpoch-1-alt1.noarch.rpm
error: Failed dependencies:
	dummy > 0:1-alt1 conflicts with conflGreaterEpoch-1-alt1.noarch

NOT OK (ALT#35930): this form of Conflicts is used to ensure that no
subpackages from different releases/builds get installed together.

* noninstallable_dummyDisttag_with_conflEqualEpoch (and similar ones)

$ rpm -qp RPMS/conflEqualEpoch/noarch/conflEqualEpoch-1-alt1.noarch.rpm --conflicts
dummy = 0:1-alt1
$ rpm -i RPMS/dummyDisttag/noarch/dummy-1-alt1.noarch.rpm RPMS/conflEqualEpoch/noarch/conflEqualEpoch-1-alt1.noarch.rpm

succeeds

NOT OK: this form of conflicts could be used to declare conflicting subpackages.

Here are the interesting failed test cases with disttag in the
dependencies (like after the change made by this commit), i.e. with
dependencies in the form E:V-R:D written in Conflicts or Obsoletes:

* installable_dummy_with_conflLessEpochDisttag (and similar ones),

$ rpm -qp RPMS/dummy/noarch/dummy-1-alt1.noarch.rpm --provides
dummy = 1-alt1
$ rpm -qp RPMS/conflLessEpochDisttag/noarch/conflLessEpochDisttag-1-alt1.noarch.rpm --conflicts
dummy < 0:1-alt1:zzz+777.66
$ rpm -i RPMS/dummy/noarch/dummy-1-alt1.noarch.rpm RPMS/conflLessEpochDisttag/noarch/conflLessEpochDisttag-1-alt1.noarch.rpm
error: Failed dependencies:
	dummy < 0:1-alt1:zzz+777.66 conflicts with conflLessEpochDisttag-1-alt1.noarch

OK: dummy-1-alt1.noarch.rpm is from another build (if built with the
"new" rpm-build, it would include the disttag in Provides). This form
of Conflicts is used to ensure that no subpackages from different
releases/builds get installed together. The difference in behavior
with the "new" rpm is explained by that the "new" rpm cannot
(unfortunately) detect this subtle mismatch.

* nonobsoleted_dummy_with_obsolLessEpochDisttag (and similar ones)

(like the previous case)

$ rpm -qp RPMS/obsolLessEpochDisttag/noarch/obsolLessEpochDisttag-1-alt1.noarch.rpm --obsoletes
dummy < 0:1-alt1:zzz+777.66
$ rpm -i RPMS/dummy/noarch/dummy-1-alt1.noarch.rpm RPMS/obsolLessEpochDisttag/noarch/obsolLessEpochDisttag-1-alt1.noarch.rpm
$ rpm -q dummy
package dummy is not installed

OK

* nonobsoleted_dummyDisttag_with_obsolLessEpochDisttag (and similar ones)

$ rpm -qp RPMS/dummyDisttag/noarch/dummy-1-alt1.noarch.rpm --provides
dummy = 1-alt1:zzz+777.66
$ rpm -qp RPMS/obsolLessEpochDisttag/noarch/obsolLessEpochDisttag-1-alt1.noarch.rpm --obsoletes
dummy < 0:1-alt1:zzz+777.66
$ rpm -i RPMS/dummyDisttag/noarch/dummy-1-alt1.noarch.rpm RPMS/obsolLessEpochDisttag/noarch/obsolLessEpochDisttag-1-alt1.noarch.rpm
$ rpm -q dummy
package dummy is not installed

NOT OK, but very improbable (the real name of the subpackage must be
the same as the obsoleted name of an older package, but the obsoleting
package is a different subpackage; so, it's improbable that one keeps
the old name of a subpackage, but wants to obsolete it with another
subpackage).

So, introducing this change to the %EVR value would make the new
packages be treated better by the "old" rpm; even the treatment in the
cases where the behavior is different from the behavior of the "new"
rpm is good (except for one improbable case).
This commit is contained in:
Ivan Zakharyaschev 2019-01-21 16:51:33 +03:00
parent 6670035689
commit 66e8bff6e4

View File

@ -560,7 +560,7 @@
@alt@%systemd_unitdir %_unitdir
@alt@%make_session %nil
@alt@
@alt@%EVR %{?epoch:%epoch:}%{version}-%{release}
@alt@%EVR %{?epoch:%epoch:}%{version}-%{release}%{?disttag::%disttag}
@alt@
@alt@# GCC versioning.
@alt@%__gcc_version %(gcc -dumpversion)