rpm-ostree/tests/vmcheck/test-override-remove.sh
Jonathan Lebon 4686e15b94 core: handle shared files and multilib
Not all files from an RPM are necessarily removed during pkg erasure.
For example, files which are shared between pkgs shouldn't be deleted.
Similarly, not all files in an RPM are necessarily copied during pkg
installs. This is the case for multilib handling, which is a mess in its
own right. But such is the cost of trying to replace major parts of a
long-standing foundational project like RPM.

This patch adds some smarts to the way we do overlays and overrides to
handle these cases by calculating beforehand which files we *should't*
checkout/delete.

Closes: #1217
Closes: #1145

Closes: #1227
Approved by: cgwalters
2018-02-08 21:58:55 +00:00

207 lines
8.2 KiB
Bash
Executable File

#!/bin/bash
#
# Copyright (C) 2017 Red Hat, Inc.
#
# This library 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 of the License, or (at your option) any later version.
#
# This library 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 library; if not, write to the
# Free Software Foundation, Inc., 59 Temple Place - Suite 330,
# Boston, MA 02111-1307, USA.
set -euo pipefail
. ${commondir}/libtest.sh
. ${commondir}/libvm.sh
set -x
# create a new vmcheck commit which has foo and bar in it already so that we can
# target them with our override
# make sure the packages are not already layered
vm_assert_layered_pkg foo absent
vm_assert_layered_pkg bar absent
vm_assert_status_jq \
'.deployments[0]["base-checksum"]|not' \
'.deployments[0]["pending-base-checksum"]|not' \
'.deployments[0]["base-removals"]|length == 0' \
'.deployments[0]["requested-base-removals"]|length == 0'
vm_cmd ostree refs $(vm_get_booted_csum) \
--create vmcheck_tmp/without_foo_and_bar
# create a new branch with foo and bar.
# foo has files in /lib, to test our re-canonicalization to /usr
vm_build_rpm foo \
files "%dir /lib/foo
/lib/foo/foo.txt
/lib/foo/shared.txt" \
install 'mkdir -p %{buildroot}/lib/foo && \
echo %{name} > %{buildroot}/lib/foo/foo.txt && \
echo shared > %{buildroot}/lib/foo/shared.txt'
# make bar co-own /lib/foo and /lib/foo/shared.txt
vm_build_rpm bar \
files "%dir /lib/foo
/lib/foo/bar.txt
/lib/foo/shared.txt" \
install 'mkdir -p %{buildroot}/lib/foo && \
echo %{name} > %{buildroot}/lib/foo/bar.txt && \
echo shared > %{buildroot}/lib/foo/shared.txt'
vm_rpmostree install foo bar
vm_cmd ostree refs $(vm_get_deployment_info 0 checksum) \
--create vmcheck_tmp/with_foo_and_bar
vm_rpmostree cleanup -p
# upgrade to new commit with foo in the base layer
vm_cmd ostree commit -b vmcheck --tree=ref=vmcheck_tmp/with_foo_and_bar
vm_rpmostree upgrade
vm_reboot
if ! vm_has_packages foo bar; then
assert_not_reached "foo or bar not in base layer"
fi
echo "ok setup"
# And now we move the local cache; this will force an error if we ever try to
# reach the repo. This implicitly tests that `override remove/reset` operate in
# cache-only mode.
vm_rpmostree cleanup --repomd
vm_cmd mv /tmp/vmcheck/yumrepo{,.bak}
# funky jq syntax: see test-override-local-replace.sh for an explanation of how
# this works. the only difference here is the [.0] which we use to access the
# nevra of each gv_nevra element.
# remove just bar first to check deletion handling
vm_rpmostree override remove bar
vm_assert_status_jq \
'.deployments[0]["base-removals"]|length == 1' \
'[.deployments[0]["base-removals"][][.0]]|index("bar-1.0-1.x86_64") >= 0' \
'.deployments[0]["requested-base-removals"]|length == 1' \
'.deployments[0]["requested-base-removals"]|index("bar") >= 0'
newroot=$(vm_get_deployment_root 0)
# And test that we removed fully owned files, but not shared files
vm_cmd "test -d ${newroot}/usr/lib/foo && \
test -f ${newroot}/usr/lib/foo/foo.txt && \
test -f ${newroot}/usr/lib/foo/shared.txt && \
test ! -f ${newroot}/usr/lib/foo/bar.txt"
echo "ok override remove bar"
# now also remove foo
vm_rpmostree override remove foo
vm_assert_status_jq \
'.deployments[0]["base-removals"]|length == 2' \
'[.deployments[0]["base-removals"][][.0]]|index("foo-1.0-1.x86_64") >= 0' \
'[.deployments[0]["base-removals"][][.0]]|index("bar-1.0-1.x86_64") >= 0' \
'.deployments[0]["requested-base-removals"]|length == 2' \
'.deployments[0]["requested-base-removals"]|index("foo") >= 0' \
'.deployments[0]["requested-base-removals"]|index("bar") >= 0'
newroot=$(vm_get_deployment_root 0)
# And this tests handling /lib -> /usr/lib as well as removal of shared files
vm_cmd "test -d ${newroot}/usr/lib && \
test '!' -f ${newroot}/usr/lib/foo/foo.txt && \
test '!' -f ${newroot}/usr/lib/foo/shared.txt && \
test '!' -d ${newroot}/usr/lib/foo"
echo "ok override remove foo and bar"
vm_cmd ostree commit -b vmcheck --tree=ref=vmcheck
vm_rpmostree upgrade --cache-only
vm_assert_status_jq \
'.deployments[0]["base-removals"]|length == 2' \
'[.deployments[0]["base-removals"][][.0]]|index("foo-1.0-1.x86_64") >= 0' \
'[.deployments[0]["base-removals"][][.0]]|index("bar-1.0-1.x86_64") >= 0' \
'.deployments[0]["requested-base-removals"]|length == 2' \
'.deployments[0]["requested-base-removals"]|index("foo") >= 0' \
'.deployments[0]["requested-base-removals"]|index("bar") >= 0'
echo "ok override remove carried through upgrade"
vm_rpmostree override reset foo
vm_assert_status_jq \
'.deployments[0]["base-removals"]|length == 1' \
'[.deployments[0]["base-removals"][][.0]]|index("bar-1.0-1.x86_64") >= 0' \
'.deployments[0]["requested-base-removals"]|length == 1' \
'.deployments[0]["requested-base-removals"]|index("bar") >= 0'
echo "ok override reset foo"
vm_rpmostree override reset --all
vm_assert_status_jq \
'.deployments[0]["base-removals"]|length == 0' \
'.deployments[0]["requested-base-removals"]|length == 0'
echo "ok override reset --all"
# check that upgrading to a base without foo works
vm_rpmostree override remove foo
vm_assert_status_jq \
'.deployments[0]["base-removals"]|length == 1' \
'[.deployments[0]["base-removals"][][.0]]|index("foo-1.0-1.x86_64") >= 0' \
'.deployments[0]["requested-base-removals"]|length == 1' \
'.deployments[0]["requested-base-removals"]|index("foo") >= 0'
vm_cmd ostree commit -b vmcheck --tree=ref=vmcheck_tmp/without_foo_and_bar
vm_rpmostree upgrade --cache-only
vm_assert_status_jq \
'.deployments[0]["base-removals"]|length == 0' \
'.deployments[0]["requested-base-removals"]|length == 1' \
'.deployments[0]["requested-base-removals"]|index("foo") >= 0'
echo "ok override remove requested but not applied"
# check that upgrading again to a base with foo turns the override back on
vm_cmd ostree commit -b vmcheck --tree=ref=vmcheck_tmp/with_foo_and_bar
vm_rpmostree upgrade --cache-only
vm_assert_status_jq \
'.deployments[0]["base-removals"]|length == 1' \
'[.deployments[0]["base-removals"][][.0]]|index("foo-1.0-1.x86_64") >= 0' \
'.deployments[0]["requested-base-removals"]|length == 1' \
'.deployments[0]["requested-base-removals"]|index("foo") >= 0'
echo "ok override remove re-applied"
vm_rpmostree cleanup -p
# Restore the local yum repo.
vm_cmd mv /tmp/vmcheck/yumrepo{.bak,}
echo "ok override remove/reset operate offline"
# a few error checks
if vm_rpmostree override remove non-existent-package; then
assert_not_reached "override remove non-existent-package succeeded?"
fi
echo "ok override remove non-existent-package fails"
vm_rpmostree install foo
if vm_rpmostree override remove foo; then
assert_not_reached "override remove layered pkg foo succeeded?"
fi
vm_rpmostree cleanup -p
echo "ok override remove layered pkg foo fails"
# the next two error checks expect an upgraded layer with foo builtin
vm_cmd ostree commit -b vmcheck --tree=ref=vmcheck_tmp/with_foo_and_bar
vm_rpmostree upgrade
vm_rpmostree override remove foo
if vm_rpmostree install foo; then
assert_not_reached "tried to layer pkg removed by override"
fi
# the check blocking this isn't related to overrides, though for consistency
# let's make sure this fails here too
if vm_rpmostree install /tmp/vmcheck/yumrepo/packages/x86_64/foo-1.0-1.x86_64.rpm; then
assert_not_reached "tried to layer local pkg removed by override"
fi
vm_rpmostree cleanup -p
echo "ok can't layer pkg removed by override"
vm_build_rpm foo-ext requires "foo = 1.0-1"
vm_rpmostree upgrade --install foo-ext
if vm_rpmostree override remove foo; then
assert_not_reached "override remove base pkg needed by layered pkg succeeded?"
fi
vm_rpmostree cleanup -p
echo "ok override remove base dep to layered pkg fails"