Repository navigation
Add the kolla inventory groups 2026.1 introduced - #616
Merged
Merged
Conversation
kolla-ansible 2026.1's site.yml selects on eight inventory groups this
file does not define. A play whose hosts: names an undefined group is
not an error -- it matches no hosts and deploys nothing, with no failed
task -- so each of these is silent until someone notices the container
is missing.
Two of them are a rename, and they are the ones that bite today. 2026.1
dissolved kolla's monolithic common role into cron, fluentd, logs and
kolla_toolbox, and spells the latter two with underscores, while this
file has spelled them kolla-logs and kolla-toolbox since "Add unified
host groups". Ansible does not alias the two -- it warns about the
invalid characters and leaves the groups distinct -- so on a 2026.1
cluster the emitted kolla-logs.yml and kolla-kolla_toolbox.yml select
zero hosts. That is the likely origin of the "kolla_toolbox container is
missing or not running!" signature.
The generated playbook is what it is, so upstream's spelling wins. Add
kolla_logs and kolla_toolbox as aliases whose only child is the
hyphenated group rather than as copies of its membership: OSISM maps
these differently from upstream (kolla-logs to generic, not common), one
source of truth keeps the two spellings from diverging, and the
hyphenated groups that every image built for 2023.2 through 2025.2 still
selects on are left untouched. Both spellings must resolve for as long
as both releases are supported, which is why this is an addition and not
a rename. Verified with ansible-core 2.19.11 against a five-host
inventory: kolla_toolbox went from no hosts to the same five the
hyphenated group already resolved to, and kolla-toolbox is unchanged.
The remaining six are new groups rather than renamed ones, so nothing
regresses without them -- but each is selected by a 2026.1 play and
would silently match nothing once its service is turned on:
cinder-backup-lvm, cinder-backup-multiple the lvm and
cinder-volume-lvm, cinder-volume-multiple multiple-backend
variants 2026.1 split
out; mapped to storage,
like the base groups
they extend
prometheus-openstack-network-exporter compute + network, as
upstream multinode maps
it
prometheus-valkey-exporter valkey, matching how
prometheus-mysqld- and
-memcached-exporter map
to their service group
enable_cinder_backend_lvm is "no" in osism/defaults and upstream's two
new exporters have no OSISM enable flag yet, so all six are latent for
now; defining the groups here means the defaults re-sync onto 2026.1
group_vars does not have to come back for them.
Sections are ordered on the full section name, so the -lvm and -multiple
variants sort ahead of the base group (- before :) and the underscore
aliases after the hyphenated ones. check-inventory-sorting and
check-kolla-inventory both pass.
Assisted-by: Claude:claude-opus-5
Signed-off-by: Roger Luethi <luethi@osism.tech>
This was referenced Sep 4, 2026
ideaship
added a commit
that referenced
this pull request
Sep 4, 2026
This repo has carried its own inventory-drift check since 2022, gated in CI since #602 (merged 2026-06-30). One day later osism/release landed kolla_inventory, a plugin in its check-drift tool that does the same comparison, and its docs described this script as retired -- which it was not. Two implementations of one check have run side by side ever since, and they had already diverged: this one compares against a single hardcoded KOLLA_BRANCH = "stable/2025.2", so it never saw that 2026.1 renames kolla-toolbox to kolla_toolbox and kolla-logs to kolla_logs and adds six more groups. The plugin, now range-aware, checks every release OSISM builds. Keep the gate, drop the duplicate implementation: tox -e check-kolla now invokes the plugin instead of the local script, and the job gains osism/release in required-projects so Zuul checks it out alongside this repo. The pipelines and the job name do not change. The gate is what makes this worth wiring rather than simply deleting. osism/release runs its detector in periodic-daily only, and reads this repo from GitHub main, so it can report drift a generics change introduced but never block it. Zuul checks out the proposed change here, so the plugin runs against the inventory under review -- and speculative merging means an in-flight change to the detector is tested against a real inventory before it lands. Nothing is suppressed that was suppressed before. IGNORE_ROLE_GROUPS and IGNORE_NOT_DEPLOYED are covered entry for entry by the plugin's shipped allowlist, including its own stale-entry guard; a local run reports 19 allowlisted and 0 stale. The detector needs only requests and PyYAML, both already pinned in this repo's requirements.txt at the same versions, so the tox env keeps its deps. The script's own guidance is not lost either: the plugin's remediation gives the same add-or-allowlist instruction, and names both spellings a renamed group needs while two releases want different ones. python3 ../release/src/check-drift.py --group kolla \ --plugin kolla_inventory --base-dir .. --remote-fallback \ --use-raw-get --base-dir .. finds this repo and osism/release as siblings, which is both the Zuul workspace layout and the usual one-directory-per-org local layout; kolla-ansible is not checked out, hence --remote-fallback. Each release contributes one file read, so --use-raw-get fetches those directly rather than a source tarball per ref. Verified locally: tox -e check-kolla passes against this branch, and fails with exit 1 against a main checkout that still lacks the 2026.1 groups. Depends-On: #616 Assisted-by: Claude:claude-opus-5 Signed-off-by: Roger Luethi <luethi@osism.tech>
ideaship
added a commit
that referenced
this pull request
Sep 4, 2026
This repo has carried its own inventory-drift check since 2022, gated in CI since #602 (merged 2026-06-30). One day later osism/release landed kolla_inventory, a plugin in its check-drift tool that does the same comparison, and its docs described this script as retired -- which it was not. Two implementations of one check have run side by side ever since, and they had already diverged: this one compares against a single hardcoded KOLLA_BRANCH = "stable/2025.2", so it never saw that 2026.1 renames kolla-toolbox to kolla_toolbox and kolla-logs to kolla_logs and adds six more groups. The plugin, now range-aware, checks every release OSISM builds. Keep the gate, drop the duplicate implementation: tox -e check-kolla now invokes the plugin instead of the local script, and the job gains osism/release in required-projects so Zuul checks it out alongside this repo. The pipelines and the job name do not change. The gate is what makes this worth wiring rather than simply deleting. osism/release runs its detector in periodic-daily only, and reads this repo from GitHub main, so it can report drift a generics change introduced but never block it. Zuul checks out the proposed change here, so the plugin runs against the inventory under review -- and speculative merging means an in-flight change to the detector is tested against a real inventory before it lands. Nothing is suppressed that was suppressed before. IGNORE_ROLE_GROUPS and IGNORE_NOT_DEPLOYED are covered entry for entry by the plugin's shipped allowlist, including its own stale-entry guard; a local run reports 19 allowlisted and 0 stale. The detector needs only requests and PyYAML, both already pinned in this repo's requirements.txt at the same versions, so the tox env keeps its deps. The script's own guidance is not lost either: the plugin's remediation gives the same add-or-allowlist instruction, and names both spellings a renamed group needs while two releases want different ones. python3 ../release/src/check-drift.py --group kolla \ --plugin kolla_inventory --base-dir .. --remote-fallback \ --use-raw-get --base-dir .. finds this repo and osism/release as siblings, which is both the Zuul workspace layout and the usual one-directory-per-org local layout; kolla-ansible is not checked out, hence --remote-fallback. Each release contributes one file read, so --use-raw-get fetches those directly rather than a source tarball per ref. Verified locally: tox -e check-kolla passes against this branch, and fails with exit 1 against a main checkout that still lacks the 2026.1 groups. Depends-On: #616 Depends-On: osism/release#2693 Assisted-by: Claude:claude-opus-5 Signed-off-by: Roger Luethi <luethi@osism.tech>
ideaship
marked this pull request as ready for review
September 5, 2026 17:17
ideaship
added a commit
to osism/container-image-kolla-ansible
that referenced
this pull request
Sep 6, 2026
2026.1 dissolved the monolithic `common` role into `logs`,
`kolla_toolbox`, `cron` and `fluentd`. `roles/common/` survives holding
one shared template that `kolla_toolbox` consumes -- no tasks at all --
so OSISM's `kolla-common.yml`, which still applies `role: common`, runs
a play with nothing in it and none of the four services is deployed.
Observed on a live 2026.1 cluster:
PLAY [Apply role common] ****
PLAY RECAP ******************
a play header, an empty recap, exit 0, and no `cron`, `fluentd` or
`kolla_toolbox` container on any host. The infrastructure stage then
reaches mariadb and fails there:
TASK [mariadb : Wait for MariaDB service to sync WSREP]
"msg": "kolla_toolbox container is missing or not running!"
because the WSREP check runs its query through a container nothing
created. Deploying kolla_toolbox by hand clears it and mariadb comes up
healthy on all three control nodes, which is what identifies this as the
cause rather than a coincidence.
Fold the four successors into this file rather than making each an
`osism apply` target of its own. Upstream runs them as four separate
site.yml plays, and routing them individually is the more faithful
shape, but it would first require python-osism's `enums.py` collections
to become release-aware: they are static, so naming `logs` or
`kolla_toolbox` in one would break `osism apply
collection-infrastructure` on <= 2025.2, where those playbooks do not
exist. Folding keeps the release difference inside the file that is
already per-release, and keeps `osism apply common` doing what the
deploy guide has always said it does -- which is also what upstream's
own release note requires, since it warns that anything narrower than
site.yml loses the common role.
Play order, host groups and tags follow 2026.1's site.yml exactly. The
prepended group_by play exists only for fluentd, the one successor whose
host selector intersects an `enable_*` group; the other three select
plain inventory groups and need none.
Only 2026.1 changes. On <= 2025.2 `role: common` still does the work and
those files are untouched.
Requires the inventory groups the four plays select: `kolla_logs` and
`kolla_toolbox` are spelled with underscores upstream, which
osism/generics#616 adds. Without it those two plays match no hosts and
fail silently.
Accepted trade-off: `cron` and `fluentd` now install early and by
default. `enable_fluentd` still gates fluentd, `cron` has no flag
upstream, and OSISM offers operators no alternative to either.
Assisted-by: Claude:claude-opus-5
Signed-off-by: Roger Luethi <luethi@osism.tech>
ideaship
added a commit
to osism/container-image-kolla-ansible
that referenced
this pull request
Sep 7, 2026
2026.1 dissolved the monolithic `common` role into `logs`,
`kolla_toolbox`, `cron` and `fluentd`. `roles/common/` survives holding
one shared template that `kolla_toolbox` consumes -- no tasks at all --
so OSISM's `kolla-common.yml`, which still applies `role: common`, runs
a play with nothing in it and none of the four services is deployed.
Observed on a live 2026.1 cluster:
PLAY [Apply role common] ****
PLAY RECAP ******************
a play header, an empty recap, exit 0, and no `cron`, `fluentd` or
`kolla_toolbox` container on any host. The infrastructure stage then
reaches mariadb and fails there:
TASK [mariadb : Wait for MariaDB service to sync WSREP]
"msg": "kolla_toolbox container is missing or not running!"
because the WSREP check runs its query through a container nothing
created. Deploying kolla_toolbox by hand clears it and mariadb comes up
healthy on all three control nodes, which is what identifies this as the
cause rather than a coincidence.
Fold the four successors into this file rather than making each an
`osism apply` target of its own. Upstream runs them as four separate
site.yml plays, and routing them individually is the more faithful
shape, but it would first require python-osism's `enums.py` collections
to become release-aware: they are static, so naming `logs` or
`kolla_toolbox` in one would break `osism apply
collection-infrastructure` on <= 2025.2, where those playbooks do not
exist. Folding keeps the release difference inside the file that is
already per-release, and keeps `osism apply common` doing what the
deploy guide has always said it does -- which is also what upstream's
own release note requires, since it warns that anything narrower than
site.yml loses the common role.
Play order, host groups and tags follow 2026.1's site.yml exactly. The
prepended group_by play exists only for fluentd, the one successor whose
host selector intersects an `enable_*` group; the other three select
plain inventory groups and need none.
Only 2026.1 changes. On <= 2025.2 `role: common` still does the work and
those files are untouched.
Requires the inventory groups the four plays select: `kolla_logs` and
`kolla_toolbox` are spelled with underscores upstream, which
osism/generics#616 adds. Without it those two plays match no hosts and
fail silently.
Accepted trade-off: `cron` and `fluentd` now install early and by
default. `enable_fluentd` still gates fluentd, `cron` has no flag
upstream, and OSISM offers operators no alternative to either.
Assisted-by: Claude:claude-opus-5
Signed-off-by: Roger Luethi <luethi@osism.tech>
berendt
pushed a commit
that referenced
this pull request
Sep 9, 2026
This repo has carried its own inventory-drift check since 2022, gated in CI since #602 (merged 2026-06-30). One day later osism/release landed kolla_inventory, a plugin in its check-drift tool that does the same comparison, and its docs described this script as retired -- which it was not. Two implementations of one check have run side by side ever since, and they had already diverged: this one compares against a single hardcoded KOLLA_BRANCH = "stable/2025.2", so it never saw that 2026.1 renames kolla-toolbox to kolla_toolbox and kolla-logs to kolla_logs and adds six more groups. The plugin, now range-aware, checks every release OSISM builds. Keep the gate, drop the duplicate implementation: tox -e check-kolla now invokes the plugin instead of the local script, and the job gains osism/release in required-projects so Zuul checks it out alongside this repo. The pipelines and the job name do not change. The gate is what makes this worth wiring rather than simply deleting. osism/release runs its detector in periodic-daily only, and reads this repo from GitHub main, so it can report drift a generics change introduced but never block it. Zuul checks out the proposed change here, so the plugin runs against the inventory under review -- and speculative merging means an in-flight change to the detector is tested against a real inventory before it lands. Nothing is suppressed that was suppressed before. IGNORE_ROLE_GROUPS and IGNORE_NOT_DEPLOYED are covered entry for entry by the plugin's shipped allowlist, including its own stale-entry guard; a local run reports 19 allowlisted and 0 stale. The detector needs only requests and PyYAML, both already pinned in this repo's requirements.txt at the same versions, so the tox env keeps its deps. The script's own guidance is not lost either: the plugin's remediation gives the same add-or-allowlist instruction, and names both spellings a renamed group needs while two releases want different ones. python3 ../release/src/check-drift.py --group kolla \ --plugin kolla_inventory --base-dir .. --remote-fallback \ --use-raw-get --base-dir .. finds this repo and osism/release as siblings, which is both the Zuul workspace layout and the usual one-directory-per-org local layout; kolla-ansible is not checked out, hence --remote-fallback. Each release contributes one file read, so --use-raw-get fetches those directly rather than a source tarball per ref. Verified locally: tox -e check-kolla passes against this branch, and fails with exit 1 against a main checkout that still lacks the 2026.1 groups. Depends-On: #616 Depends-On: osism/release#2693 Assisted-by: Claude:claude-opus-5 Signed-off-by: Roger Luethi <luethi@osism.tech>
ideaship
added a commit
to osism/container-image-kolla-ansible
that referenced
this pull request
Sep 9, 2026
2026.1 dissolved the monolithic `common` role into `logs`,
`kolla_toolbox`, `cron` and `fluentd`. `roles/common/` survives holding
one shared template that `kolla_toolbox` consumes -- no tasks at all --
so OSISM's `kolla-common.yml`, which still applies `role: common`, runs
a play with nothing in it and none of the four services is deployed.
Observed on a live 2026.1 cluster:
PLAY [Apply role common] ****
PLAY RECAP ******************
a play header, an empty recap, exit 0, and no `cron`, `fluentd` or
`kolla_toolbox` container on any host. The infrastructure stage then
reaches mariadb and fails there:
TASK [mariadb : Wait for MariaDB service to sync WSREP]
"msg": "kolla_toolbox container is missing or not running!"
because the WSREP check runs its query through a container nothing
created. Deploying kolla_toolbox by hand clears it and mariadb comes up
healthy on all three control nodes, which is what identifies this as the
cause rather than a coincidence.
Fold the four successors into this file rather than making each an
`osism apply` target of its own. Upstream runs them as four separate
site.yml plays, and routing them individually is the more faithful
shape, but it would first require python-osism's `enums.py` collections
to become release-aware: they are static, so naming `logs` or
`kolla_toolbox` in one would break `osism apply
collection-infrastructure` on <= 2025.2, where those playbooks do not
exist. Folding keeps the release difference inside the file that is
already per-release, and keeps `osism apply common` doing what the
deploy guide has always said it does -- which is also what upstream's
own release note requires, since it warns that anything narrower than
site.yml loses the common role.
Play order, host groups and tags follow 2026.1's site.yml exactly. The
prepended group_by play exists only for fluentd, the one successor whose
host selector intersects an `enable_*` group; the other three select
plain inventory groups and need none.
Only 2026.1 changes. On <= 2025.2 `role: common` still does the work and
those files are untouched.
Requires the inventory groups the four plays select: `kolla_logs` and
`kolla_toolbox` are spelled with underscores upstream, which
osism/generics#616 adds. Without it those two plays match no hosts and
fail silently.
Accepted trade-off: `cron` and `fluentd` now install early and by
default. `enable_fluentd` still gates fluentd, `cron` has no flag
upstream, and OSISM offers operators no alternative to either.
Assisted-by: Claude:claude-opus-5
Signed-off-by: Roger Luethi <luethi@osism.tech>
ideaship
added a commit
to osism/container-image-kolla-ansible
that referenced
this pull request
Sep 9, 2026
2026.1 dissolved the monolithic `common` role into `logs`,
`kolla_toolbox`, `cron` and `fluentd`. `roles/common/` survives holding
one shared template that `kolla_toolbox` consumes -- no tasks at all --
so OSISM's `kolla-common.yml`, which still applies `role: common`, runs
a play with nothing in it and none of the four services is deployed.
Observed on a live 2026.1 cluster:
PLAY [Apply role common] ****
PLAY RECAP ******************
a play header, an empty recap, exit 0, and no `cron`, `fluentd` or
`kolla_toolbox` container on any host. The infrastructure stage then
reaches mariadb and fails there:
TASK [mariadb : Wait for MariaDB service to sync WSREP]
"msg": "kolla_toolbox container is missing or not running!"
because the WSREP check runs its query through a container nothing
created. Deploying kolla_toolbox by hand clears it and mariadb comes up
healthy on all three control nodes, which is what identifies this as the
cause rather than a coincidence.
Fold the four successors into this file rather than making each an
`osism apply` target of its own. Upstream runs them as four separate
site.yml plays, and routing them individually is the more faithful
shape, but it would first require python-osism's `enums.py` collections
to become release-aware: they are static, so naming `logs` or
`kolla_toolbox` in one would break `osism apply
collection-infrastructure` on <= 2025.2, where those playbooks do not
exist. Folding keeps the release difference inside the file that is
already per-release, and keeps `osism apply common` doing what the
deploy guide has always said it does -- which is also what upstream's
own release note requires, since it warns that anything narrower than
site.yml loses the common role.
Play order, host groups and tags follow 2026.1's site.yml exactly. The
prepended group_by play exists only for fluentd, the one successor whose
host selector intersects an `enable_*` group; the other three select
plain inventory groups and need none.
Only 2026.1 changes. On <= 2025.2 `role: common` still does the work and
those files are untouched.
Requires the inventory groups the four plays select: `kolla_logs` and
`kolla_toolbox` are spelled with underscores upstream, which
osism/generics#616 adds. Without it those two plays match no hosts and
fail silently.
Accepted trade-off: `cron` and `fluentd` now install early and by
default. `enable_fluentd` still gates fluentd, `cron` has no flag
upstream, and OSISM offers operators no alternative to either.
Assisted-by: Claude:claude-opus-5
Signed-off-by: Roger Luethi <luethi@osism.tech>
berendt
pushed a commit
to osism/container-image-kolla-ansible
that referenced
this pull request
Sep 9, 2026
2026.1 dissolved the monolithic `common` role into `logs`,
`kolla_toolbox`, `cron` and `fluentd`. `roles/common/` survives holding
one shared template that `kolla_toolbox` consumes -- no tasks at all --
so OSISM's `kolla-common.yml`, which still applies `role: common`, runs
a play with nothing in it and none of the four services is deployed.
Observed on a live 2026.1 cluster:
PLAY [Apply role common] ****
PLAY RECAP ******************
a play header, an empty recap, exit 0, and no `cron`, `fluentd` or
`kolla_toolbox` container on any host. The infrastructure stage then
reaches mariadb and fails there:
TASK [mariadb : Wait for MariaDB service to sync WSREP]
"msg": "kolla_toolbox container is missing or not running!"
because the WSREP check runs its query through a container nothing
created. Deploying kolla_toolbox by hand clears it and mariadb comes up
healthy on all three control nodes, which is what identifies this as the
cause rather than a coincidence.
Fold the four successors into this file rather than making each an
`osism apply` target of its own. Upstream runs them as four separate
site.yml plays, and routing them individually is the more faithful
shape, but it would first require python-osism's `enums.py` collections
to become release-aware: they are static, so naming `logs` or
`kolla_toolbox` in one would break `osism apply
collection-infrastructure` on <= 2025.2, where those playbooks do not
exist. Folding keeps the release difference inside the file that is
already per-release, and keeps `osism apply common` doing what the
deploy guide has always said it does -- which is also what upstream's
own release note requires, since it warns that anything narrower than
site.yml loses the common role.
Play order, host groups and tags follow 2026.1's site.yml exactly. The
prepended group_by play exists only for fluentd, the one successor whose
host selector intersects an `enable_*` group; the other three select
plain inventory groups and need none.
Only 2026.1 changes. On <= 2025.2 `role: common` still does the work and
those files are untouched.
Requires the inventory groups the four plays select: `kolla_logs` and
`kolla_toolbox` are spelled with underscores upstream, which
osism/generics#616 adds. Without it those two plays match no hosts and
fail silently.
Accepted trade-off: `cron` and `fluentd` now install early and by
default. `enable_fluentd` still gates fluentd, `cron` has no flag
upstream, and OSISM offers operators no alternative to either.
Assisted-by: Claude:claude-opus-5
Signed-off-by: Roger Luethi <luethi@osism.tech>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
kolla-ansible 2026.1's
site.ymlselects on eight inventory groupsinventory/51-kolladoes not define. A play whosehosts:names an undefinedgroup is not an error — it matches no hosts and deploys nothing, with no failed
task — so each of these is silent until someone notices a container is missing.
The two that bite today
2026.1 dissolved kolla's monolithic
commonrole intocron,fluentd,logsand
kolla_toolbox, and spells the latter two with underscores, while thisfile has spelled them
kolla-logs/kolla-toolboxsince "Add unified hostgroups". Ansible does not alias the two — it warns about the invalid characters
and leaves the groups distinct — so on a 2026.1 cluster the emitted
kolla-logs.ymlandkolla-kolla_toolbox.ymlselect zero hosts. That is thelikely origin of the
kolla_toolbox container is missing or not running!signature.
The generated playbook is what it is, so upstream's spelling wins.
kolla_logsand
kolla_toolboxare added as aliases whose only child is the hyphenatedgroup, not as copies of its membership:
kolla-logs→generic, upstream→
common), so copying upstream's members would have been wrongand they are untouched
Both spellings must resolve for as long as both releases are supported, which
is why this is an addition and not a rename.
Verified with ansible-core 2.19.11 against a five-host inventory:
kolla-toolbox(≤2025.2 plays)kolla_toolbox(2026.1 plays)Same for logs.
The six that are latent
New groups rather than renamed ones, so nothing regresses without them — but each
is selected by a 2026.1 play and would silently match nothing once its service is
turned on.
enable_cinder_backend_lvmis"no"inosism/defaultsandupstream's two new exporters have no OSISM enable flag yet, so defining the groups
here means the defaults re-sync onto 2026.1 group_vars does not have to come back
for them.
cinder-backup-lvm,cinder-backup-multiple,cinder-volume-lvm,cinder-volume-multiplestorageprometheus-openstack-network-exportercompute+networkprometheus-valkey-exportervalkeyNotes for review
-lvm/-multiplevariantssort ahead of their base group (
-before:) and the underscore aliasesafter the hyphenated ones.
check-inventory-sortingandcheck-kolla-inventoryboth pass.common-role chain, and the inventory-drift item under:kolla_inventorydrift plugin range-aware —it reported exactly these eight and goes to zero with this applied: