commit:     1e9f25d74fd6df7ef54edffe496499dc1711e911
Author:     Sam James <sam <AT> gentoo <DOT> org>
AuthorDate: Sun Dec 31 18:14:33 2023 +0000
Commit:     Sam James <sam <AT> gentoo <DOT> org>
CommitDate: Sun Dec 31 22:23:27 2023 +0000
URL:        https://gitweb.gentoo.org/proj/portage.git/commit/?id=1e9f25d7

gpkg: fix basename handling via aux_update

When using a binpkg with BUILD_ID, we might sometimes get a UserWarning
for mismatched/corrupt gpkg structure:
```
UserWarning: gpkg file structure mismatch in 
/tmp/tmpo1x85ec1/pkgdir/dev-libs/B/B-1-1.gpkg.tar; files: ['B-1/gpkg-1', 
'B-1-1/metadata.tar.zst', 'B-1/image.tar.zst', 'B-1-1/Manifest']
    warnings.warn(e)
```

update_metadata directly uses self.prefix instead of self.basename, while
e.g. _get_inner_tarinfo prefers self.basename > self.prefix > error.

Given update_metadata calls _create_tarinfo, use the same logic as it
and _get_inner_tarinfo to avoid corrupting the filename for the image.

Bug: https://bugs.gentoo.org/920828
Thanks-to: Zac Medico <zmedico <AT> gentoo.org>
Signed-off-by: Sam James <sam <AT> gentoo.org>

 lib/portage/gpkg.py                       |  9 ++-
 lib/portage/tests/update/test_move_ent.py | 92 ++++++++++++++++++++++++++++++-
 2 files changed, 97 insertions(+), 4 deletions(-)

diff --git a/lib/portage/gpkg.py b/lib/portage/gpkg.py
index 2e1130857b..031b3f87cb 100644
--- a/lib/portage/gpkg.py
+++ b/lib/portage/gpkg.py
@@ -998,13 +998,16 @@ class gpkg:
         """
         self._verify_binpkg()
         self.checksums = []
-        old_basename = self.prefix
-
         if self.signature_exist and not force:
             raise SignedPackage("Cannot update a signed gpkg file")
 
         if new_basename is None:
-            new_basename = old_basename
+            if self.basename:
+                new_basename = self.basename
+            elif self.prefix:
+                new_basename = self.prefix
+            else:
+                raise InvalidBinaryPackageFormat("No basename or prefix 
specified")
         else:
             new_basename = new_basename.split("/", maxsplit=1)[-1]
             self.basename = new_basename

diff --git a/lib/portage/tests/update/test_move_ent.py 
b/lib/portage/tests/update/test_move_ent.py
index 436b846cf3..169b892a30 100644
--- a/lib/portage/tests/update/test_move_ent.py
+++ b/lib/portage/tests/update/test_move_ent.py
@@ -3,7 +3,7 @@
 
 import sys
 import textwrap
-
+import pytest
 import portage
 from portage import os
 from portage.const import SUPPORTED_GENTOO_BINPKG_FORMATS
@@ -230,3 +230,93 @@ class MoveEntTestCase(TestCase):
 
                 finally:
                     playground.cleanup()
+
+    @pytest.mark.filterwarnings("error")
+    def testMoveEntWithCorruptIndex(self):
+        """
+        Test handling of the Packages index being stale (bug #920828)
+        and gpkg's binpkg-multi-instance handling.
+
+        We expect a UserWarning to be thrown if the gpkg structure is broken,
+        so we promote that to an error.
+        """
+        ebuilds = {
+            "dev-libs/A-moved-1::test_repo": {
+                "EAPI": "4",
+                "SLOT": "2",
+            },
+            "dev-libs/B-1::test_repo": {"EAPI": "4", "RDEPEND": 
"dev-libs/A-moved"},
+        }
+
+        installed = {
+            "dev-libs/A-1::test_repo": {
+                "EAPI": "4",
+            },
+            "dev-libs/B-1::test_repo": {"EAPI": "4", "RDEPEND": "dev-libs/A"},
+        }
+
+        binpkgs = {
+            "dev-libs/A-1::test_repo": {
+                "EAPI": "4",
+                "BUILD_ID": "1",
+            },
+            "dev-libs/B-1::test_repo": {
+                "EAPI": "4",
+                "BUILD_ID": "1",
+                "RDEPEND": "dev-libs/A",
+            },
+        }
+
+        updates = textwrap.dedent(
+            """
+                       move dev-libs/A dev-libs/A-moved
+               """
+        )
+
+        for binpkg_format in ("gpkg",):
+            with self.subTest(binpkg_format=binpkg_format):
+                print(colorize("HILITE", binpkg_format), end=" ... ")
+                sys.stdout.flush()
+                playground = ResolverPlayground(
+                    binpkgs=binpkgs,
+                    ebuilds=ebuilds,
+                    installed=installed,
+                    user_config={
+                        "make.conf": (
+                            f'BINPKG_FORMAT="{binpkg_format}"',
+                            f'FEATURES="binpkg-multi-instance 
pkgdir-index-trusted"',
+                        ),
+                    },
+                    debug=True,
+                )
+
+                settings = playground.settings
+                trees = playground.trees
+                eroot = settings["EROOT"]
+                test_repo_location = 
settings.repositories["test_repo"].location
+                portdb = trees[eroot]["porttree"].dbapi
+                vardb = trees[eroot]["vartree"].dbapi
+                bindb = trees[eroot]["bintree"].dbapi
+
+                updates_dir = os.path.join(test_repo_location, "profiles", 
"updates")
+
+                try:
+                    ensure_dirs(updates_dir)
+                    with open(os.path.join(updates_dir, "1Q-2010"), "w") as f:
+                        f.write(updates)
+
+                    # Make the Packages index out-of-date
+                    os.remove(
+                        os.path.join(
+                            bindb.bintree.pkgdir, "dev-libs", "A", 
"A-1-1.gpkg.tar"
+                        )
+                    )
+
+                    global_noiselimit = portage.util.noiselimit
+                    portage.util.noiselimit = -2
+                    try:
+                        _do_global_updates(trees, {})
+                    finally:
+                        portage.util.noiselimit = global_noiselimit
+                finally:
+                    playground.cleanup()

Reply via email to