fix: remove stale repo + depth=1 for clone; macOS browser/npm/agent_skills/role defaults compatibility

This commit is contained in:
Haitao Pan 2026-06-19 11:37:33 +08:00
parent e4aa8affee
commit edc70fb658
31 changed files with 165 additions and 135 deletions

View File

@ -42,18 +42,14 @@
register: ai_agent_runtime_pandoc_version register: ai_agent_runtime_pandoc_version
changed_when: false changed_when: false
check_mode: false check_mode: false
when: when: ai_agent_runtime_docs_enabled | bool
- ansible_facts.os_family == "Debian"
- ai_agent_runtime_docs_enabled | bool
- name: Check xelatex version - name: Check xelatex version
ansible.builtin.command: xelatex --version ansible.builtin.command: xelatex --version
register: ai_agent_runtime_xelatex_version register: ai_agent_runtime_xelatex_version
changed_when: false changed_when: false
check_mode: false check_mode: false
when: when: ai_agent_runtime_docs_enabled | bool
- ansible_facts.os_family == "Debian"
- ai_agent_runtime_docs_enabled | bool
- name: Check Chinese font inventory - name: Check Chinese font inventory
ansible.builtin.command: fc-list :lang=zh family ansible.builtin.command: fc-list :lang=zh family
@ -61,7 +57,6 @@
changed_when: false changed_when: false
check_mode: false check_mode: false
when: when:
- ansible_facts.os_family == "Debian"
- ai_agent_runtime_fonts_enabled | bool - ai_agent_runtime_fonts_enabled | bool
- ai_agent_runtime_verify_chinese_fonts | bool - ai_agent_runtime_verify_chinese_fonts | bool
@ -71,7 +66,6 @@
- ai_agent_runtime_chinese_fonts.stdout | length > 0 - ai_agent_runtime_chinese_fonts.stdout | length > 0
fail_msg: "No Chinese fonts were discovered by fontconfig." fail_msg: "No Chinese fonts were discovered by fontconfig."
when: when:
- ansible_facts.os_family == "Debian"
- ai_agent_runtime_fonts_enabled | bool - ai_agent_runtime_fonts_enabled | bool
- ai_agent_runtime_verify_chinese_fonts | bool - ai_agent_runtime_verify_chinese_fonts | bool

View File

@ -42,8 +42,8 @@
ansible.builtin.copy: ansible.builtin.copy:
src: "{{ acp_codex_bridge_local_binary_path }}" src: "{{ acp_codex_bridge_local_binary_path }}"
dest: "{{ acp_codex_bridge_binary_path }}" dest: "{{ acp_codex_bridge_binary_path }}"
owner: "{{ omit if ansible_os_family == 'Darwin' else 'root' }}" owner: root
group: "{{ omit if ansible_os_family == 'Darwin' else 'root' }}" group: root
mode: "0755" mode: "0755"
when: not (acp_codex_bridge_use_prebuilt | bool) when: not (acp_codex_bridge_use_prebuilt | bool)
@ -61,7 +61,6 @@
path: "{{ item }}" path: "{{ item }}"
state: absent state: absent
loop: "{{ acp_codex_obsolete_caddy_fragment_paths }}" loop: "{{ acp_codex_obsolete_caddy_fragment_paths }}"
when: ansible_os_family != 'Darwin'
notify: Reload caddy notify: Reload caddy
- name: Deploy Caddy main file - name: Deploy Caddy main file
@ -73,7 +72,6 @@
mode: "0644" mode: "0644"
notify: Reload caddy notify: Reload caddy
when: when:
- ansible_os_family != 'Darwin'
- acp_codex_manage_caddy | bool - acp_codex_manage_caddy | bool
- name: Deploy Codex ACP systemd service - name: Deploy Codex ACP systemd service

View File

@ -2,7 +2,6 @@
- name: Install Codex ACP prerequisites - name: Install Codex ACP prerequisites
ansible.builtin.import_tasks: install.yml ansible.builtin.import_tasks: install.yml
tags: [acp_codex, acp_codex_install] tags: [acp_codex, acp_codex_install]
when: ansible_os_family != 'Darwin'
- name: Configure Codex ACP service and Caddy - name: Configure Codex ACP service and Caddy
ansible.builtin.import_tasks: config.yml ansible.builtin.import_tasks: config.yml
@ -17,4 +16,3 @@
tags: [acp_codex, acp_codex_validate] tags: [acp_codex, acp_codex_validate]
when: when:
- not ansible_check_mode - not ansible_check_mode
- ansible_os_family != 'Darwin'

View File

@ -1,15 +1,13 @@
--- ---
acp_gemini_service_name: acp-gemini acp_gemini_service_name: acp-gemini
acp_gemini_service_user: "{{ ansible_env.USER | default('ubuntu') if ansible_os_family == 'Darwin' else 'ubuntu' }}" acp_gemini_service_user: ubuntu
acp_gemini_service_group: "{{ 'staff' if ansible_os_family == 'Darwin' else 'ubuntu' }}" acp_gemini_service_group: ubuntu
acp_gemini_home: "{{ ansible_env.HOME | default('/home/' + acp_gemini_service_user) if ansible_os_family == 'Darwin' else '/home/ubuntu' }}" acp_gemini_home: /home/ubuntu
acp_gemini_workdir: "{{ acp_gemini_home }}/.gemini" acp_gemini_workdir: /home/ubuntu/.gemini
acp_gemini_xdg_config_home: "{{ acp_gemini_home }}/.config" acp_gemini_xdg_config_home: /home/ubuntu/.config
acp_gemini_xdg_state_home: "{{ acp_gemini_home }}/.local/state" acp_gemini_xdg_state_home: /home/ubuntu/.local/state
acp_gemini_config_dir: "{{ acp_gemini_home }}/.gemini" acp_gemini_config_dir: /home/ubuntu/.gemini
acp_gemini_npm_global_bin: "{{ acp_gemini_home + '/.local/bin' if ansible_os_family == 'Darwin' else '/usr/bin' }}" acp_gemini_binary_path: /usr/bin/antigravity-cli
acp_gemini_binary_path: "{{ acp_gemini_npm_global_bin }}/gemini"
acp_gemini_path: "{{ acp_gemini_npm_global_bin }}:/opt/homebrew/bin:/opt/homebrew/sbin:/usr/local/bin:/usr/local/sbin:/usr/bin:/bin"
acp_gemini_args: --experimental-acp acp_gemini_args: --experimental-acp
acp_gemini_bridge_local_source_dir: "{{ playbook_dir }}/../xworkmate-bridge" acp_gemini_bridge_local_source_dir: "{{ playbook_dir }}/../xworkmate-bridge"
acp_gemini_bridge_local_build_dir: "{{ playbook_dir }}/.artifacts/acp_gemini" acp_gemini_bridge_local_build_dir: "{{ playbook_dir }}/.artifacts/acp_gemini"

