homelab/orchestration/ansible/playbooks/paperclip-openclaw.yml
Dan V deb6c38d7b chore: commit homelab setup — deployment, services, orchestration, skill
- Add .gitignore: exclude compiled binaries, build artifacts, and Helm
  values files containing real secrets (authentik, prometheus)
- Add all Kubernetes deployment manifests (deployment/)
- Add services source code: ha-sync, device-inventory, games-console,
  paperclip, parts-inventory
- Add Ansible orchestration: playbooks, roles, inventory, cloud-init
- Add hardware specs, execution plans, scripts, HOMELAB.md
- Add skills/homelab/SKILL.md + skills/install.sh to preserve Copilot skill
- Remove previously-tracked inventory-cli binary from git index

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-04-09 08:10:32 +02:00

124 lines
No EOL
3.8 KiB
YAML

---
- name: Deploy Paperclip on openclaw
hosts: openclaw
become: true
gather_facts: true
vars:
paperclip_user: dan
paperclip_home: /home/dan
paperclip_config_path: /home/dan/.paperclip/instances/default/config.json
paperclip_logs_dir: /home/dan/.paperclip/instances/default/logs
paperclip_service_name: paperclip
paperclip_host: "0.0.0.0"
paperclip_port: 3100
paperclip_allowed_hostnames:
- "192.168.2.88"
- "openclaw"
tasks:
- name: Ensure Paperclip logs directory exists
ansible.builtin.file:
path: "{{ paperclip_logs_dir }}"
state: directory
owner: "{{ paperclip_user }}"
group: "{{ paperclip_user }}"
mode: "0755"
- name: Ensure Paperclip config has LAN authenticated private mode
ansible.builtin.shell: |
python3 - <<'PY'
import json
from pathlib import Path
config_path = Path("{{ paperclip_config_path }}")
if not config_path.exists():
raise SystemExit(f"Missing config file: {config_path}")
data = json.loads(config_path.read_text())
server = data.setdefault("server", {})
before = json.dumps(server, sort_keys=True)
server["deploymentMode"] = "authenticated"
server["exposure"] = "private"
server["host"] = "{{ paperclip_host }}"
server["port"] = {{ paperclip_port }}
allowed = set(server.get("allowedHostnames", []))
allowed.update({{ paperclip_allowed_hostnames | to_json }})
server["allowedHostnames"] = sorted(allowed)
server["serveUi"] = True
after = json.dumps(server, sort_keys=True)
if before != after:
config_path.write_text(json.dumps(data, indent=2) + "\n")
print("changed")
else:
print("unchanged")
PY
args:
executable: /bin/bash
register: paperclip_config_update
changed_when: "'changed' in paperclip_config_update.stdout"
- name: Ensure Paperclip systemd service is installed
ansible.builtin.copy:
dest: /etc/systemd/system/{{ paperclip_service_name }}.service
owner: root
group: root
mode: "0644"
content: |
[Unit]
Description=Paperclip Server
After=network-online.target
Wants=network-online.target
[Service]
Type=simple
User={{ paperclip_user }}
Group={{ paperclip_user }}
WorkingDirectory={{ paperclip_home }}
Environment=HOME={{ paperclip_home }}
Environment=PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
ExecStart=/usr/bin/env npx -y paperclipai run
Restart=always
RestartSec=3
TimeoutStopSec=20
[Install]
WantedBy=multi-user.target
notify: Restart Paperclip
- name: Ensure UFW allows Paperclip port when enabled
community.general.ufw:
rule: allow
port: "{{ paperclip_port | string }}"
proto: tcp
when: ansible_os_family == "Debian"
- name: Ensure Paperclip service is enabled and running
ansible.builtin.systemd:
name: "{{ paperclip_service_name }}"
daemon_reload: true
enabled: true
state: started
- name: Wait for Paperclip health endpoint
ansible.builtin.uri:
url: "http://{{ ansible_host }}:{{ paperclip_port }}/api/health"
method: GET
return_content: true
register: paperclip_health
retries: 10
delay: 3
until: paperclip_health.status == 200
- name: Show health response
ansible.builtin.debug:
var: paperclip_health.json
handlers:
- name: Restart Paperclip
ansible.builtin.systemd:
name: "{{ paperclip_service_name }}"
daemon_reload: true
state: restarted