feat: full macOS (Darwin) compatibility fixes for Ansible playbooks
This commit is contained in:
parent
c7784f2063
commit
044a264256
27
api.plist.j2
Normal file
27
api.plist.j2
Normal file
@ -0,0 +1,27 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>Label</key>
|
||||
<string>plus.svc.xworkspace.api</string>
|
||||
<key>ProgramArguments</key>
|
||||
<array>
|
||||
<string>/bin/bash</string>
|
||||
<string>-c</string>
|
||||
<string>
|
||||
source "{{ xworkspace_console_config_dir }}/portal.env"
|
||||
exec {{ xworkspace_console_api_exec }}
|
||||
</string>
|
||||
</array>
|
||||
<key>RunAtLoad</key>
|
||||
<true/>
|
||||
<key>KeepAlive</key>
|
||||
<true/>
|
||||
<key>WorkingDirectory</key>
|
||||
<string>{{ xworkspace_console_api_working_dir }}</string>
|
||||
<key>StandardOutPath</key>
|
||||
<string>{{ ansible_env.HOME }}/.local/state/xworkspace/api.log</string>
|
||||
<key>StandardErrorPath</key>
|
||||
<string>{{ ansible_env.HOME }}/.local/state/xworkspace/api.err.log</string>
|
||||
</dict>
|
||||
</plist>
|
||||
27
console.plist.j2
Normal file
27
console.plist.j2
Normal file
@ -0,0 +1,27 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>Label</key>
|
||||
<string>plus.svc.xworkspace.console</string>
|
||||
<key>ProgramArguments</key>
|
||||
<array>
|
||||
<string>/bin/bash</string>
|
||||
<string>-c</string>
|
||||
<string>
|
||||
export PATH="/opt/homebrew/bin:/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin:$PATH"
|
||||
exec /usr/bin/env npm run preview -- --host 127.0.0.1 --port {{ xworkspace_console_port }}
|
||||
</string>
|
||||
</array>
|
||||
<key>RunAtLoad</key>
|
||||
<true/>
|
||||
<key>KeepAlive</key>
|
||||
<true/>
|
||||
<key>WorkingDirectory</key>
|
||||
<string>{{ xworkspace_console_dashboard_dir }}</string>
|
||||
<key>StandardOutPath</key>
|
||||
<string>{{ ansible_env.HOME }}/.local/state/xworkspace/console.log</string>
|
||||
<key>StandardErrorPath</key>
|
||||
<string>{{ ansible_env.HOME }}/.local/state/xworkspace/console.err.log</string>
|
||||
</dict>
|
||||
</plist>
|
||||
@ -9,3 +9,4 @@
|
||||
DEBIAN_FRONTEND: noninteractive
|
||||
APT_LISTCHANGES_FRONTEND: none
|
||||
become: true
|
||||
when: ansible_os_family != 'Darwin'
|
||||
|
||||
@ -9,3 +9,4 @@
|
||||
DEBIAN_FRONTEND: noninteractive
|
||||
APT_LISTCHANGES_FRONTEND: none
|
||||
become: true
|
||||
when: ansible_os_family != 'Darwin'
|
||||
|
||||
@ -1,9 +1,9 @@
|
||||
---
|
||||
- name: Assert AI agent runtime is only supported on Debian family
|
||||
- name: Assert AI agent runtime is supported on Debian or Darwin family
|
||||
ansible.builtin.assert:
|
||||
that:
|
||||
- ansible_facts.os_family == "Debian"
|
||||
fail_msg: "roles/ai_agent_runtime currently supports Debian-based hosts only."
|
||||
- ansible_facts.os_family in ["Debian", "Darwin"]
|
||||
fail_msg: "roles/ai_agent_runtime currently supports Debian-based and Darwin hosts only."
|
||||
|
||||
- name: Install AI agent runtime base packages
|
||||
ansible.builtin.apt:
|
||||
@ -15,6 +15,7 @@
|
||||
DEBIAN_FRONTEND: noninteractive
|
||||
APT_LISTCHANGES_FRONTEND: none
|
||||
become: true
|
||||
when: ansible_os_family != 'Darwin'
|
||||
|
||||
- name: Configure Node.js runtime
|
||||
ansible.builtin.include_tasks: nodejs.yml
|
||||
|
||||
@ -7,18 +7,25 @@
|
||||
install_yarn: "{{ ai_agent_runtime_install_yarn }}"
|
||||
yarn_version: "{{ ai_agent_runtime_yarn_version }}"
|
||||
|
||||
- name: Ensure user local bin directory exists on macOS
|
||||
ansible.builtin.file:
|
||||
path: "{{ ansible_env.HOME }}/.local/bin"
|
||||
state: directory
|
||||
mode: "0755"
|
||||
when: ansible_os_family == 'Darwin'
|
||||
|
||||
- name: Install npm global package manager helper
|
||||
ansible.builtin.copy:
|
||||
src: manage_npm_global_package.sh
|
||||
dest: /usr/local/sbin/ai-workspace-manage-npm-global-package
|
||||
owner: root
|
||||
group: root
|
||||
dest: "{{ '/usr/local/sbin' if ansible_os_family != 'Darwin' else ansible_env.HOME + '/.local/bin' }}/ai-workspace-manage-npm-global-package"
|
||||
owner: "{{ 'root' if ansible_os_family != 'Darwin' else xworkspace_console_user }}"
|
||||
group: "{{ 'root' if ansible_os_family != 'Darwin' else ('staff' if ansible_os_family == 'Darwin' else xworkspace_console_user) }}"
|
||||
mode: "0755"
|
||||
become: true
|
||||
become: "{{ ansible_os_family != 'Darwin' }}"
|
||||
|
||||
- name: Install global npm packages for AI runtime
|
||||
ansible.builtin.command:
|
||||
cmd: "/usr/local/sbin/ai-workspace-manage-npm-global-package {{ ai_agent_runtime_npm_global_package_action }} {{ item }}"
|
||||
cmd: "{{ '/usr/local/sbin' if ansible_os_family != 'Darwin' else ansible_env.HOME + '/.local/bin' }}/ai-workspace-manage-npm-global-package {{ ai_agent_runtime_npm_global_package_action }} {{ item }}"
|
||||
loop: "{{ ai_agent_runtime_npm_global_packages }}"
|
||||
register: ai_agent_runtime_npm_global_install
|
||||
changed_when: "'changed=1' in ai_agent_runtime_npm_global_install.stdout"
|
||||
@ -26,7 +33,7 @@
|
||||
|
||||
- name: Install pinned Playwright package for AI runtime
|
||||
ansible.builtin.command:
|
||||
cmd: "/usr/local/sbin/ai-workspace-manage-npm-global-package {{ ai_agent_runtime_npm_global_package_action }} playwright@{{ ai_agent_runtime_playwright_version }}"
|
||||
cmd: "{{ '/usr/local/sbin' if ansible_os_family != 'Darwin' else ansible_env.HOME + '/.local/bin' }}/ai-workspace-manage-npm-global-package {{ ai_agent_runtime_npm_global_package_action }} playwright@{{ ai_agent_runtime_playwright_version }}"
|
||||
register: ai_agent_runtime_playwright_install
|
||||
changed_when: "'changed=1' in ai_agent_runtime_playwright_install.stdout"
|
||||
when:
|
||||
|
||||
@ -12,7 +12,7 @@ acp_gemini_args: --experimental-acp
|
||||
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_binary_path: "{{ acp_gemini_bridge_local_build_dir }}/xworkmate-go-core"
|
||||
acp_gemini_bridge_build_goos: linux
|
||||
acp_gemini_bridge_build_goos: "{{ 'darwin' if ansible_os_family == 'Darwin' else 'linux' }}"
|
||||
acp_gemini_bridge_build_goarch: "{{ 'arm64' if ansible_architecture in ['aarch64', 'arm64'] else 'amd64' }}"
|
||||
acp_gemini_bridge_binary_path: /usr/local/bin/xworkmate-go-core
|
||||
acp_gemini_bridge_use_prebuilt: "{{ lookup('ansible.builtin.env', 'AI_WORKSPACE_USE_PREBUILT_BRIDGE') | default('false', true) | bool }}"
|
||||
|
||||
@ -1,8 +1,23 @@
|
||||
---
|
||||
- name: Reload caddy
|
||||
ansible.builtin.service:
|
||||
name: caddy
|
||||
state: reloaded
|
||||
when: ansible_os_family != 'Darwin'
|
||||
|
||||
- name: Restart acp gemini
|
||||
ansible.builtin.systemd:
|
||||
ansible.builtin.service:
|
||||
name: "{{ acp_gemini_service_name }}"
|
||||
state: restarted
|
||||
daemon_reload: true
|
||||
when:
|
||||
- not ansible_check_mode
|
||||
when: ansible_os_family != 'Darwin'
|
||||
|
||||
- name: Restart acp gemini on macOS
|
||||
ansible.builtin.command: "launchctl stop plus.svc.xworkspace.acp.gemini"
|
||||
register: launchctl_stop
|
||||
failed_when: false
|
||||
changed_when: false
|
||||
notify: Start acp gemini on macOS
|
||||
|
||||
- name: Start acp gemini on macOS
|
||||
ansible.builtin.command: "launchctl start plus.svc.xworkspace.acp.gemini"
|
||||
changed_when: false
|
||||
|
||||
@ -33,6 +33,7 @@
|
||||
ansible.builtin.command:
|
||||
cmd: chattr -i "{{ acp_gemini_bridge_binary_path }}"
|
||||
when:
|
||||
- ansible_os_family != 'Darwin'
|
||||
- "'i' in (acp_gemini_bridge_binary_attrs.stdout | default(''))"
|
||||
changed_when: true
|
||||
become: true
|
||||
@ -51,50 +52,70 @@
|
||||
ansible.builtin.command:
|
||||
cmd: chattr +i "{{ acp_gemini_bridge_binary_path }}"
|
||||
when:
|
||||
- ansible_os_family != 'Darwin'
|
||||
- "'i' in (acp_gemini_bridge_binary_attrs.stdout | default(''))"
|
||||
changed_when: true
|
||||
become: true
|
||||
|
||||
- name: Deploy Gemini ACP adapter service
|
||||
- name: Deploy Gemini ACP systemd service
|
||||
ansible.builtin.command:
|
||||
cmd: lsattr "/etc/systemd/system/{{ acp_gemini_service_name }}.service"
|
||||
register: acp_gemini_service_attrs
|
||||
changed_when: false
|
||||
failed_when: false
|
||||
when: ansible_os_family != 'Darwin'
|
||||
|
||||
- name: Remove immutable flag from Gemini ACP systemd service when present
|
||||
ansible.builtin.command:
|
||||
cmd: chattr -i "/etc/systemd/system/{{ acp_gemini_service_name }}.service"
|
||||
when:
|
||||
- ansible_os_family != 'Darwin'
|
||||
- "'i' in (acp_gemini_service_attrs.stdout | default(''))"
|
||||
changed_when: true
|
||||
become: true
|
||||
|
||||
- name: Deploy Gemini ACP adapter service
|
||||
- name: Deploy Gemini ACP systemd service
|
||||
ansible.builtin.template:
|
||||
src: gemini-acp-adapter.service.j2
|
||||
src: gemini-acp.service.j2
|
||||
dest: "/etc/systemd/system/{{ acp_gemini_service_name }}.service"
|
||||
owner: root
|
||||
group: root
|
||||
mode: "0644"
|
||||
notify: Restart acp gemini
|
||||
when: ansible_os_family != 'Darwin'
|
||||
|
||||
- name: Restore immutable flag on Gemini ACP systemd service
|
||||
ansible.builtin.command:
|
||||
cmd: chattr +i "/etc/systemd/system/{{ acp_gemini_service_name }}.service"
|
||||
when:
|
||||
- ansible_os_family != 'Darwin'
|
||||
- "'i' in (acp_gemini_service_attrs.stdout | default(''))"
|
||||
changed_when: true
|
||||
become: true
|
||||
|
||||
- name: Reload systemd manager configuration for Gemini ACP
|
||||
- name: Reload systemd manager configuration
|
||||
ansible.builtin.systemd:
|
||||
daemon_reload: true
|
||||
when: ansible_os_family != 'Darwin'
|
||||
|
||||
- name: Ensure Gemini ACP adapter service is enabled and running
|
||||
- name: Ensure Caddy is enabled and running
|
||||
ansible.builtin.systemd:
|
||||
name: caddy
|
||||
enabled: true
|
||||
state: started
|
||||
when:
|
||||
- ansible_os_family != 'Darwin'
|
||||
- acp_gemini_manage_caddy | bool
|
||||
|
||||
- name: Ensure Gemini ACP service is enabled and running
|
||||
ansible.builtin.systemd:
|
||||
name: "{{ acp_gemini_service_name }}"
|
||||
enabled: true
|
||||
state: started
|
||||
when:
|
||||
- not ansible_check_mode
|
||||
- ansible_os_family != 'Darwin'
|
||||
|
||||
- name: Import macOS specific Gemini ACP tasks
|
||||
ansible.builtin.import_tasks: macos.yml
|
||||
when: ansible_os_family == 'Darwin'
|
||||
|
||||
13
roles/vhosts/acp_server_gemini/tasks/macos.yml
Normal file
13
roles/vhosts/acp_server_gemini/tasks/macos.yml
Normal file
@ -0,0 +1,13 @@
|
||||
---
|
||||
- name: Create launchd plist template for Gemini ACP
|
||||
ansible.builtin.template:
|
||||
src: gemini.plist.j2
|
||||
dest: "{{ ansible_env.HOME }}/Library/LaunchAgents/plus.svc.xworkspace.acp.gemini.plist"
|
||||
mode: "0644"
|
||||
notify: Restart acp gemini on macOS
|
||||
|
||||
- name: Reload launchd agent for Gemini ACP
|
||||
ansible.builtin.command: "launchctl load -w {{ ansible_env.HOME }}/Library/LaunchAgents/plus.svc.xworkspace.acp.gemini.plist"
|
||||
register: launchctl_result
|
||||
changed_when: false
|
||||
failed_when: launchctl_result.rc != 0 and 'already loaded' not in launchctl_result.stderr
|
||||
41
roles/vhosts/acp_server_gemini/templates/gemini.plist.j2
Normal file
41
roles/vhosts/acp_server_gemini/templates/gemini.plist.j2
Normal file
@ -0,0 +1,41 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>Label</key>
|
||||
<string>plus.svc.xworkspace.acp.gemini</string>
|
||||
<key>ProgramArguments</key>
|
||||
<array>
|
||||
<string>/bin/bash</string>
|
||||
<string>-c</string>
|
||||
<string>
|
||||
export PATH="{{ acp_gemini_path }}"
|
||||
export LITELLM_MASTER_KEY="{{ acp_gemini_auth_token }}"
|
||||
{% for key, value in acp_gemini_environment.items() %}
|
||||
export {{ key }}="{{ value }}"
|
||||
{% endfor %}
|
||||
|
||||
exec "{{ acp_gemini_bridge_binary_path }}" acp-server \
|
||||
--port {{ acp_gemini_listen_port }} \
|
||||
--host {{ acp_gemini_listen_host }} \
|
||||
--sub-command gemini \
|
||||
--sub-command mcp-app-server
|
||||
</string>
|
||||
</array>
|
||||
<key>RunAtLoad</key>
|
||||
<true/>
|
||||
<key>KeepAlive</key>
|
||||
<true/>
|
||||
<key>WorkingDirectory</key>
|
||||
<string>{{ acp_gemini_workdir }}</string>
|
||||
<key>StandardOutPath</key>
|
||||
<string>{{ ansible_env.HOME }}/.local/state/xworkspace/acp.gemini.log</string>
|
||||
<key>StandardErrorPath</key>
|
||||
<string>{{ ansible_env.HOME }}/.local/state/xworkspace/acp.gemini.err.log</string>
|
||||
<key>EnvironmentVariables</key>
|
||||
<dict>
|
||||
<key>HOME</key>
|
||||
<string>{{ acp_gemini_workdir }}</string>
|
||||
</dict>
|
||||
</dict>
|
||||
</plist>
|
||||
@ -4,7 +4,7 @@ acp_hermes_version: "0.15"
|
||||
acp_hermes_bridge_local_source_dir: "{{ playbook_dir }}/../xworkmate-bridge"
|
||||
acp_hermes_bridge_local_build_dir: "{{ playbook_dir }}/.artifacts/acp_hermes"
|
||||
acp_hermes_bridge_local_binary_path: "{{ acp_hermes_bridge_local_build_dir }}/xworkmate-go-core"
|
||||
acp_hermes_bridge_build_goos: linux
|
||||
acp_hermes_bridge_build_goos: "{{ 'darwin' if ansible_os_family == 'Darwin' else 'linux' }}"
|
||||
acp_hermes_bridge_build_goarch: "{{ 'arm64' if ansible_architecture in ['aarch64', 'arm64'] else 'amd64' }}"
|
||||
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
|
||||
|
||||
@ -1,8 +1,23 @@
|
||||
---
|
||||
- name: Reload caddy
|
||||
ansible.builtin.service:
|
||||
name: caddy
|
||||
state: reloaded
|
||||
when: ansible_os_family != 'Darwin'
|
||||
|
||||
- name: Restart acp hermes
|
||||
ansible.builtin.systemd:
|
||||
ansible.builtin.service:
|
||||
name: "{{ acp_hermes_service_name }}"
|
||||
state: restarted
|
||||
daemon_reload: true
|
||||
when:
|
||||
- not ansible_check_mode
|
||||
when: ansible_os_family != 'Darwin'
|
||||
|
||||
- name: Restart acp hermes on macOS
|
||||
ansible.builtin.command: "launchctl stop plus.svc.xworkspace.acp.hermes"
|
||||
register: launchctl_stop
|
||||
failed_when: false
|
||||
changed_when: false
|
||||
notify: Start acp hermes on macOS
|
||||
|
||||
- name: Start acp hermes on macOS
|
||||
ansible.builtin.command: "launchctl start plus.svc.xworkspace.acp.hermes"
|
||||
changed_when: false
|
||||
|
||||
@ -34,6 +34,7 @@
|
||||
ansible.builtin.command:
|
||||
cmd: chattr -i "{{ acp_hermes_bridge_binary_path }}"
|
||||
when:
|
||||
- ansible_os_family != 'Darwin'
|
||||
- "'i' in (acp_hermes_bridge_binary_attrs.stdout | default(''))"
|
||||
changed_when: true
|
||||
become: true
|
||||
@ -52,6 +53,7 @@
|
||||
ansible.builtin.command:
|
||||
cmd: chattr +i "{{ acp_hermes_bridge_binary_path }}"
|
||||
when:
|
||||
- ansible_os_family != 'Darwin'
|
||||
- "'i' in (acp_hermes_bridge_binary_attrs.stdout | default(''))"
|
||||
changed_when: true
|
||||
become: true
|
||||
@ -124,11 +126,13 @@
|
||||
changed_when: false
|
||||
failed_when: false
|
||||
check_mode: false
|
||||
when: ansible_os_family != 'Darwin'
|
||||
|
||||
- name: Remove immutable flag from Hermes ACP systemd service when present
|
||||
ansible.builtin.command:
|
||||
cmd: chattr -i "/etc/systemd/system/{{ acp_hermes_service_name }}.service"
|
||||
when:
|
||||
- ansible_os_family != 'Darwin'
|
||||
- "'i' in (acp_hermes_service_attrs.stdout | default(''))"
|
||||
changed_when: true
|
||||
become: true
|
||||
@ -147,6 +151,7 @@
|
||||
failed_when: false
|
||||
no_log: true
|
||||
check_mode: false
|
||||
when: ansible_os_family != 'Darwin'
|
||||
|
||||
- name: Resolve Hermes ACP auth token
|
||||
ansible.builtin.set_fact:
|
||||
@ -166,11 +171,13 @@
|
||||
group: root
|
||||
mode: "0644"
|
||||
notify: Restart acp hermes
|
||||
when: ansible_os_family != 'Darwin'
|
||||
|
||||
- name: Restore immutable flag on Hermes ACP systemd service
|
||||
ansible.builtin.command:
|
||||
cmd: chattr +i "/etc/systemd/system/{{ acp_hermes_service_name }}.service"
|
||||
when:
|
||||
- ansible_os_family != 'Darwin'
|
||||
- "'i' in (acp_hermes_service_attrs.stdout | default(''))"
|
||||
changed_when: true
|
||||
become: true
|
||||
@ -178,6 +185,7 @@
|
||||
- name: Reload systemd manager configuration for Hermes ACP
|
||||
ansible.builtin.systemd:
|
||||
daemon_reload: true
|
||||
when: ansible_os_family != 'Darwin'
|
||||
|
||||
- name: Ensure Hermes ACP adapter service is enabled and running
|
||||
ansible.builtin.systemd:
|
||||
@ -186,3 +194,8 @@
|
||||
state: started
|
||||
when:
|
||||
- not ansible_check_mode
|
||||
- ansible_os_family != 'Darwin'
|
||||
|
||||
- name: Import macOS specific Hermes ACP tasks
|
||||
ansible.builtin.import_tasks: macos.yml
|
||||
when: ansible_os_family == 'Darwin'
|
||||
|
||||
13
roles/vhosts/acp_server_hermes/tasks/macos.yml
Normal file
13
roles/vhosts/acp_server_hermes/tasks/macos.yml
Normal file
@ -0,0 +1,13 @@
|
||||
---
|
||||
- name: Create launchd plist template for Hermes ACP
|
||||
ansible.builtin.template:
|
||||
src: hermes.plist.j2
|
||||
dest: "{{ ansible_env.HOME }}/Library/LaunchAgents/plus.svc.xworkspace.acp.hermes.plist"
|
||||
mode: "0644"
|
||||
notify: Restart acp hermes on macOS
|
||||
|
||||
- name: Reload launchd agent for Hermes ACP
|
||||
ansible.builtin.command: "launchctl load -w {{ ansible_env.HOME }}/Library/LaunchAgents/plus.svc.xworkspace.acp.hermes.plist"
|
||||
register: launchctl_result
|
||||
changed_when: false
|
||||
failed_when: launchctl_result.rc != 0 and 'already loaded' not in launchctl_result.stderr
|
||||
42
roles/vhosts/acp_server_hermes/templates/hermes.plist.j2
Normal file
42
roles/vhosts/acp_server_hermes/templates/hermes.plist.j2
Normal file
@ -0,0 +1,42 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>Label</key>
|
||||
<string>plus.svc.xworkspace.acp.hermes</string>
|
||||
<key>ProgramArguments</key>
|
||||
<array>
|
||||
<string>/bin/bash</string>
|
||||
<string>-c</string>
|
||||
<string>
|
||||
export PATH="{{ acp_hermes_path }}"
|
||||
export LITELLM_MASTER_KEY="{{ acp_hermes_auth_token }}"
|
||||
export HERMES_ADAPTER_AUTH_TOKEN="{{ acp_hermes_effective_auth_token }}"
|
||||
{% for key, value in acp_hermes_environment.items() %}
|
||||
export {{ key }}="{{ value }}"
|
||||
{% endfor %}
|
||||
|
||||
exec "{{ acp_hermes_bridge_binary_path }}" acp-server \
|
||||
--port {{ acp_hermes_listen_port }} \
|
||||
--host {{ acp_hermes_listen_host }} \
|
||||
--sub-command hermes \
|
||||
--sub-command mcp-app-server
|
||||
</string>
|
||||
</array>
|
||||
<key>RunAtLoad</key>
|
||||
<true/>
|
||||
<key>KeepAlive</key>
|
||||
<true/>
|
||||
<key>WorkingDirectory</key>
|
||||
<string>{{ acp_hermes_workdir }}</string>
|
||||
<key>StandardOutPath</key>
|
||||
<string>{{ ansible_env.HOME }}/.local/state/xworkspace/acp.hermes.log</string>
|
||||
<key>StandardErrorPath</key>
|
||||
<string>{{ ansible_env.HOME }}/.local/state/xworkspace/acp.hermes.err.log</string>
|
||||
<key>EnvironmentVariables</key>
|
||||
<dict>
|
||||
<key>HOME</key>
|
||||
<string>{{ acp_hermes_workdir }}</string>
|
||||
</dict>
|
||||
</dict>
|
||||
</plist>
|
||||
@ -37,12 +37,14 @@
|
||||
- gnupg
|
||||
- ca-certificates
|
||||
state: present
|
||||
when: ansible_os_family != 'Darwin'
|
||||
|
||||
- name: Ensure apt keyrings directory exists
|
||||
file:
|
||||
path: /etc/apt/keyrings
|
||||
state: directory
|
||||
mode: '0755'
|
||||
when: ansible_os_family != 'Darwin'
|
||||
|
||||
- name: Remove old NodeSource repository list files
|
||||
file:
|
||||
@ -55,6 +57,7 @@
|
||||
when:
|
||||
- nodejs_needs_install | default(true)
|
||||
- not nodejs_offline_active
|
||||
- ansible_os_family != 'Darwin'
|
||||
|
||||
- name: Add NodeSource GPG key
|
||||
get_url:
|
||||
@ -65,6 +68,7 @@
|
||||
when:
|
||||
- nodejs_needs_install | default(true)
|
||||
- not nodejs_offline_active
|
||||
- ansible_os_family != 'Darwin'
|
||||
|
||||
- name: Add NodeSource repository
|
||||
apt_repository:
|
||||
@ -75,6 +79,7 @@
|
||||
when:
|
||||
- nodejs_needs_install | default(true)
|
||||
- not nodejs_offline_active
|
||||
- ansible_os_family != 'Darwin'
|
||||
|
||||
- name: Update apt cache for NodeSource repository
|
||||
apt:
|
||||
@ -84,6 +89,7 @@
|
||||
- nodejs_needs_install | default(true)
|
||||
- not nodejs_offline_active
|
||||
- nodesource_key.changed or nodesource_repo.changed
|
||||
- ansible_os_family != 'Darwin'
|
||||
|
||||
- name: Install Node.js (exact version)
|
||||
apt:
|
||||
@ -92,7 +98,9 @@
|
||||
state: present
|
||||
allow_downgrade: true
|
||||
update_cache: yes
|
||||
when: nodejs_needs_install | default(true)
|
||||
when:
|
||||
- nodejs_needs_install | default(true)
|
||||
- ansible_os_family != 'Darwin'
|
||||
|
||||
- name: Verify npm is available
|
||||
command: npm --version
|
||||
@ -123,6 +131,7 @@
|
||||
- install_yarn | default(true)
|
||||
- yarn_desired_version | length == 0
|
||||
- not nodejs_offline_active
|
||||
- ansible_os_family != 'Darwin'
|
||||
|
||||
- name: Add Yarn repository
|
||||
apt_repository:
|
||||
@ -133,6 +142,7 @@
|
||||
- install_yarn | default(true)
|
||||
- yarn_desired_version | length == 0
|
||||
- not nodejs_offline_active
|
||||
- ansible_os_family != 'Darwin'
|
||||
|
||||
- name: Install Yarn
|
||||
apt:
|
||||
@ -142,6 +152,7 @@
|
||||
when:
|
||||
- install_yarn | default(true)
|
||||
- yarn_desired_version | length == 0
|
||||
- ansible_os_family != 'Darwin'
|
||||
|
||||
- name: Enable Corepack
|
||||
command: corepack enable
|
||||
@ -160,7 +171,7 @@
|
||||
- name: Set npm to use version tags by default
|
||||
shell: npm config set save-exact true
|
||||
args:
|
||||
creates: /root/.npmrc
|
||||
creates: "{{ ansible_env.HOME }}/.npmrc"
|
||||
|
||||
- name: Create npm global directory
|
||||
file:
|
||||
@ -173,7 +184,9 @@
|
||||
src: npm_global.sh.j2
|
||||
dest: /etc/profile.d/npm_global.sh
|
||||
mode: '0644'
|
||||
when: add_npm_to_path | default(true)
|
||||
when:
|
||||
- add_npm_to_path | default(true)
|
||||
- ansible_os_family != 'Darwin'
|
||||
|
||||
- name: Verify installations
|
||||
debug:
|
||||
|
||||
11
roles/vhosts/qmd/handlers/main.yml
Normal file
11
roles/vhosts/qmd/handlers/main.yml
Normal file
@ -0,0 +1,11 @@
|
||||
---
|
||||
- name: Restart QMD on macOS
|
||||
ansible.builtin.command: "launchctl stop plus.svc.xworkspace.qmd"
|
||||
register: launchctl_stop
|
||||
failed_when: false
|
||||
changed_when: false
|
||||
notify: Start QMD on macOS
|
||||
|
||||
- name: Start QMD on macOS
|
||||
ansible.builtin.command: "launchctl start plus.svc.xworkspace.qmd"
|
||||
changed_when: false
|
||||
13
roles/vhosts/qmd/tasks/macos.yml
Normal file
13
roles/vhosts/qmd/tasks/macos.yml
Normal file
@ -0,0 +1,13 @@
|
||||
---
|
||||
- name: Create launchd plist template for QMD
|
||||
ansible.builtin.template:
|
||||
src: qmd.plist.j2
|
||||
dest: "{{ ansible_env.HOME }}/Library/LaunchAgents/plus.svc.xworkspace.qmd.plist"
|
||||
mode: "0644"
|
||||
notify: Restart QMD on macOS
|
||||
|
||||
- name: Reload launchd agent for QMD
|
||||
ansible.builtin.command: "launchctl load -w {{ ansible_env.HOME }}/Library/LaunchAgents/plus.svc.xworkspace.qmd.plist"
|
||||
register: launchctl_result
|
||||
changed_when: false
|
||||
failed_when: launchctl_result.rc != 0 and 'already loaded' not in launchctl_result.stderr
|
||||
@ -1,9 +1,9 @@
|
||||
---
|
||||
- name: Assert QMD is only supported on Debian family
|
||||
- name: Assert QMD is supported on Debian or Darwin family
|
||||
ansible.builtin.assert:
|
||||
that:
|
||||
- ansible_facts.os_family == "Debian"
|
||||
fail_msg: "roles/vhosts/qmd currently supports Debian-based hosts only."
|
||||
- ansible_facts.os_family in ["Debian", "Darwin"]
|
||||
fail_msg: "roles/vhosts/qmd currently supports Debian-based and Darwin hosts only."
|
||||
|
||||
- name: Ensure QMD config and cache directories exist
|
||||
ansible.builtin.file:
|
||||
@ -27,10 +27,12 @@
|
||||
cmd: "id -u {{ qmd_user }}"
|
||||
register: qmd_service_uid_result
|
||||
changed_when: false
|
||||
when: ansible_os_family != 'Darwin'
|
||||
|
||||
- name: Set QMD service user uid
|
||||
ansible.builtin.set_fact:
|
||||
qmd_service_uid: "{{ qmd_service_uid_result.stdout | trim }}"
|
||||
when: ansible_os_family != 'Darwin'
|
||||
|
||||
- name: Deploy QMD collection index config
|
||||
ansible.builtin.template:
|
||||
@ -221,6 +223,7 @@
|
||||
group: "{{ qmd_group }}"
|
||||
mode: "0644"
|
||||
register: qmd_mcp_user_service_unit
|
||||
when: ansible_os_family != 'Darwin'
|
||||
|
||||
- name: Enable QMD service user linger
|
||||
ansible.builtin.command:
|
||||
@ -228,6 +231,7 @@
|
||||
creates: "/var/lib/systemd/linger/{{ qmd_user }}"
|
||||
when:
|
||||
- not ansible_check_mode
|
||||
- ansible_os_family != 'Darwin'
|
||||
|
||||
- name: Ensure QMD service user manager is running
|
||||
ansible.builtin.systemd:
|
||||
@ -235,6 +239,7 @@
|
||||
state: started
|
||||
when:
|
||||
- not ansible_check_mode
|
||||
- ansible_os_family != 'Darwin'
|
||||
|
||||
- name: Reload QMD user systemd manager
|
||||
ansible.builtin.command:
|
||||
@ -248,6 +253,7 @@
|
||||
changed_when: false
|
||||
when:
|
||||
- not ansible_check_mode
|
||||
- ansible_os_family != 'Darwin'
|
||||
|
||||
- name: Ensure QMD MCP daemon is enabled and running
|
||||
ansible.builtin.command:
|
||||
@ -267,6 +273,7 @@
|
||||
'Created symlink' in (qmd_mcp_service_enable.stderr | default(''))
|
||||
when:
|
||||
- not ansible_check_mode
|
||||
- ansible_os_family != 'Darwin'
|
||||
|
||||
- name: Restart QMD MCP daemon after unit changes
|
||||
ansible.builtin.command:
|
||||
@ -280,6 +287,11 @@
|
||||
when:
|
||||
- qmd_mcp_user_service_unit.changed | default(false)
|
||||
- not ansible_check_mode
|
||||
- ansible_os_family != 'Darwin'
|
||||
|
||||
- name: Import macOS specific QMD tasks
|
||||
ansible.builtin.import_tasks: macos.yml
|
||||
when: ansible_os_family == 'Darwin'
|
||||
|
||||
- name: Validate QMD status
|
||||
ansible.builtin.command:
|
||||
|
||||
34
roles/vhosts/qmd/templates/qmd.plist.j2
Normal file
34
roles/vhosts/qmd/templates/qmd.plist.j2
Normal file
@ -0,0 +1,34 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>Label</key>
|
||||
<string>plus.svc.xworkspace.qmd</string>
|
||||
<key>ProgramArguments</key>
|
||||
<array>
|
||||
<string>/bin/bash</string>
|
||||
<string>-c</string>
|
||||
<string>
|
||||
source "{{ qmd_env_path }}"
|
||||
exec "{{ qmd_binary_path }}" mcp --http --port {{ qmd_mcp_port }}
|
||||
</string>
|
||||
</array>
|
||||
<key>RunAtLoad</key>
|
||||
<true/>
|
||||
<key>KeepAlive</key>
|
||||
<true/>
|
||||
<key>WorkingDirectory</key>
|
||||
<string>{{ qmd_home }}</string>
|
||||
<key>StandardOutPath</key>
|
||||
<string>{{ ansible_env.HOME }}/.local/state/xworkspace/qmd.log</string>
|
||||
<key>StandardErrorPath</key>
|
||||
<string>{{ ansible_env.HOME }}/.local/state/xworkspace/qmd.err.log</string>
|
||||
<key>EnvironmentVariables</key>
|
||||
<dict>
|
||||
<key>HOME</key>
|
||||
<string>{{ qmd_home }}</string>
|
||||
<key>PATH</key>
|
||||
<string>/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin:{{ ansible_env.HOME }}/.nvm/versions/node/{{ nodejs_version }}/bin</string>
|
||||
</dict>
|
||||
</dict>
|
||||
</plist>
|
||||
30
roles/vhosts/vault/tasks/macos.yml
Normal file
30
roles/vhosts/vault/tasks/macos.yml
Normal file
@ -0,0 +1,30 @@
|
||||
---
|
||||
- name: Install HashiCorp Tap
|
||||
ansible.builtin.command: brew tap hashicorp/tap
|
||||
changed_when: false
|
||||
|
||||
- name: Install Vault via Homebrew
|
||||
ansible.builtin.command: brew install hashicorp/tap/vault
|
||||
args:
|
||||
creates: /opt/homebrew/bin/vault
|
||||
changed_when: true
|
||||
|
||||
- name: Create symlink for Vault binary to match Linux path
|
||||
ansible.builtin.file:
|
||||
src: /opt/homebrew/bin/vault
|
||||
dest: /usr/local/bin/vault
|
||||
state: link
|
||||
become: true
|
||||
ignore_errors: true
|
||||
|
||||
- name: Create launchd plist template for Vault
|
||||
ansible.builtin.template:
|
||||
src: vault.plist.j2
|
||||
dest: "{{ ansible_env.HOME }}/Library/LaunchAgents/plus.svc.xworkspace.vault.plist"
|
||||
mode: "0644"
|
||||
|
||||
- name: Start Vault on macOS
|
||||
ansible.builtin.command: "launchctl load -w {{ ansible_env.HOME }}/Library/LaunchAgents/plus.svc.xworkspace.vault.plist"
|
||||
register: launchctl_result
|
||||
changed_when: false
|
||||
failed_when: launchctl_result.rc != 0 and 'already loaded' not in launchctl_result.stderr
|
||||
@ -23,6 +23,7 @@
|
||||
update_cache: true
|
||||
when:
|
||||
- vault_deploy_mode == "standalone"
|
||||
- ansible_os_family != 'Darwin'
|
||||
|
||||
- name: Check standalone Vault binary
|
||||
ansible.builtin.command: "{{ vault_binary_path }} version"
|
||||
@ -31,6 +32,7 @@
|
||||
failed_when: false
|
||||
when:
|
||||
- vault_deploy_mode == "standalone"
|
||||
- ansible_os_family != 'Darwin'
|
||||
|
||||
- name: Download standalone Vault release
|
||||
ansible.builtin.unarchive:
|
||||
@ -40,6 +42,7 @@
|
||||
mode: "0755"
|
||||
when:
|
||||
- vault_deploy_mode == "standalone"
|
||||
- ansible_os_family != 'Darwin'
|
||||
- vault_binary_check.rc != 0 or (vault_binary_check.stdout | default('')) is not search(vault_version)
|
||||
|
||||
- name: Ensure standalone Vault directories exist
|
||||
@ -81,6 +84,7 @@
|
||||
no_log: true
|
||||
when:
|
||||
- vault_deploy_mode == "standalone"
|
||||
- ansible_os_family != 'Darwin'
|
||||
|
||||
- name: Start standalone Vault service
|
||||
ansible.builtin.systemd:
|
||||
@ -90,6 +94,11 @@
|
||||
daemon_reload: true
|
||||
when:
|
||||
- vault_deploy_mode == "standalone"
|
||||
- ansible_os_family != 'Darwin'
|
||||
|
||||
- name: Import macOS specific Vault tasks
|
||||
ansible.builtin.import_tasks: macos.yml
|
||||
when: ansible_os_family == 'Darwin'
|
||||
|
||||
- name: Wait for standalone Vault API
|
||||
ansible.builtin.uri:
|
||||
|
||||
27
roles/vhosts/vault/templates/vault.plist.j2
Normal file
27
roles/vhosts/vault/templates/vault.plist.j2
Normal file
@ -0,0 +1,27 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>Label</key>
|
||||
<string>plus.svc.xworkspace.vault</string>
|
||||
<key>ProgramArguments</key>
|
||||
<array>
|
||||
<string>/bin/bash</string>
|
||||
<string>-c</string>
|
||||
<string>
|
||||
export VAULT_DEV_ROOT_TOKEN_ID="{{ vault_server_root_access_token }}"
|
||||
exec "{{ vault_binary_path }}" server -dev -dev-listen-address={{ vault_listen_addr }} -dev-root-token-id={{ vault_server_root_access_token }}
|
||||
</string>
|
||||
</array>
|
||||
<key>RunAtLoad</key>
|
||||
<true/>
|
||||
<key>KeepAlive</key>
|
||||
<true/>
|
||||
<key>WorkingDirectory</key>
|
||||
<string>{{ vault_data_dir }}</string>
|
||||
<key>StandardOutPath</key>
|
||||
<string>{{ ansible_env.HOME }}/.local/state/xworkspace/vault.log</string>
|
||||
<key>StandardErrorPath</key>
|
||||
<string>{{ ansible_env.HOME }}/.local/state/xworkspace/vault.err.log</string>
|
||||
</dict>
|
||||
</plist>
|
||||
@ -6,6 +6,18 @@
|
||||
daemon_reload: true
|
||||
when:
|
||||
- not ansible_check_mode
|
||||
- ansible_os_family != 'Darwin'
|
||||
|
||||
- name: Restart bridge on macOS
|
||||
ansible.builtin.command: "launchctl stop plus.svc.xworkspace.bridge"
|
||||
register: launchctl_stop
|
||||
failed_when: false
|
||||
changed_when: false
|
||||
notify: Start bridge on macOS
|
||||
|
||||
- name: Start bridge on macOS
|
||||
ansible.builtin.command: "launchctl start plus.svc.xworkspace.bridge"
|
||||
changed_when: false
|
||||
|
||||
- name: Reload caddy
|
||||
ansible.builtin.systemd:
|
||||
@ -13,3 +25,4 @@
|
||||
state: reloaded
|
||||
when:
|
||||
- not ansible_check_mode
|
||||
- ansible_os_family != 'Darwin'
|
||||
|
||||
13
roles/vhosts/xworkmate_bridge/tasks/macos.yml
Normal file
13
roles/vhosts/xworkmate_bridge/tasks/macos.yml
Normal file
@ -0,0 +1,13 @@
|
||||
---
|
||||
- name: Create launchd plist template for XWorkMate Bridge
|
||||
ansible.builtin.template:
|
||||
src: bridge.plist.j2
|
||||
dest: "{{ ansible_env.HOME }}/Library/LaunchAgents/plus.svc.xworkspace.bridge.plist"
|
||||
mode: "0644"
|
||||
notify: Restart bridge on macOS
|
||||
|
||||
- name: Reload launchd agent for XWorkMate Bridge
|
||||
ansible.builtin.command: "launchctl load -w {{ ansible_env.HOME }}/Library/LaunchAgents/plus.svc.xworkspace.bridge.plist"
|
||||
register: launchctl_result
|
||||
changed_when: false
|
||||
failed_when: launchctl_result.rc != 0 and 'already loaded' not in launchctl_result.stderr
|
||||
@ -3,6 +3,7 @@
|
||||
ansible.builtin.package:
|
||||
name: "{{ xworkmate_bridge_packages }}"
|
||||
state: present
|
||||
when: ansible_os_family != 'Darwin'
|
||||
|
||||
- name: Ensure xworkmate-bridge service group exists
|
||||
ansible.builtin.group:
|
||||
@ -43,6 +44,7 @@
|
||||
changed_when: false
|
||||
failed_when: false
|
||||
no_log: true
|
||||
when: ansible_os_family != 'Darwin'
|
||||
|
||||
- name: Read existing xworkmate-bridge review auth token from systemd units
|
||||
ansible.builtin.shell: |
|
||||
@ -62,6 +64,7 @@
|
||||
changed_when: false
|
||||
failed_when: false
|
||||
no_log: true
|
||||
when: ansible_os_family != 'Darwin'
|
||||
|
||||
- name: Resolve xworkmate-bridge auth token
|
||||
ansible.builtin.set_fact:
|
||||
@ -112,6 +115,7 @@
|
||||
failed_when: false
|
||||
when:
|
||||
- not ansible_check_mode
|
||||
- ansible_os_family != 'Darwin'
|
||||
|
||||
- name: Remove deprecated Docker bridge compose file
|
||||
ansible.builtin.file:
|
||||
@ -134,6 +138,7 @@
|
||||
failed_when: false
|
||||
when:
|
||||
- not ansible_check_mode
|
||||
- ansible_os_family != 'Darwin'
|
||||
|
||||
- name: Remove obsolete user-level xworkmate-serve service file
|
||||
ansible.builtin.file:
|
||||
@ -146,11 +151,13 @@
|
||||
register: xworkmate_bridge_config_attrs
|
||||
changed_when: false
|
||||
failed_when: false
|
||||
when: ansible_os_family != 'Darwin'
|
||||
|
||||
- name: Remove immutable flag from xworkmate-bridge config file when present
|
||||
ansible.builtin.command:
|
||||
cmd: chattr -i "{{ xworkmate_bridge_config_file }}"
|
||||
when:
|
||||
- ansible_os_family != 'Darwin'
|
||||
- "'i' in (xworkmate_bridge_config_attrs.stdout | default(''))"
|
||||
changed_when: true
|
||||
|
||||
@ -169,6 +176,7 @@
|
||||
changed_when: true
|
||||
when:
|
||||
- not ansible_check_mode
|
||||
- ansible_os_family != 'Darwin'
|
||||
|
||||
- name: Inspect xworkmate-bridge systemd unit attributes
|
||||
ansible.builtin.command:
|
||||
@ -176,11 +184,13 @@
|
||||
register: xworkmate_bridge_unit_attrs
|
||||
changed_when: false
|
||||
failed_when: false
|
||||
when: ansible_os_family != 'Darwin'
|
||||
|
||||
- name: Remove immutable flag from xworkmate-bridge systemd unit when present
|
||||
ansible.builtin.command:
|
||||
cmd: chattr -i "{{ xworkmate_bridge_systemd_unit_path }}"
|
||||
when:
|
||||
- ansible_os_family != 'Darwin'
|
||||
- "'i' in (xworkmate_bridge_unit_attrs.stdout | default(''))"
|
||||
changed_when: true
|
||||
|
||||
@ -195,6 +205,7 @@
|
||||
no_log: true
|
||||
register: xworkmate_bridge_systemd_unit
|
||||
notify: Reload bridge
|
||||
when: ansible_os_family != 'Darwin'
|
||||
|
||||
- name: Restore immutable flag on xworkmate-bridge systemd unit
|
||||
ansible.builtin.command:
|
||||
@ -202,6 +213,7 @@
|
||||
changed_when: true
|
||||
when:
|
||||
- not ansible_check_mode
|
||||
- ansible_os_family != 'Darwin'
|
||||
|
||||
- name: Reload systemd after xworkmate-bridge unit changes
|
||||
ansible.builtin.systemd:
|
||||
@ -209,6 +221,7 @@
|
||||
when:
|
||||
- xworkmate_bridge_systemd_unit.changed | default(false)
|
||||
- not ansible_check_mode
|
||||
- ansible_os_family != 'Darwin'
|
||||
|
||||
- name: Ensure Caddy fragment directory exists
|
||||
ansible.builtin.file:
|
||||
@ -224,11 +237,13 @@
|
||||
register: xworkmate_bridge_caddyfile_attrs
|
||||
changed_when: false
|
||||
failed_when: false
|
||||
when: ansible_os_family != 'Darwin'
|
||||
|
||||
- name: Remove immutable flag from Caddy main file when present
|
||||
ansible.builtin.command:
|
||||
cmd: chattr -i "{{ xworkmate_bridge_caddyfile_path }}"
|
||||
when:
|
||||
- ansible_os_family != 'Darwin'
|
||||
- "'i' in (xworkmate_bridge_caddyfile_attrs.stdout | default(''))"
|
||||
changed_when: true
|
||||
|
||||
@ -248,6 +263,7 @@
|
||||
ansible.builtin.command:
|
||||
cmd: chattr +i "{{ xworkmate_bridge_caddyfile_path }}"
|
||||
when:
|
||||
- ansible_os_family != 'Darwin'
|
||||
- "'i' in (xworkmate_bridge_caddyfile_attrs.stdout | default(''))"
|
||||
changed_when: true
|
||||
|
||||
@ -257,11 +273,13 @@
|
||||
register: xworkmate_bridge_site_fragment_attrs
|
||||
changed_when: false
|
||||
failed_when: false
|
||||
when: ansible_os_family != 'Darwin'
|
||||
|
||||
- name: Remove immutable flag from xworkmate-bridge Caddy fragment when present
|
||||
ansible.builtin.command:
|
||||
cmd: chattr -i "{{ xworkmate_bridge_service_caddy_fragment_path }}"
|
||||
when:
|
||||
- ansible_os_family != 'Darwin'
|
||||
- "'i' in (xworkmate_bridge_site_fragment_attrs.stdout | default(''))"
|
||||
changed_when: true
|
||||
|
||||
@ -288,6 +306,7 @@
|
||||
changed_when: true
|
||||
when:
|
||||
- not ansible_check_mode
|
||||
- ansible_os_family != 'Darwin'
|
||||
- xworkmate_bridge_public_access | bool
|
||||
|
||||
- name: Inspect deprecated ACP Caddy fragment attributes
|
||||
@ -297,11 +316,13 @@
|
||||
changed_when: false
|
||||
failed_when: false
|
||||
loop: "{{ xworkmate_bridge_obsolete_caddy_fragment_paths }}"
|
||||
when: ansible_os_family != 'Darwin'
|
||||
|
||||
- name: Remove immutable flag from deprecated ACP Caddy fragments when present
|
||||
ansible.builtin.command:
|
||||
cmd: chattr -i "{{ item.item }}"
|
||||
when:
|
||||
- ansible_os_family != 'Darwin'
|
||||
- "'i' in (item.stdout | default(''))"
|
||||
changed_when: true
|
||||
loop: "{{ xworkmate_bridge_obsolete_fragment_attrs.results }}"
|
||||
@ -322,6 +343,7 @@
|
||||
state: started
|
||||
when:
|
||||
- not ansible_check_mode
|
||||
- ansible_os_family != 'Darwin'
|
||||
|
||||
- name: Ensure Caddy is enabled and running
|
||||
ansible.builtin.systemd:
|
||||
@ -330,6 +352,7 @@
|
||||
state: started
|
||||
when:
|
||||
- not ansible_check_mode
|
||||
- ansible_os_family != 'Darwin'
|
||||
|
||||
- name: Apply xworkmate-bridge service and Caddy changes before validation
|
||||
ansible.builtin.meta: flush_handlers
|
||||
@ -339,3 +362,7 @@
|
||||
tags: [xworkmate_bridge, xworkmate_bridge_validate]
|
||||
when:
|
||||
- not ansible_check_mode
|
||||
|
||||
- name: Import macOS specific xworkmate-bridge tasks
|
||||
ansible.builtin.import_tasks: macos.yml
|
||||
when: ansible_os_family == 'Darwin'
|
||||
|
||||
37
roles/vhosts/xworkmate_bridge/templates/bridge.plist.j2
Normal file
37
roles/vhosts/xworkmate_bridge/templates/bridge.plist.j2
Normal file
@ -0,0 +1,37 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>Label</key>
|
||||
<string>plus.svc.xworkspace.bridge</string>
|
||||
<key>ProgramArguments</key>
|
||||
<array>
|
||||
<string>/bin/bash</string>
|
||||
<string>-c</string>
|
||||
<string>
|
||||
{% for key, value in xworkmate_bridge_service_environment.items() %}
|
||||
export {{ key }}="{{ value }}"
|
||||
{% endfor %}
|
||||
|
||||
exec "{{ xworkmate_bridge_binary_path }}" server \
|
||||
--port {{ xworkmate_bridge_listen_port }} \
|
||||
--host {{ xworkmate_bridge_listen_host }}
|
||||
</string>
|
||||
</array>
|
||||
<key>RunAtLoad</key>
|
||||
<true/>
|
||||
<key>KeepAlive</key>
|
||||
<true/>
|
||||
<key>WorkingDirectory</key>
|
||||
<string>{{ xworkmate_bridge_base_dir }}</string>
|
||||
<key>StandardOutPath</key>
|
||||
<string>{{ ansible_env.HOME }}/.local/state/xworkspace/bridge.log</string>
|
||||
<key>StandardErrorPath</key>
|
||||
<string>{{ ansible_env.HOME }}/.local/state/xworkspace/bridge.err.log</string>
|
||||
<key>EnvironmentVariables</key>
|
||||
<dict>
|
||||
<key>HOME</key>
|
||||
<string>{{ xworkmate_bridge_base_dir }}</string>
|
||||
</dict>
|
||||
</dict>
|
||||
</plist>
|
||||
@ -10,9 +10,9 @@
|
||||
xworkspace_console_user: ubuntu
|
||||
xworkspace_console_public_access: false
|
||||
xworkspace_console_domain: workspace.svc.plus
|
||||
xworkspace_console_home: /home/ubuntu
|
||||
xworkspace_console_root: /home/ubuntu/xworkspace
|
||||
xworkspace_console_repo_dir: /home/ubuntu/xworkspace-console
|
||||
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: >-
|
||||
@ -23,16 +23,16 @@
|
||||
}}
|
||||
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: /home/ubuntu/xworkspace-console/dashboard
|
||||
xworkspace_console_api_dir: /home/ubuntu/xworkspace-console/api
|
||||
xworkspace_console_api_binary: /home/ubuntu/xworkspace-console/bin/xworkspace-api
|
||||
xworkspace_console_runtime_marker: /home/ubuntu/xworkspace-console/.runtime-archive-sha256
|
||||
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_scripts_dir: /home/ubuntu/xworkspace/scripts
|
||||
xworkspace_console_config_dir: /home/ubuntu/.config/xworkspace
|
||||
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
|
||||
xworkspace_console_port: 17000
|
||||
xworkspace_console_api_port: 8788
|
||||
@ -111,6 +111,7 @@
|
||||
state: present
|
||||
install_recommends: false
|
||||
update_cache: true
|
||||
when: ansible_os_family != 'Darwin'
|
||||
|
||||
- name: Ensure Google Chrome apt keyring directory exists
|
||||
ansible.builtin.file:
|
||||
@ -119,6 +120,7 @@
|
||||
owner: root
|
||||
group: root
|
||||
mode: "0755"
|
||||
when: ansible_os_family != 'Darwin'
|
||||
|
||||
- name: Install Google Linux signing key
|
||||
ansible.builtin.shell: |
|
||||
@ -134,6 +136,7 @@
|
||||
when:
|
||||
- ansible_architecture in ['x86_64', 'amd64']
|
||||
- not ai_workspace_offline_active
|
||||
- ansible_os_family != 'Darwin'
|
||||
|
||||
- name: Configure Google Chrome apt repository
|
||||
ansible.builtin.copy:
|
||||
@ -145,6 +148,7 @@
|
||||
when:
|
||||
- ansible_architecture in ['x86_64', 'amd64']
|
||||
- not ai_workspace_offline_active
|
||||
- ansible_os_family != 'Darwin'
|
||||
|
||||
- name: Refresh apt cache after Google Chrome repository changes
|
||||
ansible.builtin.apt:
|
||||
@ -152,6 +156,7 @@
|
||||
when:
|
||||
- ansible_architecture in ['x86_64', 'amd64']
|
||||
- not ai_workspace_offline_active
|
||||
- ansible_os_family != 'Darwin'
|
||||
|
||||
- name: Install AI Agentic Workspace runtime packages
|
||||
ansible.builtin.apt:
|
||||
@ -162,6 +167,7 @@
|
||||
+ ([xworkspace_console_browser_package] if xworkspace_console_browser_package | length > 0 else [])
|
||||
}}
|
||||
state: present
|
||||
when: ansible_os_family != 'Darwin'
|
||||
|
||||
- name: Ensure ttyd binary target directory exists
|
||||
ansible.builtin.file:
|
||||
@ -170,6 +176,7 @@
|
||||
owner: root
|
||||
group: root
|
||||
mode: "0755"
|
||||
when: ansible_os_family != 'Darwin'
|
||||
|
||||
- name: Set ttyd binary download metadata
|
||||
ansible.builtin.set_fact:
|
||||
@ -191,16 +198,31 @@
|
||||
owner: root
|
||||
group: root
|
||||
force: false
|
||||
when: not ai_workspace_offline_active
|
||||
when:
|
||||
- not ai_workspace_offline_active
|
||||
- ansible_os_family != 'Darwin'
|
||||
|
||||
- name: Verify ttyd binary
|
||||
ansible.builtin.command: "{{ xworkspace_console_ttyd_binary_path }} --version"
|
||||
register: xworkspace_console_ttyd_version
|
||||
changed_when: false
|
||||
register: ttyd_version_check
|
||||
failed_when: ttyd_version_check.rc != 0
|
||||
when: ansible_os_family != 'Darwin'
|
||||
|
||||
- name: Find ttyd path on macOS
|
||||
ansible.builtin.command: which ttyd
|
||||
register: ttyd_macos_path
|
||||
changed_when: false
|
||||
when: ansible_os_family == 'Darwin'
|
||||
|
||||
- name: Set ttyd binary path for macOS
|
||||
ansible.builtin.set_fact:
|
||||
xworkspace_console_ttyd_binary_path: "{{ ttyd_macos_path.stdout }}"
|
||||
when: ansible_os_family == 'Darwin'
|
||||
|
||||
- name: Show ttyd binary version
|
||||
ansible.builtin.debug:
|
||||
var: xworkspace_console_ttyd_version.stdout
|
||||
msg: "{{ ttyd_version_check.stdout | default('ttyd path: ' + ttyd_macos_path.stdout | default('Unknown')) }}"
|
||||
|
||||
- name: Ensure AI Agentic Workspace user exists
|
||||
ansible.builtin.user:
|
||||
@ -208,32 +230,36 @@
|
||||
state: present
|
||||
create_home: true
|
||||
shell: /bin/bash
|
||||
when: xworkspace_console_user != 'root'
|
||||
when:
|
||||
- xworkspace_console_user != 'root'
|
||||
- ansible_os_family != 'Darwin'
|
||||
|
||||
- name: Ensure AI Agentic Workspace directories exist
|
||||
ansible.builtin.file:
|
||||
path: "{{ item }}"
|
||||
state: directory
|
||||
owner: "{{ xworkspace_console_user }}"
|
||||
group: "{{ xworkspace_console_user }}"
|
||||
group: "{{ 'staff' if ansible_os_family == 'Darwin' else xworkspace_console_user }}"
|
||||
mode: "0755"
|
||||
loop:
|
||||
- "{{ xworkspace_console_root }}"
|
||||
- "{{ xworkspace_console_scripts_dir }}"
|
||||
- "{{ xworkspace_console_repo_dir }}"
|
||||
- "{{ xworkspace_console_home }}/.config"
|
||||
- "{{ xworkspace_console_config_dir }}"
|
||||
- "{{ xworkspace_console_home }}/.config/autostart"
|
||||
- "{{ xworkspace_console_home }}/.config/systemd"
|
||||
- "{{ xworkspace_console_home }}/.config/systemd/user"
|
||||
- "{{ xworkspace_console_home }}/.config/systemd/user/default.target.wants"
|
||||
- "{{ xworkspace_console_home }}/.config/systemd/user/timers.target.wants"
|
||||
loop: "{{ _directories | reject('search', 'systemd') | list if ansible_os_family == 'Darwin' else _directories }}"
|
||||
vars:
|
||||
_directories:
|
||||
- "{{ xworkspace_console_root }}"
|
||||
- "{{ xworkspace_console_scripts_dir }}"
|
||||
- "{{ xworkspace_console_repo_dir }}"
|
||||
- "{{ xworkspace_console_home }}/.config"
|
||||
- "{{ xworkspace_console_config_dir }}"
|
||||
- "{{ xworkspace_console_home }}/.config/autostart"
|
||||
- "{{ xworkspace_console_home }}/.config/systemd"
|
||||
- "{{ xworkspace_console_home }}/.config/systemd/user"
|
||||
- "{{ xworkspace_console_home }}/.config/systemd/user/default.target.wants"
|
||||
- "{{ xworkspace_console_home }}/.config/systemd/user/timers.target.wants"
|
||||
|
||||
- name: Deploy AI Agentic Workspace status generator
|
||||
ansible.builtin.copy:
|
||||
dest: "{{ xworkspace_console_scripts_dir }}/generate-status.py"
|
||||
owner: "{{ xworkspace_console_user }}"
|
||||
group: "{{ xworkspace_console_user }}"
|
||||
group: "{{ 'staff' if ansible_os_family == 'Darwin' else xworkspace_console_user }}"
|
||||
mode: "0755"
|
||||
content: |
|
||||
#!/usr/bin/env python3
|
||||
@ -365,7 +391,7 @@
|
||||
ansible.builtin.copy:
|
||||
dest: "{{ xworkspace_console_home }}/.config/systemd/user/xworkspace-status.service"
|
||||
owner: "{{ xworkspace_console_user }}"
|
||||
group: "{{ xworkspace_console_user }}"
|
||||
group: "{{ 'staff' if ansible_os_family == 'Darwin' else xworkspace_console_user }}"
|
||||
mode: "0644"
|
||||
content: |
|
||||
[Unit]
|
||||
@ -376,12 +402,13 @@
|
||||
[Service]
|
||||
Type=oneshot
|
||||
ExecStart={{ xworkspace_console_scripts_dir }}/generate-status.py
|
||||
when: ansible_os_family != 'Darwin'
|
||||
|
||||
- name: Deploy AI Agentic Workspace status timer
|
||||
ansible.builtin.copy:
|
||||
dest: "{{ xworkspace_console_home }}/.config/systemd/user/xworkspace-status.timer"
|
||||
owner: "{{ xworkspace_console_user }}"
|
||||
group: "{{ xworkspace_console_user }}"
|
||||
group: "{{ 'staff' if ansible_os_family == 'Darwin' else xworkspace_console_user }}"
|
||||
mode: "0644"
|
||||
content: |
|
||||
[Unit]
|
||||
@ -395,12 +422,13 @@
|
||||
|
||||
[Install]
|
||||
WantedBy=timers.target
|
||||
when: ansible_os_family != 'Darwin'
|
||||
|
||||
- name: Deploy Xinit entrypoint for AI Agentic Workspace
|
||||
ansible.builtin.copy:
|
||||
dest: "{{ xworkspace_console_home }}/.xinitrc"
|
||||
owner: "{{ xworkspace_console_user }}"
|
||||
group: "{{ xworkspace_console_user }}"
|
||||
group: "{{ 'staff' if ansible_os_family == 'Darwin' else xworkspace_console_user }}"
|
||||
mode: "0755"
|
||||
content: |
|
||||
#!/usr/bin/env bash
|
||||
@ -427,22 +455,24 @@
|
||||
systemctl --user start xworkspace-console.service >/dev/null 2>&1 || true
|
||||
|
||||
exec dbus-launch --exit-with-session startxfce4
|
||||
when: ansible_os_family != 'Darwin'
|
||||
|
||||
- name: Point Xsession to Xinit entrypoint
|
||||
ansible.builtin.copy:
|
||||
dest: "{{ xworkspace_console_home }}/.xsession"
|
||||
owner: "{{ xworkspace_console_user }}"
|
||||
group: "{{ xworkspace_console_user }}"
|
||||
group: "{{ 'staff' if ansible_os_family == 'Darwin' else xworkspace_console_user }}"
|
||||
mode: "0755"
|
||||
content: |
|
||||
#!/usr/bin/env bash
|
||||
exec "$HOME/.xinitrc"
|
||||
when: ansible_os_family != 'Darwin'
|
||||
|
||||
- name: Deploy AI Agentic Workspace console launcher script
|
||||
ansible.builtin.copy:
|
||||
dest: "{{ xworkspace_console_scripts_dir }}/start.sh"
|
||||
owner: "{{ xworkspace_console_user }}"
|
||||
group: "{{ xworkspace_console_user }}"
|
||||
group: "{{ 'staff' if ansible_os_family == 'Darwin' else xworkspace_console_user }}"
|
||||
mode: "0755"
|
||||
content: |
|
||||
#!/usr/bin/env bash
|
||||
@ -453,7 +483,7 @@
|
||||
ansible.builtin.copy:
|
||||
dest: "{{ xworkspace_console_scripts_dir }}/chrome-app.sh"
|
||||
owner: "{{ xworkspace_console_user }}"
|
||||
group: "{{ xworkspace_console_user }}"
|
||||
group: "{{ 'staff' if ansible_os_family == 'Darwin' else xworkspace_console_user }}"
|
||||
mode: "0755"
|
||||
content: |
|
||||
#!/usr/bin/env bash
|
||||
@ -495,7 +525,7 @@
|
||||
dest: "{{ xworkspace_console_repo_dir | dirname }}"
|
||||
remote_src: true
|
||||
owner: "{{ xworkspace_console_user }}"
|
||||
group: "{{ 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)
|
||||
@ -509,7 +539,7 @@
|
||||
ansible.builtin.copy:
|
||||
dest: "{{ xworkspace_console_runtime_marker }}"
|
||||
owner: "{{ xworkspace_console_user }}"
|
||||
group: "{{ xworkspace_console_user }}"
|
||||
group: "{{ 'staff' if ansible_os_family == 'Darwin' else xworkspace_console_user }}"
|
||||
mode: "0644"
|
||||
content: "{{ xworkspace_console_runtime_archive_stat.stat.checksum }}\n"
|
||||
when:
|
||||
@ -581,7 +611,7 @@
|
||||
ansible.builtin.copy:
|
||||
dest: "{{ xworkspace_console_config_dir }}/portal-services.json"
|
||||
owner: "{{ xworkspace_console_user }}"
|
||||
group: "{{ xworkspace_console_user }}"
|
||||
group: "{{ 'staff' if ansible_os_family == 'Darwin' else xworkspace_console_user }}"
|
||||
mode: "0644"
|
||||
content: "{{ {'services': xworkspace_console_portal_services} | to_nice_json }}\n"
|
||||
|
||||
@ -589,7 +619,7 @@
|
||||
ansible.builtin.copy:
|
||||
dest: "{{ xworkspace_console_config_dir }}/auth-token"
|
||||
owner: "{{ xworkspace_console_user }}"
|
||||
group: "{{ xworkspace_console_user }}"
|
||||
group: "{{ 'staff' if ansible_os_family == 'Darwin' else xworkspace_console_user }}"
|
||||
mode: "0600"
|
||||
content: "{{ xworkspace_console_auth_token }}\n"
|
||||
no_log: true
|
||||
@ -598,7 +628,7 @@
|
||||
ansible.builtin.copy:
|
||||
dest: "{{ xworkspace_console_home }}/.ai_workspace_auth_token"
|
||||
owner: "{{ xworkspace_console_user }}"
|
||||
group: "{{ xworkspace_console_user }}"
|
||||
group: "{{ 'staff' if ansible_os_family == 'Darwin' else xworkspace_console_user }}"
|
||||
mode: "0600"
|
||||
content: "{{ xworkspace_console_auth_token }}\n"
|
||||
no_log: true
|
||||
@ -607,7 +637,7 @@
|
||||
ansible.builtin.copy:
|
||||
dest: "{{ xworkspace_console_config_dir }}/portal.env"
|
||||
owner: "{{ xworkspace_console_user }}"
|
||||
group: "{{ xworkspace_console_user }}"
|
||||
group: "{{ 'staff' if ansible_os_family == 'Darwin' else xworkspace_console_user }}"
|
||||
mode: "0600"
|
||||
content: |
|
||||
AI_WORKSPACE_AUTH_TOKEN={{ xworkspace_console_auth_token }}
|
||||
@ -623,7 +653,7 @@
|
||||
ansible.builtin.copy:
|
||||
dest: "{{ xworkspace_console_home }}/.config/systemd/user/xworkspace-console.service"
|
||||
owner: "{{ xworkspace_console_user }}"
|
||||
group: "{{ xworkspace_console_user }}"
|
||||
group: "{{ 'staff' if ansible_os_family == 'Darwin' else xworkspace_console_user }}"
|
||||
mode: "0644"
|
||||
content: |
|
||||
[Unit]
|
||||
@ -640,12 +670,13 @@
|
||||
|
||||
[Install]
|
||||
WantedBy=default.target
|
||||
when: ansible_os_family != 'Darwin'
|
||||
|
||||
- name: Deploy XWorkspace API service
|
||||
ansible.builtin.copy:
|
||||
dest: "{{ xworkspace_console_home }}/.config/systemd/user/xworkspace-api.service"
|
||||
owner: "{{ xworkspace_console_user }}"
|
||||
group: "{{ xworkspace_console_user }}"
|
||||
group: "{{ 'staff' if ansible_os_family == 'Darwin' else xworkspace_console_user }}"
|
||||
mode: "0644"
|
||||
content: |
|
||||
[Unit]
|
||||
@ -663,12 +694,13 @@
|
||||
|
||||
[Install]
|
||||
WantedBy=default.target
|
||||
when: ansible_os_family != 'Darwin'
|
||||
|
||||
- name: Deploy AI Agentic Workspace ttyd service
|
||||
ansible.builtin.copy:
|
||||
dest: "{{ xworkspace_console_home }}/.config/systemd/user/xworkspace-ttyd.service"
|
||||
owner: "{{ xworkspace_console_user }}"
|
||||
group: "{{ xworkspace_console_user }}"
|
||||
group: "{{ 'staff' if ansible_os_family == 'Darwin' else xworkspace_console_user }}"
|
||||
mode: "0644"
|
||||
content: |
|
||||
[Unit]
|
||||
@ -684,6 +716,7 @@
|
||||
|
||||
[Install]
|
||||
WantedBy=default.target
|
||||
when: ansible_os_family != 'Darwin'
|
||||
|
||||
- name: Enable XWorkspace Console service
|
||||
ansible.builtin.file:
|
||||
@ -691,6 +724,7 @@
|
||||
dest: "{{ xworkspace_console_home }}/.config/systemd/user/default.target.wants/xworkspace-console.service"
|
||||
state: link
|
||||
become_user: "{{ xworkspace_console_user }}"
|
||||
when: ansible_os_family != 'Darwin'
|
||||
|
||||
- name: Enable XWorkspace API service
|
||||
ansible.builtin.file:
|
||||
@ -698,6 +732,7 @@
|
||||
dest: "{{ xworkspace_console_home }}/.config/systemd/user/default.target.wants/xworkspace-api.service"
|
||||
state: link
|
||||
become_user: "{{ xworkspace_console_user }}"
|
||||
when: ansible_os_family != 'Darwin'
|
||||
|
||||
- name: Enable AI Agentic Workspace ttyd service
|
||||
ansible.builtin.file:
|
||||
@ -705,6 +740,7 @@
|
||||
dest: "{{ xworkspace_console_home }}/.config/systemd/user/default.target.wants/xworkspace-ttyd.service"
|
||||
state: link
|
||||
become_user: "{{ xworkspace_console_user }}"
|
||||
when: ansible_os_family != 'Darwin'
|
||||
|
||||
- name: Enable AI Agentic Workspace LiteLLM service
|
||||
ansible.builtin.file:
|
||||
@ -713,6 +749,7 @@
|
||||
state: link
|
||||
force: true
|
||||
become_user: "{{ xworkspace_console_user }}"
|
||||
when: ansible_os_family != 'Darwin'
|
||||
|
||||
- name: Enable AI Agentic Workspace status timer
|
||||
ansible.builtin.file:
|
||||
@ -720,6 +757,7 @@
|
||||
dest: "{{ xworkspace_console_home }}/.config/systemd/user/timers.target.wants/xworkspace-status.timer"
|
||||
state: link
|
||||
become_user: "{{ xworkspace_console_user }}"
|
||||
when: ansible_os_family != 'Darwin'
|
||||
|
||||
- name: Kill legacy python http.server on port 7000
|
||||
ansible.builtin.shell: |
|
||||
@ -741,6 +779,7 @@
|
||||
- "{{ xworkspace_console_home }}/.config/systemd/user/default.target.wants/xworkspace-portal.service"
|
||||
- "{{ xworkspace_console_home }}/.config/systemd/user/default.target.wants/xworkspace-chrome.service"
|
||||
- "{{ xworkspace_console_home }}/.config/systemd/user/default.target.wants/xworkspace-console.target"
|
||||
when: ansible_os_family != 'Darwin'
|
||||
|
||||
- name: Remove legacy portal directory
|
||||
ansible.builtin.file:
|
||||
@ -754,6 +793,7 @@
|
||||
systemctl start "user@${uid}.service" || true
|
||||
runuser -u {{ xworkspace_console_user }} -- env XDG_RUNTIME_DIR="/run/user/${uid}" DBUS_SESSION_BUS_ADDRESS="unix:path=/run/user/${uid}/bus" systemctl --user daemon-reload
|
||||
become: true
|
||||
when: ansible_os_family != 'Darwin'
|
||||
|
||||
- name: Restart xworkspace-console service
|
||||
ansible.builtin.shell: |
|
||||
@ -762,6 +802,7 @@
|
||||
systemctl start "user@${uid}.service" || true
|
||||
runuser -u {{ xworkspace_console_user }} -- env XDG_RUNTIME_DIR="/run/user/${uid}" DBUS_SESSION_BUS_ADDRESS="unix:path=/run/user/${uid}/bus" systemctl --user restart xworkspace-console.service
|
||||
become: true
|
||||
when: ansible_os_family != 'Darwin'
|
||||
|
||||
- name: Restart xworkspace-api service
|
||||
ansible.builtin.shell: |
|
||||
@ -770,6 +811,7 @@
|
||||
systemctl start "user@${uid}.service" || true
|
||||
runuser -u {{ xworkspace_console_user }} -- env XDG_RUNTIME_DIR="/run/user/${uid}" DBUS_SESSION_BUS_ADDRESS="unix:path=/run/user/${uid}/bus" systemctl --user restart xworkspace-api.service
|
||||
become: true
|
||||
when: ansible_os_family != 'Darwin'
|
||||
|
||||
- name: Restart xworkspace-ttyd service
|
||||
ansible.builtin.shell: |
|
||||
@ -778,6 +820,7 @@
|
||||
systemctl start "user@${uid}.service" || true
|
||||
runuser -u {{ xworkspace_console_user }} -- env XDG_RUNTIME_DIR="/run/user/${uid}" DBUS_SESSION_BUS_ADDRESS="unix:path=/run/user/${uid}/bus" systemctl --user restart xworkspace-ttyd.service
|
||||
become: true
|
||||
when: ansible_os_family != 'Darwin'
|
||||
|
||||
- name: Hide XFCE desktop icons
|
||||
ansible.builtin.command: xfconf-query -c xfce4-desktop -p /desktop-icons/style -t int -s 0 --create
|
||||
@ -791,6 +834,7 @@
|
||||
owner: root
|
||||
group: root
|
||||
mode: "0755"
|
||||
when: ansible_os_family != 'Darwin'
|
||||
|
||||
- name: Deploy xworkspace-console public Caddy site
|
||||
ansible.builtin.copy:
|
||||
@ -802,19 +846,29 @@
|
||||
{{ xworkspace_console_domain }} {
|
||||
reverse_proxy 127.0.0.1:{{ xworkspace_console_port }}
|
||||
}
|
||||
when: xworkspace_console_public_access | bool
|
||||
when:
|
||||
- xworkspace_console_public_access | bool
|
||||
- ansible_os_family != 'Darwin'
|
||||
register: xworkspace_caddy_deploy
|
||||
|
||||
- name: Remove xworkspace-console public Caddy site when disabled
|
||||
ansible.builtin.file:
|
||||
path: "/etc/caddy/conf.d/{{ xworkspace_console_domain }}.caddy"
|
||||
state: absent
|
||||
when: not (xworkspace_console_public_access | bool)
|
||||
when:
|
||||
- not (xworkspace_console_public_access | bool)
|
||||
- ansible_os_family != 'Darwin'
|
||||
register: xworkspace_caddy_remove
|
||||
|
||||
- name: Reload Caddy if xworkspace-console proxy changed
|
||||
ansible.builtin.service:
|
||||
name: caddy
|
||||
state: reloaded
|
||||
when: (xworkspace_caddy_deploy.changed or xworkspace_caddy_remove.changed) and not ansible_check_mode
|
||||
when:
|
||||
- (xworkspace_caddy_deploy.changed or xworkspace_caddy_remove.changed) and not ansible_check_mode
|
||||
- ansible_os_family != 'Darwin'
|
||||
failed_when: false
|
||||
|
||||
- name: Import macOS specific XWorkspace console tasks
|
||||
ansible.builtin.include_tasks: xworkspace_console_macos.yml
|
||||
when: ansible_os_family == 'Darwin'
|
||||
|
||||
29
ttyd.plist.j2
Normal file
29
ttyd.plist.j2
Normal file
@ -0,0 +1,29 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>Label</key>
|
||||
<string>plus.svc.xworkspace.ttyd</string>
|
||||
<key>ProgramArguments</key>
|
||||
<array>
|
||||
<string>{{ xworkspace_console_ttyd_binary_path }}</string>
|
||||
<string>-i</string>
|
||||
<string>lo0</string>
|
||||
<string>-p</string>
|
||||
<string>{{ xworkspace_console_ttyd_port }}</string>
|
||||
<string>-O</string>
|
||||
<string>login</string>
|
||||
<string>bash</string>
|
||||
</array>
|
||||
<key>RunAtLoad</key>
|
||||
<true/>
|
||||
<key>KeepAlive</key>
|
||||
<true/>
|
||||
<key>WorkingDirectory</key>
|
||||
<string>{{ ansible_env.HOME }}</string>
|
||||
<key>StandardOutPath</key>
|
||||
<string>{{ ansible_env.HOME }}/.local/state/xworkspace/ttyd.log</string>
|
||||
<key>StandardErrorPath</key>
|
||||
<string>{{ ansible_env.HOME }}/.local/state/xworkspace/ttyd.err.log</string>
|
||||
</dict>
|
||||
</plist>
|
||||
37
xworkspace_console_macos.yml
Normal file
37
xworkspace_console_macos.yml
Normal file
@ -0,0 +1,37 @@
|
||||
---
|
||||
- name: Create launchd plist templates for XWorkspace
|
||||
ansible.builtin.template:
|
||||
src: "{{ item.src }}"
|
||||
dest: "{{ ansible_env.HOME }}/Library/LaunchAgents/plus.svc.xworkspace.{{ item.name }}.plist"
|
||||
mode: "0644"
|
||||
loop:
|
||||
- src: console.plist.j2
|
||||
name: console
|
||||
- src: api.plist.j2
|
||||
name: api
|
||||
- src: ttyd.plist.j2
|
||||
name: ttyd
|
||||
register: xworkspace_mac_plists
|
||||
|
||||
- name: Restart launchd agents for XWorkspace on template change
|
||||
ansible.builtin.command: "launchctl stop plus.svc.xworkspace.{{ item.item.name }}"
|
||||
loop: "{{ xworkspace_mac_plists.results }}"
|
||||
when: item.changed
|
||||
failed_when: false
|
||||
changed_when: false
|
||||
|
||||
- name: Reload launchd agents for XWorkspace
|
||||
ansible.builtin.command: "launchctl load -w {{ ansible_env.HOME }}/Library/LaunchAgents/plus.svc.xworkspace.{{ item.name }}.plist"
|
||||
loop:
|
||||
- { name: console }
|
||||
- { name: api }
|
||||
- { name: ttyd }
|
||||
register: launchctl_result
|
||||
changed_when: false
|
||||
failed_when: launchctl_result.rc != 0 and 'already loaded' not in launchctl_result.stderr
|
||||
|
||||
- name: Start launchd agents for XWorkspace
|
||||
ansible.builtin.command: "launchctl start plus.svc.xworkspace.{{ item.item.name }}"
|
||||
loop: "{{ xworkspace_mac_plists.results }}"
|
||||
when: item.changed
|
||||
changed_when: false
|
||||
Loading…
Reference in New Issue
Block a user