View File

@ -42,8 +42,8 @@
ansible.builtin.copy: ansible.builtin.copy:
src: "{{ acp_gemini_bridge_local_binary_path }}" src: "{{ acp_gemini_bridge_local_binary_path }}"
dest: "{{ acp_gemini_bridge_binary_path }}" dest: "{{ acp_gemini_bridge_binary_path }}"
owner: "{{ omit if ansible_os_family == 'Darwin' else acp_gemini_service_user }}" owner: "{{ acp_gemini_service_user }}"
group: "{{ omit if ansible_os_family == 'Darwin' else acp_gemini_service_group }}" group: "{{ acp_gemini_service_group }}"
mode: "0755" mode: "0755"
notify: Restart acp gemini notify: Restart acp gemini
when: not (acp_gemini_bridge_use_prebuilt | bool) when: not (acp_gemini_bridge_use_prebuilt | bool)

View File

@ -2,7 +2,6 @@
- name: Install Gemini ACP prerequisites - name: Install Gemini ACP prerequisites
ansible.builtin.import_tasks: install.yml ansible.builtin.import_tasks: install.yml
tags: [acp_gemini, acp_gemini_install] tags: [acp_gemini, acp_gemini_install]
when: ansible_os_family != 'Darwin'
- name: Configure Gemini ACP adapter - name: Configure Gemini ACP adapter
ansible.builtin.import_tasks: config.yml ansible.builtin.import_tasks: config.yml
@ -17,4 +16,3 @@
tags: [acp_gemini, acp_gemini_validate] tags: [acp_gemini, acp_gemini_validate]
when: when:
- not ansible_check_mode - not ansible_check_mode
- ansible_os_family != 'Darwin'

View File

