diff --git a/roles/vhosts/acp_server_codex/tasks/config.yml b/roles/vhosts/acp_server_codex/tasks/config.yml index 65e353d..962feaf 100644 --- a/roles/vhosts/acp_server_codex/tasks/config.yml +++ b/roles/vhosts/acp_server_codex/tasks/config.yml @@ -38,10 +38,21 @@ changed_when: true become: true -- name: Upload XWorkmate Go ACP server binary - ansible.builtin.copy: - src: "{{ acp_codex_bridge_local_binary_path }}" - dest: "{{ acp_codex_bridge_binary_path }}" +- name: Download XWorkmate Bridge release archive + ansible.builtin.get_url: + url: "https://github.com/ai-workspace-lab/xworkmate-bridge/releases/latest/download/xworkmate-bridge-{{ ansible_system | lower }}-{{ 'amd64' if ansible_architecture in ['x86_64', 'amd64'] else 'arm64' }}.tar.gz" + dest: "/tmp/xworkmate-bridge.tar.gz" + mode: "0644" + when: not (acp_codex_bridge_use_prebuilt | bool) + +- name: Extract XWorkmate Go ACP server binary + ansible.builtin.unarchive: + src: "/tmp/xworkmate-bridge.tar.gz" + dest: "{{ acp_codex_bridge_binary_path | dirname }}" + remote_src: true + extra_opts: + - "--strip-components=2" + - "xworkmate-bridge/bin/xworkmate-go-core" owner: root group: root mode: "0755" diff --git a/roles/vhosts/acp_server_gemini/tasks/config.yml b/roles/vhosts/acp_server_gemini/tasks/config.yml index 144b6b2..17e5e2f 100644 --- a/roles/vhosts/acp_server_gemini/tasks/config.yml +++ b/roles/vhosts/acp_server_gemini/tasks/config.yml @@ -38,16 +38,27 @@ changed_when: true become: true -- name: Upload XWorkmate Go ACP adapter binary for Gemini - ansible.builtin.copy: - src: "{{ acp_gemini_bridge_local_binary_path }}" - dest: "{{ acp_gemini_bridge_binary_path }}" +- name: Download XWorkmate Bridge release archive for Gemini + ansible.builtin.get_url: + url: "https://github.com/ai-workspace-lab/xworkmate-bridge/releases/latest/download/xworkmate-bridge-{{ ansible_system | lower }}-{{ 'amd64' if ansible_architecture in ['x86_64', 'amd64'] else 'arm64' }}.tar.gz" + dest: "/tmp/xworkmate-bridge-gemini.tar.gz" + mode: "0644" + when: not (acp_gemini_bridge_use_prebuilt | bool) + +- name: Extract XWorkmate Go ACP adapter binary for Gemini + ansible.builtin.unarchive: + src: "/tmp/xworkmate-bridge-gemini.tar.gz" + dest: "{{ acp_gemini_bridge_binary_path | dirname }}" + remote_src: true + extra_opts: + - "--strip-components=2" + - "xworkmate-bridge/bin/xworkmate-go-core" owner: "{{ omit if ansible_os_family == 'Darwin' else acp_gemini_service_user }}" group: "{{ omit if ansible_os_family == 'Darwin' else acp_gemini_service_group }}" mode: "0755" notify: Restart acp gemini - when: not (acp_gemini_bridge_use_prebuilt | bool) become: true + when: not (acp_gemini_bridge_use_prebuilt | bool) - name: Restore immutable flag on Gemini bridge binary ansible.builtin.command: diff --git a/roles/vhosts/acp_server_opencode/tasks/config.yml b/roles/vhosts/acp_server_opencode/tasks/config.yml index 05d09d6..46069ac 100644 --- a/roles/vhosts/acp_server_opencode/tasks/config.yml +++ b/roles/vhosts/acp_server_opencode/tasks/config.yml @@ -37,10 +37,21 @@ changed_when: true become: true -- name: Upload XWorkmate Go ACP server binary for OpenCode - ansible.builtin.copy: - src: "{{ acp_opencode_bridge_local_binary_path }}" - dest: "{{ acp_opencode_bridge_binary_path }}" +- name: Download XWorkmate Bridge release archive for OpenCode + ansible.builtin.get_url: + url: "https://github.com/ai-workspace-lab/xworkmate-bridge/releases/latest/download/xworkmate-bridge-{{ ansible_system | lower }}-{{ 'amd64' if ansible_architecture in ['x86_64', 'amd64'] else 'arm64' }}.tar.gz" + dest: "/tmp/xworkmate-bridge-opencode.tar.gz" + mode: "0644" + when: not (acp_opencode_bridge_use_prebuilt | bool) + +- name: Extract XWorkmate Go ACP server binary for OpenCode + ansible.builtin.unarchive: + src: "/tmp/xworkmate-bridge-opencode.tar.gz" + dest: "{{ acp_opencode_bridge_binary_path | dirname }}" + remote_src: true + extra_opts: + - "--strip-components=2" + - "xworkmate-bridge/bin/xworkmate-go-core" owner: root group: root mode: "0755" diff --git a/roles/vhosts/gateway_openclaw/defaults/main.yml b/roles/vhosts/gateway_openclaw/defaults/main.yml index f400c99..6f93586 100644 --- a/roles/vhosts/gateway_openclaw/defaults/main.yml +++ b/roles/vhosts/gateway_openclaw/defaults/main.yml @@ -25,13 +25,10 @@ gateway_openclaw_install_dir: "{{ gateway_openclaw_home }}/.local/lib/node_modul gateway_openclaw_required_version: "2026.6.1" gateway_openclaw_npm_package_spec: "openclaw@{{ gateway_openclaw_required_version }}" gateway_openclaw_global_npm_dir: "{{ gateway_openclaw_home }}/.openclaw/npm" -gateway_openclaw_multi_session_plugin_package_spec: "github:x-evor/openclaw-multi-session-plugins#main" +gateway_openclaw_multi_session_plugin_archive_url: "https://github.com/ai-workspace-lab/openclaw-multi-session-plugins/releases/latest/download/openclaw-multi-session-plugins-runtime-all.tar.gz" gateway_openclaw_required_global_plugins: - name: "@openclaw/codex" version: "{{ gateway_openclaw_required_version }}" - - name: "openclaw-multi-session-plugins" - version: "{{ gateway_openclaw_required_version }}" - package_spec: "{{ gateway_openclaw_multi_session_plugin_package_spec }}" gateway_openclaw_removed_global_plugins: - "@openclaw/acpx" gateway_openclaw_extension_dependency_dirs: [] diff --git a/roles/vhosts/gateway_openclaw/tasks/main.yml b/roles/vhosts/gateway_openclaw/tasks/main.yml index 185e140..d8aa6eb 100644 --- a/roles/vhosts/gateway_openclaw/tasks/main.yml +++ b/roles/vhosts/gateway_openclaw/tasks/main.yml @@ -90,6 +90,32 @@ - not ansible_check_mode notify: Restart openclaw gateway +- name: Ensure OpenClaw extensions directory exists + ansible.builtin.file: + path: "{{ gateway_openclaw_home }}/.openclaw/extensions" + state: directory + owner: "{{ gateway_openclaw_service_user }}" + group: "{{ gateway_openclaw_service_group }}" + mode: "0755" + become: "{{ ansible_os_family != 'Darwin' }}" + +- name: Download OpenClaw Multi-Session Plugins offline archive + ansible.builtin.get_url: + url: "{{ gateway_openclaw_multi_session_plugin_archive_url }}" + dest: "/tmp/openclaw-multi-session-plugins.tar.gz" + mode: "0644" + +- name: Extract OpenClaw Multi-Session Plugins + ansible.builtin.unarchive: + src: "/tmp/openclaw-multi-session-plugins.tar.gz" + dest: "{{ gateway_openclaw_home }}/.openclaw/extensions" + remote_src: true + owner: "{{ gateway_openclaw_service_user }}" + group: "{{ gateway_openclaw_service_group }}" + mode: "0755" + become: "{{ ansible_os_family != 'Darwin' }}" + notify: Restart openclaw gateway + - name: Ensure OpenClaw global plugin npm directory exists ansible.builtin.file: path: "{{ gateway_openclaw_global_npm_dir }}" diff --git a/setup-xworkspace-console.yaml b/setup-xworkspace-console.yaml index 374d482..5a3e336 100644 --- a/setup-xworkspace-console.yaml +++ b/setup-xworkspace-console.yaml @@ -13,24 +13,14 @@ xworkspace_console_home: "{{ ansible_env.HOME | default('/home/ubuntu') }}" xworkspace_console_root: "{{ xworkspace_console_home }}/.local/state/ai-workspace" xworkspace_console_repo_dir: "{{ xworkspace_console_home }}/xworkspace-console" - xworkspace_console_source_repo: "https://github.com/ai-workspace-lab/xworkspace-console.git" - xworkspace_console_source_version: "main" - xworkspace_console_source_repo_safe_dir: >- - {{ - (xworkspace_console_source_repo | regex_replace('^file://', '')) - if xworkspace_console_source_repo is match('^file://') - else '' - }} xworkspace_console_runtime_archive: "{{ lookup('ansible.builtin.env', 'XWORKSPACE_CONSOLE_RUNTIME_ARCHIVE') | default('', true) }}" ai_workspace_prebuilt_components_required: "{{ lookup('ansible.builtin.env', 'AI_WORKSPACE_PREBUILT_COMPONENTS_REQUIRED') | default('false', true) | bool }}" xworkspace_console_dashboard_dir: "{{ xworkspace_console_repo_dir }}/dashboard" xworkspace_console_api_dir: "{{ xworkspace_console_repo_dir }}/api" xworkspace_console_api_binary: "{{ xworkspace_console_repo_dir }}/bin/xworkspace-api" xworkspace_console_runtime_marker: "{{ xworkspace_console_repo_dir }}/.runtime-archive-sha256" - xworkspace_console_api_working_dir: >- - {{ xworkspace_console_repo_dir if xworkspace_console_runtime_archive | length > 0 else xworkspace_console_api_dir }} - xworkspace_console_api_exec: >- - {{ xworkspace_console_api_binary if xworkspace_console_runtime_archive | length > 0 else '/usr/bin/env go run .' }} + xworkspace_console_api_working_dir: "{{ xworkspace_console_repo_dir }}" + xworkspace_console_api_exec: "{{ xworkspace_console_api_binary }}" xworkspace_console_scripts_dir: "{{ xworkspace_console_root }}/scripts" xworkspace_console_config_dir: "{{ xworkspace_console_home }}/.config/xworkspace" xworkspace_console_url: http://127.0.0.1:17000 @@ -498,36 +488,54 @@ --disable-sync \ --new-window + - name: Download XWorkspace Console runtime release + ansible.builtin.get_url: + url: "https://github.com/ai-workspace-lab/xworkspace-console/releases/latest/download/xworkspace-console-runtime-{{ ansible_system | lower }}-{{ 'amd64' if ansible_architecture in ['x86_64', 'amd64'] else 'arm64' }}.tar.gz" + dest: "/tmp/xworkspace-console-runtime.tar.gz" + mode: "0644" + force: true + when: xworkspace_console_runtime_archive | length == 0 + + - name: Set runtime archive path + ansible.builtin.set_fact: + xworkspace_console_runtime_archive_resolved: "{{ xworkspace_console_runtime_archive if (xworkspace_console_runtime_archive | length > 0) else '/tmp/xworkspace-console-runtime.tar.gz' }}" + - name: Validate packaged XWorkspace Console runtime ansible.builtin.stat: - path: "{{ xworkspace_console_runtime_archive }}" + path: "{{ xworkspace_console_runtime_archive_resolved }}" register: xworkspace_console_runtime_archive_stat - when: xworkspace_console_runtime_archive | length > 0 - name: Require packaged XWorkspace Console runtime ansible.builtin.assert: that: - - xworkspace_console_runtime_archive | length > 0 - xworkspace_console_runtime_archive_stat.stat.exists | default(false) - fail_msg: "A valid XWORKSPACE_CONSOLE_RUNTIME_ARCHIVE is required in prebuilt-only mode." - when: ai_workspace_prebuilt_components_required + fail_msg: "A valid XWORKSPACE_CONSOLE_RUNTIME_ARCHIVE is required or download failed." - name: Inspect installed XWorkspace Console runtime marker ansible.builtin.slurp: path: "{{ xworkspace_console_runtime_marker }}" register: xworkspace_console_runtime_marker_content failed_when: false - when: xworkspace_console_runtime_archive | length > 0 + + - name: Stop xworkspace-console services before extracting + ansible.builtin.shell: | + uid="$(id -u {{ xworkspace_console_user }})" + systemctl start "user@${uid}.service" || true + for svc in xworkspace-status.timer xworkspace-status.service xworkspace-console.service; do + runuser -u {{ xworkspace_console_user }} -- env XDG_RUNTIME_DIR="/run/user/${uid}" DBUS_SESSION_BUS_ADDRESS="unix:path=/run/user/${uid}/bus" systemctl --user stop "$svc" || true + done + become: true + changed_when: false + when: ansible_os_family != 'Darwin' - name: Install packaged XWorkspace Console runtime ansible.builtin.unarchive: - src: "{{ xworkspace_console_runtime_archive }}" + src: "{{ xworkspace_console_runtime_archive_resolved }}" dest: "{{ xworkspace_console_repo_dir | dirname }}" remote_src: true owner: "{{ xworkspace_console_user }}" group: "{{ 'staff' if ansible_os_family == 'Darwin' else xworkspace_console_user }}" when: - - xworkspace_console_runtime_archive | length > 0 - xworkspace_console_runtime_archive_stat.stat.exists | default(false) - >- (xworkspace_console_runtime_marker_content.content | default('') | b64decode | trim) @@ -543,91 +551,8 @@ mode: "0644" content: "{{ xworkspace_console_runtime_archive_stat.stat.checksum }}\n" when: - - xworkspace_console_runtime_archive | length > 0 - xworkspace_console_runtime_archive_stat.stat.exists | default(false) - - name: Trust local XWorkspace Console source repository for Git - ansible.builtin.command: - argv: - - git - - config - - --global - - --add - - safe.directory - - "{{ xworkspace_console_source_repo_safe_dir }}" - become_user: "{{ xworkspace_console_user }}" - changed_when: false - when: - - xworkspace_console_runtime_archive | length == 0 - - xworkspace_console_source_repo_safe_dir | length > 0 - - - name: Trust local XWorkspace Console source repository .git directory for Git - ansible.builtin.command: - argv: - - git - - config - - --global - - --add - - safe.directory - - "{{ xworkspace_console_source_repo_safe_dir }}/.git" - become_user: "{{ xworkspace_console_user }}" - changed_when: false - when: - - xworkspace_console_runtime_archive | length == 0 - - xworkspace_console_source_repo_safe_dir | length > 0 - - - name: Stop xworkspace-status timer and services to avoid write conflict on Linux - ansible.builtin.shell: | - uid="$(id -u {{ xworkspace_console_user }})" - systemctl start "user@${uid}.service" || true - for svc in xworkspace-status.timer xworkspace-status.service xworkspace-console.service; do - runuser -u {{ xworkspace_console_user }} -- env XDG_RUNTIME_DIR="/run/user/${uid}" DBUS_SESSION_BUS_ADDRESS="unix:path=/run/user/${uid}/bus" systemctl --user stop "$svc" || true - done - become: true - changed_when: false - when: - - ansible_os_family != 'Darwin' - - xworkspace_console_runtime_archive | length == 0 - - - name: Remove stale xworkspace-console repo to avoid shallow checkout failures - ansible.builtin.file: - path: "{{ xworkspace_console_repo_dir }}" - state: absent - become_user: "{{ xworkspace_console_user }}" - when: - - xworkspace_console_runtime_archive | length == 0 - - - name: Clone xworkspace-console repository - ansible.builtin.git: - repo: "{{ xworkspace_console_source_repo }}" - dest: "{{ xworkspace_console_repo_dir }}" - version: "{{ xworkspace_console_source_version }}" - force: true - depth: 1 - become_user: "{{ xworkspace_console_user }}" - register: xworkspace_console_source_checkout - when: xworkspace_console_runtime_archive | length == 0 - - - name: Build dashboard assets on target - ansible.builtin.shell: | - set -euo pipefail - cd "{{ xworkspace_console_dashboard_dir }}" - source_commit="$(git -C "{{ xworkspace_console_repo_dir }}" rev-parse HEAD)" - marker=".ai-workspace-build-commit" - if [ -f "dist/index.html" ] && [ "$(cat "$marker" 2>/dev/null || true)" = "$source_commit" ]; then - echo "build=unchanged" - exit 0 - fi - npm install && npm run build - printf '%s\n' "$source_commit" > "$marker" - echo "build=changed" - args: - executable: /bin/bash - become_user: "{{ xworkspace_console_user }}" - register: xworkspace_console_dashboard_build - changed_when: "'build=changed' in (xworkspace_console_dashboard_build.stdout | default(''))" - when: xworkspace_console_runtime_archive | length == 0 - - name: Deploy AI Workspace portal service configuration ansible.builtin.copy: dest: "{{ xworkspace_console_config_dir }}/portal-services.json"