feat: initial commit — Ansible roles storage-01/gpu-01 opérationnels

This commit is contained in:
alkatrazz 2026-05-12 17:17:03 +02:00
commit b3fce8af5d
70 changed files with 2688 additions and 0 deletions

View file

@ -0,0 +1,15 @@
---
litellm_user: litellm
litellm_venv: /opt/litellm/venv
litellm_config_dir: /etc/litellm
litellm_host: "127.0.0.1" # loopback — Hermes est sur la même machine
litellm_port: 4000
litellm_master_key: "lm-studio"
# Clé Anthropic — vient du vault
litellm_anthropic_api_key: "{{ vault_anthropic_api_key }}"
# Endpoint llama-server sur gpu-01
litellm_local_llm_base_url: "http://192.168.10.20:1234/v1"
litellm_local_llm_api_key: "lm-studio"

View file

@ -0,0 +1,76 @@
#!/bin/bash
# Switch le modèle de Hermes via LiteLLM (hermes-default alias)
# Usage: hermes-switch [qwen|claude|status]
CONFIG=/etc/litellm/config.yaml
qwen_block=' litellm_params:\n model: openai/qwen2.5-7b-instruct\n api_base: http://192.168.10.20:1234/v1\n api_key: lm-studio'
claude_block=' litellm_params:\n model: anthropic/claude-sonnet-4-6\n api_key: os.environ/ANTHROPIC_API_KEY'
current() {
grep -A3 "model_name: hermes-default" "$CONFIG" | grep "model:" | awk '{print $2}'
}
status() {
local cur=$(current)
echo "hermes-default → $cur"
}
switch_qwen() {
python3 - "$CONFIG" <<'EOF'
import sys, re
path = sys.argv[1]
text = open(path).read()
block = """ - model_name: hermes-default
litellm_params:
model: openai/qwen3-8b
api_base: http://192.168.10.20:1234/v1
api_key: lm-studio"""
text = re.sub(
r' - model_name: hermes-default\n litellm_params:.*?(?=\n -|\nlitellm_settings)',
block + '\n',
text, flags=re.DOTALL
)
open(path, 'w').write(text)
print("OK")
EOF
}
switch_claude() {
python3 - "$CONFIG" <<'EOF'
import sys, re
path = sys.argv[1]
text = open(path).read()
block = """ - model_name: hermes-default
litellm_params:
model: anthropic/claude-sonnet-4-6
api_key: os.environ/ANTHROPIC_API_KEY"""
text = re.sub(
r' - model_name: hermes-default\n litellm_params:.*?(?=\n -|\nlitellm_settings)',
block + '\n',
text, flags=re.DOTALL
)
open(path, 'w').write(text)
print("OK")
EOF
}
case "${1:-status}" in
qwen)
switch_qwen
systemctl restart litellm
echo "Hermes → Qwen3-8B (gpu-01)"
;;
claude)
switch_claude
systemctl restart litellm
echo "Hermes → Claude Sonnet 4.6 (API Anthropic)"
;;
status)
status
;;
*)
echo "Usage: hermes-switch [qwen|claude|status]"
exit 1
;;
esac

View file

@ -0,0 +1,9 @@
---
- name: Reload systemd
ansible.builtin.systemd:
daemon_reload: true
- name: Restart litellm
ansible.builtin.systemd:
name: litellm
state: restarted

View file

@ -0,0 +1,62 @@
---
- name: Install Python pip and devel
ansible.builtin.dnf:
name:
- python3-pip
- python3-devel
state: present
- name: Create litellm system user
ansible.builtin.user:
name: "{{ litellm_user }}"
system: true
shell: /sbin/nologin
home: /opt/litellm
create_home: true
state: present
- name: Install litellm[proxy] in venv
ansible.builtin.pip:
name: "litellm[proxy]"
virtualenv: "{{ litellm_venv }}"
virtualenv_command: python3 -m venv
state: present
- name: Create config directory
ansible.builtin.file:
path: "{{ litellm_config_dir }}"
state: directory
owner: "{{ litellm_user }}"
group: "{{ litellm_user }}"
mode: '0750'
- name: Deploy LiteLLM config
ansible.builtin.template:
src: config.yaml.j2
dest: "{{ litellm_config_dir }}/config.yaml"
owner: "{{ litellm_user }}"
group: "{{ litellm_user }}"
mode: '0640'
notify: Restart litellm
- name: Deploy systemd service
ansible.builtin.template:
src: litellm.service.j2
dest: /etc/systemd/system/litellm.service
mode: '0644'
notify:
- Reload systemd
- Restart litellm
- name: Deploy hermes-switch script
ansible.builtin.copy:
src: hermes-switch
dest: /usr/local/bin/hermes-switch
mode: '0755'
- name: Enable and start litellm
ansible.builtin.systemd:
name: litellm
enabled: true
daemon_reload: true
state: started

View file

@ -0,0 +1,36 @@
model_list:
# Alias Hermes — changer uniquement ce bloc pour switcher le modèle de Hermes
# sans toucher à la configuration de Hermes lui-même
- model_name: hermes-default
litellm_params:
model: openai/qwen3-8b
api_base: {{ litellm_local_llm_base_url }}
api_key: {{ litellm_local_llm_api_key }}
# Pour passer Hermes sur Claude : remplacer les 3 lignes ci-dessus par :
# model: anthropic/claude-sonnet-4-6
# api_key: os.environ/ANTHROPIC_API_KEY
# Modèles accessibles directement par nom
- model_name: qwen3-8b
litellm_params:
model: openai/qwen3-8b
api_base: {{ litellm_local_llm_base_url }}
api_key: {{ litellm_local_llm_api_key }}
- model_name: claude-sonnet-4-6
litellm_params:
model: anthropic/claude-sonnet-4-6
api_key: os.environ/ANTHROPIC_API_KEY
- model_name: claude-opus-4-7
litellm_params:
model: anthropic/claude-opus-4-7
api_key: os.environ/ANTHROPIC_API_KEY
litellm_settings:
drop_params: true
request_timeout: 600
general_settings:
master_key: {{ litellm_master_key }}

View file

@ -0,0 +1,25 @@
[Unit]
Description=LiteLLM Proxy — unified LLM gateway (Qwen local + Claude API)
After=network-online.target
Wants=network-online.target
[Service]
Type=simple
User={{ litellm_user }}
Group={{ litellm_user }}
Environment=ANTHROPIC_API_KEY={{ litellm_anthropic_api_key }}
ExecStart={{ litellm_venv }}/bin/litellm \
--config {{ litellm_config_dir }}/config.yaml \
--host {{ litellm_host }} \
--port {{ litellm_port }}
Restart=on-failure
RestartSec=10
StandardOutput=journal
StandardError=journal
SyslogIdentifier=litellm
[Install]
WantedBy=multi-user.target