@ -19,7 +19,7 @@ Environment=GEMINI_ADAPTER_ALLOWED_ORIGINS={{ acp_gemini_allowed_origins | join(
Environment={{ key }}={{ value }} Environment={{ key }}={{ value }}
{% endif %} {% endif %}
{% endfor %} {% endfor %}
ExecStart={{ acp_gemini_bridge_binary_path }} adapter gemini --listen {{ acp_gemini_listen_host }}:{{ acp_gemini_listen_port }} --gemini-bin {{ acp_gemini_binary_path }} --gemini-args "{{ acp_gemini_args }}" ExecStart={{ acp_gemini_bridge_binary_path }} adapter antigravity-cli --listen {{ acp_gemini_listen_host }}:{{ acp_gemini_listen_port }} --antigravity-cli-bin {{ acp_gemini_binary_path }} --antigravity-cli-args "{{ acp_gemini_args }}"
Restart=always Restart=always
RestartSec=2 RestartSec=2

View File

@ -18,7 +18,7 @@
exec "{{ acp_gemini_bridge_binary_path }}" acp-server \ exec "{{ acp_gemini_bridge_binary_path }}" acp-server \
--port {{ acp_gemini_listen_port }} \ --port {{ acp_gemini_listen_port }} \
--host {{ acp_gemini_listen_host }} \ --host {{ acp_gemini_listen_host }} \
--sub-command gemini \ --sub-command antigravity-cli \
--sub-command mcp-app-server --sub-command mcp-app-server
</string> </string>
</array> </array>

View File

@ -9,16 +9,15 @@ acp_hermes_bridge_build_goarch: "{{ 'arm64' if ansible_architecture in ['aarch64
acp_hermes_bridge_use_prebuilt: "{{ lookup('ansible.builtin.env', 'AI_WORKSPACE_USE_PREBUILT_BRIDGE') | default('false', true) | bool }}" acp_hermes_bridge_use_prebuilt: "{{ lookup('ansible.builtin.env', 'AI_WORKSPACE_USE_PREBUILT_BRIDGE') | default('false', true) | bool }}"
acp_hermes_listen_host: 127.0.0.1 acp_hermes_listen_host: 127.0.0.1
acp_hermes_listen_port: 3920 acp_hermes_listen_port: 3920
acp_hermes_service_user: "{{ ansible_env.USER | default('ubuntu') if ansible_os_family == 'Darwin' else 'ubuntu' }}" acp_hermes_service_user: ubuntu
acp_hermes_service_group: "{{ 'staff' if ansible_os_family == 'Darwin' else 'ubuntu' }}" acp_hermes_service_group: ubuntu
acp_hermes_bridge_binary_path: /usr/local/bin/xworkmate-go-core acp_hermes_bridge_binary_path: /usr/local/bin/xworkmate-go-core
acp_hermes_home: "{{ ansible_env.HOME | default('/home/' + acp_hermes_service_user) if ansible_os_family == 'Darwin' else '/home/ubuntu' }}" acp_hermes_workdir: /home/ubuntu/hermes-agent
acp_hermes_workdir: "{{ acp_hermes_home }}/hermes-agent" acp_hermes_home: /home/ubuntu
acp_hermes_binary_path: "{{ acp_hermes_workdir }}/venv/bin/hermes" acp_hermes_binary_path: /home/ubuntu/hermes-agent/venv/bin/hermes
acp_hermes_path: "{{ acp_hermes_binary_path | dirname }}:/opt/homebrew/bin:/opt/homebrew/sbin:/usr/local/bin:/usr/local/sbin:/usr/bin:/bin"
acp_hermes_args: acp acp_hermes_args: acp
acp_hermes_xdg_config_home: "{{ acp_hermes_home }}/.config" acp_hermes_xdg_config_home: /home/ubuntu/.config
acp_hermes_xdg_state_home: "{{ acp_hermes_home }}/.local/state" acp_hermes_xdg_state_home: /home/ubuntu/.local/state
acp_hermes_allowed_origins: acp_hermes_allowed_origins:
- https://xworkmate.svc.plus - https://xworkmate.svc.plus
- http://localhost:* - http://localhost:*

View File

@ -43,8 +43,8 @@
ansible.builtin.copy: ansible.builtin.copy:
src: "{{ acp_hermes_bridge_local_binary_path }}" src: "{{ acp_hermes_bridge_local_binary_path }}"
dest: "{{ acp_hermes_bridge_binary_path }}" dest: "{{ acp_hermes_bridge_binary_path }}"
owner: "{{ omit if ansible_os_family == 'Darwin' else acp_hermes_service_user }}" owner: "{{ acp_hermes_service_user }}"
group: "{{ omit if ansible_os_family == 'Darwin' else acp_hermes_service_group }}" group: "{{ acp_hermes_service_group }}"
mode: "0755" mode: "0755"
notify: Restart acp hermes notify: Restart acp hermes
when: not (acp_hermes_bridge_use_prebuilt | bool) when: not (acp_hermes_bridge_use_prebuilt | bool)

View File

@ -2,7 +2,6 @@
- name: Install Hermes ACP prerequisites - name: Install Hermes ACP prerequisites
ansible.builtin.import_tasks: install.yml ansible.builtin.import_tasks: install.yml
tags: [acp_hermes, acp_hermes_install] tags: [acp_hermes, acp_hermes_install]
when: ansible_os_family != 'Darwin'
- name: Configure Hermes ACP adapter - name: Configure Hermes ACP adapter
ansible.builtin.import_tasks: config.yml ansible.builtin.import_tasks: config.yml
@ -17,4 +16,3 @@
tags: [acp_hermes, acp_hermes_validate] tags: [acp_hermes, acp_hermes_validate]
when: when:
- not ansible_check_mode - not ansible_check_mode
- ansible_os_family != 'Darwin'

View File

@ -7,8 +7,6 @@ acp_opencode_service_user: "{{ ansible_env.USER | default('ubuntu') }}"
acp_opencode_service_group: "{{ 'staff' if ansible_os_family == 'Darwin' else (ansible_env.USER | default('ubuntu')) }}" acp_opencode_service_group: "{{ 'staff' if ansible_os_family == 'Darwin' else (ansible_env.USER | default('ubuntu')) }}"
acp_opencode_home: "{{ ansible_env.HOME | default('/home/' + acp_opencode_service_user) }}" acp_opencode_home: "{{ ansible_env.HOME | default('/home/' + acp_opencode_service_user) }}"
acp_opencode_workdir: "{{ ansible_env.HOME | default('/home/' + acp_opencode_service_user) }}/.opencode" acp_opencode_workdir: "{{ ansible_env.HOME | default('/home/' + acp_opencode_service_user) }}/.opencode"
acp_opencode_npm_global_bin: "{{ (ansible_env.HOME | default('/home/' + acp_opencode_service_user)) + '/.local/bin' if ansible_os_family == 'Darwin' else '/usr/bin' }}"
acp_opencode_path: "{{ acp_opencode_npm_global_bin }}:/opt/homebrew/bin:/opt/homebrew/sbin:/usr/local/bin:/usr/local/sbin:/usr/bin:/bin"
acp_opencode_listen_host: 127.0.0.1 acp_opencode_listen_host: 127.0.0.1
acp_opencode_listen_port: 38992 acp_opencode_listen_port: 38992
acp_opencode_packages: [] acp_opencode_packages: []

View File

@ -41,8 +41,8 @@
ansible.builtin.copy: ansible.builtin.copy:
src: "{{ acp_opencode_bridge_local_binary_path }}" src: "{{ acp_opencode_bridge_local_binary_path }}"
dest: "{{ acp_opencode_bridge_binary_path }}" dest: "{{ acp_opencode_bridge_binary_path }}"
owner: "{{ omit if ansible_os_family == 'Darwin' else 'root' }}" owner: root
group: "{{ omit if ansible_os_family == 'Darwin' else 'root' }}" group: root
mode: "0755" mode: "0755"
when: not (acp_opencode_bridge_use_prebuilt | bool) when: not (acp_opencode_bridge_use_prebuilt | bool)
@ -76,7 +76,6 @@
mode: "0644" mode: "0644"
notify: Reload caddy notify: Reload caddy
when: when:
- ansible_os_family != 'Darwin'
- acp_opencode_manage_caddy | bool - acp_opencode_manage_caddy | bool
- name: Remove deprecated standalone OpenCode Caddy fragments - name: Remove deprecated standalone OpenCode Caddy fragments
@ -84,7 +83,6 @@
path: "{{ item }}" path: "{{ item }}"
state: absent state: absent
loop: "{{ acp_opencode_obsolete_caddy_fragment_paths }}" loop: "{{ acp_opencode_obsolete_caddy_fragment_paths }}"
when: ansible_os_family != 'Darwin'
notify: Reload caddy notify: Reload caddy
- name: Deploy OpenCode ACP systemd service - name: Deploy OpenCode ACP systemd service

View File

@ -2,7 +2,6 @@
- name: Install OpenCode ACP prerequisites - name: Install OpenCode ACP prerequisites
ansible.builtin.import_tasks: install.yml ansible.builtin.import_tasks: install.yml
tags: [acp_opencode, acp_opencode_install] tags: [acp_opencode, acp_opencode_install]
when: ansible_os_family != 'Darwin'
- name: Configure OpenCode ACP service and Caddy - name: Configure OpenCode ACP service and Caddy
ansible.builtin.import_tasks: config.yml ansible.builtin.import_tasks: config.yml
@ -17,4 +16,3 @@
tags: [acp_opencode, acp_opencode_validate] tags: [acp_opencode, acp_opencode_validate]
when: when:
- not ansible_check_mode - not ansible_check_mode
- ansible_os_family != 'Darwin'

View File

@ -19,6 +19,12 @@ journald_log_rotation: # 启用 journald 日志管理
# 总开关 # 总开关
enable_common: true enable_common: true
# macOS (Darwin) baseline: shared Homebrew CLI prerequisites used by helper
# scripts across roles (e.g. jq is required by vault's init_vault_admin.sh).
# macOS ships curl/base64 already; jq is not present by default.
common_darwin_brew_packages:
- jq
common_firewall: common_firewall:
enabled: true enabled: true
ssh_port: 22 ssh_port: 22

View File

@ -0,0 +1,14 @@
---
# macOS (Darwin) baseline: install shared command-line prerequisites that the
# Linux apt/yum baselines provide elsewhere. These tools are required by helper
# scripts in other roles (e.g. vault's init_vault_admin.sh needs jq), so they
# are installed once here in the common role rather than per-role.
#
# Homebrew installs into /opt/homebrew (Apple Silicon) or /usr/local (Intel);
# `creates` is checked against both so the task stays idempotent on either arch.
- name: Common(Darwin) | install Homebrew prerequisites
ansible.builtin.command: "brew install {{ item }}"
args:
creates: "{{ '/opt/homebrew/bin/' ~ item if ansible_machine == 'arm64' else '/usr/local/bin/' ~ item }}"
loop: "{{ common_darwin_brew_packages }}"
changed_when: true

View File

@ -1,9 +1,16 @@
--- ---
# ===== Base system (always) ===== # ===== Base system (always) =====
# The Base hardening tasks below set timezone (timedatectl), rewrite
# /etc/hostname + /etc/hosts, set the hostname, harden ssh, configure fail2ban,
# raise file limits and open firewall ports. They all run with become: true and
# rely on Linux-only tooling/paths, so they are skipped on macOS (Darwin), where
# the deploy runs unprivileged. macOS prerequisites are handled by
# common_darwin.yml instead.
- name: Base | set timezone - name: Base | set timezone
ansible.builtin.command: "timedatectl set-timezone Asia/Shanghai" ansible.builtin.command: "timedatectl set-timezone Asia/Shanghai"
changed_when: false changed_when: false
become: true become: true
when: ansible_os_family != 'Darwin'
- name: Base | render /etc/hostname - name: Base | render /etc/hostname
ansible.builtin.template: ansible.builtin.template:
@ -13,11 +20,13 @@
group: root group: root
mode: "0644" mode: "0644"
become: true become: true
when: ansible_os_family != 'Darwin'
- name: Base | set hostname - name: Base | set hostname
ansible.builtin.hostname: ansible.builtin.hostname:
name: "{{ inventory_hostname }}" name: "{{ inventory_hostname }}"
become: true become: true
when: ansible_os_family != 'Darwin'
- name: Base | update /etc/hosts - name: Base | update /etc/hosts
ansible.builtin.template: ansible.builtin.template:
@ -27,29 +36,35 @@
group: root group: root
mode: "0644" mode: "0644"
become: true become: true
when: ansible_os_family != 'Darwin'
- name: Base | harden ssh - name: Base | harden ssh
ansible.builtin.script: files/secure_ssh.sh ansible.builtin.script: files/secure_ssh.sh
become: true become: true
when: ansible_os_family != 'Darwin'
- name: Base | harden ssh config - name: Base | harden ssh config
ansible.builtin.import_tasks: harden_ssh.yml ansible.builtin.import_tasks: harden_ssh.yml
tags: [ssh, security] tags: [ssh, security]
when: ansible_os_family != 'Darwin'
- name: Base | configure fail2ban - name: Base | configure fail2ban
ansible.builtin.import_tasks: fail2ban.yml ansible.builtin.import_tasks: fail2ban.yml
tags: [fail2ban, security] tags: [fail2ban, security]
when: ansible_os_family != 'Darwin'
- name: Base | file limits - name: Base | file limits
ansible.builtin.import_tasks: limits.yml ansible.builtin.import_tasks: limits.yml
when: when:
- common_security_limits.enabled | default(true) | bool - common_security_limits.enabled | default(true) | bool
- ansible_os_family != 'Darwin'
tags: [limits, baseline] tags: [limits, baseline]
- name: Base | allow HTTP/HTTPS ports - name: Base | allow HTTP/HTTPS ports
ansible.builtin.import_tasks: firewall_ports.yml ansible.builtin.import_tasks: firewall_ports.yml
when: when:
- common_firewall.enabled | default(true) | bool - common_firewall.enabled | default(true) | bool
- ansible_os_family != 'Darwin'
tags: [firewall, baseline] tags: [firewall, baseline]
# ===== Common baseline (OS split) ===== # ===== Common baseline (OS split) =====
@ -65,6 +80,12 @@
- enable_common | bool - enable_common | bool
- ansible_facts.os_family == "RedHat" - ansible_facts.os_family == "RedHat"
- name: Common | Darwin (macOS) baseline
ansible.builtin.import_tasks: common_darwin.yml
when:
- enable_common | bool
- ansible_facts.os_family == "Darwin"
# ===== Add-ons (default OFF) ===== # ===== Add-ons (default OFF) =====
- name: Addon | S3FS mount - name: Addon | S3FS mount
ansible.builtin.import_tasks: addons/s3fs.yml ansible.builtin.import_tasks: addons/s3fs.yml

View File

@ -37,7 +37,7 @@ gateway_openclaw_config_path: "{{ gateway_openclaw_home }}/.openclaw/openclaw.js
gateway_openclaw_workspace_path: "{{ gateway_openclaw_home }}/.openclaw/workspace" gateway_openclaw_workspace_path: "{{ gateway_openclaw_home }}/.openclaw/workspace"
gateway_openclaw_workspace_mode: "0775" gateway_openclaw_workspace_mode: "0775"
gateway_openclaw_compile_cache_dir: /var/tmp/openclaw-compile-cache gateway_openclaw_compile_cache_dir: /var/tmp/openclaw-compile-cache
gateway_openclaw_service_path: "{{ gateway_openclaw_home }}/.nix-profile/bin:{{ gateway_openclaw_home }}/.local/bin:{{ gateway_openclaw_home }}/.npm-global/bin:{{ gateway_openclaw_home }}/bin:/opt/homebrew/bin:/opt/homebrew/sbin:/usr/local/bin:/usr/local/sbin:/usr/bin:/bin" gateway_openclaw_service_path: "{{ gateway_openclaw_home }}/.nix-profile/bin:{{ gateway_openclaw_home }}/.local/bin:{{ gateway_openclaw_home }}/.npm-global/bin:{{ gateway_openclaw_home }}/bin:/opt/homebrew/bin:/usr/local/bin:/usr/bin:/bin"
gateway_openclaw_extension_backup_dir: "{{ gateway_openclaw_home }}/.openclaw/backups/extensions" gateway_openclaw_extension_backup_dir: "{{ gateway_openclaw_home }}/.openclaw/backups/extensions"
gateway_openclaw_upstream_host: 127.0.0.1 gateway_openclaw_upstream_host: 127.0.0.1

View File

@ -18,11 +18,11 @@
{{ {{
gateway_openclaw_gateway_token gateway_openclaw_gateway_token
if (gateway_openclaw_gateway_token | trim | length > 0) if (gateway_openclaw_gateway_token | trim | length > 0)
else (( else (
( (
gateway_openclaw_existing_config_raw.content | default('') | b64decode | from_json gateway_openclaw_existing_config_raw.content | default('') | b64decode | from_json
).gateway.auth.token | default('') ).gateway.auth.token | default('')
) if (gateway_openclaw_existing_config_raw.content | default('') | length > 0) else '') )
}} }}
no_log: true no_log: true
@ -79,7 +79,7 @@
PATH: "{{ gateway_openclaw_service_path }}" PATH: "{{ gateway_openclaw_service_path }}"
OPENCLAW_NO_RESPAWN: "1" OPENCLAW_NO_RESPAWN: "1"
NODE_COMPILE_CACHE: "{{ gateway_openclaw_compile_cache_dir }}" NODE_COMPILE_CACHE: "{{ gateway_openclaw_compile_cache_dir }}"
become: true become: "{{ ansible_os_family != 'Darwin' }}"
become_user: "{{ gateway_openclaw_service_user }}" become_user: "{{ gateway_openclaw_service_user }}"
register: gateway_openclaw_package_install register: gateway_openclaw_package_install
changed_when: >- changed_when: >-
@ -150,10 +150,6 @@
ansible.builtin.file: ansible.builtin.file:
path: "{{ gateway_openclaw_compile_cache_dir }}" path: "{{ gateway_openclaw_compile_cache_dir }}"
state: absent state: absent
register: gateway_openclaw_compile_cache_reset
retries: 5
delay: 1
until: gateway_openclaw_compile_cache_reset is succeeded
when: when:
- not ansible_check_mode - not ansible_check_mode
- >- - >-
@ -569,7 +565,6 @@
owner: root owner: root
group: root group: root
mode: "0755" mode: "0755"
when: ansible_os_family != 'Darwin'
- name: Inspect Caddy main file attributes - name: Inspect Caddy main file attributes
ansible.builtin.command: ansible.builtin.command:
@ -597,7 +592,6 @@
group: root group: root
mode: "0644" mode: "0644"
state: present state: present
when: ansible_os_family != 'Darwin'
notify: Reload caddy notify: Reload caddy
- name: Restore immutable flag on Caddy main file - name: Restore immutable flag on Caddy main file
@ -632,18 +626,14 @@
owner: root owner: root
group: root group: root
mode: "0644" mode: "0644"
when: when: gateway_openclaw_public_access | bool
- ansible_os_family != 'Darwin'
- gateway_openclaw_public_access | bool
notify: Reload caddy notify: Reload caddy
- name: Remove OpenClaw public Caddy site when public access is disabled - name: Remove OpenClaw public Caddy site when public access is disabled
ansible.builtin.file: ansible.builtin.file:
path: "{{ gateway_openclaw_caddy_fragment_path }}" path: "{{ gateway_openclaw_caddy_fragment_path }}"
state: absent state: absent
when: when: not (gateway_openclaw_public_access | bool)
- ansible_os_family != 'Darwin'
- not (gateway_openclaw_public_access | bool)
notify: Reload caddy notify: Reload caddy
- name: Restore immutable flag on OpenClaw Caddy fragment - name: Restore immutable flag on OpenClaw Caddy fragment

View File

@ -12,9 +12,18 @@
when: ansible_os_family != 'Darwin' when: ansible_os_family != 'Darwin'
- name: Install LiteLLM prerequisites (macOS) - name: Install LiteLLM prerequisites (macOS)
community.general.homebrew: # Use brew from PATH (Apple Silicon prefix first) instead of the
name: python@3.13 # community.general.homebrew module, which can select a stale Intel Homebrew
state: present # at /usr/local that crashes on newer macOS versions. See postgres macos.yml.
ansible.builtin.command: brew install python@3.13
environment:
PATH: "/opt/homebrew/bin:/usr/local/bin:{{ ansible_env.PATH }}"
HOMEBREW_NO_AUTO_UPDATE: "1"
register: litellm_brew_python
changed_when: >-
'already installed' not in (litellm_brew_python.stderr | default(''))
and 'already installed' not in (litellm_brew_python.stdout | default(''))
failed_when: litellm_brew_python.rc != 0
when: ansible_os_family == 'Darwin' when: ansible_os_family == 'Darwin'
- name: Materialize persisted LiteLLM secrets - name: Materialize persisted LiteLLM secrets
@ -68,8 +77,8 @@
ansible.builtin.file: ansible.builtin.file:
path: "{{ litellm_config_dir }}" path: "{{ litellm_config_dir }}"
state: directory state: directory
owner: root owner: "{{ litellm_service_user if ansible_os_family == 'Darwin' else 'root' }}"
group: root group: "{{ litellm_service_group if ansible_os_family == 'Darwin' else 'root' }}"
mode: "0755" mode: "0755"
- name: Provision LiteLLM Database - name: Provision LiteLLM Database
@ -89,8 +98,8 @@
ansible.builtin.template: ansible.builtin.template:
src: litellm.env.j2 src: litellm.env.j2
dest: "{{ litellm_env_file }}" dest: "{{ litellm_env_file }}"
owner: root owner: "{{ litellm_service_user if ansible_os_family == 'Darwin' else 'root' }}"
group: root group: "{{ litellm_service_group if ansible_os_family == 'Darwin' else 'root' }}"
mode: "0600" mode: "0600"
notify: Restart litellm notify: Restart litellm

View File

@ -25,7 +25,11 @@
{% endif %} {% endif %}
args: args:
executable: /bin/bash executable: /bin/bash
become: true environment:
PATH: "/opt/homebrew/opt/postgresql@16/bin:/usr/local/opt/postgresql@16/bin:{{ ansible_env.PATH }}"
# On macOS Homebrew there is no `postgres` system user and no passwordless
# sudo; the current user is the DB superuser, so run psql without escalation.
become: "{{ ansible_os_family != 'Darwin' }}"
become_user: "{{ 'root' if litellm_database_provisioner == 'docker' else 'postgres' }}" become_user: "{{ 'root' if litellm_database_provisioner == 'docker' else 'postgres' }}"
register: create_user_result register: create_user_result
changed_when: "'CREATE ROLE' in create_user_result.stdout | default('')" changed_when: "'CREATE ROLE' in create_user_result.stdout | default('')"
@ -42,7 +46,11 @@
{% endif %} {% endif %}
args: args:
executable: /bin/bash executable: /bin/bash
become: true environment:
PATH: "/opt/homebrew/opt/postgresql@16/bin:/usr/local/opt/postgresql@16/bin:{{ ansible_env.PATH }}"
# On macOS Homebrew there is no `postgres` system user and no passwordless
# sudo; the current user is the DB superuser, so run psql without escalation.
become: "{{ ansible_os_family != 'Darwin' }}"
become_user: "{{ 'root' if litellm_database_provisioner == 'docker' else 'postgres' }}" become_user: "{{ 'root' if litellm_database_provisioner == 'docker' else 'postgres' }}"
register: create_db_result register: create_db_result
changed_when: "'CREATE DATABASE' in create_db_result.stdout | default('')" changed_when: "'CREATE DATABASE' in create_db_result.stdout | default('')"
@ -57,7 +65,11 @@
{% endif %} {% endif %}
args: args:
executable: /bin/bash executable: /bin/bash
become: true environment:
PATH: "/opt/homebrew/opt/postgresql@16/bin:/usr/local/opt/postgresql@16/bin:{{ ansible_env.PATH }}"
# On macOS Homebrew there is no `postgres` system user and no passwordless
# sudo; the current user is the DB superuser, so run psql without escalation.
become: "{{ ansible_os_family != 'Darwin' }}"
become_user: "{{ 'root' if litellm_database_provisioner == 'docker' else 'postgres' }}" become_user: "{{ 'root' if litellm_database_provisioner == 'docker' else 'postgres' }}"
changed_when: false changed_when: false
no_log: true no_log: true
@ -80,7 +92,11 @@
SQL SQL
args: args:
executable: /bin/bash executable: /bin/bash
become: true environment:
PATH: "/opt/homebrew/opt/postgresql@16/bin:/usr/local/opt/postgresql@16/bin:{{ ansible_env.PATH }}"
# On macOS Homebrew there is no `postgres` system user and no passwordless
# sudo; the current user is the DB superuser, so run psql without escalation.
become: "{{ ansible_os_family != 'Darwin' }}"
become_user: "{{ 'root' if litellm_database_provisioner == 'docker' else 'postgres' }}" become_user: "{{ 'root' if litellm_database_provisioner == 'docker' else 'postgres' }}"
changed_when: false changed_when: false
no_log: true no_log: true

View File

@ -1,3 +1,2 @@
dependencies: dependencies:
- role: common - role: common
when: ansible_os_family != 'Darwin'

View File

@ -1,8 +1,19 @@
--- ---
- name: Ensure PostgreSQL 16 is installed via Homebrew - name: Ensure PostgreSQL 16 is installed via Homebrew
community.general.homebrew: # Use brew from PATH (like the vault/openclaw roles) rather than the
name: postgresql@16 # community.general.homebrew module, which auto-detects a brew prefix and can
state: present # pick a stale Intel Homebrew at /usr/local that crashes on newer macOS
# versions ("unknown or unsupported macOS version"). Prepending the Apple
# Silicon prefix selects the working brew when both are installed.
ansible.builtin.command: brew install postgresql@16
environment:
PATH: "/opt/homebrew/bin:/usr/local/bin:{{ ansible_env.PATH }}"
HOMEBREW_NO_AUTO_UPDATE: "1"
register: postgresql_brew_install
changed_when: >-
'already installed' not in (postgresql_brew_install.stderr | default(''))
and 'already installed' not in (postgresql_brew_install.stdout | default(''))
failed_when: postgresql_brew_install.rc != 0
- name: Start PostgreSQL via Homebrew Services - name: Start PostgreSQL via Homebrew Services
ansible.builtin.command: brew services start postgresql@16 ansible.builtin.command: brew services start postgresql@16

View File

@ -139,21 +139,6 @@ vault write "auth/userpass/users/${USERNAME}" \
userpass_accessor="$(vault auth list -format=json | jq -r '."userpass/".accessor')" userpass_accessor="$(vault auth list -format=json | jq -r '."userpass/".accessor')"
entity_id=""
alias_ids_json="$(vault list -format=json identity/entity-alias/id 2>/dev/null || true)"
if [[ -n "$alias_ids_json" && "$alias_ids_json" != "null" ]]; then
while IFS= read -r alias_id; do
alias_json="$(vault read -format=json "identity/entity-alias/id/${alias_id}" 2>/dev/null || true)"
if [[ -z "$alias_json" ]]; then
continue
fi
if printf '%s' "$alias_json" | jq -e --arg username "$USERNAME" --arg accessor "$userpass_accessor" '.data.name == $username and .data.mount_accessor == $accessor' >/dev/null; then
entity_id="$(printf '%s' "$alias_json" | jq -r '.data.canonical_id')"
break
fi
done < <(printf '%s' "$alias_ids_json" | jq -r '.[]?')
fi
methods_json="$(curl -sS \ methods_json="$(curl -sS \
-H "X-Vault-Token: ${VAULT_TOKEN}" \ -H "X-Vault-Token: ${VAULT_TOKEN}" \
-H "X-Vault-Request: true" \ -H "X-Vault-Request: true" \
@ -173,16 +158,29 @@ if [[ -z "$method_id" ]]; then
method_id="$(printf '%s' "$method_json" | jq -r '.data.method_id // .data.id')" method_id="$(printf '%s' "$method_json" | jq -r '.data.method_id // .data.id')"
fi fi
bootstrap_token="" # Resolve the admin's identity entity WITHOUT logging in. Once the login MFA
if [[ -z "$entity_id" || "$entity_id" == "null" ]]; then # enforcement below exists, a userpass login is MFA-gated and returns no
bootstrap_json="$(vault write -format=json "auth/userpass/login/${USERNAME}" password="$PASSWORD")" # entity_id (causing "missing entityID" on every re-run). Instead look up the
entity_id="$(printf '%s' "$bootstrap_json" | jq -r '.auth.entity_id')" # entity via its userpass entity-alias, creating the entity + alias on first run.
bootstrap_token="$(printf '%s' "$bootstrap_json" | jq -r '.auth.client_token')" entity_id=""
fi for alias_id in $(vault list -format=json identity/entity-alias/id 2>/dev/null | jq -r '.[]?'); do
alias_json="$(vault read -format=json "identity/entity-alias/id/${alias_id}" 2>/dev/null || true)"
alias_name="$(printf '%s' "$alias_json" | jq -r '.data.name // empty')"
alias_mount="$(printf '%s' "$alias_json" | jq -r '.data.mount_accessor // empty')"
if [[ "$alias_name" == "$USERNAME" && "$alias_mount" == "$userpass_accessor" ]]; then
entity_id="$(printf '%s' "$alias_json" | jq -r '.data.canonical_id // empty')"
break
fi
done
if [[ -z "$entity_id" || "$entity_id" == "null" ]]; then if [[ -z "$entity_id" ]]; then
echo "unable to resolve Vault entity for userpass user ${USERNAME}" >&2 entity_id="$(vault write -format=json identity/entity \
exit 1 name="$USERNAME" \
policies="$POLICY_NAME" | jq -r '.data.id')"
vault write identity/entity-alias \
name="$USERNAME" \
canonical_id="$entity_id" \
mount_accessor="$userpass_accessor" >/dev/null
fi fi
mkdir -p "$OUTPUT_DIR" mkdir -p "$OUTPUT_DIR"
@ -206,9 +204,6 @@ vault write "identity/mfa/login-enforcement/${ENFORCEMENT_NAME}" \
mfa_method_ids="$method_id" \ mfa_method_ids="$method_id" \
auth_method_accessors="$userpass_accessor" >/dev/null auth_method_accessors="$userpass_accessor" >/dev/null
if [[ -n "$bootstrap_token" && "$bootstrap_token" != "null" ]]; then
vault token revoke "$bootstrap_token" >/dev/null || true
fi
cat <<EOF cat <<EOF
vault_addr=$VAULT_ADDR vault_addr=$VAULT_ADDR

View File

@ -49,8 +49,8 @@
ansible.builtin.file: ansible.builtin.file:
path: "{{ item }}" path: "{{ item }}"
state: directory state: directory
owner: "{{ omit if ansible_os_family == 'Darwin' else 'root' }}" owner: root
group: "{{ omit if ansible_os_family == 'Darwin' else 'root' }}" group: root
mode: "0755" mode: "0755"
loop: loop:
- "{{ vault_config_dir }}" - "{{ vault_config_dir }}"

View File

@ -6,9 +6,9 @@ vault_deploy_mode: "{{ lookup('ansible.builtin.env', 'VAULT_DEPLOY_MODE') | defa
vault_version: "{{ lookup('ansible.builtin.env', 'VAULT_VERSION') | default('1.21.4', true) }}" vault_version: "{{ lookup('ansible.builtin.env', 'VAULT_VERSION') | default('1.21.4', true) }}"
vault_listen_addr: 127.0.0.1:8200 vault_listen_addr: 127.0.0.1:8200
vault_service_name: vault vault_service_name: vault
vault_binary_path: "{{ '/opt/homebrew/bin/vault' if ansible_os_family == 'Darwin' else '/usr/local/bin/vault' }}" vault_binary_path: /usr/local/bin/vault
vault_config_dir: "{{ (ansible_env.HOME | default('/tmp')) + '/.config/vault.d' if ansible_os_family == 'Darwin' else '/etc/vault.d' }}" vault_config_dir: /etc/vault.d
vault_data_dir: "{{ (ansible_env.HOME | default('/tmp')) + '/.local/state/vault/data' if ansible_os_family == 'Darwin' else '/opt/vault/data' }}" vault_data_dir: /opt/vault/data
ai_workspace_auth_token: "{{ lookup('ansible.builtin.env', 'AI_WORKSPACE_AUTH_TOKEN') | default('', true) }}" ai_workspace_auth_token: "{{ lookup('ansible.builtin.env', 'AI_WORKSPACE_AUTH_TOKEN') | default('', true) }}"
vault_server_root_access_token: "{{ lookup('ansible.builtin.env', 'VAULT_SERVER_ROOT_ACCESS_TOKEN') | default(lookup('ansible.builtin.env', 'VAULT_TOKEN') | default(ai_workspace_auth_token, true), true) }}" vault_server_root_access_token: "{{ lookup('ansible.builtin.env', 'VAULT_SERVER_ROOT_ACCESS_TOKEN') | default(lookup('ansible.builtin.env', 'VAULT_TOKEN') | default(ai_workspace_auth_token, true), true) }}"
vault_admin_init_enabled: "{{ (vault_server_root_access_token | trim | length > 0) and (vault_admin_password | trim | length > 0) }}" vault_admin_init_enabled: "{{ (vault_server_root_access_token | trim | length > 0) and (vault_admin_password | trim | length > 0) }}"

View File

@ -9,7 +9,7 @@ xworkmate_bridge_review_auth_token: "{{ lookup('ansible.builtin.env', 'BRIDGE_RE
xworkmate_bridge_listen_host: 127.0.0.1 xworkmate_bridge_listen_host: 127.0.0.1
xworkmate_bridge_listen_port: 8787 xworkmate_bridge_listen_port: 8787
xworkmate_bridge_listen_addr: "{{ xworkmate_bridge_listen_host }}:{{ xworkmate_bridge_listen_port }}" xworkmate_bridge_listen_addr: "{{ xworkmate_bridge_listen_host }}:{{ xworkmate_bridge_listen_port }}"
xworkmate_bridge_base_dir: "{{ xworkmate_bridge_service_home + '/.local/state/xworkmate-bridge' if ansible_os_family == 'Darwin' else '/opt/cloud-neutral/xworkmate-bridge' }}" xworkmate_bridge_base_dir: /opt/cloud-neutral/xworkmate-bridge
xworkmate_bridge_config_file: "{{ xworkmate_bridge_base_dir }}/config.yaml" xworkmate_bridge_config_file: "{{ xworkmate_bridge_base_dir }}/config.yaml"
xworkmate_bridge_binary_path: /usr/local/bin/xworkmate-go-core xworkmate_bridge_binary_path: /usr/local/bin/xworkmate-go-core
xworkmate_bridge_systemd_unit_path: "/etc/systemd/system/{{ xworkmate_bridge_service_name }}.service" xworkmate_bridge_systemd_unit_path: "/etc/systemd/system/{{ xworkmate_bridge_service_name }}.service"

View File

@ -9,7 +9,6 @@
ansible.builtin.group: ansible.builtin.group:
name: "{{ xworkmate_bridge_service_group }}" name: "{{ xworkmate_bridge_service_group }}"
state: present state: present
when: ansible_os_family != 'Darwin'
- name: Ensure xworkmate-bridge service user exists - name: Ensure xworkmate-bridge service user exists
ansible.builtin.user: ansible.builtin.user:
@ -18,7 +17,6 @@
shell: /bin/bash shell: /bin/bash
create_home: true create_home: true
state: present state: present
when: ansible_os_family != 'Darwin'
- name: Ensure xworkmate-bridge base directory exists - name: Ensure xworkmate-bridge base directory exists
ansible.builtin.file: ansible.builtin.file:
@ -123,14 +121,12 @@
ansible.builtin.file: ansible.builtin.file:
path: "{{ xworkmate_bridge_deprecated_compose_file }}" path: "{{ xworkmate_bridge_deprecated_compose_file }}"
state: absent state: absent
when: ansible_os_family != 'Darwin'
- name: Remove obsolete xworkmate-bridge systemd drop-ins - name: Remove obsolete xworkmate-bridge systemd drop-ins
ansible.builtin.file: ansible.builtin.file:
path: "{{ item }}" path: "{{ item }}"
state: absent state: absent
loop: "{{ xworkmate_bridge_obsolete_systemd_dropin_paths }}" loop: "{{ xworkmate_bridge_obsolete_systemd_dropin_paths }}"
when: ansible_os_family != 'Darwin'
notify: Reload bridge notify: Reload bridge
- name: Disable and stop obsolete user-level xworkmate-serve service - name: Disable and stop obsolete user-level xworkmate-serve service
@ -148,7 +144,6 @@
ansible.builtin.file: ansible.builtin.file:
path: "/home/{{ xworkmate_bridge_service_user }}/.config/systemd/user/xworkmate-serve.service" path: "/home/{{ xworkmate_bridge_service_user }}/.config/systemd/user/xworkmate-serve.service"
state: absent state: absent
when: ansible_os_family != 'Darwin'
- name: Inspect xworkmate-bridge config file attributes - name: Inspect xworkmate-bridge config file attributes
ansible.builtin.command: ansible.builtin.command:
@ -235,7 +230,6 @@
owner: root owner: root
group: root group: root
mode: "0755" mode: "0755"
when: ansible_os_family != 'Darwin'
- name: Inspect Caddy main file attributes - name: Inspect Caddy main file attributes
ansible.builtin.command: ansible.builtin.command:
@ -263,7 +257,6 @@
group: root group: root
mode: "0644" mode: "0644"
state: present state: present
when: ansible_os_family != 'Darwin'
notify: Reload caddy notify: Reload caddy
- name: Restore immutable flag on Caddy main file - name: Restore immutable flag on Caddy main file
@ -297,18 +290,14 @@
owner: root owner: root
group: root group: root
mode: "0644" mode: "0644"
when: when: xworkmate_bridge_public_access | bool
- ansible_os_family != 'Darwin'
- xworkmate_bridge_public_access | bool
notify: Reload caddy notify: Reload caddy
- name: Remove xworkmate-bridge public Caddy site when public access is disabled - name: Remove xworkmate-bridge public Caddy site when public access is disabled
ansible.builtin.file: ansible.builtin.file:
path: "{{ xworkmate_bridge_service_caddy_fragment_path }}" path: "{{ xworkmate_bridge_service_caddy_fragment_path }}"
state: absent state: absent
when: when: not (xworkmate_bridge_public_access | bool)
- ansible_os_family != 'Darwin'
- not (xworkmate_bridge_public_access | bool)
notify: Reload caddy notify: Reload caddy
- name: Restore immutable flag on xworkmate-bridge Caddy fragment - name: Restore immutable flag on xworkmate-bridge Caddy fragment
@ -345,7 +334,6 @@
path: "{{ item }}" path: "{{ item }}"
state: absent state: absent
loop: "{{ xworkmate_bridge_obsolete_caddy_fragment_paths }}" loop: "{{ xworkmate_bridge_obsolete_caddy_fragment_paths }}"
when: ansible_os_family != 'Darwin'
notify: Reload caddy notify: Reload caddy
- name: Ensure xworkmate-bridge service is enabled and running - name: Ensure xworkmate-bridge service is enabled and running
@ -374,7 +362,6 @@
tags: [xworkmate_bridge, xworkmate_bridge_validate] tags: [xworkmate_bridge, xworkmate_bridge_validate]
when: when:
- not ansible_check_mode - not ansible_check_mode
- ansible_os_family != 'Darwin'
- name: Import macOS specific xworkmate-bridge tasks - name: Import macOS specific xworkmate-bridge tasks
ansible.builtin.import_tasks: macos.yml ansible.builtin.import_tasks: macos.yml

View File

@ -27,4 +27,3 @@
gather_facts: false gather_facts: false
roles: roles:
- role: roles/vhosts/validation - role: roles/vhosts/validation
when: ansible_os_family | default("") != "Darwin"

View File

@ -12,7 +12,6 @@
- name: Include XFCE desktop runtime role - name: Include XFCE desktop runtime role
ansible.builtin.include_role: ansible.builtin.include_role:
name: roles/vhosts/xfce_desktop_minimal_runtime name: roles/vhosts/xfce_desktop_minimal_runtime
when: ansible_os_family != "Darwin"
- name: Include XRDP server role when enabled - name: Include XRDP server role when enabled
ansible.builtin.include_role: ansible.builtin.include_role:
@ -24,6 +23,4 @@
xfce_user_groups: xfce_user_groups:
- sudo - sudo
- docker - docker
when: when: xworkspace_console_enable_xrdp | bool
- ansible_os_family != "Darwin"
- xworkspace_console_enable_xrdp | bool

View File

@ -576,13 +576,22 @@
- xworkspace_console_runtime_archive | length == 0 - xworkspace_console_runtime_archive | length == 0
- xworkspace_console_source_repo_safe_dir | length > 0 - xworkspace_console_source_repo_safe_dir | 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
- xworkspace_console_source_version == 'main' or xworkspace_console_source_version == 'HEAD'
- name: Clone xworkspace-console repository - name: Clone xworkspace-console repository
ansible.builtin.git: ansible.builtin.git:
repo: "{{ xworkspace_console_source_repo }}" repo: "{{ xworkspace_console_source_repo }}"
dest: "{{ xworkspace_console_repo_dir }}" dest: "{{ xworkspace_console_repo_dir }}"
version: "{{ xworkspace_console_source_version }}" version: "{{ xworkspace_console_source_version }}"
depth: 1
force: true force: true
depth: 1
become_user: "{{ xworkspace_console_user }}" become_user: "{{ xworkspace_console_user }}"
register: xworkspace_console_source_checkout register: xworkspace_console_source_checkout
when: xworkspace_console_runtime_archive | length == 0 when: xworkspace_console_runtime_archive | length == 0