diff --git a/calm/package.py b/calm/package.py index 3a80c7a..2205376 100755 --- a/calm/package.py +++ b/calm/package.py @@ -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: