[PATCH 23/26] lucid: handle vars_prompt

Daniel Gomez <[email protected]> Tue, 19 May 2026 15:28:20 +0200
Newsgroups dev.linux.lists.kdevops
Message-ID <[email protected]>
From: Daniel Gomez <[email protected]>

vars_prompt is one of the few places a playbook blocks for
interactive user input, and lucid's background redraw thread
racing against Ansible's readline loop produces a garbled prompt
where the spinner line overwrites the user's keystrokes. Inherited
as a no-op from CallbackBase, the plugin had no way to know the
tty was about to be handed over.

This commit clears any pending dynamic frame under the output lock
so the terminal is in a known state when Ansible's input layer
takes over, then stays off stdout entirely while the prompt is
active. The log still records the prompt text so the audit trail
is complete, and _clear_display resets display_lines to zero so
the next redraw cycle rebuilds the frame from scratch once the
user has answered. Lucid does not try to render the prompt itself;
owning the tty from both sides was the source of the original
garbling, so we cede it and let Ansible drive.

Generated-by: Claude AI
Signed-off-by: Daniel Gomez <[email protected]>
---
 callback_plugins/lucid.py | 31 +++++++++++++++++++++++++++++++
 1 file changed, 31 insertions(+)

diff --git a/callback_plugins/lucid.py b/callback_plugins/lucid.py
index 83532e03..d48276aa 100644
--- a/callback_plugins/lucid.py
+++ b/callback_plugins/lucid.py
@@ -688,6 +688,37 @@ class CallbackModule(CallbackBase):
         """
         self._handle_result(result, "failed")
 
+    def v2_playbook_on_vars_prompt(
+        self,
+        varname,
+        private=True,
+        prompt=None,
+        encrypt=None,
+        confirm=False,
+        salt_size=None,
+        salt=None,
+        default=None,
+        unsafe=None,
+    ):
+        """A play is about to block for interactive vars_prompt input.
+
+        vars_prompt is one of the few places Ansible hands the tty
+        over to a readline loop for user input. Lucid's background
+        update thread racing against that readline produces a
+        garbled prompt and occasionally eats the user's keystrokes.
+        We clear any pending dynamic frame under the output lock so
+        the terminal is in a known state, then stay off the tty
+        entirely while Ansible's input layer owns it. The log still
+        records the prompt so the audit trail is complete, and the
+        next redraw cycle rebuilds the dynamic frame from scratch
+        because _clear_display resets display_lines to zero.
+        """
+        if self.dynamic_mode and self.display_lines > 0:
+            with self.output_lock:
+                self._clear_display()
+        prompt_text = prompt or f"enter value for {varname}"
+        self._write_to_log(f"VARS_PROMPT: {prompt_text}")
+
     def v2_runner_item_on_ok(self, result):
         """Loop item succeeded — log per-item command and output"""
         self._log_item_result(result)

-- 
2.53.0