Skip to content

fix(ansible): /opt/autobot/venv is built by three producers with two interpreters #13746

Closed

Description

@mrveiss

Part of #13743 · Wave 2 — depends on #13745 (the group fix decides which hosts this runs on at all).

Three producers build a venv at /opt/autobot/venv, with two different interpreters:

Producer Path Interpreter
roles/backend_services/tasks/main.yml:49 /opt/autobot/venv 3.14
deploy-native-services.yml:365 (hosts: npu) /opt/autobot/venv 3.11
deploy-native-services.yml:511 (hosts: aiml) /opt/autobot/venv 3.14

The role-based NPU path is already correct — roles/npu-worker uses {{ npu_install_dir }}/venv (/opt/autobot/autobot-npu-worker/venv), its own directory. Only the playbook writes the NPU venv into the shared path.

Why it matters

Co-location is a supported layout — the role-facts test inventory covers a single host carrying SLM + backend + vnc — so these plays can land on one machine.

The aiml play creates its venv with a bare shell: and no creates: guard:

- name: Create Python virtual environment
  shell: |
    cd /opt/autobot
    python3.14 -m venv venv

On a co-located host that re-runs over an existing 3.11 tree, rewriting pyvenv.cfg to 3.14 while site-packages still holds 3.11-built OpenVINO binaries. The failure is a native-extension ImportError at worker startup, not a deploy error — so the deploy reports success and the worker dies later.

Fix

Give the NPU worker its own venv path in the playbook, matching what roles/npu-worker already does, and add a creates: guard (or the python314 role's ensure_venv_version.yml, which exists precisely for this) to the aiml play so it cannot silently re-point an existing venv.

Acceptance criteria

  • No two producers build /opt/autobot/venv with different interpreters.
  • The aiml venv creation is guarded — re-running it against an existing venv of a different minor version fails loudly or is a no-op, never a silent re-point.
  • Verified against a co-located layout (npu + aiml on one host), not only the split-fleet case.

Activity

  1. mrveiss commented on Aug 8, 2026

    @mrveiss
    OwnerAuthor

    Tracked under epic #13743 (Python 3.14 consistency). Audit with the measurements: docs/audit/python_314_consistency.md, landing in PR #13750.

  2. mrveiss commented on Aug 9, 2026

    @mrveiss
    OwnerAuthor

    Delivered and merged: PR #13787, squashed as 134c1cc.

    The stated dependency on #13745 was not real. That issue's premise did not reproduce — npu and aiml both resolve via the #2515 alias block — so there was no group fix to wait on.

    AC 1 — /opt/autobot/venv now has one interpreter. The playbook's NPU venv moves to {{ npu_venv }} = /opt/autobot/autobot-npu-worker/venv, matching what roles/npu-worker already uses; /opt/autobot/venv is left to its 3.14 producers. The 3.11 interpreter stays — moving the NPU worker to 3.14 is #13747 with its own blockers, and once the paths differ there is no collision to fix.

    Moving the venv meant moving the systemd unit with it: Environment="PATH=…" and ExecStart both referenced the old path, so a path change without them would have left a unit pointing at a venv nothing builds.

    AC 2 — both the npu and aiml plays now include roles/python314's ensure_venv_version, which removes a venv of the wrong minor version so the create task rebuilds it; the aiml create task also gains the creates: guard it never had. Reused rather than reimplemented — that task file's own comment describes this exact failure.

    AC 3 — autobot-slm-backend/ansible/tests/check_venv_producers.py, run by the ansible-role-facts-test workflow. Checking the property statically means co-location needs no test fleet: if no path has two interpreters, which host the plays land on is irrelevant.

    check_venv_producers: 9 venv path(s), each with a single interpreter.
    exit=0
    

    Deliberate failure — the same guard against the unfixed playbook reproduces this issue's table, and found a fourth producer it did not list:

    A venv path is built by more than one interpreter:
      /opt/autobot/venv
        python3.11   playbooks/deploy-native-services.yml:365
        python3.11   playbooks/deploy-native-services.yml:373   <- the pip task's virtualenv_python
        python3.14   playbooks/deploy-native-services.yml:511
        python3.14   roles/backend_services/tasks/main.yml:49
    exit=1
    

    Three drafting errors were caught before this shipped, each of which would have left a check that lies: a \S+ path regex truncating {{ npu_install_dir }}/venv to {{ (collapsing eight unrelated venvs into one phantom conflict); cd /opt/autobot + python3.14 -m venv venv recording the path as venv; and the workflow's paths: filter not covering playbooks/** or roles/**, so the new step would never have run on a change that breaks it.

    Closing.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions