Skip to content

fix: make memory fact locale-safe and integer-valued#1364

Merged
michael-balint merged 1 commit into
masterfrom
dholt/memory-fact-locale
Jul 15, 2026
Merged

fix: make memory fact locale-safe and integer-valued#1364
michael-balint merged 1 commit into
masterfrom
dholt/memory-fact-locale

Conversation

@dholt

@dholt dholt commented Jul 15, 2026

Copy link
Copy Markdown
Contributor

Summary

  • Make the memory custom fact locale-safe and integer-valued: compute total_mb with awk printf "%d" instead of the default float print.
  • Root cause of AnsibleUndefinedVariable: ''ansible.utils.unsafe_proxy.AnsibleUnsafeText object'' has no attribute ''total_mb''' #1321: awk's default output renders floats using the host's LC_NUMERIC decimal separator. On comma-decimal locales the fact emitted { "total_mb": 60760,1 } — invalid JSON — so Ansible silently provided the fact as a raw string and slurm.conf templating failed with the reported AnsibleUnsafeText ... has no attribute 'total_mb' error. This also explains why the error only reproduced for some users: it depends on the host locale.
  • Harden the slurm.conf template to parse a string-typed fact (from_json) so any future malformed fact fails clearly instead of with an opaque attribute error.

Validation

  • bash -n on the fact script; the fact output parses as JSON with an integer total_mb.
  • Demonstrated the defect mechanism: awk '{print $2*0.95}' emits 60760.1 (locale-dependent separator), printf "%d" cannot emit a separator.
  • ansible-playbook --syntax-check playbooks/slurm-cluster.yml; full role lint: 0 failures.
  • Live single-node GPU validation summary will be posted as a follow-up comment before review: fresh Slurm deployment asserting RealMemory templates as an integer and the fact parses under a comma-decimal locale on the deployed node.

Notes

The memory custom fact computed total_mb with awk's default print,
which emits a float (e.g. 60760.1) whose decimal separator follows
LC_NUMERIC. On comma-decimal locales the fact rendered as
{ "total_mb": 60760,1 } — invalid JSON — so Ansible fell back to
providing the fact as a raw string and slurm.conf templating failed
with an opaque AnsibleUnsafeText attribute error on total_mb.

Use printf "%d" so the value is always an integer with no locale-
dependent formatting (RealMemory expects an integer anyway), and
harden the slurm.conf template to parse a string fact so a malformed
fact fails clearly rather than with an attribute error.

Fixes #1321
@dholt

dholt commented Jul 15, 2026

Copy link
Copy Markdown
Contributor Author

Live validation summary

Validated on a disposable dual-GPU server (Ubuntu 22.04) with a fresh full slurm-cluster.yml deployment from a branch carrying this change:

  • The deployed /etc/slurm/slurm.conf templated RealMemory=244707 — an integer computed by the new fact.
  • On the deployed node, a comma-decimal locale (de_DE.UTF-8) was generated and the fact executed under it: output parsed as valid JSON with an integer total_mb ({ "total_mb": 244707 }). Under the same conditions the previous implementation emits a comma-decimal float, which is invalid JSON and reproduces the reported failure.
  • Slurm deployed and scheduled normally (srun --gpus=1 nvidia-smi passing).

@dholt dholt marked this pull request as ready for review July 15, 2026 17:53
@dholt dholt requested a review from michael-balint July 15, 2026 17:53
@michael-balint michael-balint merged commit 5693116 into master Jul 15, 2026
31 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

AnsibleUndefinedVariable: ''ansible.utils.unsafe_proxy.AnsibleUnsafeText object'' has no attribute ''total_mb'''

2 participants