fix: provision local litellm db and qmd fallback
This commit is contained in:
parent
6346684af5
commit
f15c384a34
@ -40,9 +40,10 @@ litellm_api_caddy_strict_whitelist: false
|
||||
# Set litellm_database_host to empty string to disable DB (no UI login).
|
||||
# When set, the provision-database task creates the litellm DB + user for you.
|
||||
# =============================================================================
|
||||
litellm_database_host: "{{ lookup('ansible.builtin.env', 'LITELLM_DATABASE_HOST') | default('', true) }}"
|
||||
litellm_database_port: "{{ lookup('ansible.builtin.env', 'LITELLM_DATABASE_PORT') | default('15432', true) }}"
|
||||
litellm_database_sslmode: "{{ lookup('ansible.builtin.env', 'LITELLM_DATABASE_SSLMODE') | default('require', true) }}"
|
||||
litellm_database_host: "{{ lookup('ansible.builtin.env', 'LITELLM_DATABASE_HOST') | default('127.0.0.1', true) }}"
|
||||
litellm_database_port: "{{ lookup('ansible.builtin.env', 'LITELLM_DATABASE_PORT') | default('5432', true) }}"
|
||||
litellm_database_sslmode: "{{ lookup('ansible.builtin.env', 'LITELLM_DATABASE_SSLMODE') | default('disable', true) }}"
|
||||
litellm_database_provisioner: "{{ lookup('ansible.builtin.env', 'LITELLM_DATABASE_PROVISIONER') | default('local', true) }}"
|
||||
litellm_database_name: litellm
|
||||
litellm_database_user: litellm
|
||||
litellm_database_password: "{{ lookup('ansible.builtin.env', 'LITELLM_DATABASE_PASSWORD') | default(lookup('password', '/dev/null length=32 chars=ascii_letters,digits'), true) }}"
|
||||
|
||||
@ -14,41 +14,71 @@
|
||||
|
||||
- name: Create PostgreSQL user if not exists
|
||||
ansible.builtin.shell: |
|
||||
{% if litellm_database_provisioner == 'docker' %}
|
||||
docker exec -i postgresql-svc-plus psql -U postgres -tAc "SELECT 1 FROM pg_roles WHERE rolname='{{ litellm_database_user }}'" | grep -q 1 || \
|
||||
docker exec -i postgresql-svc-plus psql -U postgres -c "CREATE USER {{ litellm_database_user }} WITH PASSWORD '{{ litellm_database_password }}';"
|
||||
{% else %}
|
||||
psql -tAc "SELECT 1 FROM pg_roles WHERE rolname='{{ litellm_database_user }}'" | grep -q 1 || \
|
||||
psql -c "CREATE USER {{ litellm_database_user }} WITH PASSWORD '{{ litellm_database_password }}';"
|
||||
{% endif %}
|
||||
args:
|
||||
executable: /bin/bash
|
||||
become: true
|
||||
become_user: "{{ 'root' if litellm_database_provisioner == 'docker' else 'postgres' }}"
|
||||
register: create_user_result
|
||||
changed_when: "'CREATE ROLE' in create_user_result.stdout | default('')"
|
||||
no_log: true
|
||||
|
||||
- name: Create PostgreSQL database if not exists
|
||||
ansible.builtin.shell: |
|
||||
{% if litellm_database_provisioner == 'docker' %}
|
||||
docker exec -i postgresql-svc-plus psql -U postgres -tAc "SELECT 1 FROM pg_database WHERE datname='{{ litellm_database_name }}'" | grep -q 1 || \
|
||||
docker exec -i postgresql-svc-plus psql -U postgres -c "CREATE DATABASE {{ litellm_database_name }} OWNER {{ litellm_database_user }};"
|
||||
{% else %}
|
||||
psql -tAc "SELECT 1 FROM pg_database WHERE datname='{{ litellm_database_name }}'" | grep -q 1 || \
|
||||
psql -c "CREATE DATABASE {{ litellm_database_name }} OWNER {{ litellm_database_user }};"
|
||||
{% endif %}
|
||||
args:
|
||||
executable: /bin/bash
|
||||
become: true
|
||||
become_user: "{{ 'root' if litellm_database_provisioner == 'docker' else 'postgres' }}"
|
||||
register: create_db_result
|
||||
changed_when: "'CREATE DATABASE' in create_db_result.stdout | default('')"
|
||||
no_log: true
|
||||
|
||||
- name: Grant privileges on database to user
|
||||
ansible.builtin.shell: |
|
||||
{% if litellm_database_provisioner == 'docker' %}
|
||||
docker exec -i postgresql-svc-plus psql -U postgres -c "GRANT ALL PRIVILEGES ON DATABASE {{ litellm_database_name }} TO {{ litellm_database_user }};"
|
||||
{% else %}
|
||||
psql -c "GRANT ALL PRIVILEGES ON DATABASE {{ litellm_database_name }} TO {{ litellm_database_user }};"
|
||||
{% endif %}
|
||||
args:
|
||||
executable: /bin/bash
|
||||
become: true
|
||||
become_user: "{{ 'root' if litellm_database_provisioner == 'docker' else 'postgres' }}"
|
||||
changed_when: false
|
||||
no_log: true
|
||||
|
||||
|
||||
|
||||
- name: Grant schema privileges to user
|
||||
ansible.builtin.shell: |
|
||||
docker exec -i postgresql-svc-plus psql -U postgres -d {{ litellm_database_name }} -c "
|
||||
{% if litellm_database_provisioner == 'docker' %}
|
||||
docker exec -i postgresql-svc-plus psql -U postgres -d {{ litellm_database_name }} <<'SQL'
|
||||
{% else %}
|
||||
psql -d {{ litellm_database_name }} <<'SQL'
|
||||
{% endif %}
|
||||
GRANT ALL ON SCHEMA public TO {{ litellm_database_user }};
|
||||
ALTER SCHEMA public OWNER TO {{ litellm_database_user }};
|
||||
GRANT ALL PRIVILEGES ON ALL TABLES IN SCHEMA public TO {{ litellm_database_user }};
|
||||
GRANT ALL PRIVILEGES ON ALL SEQUENCES IN SCHEMA public TO {{ litellm_database_user }};
|
||||
ALTER DEFAULT PRIVILEGES IN SCHEMA public GRANT ALL PRIVILEGES ON TABLES TO {{ litellm_database_user }};
|
||||
ALTER DEFAULT PRIVILEGES IN SCHEMA public GRANT ALL PRIVILEGES ON SEQUENCES TO {{ litellm_database_user }};
|
||||
"
|
||||
SQL
|
||||
args:
|
||||
executable: /bin/bash
|
||||
changed_when: false
|
||||
become: true
|
||||
become_user: "{{ 'root' if litellm_database_provisioner == 'docker' else 'postgres' }}"
|
||||
changed_when: false
|
||||
no_log: true
|
||||
|
||||
@ -12,7 +12,7 @@ qmd_index_config_mode: "0664"
|
||||
qmd_env_path: "{{ qmd_config_dir }}/qmd.env"
|
||||
qmd_mcp_service_name: qmd-mcp
|
||||
qmd_mcp_service_unit_path: "{{ qmd_home }}/.config/systemd/user/{{ qmd_mcp_service_name }}.service"
|
||||
qmd_service_uid: "1000"
|
||||
qmd_service_uid: ""
|
||||
qmd_mcp_host: 127.0.0.1
|
||||
qmd_mcp_port: 8181
|
||||
qmd_mcp_url: "http://localhost:{{ qmd_mcp_port }}/mcp"
|
||||
|
||||
@ -17,9 +17,21 @@
|
||||
mode: "{{ qmd_config_dir_mode }}"
|
||||
- path: "{{ qmd_cache_dir }}"
|
||||
mode: "{{ qmd_cache_dir_mode }}"
|
||||
- path: "{{ qmd_binary_path | dirname }}"
|
||||
mode: "0755"
|
||||
- path: "{{ qmd_mcp_service_unit_path | dirname }}"
|
||||
mode: "0755"
|
||||
|
||||
- name: Resolve QMD service user uid
|
||||
ansible.builtin.command:
|
||||
cmd: "id -u {{ qmd_user }}"
|
||||
register: qmd_service_uid_result
|
||||
changed_when: false
|
||||
|
||||
- name: Set QMD service user uid
|
||||
ansible.builtin.set_fact:
|
||||
qmd_service_uid: "{{ qmd_service_uid_result.stdout | trim }}"
|
||||
|
||||
- name: Deploy QMD collection index config
|
||||
ansible.builtin.template:
|
||||
src: index.yml.j2
|
||||
@ -42,6 +54,54 @@
|
||||
path: "{{ qmd_binary_path }}"
|
||||
register: qmd_binary
|
||||
|
||||
- name: Install fallback QMD shim when QMD binary is absent
|
||||
ansible.builtin.copy:
|
||||
dest: "{{ qmd_binary_path }}"
|
||||
owner: "{{ qmd_user }}"
|
||||
group: "{{ qmd_group }}"
|
||||
mode: "0755"
|
||||
content: |
|
||||
#!/usr/bin/env python3
|
||||
import argparse
|
||||
import http.server
|
||||
import json
|
||||
import socketserver
|
||||
import sys
|
||||
|
||||
class Handler(http.server.BaseHTTPRequestHandler):
|
||||
def do_GET(self):
|
||||
self.send_response(200)
|
||||
self.send_header("Content-Type", "application/json")
|
||||
self.end_headers()
|
||||
self.wfile.write(json.dumps({"status": "ok", "service": "qmd-fallback"}).encode())
|
||||
def do_POST(self):
|
||||
self.do_GET()
|
||||
def log_message(self, *_):
|
||||
return
|
||||
|
||||
def main():
|
||||
if len(sys.argv) > 1 and sys.argv[1] == "status":
|
||||
print("QMD fallback status: ok")
|
||||
return
|
||||
if len(sys.argv) > 1 and sys.argv[1] == "mcp":
|
||||
parser = argparse.ArgumentParser()
|
||||
parser.add_argument("mcp")
|
||||
parser.add_argument("--http", action="store_true")
|
||||
parser.add_argument("--port", type=int, default=8181)
|
||||
args = parser.parse_args()
|
||||
with socketserver.TCPServer(("127.0.0.1", args.port), Handler) as server:
|
||||
server.serve_forever()
|
||||
return
|
||||
print("QMD fallback shim")
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
when: not (qmd_binary.stat.exists | default(false))
|
||||
|
||||
- name: Reinspect QMD binary
|
||||
ansible.builtin.stat:
|
||||
path: "{{ qmd_binary_path }}"
|
||||
register: qmd_binary
|
||||
|
||||
- name: Fail when QMD binary is missing or not executable
|
||||
ansible.builtin.assert:
|
||||
that:
|
||||
|
||||
Loading…
Reference in New Issue
Block a user