--- - name: Deploy Agent S Computer Use Agent hosts: agent_s become: yes vars: system_user: "{{ ansible_user }}" agent_s_venv: "/home/{{ system_user }}/env/agents" agent_s_repo: "/home/{{ system_user }}/gh/Agent-S" chrome_deb_url: "https://dl.google.com/linux/direct/google-chrome-stable_current_amd64.deb" tasks: # Disable snap - doesn't work in containers with AppArmor disabled - name: Prevent snapd from being installed copy: dest: /etc/apt/preferences.d/nosnap.pref content: | Package: snapd Pin: release a=* Pin-Priority: -10 mode: '0644' - name: Update apt cache apt: update_cache: yes cache_valid_time: 3600 # Firefox Setup, must be in place before desktop install to remove snap dependency - name: Create APT keyrings directory file: path: /etc/apt/keyrings state: directory mode: '0755' - name: Download Mozilla APT signing key get_url: url: https://packages.mozilla.org/apt/repo-signing-key.gpg dest: /etc/apt/keyrings/packages.mozilla.org.asc mode: '0644' - name: Add Mozilla APT repository apt_repository: repo: "deb [signed-by=/etc/apt/keyrings/packages.mozilla.org.asc] https://packages.mozilla.org/apt mozilla main" filename: mozilla state: present - name: Set Firefox package priority to prefer Mozilla repo copy: dest: /etc/apt/preferences.d/mozilla content: | Package: * Pin: origin packages.mozilla.org Pin-Priority: 1000 mode: '0644' - name: Update apt cache after adding Mozilla repo apt: update_cache: yes - name: Install Firefox from Mozilla repo apt: name: firefox state: present # Desktop Environment - MATE for better AT-SPI accessibility support - name: Install MATE desktop environment apt: name: - ubuntu-mate-desktop state: present # AT-SPI Accessibility Stack - name: Install AT-SPI accessibility infrastructure apt: name: - at-spi2-core - libatk-adaptor - libatk1.0-0 - libatk-bridge2.0-0 state: present - name: Configure AT-SPI environment for accessibility copy: dest: /etc/profile.d/atspi.sh content: | # Enable AT-SPI accessibility bridge export GTK_MODULES=gail:atk-bridge export NO_AT_BRIDGE=0 export ACCESSIBILITY_ENABLED=1 mode: '0644' - name: Configure GPU environment for direct rendering copy: dest: /etc/profile.d/gpu.sh content: | # Force GPU rendering via AMD render node export DRI_PRIME=1 export LIBVA_DRIVER_NAME=radeonsi export MESA_LOADER_DRIVER_OVERRIDE=radeonsi # Chrome/Chromium GPU flags export CHROMIUM_FLAGS="--enable-gpu-rasterization --enable-zero-copy --use-gl=egl" mode: '0644' # Sound Support - name: Install sound support packages apt: name: - git - libpulse-dev - autoconf - m4 - intltool - build-essential - dpkg-dev state: present # Mouse, Assistive Technology, and Python - name: Install assistive technology and Python packages apt: name: - python3-tk - python3-dev - python3-pyatspi - python3-gi - gnome-screenshot - python3-venv - python3-pip state: present # OCR - name: Install OCR support apt: name: - tesseract-ocr state: present # GPU Drivers - AMD Mesa (radeonsi/RADV) - name: Install AMD GPU drivers and utilities apt: name: - mesa-utils - mesa-utils-extra - mesa-vulkan-drivers - vulkan-tools - libgl1-mesa-dri - libglx-mesa0 - libglu1-mesa - libdrm2 - libdrm-amdgpu1 - libegl1 - libegl-mesa0 - libgbm1 - vainfo - mesa-va-drivers state: present # VirtualGL for GPU-accelerated remote rendering - name: Check if VirtualGL is installed command: dpkg -s virtualgl register: virtualgl_check failed_when: false changed_when: false - name: Download VirtualGL get_url: url: https://github.com/VirtualGL/virtualgl/releases/download/3.1.2/virtualgl_3.1.2_amd64.deb dest: /tmp/virtualgl.deb mode: '0644' when: virtualgl_check.rc != 0 - name: Install VirtualGL apt: deb: /tmp/virtualgl.deb state: present when: virtualgl_check.rc != 0 # GPU Permissions - Add user to video and render groups for DRI access - name: Add user to video group for GPU access user: name: "{{ system_user }}" groups: video append: yes - name: Add user to render group for GPU render node access user: name: "{{ system_user }}" groups: render append: yes - name: Create udev rules for GPU device permissions copy: dest: /etc/udev/rules.d/99-gpu-permissions.rules content: | # Allow video group access to DRI devices SUBSYSTEM=="drm", KERNEL=="card*", MODE="0666" SUBSYSTEM=="drm", KERNEL=="renderD*", MODE="0666" mode: '0644' notify: Reload udev # Fix GPU permissions on container start (LXC passthrough doesn't honor udev) - name: Create systemd service to fix GPU permissions on boot copy: dest: /etc/systemd/system/fix-gpu-permissions.service content: | [Unit] Description=Fix GPU device permissions for LXC passthrough After=local-fs.target [Service] Type=oneshot ExecStart=/bin/chmod 666 /dev/dri/card2 /dev/dri/renderD129 RemainAfterExit=yes [Install] WantedBy=multi-user.target mode: '0644' notify: Reload systemd - name: Enable GPU permissions fix service systemd: name: fix-gpu-permissions enabled: yes state: started daemon_reload: yes # Create dl directory - name: Create download directory become: no file: path: "/home/{{ system_user }}/dl" state: directory mode: '0755' # Chrome Installation - name: Download Google Chrome get_url: url: "{{ chrome_deb_url }}" dest: /tmp/google-chrome-stable_current_amd64.deb mode: '0644' - name: Install Google Chrome apt: deb: /tmp/google-chrome-stable_current_amd64.deb state: present - name: Clean up Chrome installer file: path: /tmp/google-chrome-stable_current_amd64.deb state: absent # Chrome GPU Configuration - Use ANGLE+Vulkan to bypass broken GLX in XRDP - name: Create Chrome policies directory file: path: /etc/opt/chrome/policies/managed state: directory mode: '0755' - name: Configure Chrome GPU policy copy: dest: /etc/opt/chrome/policies/managed/gpu-policy.json content: | { "HardwareAccelerationModeEnabled": true } mode: '0644' - name: Create Chrome Vulkan launcher copy: dest: /usr/share/applications/google-chrome-vulkan.desktop content: | [Desktop Entry] Version=1.0 Name=Google Chrome (Vulkan) GenericName=Web Browser Exec=/usr/bin/google-chrome-stable --ignore-gpu-blocklist --use-gl=angle --use-angle=vulkan --enable-features=Vulkan,DefaultANGLEVulkan,VulkanFromANGLE,CanvasOopRasterization --enable-gpu-rasterization --canvas-oop-rasterization %U Terminal=false Icon=google-chrome Type=Application Categories=Network;WebBrowser; mode: '0644' # Python Virtual Environment Setup - name: Create virtual environment directory become: no file: path: "/home/{{ system_user }}/env" state: directory mode: '0755' - name: Create Python virtual environment with system site packages become: no command: python3 -m venv --system-site-packages {{ agent_s_venv }} args: creates: "{{ agent_s_venv }}/bin/activate" - name: Install Python packages in virtual environment become: no pip: name: - lxml - pillow - setuptools virtualenv: "{{ agent_s_venv }}" state: present # Clone Agent-S Repository - name: Create gh directory become: no file: path: "/home/{{ system_user }}/gh" state: directory mode: '0755' - name: Clone Agent-S repository become: no git: repo: https://github.com/simular-ai/Agent-S.git dest: "{{ agent_s_repo }}" version: main update: yes - name: Create environment activation script become: no template: src: agent_s_env.j2 dest: "/home/{{ system_user }}/.agent_s_env" mode: '0644' - name: Create XRDP Xorg config directory file: path: /etc/X11/xrdp state: directory mode: '0755' - name: Deploy XRDP Xorg configuration for 1024x1024 resolution template: src: xorg.conf.j2 dest: /etc/X11/xrdp/xorg.conf mode: '0644' handlers: - name: Reload systemd systemd: daemon_reload: yes - name: Reload udev shell: udevadm control --reload-rules && udevadm trigger become: yes