* [PATCH v4 1/2] ansible: use native verbosity config instead of custom AV variable
2025-12-01 23:11 [PATCH v4 0/2] Lucid: A custom Ansible stdout callback for kdevops Daniel Gomez
@ 2025-12-01 23:11 ` Daniel Gomez
2025-12-03 20:26 ` Chuck Lever
2025-12-01 23:11 ` [PATCH v4 2/2] ansible: add lucid callback plugin for clean output Daniel Gomez
2025-12-01 23:14 ` [PATCH v4 0/2] Lucid: A custom Ansible stdout callback for kdevops Daniel Gomez
2 siblings, 1 reply; 6+ messages in thread
From: Daniel Gomez @ 2025-12-01 23:11 UTC (permalink / raw)
To: Luis Chamberlain, Chuck Lever; +Cc: kdevops, Daniel Gomez
From: Daniel Gomez <da.gomez@samsung.com>
Replace the custom AV makefile variable and validate_av.py script with
Ansible's native verbosity configuration. The verbosity level is now
configured via the verbosity key in ansible.cfg, which can be set
through the new ANSIBLE_CFG_VERBOSITY Kconfig option.
This change removes the $(ANSIBLE_VERBOSE) variable from all 52
Makefiles that were passing it to ansible-playbook calls. Since
ansible.cfg now contains the verbosity setting, the command-line
argument is no longer needed.
The runtime override is now done using the standard ANSIBLE_VERBOSITY
environment variable instead of the custom AV=N syntax.
Generated-by: Claude AI
Signed-off-by: Daniel Gomez <da.gomez@samsung.com>
---
CLAUDE.md | 6 ++---
Makefile | 6 ++---
Makefile.btrfs_progs | 2 +-
Makefile.build_qemu | 8 +++----
Makefile.docker-mirror | 4 ++--
Makefile.hypervisor-tunings | 2 +-
Makefile.kdevops | 10 ++++----
Makefile.postfix | 2 +-
docs/fio-tests.md | 2 +-
docs/monitoring.md | 2 +-
docs/reboot-limit.md | 2 +-
kconfigs/Kconfig.ansible_cfg | 20 ++++++++++++++++
.../roles/ansible_cfg/templates/ansible.cfg.j2 | 1 +
scripts/ansible.Makefile | 3 ---
scripts/archive.Makefile | 2 +-
scripts/devconfig.Makefile | 4 ++--
scripts/dynamic-pci-kconfig.Makefile | 2 +-
scripts/firstconfig.Makefile | 2 +-
scripts/guestfs.Makefile | 18 +++++++-------
| 2 +-
scripts/install-rcloud-deps.Makefile | 2 +-
scripts/iscsi.Makefile | 2 +-
scripts/journal-server.Makefile | 10 ++++----
scripts/kconfig/Makefile | 2 +-
scripts/kotd.Makefile | 6 ++---
scripts/krb5.Makefile | 4 ++--
scripts/ktls.Makefile | 2 +-
scripts/nfsd.Makefile | 2 +-
scripts/nixos.Makefile | 10 ++++----
scripts/provision.Makefile | 2 +-
scripts/rdma.Makefile | 4 ++--
scripts/smbd.Makefile | 2 +-
scripts/systemd-timesync.Makefile | 4 ++--
scripts/terraform.Makefile | 14 +++++------
scripts/update_etc_hosts.Makefile | 2 +-
scripts/validate_av.py | 28 ----------------------
workflows/ai/Makefile | 20 ++++++++--------
workflows/blktests/Makefile | 16 ++++++-------
workflows/build-linux/Makefile | 8 +++----
workflows/common/Makefile | 2 +-
workflows/cxl/Makefile | 14 +++++------
workflows/demos/reboot-limit/Makefile | 14 +++++------
workflows/fio-tests/Makefile | 12 +++++-----
workflows/fstests/Makefile | 28 +++++++++++-----------
workflows/gitr/Makefile | 8 +++----
workflows/linux/Makefile | 28 +++++++++++-----------
workflows/ltp/Makefile | 8 +++----
workflows/minio/Makefile | 10 ++++----
workflows/mmtests/Makefile | 16 ++++++-------
workflows/nfstest/Makefile | 8 +++----
workflows/pynfs/Makefile | 12 +++++-----
workflows/rcloud/Makefile | 4 ++--
workflows/selftests/Makefile | 8 +++----
workflows/steady_state/Makefile | 8 +++----
workflows/sysbench/Makefile | 16 ++++++-------
workflows/vllm/Makefile | 20 ++++++++--------
56 files changed, 223 insertions(+), 233 deletions(-)
diff --git a/CLAUDE.md b/CLAUDE.md
index 28920130..5c9091d9 100644
--- a/CLAUDE.md
+++ b/CLAUDE.md
@@ -121,7 +121,7 @@ make mmtests-compare # Compare baseline vs dev results (A/B testing)
```bash
make help # Show available targets
make V=1 [target] # Verbose build output
-make AV=1-6 [target] # Ansible verbose output (levels 0-6)
+ANSIBLE_VERBOSITY=1-6 make [target] # Ansible verbose output (levels 0-6)
make dynconfig # Generate dynamic configuration
make style # Check for whitespace issues - ALWAYS run before completing work
make fix-whitespace-last-commit # Fixes commit white space damage
@@ -986,7 +986,7 @@ tasks complete, leading to variable access before they're properly set.
```bash
# Run with verbose output to see variable resolution
-make target AV=3 # Ansible verbose level 3
+ANSIBLE_VERBOSITY=3 make target # Ansible verbose level 3
```
### A/B Testing Variable Resolution Example
@@ -1045,7 +1045,7 @@ When developing features that involve per-node variables:
grep "active_.*:" extra_vars.yaml
# Verify node-specific settings
- make target AV=2 | grep -A5 -B5 "Set.*fact"
+ ANSIBLE_VERBOSITY=2 make target | grep -A5 -B5 "Set.*fact"
```
### Common Patterns to Avoid
diff --git a/Makefile b/Makefile
index f8d36572..e58c99f9 100644
--- a/Makefile
+++ b/Makefile
@@ -234,7 +234,7 @@ include scripts/gen-nodes.Makefile
false)
$(ANSIBLE_CFG_FILE): .config
- $(Q)ansible-playbook $(ANSIBLE_VERBOSE) --connection=local \
+ $(Q)ansible-playbook --connection=local \
--inventory localhost, \
$(KDEVOPS_PLAYBOOKS_DIR)/ansible_cfg.yml \
--extra-vars=@./.extra_vars_auto.yaml
@@ -264,13 +264,13 @@ include scripts/bringup.Makefile
endif
$(ANSIBLE_INVENTORY_FILE): .config $(ANSIBLE_CFG_FILE) $(KDEVOPS_HOSTS_TEMPLATE) $(KDEVOPS_EXTRA_VARS)
- $(Q)ansible-playbook $(ANSIBLE_VERBOSE) --connection=local \
+ $(Q)ansible-playbook --connection=local \
--inventory localhost, \
$(KDEVOPS_PLAYBOOKS_DIR)/gen_hosts.yml \
--extra-vars=@./extra_vars.yaml
$(KDEVOPS_NODES): .config $(ANSIBLE_CFG_FILE) $(KDEVOPS_NODES_TEMPLATE) $(KDEVOPS_EXTRA_VARS)
- $(Q)ansible-playbook $(ANSIBLE_VERBOSE) \
+ $(Q)ansible-playbook \
$(KDEVOPS_PLAYBOOKS_DIR)/gen_nodes.yml \
--extra-vars=@./extra_vars.yaml
diff --git a/Makefile.btrfs_progs b/Makefile.btrfs_progs
index 9ccfafa3..03a99ee5 100644
--- a/Makefile.btrfs_progs
+++ b/Makefile.btrfs_progs
@@ -5,7 +5,7 @@ BTRFS_PROGS_SETUP_ARGS += btrfs_progs_build=True
PHONY += btrfs-progs
btrfs-progs: $(KDEVOPS_NODES)
- $(Q)ansible-playbook $(ANSIBLE_VERBOSE) \
+ $(Q)ansible-playbook \
$(KDEVOPS_PLAYBOOKS_DIR)/btrfs-progs.yml \
--extra-vars=$(BTRFS_PROGS_SETUP_ARGS) $(LIMIT_HOSTS)
diff --git a/Makefile.build_qemu b/Makefile.build_qemu
index 2eac6e9b..44a5c24e 100644
--- a/Makefile.build_qemu
+++ b/Makefile.build_qemu
@@ -20,25 +20,25 @@ QEMU_BUILD_SETUP_ARGS += qemu_target="ppc64-softmmu"
endif
qemu: $(KDEVOPS_EXTRA_VARS)
- $(Q)ansible-playbook $(ANSIBLE_VERBOSE) \
+ $(Q)ansible-playbook \
$(KDEVOPS_PLAYBOOKS_DIR)/build_qemu.yml \
--extra-vars=@./extra_vars.yaml
PHONY += qemu
qemu-install: $(KDEVOPS_EXTRA_VARS)
- $(Q)ansible-playbook $(ANSIBLE_VERBOSE) \
+ $(Q)ansible-playbook \
$(KDEVOPS_PLAYBOOKS_DIR)/build_qemu.yml \
--extra-vars=@./extra_vars.yaml --tags vars,install
PHONY += qemu-install
qemu-configure: $(KDEVOPS_EXTRA_VARS)
- $(Q)ansible-playbook $(ANSIBLE_VERBOSE) \
+ $(Q)ansible-playbook \
$(KDEVOPS_PLAYBOOKS_DIR)/build_qemu.yml \
--extra-vars=@./extra_vars.yaml --tags vars,configure
PHONY += qemu-configure
qemu-build: $(KDEVOPS_EXTRA_VARS)
- $(Q)ansible-playbook $(ANSIBLE_VERBOSE) \
+ $(Q)ansible-playbook \
$(KDEVOPS_PLAYBOOKS_DIR)/build_qemu.yml \
--extra-vars=@./extra_vars.yaml --tags vars,build
PHONY += qemu-build
diff --git a/Makefile.docker-mirror b/Makefile.docker-mirror
index 25e7a961..4501ef21 100644
--- a/Makefile.docker-mirror
+++ b/Makefile.docker-mirror
@@ -16,7 +16,7 @@ docker-mirror-help:
docker-mirror: $(KDEVOPS_EXTRA_VARS)
@echo "Setting up Docker registry mirror with automatic background updates..."
- $(Q)ansible-playbook $(ANSIBLE_VERBOSE) \
+ $(Q)ansible-playbook \
--connection=local \
--tags docker-mirror \
$(KDEVOPS_PLAYBOOKS_DIR)/docker-mirror.yml \
@@ -52,7 +52,7 @@ docker-mirror-status:
docker-mirror-pull: $(KDEVOPS_EXTRA_VARS)
@echo "Manually triggering Docker image downloads..."
@echo "This may take several minutes depending on image sizes and network speed."
- $(Q)ansible-playbook $(ANSIBLE_VERBOSE) \
+ $(Q)ansible-playbook \
--connection=local \
--tags docker-mirror-pull \
$(KDEVOPS_PLAYBOOKS_DIR)/docker-mirror.yml \
diff --git a/Makefile.hypervisor-tunings b/Makefile.hypervisor-tunings
index ff29b89c..abaf9025 100644
--- a/Makefile.hypervisor-tunings
+++ b/Makefile.hypervisor-tunings
@@ -14,7 +14,7 @@ HYPERVISOR_TUNING_ARGS += hypervisor_tunning_zswap_max_pool_percent=$(ZSWAP_MAX_
endif
kdevops_hypervisor_tunning: $(KDEVOPS_EXTRA_VARS)
- $(Q)ansible-playbook $(ANSIBLE_VERBOSE) \
+ $(Q)ansible-playbook \
$(KDEVOPS_PLAYBOOKS_DIR)/hypervisor-tuning.yml \
--extra-vars=@./extra_vars.yaml
PHONY += kdevops_hypervisor_tunning
diff --git a/Makefile.kdevops b/Makefile.kdevops
index fd03b392..46725d8a 100644
--- a/Makefile.kdevops
+++ b/Makefile.kdevops
@@ -8,28 +8,28 @@ kdevops_all: kdevops_deps
PHONY := kdevops_all
kdevops_terraform_deps:
- $(Q)ansible-playbook $(ANSIBLE_VERBOSE) \
+ $(Q)ansible-playbook \
--inventory localhost, \
$(KDEVOPS_PLAYBOOKS_DIR)/install_terraform.yml
PHONY += kdevops_terraform_deps
kdevops_install_libvirt:
- $(Q)ansible-playbook $(ANSIBLE_VERBOSE) \
+ $(Q)ansible-playbook \
$(KDEVOPS_PLAYBOOKS_DIR)/libvirt_user.yml -e "skip_configuration=True"
kdevops_configure_libvirt:
- $(Q)ansible-playbook $(ANSIBLE_VERBOSE) \
+ $(Q)ansible-playbook \
$(KDEVOPS_PLAYBOOKS_DIR)/libvirt_user.yml -e "skip_install=True" \
-e 'running_user=$(USER)'
kdevops_verify_libvirt_user:
- $(Q)ansible-playbook $(ANSIBLE_VERBOSE) \
+ $(Q)ansible-playbook \
$(KDEVOPS_PLAYBOOKS_DIR)/libvirt_user.yml -e "only_verify_user=True"
PHONY += kdevops_verify_libvirt_user
kdevops_libvirt_storage_pool_create:
- $(Q)ansible-playbook $(ANSIBLE_VERBOSE) \
+ $(Q)ansible-playbook \
$(KDEVOPS_PLAYBOOKS_DIR)/libvirt_storage_pool_create.yml
PHONY += kdevops_libvirt_storage_pool_create
diff --git a/Makefile.postfix b/Makefile.postfix
index 226261ee..5840acc2 100644
--- a/Makefile.postfix
+++ b/Makefile.postfix
@@ -7,7 +7,7 @@ POSTFIX_SETUP_ARGS += postfix_relay_host_setup=True
POSTFIX_SETUP_ARGS += postfix_relay_host=$(POSTFIX_RELAY_HOST)
kdevops_postfix_setup_relay: $(KDEVOPS_EXTRA_VARS)
- $(Q)ansible-playbook $(ANSIBLE_VERBOSE) \
+ $(Q)ansible-playbook \
$(KDEVOPS_PLAYBOOKS_DIR)/postfix_relay_host.yml \
--extra-vars=@./extra_vars.yaml
PHONY += kdevops_postfix_setup_relay
diff --git a/docs/fio-tests.md b/docs/fio-tests.md
index 3383d81a..1a77263c 100644
--- a/docs/fio-tests.md
+++ b/docs/fio-tests.md
@@ -308,7 +308,7 @@ CI-specific optimizations:
Enable verbose output:
```bash
make V=1 fio-tests # Verbose build output
-make AV=2 fio-tests # Ansible verbose output
+ANSIBLE_VERBOSITY=2 make fio-tests # Ansible verbose output
```
## Performance considerations
diff --git a/docs/monitoring.md b/docs/monitoring.md
index 9eb10da8..b4800ec9 100644
--- a/docs/monitoring.md
+++ b/docs/monitoring.md
@@ -232,7 +232,7 @@ grep -E "enable_monitoring|monitor_" .config
2. **Check ansible output for monitoring tasks**:
```bash
-make fstests-tests AV=2 | grep -A5 -B5 monitoring
+ANSIBLE_VERBOSITY=2 make fstests-tests | grep -A5 -B5 monitoring
```
3. **Look for error messages**:
diff --git a/docs/reboot-limit.md b/docs/reboot-limit.md
index 305d9ade..305d5d78 100644
--- a/docs/reboot-limit.md
+++ b/docs/reboot-limit.md
@@ -173,7 +173,7 @@ Enable verbose output for troubleshooting:
```bash
# Ansible verbose mode
-make reboot-limit-baseline AV=3
+ANSIBLE_VERBOSITY=3 make reboot-limit-baseline
# Check individual node status
ansible baseline:dev:service -m shell -a "cat /data/reboot-limit/*/reboot-count.txt"
diff --git a/kconfigs/Kconfig.ansible_cfg b/kconfigs/Kconfig.ansible_cfg
index e3fd02f1..bea093fe 100644
--- a/kconfigs/Kconfig.ansible_cfg
+++ b/kconfigs/Kconfig.ansible_cfg
@@ -172,6 +172,26 @@ config ANSIBLE_CFG_CALLBACK_PLUGIN_PROFILE_TASKS
https://docs.ansible.com/ansible/latest/collections/ansible/posix/profile_tasks_callback.html
endmenu
+config ANSIBLE_CFG_VERBOSITY
+ int "Ansible verbosity level"
+ output yaml
+ range 0 6
+ default 0
+ help
+ Set the default verbosity level for Ansible output (0-6).
+
+ Level 0: Normal output (only changes and errors)
+ Level 1: -v equivalent, shows task results
+ Level 2: -vv equivalent, shows task input
+ Level 3: -vvv equivalent, shows connection debug
+ Level 4-6: Increasingly verbose debugging information
+
+ This sets the verbosity key in ansible.cfg [defaults] section.
+ Can be overridden at runtime via ANSIBLE_VERBOSITY environment
+ variable.
+
+ https://docs.ansible.com/ansible/latest/reference_appendices/config.html#default-verbosity
+
config ANSIBLE_CFG_DEPRECATION_WARNINGS
bool "deprecation_warnings"
output yaml
diff --git a/playbooks/roles/ansible_cfg/templates/ansible.cfg.j2 b/playbooks/roles/ansible_cfg/templates/ansible.cfg.j2
index deb1a559..165aec0e 100644
--- a/playbooks/roles/ansible_cfg/templates/ansible.cfg.j2
+++ b/playbooks/roles/ansible_cfg/templates/ansible.cfg.j2
@@ -2,6 +2,7 @@
{% if ansible_cfg_callback_plugin_profile_tasks %}
callbacks_enabled = ansible.posix.profile_tasks, {{ ansible_cfg_callback_plugin_string }}
{% endif %}
+verbosity = {{ ansible_cfg_verbosity | default(0) }}
deprecation_warnings = {{ ansible_cfg_deprecation_warnings }}
stdout_callback = {{ ansible_cfg_callback_plugin_string }}
check_mode_markers = {{ ansible_cfg_callback_plugin_check_mode_markers }}
diff --git a/scripts/ansible.Makefile b/scripts/ansible.Makefile
index 0ce8168f..4d2bc0c4 100644
--- a/scripts/ansible.Makefile
+++ b/scripts/ansible.Makefile
@@ -1,8 +1,5 @@
# SPDX-License-Identifier: copyleft-next-0.3.1
-AV ?= 0
-export ANSIBLE_VERBOSE := $(shell scripts/validate_av.py --av "$(AV)")
-
ansible-requirements:
$(Q)ansible-galaxy install -r requirements.yml
PHONY += ansible-requirements
diff --git a/scripts/archive.Makefile b/scripts/archive.Makefile
index 23a693d7..3356a9ff 100644
--- a/scripts/archive.Makefile
+++ b/scripts/archive.Makefile
@@ -13,7 +13,7 @@ ARCHIVE_DYNAMIC_RUNTIME_VARS += \
endif
ci-archive:
- $(Q)ansible-playbook $(ANSIBLE_VERBOSE) \
+ $(Q)ansible-playbook \
playbooks/kdevops_archive.yml \
--extra-vars '{ $(ARCHIVE_DYNAMIC_RUNTIME_VARS) }' \
--extra-vars=@./extra_vars.yaml
diff --git a/scripts/devconfig.Makefile b/scripts/devconfig.Makefile
index db68dd18..3b368055 100644
--- a/scripts/devconfig.Makefile
+++ b/scripts/devconfig.Makefile
@@ -56,7 +56,7 @@ extend-extra-args-devconfig:
PHONY += devconfig
devconfig: $(KDEVOPS_NODES)
- $(Q)ansible-playbook $(ANSIBLE_VERBOSE) \
+ $(Q)ansible-playbook \
$(KDEVOPS_PLAYBOOKS_DIR)/devconfig.yml \
--extra-vars="$(BOOTLINUX_ARGS)" \
--extra-vars '{ kdevops_cli_install: True }' \
@@ -70,7 +70,7 @@ HELP_TARGETS+=devconfig-generic-help-menu
ifeq (y,$(CONFIG_SYSCTL_TUNING))
PHONY += sysctl-tunings
sysctl-tunings: $(KDEVOPS_NODES)
- $(Q)ansible-playbook $(ANSIBLE_VERBOSE) \
+ $(Q)ansible-playbook \
$(KDEVOPS_PLAYBOOKS_DIR)/devconfig.yml \
--extra-vars="$(BOOTLINUX_ARGS)" $(LIMIT_HOSTS) --tags vars,sysctl
diff --git a/scripts/dynamic-pci-kconfig.Makefile b/scripts/dynamic-pci-kconfig.Makefile
index f4d71355..06dc7886 100644
--- a/scripts/dynamic-pci-kconfig.Makefile
+++ b/scripts/dynamic-pci-kconfig.Makefile
@@ -42,7 +42,7 @@ endif # CONFIG_KDEVOPS_LIBVIRT_PCIE_PASSTHROUGH
HELP_TARGETS += dynamic-kconfig-pci-help
dynamic_pcipassthrough_kconfig:
- $(Q)ansible-playbook $(ANSIBLE_VERBOSE) \
+ $(Q)ansible-playbook \
playbooks/gen-pci-kconfig.yml \
--extra-vars '{ $(PCIE_RUNTIME_VARS) }'
diff --git a/scripts/firstconfig.Makefile b/scripts/firstconfig.Makefile
index 4904afcc..94097cd7 100644
--- a/scripts/firstconfig.Makefile
+++ b/scripts/firstconfig.Makefile
@@ -1,7 +1,7 @@
# SPDX-License-Identifier: copyleft-next-0.3.1
firstconfig:
- $(Q)ansible-playbook $(ANSIBLE_VERBOSE) \
+ $(Q)ansible-playbook \
--extra-vars '{ kdevops_cli_install: True }' \
--tags vars_simple,firstconfig \
$(KDEVOPS_PLAYBOOKS_DIR)/devconfig.yml
diff --git a/scripts/guestfs.Makefile b/scripts/guestfs.Makefile
index 205e3ce0..247d2846 100644
--- a/scripts/guestfs.Makefile
+++ b/scripts/guestfs.Makefile
@@ -52,39 +52,39 @@ KDEVOPS_PROVISION_DESTROY_METHOD := destroy_guestfs
$(Q)make linux-clone
libvirt_pcie_passthrough_permissions:
- $(Q)ansible-playbook $(ANSIBLE_VERBOSE) \
+ $(Q)ansible-playbook \
playbooks/libvirt_pcie_passthrough.yml
$(KDEVOPS_PROVISIONED_SSH):
$(Q)if [[ "$(CONFIG_KDEVOPS_SSH_CONFIG_UPDATE)" == "y" ]]; then \
- ansible-playbook $(ANSIBLE_VERBOSE) \
+ ansible-playbook \
playbooks/update_ssh_config_guestfs.yml \
--extra-vars=@./extra_vars.yaml; \
LIBVIRT_DEFAULT_URI=$(CONFIG_LIBVIRT_URI) \
$(TOPDIR)/scripts/update_ssh_config_guestfs.py; \
fi
- $(Q)ansible $(ANSIBLE_VERBOSE) 'baseline:dev:service' -m wait_for_connection
+ $(Q)ansible 'baseline:dev:service' -m wait_for_connection
$(Q)touch $(KDEVOPS_PROVISIONED_SSH)
install_libguestfs:
- $(Q)ansible-playbook $(ANSIBLE_VERBOSE) \
+ $(Q)ansible-playbook \
--limit 'localhost' \
playbooks/guestfs.yml \
--extra-vars=@./extra_vars.yaml \
--tags install-deps
bringup_guestfs: $(GUESTFS_BRINGUP_DEPS)
- $(Q)ansible-playbook $(ANSIBLE_VERBOSE) \
+ $(Q)ansible-playbook \
--limit 'localhost' \
$(KDEVOPS_PLAYBOOKS_DIR)/guestfs.yml \
--extra-vars=@./extra_vars.yaml \
--tags network,pool,base_image
- $(Q)ansible-playbook $(ANSIBLE_VERBOSE) \
+ $(Q)ansible-playbook \
--limit 'baseline:dev:service:ai' \
playbooks/guestfs.yml \
--extra-vars=@./extra_vars.yaml \
--tags bringup
- $(Q)ansible-playbook $(ANSIBLE_VERBOSE) \
+ $(Q)ansible-playbook \
--limit 'localhost' \
$(KDEVOPS_PLAYBOOKS_DIR)/guestfs.yml \
--extra-vars=@./extra_vars.yaml \
@@ -92,14 +92,14 @@ bringup_guestfs: $(GUESTFS_BRINGUP_DEPS)
PHONY += bringup_guestfs
status_guestfs:
- $(Q)ansible-playbook $(ANSIBLE_VERBOSE) \
+ $(Q)ansible-playbook \
playbooks/guestfs.yml \
--extra-vars=@./extra_vars.yaml \
--tags status
PHONY += status_guestfs
destroy_guestfs:
- $(Q)ansible-playbook $(ANSIBLE_VERBOSE) \
+ $(Q)ansible-playbook \
--limit 'baseline:dev:service' \
playbooks/guestfs.yml \
--extra-vars=@./extra_vars.yaml \
--git a/scripts/install-menuconfig-deps.Makefile b/scripts/install-menuconfig-deps.Makefile
index 4b9aef8d..c16d0a5c 100644
--- a/scripts/install-menuconfig-deps.Makefile
+++ b/scripts/install-menuconfig-deps.Makefile
@@ -1,7 +1,7 @@
# SPDX-License-Identifier: copyleft-next-0.3.1
menuconfig-deps:
- $(Q)ansible-playbook $(ANSIBLE_VERBOSE) \
+ $(Q)ansible-playbook \
$(KDEVOPS_PLAYBOOKS_DIR)/install-menuconfig-deps.yml \
-e 'kdevops_first_run=True'
PHONY += menuconfig-deps
diff --git a/scripts/install-rcloud-deps.Makefile b/scripts/install-rcloud-deps.Makefile
index 94489cdf..6d6235ed 100644
--- a/scripts/install-rcloud-deps.Makefile
+++ b/scripts/install-rcloud-deps.Makefile
@@ -1,7 +1,7 @@
# SPDX-License-Identifier: copyleft-next-0.3.1
rcloud-deps:
- $(Q)ansible-playbook $(ANSIBLE_VERBOSE) \
+ $(Q)ansible-playbook \
$(KDEVOPS_PLAYBOOKS_DIR)/install-rcloud-deps.yml \
-e 'kdevops_first_run=True'
PHONY += rcloud-deps
diff --git a/scripts/iscsi.Makefile b/scripts/iscsi.Makefile
index a647c2b4..d6e42fc9 100644
--- a/scripts/iscsi.Makefile
+++ b/scripts/iscsi.Makefile
@@ -6,7 +6,7 @@ ISCSI_EXTRA_ARGS += kdevops_enable_iscsi=true
ANSIBLE_EXTRA_ARGS += $(ISCSI_EXTRA_ARGS)
iscsi:
- $(Q)ansible-playbook $(ANSIBLE_VERBOSE) \
+ $(Q)ansible-playbook \
--extra-vars=@./extra_vars.yaml \
$(KDEVOPS_PLAYBOOKS_DIR)/iscsi.yml
diff --git a/scripts/journal-server.Makefile b/scripts/journal-server.Makefile
index d3c39712..b6ef1385 100644
--- a/scripts/journal-server.Makefile
+++ b/scripts/journal-server.Makefile
@@ -11,24 +11,24 @@ ANSIBLE_EXTRA_ARGS += devconfig_systemd_journal_use_http='True'
endif
journal-client:
- $(Q)ansible-playbook $(ANSIBLE_VERBOSE) \
+ $(Q)ansible-playbook \
--limit 'baseline:dev' \
--extra-vars '{ kdevops_cli_install: True }' \
--tags vars_simple,journal \
$(KDEVOPS_PLAYBOOKS_DIR)/devconfig.yml
journal-server:
- $(Q)ansible-playbook $(ANSIBLE_VERBOSE) \
+ $(Q)ansible-playbook \
$(KDEVOPS_PLAYBOOKS_DIR)/install_systemd_journal_remote.yml
journal-restart:
- $(Q)ansible-playbook $(ANSIBLE_VERBOSE) \
+ $(Q)ansible-playbook \
--limit 'baseline:dev' \
--tags vars_extra,journal-upload-restart \
$(KDEVOPS_PLAYBOOKS_DIR)/devconfig.yml
journal-status:
- $(Q)ansible-playbook $(ANSIBLE_VERBOSE) \
+ $(Q)ansible-playbook \
--limit 'baseline:dev' \
--tags vars_extra,journal-status \
$(KDEVOPS_PLAYBOOKS_DIR)/devconfig.yml
@@ -41,7 +41,7 @@ journal-dump:
journal-ln:
- $(Q)ansible-playbook $(ANSIBLE_VERBOSE) \
+ $(Q)ansible-playbook \
--limit 'baseline:dev' \
--tags vars_extra,journal_ln \
$(KDEVOPS_PLAYBOOKS_DIR)/devconfig.yml
diff --git a/scripts/kconfig/Makefile b/scripts/kconfig/Makefile
index 76e4f5c3..f59df38c 100644
--- a/scripts/kconfig/Makefile
+++ b/scripts/kconfig/Makefile
@@ -73,7 +73,7 @@ help:
@echo
@echo "Variable options:"
@echo "make V=n [targets] 1: verbose build (Makefile)"
- @echo "make AV=n [targets] 0-6: verbose build (Ansible)"
+ @echo "ANSIBLE_VERBOSITY=n make [targets] 0-6: verbose build (Ansible)"
.PHONY: clean
clean:
diff --git a/scripts/kotd.Makefile b/scripts/kotd.Makefile
index c74aad5a..82dc8042 100644
--- a/scripts/kotd.Makefile
+++ b/scripts/kotd.Makefile
@@ -10,19 +10,19 @@ endif # HAVE_DISTRO_CUSTOM_KOTD_REPO
ANSIBLE_CMD_KOTD_ENABLE :=
kotd: inventory .config
- $(Q)$(ANSIBLE_CMD_KOTD_ENABLE)ansible-playbook $(ANSIBLE_VERBOSE) \
+ $(Q)$(ANSIBLE_CMD_KOTD_ENABLE)ansible-playbook \
playbooks/devconfig.yml --tags vars,kotd \
--extra-vars=@./extra_vars.yaml
kotd-baseline: inventory .config
- $(Q)$(ANSIBLE_CMD_KOTD_ENABLE)ansible-playbook $(ANSIBLE_VERBOSE) \
+ $(Q)$(ANSIBLE_CMD_KOTD_ENABLE)ansible-playbook \
--limit 'baseline' \
playbooks/devconfig.yml \
--tags vars,kotd \
--extra-vars=@./extra_vars.yaml
kotd-dev: inventory .config
- $(Q)$(ANSIBLE_CMD_KOTD_ENABLE)ansible-playbook $(ANSIBLE_VERBOSE) \
+ $(Q)$(ANSIBLE_CMD_KOTD_ENABLE)ansible-playbook \
--limit 'dev' \
playbooks/devconfig.yml \
--tags vars,kotd \
diff --git a/scripts/krb5.Makefile b/scripts/krb5.Makefile
index a414fc8b..0e42d42d 100644
--- a/scripts/krb5.Makefile
+++ b/scripts/krb5.Makefile
@@ -7,12 +7,12 @@ KRB5_EXTRA_ARGS += kdevops_krb5_enable=True
ANSIBLE_EXTRA_ARGS += $(KRB5_EXTRA_ARGS)
kdc:
- $(Q)ansible-playbook $(ANSIBLE_VERBOSE) \
+ $(Q)ansible-playbook \
--extra-vars=@./extra_vars.yaml \
$(KDEVOPS_PLAYBOOKS_DIR)/kdc.yml
krb5:
- $(Q)ansible-playbook $(ANSIBLE_VERBOSE) \
+ $(Q)ansible-playbook \
--extra-vars=@./extra_vars.yaml \
$(KDEVOPS_PLAYBOOKS_DIR)/krb5.yml
diff --git a/scripts/ktls.Makefile b/scripts/ktls.Makefile
index 83a8dbe6..912c4189 100644
--- a/scripts/ktls.Makefile
+++ b/scripts/ktls.Makefile
@@ -1,7 +1,7 @@
ifeq (y,$(CONFIG_KDEVOPS_SETUP_KTLS))
ktls:
- $(Q)ansible-playbook $(ANSIBLE_VERBOSE) \
+ $(Q)ansible-playbook \
--extra-vars=@./extra_vars.yaml \
$(KDEVOPS_PLAYBOOKS_DIR)/ktls.yml
diff --git a/scripts/nfsd.Makefile b/scripts/nfsd.Makefile
index 92933536..a97b1bd2 100644
--- a/scripts/nfsd.Makefile
+++ b/scripts/nfsd.Makefile
@@ -28,7 +28,7 @@ PHONY += extend-extra-args-nfsd
ANSIBLE_EXTRA_ARGS += $(NFSD_EXTRA_ARGS)
nfsd:
- $(Q)ansible-playbook $(ANSIBLE_VERBOSE) \
+ $(Q)ansible-playbook \
--extra-vars=@./extra_vars.yaml \
$(KDEVOPS_PLAYBOOKS_DIR)/nfsd.yml
diff --git a/scripts/nixos.Makefile b/scripts/nixos.Makefile
index 7a88c527..1d8c4e47 100644
--- a/scripts/nixos.Makefile
+++ b/scripts/nixos.Makefile
@@ -42,7 +42,7 @@ KDEVOPS_PROVISION_DESTROY_METHOD := destroy_nixos
$(Q)make linux-clone
libvirt_pcie_passthrough_permissions:
- $(Q)ansible-playbook $(ANSIBLE_VERBOSE) \
+ $(Q)ansible-playbook \
playbooks/libvirt_pcie_passthrough.yml
$(KDEVOPS_PROVISIONED_SSH): $(KDEVOPS_HOSTS_PREFIX)
@@ -51,21 +51,21 @@ $(KDEVOPS_PROVISIONED_SSH): $(KDEVOPS_HOSTS_PREFIX)
$(Q)touch $(KDEVOPS_PROVISIONED_SSH)
install_nixos_deps:
- $(Q)ansible-playbook $(ANSIBLE_VERBOSE) \
+ $(Q)ansible-playbook \
--limit 'localhost' \
playbooks/nixos.yml \
--extra-vars=@./extra_vars.yaml \
--tags install-deps
generate_nixos_configs:
- $(Q)ansible-playbook $(ANSIBLE_VERBOSE) \
+ $(Q)ansible-playbook \
--limit 'localhost' \
playbooks/nixos.yml \
--extra-vars=@./extra_vars.yaml \
--tags generate-configs
bringup_nixos: $(NIXOS_BRINGUP_DEPS) generate_nixos_configs
- $(Q)ansible-playbook $(ANSIBLE_VERBOSE) \
+ $(Q)ansible-playbook \
$(KDEVOPS_PLAYBOOKS_DIR)/nixos.yml \
--extra-vars=@./extra_vars.yaml \
--tags build-vms,bringup,console
@@ -76,7 +76,7 @@ status_nixos:
PHONY += status_nixos
destroy_nixos:
- $(Q)ansible-playbook $(ANSIBLE_VERBOSE) \
+ $(Q)ansible-playbook \
playbooks/nixos.yml \
--extra-vars=@./extra_vars.yaml \
--tags destroy
diff --git a/scripts/provision.Makefile b/scripts/provision.Makefile
index b13d31e8..378cbde4 100644
--- a/scripts/provision.Makefile
+++ b/scripts/provision.Makefile
@@ -69,7 +69,7 @@ KDEVOPS_MRPROPER += $(KDEVOPS_PROVISIONED_DEVCONFIG)
$(KDEVOPS_PROVISIONED_DEVCONFIG):
$(Q)if [[ "$(CONFIG_KDEVOPS_ANSIBLE_PROVISION_PLAYBOOK)" != "" ]]; then \
- ansible-playbook $(ANSIBLE_VERBOSE) \
+ ansible-playbook \
$(KDEVOPS_PLAYBOOKS_DIR)/$(KDEVOPS_ANSIBLE_PROVISION_PLAYBOOK) ;\
fi
$(Q)touch $(KDEVOPS_PROVISIONED_DEVCONFIG)
diff --git a/scripts/rdma.Makefile b/scripts/rdma.Makefile
index c63b63a7..db74c652 100644
--- a/scripts/rdma.Makefile
+++ b/scripts/rdma.Makefile
@@ -1,7 +1,7 @@
ifeq (y,$(CONFIG_KDEVOPS_SETUP_RDMA_SIW))
siw:
- $(Q)ansible-playbook $(ANSIBLE_VERBOSE) \
+ $(Q)ansible-playbook \
--extra-vars=@./extra_vars.yaml \
$(KDEVOPS_PLAYBOOKS_DIR)/siw.yml
@@ -14,7 +14,7 @@ endif
ifeq (y,$(CONFIG_KDEVOPS_SETUP_RDMA_RXE))
rxe:
- $(Q)ansible-playbook $(ANSIBLE_VERBOSE) \
+ $(Q)ansible-playbook \
--extra-vars=@./extra_vars.yaml \
$(KDEVOPS_PLAYBOOKS_DIR)/rxe.yml
diff --git a/scripts/smbd.Makefile b/scripts/smbd.Makefile
index 3101e978..88846fbe 100644
--- a/scripts/smbd.Makefile
+++ b/scripts/smbd.Makefile
@@ -8,7 +8,7 @@ SMBD_EXTRA_ARGS += kdevops_smbd_enable=True
ANSIBLE_EXTRA_ARGS += $(SMBD_EXTRA_ARGS)
smbd:
- $(Q)ansible-playbook $(ANSIBLE_VERBOSE) \
+ $(Q)ansible-playbook \
--extra-vars=@./extra_vars.yaml \
$(KDEVOPS_PLAYBOOKS_DIR)/smbd.yml
diff --git a/scripts/systemd-timesync.Makefile b/scripts/systemd-timesync.Makefile
index 148bf173..c788ca0a 100644
--- a/scripts/systemd-timesync.Makefile
+++ b/scripts/systemd-timesync.Makefile
@@ -20,14 +20,14 @@ ANSIBLE_EXTRA_ARGS += devconfig_enable_systemd_timesyncd_ntp_google_debian='True
endif
timesyncd-client:
- $(Q)ansible-playbook $(ANSIBLE_VERBOSE) \
+ $(Q)ansible-playbook \
--limit 'baseline:dev' \
--extra-vars '{ kdevops_cli_install: True }' \
--tags vars_simple,timesyncd \
$(KDEVOPS_PLAYBOOKS_DIR)/devconfig.yml
timesyncd-server:
- $(Q)ansible-playbook $(ANSIBLE_VERBOSE) \
+ $(Q)ansible-playbook \
$(KDEVOPS_PLAYBOOKS_DIR)/install_systemd_timesyncd.yml
timesyncd-status:
diff --git a/scripts/terraform.Makefile b/scripts/terraform.Makefile
index e18e12b6..363d6cf6 100644
--- a/scripts/terraform.Makefile
+++ b/scripts/terraform.Makefile
@@ -197,36 +197,36 @@ endif
endif
bringup_terraform: lambdalabs-ssh-check
- $(Q)ansible-playbook $(ANSIBLE_VERBOSE) \
+ $(Q)ansible-playbook \
playbooks/terraform.yml --tags bringup \
--extra-vars=@./extra_vars.yaml
$(KDEVOPS_PROVISIONED_SSH):
- $(Q)ansible-playbook $(ANSIBLE_VERBOSE) \
+ $(Q)ansible-playbook \
playbooks/terraform.yml --tags ssh \
--extra-vars=@./extra_vars.yaml
- $(Q)ansible $(ANSIBLE_VERBOSE) \
+ $(Q)ansible \
baseline:dev:service \
-m wait_for_connection
$(Q)touch $(KDEVOPS_PROVISIONED_SSH)
- $(Q)ansible-playbook $(ANSIBLE_VERBOSE) \
+ $(Q)ansible-playbook \
-i hosts playbooks/extra_volumes.yml \
--extra-vars=@./extra_vars.yaml
status_terraform:
- $(Q)ansible-playbook $(ANSIBLE_VERBOSE) \
+ $(Q)ansible-playbook \
playbooks/terraform.yml --tags status \
--extra-vars=@./extra_vars.yaml
destroy_terraform: destroy_terraform_base lambdalabs-ssh-clean-after
destroy_terraform_base:
- $(Q)ansible-playbook $(ANSIBLE_VERBOSE) \
+ $(Q)ansible-playbook \
playbooks/terraform.yml --tags destroy \
--extra-vars=@./extra_vars.yaml
$(Q)rm -f $(KDEVOPS_PROVISIONED_SSH) $(KDEVOPS_PROVISIONED_DEVCONFIG)
$(KDEVOPS_TFVARS): $(KDEVOPS_TFVARS_TEMPLATE) .config
- $(Q)ansible-playbook $(ANSIBLE_VERBOSE) \
+ $(Q)ansible-playbook \
$(KDEVOPS_PLAYBOOKS_DIR)/gen_tfvars.yml \
--extra-vars=@./extra_vars.yaml
diff --git a/scripts/update_etc_hosts.Makefile b/scripts/update_etc_hosts.Makefile
index 5fb90e98..774d36c6 100644
--- a/scripts/update_etc_hosts.Makefile
+++ b/scripts/update_etc_hosts.Makefile
@@ -1,5 +1,5 @@
update_etc_hosts:
- $(Q)ansible-playbook $(ANSIBLE_VERBOSE) \
+ $(Q)ansible-playbook \
playbooks/update_etc_hosts.yml
KDEVOPS_BRING_UP_DEPS_EARLY += update_etc_hosts
diff --git a/scripts/validate_av.py b/scripts/validate_av.py
deleted file mode 100755
index fffb836f..00000000
--- a/scripts/validate_av.py
+++ /dev/null
@@ -1,28 +0,0 @@
-#!/usr/bin/env python3
-# SPDX-License-Identifier: copyleft-next-0.3.1
-
-import argparse
-
-
-def get_ansible_verbosity(av: str, max_level: int = 6) -> str:
- """Return Ansible verbosity flag (e.g. -vv or emtpy)."""
- try:
- av = int(av)
- except ValueError:
- return ""
- av = max(0, min(av, max_level))
- return "-" + "v" * av if av > 0 else ""
-
-
-def main():
- parser = argparse.ArgumentParser(
- description="Validate and return Ansible verbosity level."
- )
- parser.add_argument("--av", type=str, default="0", help="Verbosity level (0-6)")
-
- args = parser.parse_args()
- print(get_ansible_verbosity(args.av))
-
-
-if __name__ == "__main__":
- main()
diff --git a/workflows/ai/Makefile b/workflows/ai/Makefile
index b5fca977..90c809ed 100644
--- a/workflows/ai/Makefile
+++ b/workflows/ai/Makefile
@@ -30,7 +30,7 @@ export AI_ARGS_SEPARATED := $(subst $(space),$(comma),$(AI_ARGS))
# Main AI workflow targets
ai: $(KDEVOPS_NODES) $(ANSIBLE_INVENTORY_FILE)
- $(Q)ansible-playbook $(ANSIBLE_VERBOSE) \
+ $(Q)ansible-playbook \
playbooks/ai.yml \
--extra-vars=@$(KDEVOPS_EXTRA_VARS) \
--extra-vars="$(AI_ARGS) $(AI_MANUAL_ARGS)" \
@@ -44,7 +44,7 @@ ai-dev:
# AI Testing/Benchmark targets
ai-tests: $(KDEVOPS_NODES) $(ANSIBLE_INVENTORY_FILE)
- $(Q)ansible-playbook $(ANSIBLE_VERBOSE) \
+ $(Q)ansible-playbook \
playbooks/ai_tests.yml \
--extra-vars=@$(KDEVOPS_EXTRA_VARS) \
--extra-vars="$(AI_ARGS) $(AI_MANUAL_ARGS)" \
@@ -52,7 +52,7 @@ ai-tests: $(KDEVOPS_NODES) $(ANSIBLE_INVENTORY_FILE)
$(Q)$(MAKE) ai-results
ai-tests-baseline: $(KDEVOPS_NODES) $(ANSIBLE_INVENTORY_FILE)
- $(Q)ansible-playbook $(ANSIBLE_VERBOSE) \
+ $(Q)ansible-playbook \
-l baseline \
playbooks/ai_tests.yml \
--extra-vars=@$(KDEVOPS_EXTRA_VARS) \
@@ -60,7 +60,7 @@ ai-tests-baseline: $(KDEVOPS_NODES) $(ANSIBLE_INVENTORY_FILE)
$(Q)$(MAKE) ai-results-baseline
ai-tests-dev: $(KDEVOPS_NODES) $(ANSIBLE_INVENTORY_FILE)
- $(Q)ansible-playbook $(ANSIBLE_VERBOSE) \
+ $(Q)ansible-playbook \
-l dev \
playbooks/ai_tests.yml \
--extra-vars=@$(KDEVOPS_EXTRA_VARS) \
@@ -69,7 +69,7 @@ ai-tests-dev: $(KDEVOPS_NODES) $(ANSIBLE_INVENTORY_FILE)
# Target to only run results analysis and graph generation
ai-tests-results:
- $(Q)ansible-playbook $(ANSIBLE_VERBOSE) \
+ $(Q)ansible-playbook \
playbooks/ai_tests.yml \
--extra-vars=@$(KDEVOPS_EXTRA_VARS) \
--extra-vars="$(AI_ARGS) $(AI_MANUAL_ARGS)" \
@@ -78,7 +78,7 @@ ai-tests-results:
# Results collection targets
ai-results:
- $(Q)ansible-playbook $(ANSIBLE_VERBOSE) \
+ $(Q)ansible-playbook \
playbooks/ai_results.yml \
--extra-vars=@$(KDEVOPS_EXTRA_VARS) \
--extra-vars="$(AI_ARGS) $(AI_MANUAL_ARGS)" \
@@ -91,26 +91,26 @@ ai-results-dev:
$(Q)$(MAKE) ai-results HOSTS="dev"
monitor-results: $(KDEVOPS_EXTRA_VARS)
- $(Q)ansible-playbook $(ANSIBLE_VERBOSE) \
+ $(Q)ansible-playbook \
playbooks/monitor-results.yml \
--extra-vars=@./extra_vars.yaml
ai-setup:
- $(Q)ansible-playbook $(ANSIBLE_VERBOSE) \
+ $(Q)ansible-playbook \
playbooks/ai_setup.yml \
--extra-vars=@$(KDEVOPS_EXTRA_VARS) \
--extra-vars="$(AI_ARGS) $(AI_MANUAL_ARGS)" \
$(LIMIT_HOSTS)
ai-uninstall:
- $(Q)ansible-playbook $(ANSIBLE_VERBOSE) \
+ $(Q)ansible-playbook \
playbooks/ai_uninstall.yml \
--extra-vars=@$(KDEVOPS_EXTRA_VARS) \
--extra-vars="$(AI_ARGS) $(AI_MANUAL_ARGS)" \
$(LIMIT_HOSTS)
ai-destroy:
- $(Q)ansible-playbook $(ANSIBLE_VERBOSE) \
+ $(Q)ansible-playbook \
playbooks/ai_destroy.yml \
--extra-vars=@$(KDEVOPS_EXTRA_VARS) \
--extra-vars="$(AI_ARGS) $(AI_MANUAL_ARGS)" \
diff --git a/workflows/blktests/Makefile b/workflows/blktests/Makefile
index 047aba3b..4bfbf8e7 100644
--- a/workflows/blktests/Makefile
+++ b/workflows/blktests/Makefile
@@ -57,12 +57,12 @@ extend-extra-args-blktests:
fi
blktests:
- $(Q)ansible-playbook $(ANSIBLE_VERBOSE) \
+ $(Q)ansible-playbook \
playbooks/blktests.yml \
--skip-tags run_tests,copy_results $(LIMIT_HOSTS)
blktests-baseline:
- $(Q)ansible-playbook $(ANSIBLE_VERBOSE) \
+ $(Q)ansible-playbook \
--limit 'baseline' \
playbooks/blktests.yml \
--tags vars,run_tests,copy_results \
@@ -71,7 +71,7 @@ blktests-baseline:
blktests-baseline-skip-kdevops-update:
- $(Q)ansible-playbook $(ANSIBLE_VERBOSE) \
+ $(Q)ansible-playbook \
--limit 'baseline' \
playbooks/blktests.yml \
--tags vars,run_tests,copy_results --skip-tags git_update \
@@ -79,7 +79,7 @@ blktests-baseline-skip-kdevops-update:
--extra-vars=@./extra_vars.yaml $(LIMIT_HOSTS)
blktests-baseline-run-oscheck-only:
- $(Q)ansible-playbook $(ANSIBLE_VERBOSE) \
+ $(Q)ansible-playbook \
--limit 'baseline' \
playbooks/blktests.yml \
--tags vars,run_tests,copy_results \
@@ -88,7 +88,7 @@ blktests-baseline-run-oscheck-only:
--extra-vars=@./extra_vars.yaml $(LIMIT_HOSTS)
blktests-dev:
- $(Q)ansible-playbook $(ANSIBLE_VERBOSE) \
+ $(Q)ansible-playbook \
--limit 'dev' \
playbooks/blktests.yml \
--tags vars,run_tests,copy_results \
@@ -96,7 +96,7 @@ blktests-dev:
--extra-vars=@./extra_vars.yaml $(LIMIT_HOSTS)
blktests-baseline-results:
- $(Q)ansible-playbook $(ANSIBLE_VERBOSE) \
+ $(Q)ansible-playbook \
--limit 'baseline' \
playbooks/blktests.yml \
--tags copy_results,print_results \
@@ -106,7 +106,7 @@ blktests-baseline-results:
blktests-results: blktests-baseline-results
blktests-dev-results:
- $(Q)ansible-playbook $(ANSIBLE_VERBOSE) \
+ $(Q)ansible-playbook \
--limit 'dev' \
playbooks/blktests.yml \
--tags copy_results,print_results \
@@ -114,7 +114,7 @@ blktests-dev-results:
--extra-vars=@./extra_vars.yaml $(LIMIT_HOSTS)
monitor-results: $(KDEVOPS_EXTRA_VARS)
- $(Q)ansible-playbook $(ANSIBLE_VERBOSE) \
+ $(Q)ansible-playbook \
playbooks/monitor-results.yml \
--extra-vars=@./extra_vars.yaml \
$(LIMIT_HOSTS)
diff --git a/workflows/build-linux/Makefile b/workflows/build-linux/Makefile
index d19c3854..cf375a60 100644
--- a/workflows/build-linux/Makefile
+++ b/workflows/build-linux/Makefile
@@ -4,7 +4,7 @@ PHONY += monitor-results monitor-kill
# Main build-linux workflow targets
build-linux: $(KDEVOPS_NODES) $(ANSIBLE_INVENTORY_FILE)
- $(Q)ansible-playbook $(ANSIBLE_VERBOSE) \
+ $(Q)ansible-playbook \
-i hosts \
playbooks/build_linux.yml \
-f 10 \
@@ -23,7 +23,7 @@ build-linux-dev:
# Results collection target
build-linux-results:
- $(Q)ansible-playbook $(ANSIBLE_VERBOSE) \
+ $(Q)ansible-playbook \
-i hosts \
playbooks/build_linux_results.yml \
--extra-vars=@$(KDEVOPS_EXTRA_VARS) \
@@ -65,12 +65,12 @@ build-linux-visualize:
exit 1)
monitor-results: $(KDEVOPS_EXTRA_VARS)
- $(Q)ansible-playbook $(ANSIBLE_VERBOSE) \
+ $(Q)ansible-playbook \
playbooks/monitor-results.yml \
--extra-vars=@$(KDEVOPS_EXTRA_VARS)
monitor-kill: $(KDEVOPS_EXTRA_VARS)
- $(Q)ansible-playbook $(ANSIBLE_VERBOSE) \
+ $(Q)ansible-playbook \
-i hosts \
playbooks/monitor-kill.yml \
--extra-vars=@$(KDEVOPS_EXTRA_VARS) \
diff --git a/workflows/common/Makefile b/workflows/common/Makefile
index 9ae0a0a9..ef9e45f4 100644
--- a/workflows/common/Makefile
+++ b/workflows/common/Makefile
@@ -37,7 +37,7 @@ endif # CONFIG_WORKFLOW_INFER_USER_AND_GROUP == y
ifeq (y,$(CONFIG_KDEVOPS_WORKFLOW_GIT_CLONES_KDEVOPS_GIT))
kdevops-git-reset:
- $(Q)ansible-playbook $(ANSIBLE_VERBOSE) \
+ $(Q)ansible-playbook \
playbooks/common.yml --tags vars,kdevops_reset \
--extra-vars '{ kdevops_git_reset: True }' $(LIMIT_HOSTS)
diff --git a/workflows/cxl/Makefile b/workflows/cxl/Makefile
index 6d7894a9..0c4a939e 100644
--- a/workflows/cxl/Makefile
+++ b/workflows/cxl/Makefile
@@ -17,42 +17,42 @@ BOOTLINUX_CXL_HELP :=
include $(TOPDIR)/workflows/cxl/Makefile.kernel
cxl:
- $(Q)ansible-playbook $(ANSIBLE_VERBOSE) \
+ $(Q)ansible-playbook \
playbooks/cxl.yml \
--skip-tags run_tests,copy_results \
$(LIMIT_HOSTS)
cxl-test-probe:
- $(Q)ansible-playbook $(ANSIBLE_VERBOSE) \
+ $(Q)ansible-playbook \
playbooks/cxl.yml \
--tags vars,cxl-test-prep,cxl-test-probe \
--extra-vars '{ $(CXL_DYNAMIC_RUNTIME_VARS) }' \
$(LIMIT_HOSTS)
cxl-test-meson:
- $(Q)ansible-playbook $(ANSIBLE_VERBOSE) \
+ $(Q)ansible-playbook \
playbooks/cxl.yml \
--tags vars,cxl-test-prep,cxl-test-meson \
--extra-vars '{ $(CXL_DYNAMIC_RUNTIME_VARS) }' \
$(LIMIT_HOSTS)
cxl-results:
- $(Q)ansible-playbook $(ANSIBLE_VERBOSE) \
+ $(Q)ansible-playbook \
playbooks/cxl.yml \
--tags vars,copy_results $(LIMIT_HOSTS)
cxl-mem-setup:
- $(Q)ansible-playbook $(ANSIBLE_VERBOSE) \
+ $(Q)ansible-playbook \
playbooks/cxl.yml \
--tags vars,extra-vars,cxl-mem-setup $(LIMIT_HOSTS)
cxl-create-dc-region:
- $(Q)ansible-playbook $(ANSIBLE_VERBOSE) \
+ $(Q)ansible-playbook \
playbooks/cxl.yml \
--tags vars,cxl-create-dc-region $(LIMIT_HOSTS)
cxl-dcd-setup:
- $(Q)ansible-playbook $(ANSIBLE_VERBOSE) \
+ $(Q)ansible-playbook \
playbooks/cxl.yml \
--tags vars,cxl-dcd-setup $(LIMIT_HOSTS)
diff --git a/workflows/demos/reboot-limit/Makefile b/workflows/demos/reboot-limit/Makefile
index 680eed88..3db8ad53 100644
--- a/workflows/demos/reboot-limit/Makefile
+++ b/workflows/demos/reboot-limit/Makefile
@@ -121,7 +121,7 @@ endif # CONFIG_REBOOT_LIMIT_ENABLE_LOOP
# The playbook reboot-limit.yml is used to run all tasks defined except those
# with tags "run_tests" or "copy_results".
reboot-limit: $(KDEVOPS_EXTRA_VARS)
- $(Q)ansible-playbook $(ANSIBLE_VERBOSE) \
+ $(Q)ansible-playbook \
playbooks/reboot-limit.yml \
--skip-tags run_tests,copy_results \
--extra-vars="reboot_limit_max=$(REBOOT_LIMIT_MAX)"
@@ -152,13 +152,13 @@ reboot-limit: $(KDEVOPS_EXTRA_VARS)
# use the vars tag to ensure we get variables defined which we construct on the
# fly.
reboot-limit-baseline: $(KDEVOPS_EXTRA_VARS)
- $(Q)ansible-playbook $(ANSIBLE_VERBOSE) \
+ $(Q)ansible-playbook \
--limit 'baseline' \
playbooks/reboot-limit.yml \
--tags vars,first_run,reset \
--extra-vars=@./extra_vars.yaml \
--extra-vars="reboot_limit_max=$(REBOOT_LIMIT_MAX)"
- $(Q)ansible-playbook $(ANSIBLE_VERBOSE) \
+ $(Q)ansible-playbook \
--limit 'baseline' \
playbooks/reboot-limit.yml \
--tags vars,run_tests,copy_results \
@@ -178,7 +178,7 @@ reboot-limit-baseline-kotd:
# Resets the boot counters so we start from scratch
reboot-limit-baseline-reset:
- $(Q)ansible-playbook $(ANSIBLE_VERBOSE) \
+ $(Q)ansible-playbook \
--limit 'baseline' \
playbooks/reboot-limit.yml \
--tags vars,reset \
@@ -191,13 +191,13 @@ reboot-limit-tests: reboot-limit-baseline reboot-limit-dev
# Check if dev group has hosts before running
reboot-limit-dev: $(KDEVOPS_EXTRA_VARS)
$(Q)if grep -A1 '^\[dev\]' hosts | grep -qE '^[a-zA-Z0-9]'; then \
- ansible-playbook $(ANSIBLE_VERBOSE) \
+ ansible-playbook \
--limit 'dev' \
playbooks/reboot-limit.yml \
--tags vars,first_run,reset \
--extra-vars=@./extra_vars.yaml \
--extra-vars="reboot_limit_max=$(REBOOT_LIMIT_MAX)" && \
- ansible-playbook $(ANSIBLE_VERBOSE) \
+ ansible-playbook \
--limit 'dev' \
playbooks/reboot-limit.yml \
--tags vars,run_tests,copy_results \
@@ -214,7 +214,7 @@ reboot-limit-dev-kotd:
$(Q)$(REBOOT_LIMIT_LOOP_KOTD) dev
reboot-limit-dev-reset:
- $(Q)ansible-playbook $(ANSIBLE_VERBOSE) \
+ $(Q)ansible-playbook \
--limit 'dev' \
playbooks/reboot-limit.yml \
--tags vars,reset \
diff --git a/workflows/fio-tests/Makefile b/workflows/fio-tests/Makefile
index 218cfbfc..30ac2ea6 100644
--- a/workflows/fio-tests/Makefile
+++ b/workflows/fio-tests/Makefile
@@ -1,37 +1,37 @@
fio-tests:
- $(Q)ansible-playbook $(ANSIBLE_VERBOSE) \
+ $(Q)ansible-playbook \
--extra-vars=@$(KDEVOPS_EXTRA_VARS) \
playbooks/fio-tests.yml \
$(LIMIT_HOSTS)
fio-tests-baseline:
- $(Q)ansible-playbook $(ANSIBLE_VERBOSE) \
+ $(Q)ansible-playbook \
--extra-vars=@$(KDEVOPS_EXTRA_VARS) \
playbooks/fio-tests-baseline.yml \
$(LIMIT_HOSTS)
fio-tests-results:
- $(Q)ansible-playbook $(ANSIBLE_VERBOSE) \
+ $(Q)ansible-playbook \
--extra-vars=@$(KDEVOPS_EXTRA_VARS) \
playbooks/fio-tests.yml \
--tags results \
$(LIMIT_HOSTS)
fio-tests-graph:
- $(Q)ansible-playbook $(ANSIBLE_VERBOSE) \
+ $(Q)ansible-playbook \
--extra-vars=@$(KDEVOPS_EXTRA_VARS) \
playbooks/fio-tests-graph.yml \
$(LIMIT_HOSTS)
fio-tests-compare:
- $(Q)ansible-playbook $(ANSIBLE_VERBOSE) \
+ $(Q)ansible-playbook \
--extra-vars=@$(KDEVOPS_EXTRA_VARS) \
playbooks/fio-tests-compare.yml \
$(LIMIT_HOSTS)
fio-tests-trend-analysis:
- $(Q)ansible-playbook $(ANSIBLE_VERBOSE) \
+ $(Q)ansible-playbook \
--extra-vars=@$(KDEVOPS_EXTRA_VARS) \
playbooks/fio-tests-trend-analysis.yml \
$(LIMIT_HOSTS)
diff --git a/workflows/fstests/Makefile b/workflows/fstests/Makefile
index ef6347ac..4de28a20 100644
--- a/workflows/fstests/Makefile
+++ b/workflows/fstests/Makefile
@@ -129,20 +129,20 @@ endif
endif
fstests: $(FSTESTS_BASELINE_EXTRA)
- $(Q)ansible-playbook $(ANSIBLE_VERBOSE) \
+ $(Q)ansible-playbook \
--limit 'localhost:baseline:dev' \
playbooks/fstests.yml \
--skip-tags run_tests,copy_results $(LIMIT_HOSTS)
fstests-kdevops-setup: $(KDEVOPS_EXTRA_VARS) $(FSTESTS_BASELINE_EXTRA)
- $(Q)ansible-playbook $(ANSIBLE_VERBOSE) \
+ $(Q)ansible-playbook \
--limit 'baseline:dev' \
playbooks/fstests.yml \
--tags vars,kdevops_fstests_setup,gendisks \
$(LIMIT_HOSTS)
fstests-baseline: $(FSTESTS_BASELINE_EXTRA)
- $(Q)PYTHONUNBUFFERED=1 ansible-playbook $(ANSIBLE_VERBOSE) \
+ $(Q)PYTHONUNBUFFERED=1 ansible-playbook \
--limit 'baseline' \
playbooks/fstests.yml \
--tags vars,run_tests,copy_results \
@@ -150,7 +150,7 @@ fstests-baseline: $(FSTESTS_BASELINE_EXTRA)
--extra-vars=@./extra_vars.yaml $(LIMIT_HOSTS)
fstests-baseline-skip-kdevops-update: $(KDEVOPS_EXTRA_VARS)
- $(Q)ansible-playbook $(ANSIBLE_VERBOSE) \
+ $(Q)ansible-playbook \
--limit 'baseline' \
playbooks/fstests.yml \
--tags run_tests,copy_results \
@@ -161,7 +161,7 @@ fstests-baseline-skip-kdevops-update: $(KDEVOPS_EXTRA_VARS)
$(LIMIT_HOSTS)
fstests-baseline-run-oscheck-only: $(KDEVOPS_EXTRA_VARS)
- $(Q)ansible-playbook $(ANSIBLE_VERBOSE) \
+ $(Q)ansible-playbook \
--limit 'baseline' \
playbooks/fstests.yml \
--tags run_tests,copy_results \
@@ -172,7 +172,7 @@ fstests-baseline-run-oscheck-only: $(KDEVOPS_EXTRA_VARS)
$(LIMIT_HOSTS)
fstests-config: $(KDEVOPS_EXTRA_VARS)
- $(Q)ansible-playbook $(ANSIBLE_VERBOSE) \
+ $(Q)ansible-playbook \
--limit 'baseline' \
playbooks/fstests.yml \
--tags vars,generate-fstests-config \
@@ -180,14 +180,14 @@ fstests-config: $(KDEVOPS_EXTRA_VARS)
$(LIMIT_HOSTS)
fstests-config-debug: $(KDEVOPS_EXTRA_VARS)
- $(Q)ansible-playbook $(ANSIBLE_VERBOSE) \
+ $(Q)ansible-playbook \
playbooks/fstests.yml \
-e 'fstests_debug_localhost=True' \
--tags vars,generate-fstests-config \
--extra-vars=@./extra_vars.yaml
fstests-dev: $(KDEVOPS_EXTRA_VARS)
- $(Q)ansible-playbook $(ANSIBLE_VERBOSE) \
+ $(Q)ansible-playbook \
--limit 'dev' \
playbooks/fstests.yml \
--tags vars,run_tests,copy_results \
@@ -196,7 +196,7 @@ fstests-dev: $(KDEVOPS_EXTRA_VARS)
--extra-vars=@./extra_vars.yaml $(LIMIT_HOSTS)
fstests-tests: $(KDEVOPS_EXTRA_VARS)
- $(Q)ansible-playbook $(ANSIBLE_VERBOSE) \
+ $(Q)ansible-playbook \
--limit 'baseline:dev' \
playbooks/fstests.yml \
--tags vars,run_tests,copy_results \
@@ -205,7 +205,7 @@ fstests-tests: $(KDEVOPS_EXTRA_VARS)
--extra-vars=@./extra_vars.yaml $(LIMIT_HOSTS)
fstests-baseline-results-tfb-ls: $(KDEVOPS_EXTRA_VARS)
- $(Q)ansible-playbook $(ANSIBLE_VERBOSE) \
+ $(Q)ansible-playbook \
--limit 'baseline' \
playbooks/fstests.yml \
--tags vars,tfb \
@@ -215,7 +215,7 @@ fstests-baseline-results-tfb-ls: $(KDEVOPS_EXTRA_VARS)
--extra-vars=@./extra_vars.yaml $(LIMIT_HOSTS)
fstests-baseline-results-tfb-trim: $(KDEVOPS_EXTRA_VARS)
- $(Q)ansible-playbook $(ANSIBLE_VERBOSE) \
+ $(Q)ansible-playbook \
--limit 'baseline' \
playbooks/fstests.yml \
--tags vars,tfb \
@@ -225,7 +225,7 @@ fstests-baseline-results-tfb-trim: $(KDEVOPS_EXTRA_VARS)
--extra-vars=@./extra_vars.yaml $(LIMIT_HOSTS)
fstests-baseline-results: $(KDEVOPS_EXTRA_VARS)
- $(Q)ansible-playbook $(ANSIBLE_VERBOSE) \
+ $(Q)ansible-playbook \
--limit 'baseline' \
playbooks/fstests.yml \
--tags copy_results,print_results,tfb \
@@ -236,7 +236,7 @@ fstests-baseline-results: $(KDEVOPS_EXTRA_VARS)
fstests-results: fstests-baseline-results
fstests-dev-results: $(KDEVOPS_EXTRA_VARS)
- $(Q)ansible-playbook $(ANSIBLE_VERBOSE) \
+ $(Q)ansible-playbook \
--limit 'dev' \
playbooks/fstests.yml \
--tags copy_results,print_results \
@@ -245,7 +245,7 @@ fstests-dev-results: $(KDEVOPS_EXTRA_VARS)
$(LIMIT_HOSTS)
monitor-results: $(KDEVOPS_EXTRA_VARS)
- $(Q)ansible-playbook $(ANSIBLE_VERBOSE) \
+ $(Q)ansible-playbook \
playbooks/monitor-results.yml \
--extra-vars=@./extra_vars.yaml \
$(LIMIT_HOSTS)
diff --git a/workflows/gitr/Makefile b/workflows/gitr/Makefile
index b1b7fe37..ad2fcefb 100644
--- a/workflows/gitr/Makefile
+++ b/workflows/gitr/Makefile
@@ -79,13 +79,13 @@ XARGS_ARGS := -I {} bash -c 'echo "{}:"; cat {}; echo;'
endif
gitr:
- $(Q)ansible-playbook $(ANSIBLE_VERBOSE) \
+ $(Q)ansible-playbook \
--limit 'baseline:dev' \
--skip-tags run_tests,run_specific_tests,copy_results \
$(KDEVOPS_PLAYBOOKS_DIR)/gitr.yml
gitr-baseline:
- $(Q)ansible-playbook $(ANSIBLE_VERBOSE) \
+ $(Q)ansible-playbook \
--limit 'baseline' \
--tags $(GITR_PLAY_TAGS) \
--extra-vars=@./extra_vars.yaml \
@@ -93,7 +93,7 @@ gitr-baseline:
gitr-dev-baseline:
- $(Q)ansible-playbook $(ANSIBLE_VERBOSE) \
+ $(Q)ansible-playbook \
--limit 'dev' \
--tags $(GITR_PLAY_TAGS) \
--extra-vars=@./extra_vars.yaml \
@@ -101,7 +101,7 @@ gitr-dev-baseline:
gitr-dev-reset:
- $(Q)ansible-playbook $(ANSIBLE_VERBOSE) \
+ $(Q)ansible-playbook \
--limit 'dev' \
--tags vars,reset \
--extra-vars=@./extra_vars.yaml \
diff --git a/workflows/linux/Makefile b/workflows/linux/Makefile
index 5cbf92ca..a6b8f2ea 100644
--- a/workflows/linux/Makefile
+++ b/workflows/linux/Makefile
@@ -111,14 +111,14 @@ ifeq (y,$(CONFIG_BOOTLINUX_AB_DIFFERENT_REF))
linux: linux-baseline linux-dev
else
linux: $(KDEVOPS_NODES)
- $(Q)ansible-playbook $(ANSIBLE_VERBOSE) \
+ $(Q)ansible-playbook \
--limit '$(BOOTLINUX_LIMIT)' \
$(KDEVOPS_PLAYBOOKS_DIR)/bootlinux.yml \
--extra-vars="$(BOOTLINUX_ARGS)" $(LIMIT_HOSTS)
endif
else
linux: $(KDEVOPS_NODES)
- $(Q)ansible-playbook $(ANSIBLE_VERBOSE) \
+ $(Q)ansible-playbook \
--limit '$(BOOTLINUX_LIMIT)' \
$(KDEVOPS_PLAYBOOKS_DIR)/bootlinux.yml \
--extra-vars="$(BOOTLINUX_ARGS)" $(LIMIT_HOSTS)
@@ -127,7 +127,7 @@ endif
PHONY += linux-baseline
ifeq (y,$(CONFIG_KDEVOPS_BASELINE_AND_DEV))
linux-baseline: $(KDEVOPS_NODES)
- $(Q)ansible-playbook $(ANSIBLE_VERBOSE) \
+ $(Q)ansible-playbook \
--limit baseline \
$(KDEVOPS_PLAYBOOKS_DIR)/bootlinux.yml \
--extra-vars="$(BOOTLINUX_ARGS)"
@@ -140,7 +140,7 @@ endif
PHONY += linux-dev
ifeq (y,$(CONFIG_KDEVOPS_BASELINE_AND_DEV))
linux-dev: $(KDEVOPS_NODES)
- $(Q)ansible-playbook $(ANSIBLE_VERBOSE) \
+ $(Q)ansible-playbook \
--limit dev \
$(KDEVOPS_PLAYBOOKS_DIR)/bootlinux.yml \
--extra-vars="$(BOOTLINUX_ARGS)"
@@ -152,7 +152,7 @@ endif
PHONY += linux-mount
linux-mount:
- $(Q)ansible-playbook $(ANSIBLE_VERBOSE) \
+ $(Q)ansible-playbook \
--limit '$(BOOTLINUX_LIMIT)' \
$(KDEVOPS_PLAYBOOKS_DIR)/bootlinux.yml \
--tags vars,9p_mount \
@@ -160,7 +160,7 @@ linux-mount:
PHONY += linux-deploy
linux-deploy:
- $(Q)ansible-playbook $(ANSIBLE_VERBOSE) \
+ $(Q)ansible-playbook \
--limit '$(BOOTLINUX_LIMIT)' \
$(KDEVOPS_PLAYBOOKS_DIR)/bootlinux.yml \
--tags vars,build-linux,install-linux,manual-update-grub,saved,vars,reboot \
@@ -168,7 +168,7 @@ linux-deploy:
PHONY += linux-build
linux-build:
- $(Q)ansible-playbook $(ANSIBLE_VERBOSE) \
+ $(Q)ansible-playbook \
--limit '$(BOOTLINUX_LIMIT)' \
$(KDEVOPS_PLAYBOOKS_DIR)/bootlinux.yml \
--tags vars,build-linux,saved,vars \
@@ -176,7 +176,7 @@ linux-build:
PHONY += linux-install
linux-install:
- $(Q)ansible-playbook $(ANSIBLE_VERBOSE) \
+ $(Q)ansible-playbook \
--limit '$(BOOTLINUX_LIMIT)' \
$(KDEVOPS_PLAYBOOKS_DIR)/bootlinux.yml \
--tags vars,build-linux,install-linux \
@@ -184,7 +184,7 @@ linux-install:
PHONY += linux-uninstall
linux-uninstall:
- $(Q)ansible-playbook $(ANSIBLE_VERBOSE) \
+ $(Q)ansible-playbook \
--limit '$(BOOTLINUX_LIMIT)' \
$(KDEVOPS_PLAYBOOKS_DIR)/bootlinux.yml \
--tags uninstall-linux,vars \
@@ -192,7 +192,7 @@ linux-uninstall:
$(LIMIT_HOSTS)
linux-clone-clients: $(KDEVOPS_NODES)
- $(Q)ansible-playbook $(ANSIBLE_VERBOSE) \
+ $(Q)ansible-playbook \
--limit '$(BOOTLINUX_LIMIT)' \
$(KDEVOPS_PLAYBOOKS_DIR)/bootlinux.yml \
--extra-vars="$(BOOTLINUX_ARGS)" $(LIMIT_HOSTS) \
@@ -200,7 +200,7 @@ linux-clone-clients: $(KDEVOPS_NODES)
PHONY += linux-clone-9p
linux-clone-9p: $(KDEVOPS_NODES)
- $(Q)ansible-playbook $(ANSIBLE_VERBOSE) \
+ $(Q)ansible-playbook \
--limit 'localhost' \
$(KDEVOPS_PLAYBOOKS_DIR)/bootlinux.yml \
--extra-vars="$(BOOTLINUX_ARGS)" \
@@ -211,14 +211,14 @@ linux-clone: $(KDEVOPS_NODES) $(LINUX_CLONE_DEFAULT_TYPE)
PHONY += linux-grub-setup
linux-grub-setup:
- $(Q)ansible-playbook $(ANSIBLE_VERBOSE) \
+ $(Q)ansible-playbook \
--limit '$(BOOTLINUX_LIMIT)' \
$(KDEVOPS_PLAYBOOKS_DIR)/bootlinux.yml \
--extra-vars="$(BOOTLINUX_ARGS)" $(LIMIT_HOSTS) --tags manual-update-grub,saved,vars
PHONY += linux-reboot
linux-reboot:
- $(Q)ansible-playbook $(ANSIBLE_VERBOSE) \
+ $(Q)ansible-playbook \
--limit '$(BOOTLINUX_LIMIT)' \
$(KDEVOPS_PLAYBOOKS_DIR)/bootlinux.yml \
--extra-vars="$(BOOTLINUX_ARGS)" $(LIMIT_HOSTS) --tags vars,reboot
@@ -232,7 +232,7 @@ uname:
ifeq (y,$(CONFIG_KDEVOPS_WORKFLOW_ENABLE_CXL))
PHONY += linux-cxl
linux-cxl: $(KDEVOPS_NODES)
- $(Q)ansible-playbook $(ANSIBLE_VERBOSE) \
+ $(Q)ansible-playbook \
--limit '$(BOOTLINUX_LIMIT)' \
$(KDEVOPS_PLAYBOOKS_DIR)/bootlinux.yml \
--tags 'vars,cxl-build,cxl-install' \
diff --git a/workflows/ltp/Makefile b/workflows/ltp/Makefile
index 592c4f2b..4510e849 100644
--- a/workflows/ltp/Makefile
+++ b/workflows/ltp/Makefile
@@ -105,13 +105,13 @@ XARGS_ARGS := -I {} bash -c 'echo "{}:"; cat {}; echo;'
endif
ltp:
- $(Q)ansible-playbook $(ANSIBLE_VERBOSE) \
+ $(Q)ansible-playbook \
--limit 'baseline:dev' \
--skip-tags run_tests,copy_results \
$(KDEVOPS_PLAYBOOKS_DIR)/ltp.yml
ltp-baseline:
- $(Q)ansible-playbook $(ANSIBLE_VERBOSE) \
+ $(Q)ansible-playbook \
--limit 'baseline' \
--tags vars,run_tests,copy_results \
--extra-vars=@./extra_vars.yaml \
@@ -119,7 +119,7 @@ ltp-baseline:
ltp-dev-baseline:
- $(Q)ansible-playbook $(ANSIBLE_VERBOSE) \
+ $(Q)ansible-playbook \
--limit 'dev' \
--tags vars,run_tests,copy_results \
--extra-vars=@./extra_vars.yaml \
@@ -127,7 +127,7 @@ ltp-dev-baseline:
ltp-dev-reset:
- $(Q)ansible-playbook $(ANSIBLE_VERBOSE) \
+ $(Q)ansible-playbook \
--limit 'dev' \
--tags vars,reset \
--extra-vars=@./extra_vars.yaml \
diff --git a/workflows/minio/Makefile b/workflows/minio/Makefile
index 69c3c687..6344256f 100644
--- a/workflows/minio/Makefile
+++ b/workflows/minio/Makefile
@@ -14,25 +14,25 @@ $(MINIO_DATA_TARGET): $(ANSIBLE_INVENTORY_FILE)
$(Q)$(MAKE) $(MINIO_DATA_TARGET_INSTALL)
$(MINIO_DATA_TARGET_INSTALL): $(ANSIBLE_INVENTORY_FILE)
- $(Q)ansible-playbook $(ANSIBLE_VERBOSE) \
+ $(Q)ansible-playbook \
$(MINIO_PLAYBOOK) \
--extra-vars=@$(KDEVOPS_EXTRA_VARS) \
--tags vars,minio_install
$(MINIO_DATA_TARGET_UNINSTALL): $(ANSIBLE_INVENTORY_FILE)
- $(Q)ansible-playbook $(ANSIBLE_VERBOSE) \
+ $(Q)ansible-playbook \
$(MINIO_PLAYBOOK) \
--extra-vars=@$(KDEVOPS_EXTRA_VARS) \
--tags vars,minio_uninstall
$(MINIO_DATA_TARGET_DESTROY): $(ANSIBLE_INVENTORY_FILE)
- $(Q)ansible-playbook $(ANSIBLE_VERBOSE) \
+ $(Q)ansible-playbook \
$(MINIO_PLAYBOOK) \
--extra-vars=@$(KDEVOPS_EXTRA_VARS) \
--tags vars,minio_destroy
$(MINIO_DATA_TARGET_RUN): $(ANSIBLE_INVENTORY_FILE)
- $(Q)ansible-playbook $(ANSIBLE_VERBOSE) \
+ $(Q)ansible-playbook \
$(MINIO_PLAYBOOK) \
--extra-vars=@$(KDEVOPS_EXTRA_VARS) \
--tags vars,minio_warp
@@ -51,7 +51,7 @@ $(MINIO_DATA_TARGET_RESULTS):
fi
$(MINIO_DATA_TARGET_MONITOR): $(KDEVOPS_EXTRA_VARS)
- $(Q)ansible-playbook $(ANSIBLE_VERBOSE) \
+ $(Q)ansible-playbook \
playbooks/monitor-results.yml \
--extra-vars=@./extra_vars.yaml
diff --git a/workflows/mmtests/Makefile b/workflows/mmtests/Makefile
index c6248b95..712ce70d 100644
--- a/workflows/mmtests/Makefile
+++ b/workflows/mmtests/Makefile
@@ -2,55 +2,55 @@ MMTESTS_ARGS :=
mmtests:
- $(Q)ansible-playbook $(ANSIBLE_VERBOSE) \
+ $(Q)ansible-playbook \
playbooks/mmtests.yml \
--extra-vars=@./extra_vars.yaml \
--tags deps,setup
$(MMTESTS_ARGS)
mmtests-baseline:
- $(Q)ansible-playbook $(ANSIBLE_VERBOSE) \
+ $(Q)ansible-playbook \
-l 'mmtests:&baseline' playbooks/mmtests.yml \
--extra-vars=@./extra_vars.yaml \
--tags run_tests \
$(MMTESTS_ARGS)
mmtests-dev:
- $(Q)ansible-playbook $(ANSIBLE_VERBOSE) \
+ $(Q)ansible-playbook \
-l 'mmtests:&dev' playbooks/mmtests.yml \
--extra-vars=@./extra_vars.yaml \
--tags run_tests \
$(MMTESTS_ARGS)
mmtests-tests:
- $(Q)ansible-playbook $(ANSIBLE_VERBOSE) \
+ $(Q)ansible-playbook \
playbooks/mmtests.yml \
--extra-vars=@./extra_vars.yaml \
--tags run_tests,results \
$(MMTESTS_ARGS)
mmtests-results:
- $(Q)ansible-playbook $(ANSIBLE_VERBOSE) \
+ $(Q)ansible-playbook \
playbooks/mmtests.yml \
--extra-vars=@./extra_vars.yaml \
--tags results \
$(MMTESTS_ARGS)
mmtests-compare:
- $(Q)ansible-playbook $(ANSIBLE_VERBOSE) \
+ $(Q)ansible-playbook \
playbooks/mmtests-compare.yml \
--extra-vars=@./extra_vars.yaml \
--tags deps,compare \
$(MMTESTS_ARGS)
monitor-results: $(KDEVOPS_EXTRA_VARS)
- $(Q)ansible-playbook $(ANSIBLE_VERBOSE) \
+ $(Q)ansible-playbook \
playbooks/monitor-results.yml \
--extra-vars=@./extra_vars.yaml \
$(MMTESTS_ARGS)
mmtests-clean:
- $(Q)ansible-playbook $(ANSIBLE_VERBOSE) \
+ $(Q)ansible-playbook \
playbooks/mmtests.yml \
--extra-vars=@./extra_vars.yaml \
--tags clean \
diff --git a/workflows/nfstest/Makefile b/workflows/nfstest/Makefile
index 4bd8e147..2842a10d 100644
--- a/workflows/nfstest/Makefile
+++ b/workflows/nfstest/Makefile
@@ -62,13 +62,13 @@ XARGS_ARGS := -I {} bash -c 'echo "{}:"; cat {}; echo;'
endif
nfstest:
- $(Q)ansible-playbook $(ANSIBLE_VERBOSE) \
+ $(Q)ansible-playbook \
--limit 'baseline:dev' \
--skip-tags run_tests,copy_results \
$(KDEVOPS_PLAYBOOKS_DIR)/nfstest.yml
nfstest-baseline:
- $(Q)ansible-playbook $(ANSIBLE_VERBOSE) \
+ $(Q)ansible-playbook \
--limit 'baseline' \
--tags vars,run_tests,copy_results \
--extra-vars=@./extra_vars.yaml \
@@ -76,7 +76,7 @@ nfstest-baseline:
nfstest-dev-baseline:
- $(Q)ansible-playbook $(ANSIBLE_VERBOSE) \
+ $(Q)ansible-playbook \
--limit 'dev' \
--tags vars,run_tests,copy_results \
--extra-vars=@./extra_vars.yaml \
@@ -84,7 +84,7 @@ nfstest-dev-baseline:
nfstest-dev-reset:
- $(Q)ansible-playbook $(ANSIBLE_VERBOSE) \
+ $(Q)ansible-playbook \
--limit 'dev' \
--tags vars,reset \
--extra-vars=@./extra_vars.yaml \
diff --git a/workflows/pynfs/Makefile b/workflows/pynfs/Makefile
index 29b0feac..df808e25 100644
--- a/workflows/pynfs/Makefile
+++ b/workflows/pynfs/Makefile
@@ -32,18 +32,18 @@ endif
# Makefile for pynfs targets
pynfs:
- $(Q)ansible-playbook $(ANSIBLE_VERBOSE) \
+ $(Q)ansible-playbook \
--limit 'baseline:dev' \
--skip-tags run_tests,copy_results,clean_local_results \
$(KDEVOPS_PLAYBOOKS_DIR)/pynfs.yml
pynfs-baseline:
- $(Q)ansible-playbook $(ANSIBLE_VERBOSE) \
+ $(Q)ansible-playbook \
--limit 'baseline' \
--tags vars,first_run,reset \
--extra-vars=@./extra_vars.yaml \
$(KDEVOPS_PLAYBOOKS_DIR)/pynfs.yml
- $(Q)ansible-playbook $(ANSIBLE_VERBOSE) \
+ $(Q)ansible-playbook \
--limit 'baseline' \
--tags vars,run_tests,copy_results \
--extra-vars=@./extra_vars.yaml \
@@ -52,12 +52,12 @@ pynfs-baseline:
# Below are the corresponding dev targets
pynfs-dev-baseline:
- $(Q)ansible-playbook $(ANSIBLE_VERBOSE) \
+ $(Q)ansible-playbook \
--limit 'dev' \
--tags vars,first_run,reset \
--extra-vars=@./extra_vars.yaml \
$(KDEVOPS_PLAYBOOKS_DIR)/pynfs.yml
- $(Q)ansible-playbook $(ANSIBLE_VERBOSE) \
+ $(Q)ansible-playbook \
--limit 'dev' \
--tags vars,run_tests,copy_results \
--extra-vars=@./extra_vars.yaml \
@@ -65,7 +65,7 @@ pynfs-dev-baseline:
pynfs-dev-reset:
- $(Q)ansible-playbook $(ANSIBLE_VERBOSE) \
+ $(Q)ansible-playbook \
--limit 'dev' \
--tags vars,reset \
--extra-vars=@./extra_vars.yaml \
diff --git a/workflows/rcloud/Makefile b/workflows/rcloud/Makefile
index 14f99679..dddee161 100644
--- a/workflows/rcloud/Makefile
+++ b/workflows/rcloud/Makefile
@@ -54,7 +54,7 @@ rcloud-build: $(RCLOUD_WORKFLOW)/target/release/rcloud $(RCLOUD_DEPS)
# Create base images with proper customization (networking, SSH, users, etc.)
rcloud-base-images:
@echo "Creating base images with virt-builder customization..."
- $(Q)ansible-playbook $(ANSIBLE_VERBOSE) \
+ $(Q)ansible-playbook \
--limit 'localhost' \
--extra-vars=@./extra_vars.yaml \
--tags network,pool,base_image \
@@ -64,7 +64,7 @@ rcloud-base-images:
# Install rcloud (copy binary, setup systemd service, install Terraform provider)
rcloud: rcloud-build rcloud-base-images
@echo "Installing rcloud..."
- $(Q)ansible-playbook $(ANSIBLE_VERBOSE) \
+ $(Q)ansible-playbook \
--extra-vars=@./extra_vars.yaml \
-i inventory/hosts \
playbooks/rcloud.yml
diff --git a/workflows/selftests/Makefile b/workflows/selftests/Makefile
index b040647e..2dd3a495 100644
--- a/workflows/selftests/Makefile
+++ b/workflows/selftests/Makefile
@@ -29,26 +29,26 @@ include $(TOPDIR)/workflows/selftests/tests/Makefile.sysctl
include $(TOPDIR)/workflows/selftests/tests/Makefile.xarray
selftests:
- $(Q)ansible-playbook $(ANSIBLE_VERBOSE) \
+ $(Q)ansible-playbook \
playbooks/selftests.yml \
--skip-tags run_tests,copy_results,check_results \
$(LIMIT_HOSTS)
selftests-baseline:
- $(Q)ansible-playbook $(ANSIBLE_VERBOSE) \
+ $(Q)ansible-playbook \
--limit 'baseline' \
playbooks/selftests.yml \
--extra-vars '{ $(SELFTESTS_DYNAMIC_RUNTIME_VARS) }' \
--tags vars,run_tests,copy_results,check_results $(LIMIT_HOSTS)
selftests-results:
- $(Q)ansible-playbook $(ANSIBLE_VERBOSE) \
+ $(Q)ansible-playbook \
--limit 'baseline' \
playbooks/selftests.yml \
--tags vars,copy_results,check_results $(LIMIT_HOSTS)
selftests-check-results:
- $(Q)ansible-playbook $(ANSIBLE_VERBOSE) \
+ $(Q)ansible-playbook \
--limit 'baseline' \
playbooks/selftests.yml \
--tags vars,check_results $(LIMIT_HOSTS)
diff --git a/workflows/steady_state/Makefile b/workflows/steady_state/Makefile
index 66a48011..f6342088 100644
--- a/workflows/steady_state/Makefile
+++ b/workflows/steady_state/Makefile
@@ -7,22 +7,22 @@ PHONY += steady-state-help-menu
SSD_STEADY_STATE_DYNAMIC_RUNTIME_VARS := "kdevops_run_ssd_steady_state": True
steady-state-files:
- $(Q)ansible-playbook $(ANSIBLE_VERBOSE) \
+ $(Q)ansible-playbook \
playbooks/steady_state.yml \
--extra-vars=@./extra_vars.yaml --tags vars,setup $(LIMIT_HOSTS)
steady-state-prefill:
- $(Q)ansible-playbook $(ANSIBLE_VERBOSE) \
+ $(Q)ansible-playbook \
playbooks/steady_state.yml \
--extra-vars=@./extra_vars.yaml --tags vars,prefill $(LIMIT_HOSTS)
steady-state-run:
- $(Q)ansible-playbook $(ANSIBLE_VERBOSE) \
+ $(Q)ansible-playbook \
playbooks/steady_state.yml \
--extra-vars=@./extra_vars.yaml --tags vars,steady_state $(LIMIT_HOSTS)
steady-state:
- $(Q)ansible-playbook $(ANSIBLE_VERBOSE) \
+ $(Q)ansible-playbook \
playbooks/steady_state.yml \
--extra-vars '{ $(SSD_STEADY_STATE_DYNAMIC_RUNTIME_VARS) }' $(LIMIT_HOSTS)
diff --git a/workflows/sysbench/Makefile b/workflows/sysbench/Makefile
index eb4ffc4a..442bd0d5 100644
--- a/workflows/sysbench/Makefile
+++ b/workflows/sysbench/Makefile
@@ -25,46 +25,46 @@ TAGS_SYSBENCH_RESULTS += results
# Target to set up sysbench (MySQL or PostgreSQL)
sysbench:
- $(Q)ansible-playbook $(ANSIBLE_VERBOSE) \
+ $(Q)ansible-playbook \
playbooks/sysbench.yml \
--skip-tags $(subst $(space),$(comma),$(TAGS_SYSBENCH_RUN))
# Target to run sysbench tests (including telemetry)
sysbench-test:
- $(Q)ansible-playbook $(ANSIBLE_VERBOSE) \
+ $(Q)ansible-playbook \
playbooks/sysbench.yml \
--tags $(subst $(space),$(comma),$(TAGS_SYSBENCH_TEST))
# Optional target to collect telemetry
sysbench-telemetry:
- $(Q)ansible-playbook $(ANSIBLE_VERBOSE) \
+ $(Q)ansible-playbook \
playbooks/sysbench.yml \
--tags $(subst $(space),$(comma),$(TAGS_SYSBENCH_TELEMETRY))
# Optional target to collect all results
sysbench-results:
- $(Q)ansible-playbook $(ANSIBLE_VERBOSE) \
+ $(Q)ansible-playbook \
playbooks/sysbench.yml \
--tags $(subst $(space),$(comma),$(TAGS_SYSBENCH_RESULTS))
monitor-results: $(KDEVOPS_EXTRA_VARS)
- $(Q)ansible-playbook $(ANSIBLE_VERBOSE) \
+ $(Q)ansible-playbook \
playbooks/monitor-results.yml \
--extra-vars=@./extra_vars.yaml
sysbench-clean:
- $(Q)ansible-playbook $(ANSIBLE_VERBOSE) \
+ $(Q)ansible-playbook \
playbooks/sysbench.yml \
--tags vars,clean
# Optional in case you want to improve graphing
sysbench-plot:
- $(Q)ansible-playbook $(ANSIBLE_VERBOSE) \
+ $(Q)ansible-playbook \
playbooks/sysbench.yml \
--tags vars,plot
monitor-results: $(KDEVOPS_EXTRA_VARS)
- $(Q)ansible-playbook $(ANSIBLE_VERBOSE) \
+ $(Q)ansible-playbook \
playbooks/monitor-results.yml \
--extra-vars=@./extra_vars.yaml \
$(LIMIT_HOSTS)
diff --git a/workflows/vllm/Makefile b/workflows/vllm/Makefile
index caed2e8a..2bbe8e55 100644
--- a/workflows/vllm/Makefile
+++ b/workflows/vllm/Makefile
@@ -3,49 +3,49 @@
HELP_TARGETS += vllm-help-menu
vllm:
- $(Q)ansible-playbook $(ANSIBLE_VERBOSE) \
+ $(Q)ansible-playbook \
--limit 'baseline:dev' \
playbooks/vllm.yml \
--tags data_partition,vars,deps,docker-config,vllm-deploy \
--extra-vars=@./extra_vars.yaml
vllm-deploy:
- $(Q)ansible-playbook $(ANSIBLE_VERBOSE) \
+ $(Q)ansible-playbook \
--limit 'baseline:dev' \
playbooks/vllm.yml \
--tags data_partition,vars,deps,docker-config,vllm-deploy \
--extra-vars=@./extra_vars.yaml
vllm-benchmark:
- $(Q)ansible-playbook $(ANSIBLE_VERBOSE) \
+ $(Q)ansible-playbook \
--limit 'baseline:dev' \
playbooks/vllm.yml \
--tags vars,vllm-benchmark \
--extra-vars=@./extra_vars.yaml
vllm-monitor:
- $(Q)ansible-playbook $(ANSIBLE_VERBOSE) \
+ $(Q)ansible-playbook \
--limit 'baseline:dev' \
playbooks/vllm.yml \
--tags vars,vllm-monitor \
--extra-vars=@./extra_vars.yaml
vllm-teardown:
- $(Q)ansible-playbook $(ANSIBLE_VERBOSE) \
+ $(Q)ansible-playbook \
--limit 'baseline:dev' \
playbooks/vllm.yml \
--tags vars,vllm-teardown \
--extra-vars=@./extra_vars.yaml
vllm-cleanup:
- $(Q)ansible-playbook $(ANSIBLE_VERBOSE) \
+ $(Q)ansible-playbook \
--limit 'baseline:dev' \
playbooks/vllm.yml \
--tags vars,vllm-cleanup \
--extra-vars=@./extra_vars.yaml
vllm-cleanup-full:
- $(Q)ansible-playbook $(ANSIBLE_VERBOSE) \
+ $(Q)ansible-playbook \
--limit 'baseline:dev' \
playbooks/vllm.yml \
--tags vars,vllm-cleanup \
@@ -53,7 +53,7 @@ vllm-cleanup-full:
--extra-vars='{"vllm_cleanup_remove_binaries": true}'
vllm-cleanup-purge:
- $(Q)ansible-playbook $(ANSIBLE_VERBOSE) \
+ $(Q)ansible-playbook \
--limit 'baseline:dev' \
playbooks/vllm.yml \
--tags vars,vllm-cleanup \
@@ -61,14 +61,14 @@ vllm-cleanup-purge:
--extra-vars='{"vllm_cleanup_remove_binaries": true, "vllm_cleanup_remove_data": true}'
vllm-results:
- $(Q)ansible-playbook $(ANSIBLE_VERBOSE) \
+ $(Q)ansible-playbook \
--limit 'baseline:dev' \
playbooks/vllm.yml \
--tags vars,vllm-results,vllm-visualize \
--extra-vars=@./extra_vars.yaml
vllm-visualize-results:
- $(Q)ansible-playbook $(ANSIBLE_VERBOSE) \
+ $(Q)ansible-playbook \
--limit 'baseline:dev' \
playbooks/vllm.yml \
--tags vars,vllm-visualize \
--
2.52.0
^ permalink raw reply related [flat|nested] 6+ messages in thread* [PATCH v4 2/2] ansible: add lucid callback plugin for clean output
2025-12-01 23:11 [PATCH v4 0/2] Lucid: A custom Ansible stdout callback for kdevops Daniel Gomez
2025-12-01 23:11 ` [PATCH v4 1/2] ansible: use native verbosity config instead of custom AV variable Daniel Gomez
@ 2025-12-01 23:11 ` Daniel Gomez
2025-12-03 21:11 ` Chuck Lever
2025-12-01 23:14 ` [PATCH v4 0/2] Lucid: A custom Ansible stdout callback for kdevops Daniel Gomez
2 siblings, 1 reply; 6+ messages in thread
From: Daniel Gomez @ 2025-12-01 23:11 UTC (permalink / raw)
To: Luis Chamberlain, Chuck Lever; +Cc: kdevops, Daniel Gomez
From: Daniel Gomez <da.gomez@samsung.com>
Add the lucid callback plugin to provide clean, minimal Ansible output
for kdevops workflows. Current Ansible output is verbose by default
making it difficult to see what matters during long-running test
operations. Lucid solves this by showing only changes and errors at
default verbosity while providing progressive detail at higher levels.
The plugin includes dynamic mode with live updates for interactive
terminals showing running tasks with spinners and elapsed time similar
to BitBake/Yocto build output. For CI/CD and piped contexts it
automatically falls back to static output. All runs generate
comprehensive logs in .ansible/logs/ with playbook names and timestamps
allowing multiple executions to coexist without conflicts.
Task-level output control is available via the output_verbosity variable
allowing playbooks to specify per-task visibility. Execution time is
shown for all tasks providing consistent performance visibility. Logs
always capture full verbosity independent of display settings ensuring
complete audit trails.
Verbosity levels control output progressively: no flags show only
changed/failed tasks with stdout/stderr, -v adds ok/skipped tasks plus
executed commands, -vv and -vvv enable tasks marked with higher
output_verbosity values.
Integrate lucid with kdevops Kconfig system providing output mode
selection (auto/static/dynamic). Add defconfig fragments for standard
use (lucid.config) and CI environments (lucid-ci.config). The CI
fragment enables static mode with verbosity level 1 for comprehensive
output suitable for build logs.
Add documentation covering requirements, parameters, verbosity levels,
status symbols, command display behavior, and CI/CD configuration.
Generated-by: Claude AI
Signed-off-by: Daniel Gomez <da.gomez@samsung.com>
---
.gitignore | 4 +
CLAUDE.md | 10 +
callback_plugins/__init__.py | 0
callback_plugins/lucid.py | 879 +++++++++++++++++++++
defconfigs/configs/lucid-ci.config | 3 +
defconfigs/configs/lucid.config | 2 +
docs/ansible-callbacks.md | 294 +++++++
kconfigs/Kconfig.ansible_cfg | 74 ++
.../roles/ansible_cfg/templates/ansible.cfg.j2 | 12 +-
9 files changed, 1277 insertions(+), 1 deletion(-)
diff --git a/.gitignore b/.gitignore
index 7472860e..ddc19b17 100644
--- a/.gitignore
+++ b/.gitignore
@@ -26,6 +26,7 @@ extra_vars.json
.config.old
ansible.cfg
+callback_plugins/__pycache__/
scripts/kconfig/.mconf-cfg
scripts/workflows/fstests/lib/__pycache__/
@@ -131,3 +132,6 @@ terraform/oci/scripts/__pycache__/
scripts/__pycache__/
docs/contrib/kdevops_contributions*
+__pycache__/
+
+.ansible
diff --git a/CLAUDE.md b/CLAUDE.md
index 5c9091d9..83376619 100644
--- a/CLAUDE.md
+++ b/CLAUDE.md
@@ -128,6 +128,16 @@ make fix-whitespace-last-commit # Fixes commit white space damage
make mrproper # Clean everything and restart from scratch
```
+### Ansible Callbacks
+
+kdevops supports multiple Ansible stdout callback plugins (dense, debug,
+diy, lucid, or custom). The default is dense.
+
+See [docs/ansible-callbacks.md](docs/ansible-callbacks.md) for:
+- Supported plugins and configuration
+- Command line override via `ANSIBLE_CFG_CALLBACK_PLUGIN`
+- Lucid plugin features and parameters
+
## Key Workflows
### fstests (Filesystem Testing)
diff --git a/callback_plugins/__init__.py b/callback_plugins/__init__.py
new file mode 100644
index 00000000..e69de29b
diff --git a/callback_plugins/lucid.py b/callback_plugins/lucid.py
new file mode 100644
index 00000000..e45f46b1
--- /dev/null
+++ b/callback_plugins/lucid.py
@@ -0,0 +1,879 @@
+#!/usr/bin/env python3
+"""
+Lucid Ansible Callback Plugin
+
+A modern stdout callback plugin providing:
+- Clean, minimal output with progressive verbosity levels
+- Task-level output control via output_verbosity variable
+- Comprehensive logging (always max verbosity)
+- Dynamic terminal display (Yocto/BitBake style) for interactive use
+- Static output for CI/CD and non-interactive terminals
+"""
+
+from __future__ import annotations
+
+import json
+import os
+import shutil
+import sys
+import time
+import threading
+from datetime import datetime
+from typing import Dict, Tuple, Optional, Any
+from collections import deque
+
+from ansible.plugins.callback import CallbackBase
+from ansible import constants as C
+
+DOCUMENTATION = """
+ name: lucid
+ type: stdout
+ short_description: Clean, minimal Ansible output with dynamic display
+ version_added: "2.10"
+ description:
+ - Provides clean, minimal output by default
+ - Progressive verbosity levels (-v, -vv, -vvv)
+ - Task-level output control via output_verbosity variable
+ - Comprehensive logging independent of display verbosity
+ - Dynamic live display for interactive terminals
+ - Static output for CI/CD environments
+ requirements:
+ - Ansible 2.10+
+ - Python 3.8+
+ options:
+ output_mode:
+ description: Output display mode (auto, static, dynamic)
+ default: auto
+ type: str
+ ini:
+ - section: callback_lucid
+ key: output_mode
+ env:
+ - name: ANSIBLE_LUCID_OUTPUT_MODE
+ choices: ['auto', 'static', 'dynamic']
+"""
+
+
+class CallbackModule(CallbackBase):
+ """
+ Lucid callback plugin for clean, minimal Ansible output
+ with dynamic terminal display and comprehensive logging.
+ """
+
+ CALLBACK_VERSION = 2.0
+ CALLBACK_TYPE = "stdout"
+ CALLBACK_NAME = "lucid"
+
+ # Spinner animation frames
+ SPINNER_FRAMES = ["⠋", "⠙", "⠹", "⠸", "⠼", "⠴", "⠦", "⠧", "⠇", "⠏"]
+
+ # Status symbols and colors (used consistently across static, dynamic, and logging)
+ STATUS_SYMBOLS = {
+ "ok": "✓",
+ "changed": "*",
+ "failed": "✗",
+ "skipped": "⊘",
+ "unreachable": "!",
+ }
+
+ STATUS_COLORS = {
+ "ok": C.COLOR_OK,
+ "changed": C.COLOR_CHANGED,
+ "failed": C.COLOR_ERROR,
+ "skipped": C.COLOR_SKIP,
+ "unreachable": C.COLOR_UNREACHABLE,
+ }
+
+ # Default terminal width when detection fails
+ DEFAULT_TERMINAL_WIDTH = 80
+
+ def __init__(self):
+ super(CallbackModule, self).__init__()
+
+ # State tracking
+ self.running_tasks: Dict[Tuple[str, str], Dict[str, Any]] = (
+ {}
+ ) # (host, task_uuid) -> task_info
+ self.completed_tasks = deque(maxlen=3) # Keep last 3 completed
+ self.current_task_name: str = ""
+ self.current_task_hosts: list[str] = []
+ self.play_hosts: list[str] = [] # All hosts in current play
+
+ # Dynamic display state
+ self.display_lines = 0
+ self.last_update = 0.0
+ self.spinner_index = 0
+ self.dynamic_mode = False
+ self.update_thread: Optional[threading.Thread] = None
+ self.update_thread_stop: Optional[threading.Event] = None
+ self.task_lock = threading.Lock()
+
+ # Will be set in set_options()
+ self.output_mode = "auto"
+ self.log_file_path: Optional[str] = None
+ self.log_timestamp = datetime.now().strftime("%Y-%m-%d_%H-%M-%S")
+ self.log_write_failed = False
+
+ def set_options(self, task_keys=None, var_options=None, direct=None):
+ """Set plugin options from ansible.cfg"""
+ super(CallbackModule, self).set_options(
+ task_keys=task_keys, var_options=var_options, direct=direct
+ )
+
+ # Load configuration
+ self.output_mode = self.get_option("output_mode")
+
+ # Determine display mode based on configuration
+ is_interactive = self._detect_interactive()
+ if self.output_mode == "static":
+ self.dynamic_mode = False
+ elif self.output_mode == "dynamic":
+ self.dynamic_mode = True
+ else: # 'auto' or any other value
+ self.dynamic_mode = is_interactive
+
+ # Initialize logging
+ self._init_log_file()
+
+ # Start update thread for dynamic mode
+ if self.dynamic_mode:
+ self._start_update_thread()
+
+ def _detect_interactive(self) -> bool:
+ """Detect if running in interactive terminal"""
+ return (
+ sys.stdout.isatty()
+ and sys.stderr.isatty()
+ and os.getenv("TERM") != "dumb"
+ and os.getenv("CI") is None
+ and os.getenv("JENKINS_HOME") is None
+ and os.getenv("GITHUB_ACTIONS") is None
+ and os.getenv("GITLAB_CI") is None
+ )
+
+ def _init_log_file(self):
+ """Defer log file creation until playbook name is known"""
+ # Log file path will be set in _create_log_file when playbook starts
+ pass
+
+ def _create_log_file(self, playbook_name: str):
+ """Create log file with playbook name and timestamp using auto-detection"""
+ if self.log_file_path:
+ # Already initialized
+ return
+
+ # Remove extension from playbook name
+ playbook_base = os.path.splitext(playbook_name)[0]
+
+ # Try default locations in order (project dir first, then user home, then system)
+ attempts = [
+ f".ansible/logs/{playbook_base}-{self.log_timestamp}.log",
+ os.path.expanduser(
+ f"~/.ansible/logs/{playbook_base}-{self.log_timestamp}.log"
+ ),
+ f"/var/log/ansible/{playbook_base}-{self.log_timestamp}.log",
+ ]
+
+ for path in attempts:
+ try:
+ os.makedirs(os.path.dirname(path), exist_ok=True)
+ # Test write access
+ with open(path, "a"):
+ pass
+ self.log_file_path = path
+ break
+ except (PermissionError, OSError):
+ continue
+
+ if self.log_file_path:
+ try:
+ with open(self.log_file_path, "w") as f:
+ f.write(
+ f"=== Ansible Playbook Log Started: {datetime.now().isoformat()} ===\n"
+ )
+ f.write(f"=== Playbook: {playbook_name} ===\n\n")
+ except (PermissionError, OSError) as e:
+ self._display.warning(
+ f"Could not initialize log file {self.log_file_path}: {e}"
+ )
+ self.log_file_path = None
+
+ def _write_to_log(self, message: str):
+ """Write to log file with timestamp (always max verbosity)"""
+ if self.log_file_path:
+ timestamp = datetime.now().isoformat()
+ try:
+ with open(self.log_file_path, "a") as f:
+ f.write(f"[{timestamp}] {message}\n")
+ except (PermissionError, OSError) as e:
+ # Warn once on first failure, then disable logging
+ if not self.log_write_failed:
+ self._display.warning(f"Log write failed, disabling logging: {e}")
+ self.log_write_failed = True
+ self.log_file_path = None
+
+ def _start_update_thread(self):
+ """Start background thread for live display updates"""
+ self.update_thread_stop = threading.Event()
+ self.update_thread = threading.Thread(target=self._update_loop, daemon=True)
+ self.update_thread.start()
+
+ def _update_loop(self):
+ """Update display every 0.5 seconds in dynamic mode"""
+ while not self.update_thread_stop.is_set():
+ if self.running_tasks:
+ self._redraw_display()
+ time.sleep(0.5)
+
+ def _should_display_output(self, result, status: str) -> bool:
+ """
+ Determine if task output should be shown based on verbosity.
+
+ Rules:
+ - Changed tasks: ALWAYS show
+ - Failed tasks: ALWAYS show
+ - OK tasks: Show if current_verbosity >= task's output_verbosity
+ - Skipped tasks: Only at -v or higher
+ """
+ # Changed and failed always show
+ if status == "changed" or status == "failed" or status == "unreachable":
+ return True
+
+ # Skipped only at -v
+ if status == "skipped":
+ return self._display.verbosity >= 1
+
+ # Get task verbosity setting (default is 1)
+ task_verbosity = self._get_task_verbosity(result)
+
+ # Compare with current verbosity
+ current_verbosity = self._display.verbosity
+
+ return current_verbosity >= task_verbosity
+
+ def _get_task_verbosity(self, result) -> int:
+ """Get the output_verbosity setting for a task (default is 1)"""
+ task_verbosity = 1
+ if hasattr(result, "_task_fields"):
+ task_vars = result._task_fields.get("vars", {})
+ task_verbosity = task_vars.get("output_verbosity", 1)
+ elif hasattr(result, "_task"):
+ task_vars = getattr(result._task, "vars", {})
+ task_verbosity = task_vars.get("output_verbosity", 1)
+ return task_verbosity
+
+ def _get_task_command(self, result) -> Optional[str]:
+ """
+ Extract the command from modules that execute shell commands.
+ Returns None for modules that don't expose their commands.
+
+ Supported modules:
+ - ansible.builtin.shell/command: returns cmd (string or list)
+ - ansible.builtin.pip: returns cmd (string)
+ - community.general.make: returns command (string)
+ - community.general.flatpak: returns command (string)
+ - community.general.flatpak_remote: returns command (string)
+ - community.general.terraform: returns command (string)
+ """
+ task = result._task
+ action = task.action
+ res = result._result
+
+ # Modules that return 'cmd' key
+ if action in (
+ "ansible.builtin.shell",
+ "ansible.builtin.command",
+ "ansible.builtin.pip",
+ "shell",
+ "command",
+ "pip",
+ ):
+ if "cmd" in res:
+ cmd = res["cmd"]
+ if isinstance(cmd, list):
+ return " ".join(cmd)
+ return cmd
+
+ # Fall back to task args for shell/command
+ if action in (
+ "ansible.builtin.shell",
+ "ansible.builtin.command",
+ "shell",
+ "command",
+ ):
+ args = task.args
+ if "_raw_params" in args:
+ return args["_raw_params"]
+ if "cmd" in args:
+ return args["cmd"]
+
+ return None
+
+ # Modules that return 'command' key
+ if action in (
+ "community.general.make",
+ "community.general.flatpak",
+ "community.general.flatpak_remote",
+ "community.general.terraform",
+ "make",
+ "flatpak",
+ "flatpak_remote",
+ "terraform",
+ ):
+ if "command" in res:
+ return res["command"]
+ return None
+
+ return None
+
+ def _has_significant_output(self, result) -> bool:
+ """Check if result has stdout, stderr, or msg content worth showing"""
+ res = result._result
+ return bool(
+ (res.get("stdout") and res["stdout"].strip())
+ or (res.get("stderr") and res["stderr"].strip())
+ or (res.get("msg") and not res.get("stdout"))
+ )
+
+ def _get_terminal_width(self) -> int:
+ """Get current terminal width, with fallback to default"""
+ try:
+ size = shutil.get_terminal_size(fallback=(self.DEFAULT_TERMINAL_WIDTH, 24))
+ return size.columns
+ except Exception:
+ return self.DEFAULT_TERMINAL_WIDTH
+
+ def _truncate_line(self, line: str, max_width: Optional[int] = None) -> str:
+ """Truncate line to fit terminal width, adding ellipsis if needed"""
+ if max_width is None:
+ max_width = self._get_terminal_width()
+
+ if len(line) <= max_width:
+ return line
+
+ # Reserve 3 characters for ellipsis
+ if max_width <= 3:
+ return "..." if max_width >= 3 else line[:max_width]
+
+ return line[: max_width - 3] + "..."
+
+ def _format_duration(self, seconds: float, width: int = 0) -> str:
+ """Format duration as human readable, optionally right-aligned to width"""
+ if seconds < 60:
+ duration = f"{seconds:.1f}s"
+ elif seconds < 3600:
+ mins = int(seconds // 60)
+ secs = int(seconds % 60)
+ duration = f"{mins}m {secs}s"
+ elif seconds < 86400:
+ hours = int(seconds // 3600)
+ mins = int((seconds % 3600) // 60)
+ duration = f"{hours}h {mins}m"
+ else:
+ days = int(seconds // 86400)
+ hours = int((seconds % 86400) // 3600)
+ duration = f"{days}d {hours}h"
+
+ if width > 0:
+ return duration.rjust(width)
+ return duration
+
+ def _display_message(self, message: str, color=None):
+ """Display message with optional color"""
+ if color:
+ self._display.display(message, color=color)
+ else:
+ self._display.display(message)
+
+ # ========================================================================
+ # Ansible v2 Callback Methods
+ # ========================================================================
+
+ def v2_playbook_on_start(self, playbook):
+ """Playbook started"""
+ playbook_name = os.path.basename(playbook._file_name)
+
+ # Create log file now that we have playbook name
+ self._create_log_file(playbook_name)
+
+ msg = f"PLAYBOOK: {playbook_name}"
+ self._display_message(msg, C.COLOR_HIGHLIGHT)
+ self._write_to_log(msg)
+
+ # Show log file path early so user can tail -f
+ if self.log_file_path:
+ self._display.display(f"Log: {self.log_file_path}")
+
+ def v2_playbook_on_play_start(self, play):
+ """Play started"""
+ name = play.get_name().strip()
+
+ # Get actual host list from play (resolved from inventory)
+ # play.hosts is just the pattern, we need to get actual hosts
+ self.play_hosts = []
+ try:
+ # Get hosts from the play's host list (resolved by PlayIterator)
+ host_list = (
+ play.get_variable_manager()
+ .get_vars(play=play)
+ .get("ansible_play_hosts_all", [])
+ )
+ if host_list:
+ self.play_hosts = list(host_list)
+ except (AttributeError, TypeError):
+ # Fallback: hosts will be populated as tasks start
+ pass
+
+ hosts = play.hosts
+ if isinstance(hosts, list):
+ hosts_str = ", ".join(hosts[:3])
+ if len(hosts) > 3:
+ hosts_str += f" (+{len(hosts) - 3} more)"
+ else:
+ hosts_str = str(hosts)
+
+ msg = f"\nPLAY: {name} [{hosts_str}]"
+ self._display_message(msg, C.COLOR_HIGHLIGHT)
+ self._write_to_log(msg)
+
+ def v2_playbook_on_task_start(self, task, is_conditional):
+ """Task started"""
+ self.current_task_name = task.get_name().strip()
+ # Initialize with play hosts so display is stable from the start
+ self.current_task_hosts = list(self.play_hosts) if self.play_hosts else []
+
+ # In static mode, print immediately (compact - no leading newline)
+ if not self.dynamic_mode:
+ msg = f"TASK: {self.current_task_name}"
+ self._display_message(msg, C.COLOR_HIGHLIGHT)
+
+ self._write_to_log(f"TASK: {self.current_task_name}")
+
+ def v2_runner_on_start(self, host, task):
+ """Task started on a host (for dynamic tracking)"""
+ key = (host.name, task._uuid)
+
+ # Check for task delegation
+ delegate_to = getattr(task, "delegate_to", None)
+
+ with self.task_lock:
+ self.running_tasks[key] = {
+ "start_time": time.time(),
+ "host": host.name,
+ "delegate_to": delegate_to,
+ "task_name": task.get_name().strip(),
+ }
+
+ if host.name not in self.current_task_hosts:
+ self.current_task_hosts.append(host.name)
+
+ if self.dynamic_mode:
+ self._redraw_display()
+
+ def v2_runner_on_ok(self, result):
+ """Task succeeded"""
+ changed = result._result.get("changed", False)
+ status = "changed" if changed else "ok"
+ self._handle_result(result, status)
+
+ def v2_runner_on_failed(self, result, ignore_errors=False):
+ """Task failed"""
+ self._handle_result(result, "failed", ignore_errors=ignore_errors)
+
+ def v2_runner_on_skipped(self, result):
+ """Task skipped"""
+ self._handle_result(result, "skipped")
+
+ def v2_runner_on_unreachable(self, result):
+ """Host unreachable"""
+ self._handle_result(result, "unreachable")
+
+ def v2_runner_retry(self, result):
+ """Task is being retried after failure"""
+ host = result._host.name
+ task_uuid = result._task._uuid
+ key = (host, task_uuid)
+
+ retries = result._result.get("retries", 0)
+ attempts = result._result.get("attempts", 0)
+
+ # Update retry info in running_tasks
+ with self.task_lock:
+ if key in self.running_tasks:
+ self.running_tasks[key]["retry_attempt"] = attempts
+ self.running_tasks[key]["retry_total"] = retries
+
+ # Log the retry attempt
+ self._write_to_log(f" ✗ [{host}] retry {attempts}/{retries} - retrying...")
+
+ # In static mode, show retry immediately
+ if not self.dynamic_mode:
+ msg = f" ✗ [{host}] retry {attempts}/{retries}"
+ self._display_message(msg, C.COLOR_WARN)
+
+ def v2_playbook_on_stats(self, stats):
+ """Final summary"""
+ # Stop update thread
+ if self.update_thread_stop:
+ self.update_thread_stop.set()
+ if self.update_thread:
+ self.update_thread.join(timeout=1.0)
+
+ # Clear dynamic display if active
+ if self.dynamic_mode and self.display_lines > 0:
+ self._clear_display()
+
+ # Print recap
+ self._display_recap(stats)
+
+ # Log file footer
+ self._write_to_log(
+ f"\n=== Playbook Completed: {datetime.now().isoformat()} ==="
+ )
+
+ # ========================================================================
+ # Result Handling
+ # ========================================================================
+
+ def _handle_result(self, result, status: str, ignore_errors: bool = False):
+ """Unified result handler for all task outcomes"""
+ host = result._host.name
+ task_uuid = result._task._uuid
+ key = (host, task_uuid)
+
+ # Calculate duration with defensive access
+ with self.task_lock:
+ task_info = self.running_tasks.pop(key, None)
+ start_time = (
+ task_info.get("start_time", time.time()) if task_info else time.time()
+ )
+ duration = time.time() - start_time
+
+ # Get delegation info from result (more reliable than task attribute)
+ delegated_vars = result._result.get("_ansible_delegated_vars", {})
+ delegate_to = delegated_vars.get("ansible_delegated_host")
+
+ # Store result data for dynamic mode display
+ result_data = {
+ "result": result,
+ "status": status,
+ "duration": duration,
+ "host": host,
+ "delegate_to": delegate_to,
+ "task_name": result._task.get_name().strip(),
+ }
+
+ # Add to completed tasks (last 3 for dynamic mode)
+ self.completed_tasks.append(result_data)
+
+ # Log everything (max verbosity)
+ self._log_result(result, status, duration)
+
+ # Display based on mode
+ if self.dynamic_mode:
+ # Dynamic mode will update on next refresh
+ # Freeze display and show output for failed tasks (not ignored)
+ if status == "failed" and not ignore_errors:
+ self._freeze_and_show_output(result_data)
+ else:
+ # Static mode - display immediately
+ self._display_result_static(result, status, duration)
+
+ def _display_result_static(self, result, status: str, duration: float):
+ """Display result in static mode"""
+ host = result._host.name
+
+ # Early exit for tasks that shouldn't be shown at current verbosity
+ # At verbosity 0: only show changed, failed, unreachable
+ if self._display.verbosity < 1 and status in ("ok", "skipped"):
+ return
+
+ # Determine if we should show output (for tasks that pass visibility check)
+ show_output = self._should_display_output(result, status)
+
+ # Format status line using class constants
+ symbol = self.STATUS_SYMBOLS.get(status, "?")
+ color = self.STATUS_COLORS.get(status, C.COLOR_OK)
+
+ # Get delegation info for display (like Ansible default: [host -> delegate])
+ delegated_vars = result._result.get("_ansible_delegated_vars", {})
+ delegate_to = delegated_vars.get("ansible_delegated_host")
+ if delegate_to:
+ host_display = f"{host} -> {delegate_to}"
+ else:
+ host_display = host
+
+ # Format time (always shown for all statuses)
+ time_str = f" ({self._format_duration(duration)})"
+
+ # Status line with unicode spacing (using regular spaces, not braille)
+ status_line = f" {symbol} [{host_display}]{time_str}"
+ self._display_message(status_line, color)
+
+ # Show command for supported modules when running with -v or higher
+ if self._display.verbosity >= 1:
+ command = self._get_task_command(result)
+ if command:
+ # Truncate very long commands
+ if len(command) > 200:
+ command = command[:197] + "..."
+ self._display.display(f" $ {command}", color=C.COLOR_VERBOSE)
+
+ # Show output if conditions met
+ if show_output:
+ self._display_output(result)
+
+ def _display_output(self, result):
+ """Display stdout/stderr/msg from task result"""
+ output = []
+ res = result._result
+
+ # stdout
+ if "stdout" in res and res["stdout"]:
+ output.append(f"\nSTDOUT:\n{res['stdout']}")
+
+ # stderr
+ if "stderr" in res and res["stderr"]:
+ output.append(f"\nSTDERR:\n{res['stderr']}")
+
+ # msg (only if no stdout content)
+ if "msg" in res and res["msg"] and not res.get("stdout"):
+ msg_text = res["msg"]
+ # Handle lists/dicts in msg
+ if isinstance(msg_text, (list, dict)):
+ msg_text = json.dumps(msg_text, indent=2)
+ output.append(f"\nMSG:\n{msg_text}")
+
+ if output:
+ self._display.display("".join(output))
+
+ def _log_result(self, result, status: str, duration: float):
+ """Write result to log file (always max verbosity)"""
+ host = result._host.name
+ res = result._result
+
+ # Get delegation info for logging
+ delegated_vars = res.get("_ansible_delegated_vars", {})
+ delegate_to = delegated_vars.get("ansible_delegated_host")
+ if delegate_to:
+ host_display = f"{host} -> {delegate_to}"
+ else:
+ host_display = host
+
+ # Status line using class constants
+ symbol = self.STATUS_SYMBOLS.get(status, "?")
+ time_str = self._format_duration(duration)
+ log_line = f" {symbol} [{host_display}] ({time_str})"
+ self._write_to_log(log_line)
+
+ # Log command for supported modules
+ command = self._get_task_command(result)
+ if command:
+ self._write_to_log(f"\n$ {command}")
+
+ # Always log full output
+ if "stdout" in res and res["stdout"]:
+ self._write_to_log(f"\nSTDOUT:\n{res['stdout']}\n")
+
+ if "stderr" in res and res["stderr"]:
+ self._write_to_log(f"\nSTDERR:\n{res['stderr']}\n")
+
+ if "msg" in res and res["msg"]:
+ msg_text = res["msg"]
+ if isinstance(msg_text, (list, dict)):
+ msg_text = json.dumps(msg_text, indent=2)
+ self._write_to_log(f"\nMSG:\n{msg_text}\n")
+
+ if status == "failed" and "exception" in res:
+ self._write_to_log(f"\nEXCEPTION:\n{res['exception']}\n")
+
+ def _display_recap(self, stats):
+ """Display final statistics"""
+ self._display_message("\nPLAY RECAP", C.COLOR_HIGHLIGHT)
+
+ hosts = sorted(stats.processed.keys())
+ for host in hosts:
+ summary = stats.summarize(host)
+
+ # More compact format
+ msg = (
+ f"{host:25s} : "
+ f"ok={summary['ok']:<3d} "
+ f"changed={summary['changed']:<3d} "
+ f"unreachable={summary['unreachable']:<3d} "
+ f"failed={summary['failures']:<3d} "
+ f"skipped={summary['skipped']:<3d}"
+ )
+
+ # Color based on status
+ if summary["failures"] > 0 or summary["unreachable"] > 0:
+ color = C.COLOR_ERROR
+ elif summary["changed"] > 0:
+ color = C.COLOR_CHANGED
+ else:
+ color = C.COLOR_OK
+
+ self._display_message(msg, color)
+
+ # ========================================================================
+ # Dynamic Mode Display
+ # ========================================================================
+
+ def _redraw_display(self):
+ """Redraw entire display in dynamic mode"""
+ # Throttle updates (max once per 0.1s)
+ now = time.time()
+ if now - self.last_update < 0.1:
+ return
+ self.last_update = now
+
+ # Increment spinner
+ self.spinner_index = (self.spinner_index + 1) % len(self.SPINNER_FRAMES)
+
+ # Clear previous display
+ self._clear_display()
+
+ # Get terminal width once for all lines
+ term_width = self._get_terminal_width()
+
+ # Build new display
+ lines = []
+
+ # Task header - truncate to terminal width
+ if self.current_task_name:
+ task_line = f"TASK: {self.current_task_name}"
+ lines.append(self._truncate_line(task_line, term_width))
+ lines.append("")
+
+ # Host status - show ALL hosts in task, running ones get spinner
+ # Create snapshot of running tasks under lock
+ with self.task_lock:
+ running_hosts = {
+ host: info for (host, _), info in self.running_tasks.items()
+ }
+
+ if self.current_task_hosts:
+ running_count = len(running_hosts)
+ total_hosts = len(self.current_task_hosts)
+ lines.append(f"Hosts: {running_count}/{total_hosts} running")
+
+ spinner = self.SPINNER_FRAMES[self.spinner_index]
+
+ # Show all hosts in stable order, running ones with spinner
+ # Format: [spinner] <time> <hostname> - time is fixed width (8 chars)
+ # This keeps spinner and time columns stable, hostname varies at end
+ time_width = 8 # Enough for "1m 30s", "10h 5m", or "99d 23h"
+
+ for host in self.current_task_hosts:
+ if host in running_hosts:
+ # Running - show spinner, time, then hostname
+ task_info = running_hosts[host]
+ elapsed = time.time() - task_info["start_time"]
+ duration_str = self._format_duration(elapsed, width=time_width)
+
+ # Get delegation info
+ delegate_to = task_info.get("delegate_to")
+ if delegate_to:
+ host_display = f"{host} -> {delegate_to}"
+ else:
+ host_display = host
+
+ # Build retry suffix if applicable
+ retry_suffix = ""
+ if "retry_attempt" in task_info:
+ attempt = task_info["retry_attempt"]
+ total = task_info["retry_total"]
+ retry_suffix = f" (retry {attempt}/{total})"
+
+ # Format: spinner, fixed-width time, hostname at end
+ host_line = (
+ f" [{spinner}] {duration_str} {host_display}{retry_suffix}"
+ )
+ else:
+ # Not running - show empty brackets and blank time column
+ blank_time = " " * time_width
+ host_line = f" [ ] {blank_time} {host}"
+
+ lines.append(self._truncate_line(host_line, term_width))
+
+ lines.append("")
+
+ # Recently completed (after running tasks)
+ if self.completed_tasks:
+ lines.append("Recent:")
+ for task_data in self.completed_tasks:
+ status = task_data["status"]
+ host = task_data["host"]
+ duration = task_data["duration"]
+ task_name = task_data.get("task_name", "Unknown task")
+ delegate_to = task_data.get("delegate_to")
+
+ # Format host with delegation if present
+ if delegate_to:
+ host_display = f"{host} -> {delegate_to}"
+ else:
+ host_display = host
+
+ # Use class constants for consistent symbols
+ symbol = self.STATUS_SYMBOLS.get(status, "?")
+
+ time_str = self._format_duration(duration)
+ recent_line = f" {symbol} {task_name} [{host_display}] ({time_str})"
+ lines.append(self._truncate_line(recent_line, term_width))
+ lines.append("")
+
+ # Display all lines
+ if lines:
+ output = "\n".join(lines)
+ # Write directly to avoid extra newlines
+ sys.stdout.write(output)
+ sys.stdout.flush()
+ # Count actual lines printed (number of newlines + 1 for the last line)
+ self.display_lines = output.count("\n") + 1
+ else:
+ self.display_lines = 0
+
+ def _clear_display(self):
+ """Clear dynamic display using ANSI escape codes"""
+ if self.display_lines > 0:
+ # Clear current line first
+ sys.stdout.write("\r\033[2K")
+ # Move up and clear remaining lines
+ for _ in range(self.display_lines - 1):
+ sys.stdout.write("\033[1A") # Move cursor up one line
+ sys.stdout.write("\033[2K") # Clear entire line
+ sys.stdout.flush()
+ self.display_lines = 0
+
+ def _freeze_and_show_output(self, result_data):
+ """
+ Freeze display and show task output in dynamic mode for failures.
+ Disables dynamic mode for the rest of the playbook.
+ """
+ # Clear dynamic display
+ if self.display_lines > 0:
+ self._clear_display()
+
+ # Show result in static format
+ result = result_data["result"]
+ status = result_data["status"]
+ duration = result_data["duration"]
+
+ # Print task name
+ msg = f"TASK: {self.current_task_name}"
+ self._display_message(msg, C.COLOR_HIGHLIGHT)
+
+ # Show result with output
+ self._display_result_static(result, status, duration)
+
+ # Disable dynamic mode for rest of playbook after failure
+ self.dynamic_mode = False
+ if self.update_thread_stop:
+ self.update_thread_stop.set()
+
+ def __del__(self):
+ """Cleanup when plugin is destroyed"""
+ if self.update_thread_stop:
+ self.update_thread_stop.set()
+ if self.update_thread:
+ self.update_thread.join(timeout=1.0)
diff --git a/defconfigs/configs/lucid-ci.config b/defconfigs/configs/lucid-ci.config
new file mode 100644
index 00000000..03aee9fd
--- /dev/null
+++ b/defconfigs/configs/lucid-ci.config
@@ -0,0 +1,3 @@
+CONFIG_ANSIBLE_CFG_CALLBACK_PLUGIN_LUCID=y
+CONFIG_ANSIBLE_CFG_LUCID_OUTPUT_MODE_STATIC=y
+CONFIG_KDEVOPS_ANSIBLE_VERBOSE=1
diff --git a/defconfigs/configs/lucid.config b/defconfigs/configs/lucid.config
new file mode 100644
index 00000000..94e943f0
--- /dev/null
+++ b/defconfigs/configs/lucid.config
@@ -0,0 +1,2 @@
+CONFIG_ANSIBLE_CFG_CALLBACK_PLUGIN_LUCID=y
+CONFIG_ANSIBLE_CFG_LUCID_OUTPUT_MODE_AUTO=y
diff --git a/docs/ansible-callbacks.md b/docs/ansible-callbacks.md
new file mode 100644
index 00000000..2f99089f
--- /dev/null
+++ b/docs/ansible-callbacks.md
@@ -0,0 +1,294 @@
+# Ansible Callback Plugins
+
+kdevops supports multiple Ansible stdout callback plugins for controlling
+playbook output. The callback plugin can be configured via Kconfig or
+overridden from the command line.
+
+## Supported Plugins
+
+| Plugin | Description |
+|--------|-------------|
+| dense (default) | Compact output from community.general |
+| debug | Ansible builtin debug callback |
+| diy | Customizable output from community.general |
+| lucid | Clean, minimal output with dynamic display (kdevops custom) |
+| custom | Any Ansible callback plugin by name |
+
+## Configuration
+
+### Via Kconfig
+
+Select the callback plugin in menuconfig:
+
+```bash
+make menuconfig
+# Navigate to: Ansible Callback Plugin Configuration
+```
+
+### Via Command Line
+
+Override the default at build time:
+
+```bash
+make ANSIBLE_CFG_CALLBACK_PLUGIN=lucid menuconfig
+make
+```
+
+When `ANSIBLE_CFG_CALLBACK_PLUGIN` is set via environment, the custom plugin
+option is automatically selected and populated with the specified value.
+
+## Plugin Details
+
+### dense (default)
+
+The dense callback from community.general provides compact single-line output.
+
+- Documentation: https://docs.ansible.com/ansible/latest/collections/community/general/dense_callback.html
+
+### debug
+
+The Ansible builtin debug callback shows detailed task information.
+
+- Documentation: https://docs.ansible.com/ansible/latest/collections/ansible/builtin/debug_module.html
+
+### diy
+
+The DIY callback from community.general allows custom output formatting
+via ansible.cfg configuration.
+
+- Documentation: https://docs.ansible.com/ansible/latest/collections/community/general/diy_callback.html
+
+### lucid
+
+A custom callback plugin developed for kdevops providing clean, minimal
+output with progressive verbosity levels and optional dynamic terminal
+display.
+
+#### Features
+
+- Clean, minimal output by default (shows only changes and errors)
+- Progressive verbosity with `-v`, `-vv`, `-vvv` flags
+- Dynamic live display for interactive terminals (BitBake/Yocto style)
+- Automatic static fallback for CI/CD and piped output
+- Task-level output control via `output_verbosity` variable
+- Comprehensive logging (always max verbosity, independent of display)
+- Consistent time tracking shown for all tasks in both modes
+
+#### Status Symbols
+
+| Symbol | Status | Meaning |
+|--------|--------|---------|
+| ✓ | ok | Task succeeded, no changes made |
+| * | changed | Task succeeded and made changes |
+| ✗ | failed | Task failed |
+| ⊘ | skipped | Task was skipped |
+| ! | unreachable | Host was unreachable |
+
+Example output (no flags):
+
+```
+TASK: Install packages
+ * [host2] (2.3s)
+TASK: Configure service
+ ✗ [host2] (0.1s)
+```
+
+Example output with `-v`:
+
+```
+TASK: Install packages
+ ✓ [host1] (0.6s)
+ * [host2] (2.3s)
+ $ apt-get install -y nginx
+TASK: Configure service
+ ⊘ [host1] (0.0s)
+ ✗ [host2] (0.1s)
+```
+
+#### Verbosity Levels
+
+Lucid uses Ansible's standard verbosity flags to control output detail:
+
+| Flag | Level | Console Output |
+|------|-------|----------------|
+| (none) | 0 | Only changed, failed, unreachable tasks (with stdout/stderr) |
+| `-v` | 1 | All tasks (ok, skipped) + executed commands + stdout/stderr |
+| `-vv` | 2 | Above + tasks with `output_verbosity: 2` |
+| `-vvv` | 3 | Above + tasks with `output_verbosity: 3` |
+
+**Output display rules:**
+- Changed, failed, unreachable: Always show stdout/stderr/msg
+- OK tasks: Show stdout/stderr only with `-v` or higher
+- Skipped tasks: Show only with `-v` or higher
+
+**Log files always capture full output regardless of verbosity level.**
+
+#### Enable lucid
+
+```bash
+./scripts/kconfig/merge_config.sh -n .config defconfigs/configs/lucid.config
+make
+```
+
+Or via command line:
+
+```bash
+make ANSIBLE_CFG_CALLBACK_PLUGIN=lucid menuconfig
+make
+```
+
+#### CI/CD Configuration
+
+For CI/CD environments where you want full verbose output similar to log files,
+use the lucid-ci configuration fragment:
+
+```bash
+./scripts/kconfig/merge_config.sh -n .config defconfigs/configs/lucid-ci.config
+make
+```
+
+This enables lucid with static output mode and verbosity level 1, providing
+comprehensive output including all task results, executed commands, and
+stdout/stderr without requiring manual `-v` flags.
+
+The verbosity level can be configured via Kconfig:
+
+```bash
+make menuconfig
+# Navigate to: Ansible Configuration -> Ansible verbosity level
+```
+
+Or override at runtime using the native Ansible environment variable:
+
+```bash
+ANSIBLE_VERBOSITY=1 make target # Force verbosity level 1 for this run
+```
+
+#### Parameters
+
+| Parameter | Choices/Defaults | Configuration | Comments |
+|-----------|------------------|---------------|----------|
+| output_mode | Choices: auto/static/dynamic<br>Default: auto | ini: [callback_lucid] output_mode<br>env: ANSIBLE_LUCID_OUTPUT_MODE | Display mode: auto detects terminal, static for CI/CD, dynamic for live updates |
+
+Log files are automatically created in `.ansible/logs/` with timestamped filenames.
+
+#### Command Display
+
+When running with `-v` or higher verbosity, lucid shows the executed command
+for modules that expose their commands in task results:
+
+- `ansible.builtin.shell`, `ansible.builtin.command`
+- `ansible.builtin.pip`
+- `community.general.make`
+- `community.general.flatpak`, `community.general.flatpak_remote`
+- `community.general.terraform`
+
+Commands are always logged to the log file regardless of verbosity level.
+
+#### Task-level Output Control
+
+Control visibility of individual tasks using the `output_verbosity` variable.
+Tasks are shown when the current verbosity level meets or exceeds the task's
+`output_verbosity` setting:
+
+```yaml
+- name: Always visible task (shown even without -v)
+ debug:
+ msg: "Important status message"
+ vars:
+ output_verbosity: 0
+
+- name: Normal task (shown with -v)
+ debug:
+ msg: "Standard task output"
+ vars:
+ output_verbosity: 1 # This is the default
+
+- name: Debug task (shown with -vv)
+ debug:
+ msg: "Debugging information"
+ vars:
+ output_verbosity: 2
+
+- name: Trace task (shown with -vvv)
+ debug:
+ msg: "Detailed trace output"
+ vars:
+ output_verbosity: 3
+```
+
+#### Force Static Mode
+
+Use the environment variable to force static output mode:
+
+```bash
+ANSIBLE_LUCID_OUTPUT_MODE=static ansible-playbook playbooks/test.yml
+```
+
+Or via make:
+
+```bash
+ANSIBLE_LUCID_OUTPUT_MODE=static make bringup
+```
+
+The standard `TERM=dumb` convention is also respected for compatibility:
+
+```bash
+TERM=dumb make bringup
+```
+
+#### Dynamic Mode Display
+
+In dynamic mode, the display shows all hosts participating in a task with a
+stable layout that prevents flickering:
+
+```
+TASK: Install packages
+
+Hosts: 1/2 running
+ [⠦] 2.3s host1 -> localhost
+ [ ] host2
+
+Recent:
+ * Install deps [host1] (1.2s)
+```
+
+Running hosts show a spinner and elapsed time. Non-running hosts show empty
+brackets. The time column is fixed-width to prevent display jumping.
+
+#### Delegation Display
+
+Tasks using `delegate_to` show delegation info in the format `host -> delegate`,
+matching Ansible's default callback behavior:
+
+```
+ * [host1 -> localhost] (2.3s)
+```
+
+This appears in static mode, dynamic mode, and log files.
+
+#### Notes
+
+- Dynamic mode provides live updates with spinner when running in interactive terminals
+- Automatically detects CI/CD environments (GitHub Actions, Jenkins, GitLab CI) and uses static mode
+- Logs are always full verbosity regardless of display verbosity
+- Log files include playbook name and timestamp: `<playbook>-YYYY-MM-DD_HH-MM-SS.log`
+- Compatible with ansible.posix.profile_tasks callback
+- Failed tasks always freeze dynamic display and switch to static mode
+
+### custom
+
+Select any Ansible callback plugin by name. When selected, a text field
+allows entering the full plugin name (e.g., `ansible.posix.json`).
+
+## Timing Analysis
+
+Enable `profile_tasks` for detailed timing analysis alongside any callback:
+
+```bash
+make menuconfig
+# Enable: Ansible Callback Plugin Configuration -> Enable profile_tasks callback for timing analysis
+```
+
+This adds a `TASKS RECAP` section at the end showing execution times for
+each task, similar to `systemd-analyze blame`.
diff --git a/kconfigs/Kconfig.ansible_cfg b/kconfigs/Kconfig.ansible_cfg
index bea093fe..1e9539b1 100644
--- a/kconfigs/Kconfig.ansible_cfg
+++ b/kconfigs/Kconfig.ansible_cfg
@@ -59,6 +59,23 @@ choice
default ANSIBLE_CFG_CALLBACK_PLUGIN_DENSE if !ANSIBLE_CFG_CALLBACK_PLUGIN_SET_BY_CLI
default ANSIBLE_CFG_CALLBACK_PLUGIN_CUSTOM if ANSIBLE_CFG_CALLBACK_PLUGIN_SET_BY_CLI
+config ANSIBLE_CFG_CALLBACK_PLUGIN_LUCID
+ bool "Ansible Lucid Callback Plugin"
+ help
+ Lucid: Modern, clean Ansible output with progressive verbosity levels.
+
+ Features:
+ - Clean, minimal output by default (shows only changes and errors)
+ - Progressive verbosity: -v shows all tasks, -vv shows debug tasks
+ - Dynamic live display for interactive terminals (BitBake/Yocto style)
+ - Static output for CI/CD and piped output
+ - Task-level output control via output_verbosity variable
+ - Comprehensive logging (always max verbosity, independent of display)
+ - Time tracking for tasks > 3 seconds
+
+ Lucid is designed by kernel developers for kernel testing workflows
+ where human-readable output and silent operation are essential.
+
config ANSIBLE_CFG_CALLBACK_PLUGIN_DEBUG
bool "Ansible Debug Callback Plugin"
help
@@ -93,6 +110,7 @@ endif # ANSIBLE_CFG_CALLBACK_PLUGIN_CUSTOM
config ANSIBLE_CFG_CALLBACK_PLUGIN_STRING
string
output yaml
+ default "lucid" if ANSIBLE_CFG_CALLBACK_PLUGIN_LUCID
default "debug" if ANSIBLE_CFG_CALLBACK_PLUGIN_DEBUG
default "dense" if ANSIBLE_CFG_CALLBACK_PLUGIN_DENSE
default "community.general.diy" if ANSIBLE_CFG_CALLBACK_PLUGIN_DIY
@@ -170,6 +188,62 @@ config ANSIBLE_CFG_CALLBACK_PLUGIN_PROFILE_TASKS
and generates a "TASKS RECAP" section showing execution times.
https://docs.ansible.com/ansible/latest/collections/ansible/posix/profile_tasks_callback.html
+
+if ANSIBLE_CFG_CALLBACK_PLUGIN_LUCID
+
+choice
+ prompt "Lucid output display mode"
+ default ANSIBLE_CFG_LUCID_OUTPUT_MODE_AUTO
+
+config ANSIBLE_CFG_LUCID_OUTPUT_MODE_AUTO
+ bool "Auto (dynamic if interactive, static otherwise)"
+ help
+ Automatically select output mode based on terminal detection.
+
+ Uses dynamic live updating display (similar to BitBake/Yocto) when
+ running in an interactive terminal with spinner animations, live
+ task timers, and parallel task visualization.
+
+ Automatically falls back to traditional static output for CI/CD,
+ piped output, and non-TTY contexts.
+
+ This is the recommended default for most use cases.
+
+config ANSIBLE_CFG_LUCID_OUTPUT_MODE_STATIC
+ bool "Static (always use traditional output)"
+ help
+ Force static output mode regardless of terminal type.
+
+ Always use traditional static output with no live updates or
+ animations. Each task result is printed as it completes.
+
+ Useful for users who prefer traditional Ansible output or when
+ dynamic mode causes issues with specific terminal emulators.
+
+config ANSIBLE_CFG_LUCID_OUTPUT_MODE_DYNAMIC
+ bool "Dynamic (always attempt live display)"
+ help
+ Force dynamic output mode even in non-interactive contexts.
+
+ Always attempt to use live updating display with ANSI escape codes
+ even if terminal detection suggests static mode should be used.
+
+ Warning: May produce garbled output in CI/CD, piped contexts, or
+ terminals that don't support ANSI escape sequences. Only use this
+ if you know your environment supports dynamic output but the
+ automatic detection fails.
+
+endchoice
+
+config ANSIBLE_CFG_LUCID_OUTPUT_MODE_STRING
+ string
+ output yaml
+ default "auto" if ANSIBLE_CFG_LUCID_OUTPUT_MODE_AUTO
+ default "static" if ANSIBLE_CFG_LUCID_OUTPUT_MODE_STATIC
+ default "dynamic" if ANSIBLE_CFG_LUCID_OUTPUT_MODE_DYNAMIC
+
+endif # ANSIBLE_CFG_CALLBACK_PLUGIN_LUCID
+
endmenu
config ANSIBLE_CFG_VERBOSITY
diff --git a/playbooks/roles/ansible_cfg/templates/ansible.cfg.j2 b/playbooks/roles/ansible_cfg/templates/ansible.cfg.j2
index 165aec0e..e4841fb3 100644
--- a/playbooks/roles/ansible_cfg/templates/ansible.cfg.j2
+++ b/playbooks/roles/ansible_cfg/templates/ansible.cfg.j2
@@ -1,6 +1,10 @@
[defaults]
+{% if ansible_cfg_callback_plugin_string == 'lucid' %}
+callback_plugins = ./callback_plugins
+{% endif %}
{% if ansible_cfg_callback_plugin_profile_tasks %}
-callbacks_enabled = ansible.posix.profile_tasks, {{ ansible_cfg_callback_plugin_string }}
+callbacks_enabled = ansible.posix.profile_tasks{% if ansible_cfg_callback_plugin_string == 'lucid' %}, {{ ansible_cfg_callback_plugin_string }}{% endif %}
+
{% endif %}
verbosity = {{ ansible_cfg_verbosity | default(0) }}
deprecation_warnings = {{ ansible_cfg_deprecation_warnings }}
@@ -48,6 +52,12 @@ playbook_on_stats_msg_color = bright green
[callback_profile_tasks]
summary_only = true
{% endif %}
+{% if ansible_cfg_callback_plugin_string == 'lucid' %}
+
+[callback_lucid]
+output_mode = {{ ansible_cfg_lucid_output_mode_string | default('auto') }}
+{% endif %}
+
[ssh_connection]
remote_port = {{ ansible_cfg_ssh_port }}
{% if ansible_facts['distribution'] == 'openSUSE' %}
--
2.52.0
^ permalink raw reply related [flat|nested] 6+ messages in thread