ec740f458f
- Introduced SMTP settings for Vaultwarden including host, port, security, and authentication details. - Added variables for signup verification, 2FA settings, password hints, and logging options. - Updated Vaultwarden deployment to utilize new SMTP configurations. - Enhanced Grafana module to support dynamic dashboard and datasource provisioning. - Added LLM proxy configuration for Open Web UI with necessary environment variables.
359 lines
12 KiB
YAML
359 lines
12 KiB
YAML
---
|
|
- name: Validate llama_server_models schema
|
|
ansible.builtin.assert:
|
|
that:
|
|
- llama_server_models is iterable
|
|
fail_msg: "llama_server_models must be a list"
|
|
|
|
- name: Create group
|
|
become: true
|
|
ansible.builtin.group:
|
|
name: "{{ llama_server_group }}"
|
|
system: true
|
|
|
|
- name: Create user
|
|
become: true
|
|
ansible.builtin.user:
|
|
name: "{{ llama_server_user }}"
|
|
groups: "{{ podman_extra_groups | default([]) }}"
|
|
shell: /bin/bash
|
|
home: "{{ llama_server_home }}"
|
|
group: "{{ llama_server_group }}"
|
|
|
|
- name: Disable password login for user
|
|
ansible.builtin.command: passwd -d "{{ llama_server_user }}"
|
|
become: true
|
|
changed_when: false
|
|
|
|
- name: Create user home
|
|
become: true
|
|
ansible.builtin.file:
|
|
path: "{{ llama_server_home }}"
|
|
state: directory
|
|
owner: "{{ llama_server_user }}"
|
|
group: "{{ llama_server_group }}"
|
|
mode: "0750"
|
|
|
|
- name: Set fact podman_binary (Debian family)
|
|
ansible.builtin.set_fact:
|
|
podman_binary: /usr/bin/podman
|
|
when: ansible_os_family == 'Debian'
|
|
|
|
- name: Set fact podman_binary (Red Hat family)
|
|
ansible.builtin.set_fact:
|
|
podman_binary: /usr/sbin/podman
|
|
when: ansible_os_family == 'RedHat'
|
|
|
|
- name: Create required folders
|
|
become: true
|
|
ansible.builtin.file:
|
|
path: "{{ llama_server_home }}/{{ item }}"
|
|
state: directory
|
|
owner: "{{ llama_server_user }}"
|
|
group: "{{ llama_server_group }}"
|
|
mode: "0750"
|
|
loop:
|
|
- models
|
|
- .cache
|
|
- .cache/llama.cpp
|
|
|
|
- name: "Add SSH Authorized key"
|
|
become: true
|
|
ansible.posix.authorized_key:
|
|
user: "{{ llama_server_user }}"
|
|
key: "{{ llama_server_pubkey }}"
|
|
state: "{{ 'present' if llama_server_pubkey is defined and llama_server_pubkey != '' else 'absent' }}"
|
|
when: llama_server_pubkey is defined and llama_server_pubkey != ""
|
|
|
|
- name: SELinux tasks (RedHat only)
|
|
when: ansible_os_family == 'RedHat'
|
|
become: true
|
|
block:
|
|
- name: Persistently set SELinux context
|
|
community.general.sefcontext:
|
|
target: "{{ llama_server_home }}(/.*)?"
|
|
setype: user_home_dir_t
|
|
state: present
|
|
|
|
- name: Persistently set SELinux context (ssh authorized keys)
|
|
community.general.sefcontext:
|
|
target: "{{ llama_server_home }}/.ssh/authorized_keys"
|
|
setype: ssh_home_t
|
|
state: present
|
|
when: llama_server_pubkey is defined and llama_server_pubkey != ""
|
|
|
|
- name: Apply SELinux context
|
|
ansible.builtin.command: restorecon -Rv {{ llama_server_home }}
|
|
changed_when: false
|
|
|
|
- name: Enable sudo access to llama user (temporary)
|
|
become: true
|
|
ansible.builtin.lineinfile:
|
|
path: "/etc/sudoers.d/ansible_{{ llama_server_user }}_tmp"
|
|
create: true
|
|
mode: "0440"
|
|
line: "{{ ansible_facts['user_id'] }} ALL=({{ llama_server_user }}) NOPASSWD: ALL"
|
|
validate: "visudo -cf %s"
|
|
|
|
- name: Enable lingering for llama user
|
|
become: true
|
|
ansible.builtin.command: loginctl enable-linger {{ llama_server_user }}
|
|
register: linger_status
|
|
changed_when: >-
|
|
'created' in linger_status.stdout or
|
|
(linger_status.rc == 0 and not
|
|
('linger file already exists' in linger_status.stderr or
|
|
'linger file does not exist' in linger_status.stderr))
|
|
failed_when:
|
|
- linger_status.rc != 0 and not
|
|
('linger file already exists' in linger_status.stderr)
|
|
|
|
- name: Get current user's UID
|
|
ansible.builtin.command: id -u {{ llama_server_user }}
|
|
changed_when: false
|
|
register: uid
|
|
|
|
- name: Get current user's GID
|
|
ansible.builtin.command: id -g {{ llama_server_user }}
|
|
changed_when: false
|
|
register: gid
|
|
|
|
- name: Run tasks as podman user
|
|
become: true
|
|
become_user: "{{ llama_server_user }}"
|
|
block:
|
|
- name: Pull the requested images
|
|
containers.podman.podman_image:
|
|
name: "{{ llama_server_image }}"
|
|
tag: "{{ llama_server_tag }}"
|
|
state: present
|
|
|
|
- name: Create pods
|
|
containers.podman.podman_container:
|
|
name: "llama.cpp"
|
|
image: "{{ llama_server_image }}:{{ llama_server_tag }}"
|
|
state: started
|
|
device: "{{ llama_server_devices | default(omit) }}"
|
|
env: "{{ llama_server_env | default(omit) }}"
|
|
ports: "0.0.0.0:{{ llama_server_port }}:8080/tcp"
|
|
volumes:
|
|
- "{{ llama_server_home }}/models:/models:Z"
|
|
- "{{ llama_server_home }}/.cache:/app/.cache:Z"
|
|
command:
|
|
- "-t"
|
|
- "{{ llama_server_argv_threads | default(10) }}"
|
|
- "-np"
|
|
- "{{ llama_server_argv_parallel | default(1) }}"
|
|
- "-b"
|
|
- "{{ llama_server_argv_batch_size | default(1024) }}"
|
|
- "-ub"
|
|
- "{{ llama_server_argv_ubatch_size | default(512) }}"
|
|
- "-fa"
|
|
- "{{ llama_server_argv_flash_attn | default('on') }}"
|
|
- "-ctk"
|
|
- "{{ llama_server_argv_cache_type_k | default('q4_0') }}"
|
|
- "-ctv"
|
|
- "{{ llama_server_argv_cache_type_v | default('q8_0') }}"
|
|
- "-cram"
|
|
- "{{ llama_server_argv_cache_reuse | default(-1) }}"
|
|
- "-sm"
|
|
- "{{ llama_server_argv_split_mode | default('layer') }}"
|
|
- "-dev"
|
|
- "{{ llama_server_argv_devices | default('Vulkan1,Vulkan2') }}"
|
|
- "-ts"
|
|
- "{{ llama_server_argv_tensor_split | default('8,12') }}"
|
|
- "-fit"
|
|
- "{{ llama_server_argv_fit | default('off') }}"
|
|
- "-mg"
|
|
- "{{ llama_server_argv_main_gpu | default(1) }}"
|
|
- "--mmap"
|
|
- "--metrics"
|
|
- "--models-preset"
|
|
- "/models/.router/models.ini"
|
|
- "--models-max"
|
|
- "{{ llama_server_models_max }}"
|
|
|
|
cmd_args:
|
|
- "--userns=keep-id"
|
|
- "--security-opt=label=disable"
|
|
|
|
- name: Create systemd service file for pods
|
|
become: true
|
|
ansible.builtin.template:
|
|
src: podman.service.j2
|
|
dest: "/etc/systemd/system/podman-llama.cpp.service"
|
|
owner: root
|
|
group: root
|
|
mode: "0644"
|
|
|
|
- name: Reload systemd daemon
|
|
become: true
|
|
ansible.builtin.systemd:
|
|
daemon_reload: true
|
|
|
|
- name: Enable containers at boot
|
|
become: true
|
|
ansible.builtin.systemd:
|
|
name: "podman-llama.cpp"
|
|
enabled: true
|
|
state: "started"
|
|
|
|
- name: Install Python packages required for llama server model sync
|
|
become: true
|
|
ansible.builtin.package:
|
|
name: "{{ __llama_sync_system_packages__ }}"
|
|
state: present
|
|
vars:
|
|
__llama_sync_system_packages__: >-
|
|
{{
|
|
{
|
|
'Debian': ['python3-pip', 'python3-packaging', 'python3-venv'],
|
|
'RedHat': ['python3-pip', 'python3-packaging'],
|
|
'Archlinux': ['python-pip', 'python-packaging']
|
|
}[ansible_os_family]
|
|
}}
|
|
|
|
- name: Install Hugging Face hub client in llama server sync virtualenv
|
|
become: true
|
|
become_user: "{{ llama_server_user }}"
|
|
ansible.builtin.pip:
|
|
name:
|
|
- pip
|
|
- setuptools
|
|
- packaging
|
|
- huggingface_hub>=0.32.0
|
|
state: present
|
|
virtualenv: "{{ llama_server_home }}/.router/.venv"
|
|
virtualenv_command: "python3 -m venv"
|
|
|
|
- name: Create llama server router model directories
|
|
become: true
|
|
ansible.builtin.file:
|
|
path: "{{ item.path }}"
|
|
state: directory
|
|
owner: "{{ llama_server_user }}"
|
|
group: "{{ llama_server_group }}"
|
|
mode: "{{ item.mode }}"
|
|
loop:
|
|
- { path: "{{ llama_server_home }}/models", mode: "0750" }
|
|
- { path: "{{ llama_server_home }}/models/managed", mode: "0750" }
|
|
- { path: "{{ llama_server_home }}/models/managed-links", mode: "0750" }
|
|
- { path: "{{ llama_server_home }}/models/.router", mode: "0750" }
|
|
|
|
- name: Copy llama server Hugging Face sync helper
|
|
become: true
|
|
ansible.builtin.copy:
|
|
src: scripts/llama_hf_sync.py
|
|
dest: "{{ llama_server_home }}/models/.router/llama_hf_sync.py"
|
|
owner: "{{ llama_server_user }}"
|
|
group: "{{ llama_server_group }}"
|
|
mode: "0750"
|
|
|
|
- name: Write desired llama server model manifest input
|
|
become: true
|
|
ansible.builtin.copy:
|
|
content: "{{ llama_server_models | to_nice_json }}"
|
|
dest: "{{ llama_server_home }}/models/.router/desired-models.json"
|
|
owner: "{{ llama_server_user }}"
|
|
group: "{{ llama_server_group }}"
|
|
mode: "0640"
|
|
|
|
- name: Write global llama server preset options
|
|
become: true
|
|
ansible.builtin.copy:
|
|
content: "{{ llama_server_preset_global | to_nice_json }}"
|
|
dest: "{{ llama_server_home }}/models/.router/preset-global.json"
|
|
owner: "{{ llama_server_user }}"
|
|
group: "{{ llama_server_group }}"
|
|
mode: "0640"
|
|
|
|
- name: Set arguments for llama server model sync
|
|
ansible.builtin.set_fact:
|
|
__llama_preset_file__:
|
|
- "{{ llama_server_home }}/.router/.venv/bin/python"
|
|
- "{{ llama_server_home }}/models/.router/llama_hf_sync.py"
|
|
- "--models-file"
|
|
- "{{ llama_server_home }}/models/.router/desired-models.json"
|
|
- "--managed-dir"
|
|
- "{{ llama_server_home }}/models/managed"
|
|
- "--links-dir"
|
|
- "{{ llama_server_home }}/models/managed-links"
|
|
- "--manifest-file"
|
|
- "{{ llama_server_home }}/models/.router/manifest.json"
|
|
- "--preset-file"
|
|
- "{{ llama_server_home }}/models/.router/models.ini"
|
|
- "--preset-global-file"
|
|
- "{{ llama_server_home }}/models/.router/preset-global.json"
|
|
- "--container-links-dir"
|
|
- "/models/managed-links"
|
|
|
|
- name: Run llama server model sync from Hugging Face
|
|
vars:
|
|
__llama_sync_argv__: >-
|
|
{{ __llama_preset_file__
|
|
+ (['--prune'] if llama_server_models_prune_enabled | default(true) else [])
|
|
+ (['--dry-run'] if llama_server_models_dry_run | default(false) else [])
|
|
}}
|
|
become: true
|
|
become_user: "{{ llama_server_user }}"
|
|
ansible.builtin.command:
|
|
argv: "{{ __llama_sync_argv__ }}"
|
|
environment:
|
|
HF_TOKEN: "{{ lookup('env', 'HF_TOKEN') | default('', true) }}"
|
|
register: __llama_sync_output__
|
|
changed_when: false
|
|
|
|
- name: Parse llama server sync output
|
|
ansible.builtin.set_fact:
|
|
__llama_sync_result__: "{{ __llama_sync_output__.stdout | from_json }}"
|
|
|
|
- name: Stat llama router preset file (when not in dry-run mode)
|
|
become: true
|
|
become_user: "{{ llama_server_user }}"
|
|
ansible.builtin.stat:
|
|
path: "{{ llama_server_home }}/models/.router/models.ini"
|
|
register: __llama_preset_stat__
|
|
when: not (llama_server_models_dry_run | default(false))
|
|
|
|
- name: Ensure router preset file exists when not in dry-run mode
|
|
ansible.builtin.assert:
|
|
that:
|
|
- __llama_preset_stat__.stat.exists
|
|
fail_msg: "llama router preset file was not created"
|
|
when: not (llama_server_models_dry_run | default(false))
|
|
|
|
- name: Query llama router model list
|
|
ansible.builtin.uri:
|
|
url: "http://127.0.0.1:{{ llama_server_port | default(8080) }}/models?reload=1"
|
|
method: GET
|
|
status_code: 200
|
|
register: __llama_router_models__
|
|
changed_when: false
|
|
when:
|
|
- llama_server_models_sync_enabled | default(true)
|
|
- not (llama_server_models_dry_run | default(false))
|
|
|
|
- name: Validate expected model aliases are available in router
|
|
ansible.builtin.assert:
|
|
that:
|
|
- item.name in (__llama_router_models__.json.data | map(attribute='id') | list)
|
|
fail_msg: "Model name '{{ item.name }}' not present in llama router /models output"
|
|
loop: "{{ __llama_sync_result__.models | default([]) }}"
|
|
loop_control:
|
|
label: "{{ item.name }}"
|
|
when:
|
|
- llama_server_models_sync_enabled | default(true)
|
|
- not (llama_server_models_dry_run | default(false))
|
|
|
|
- name: Include Llama Exporter setup
|
|
when: llama_server_exporter_enabled | default(true) | bool
|
|
ansible.builtin.include_tasks: llama_exporter.yml
|
|
tags:
|
|
- roles::llama_server::llama_exporter
|
|
|
|
- name: Remove temporary sudo access
|
|
become: true
|
|
ansible.builtin.file:
|
|
path: "/etc/sudoers.d/ansible_{{ llama_server_user }}_tmp"
|
|
state: absent
|