LLM-Server: llm/ansible für Check-Modus und ansible-core 2.21 fit gemacht

Nach Live-Check-Modus gegen ghostnet-ki (ok=23, changed=4, failed=0):
- Freiraumprüfung auf existierendes Elternelement (df schlägt im Check-Modus
  auf dem noch nicht angelegten Store fehl)
- Rechte-Durchsetzung nur über vorhandene Artefakte (file-Modul im Check-Modus)
- assert ohne loop (2.21 lehnt loop auf assert ab); statische Meldungen,
  Modell-Anwesenheit im Check-Modus nur informell
- find file_type=any für Character-Devices (renderD*)
- README: Aufruf mit --private-key nach Workstation-Konvention

Preview prognostiziert korrekt: 2 Modellverzeichnisse, 2 SOURCE.yml,
Netz-Quadlet, 2 Container-Quadlets; gepinntes ROCm-Image bereits im Store.

Generated by Mistral Vibe.
Co-Authored-By: Mistral Vibe <vibe@mistral.ai>
This commit is contained in:
2026-11-01 17:31:45 +01:00
parent 7af72785c9
commit d53b2400c9
3 changed files with 36 additions and 16 deletions
+10 -3
View File
@@ -32,15 +32,22 @@ cd llm-server/llm/ansible
## Usage (Testing)
All commands use the operator deploy key
`~/.ssh/id_ed25519_ghostnet_ai_ansible_deploy` (see AGENTS.md; no ssh-agent
required):
```bash
# Preview only – no changes, no downloads, no service start:
../../../.venv/bin/ansible-playbook -i inventories/testing playbooks/ai.yml --check --diff
../../../.venv/bin/ansible-playbook -i inventories/testing playbooks/ai.yml \
--check --diff --private-key ~/.ssh/id_ed25519_ghostnet_ai_ansible_deploy
# Provision model weights only (tag models):
../../../.venv/bin/ansible-playbook -i inventories/testing playbooks/ai.yml --tags models
../../../.venv/bin/ansible-playbook -i inventories/testing playbooks/ai.yml \
--tags models --private-key ~/.ssh/id_ed25519_ghostnet_ai_ansible_deploy
# Render quadlets and start/verify the selected profile (tag service):
../../../.venv/bin/ansible-playbook -i inventories/testing playbooks/ai.yml --tags service
../../../.venv/bin/ansible-playbook -i inventories/testing playbooks/ai.yml \
--tags service --private-key ~/.ssh/id_ed25519_ghostnet_ai_ansible_deploy
```
`inference_engine_active_profile` selects which rendered quadlet is started;
@@ -48,12 +48,14 @@
- name: Verify the rootless runtime utilities are executable
ansible.builtin.assert:
that:
- item.stat.exists
- item.stat.executable
loop: "{{ inference_engine_tools.results }}"
- inference_engine_tools.results | selectattr('stat.exists') | list | length
== inference_engine_tools.results | length
- inference_engine_tools.results | selectattr('stat.executable', 'equalto', true) | list | length
== inference_engine_tools.results | length
fail_msg: >-
{{ item.item }} is missing or not executable; run the host baseline
roles first (llm-server/host/ansible).
A required rootless runtime utility is missing or not executable
(runuser, podman, systemctl or the Podman system generator); run the
host baseline roles first (llm-server/host/ansible).
tags:
- service
@@ -68,6 +70,9 @@
ansible.builtin.find:
paths: /dev/dri
patterns: renderD*
# Render nodes are character devices; the default file_type (file) would
# skip them.
file_type: any
register: inference_engine_render_node_find
tags:
- service
@@ -105,11 +110,17 @@
- name: Verify every profile model artifact is present
ansible.builtin.assert:
that:
- item.stat.exists
loop: "{{ inference_engine_models.results }}"
- inference_engine_models.results | selectattr('stat.exists', 'equalto', true) | list | length
== inference_engine_models.results | length
fail_msg: >-
Model artifact for {{ item.item.key }} is missing under
{{ model_store_root }}; run the model_store role (--tags models) first.
Missing model artifacts under {{ model_store_root }}:
{{ inference_engine_models.results
| selectattr('stat.exists', 'equalto', false)
| map(attribute='item.key') | list | join(', ') }};
run the model_store role (--tags models) first.
# Check mode deliberately downloads nothing, so the preview continues and
# only shows the pending quadlet changes; a real run enforces presence.
when: not ansible_check_mode
tags:
- service
@@ -80,7 +80,9 @@
- /bin/df
- -m
- --output=avail
- "{{ model_store_root }}"
# dirname is used because the store root itself may not exist yet in
# check mode; it lives on the same filesystem as the store.
- "{{ model_store_root | dirname }}"
changed_when: false
check_mode: false
register: model_store_free_space
@@ -151,14 +153,14 @@
- name: Enforce model artifact ownership and permissions
ansible.builtin.file:
path: "{{ model_store_root }}/{{ item.directory }}/{{ item.file }}"
path: "{{ model_store_root }}/{{ item.item.directory }}/{{ item.item.file }}"
state: file
owner: root
group: root
mode: "{{ model_store_file_mode }}"
loop: "{{ model_store_all_artifacts }}"
loop: "{{ model_store_present.results | selectattr('stat.exists', 'equalto', true) | list }}"
loop_control:
label: "{{ item.profile }}"
label: "{{ item.item.profile }}"
tags:
- models
- service