--- - name: Deploy Agent S Computer Use Agent hosts: agent_s become: yes vars: agent_s_venv: "/home/{{principal_user}}/env/agents" agent_s_repo: "/home/{{principal_user}}/gh/Agent-S" chrome_deb_url: "https://dl.google.com/linux/direct/google-chrome-stable_current_amd64.deb" build_dir: "/usr/local/src/pulseaudio-module-xrdp" tasks: # ------------------------------------------------------------------------- # Principal user - AI agent operates on behalf of this human user # Must exist before any become_user tasks can run # ------------------------------------------------------------------------- - name: Create principal_user account user: name: "{{principal_user}}" uid: 1000 shell: /bin/bash create_home: true state: present # 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 # ------------------------------------------------------------------------- # XRDP - Remote Desktop Protocol server # ------------------------------------------------------------------------- - name: Install XRDP and xorgxrdp apt: name: - xrdp - xorgxrdp state: present - name: Add xrdp user to ssl-cert group user: name: xrdp groups: ssl-cert append: yes - name: Enable and start XRDP service systemd: name: xrdp enabled: yes state: started daemon_reload: yes # 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' # ------------------------------------------------------------------------- # Sound Support - PulseAudio + module-xrdp for RDP audio redirection # ------------------------------------------------------------------------- - name: Install sound support and build dependencies apt: name: - git - pulseaudio - libpulse-dev - autoconf - m4 - intltool - build-essential - dpkg-dev - meson - ninja-build state: present - name: Enable deb-src repositories for PulseAudio source shell: | sed -i '/^Types: deb$/s/$/ deb-src/' /etc/apt/sources.list.d/ubuntu.sources 2>/dev/null || \ find /etc/apt/sources.list.d/ -name '*.sources' -exec sed -i '/^Types: deb$/s/$/ deb-src/' {} \; args: creates: /usr/local/src/.deb_src_enabled register: deb_src_result - name: Mark deb-src as enabled file: path: /usr/local/src/.deb_src_enabled state: touch mode: '0644' when: deb_src_result.changed - name: Update apt cache after enabling deb-src apt: update_cache: yes when: deb_src_result.changed - name: Install PulseAudio build dependencies apt: name: pulseaudio state: build-dep when: deb_src_result.changed - name: Create build directory file: path: /usr/local/src state: directory mode: '0755' - name: Download PulseAudio source shell: | cd /usr/local/src && apt-get source pulseaudio args: creates: /usr/local/src/.pulseaudio_source_downloaded - name: Find PulseAudio source directory shell: ls -d /usr/local/src/pulseaudio-[0-9]*/ register: pulse_src_dir changed_when: false - name: Mark PulseAudio source as downloaded file: path: /usr/local/src/.pulseaudio_source_downloaded state: touch mode: '0644' - name: Generate PulseAudio config.h with meson shell: meson setup build args: chdir: "{{ pulse_src_dir.stdout | trim }}" creates: "{{ pulse_src_dir.stdout | trim }}/build/config.h" - name: Create build directory for pulseaudio-module-xrdp file: path: "{{ build_dir }}" state: directory mode: '0755' - name: Transfer and extract pulseaudio-module-xrdp source ansible.builtin.unarchive: src: "~/rel/pulseaudio_module_xrdp_{{pulseaudio_module_xrdp_rel}}.tar" dest: "{{ build_dir }}" - name: Check if module-xrdp-sink is already installed shell: find /usr/lib/pulse-*/modules/ -name 'module-xrdp-sink.so' 2>/dev/null | head -1 register: xrdp_sink_check changed_when: false failed_when: false - name: Bootstrap pulseaudio-module-xrdp shell: ./bootstrap args: chdir: "{{ build_dir }}" when: xrdp_sink_check.stdout == "" - name: Configure pulseaudio-module-xrdp shell: "./configure PULSE_DIR={{ pulse_src_dir.stdout | trim }}" args: chdir: "{{ build_dir }}" when: xrdp_sink_check.stdout == "" - name: Build and install pulseaudio-module-xrdp shell: make && make install args: chdir: "{{ build_dir }}" when: xrdp_sink_check.stdout == "" notify: restart xrdp # 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 # Create dl directory - name: Create download directory become_user: "{{principal_user}}" file: path: "/home/{{principal_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 # Python Virtual Environment Setup - name: Create virtual environment directory become_user: "{{principal_user}}" file: path: "/home/{{principal_user}}/env" state: directory mode: '0755' - name: Create Python virtual environment with system site packages become_user: "{{principal_user}}" 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_user: "{{principal_user}}" pip: name: - lxml - pillow - setuptools virtualenv: "{{ agent_s_venv }}" state: present # Clone Agent-S Repository - name: Create gh directory become_user: "{{principal_user}}" file: path: "/home/{{principal_user}}/gh/Agent-S" state: directory mode: '0755' - name: Transfer and extract Agent-S become_user: "{{principal_user}}" ansible.builtin.unarchive: src: "~/rel/agent_s_{{agent_s_rel}}.tar" dest: "{{ agent_s_repo }}" - name: Create environment activation script become_user: "{{principal_user}}" template: src: agent_s_env.j2 dest: "/home/{{principal_user}}/.agent_s_env" mode: '0644' - name: Create XRDP Xorg config directory file: path: /etc/X11/xrdp state: directory mode: '0755' - name: Configure MATE as XRDP session for principal_user become_user: "{{principal_user}}" copy: dest: "/home/{{principal_user}}/.xsession" content: "exec mate-session\n" mode: '0755' - name: Deploy XRDP Xorg configuration for 1024x768 resolution template: src: xorg.conf.j2 dest: /etc/X11/xrdp/xorg.conf mode: '0644' notify: restart xrdp handlers: - name: Reload systemd systemd: daemon_reload: yes - name: Reload udev shell: udevadm control --reload-rules && udevadm trigger become: yes - name: restart xrdp systemd: name: xrdp state: restarted