2019-01-23 17:53:08 +03:00
#!/bin/bash
set -xeuo pipefail
dn = $( cd $( dirname $0 ) && pwd )
. ${ dn } /libcomposetest.sh
prepare_compose_test "lockfile"
# Add a local rpm-md repo so we can mutate local test packages
pyappendjsonmember "repos" '["test-repo"]'
core: Strengthen how we enforce lockfiles
One problem with how we use lockfiles right now is that we don't enforce
them for dependencies. That is, if `foo` requires `bar`, but only `foo`
is in the manifest, then while `foo` will be locked, `bar` will never
be checked against the lockfile because it was never explicitly
requested.
Higher-level though, I don't like how indirect the locking here feels.
See some comments about that in:
https://github.com/projectatomic/rpm-ostree/pull/1745#discussion_r288772527
https://github.com/projectatomic/rpm-ostree/pull/1745#discussion_r289419017
Essentially, the manifest is an input file of patterns, and all we
really know from the lockfile output is that the set of packages in
there satisfies this input in some way. But:
1. there are multiple ways to satisfy the same input (hence why hints
like `SOLVER_FAVOR` exist)
2. the solution is dependent on how the solver is implemented (i.e.
different libsolv versions might yield different solutions)
3. the solution is dependent on flags fed to the solver (i.e. different
libdnf versions might yield different solutions)
So any attempt at cross-checking between the input file and the lockfile
is going to be very hard. Using a stricter mode as I suggested in #1745
of only allowing pure pkgnames or NEVRAs would help, but it wouldn't
address the dependency issue. (Though I'm still thinking about possibly
doing this anyway.)
The solution I propose here is instead to take the nuclear approach: we
completely exclude from the sack all packages of the same name as
packages in our lockfiles, but which do not match the NEVRA. Therefore,
any possible solution has to also satisfy our lockfile (or error out).
Closes: #1849
Approved by: cgwalters
2019-06-05 22:05:22 +03:00
build_rpm test-pkg-common
build_rpm test-pkg requires test-pkg-common
2019-07-10 16:52:54 +03:00
build_rpm another-test-pkg
2019-01-23 17:53:08 +03:00
# The test suite writes to pwd, but we need repos in composedata
# Also we need to disable gpgcheck
echo gpgcheck = 0 >> yumrepo.repo
ln yumrepo.repo composedata/test-repo.repo
2019-07-10 16:52:54 +03:00
pyappendjsonmember "packages" '["test-pkg", "another-test-pkg"]'
2019-01-23 17:53:08 +03:00
pysetjsonmember "documentation" 'False'
mkdir cache
# Create lockfile
runcompose --ex-write-lockfile-to= $PWD /versions.lock --cachedir $( pwd ) /cache
2019-07-10 16:50:30 +03:00
rpm-ostree --repo= ${ repobuild } db list ${ treeref } > test-pkg-list.txt
2019-01-23 17:53:08 +03:00
assert_file_has_content test-pkg-list.txt 'test-pkg-1.0-1.x86_64'
2019-07-10 16:52:54 +03:00
assert_file_has_content test-pkg-list.txt 'another-test-pkg-1.0-1.x86_64'
2019-01-23 17:53:08 +03:00
echo "ok compose"
assert_has_file "versions.lock"
2019-07-10 16:50:30 +03:00
assert_jq versions.lock \
'.packages["test-pkg"].evra = "1.0-1.x86_64"' \
2019-07-10 16:52:54 +03:00
'.packages["test-pkg-common"].evra = "1.0-1.x86_64"' \
'.packages["another-test-pkg"].evra = "1.0-1.x86_64"'
2019-07-10 16:50:30 +03:00
echo "ok lockfile created"
2019-01-23 17:53:08 +03:00
# Read lockfile back
core: Strengthen how we enforce lockfiles
One problem with how we use lockfiles right now is that we don't enforce
them for dependencies. That is, if `foo` requires `bar`, but only `foo`
is in the manifest, then while `foo` will be locked, `bar` will never
be checked against the lockfile because it was never explicitly
requested.
Higher-level though, I don't like how indirect the locking here feels.
See some comments about that in:
https://github.com/projectatomic/rpm-ostree/pull/1745#discussion_r288772527
https://github.com/projectatomic/rpm-ostree/pull/1745#discussion_r289419017
Essentially, the manifest is an input file of patterns, and all we
really know from the lockfile output is that the set of packages in
there satisfies this input in some way. But:
1. there are multiple ways to satisfy the same input (hence why hints
like `SOLVER_FAVOR` exist)
2. the solution is dependent on how the solver is implemented (i.e.
different libsolv versions might yield different solutions)
3. the solution is dependent on flags fed to the solver (i.e. different
libdnf versions might yield different solutions)
So any attempt at cross-checking between the input file and the lockfile
is going to be very hard. Using a stricter mode as I suggested in #1745
of only allowing pure pkgnames or NEVRAs would help, but it wouldn't
address the dependency issue. (Though I'm still thinking about possibly
doing this anyway.)
The solution I propose here is instead to take the nuclear approach: we
completely exclude from the sack all packages of the same name as
packages in our lockfiles, but which do not match the NEVRA. Therefore,
any possible solution has to also satisfy our lockfile (or error out).
Closes: #1849
Approved by: cgwalters
2019-06-05 22:05:22 +03:00
build_rpm test-pkg-common version 2.0
build_rpm test-pkg version 2.0 requires test-pkg-common
2019-07-10 16:52:54 +03:00
build_rpm another-test-pkg version 2.0
2019-01-23 17:53:08 +03:00
runcompose --ex-lockfile= $PWD /versions.lock --cachedir $( pwd ) /cache
echo "ok compose with lockfile"
core: Strengthen how we enforce lockfiles
One problem with how we use lockfiles right now is that we don't enforce
them for dependencies. That is, if `foo` requires `bar`, but only `foo`
is in the manifest, then while `foo` will be locked, `bar` will never
be checked against the lockfile because it was never explicitly
requested.
Higher-level though, I don't like how indirect the locking here feels.
See some comments about that in:
https://github.com/projectatomic/rpm-ostree/pull/1745#discussion_r288772527
https://github.com/projectatomic/rpm-ostree/pull/1745#discussion_r289419017
Essentially, the manifest is an input file of patterns, and all we
really know from the lockfile output is that the set of packages in
there satisfies this input in some way. But:
1. there are multiple ways to satisfy the same input (hence why hints
like `SOLVER_FAVOR` exist)
2. the solution is dependent on how the solver is implemented (i.e.
different libsolv versions might yield different solutions)
3. the solution is dependent on flags fed to the solver (i.e. different
libdnf versions might yield different solutions)
So any attempt at cross-checking between the input file and the lockfile
is going to be very hard. Using a stricter mode as I suggested in #1745
of only allowing pure pkgnames or NEVRAs would help, but it wouldn't
address the dependency issue. (Though I'm still thinking about possibly
doing this anyway.)
The solution I propose here is instead to take the nuclear approach: we
completely exclude from the sack all packages of the same name as
packages in our lockfiles, but which do not match the NEVRA. Therefore,
any possible solution has to also satisfy our lockfile (or error out).
Closes: #1849
Approved by: cgwalters
2019-06-05 22:05:22 +03:00
rpm-ostree --repo= ${ repobuild } db list ${ treeref } > test-pkg-list.txt
2019-01-23 17:53:08 +03:00
assert_file_has_content test-pkg-list.txt 'test-pkg-1.0-1.x86_64'
core: Strengthen how we enforce lockfiles
One problem with how we use lockfiles right now is that we don't enforce
them for dependencies. That is, if `foo` requires `bar`, but only `foo`
is in the manifest, then while `foo` will be locked, `bar` will never
be checked against the lockfile because it was never explicitly
requested.
Higher-level though, I don't like how indirect the locking here feels.
See some comments about that in:
https://github.com/projectatomic/rpm-ostree/pull/1745#discussion_r288772527
https://github.com/projectatomic/rpm-ostree/pull/1745#discussion_r289419017
Essentially, the manifest is an input file of patterns, and all we
really know from the lockfile output is that the set of packages in
there satisfies this input in some way. But:
1. there are multiple ways to satisfy the same input (hence why hints
like `SOLVER_FAVOR` exist)
2. the solution is dependent on how the solver is implemented (i.e.
different libsolv versions might yield different solutions)
3. the solution is dependent on flags fed to the solver (i.e. different
libdnf versions might yield different solutions)
So any attempt at cross-checking between the input file and the lockfile
is going to be very hard. Using a stricter mode as I suggested in #1745
of only allowing pure pkgnames or NEVRAs would help, but it wouldn't
address the dependency issue. (Though I'm still thinking about possibly
doing this anyway.)
The solution I propose here is instead to take the nuclear approach: we
completely exclude from the sack all packages of the same name as
packages in our lockfiles, but which do not match the NEVRA. Therefore,
any possible solution has to also satisfy our lockfile (or error out).
Closes: #1849
Approved by: cgwalters
2019-06-05 22:05:22 +03:00
assert_file_has_content test-pkg-list.txt 'test-pkg-common-1.0-1.x86_64'
2019-07-10 16:52:54 +03:00
assert_file_has_content test-pkg-list.txt 'another-test-pkg-1.0-1.x86_64'
echo "ok lockfile read"
# now add an override and check that not specifying a digest is allowed
cat > override.lock <<EOF
{
"packages" : {
"another-test-pkg" : {
"evra" : "2.0-1.x86_64"
}
}
}
EOF
runcompose --dry-run \
--ex-lockfile= $PWD /versions.lock \
--ex-lockfile= $PWD /override.lock \
--ex-write-lockfile-to= $PWD /versions.lock \
--cachedir $( pwd ) /cache | & tee out.txt
echo "ok compose with lockfile"
assert_file_has_content out.txt 'test-pkg-1.0-1.x86_64'
assert_file_has_content out.txt 'test-pkg-common-1.0-1.x86_64'
assert_file_has_content out.txt 'another-test-pkg-2.0-1.x86_64'
assert_jq versions.lock \
'.packages["test-pkg"].evra = "1.0-1.x86_64"' \
'.packages["test-pkg-common"].evra = "1.0-1.x86_64"' \
'.packages["another-test-pkg"].evra = "2.0-1.x86_64"'
echo "ok override"