mirror of
https://github.com/kevinveenbirkenbach/computer-playbook.git
synced 2026-11-06 10:59:59 +00:00
fix(volume-lookup): force application-defaults build on registry miss so nfs_prep pre-creates the NFS subdir
lookup('volume', role) read the lazily-populated canonical-volumes registry directly, so a lookup running before any consumer built that role (nfs_prep's pre-create loop for an early unpinned engine such as ollama) saw an empty registry and skipped the subdir; the swarm bind mount then failed with 'no such file or directory'. Force get_application_defaults() on a miss, guarded so the populated hot path skips the deepcopy. Adds two guard tests.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
1 parent
0e18481ce7
commit
687f1243cd
2 files changed
+38
-4
No files matched your search
@@ -30,7 +30,7 @@ from typing import Any
|
||||
from ansible.errors import AnsibleError
|
||||
from ansible.plugins.lookup import LookupBase
|
||||
|
||||
from utils.cache.applications import get_canonical_volumes
|
||||
from utils.cache.applications import get_application_defaults, get_canonical_volumes
|
||||
|
||||
|
||||
class LookupModule(LookupBase):
|
||||
@@ -50,6 +50,14 @@ class LookupModule(LookupBase):
|
||||
raise AnsibleError("volume lookup: application_id must be non-empty")
|
||||
|
||||
canonical = get_canonical_volumes(application_id)
|
||||
if not canonical:
|
||||
# The canonical-volumes registry fills lazily as a side effect of
|
||||
# building the application defaults; force it on a miss so a lookup
|
||||
# that runs before any consumer built this role (e.g. nfs_prep's
|
||||
# pre-create loop) does not see an empty registry and silently skip
|
||||
# the subdir. Guarded so the populated hot path skips the deepcopy.
|
||||
get_application_defaults()
|
||||
canonical = get_canonical_volumes(application_id)
|
||||
|
||||
if len(terms) == 1:
|
||||
return [dict(canonical)]
|
||||
|
||||
@@ -29,7 +29,7 @@ def _run(
|
||||
with patch(
|
||||
"plugins.lookup.volume.get_canonical_volumes",
|
||||
return_value=canonical if canonical is not None else {},
|
||||
):
|
||||
), patch("plugins.lookup.volume.get_application_defaults"):
|
||||
return LookupModule().run([application_id, name], variables={})
|
||||
|
||||
|
||||
@@ -168,7 +168,7 @@ class TestVolumeLookup(unittest.TestCase):
|
||||
with patch(
|
||||
"plugins.lookup.volume.get_canonical_volumes",
|
||||
return_value=canonical,
|
||||
):
|
||||
), patch("plugins.lookup.volume.get_application_defaults"):
|
||||
result = LookupModule().run(["web-app-mattermost"], variables={})
|
||||
self.assertEqual(result, [canonical])
|
||||
|
||||
@@ -176,7 +176,7 @@ class TestVolumeLookup(unittest.TestCase):
|
||||
with patch(
|
||||
"plugins.lookup.volume.get_canonical_volumes",
|
||||
return_value={},
|
||||
):
|
||||
), patch("plugins.lookup.volume.get_application_defaults"):
|
||||
result = LookupModule().run(["web-app-no-meta"], variables={})
|
||||
self.assertEqual(result, [{}])
|
||||
|
||||
@@ -188,6 +188,32 @@ class TestVolumeLookup(unittest.TestCase):
|
||||
with self.assertRaises(AnsibleError):
|
||||
_run("web-app-mattermost", "", canonical={"data": {}})
|
||||
|
||||
def test_forces_defaults_build_on_registry_miss(self):
|
||||
# Empty on the first read (lookup runs before any consumer built the
|
||||
# role); populated after the forced build — the nfs_prep/ollama case.
|
||||
populated = {"data": {"type": "volume"}}
|
||||
with patch(
|
||||
"plugins.lookup.volume.get_canonical_volumes",
|
||||
side_effect=[{}, populated],
|
||||
) as gcv, patch(
|
||||
"plugins.lookup.volume.get_application_defaults",
|
||||
) as gad:
|
||||
result = LookupModule().run(["svc-ai-ollama"], variables={})
|
||||
self.assertEqual(result, [populated])
|
||||
gad.assert_called_once()
|
||||
self.assertEqual(gcv.call_count, 2)
|
||||
|
||||
def test_populated_registry_skips_build(self):
|
||||
# Already populated: no forced build, no wasted defaults deepcopy.
|
||||
with patch(
|
||||
"plugins.lookup.volume.get_canonical_volumes",
|
||||
return_value={"data": {"type": "volume"}},
|
||||
), patch(
|
||||
"plugins.lookup.volume.get_application_defaults",
|
||||
) as gad:
|
||||
LookupModule().run(["web-app-mattermost"], variables={})
|
||||
gad.assert_not_called()
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
unittest.main()
|
||||
Reference in new issue
Block a user