Be a bit more aggressive about expiring old soversions
authorJon Turney <jon.turney@dronecode.org.uk>
Wed, 17 Apr 2024 22:08:31 +0000 (23:08 +0100)
committerJon Turney <jon.turney@dronecode.org.uk>
Tue, 23 Apr 2024 18:16:44 +0000 (19:16 +0100)
Allow the source package responsible for the old soversion to be
completely expired if it wouldn't normally be kept, and all of it's
install packages have no external rdepends.

calm/package.py

index 3a80c7ac4da80b64b8687d18145009771215d6e9..2205376bfc3e328a38caa58d7df8638ef4fc92f9 100755 (executable)
@@ -1660,7 +1660,7 @@ def mark_fn(packages, po, v, certain_age, vault_requests):
     # shouldn't retain anything.
     #
     if pn.endswith('-debuginfo'):
-        return Freshness.conditional
+        return (Freshness.conditional, False)
 
     # - shared library packages which don't come from the current version of
     # source (i.e. is superseded or removed), have no packages from a
@@ -1674,14 +1674,14 @@ def mark_fn(packages, po, v, certain_age, vault_requests):
             mtime = po.tar(v).mtime
             if mtime < certain_age:
                 logging.debug("deprecated soversion package '%s' version '%s' mtime '%s' is over cut-off age" % (pn, v, time.strftime("%F %T %Z", time.localtime(mtime))))
-                return Freshness.conditional
+                return (Freshness.conditional, True)
 
     # - if package depends on anything in expired_provides
     #
     requires = po.version_hints[v].get('depends', [])
     if any(ep in requires for ep in past_mistakes.expired_provides):
         logging.debug("package '%s' version '%s' not retained as it requires a provide known to be expired" % (pn, v))
-        return Freshness.conditional
+        return (Freshness.conditional, False)
 
     # - marked via 'calm-tool vault'
     #
@@ -1689,10 +1689,10 @@ def mark_fn(packages, po, v, certain_age, vault_requests):
     if es in vault_requests:
         if v in vault_requests[es]:
             logging.info("package '%s' version '%s' not retained due vault request" % (pn, v))
-            return Freshness.conditional
+            return (Freshness.conditional, False)
 
     # otherwise, make no change
-    return Freshness.fresh
+    return (Freshness.fresh, False)
 
 
 #
@@ -1708,9 +1708,6 @@ def stale_packages(packages, vault_requests):
 
     # mark install packages for freshness
     for pn, po in packages.items():
-        if po.kind != Kind.binary:
-            continue
-
         # mark as fresh any versions explicitly listed in the keep: override
         # hint (unconditionally)
         for v in po.override_hints.get('keep', '').split():
@@ -1759,13 +1756,38 @@ def stale_packages(packages, vault_requests):
             if newer:
                 mark_package_fresh(packages, pn, v)
 
+    for pn, po in packages.items():
+        if po.kind != Kind.binary:
+            continue
+
         # overwrite with 'conditional' package retention mark if it meets
         # various criteria
         for v in sorted(po.versions(), key=lambda v: SetupVersion(v)):
-            mark = mark_fn(packages, po, v, certain_age, vault_requests)
+            (mark, others) = mark_fn(packages, po, v, certain_age, vault_requests)
             if mark != Freshness.fresh:
                 mark_package_fresh(packages, pn, v, mark)
 
+            # also look over the other install packages generated by the
+            # source...
+            if others:
+                es = po.version_hints[v].get('external-source', None)
+                if es:
+                    es_po = packages[es]
+                    # ... if the source package version doesn't count as kept ...
+                    #
+                    # (set above using same critera as for install package
+                    # e.g. we have an excess number of packages)
+                    logging.warning("considering other packages from source package '%s' version '%s'" % (es, v))
+                    if getattr(es_po.tar(v), 'fresh', Freshness.stale) != Freshness.fresh:
+                        # ...  additionally mark anything with no other-source
+                        # rdepends
+                        for opn in sorted(es_po.is_used_by):
+                            if v in packages[opn].versions():
+                                if not any(packages[p].srcpackage(v) != es for p in packages[opn].rdepends):
+                                    mark_package_fresh(packages, opn, v, mark)
+                                else:
+                                    logging.warning("package '%s' version '%s' retained due to being used" % (opn, v))
+
     # mark source packages as fresh if any install package which uses it is fresh
     for po in packages.values():
         if po.kind == Kind.source:
This page took 0.045983 seconds and 5 git commands to generate.