--- # Post-provisioning customizations for OpenClaw VMs # Run after playbooks/install.yml to apply host-specific tweaks # # Usage: # ansible-playbook -i inventory.yml playbooks/customize.yml # ansible-playbook -i inventory.yml playbooks/customize.yml --limit zap # # Per-host variables (set in host_vars/.yml): # brew_packages: [] # list of Homebrew packages to install - name: OpenClaw VM customizations hosts: openclaw_servers become: true tasks: - name: Set vm.swappiness=10 (live) ansible.posix.sysctl: name: vm.swappiness value: "10" state: present reload: true - name: Persist vm.swappiness in /etc/sysctl.conf ansible.builtin.lineinfile: path: /etc/sysctl.conf regexp: '^vm\.swappiness' line: 'vm.swappiness=10' state: present # ── swarm-common virtiofs share ──────────────────────────────────────── # Host: ~/lab/swarm/swarm-common → Guest: /mnt/swarm-common # Virtiofs is mounted raw to /mnt/swarm-common-raw, then bindfs remaps # ownership to openclaw before presenting at /mnt/swarm-common. - name: Create swarm-common raw virtiofs mount point ansible.builtin.file: path: /mnt/swarm-common-raw state: directory mode: "0755" - name: Create swarm-common bindfs mount point ansible.builtin.file: path: /mnt/swarm-common state: directory mode: "0755" - name: Install bindfs (for virtiofs ownership remapping) ansible.builtin.apt: name: bindfs state: present - name: Add swarm-common virtiofs entry to fstab ansible.posix.mount: path: /mnt/swarm-common-raw src: swarm-common fstype: virtiofs opts: defaults state: present - name: Add swarm-common bindfs entry to fstab ansible.posix.mount: path: /mnt/swarm-common src: "bindfs#/mnt/swarm-common-raw" fstype: fuse opts: "force-user=openclaw,force-group=openclaw,perms=a+rX,create-for-user=openclaw,create-for-group=openclaw" state: present - name: Ensure openclaw user lingering is enabled (for user systemd services) ansible.builtin.command: cmd: loginctl enable-linger openclaw changed_when: false # ── Homebrew ─────────────────────────────────────────────────────────── - name: Install Homebrew dependencies ansible.builtin.apt: name: - build-essential - procps - curl - file - git state: present - name: Pre-create /home/linuxbrew owned by openclaw ansible.builtin.file: path: /home/linuxbrew state: directory owner: openclaw group: openclaw mode: "0755" - name: Install Homebrew (as openclaw user) ansible.builtin.shell: | NONINTERACTIVE=1 /bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)" become_user: openclaw args: creates: /home/linuxbrew/.linuxbrew/bin/brew - name: Add Homebrew to openclaw user PATH ansible.builtin.blockinfile: path: /home/openclaw/.bashrc marker: "# {mark} HOMEBREW" block: | eval "$(/home/linuxbrew/.linuxbrew/bin/brew shellenv)" owner: openclaw group: openclaw create: true - name: Install Homebrew packages ansible.builtin.shell: | brew list {{ item }} 2>/dev/null || brew install {{ item }} become_user: openclaw environment: HOME: /home/openclaw PATH: /home/linuxbrew/.linuxbrew/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin loop: "{{ brew_packages | default([]) }}" register: brew_install changed_when: "'Installing' in brew_install.stdout" # ── Automatic security updates ───────────────────────────────────────── # The upstream role installs unattended-upgrades with security-only updates. # We extend it here to enable automatic reboots for kernel/libc updates, # scheduled at 04:00 — after the 03:00 backup and the Sunday 03:10 e2scrub. - name: Ensure unattended-upgrades is installed ansible.builtin.apt: name: - unattended-upgrades - apt-listchanges state: present - name: Configure unattended-upgrades ansible.builtin.copy: dest: /etc/apt/apt.conf.d/50unattended-upgrades mode: "0644" content: | // OpenClaw VM — automatic security updates Unattended-Upgrade::Allowed-Origins { "${distro_id}:${distro_codename}-security"; "${distro_id}ESMApps:${distro_codename}-apps-security"; "${distro_id}ESM:${distro_codename}-infra-security"; }; Unattended-Upgrade::Package-Blacklist {}; Unattended-Upgrade::AutoFixInterruptedDpkg "true"; Unattended-Upgrade::MinimalSteps "true"; Unattended-Upgrade::Remove-Unused-Dependencies "true"; Unattended-Upgrade::Remove-New-Unused-Dependencies "true"; Unattended-Upgrade::Remove-Unused-Kernel-Packages "true"; // Reboot at 04:00 if required (after 03:00 backup + Sunday 03:10 e2scrub) Unattended-Upgrade::Automatic-Reboot "true"; Unattended-Upgrade::Automatic-Reboot-Time "04:00"; notify: Restart unattended-upgrades - name: Enable daily apt update and upgrade triggers ansible.builtin.copy: dest: /etc/apt/apt.conf.d/20auto-upgrades mode: "0644" content: | APT::Periodic::Update-Package-Lists "1"; APT::Periodic::Unattended-Upgrade "1"; APT::Periodic::AutocleanInterval "7"; - name: Ensure unattended-upgrades service is running and enabled ansible.builtin.systemd: name: unattended-upgrades state: started enabled: true handlers: - name: Restart unattended-upgrades ansible.builtin.systemd: name: unattended-upgrades state: restarted