feat(alloy): add journal relabeling and kottos integration on puck

Introduce structured journal relabel rules on puck to tag Pallas-managed
units with {service, project, component} labels matching the Mnemosyne
and Daedalus schema. Add kottos release variable and vault secrets
example entries for the new Pallas FastAgent runtime.

Remove the defunct mnemosyne syslog listener now that Mnemosyne ships
JSON logs via the docker-socket pipeline.
This commit is contained in:
2026-05-11 13:54:14 -04:00
parent e92ab80bbf
commit 8c95173705
19 changed files with 1336 additions and 27 deletions

192
ansible/kottos/deploy.yml Normal file
View File

@@ -0,0 +1,192 @@
---
- name: Deploy Kottos (Pallas FastAgent runtime)
hosts: ubuntu
vars:
ansible_common_remote_group: "{{ kottos_group | default([]) }}"
allow_world_readable_tmpfiles: true
tasks:
- name: Check if host has kottos service
ansible.builtin.set_fact:
has_kottos_service: "{{ 'kottos' in services | default([]) }}"
- name: Skip hosts without kottos service
ansible.builtin.meta: end_host
when: not has_kottos_service
- name: Create Kottos group
become: true
ansible.builtin.group:
name: "{{ kottos_group }}"
state: present
- name: Create kottos user
become: true
ansible.builtin.user:
name: "{{ kottos_user }}"
group: "{{ kottos_group }}"
home: "/home/{{ kottos_user }}"
shell: /bin/bash
system: false
create_home: true
- name: Add keeper_user to kottos group (optional — enables passwordless tailing)
become: true
ansible.builtin.user:
name: "{{ keeper_user }}"
groups: "{{ kottos_group }}"
append: true
when: keeper_user is defined
- name: Reset connection to pick up new group membership
ansible.builtin.meta: reset_connection
- name: Create Kottos install directory
become: true
ansible.builtin.file:
path: "{{ kottos_directory }}"
owner: "{{ kottos_user }}"
group: "{{ kottos_group }}"
state: directory
mode: '0750'
- name: Ensure base packages for Python + Docker MCP workflows
become: true
ansible.builtin.apt:
name:
- tar
- python3
- python3-venv
- python3-dev
- git
state: present
update_cache: true
- name: Transfer and unarchive Kottos release
become: true
ansible.builtin.unarchive:
src: "~/rel/kottos_{{ kottos_rel }}.tar"
dest: "{{ kottos_directory }}"
owner: "{{ kottos_user }}"
group: "{{ kottos_group }}"
mode: '0550'
notify: restart kottos
- name: Ensure .venv directory ownership is correct
become: true
ansible.builtin.file:
path: "{{ kottos_directory }}/.venv"
owner: "{{ kottos_user }}"
group: "{{ kottos_group }}"
state: directory
recurse: true
when: ansible_facts['file'] is defined or true
- name: Create virtual environment for Kottos
become: true
become_user: "{{ kottos_user }}"
ansible.builtin.command:
cmd: "python3 -m venv {{ kottos_directory }}/.venv/"
creates: "{{ kottos_directory }}/.venv/bin/activate"
- name: Install wheel in the virtualenv
become: true
become_user: "{{ kottos_user }}"
ansible.builtin.pip:
name:
- wheel
state: latest
virtualenv: "{{ kottos_directory }}/.venv"
- name: Install Kottos (pyproject.toml — pulls in pallas-mcp and fast-agent-mcp)
become: true
become_user: "{{ kottos_user }}"
ansible.builtin.pip:
chdir: "{{ kottos_directory }}/kottos"
name: .
virtualenv: "{{ kottos_directory }}/.venv"
virtualenv_command: python3 -m venv
notify: restart kottos
- name: Template agents.yaml
become: true
ansible.builtin.template:
src: agents.yaml.j2
dest: "{{ kottos_directory }}/agents.yaml"
owner: "{{ kottos_user }}"
group: "{{ kottos_group }}"
mode: '0640'
notify: restart kottos
- name: Template fastagent.config.yaml
become: true
ansible.builtin.template:
src: fastagent.config.yaml.j2
dest: "{{ kottos_directory }}/fastagent.config.yaml"
owner: "{{ kottos_user }}"
group: "{{ kottos_group }}"
mode: '0640'
notify: restart kottos
- name: Template fastagent.secrets.yaml (vault-rendered)
become: true
ansible.builtin.template:
src: fastagent.secrets.yaml.j2
dest: "{{ kottos_directory }}/fastagent.secrets.yaml"
owner: "{{ kottos_user }}"
group: "{{ kottos_group }}"
mode: '0600'
notify: restart kottos
no_log: true
- name: Template runtime .env (PALLAS_LOG_STDOUT etc.)
become: true
ansible.builtin.template:
src: .env.j2
dest: "{{ kottos_directory }}/.env"
owner: "{{ kottos_user }}"
group: "{{ kottos_group }}"
mode: '0640'
notify: restart kottos
- name: Template systemd unit
become: true
ansible.builtin.template:
src: kottos.service.j2
dest: /etc/systemd/system/kottos.service
owner: root
group: root
mode: '0644'
notify: restart kottos
- name: Enable and start kottos service
become: true
ansible.builtin.systemd:
name: kottos
enabled: true
state: started
daemon_reload: true
- name: Flush handlers before validation probes
ansible.builtin.meta: flush_handlers
# ── Validation ──────────────────────────────────────────────────────────
# Registry is the only endpoint that responds with a deterministic JSON
# payload without requiring an MCP session, so we probe it. Agent ports
# are exercised by Daedalus's health-poll loop once registered.
- name: Validate Kottos registry responds
ansible.builtin.uri:
url: "http://localhost:{{ kottos_registry_port | default(24100) }}/.well-known/mcp/server.json"
status_code: 200
return_content: true
register: registry_check
retries: 10
delay: 3
until: registry_check.status == 200
handlers:
- name: restart kottos
become: true
ansible.builtin.systemd:
name: kottos
state: restarted