feat: unify ai workspace deployment auth
This commit is contained in:
parent
4b7c52057d
commit
e2ae564745
@ -41,7 +41,8 @@ gateway_openclaw_upstream_port: 18789
|
||||
gateway_openclaw_bind: loopback
|
||||
gateway_openclaw_mode: local
|
||||
gateway_openclaw_auth_mode: token
|
||||
gateway_openclaw_gateway_token: ""
|
||||
ai_workspace_auth_token: "{{ lookup('ansible.builtin.env', 'AI_WORKSPACE_AUTH_TOKEN') | default('', true) }}"
|
||||
gateway_openclaw_gateway_token: "{{ lookup('ansible.builtin.env', 'OPENCLAW_GATEWAY_TOKEN') | default(ai_workspace_auth_token, true) }}"
|
||||
gateway_openclaw_trusted_proxies:
|
||||
- 127.0.0.1
|
||||
- "::1"
|
||||
|
||||
@ -10,7 +10,8 @@ litellm_config_file: "{{ litellm_config_dir }}/config.yaml"
|
||||
litellm_env_file: "{{ litellm_config_dir }}/litellm.env"
|
||||
litellm_systemd_unit_path: "/etc/systemd/system/{{ litellm_service_name }}.service"
|
||||
|
||||
litellm_master_key: "{{ lookup('ansible.builtin.env', 'LITELLM_MASTER_KEY') | default('', true) }}"
|
||||
ai_workspace_auth_token: "{{ lookup('ansible.builtin.env', 'AI_WORKSPACE_AUTH_TOKEN') | default('', true) }}"
|
||||
litellm_master_key: "{{ lookup('ansible.builtin.env', 'LITELLM_MASTER_KEY') | default(ai_workspace_auth_token, true) }}"
|
||||
litellm_salt_key: "{{ lookup('ansible.builtin.env', 'LITELLM_SALT_KEY') | default(lookup('password', '/tmp/.litellm_salt_key length=32 chars=ascii_letters,digits'), true) }}"
|
||||
|
||||
litellm_ui_username: "{{ lookup('ansible.builtin.env', 'LITELLM_UI_USERNAME') | default('admin', true) }}"
|
||||
@ -62,4 +63,4 @@ litellm_retry_after: 60
|
||||
litellm_num_retries: 3
|
||||
litellm_request_timeout: 600
|
||||
litellm_max_parallel_requests: 1000
|
||||
litellm_telemetry: false
|
||||
litellm_telemetry: false
|
||||
|
||||
199
roles/vhosts/vault/files/init_vault_admin.sh
Executable file
199
roles/vhosts/vault/files/init_vault_admin.sh
Executable file
@ -0,0 +1,199 @@
|
||||
#!/usr/bin/env bash
|
||||
set -euo pipefail
|
||||
|
||||
usage() {
|
||||
cat <<'EOF'
|
||||
Usage:
|
||||
init_vault_admin.sh --password <password> [options]
|
||||
|
||||
Options:
|
||||
--username <name> Admin username. Default: admin
|
||||
--password <password> Required. Password for the admin userpass account.
|
||||
--vault-addr <addr> Vault API address. Default: http://127.0.0.1:8200
|
||||
--root-token <token> Root token. Defaults to VAULT_TOKEN or
|
||||
VAULT_SERVER_ROOT_ACCESS_TOKEN if set.
|
||||
--issuer <label> TOTP issuer label. Default: Vault
|
||||
--method-name <name> TOTP method name. Default: vault-admin-totp
|
||||
--output-dir <dir> Enrollment output directory. Default: /tmp
|
||||
--ui-url <url> UI login URL. Default: http://127.0.0.1:8200/ui/vault/auth?with=userpass
|
||||
-h, --help Show this help message
|
||||
EOF
|
||||
}
|
||||
|
||||
require_cmd() {
|
||||
if ! command -v "$1" >/dev/null 2>&1; then
|
||||
echo "missing required command: $1" >&2
|
||||
exit 1
|
||||
fi
|
||||
}
|
||||
|
||||
b64decode() {
|
||||
if base64 --help 2>&1 | grep -q -- '--decode'; then
|
||||
base64 --decode
|
||||
else
|
||||
base64 -D
|
||||
fi
|
||||
}
|
||||
|
||||
USERNAME="admin"
|
||||
PASSWORD=""
|
||||
VAULT_ADDR="${VAULT_ADDR:-http://127.0.0.1:8200}"
|
||||
ROOT_TOKEN="${VAULT_TOKEN:-}"
|
||||
if [[ -z "$ROOT_TOKEN" && -n "${VAULT_SERVER_ROOT_ACCESS_TOKEN:-}" ]]; then
|
||||
ROOT_TOKEN="${VAULT_SERVER_ROOT_ACCESS_TOKEN}"
|
||||
fi
|
||||
ISSUER="Vault"
|
||||
METHOD_NAME="vault-admin-totp"
|
||||
OUTPUT_DIR="/tmp"
|
||||
UI_URL="http://127.0.0.1:8200/ui/vault/auth?with=userpass"
|
||||
POLICY_NAME="vault-admins"
|
||||
ENFORCEMENT_NAME="admin-userpass"
|
||||
|
||||
while [[ $# -gt 0 ]]; do
|
||||
case "$1" in
|
||||
--username)
|
||||
USERNAME="${2:-}"
|
||||
shift 2
|
||||
;;
|
||||
--password)
|
||||
PASSWORD="${2:-}"
|
||||
shift 2
|
||||
;;
|
||||
--vault-addr)
|
||||
VAULT_ADDR="${2:-}"
|
||||
shift 2
|
||||
;;
|
||||
--root-token)
|
||||
ROOT_TOKEN="${2:-}"
|
||||
shift 2
|
||||
;;
|
||||
--issuer)
|
||||
ISSUER="${2:-}"
|
||||
shift 2
|
||||
;;
|
||||
--method-name)
|
||||
METHOD_NAME="${2:-}"
|
||||
shift 2
|
||||
;;
|
||||
--output-dir)
|
||||
OUTPUT_DIR="${2:-}"
|
||||
shift 2
|
||||
;;
|
||||
--ui-url)
|
||||
UI_URL="${2:-}"
|
||||
shift 2
|
||||
;;
|
||||
-h|--help)
|
||||
usage
|
||||
exit 0
|
||||
;;
|
||||
*)
|
||||
echo "unknown argument: $1" >&2
|
||||
usage >&2
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
done
|
||||
|
||||
if [[ -z "$PASSWORD" ]]; then
|
||||
echo "--password is required" >&2
|
||||
usage >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [[ -z "$ROOT_TOKEN" ]]; then
|
||||
echo "root token missing: pass --root-token or export VAULT_TOKEN first" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
require_cmd vault
|
||||
require_cmd jq
|
||||
require_cmd curl
|
||||
require_cmd base64
|
||||
|
||||
export VAULT_ADDR
|
||||
export VAULT_TOKEN="$ROOT_TOKEN"
|
||||
|
||||
if ! vault status >/dev/null 2>&1; then
|
||||
echo "unable to reach Vault at $VAULT_ADDR" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if ! vault auth list -format=json | jq -e 'has("userpass/")' >/dev/null; then
|
||||
vault auth enable userpass >/dev/null
|
||||
fi
|
||||
vault auth tune -listing-visibility=unauth userpass/ >/dev/null
|
||||
|
||||
tmp_policy="$(mktemp)"
|
||||
trap 'rm -f "$tmp_policy"' EXIT
|
||||
cat >"$tmp_policy" <<'POL'
|
||||
path "*" {
|
||||
capabilities = ["create", "read", "update", "delete", "list", "patch", "sudo"]
|
||||
}
|
||||
POL
|
||||
vault policy write "$POLICY_NAME" "$tmp_policy" >/dev/null
|
||||
|
||||
vault write "auth/userpass/users/${USERNAME}" \
|
||||
password="$PASSWORD" \
|
||||
token_policies="$POLICY_NAME" >/dev/null
|
||||
|
||||
userpass_accessor="$(vault auth list -format=json | jq -r '."userpass/".accessor')"
|
||||
|
||||
methods_json="$(curl -sS \
|
||||
-H "X-Vault-Token: ${VAULT_TOKEN}" \
|
||||
-H "X-Vault-Request: true" \
|
||||
-X LIST \
|
||||
"${VAULT_ADDR}/v1/identity/mfa/method/totp")"
|
||||
method_id="$(printf '%s' "$methods_json" | jq -r --arg method_name "$METHOD_NAME" '.data.key_info // {} | to_entries[]? | select(.value.name == $method_name) | .key' | head -n1)"
|
||||
|
||||
if [[ -z "$method_id" ]]; then
|
||||
method_json="$(vault write -format=json identity/mfa/method/totp \
|
||||
method_name="$METHOD_NAME" \
|
||||
issuer="$ISSUER" \
|
||||
period=30 \
|
||||
digits=6 \
|
||||
algorithm=SHA1 \
|
||||
skew=1 \
|
||||
max_validation_attempts=5)"
|
||||
method_id="$(printf '%s' "$method_json" | jq -r '.data.method_id // .data.id')"
|
||||
fi
|
||||
|
||||
bootstrap_json="$(vault write -format=json "auth/userpass/login/${USERNAME}" password="$PASSWORD")"
|
||||
entity_id="$(printf '%s' "$bootstrap_json" | jq -r '.auth.entity_id')"
|
||||
bootstrap_token="$(printf '%s' "$bootstrap_json" | jq -r '.auth.client_token')"
|
||||
|
||||
mkdir -p "$OUTPUT_DIR"
|
||||
enrollment_json="${OUTPUT_DIR}/vault-${USERNAME}-totp.json"
|
||||
enrollment_png="${OUTPUT_DIR}/vault-${USERNAME}-totp.png"
|
||||
enrollment_uri="${OUTPUT_DIR}/vault-${USERNAME}-totp-uri.txt"
|
||||
|
||||
vault write identity/mfa/method/totp/admin-destroy \
|
||||
method_id="$method_id" \
|
||||
entity_id="$entity_id" >/dev/null 2>&1 || true
|
||||
|
||||
vault write -format=json identity/mfa/method/totp/admin-generate \
|
||||
method_id="$method_id" \
|
||||
entity_id="$entity_id" >"$enrollment_json"
|
||||
|
||||
jq -r '.data.barcode' "$enrollment_json" | b64decode >"$enrollment_png"
|
||||
jq -r '.data.url' "$enrollment_json" >"$enrollment_uri"
|
||||
chmod 600 "$enrollment_json" "$enrollment_png" "$enrollment_uri"
|
||||
|
||||
vault write "identity/mfa/login-enforcement/${ENFORCEMENT_NAME}" \
|
||||
mfa_method_ids="$method_id" \
|
||||
auth_method_accessors="$userpass_accessor" >/dev/null
|
||||
|
||||
vault token revoke "$bootstrap_token" >/dev/null || true
|
||||
|
||||
cat <<EOF
|
||||
vault_addr=$VAULT_ADDR
|
||||
username=$USERNAME
|
||||
policy=$POLICY_NAME
|
||||
method_id=$method_id
|
||||
userpass_accessor=$userpass_accessor
|
||||
entity_id=$entity_id
|
||||
enrollment_json=$enrollment_json
|
||||
enrollment_png=$enrollment_png
|
||||
enrollment_uri=$enrollment_uri
|
||||
ui_url=$UI_URL
|
||||
EOF
|
||||
@ -2,3 +2,18 @@
|
||||
script: files/setup.sh {{ domain }} {{ namespace }} {{ item.secret_name }} {{ vault_public_access | bool | lower }}
|
||||
loop: "{{ tls }}"
|
||||
when: inventory_hostname in groups[group]
|
||||
|
||||
- name: Bootstrap Vault admin userpass auth
|
||||
ansible.builtin.script: >-
|
||||
files/init_vault_admin.sh
|
||||
--username {{ vault_admin_username | quote }}
|
||||
--password {{ vault_admin_password | quote }}
|
||||
--vault-addr {{ vault_admin_addr | quote }}
|
||||
--root-token {{ vault_server_root_access_token | quote }}
|
||||
--output-dir {{ vault_admin_output_dir | quote }}
|
||||
--ui-url {{ vault_admin_ui_url | quote }}
|
||||
no_log: true
|
||||
when:
|
||||
- not ansible_check_mode
|
||||
- inventory_hostname in groups[group]
|
||||
- vault_admin_init_enabled | bool
|
||||
|
||||
@ -2,6 +2,14 @@ group: master
|
||||
namespace: vault
|
||||
# When false, disables the Ingress for public access.
|
||||
vault_public_access: false
|
||||
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_admin_init_enabled: "{{ (vault_server_root_access_token | trim | length > 0) and (vault_admin_password | trim | length > 0) }}"
|
||||
vault_admin_username: admin
|
||||
vault_admin_password: "{{ lookup('ansible.builtin.env', 'VAULT_ADMIN_PASSWORD') | default(ai_workspace_auth_token, true) }}"
|
||||
vault_admin_addr: "{{ lookup('ansible.builtin.env', 'VAULT_ADDR') | default('http://127.0.0.1:8200', true) }}"
|
||||
vault_admin_ui_url: "{{ vault_admin_addr }}/ui/vault/auth?with=userpass"
|
||||
vault_admin_output_dir: "{{ lookup('ansible.builtin.env', 'VAULT_ADMIN_OUTPUT_DIR') | default('/tmp', true) }}"
|
||||
update_secret: true
|
||||
tls:
|
||||
- secret_name: vault-tls
|
||||
|
||||
@ -3,7 +3,8 @@ xworkmate_bridge_service_name: xworkmate-bridge
|
||||
xworkmate_bridge_service_user: ubuntu
|
||||
xworkmate_bridge_service_group: ubuntu
|
||||
xworkmate_bridge_service_home: "/home/{{ xworkmate_bridge_service_user }}"
|
||||
xworkmate_bridge_auth_token: "{{ lookup('ansible.builtin.env', 'BRIDGE_AUTH_TOKEN') | default(lookup('ansible.builtin.env', 'INTERNAL_SERVICE_TOKEN') | default('', true), true) }}"
|
||||
ai_workspace_auth_token: "{{ lookup('ansible.builtin.env', 'AI_WORKSPACE_AUTH_TOKEN') | default('', true) }}"
|
||||
xworkmate_bridge_auth_token: "{{ lookup('ansible.builtin.env', 'BRIDGE_AUTH_TOKEN') | default(lookup('ansible.builtin.env', 'XWORKMATE_BRIDGE_AUTH_TOKEN') | default(lookup('ansible.builtin.env', 'INTERNAL_SERVICE_TOKEN') | default(ai_workspace_auth_token, true), true), true) }}"
|
||||
xworkmate_bridge_review_auth_token: "{{ lookup('ansible.builtin.env', 'BRIDGE_REVIEW_AUTH_TOKEN') | default('', true) }}"
|
||||
xworkmate_bridge_listen_host: 127.0.0.1
|
||||
xworkmate_bridge_listen_port: 8787
|
||||
@ -43,14 +44,15 @@ deploy_acp_gemini: true
|
||||
deploy_acp_hermes: true
|
||||
|
||||
# Unified domain settings
|
||||
xworkmate_bridge_domain: xworkmate-bridge.svc.plus
|
||||
ai_workspace_public_domain: "{{ lookup('ansible.builtin.env', 'SERVER_DOMAIN') | default(lookup('ansible.builtin.env', 'ACP_BRIDGE_DOMAIN') | default(lookup('ansible.builtin.env', 'BRIDGE_DOMAIN') | default('xworkmate-bridge.svc.plus', true), true), true) }}"
|
||||
xworkmate_bridge_domain: "{{ lookup('ansible.builtin.env', 'XWORKMATE_BRIDGE_DOMAIN') | default(ai_workspace_public_domain, true) }}"
|
||||
|
||||
# When false, disables public Caddy access to XWorkmate Bridge.
|
||||
xworkmate_bridge_public_access: "{{ true if ai_workspace_security_level != 'strict' else false }}"
|
||||
|
||||
xworkmate_bridge_public_base_url: https://xworkmate-bridge.svc.plus
|
||||
xworkmate_bridge_service_domain: xworkmate-bridge.svc.plus
|
||||
xworkmate_bridge_service_public_base_url: https://xworkmate-bridge.svc.plus
|
||||
xworkmate_bridge_public_base_url: "https://{{ xworkmate_bridge_domain }}"
|
||||
xworkmate_bridge_service_domain: "{{ xworkmate_bridge_domain }}"
|
||||
xworkmate_bridge_service_public_base_url: "https://{{ xworkmate_bridge_domain }}"
|
||||
xworkmate_bridge_validation_origin: https://xworkmate.svc.plus
|
||||
|
||||
# Caddy configuration paths
|
||||
|
||||
@ -11,14 +11,71 @@
|
||||
xworkspace_console_root: /home/ubuntu/xworkspace
|
||||
xworkspace_console_repo_dir: /home/ubuntu/xworkspace-console
|
||||
xworkspace_console_dashboard_dir: /home/ubuntu/xworkspace-console/dashboard
|
||||
xworkspace_console_api_dir: /home/ubuntu/xworkspace-console/api
|
||||
xworkspace_console_scripts_dir: /home/ubuntu/xworkspace/scripts
|
||||
xworkspace_console_config_dir: /home/ubuntu/.config/xworkspace
|
||||
xworkspace_console_url: http://127.0.0.1:17000
|
||||
xworkspace_console_port: 17000
|
||||
xworkspace_console_api_port: 8788
|
||||
xworkspace_console_ttyd_port: 7681
|
||||
xworkspace_console_enable_ttyd: true
|
||||
xworkspace_console_install_chrome: true
|
||||
xworkspace_console_autostart_enabled: true
|
||||
xworkspace_console_ttyd_binary_path: /usr/local/bin/ttyd
|
||||
ai_workspace_auth_token: "{{ lookup('ansible.builtin.env', 'AI_WORKSPACE_AUTH_TOKEN') | default('', true) }}"
|
||||
xworkspace_console_auth_token: >-
|
||||
{{ lookup('ansible.builtin.env', 'XWORKSPACE_CONSOLE_AUTH_TOKEN')
|
||||
| default(lookup('ansible.builtin.env', 'AI_WORKSPACE_AUTH_TOKEN'), true)
|
||||
| default(lookup('ansible.builtin.env', 'BRIDGE_AUTH_TOKEN'), true)
|
||||
| default(lookup('ansible.builtin.env', 'XWORKMATE_BRIDGE_AUTH_TOKEN'), true)
|
||||
| default(lookup('ansible.builtin.env', 'INTERNAL_SERVICE_TOKEN'), true) }}
|
||||
xworkspace_console_review_auth_token: "{{ lookup('ansible.builtin.env', 'BRIDGE_REVIEW_AUTH_TOKEN') | default('', true) }}"
|
||||
xworkspace_console_portal_services:
|
||||
- key: litellm
|
||||
name: LiteLLM Admin UI
|
||||
url: http://localhost:4000/ui
|
||||
openMode: iframe
|
||||
healthUrl: http://127.0.0.1:4000/ui
|
||||
description: Model routing and provider administration.
|
||||
icon: chart
|
||||
match:
|
||||
- litellm
|
||||
- lite
|
||||
port: 4000
|
||||
role: model-router
|
||||
- key: openclaw
|
||||
name: OpenClaw
|
||||
url: http://127.0.0.1:18789/channels
|
||||
openMode: external
|
||||
healthUrl: http://127.0.0.1:18789/channels
|
||||
description: Gateway dashboard.
|
||||
icon: claw
|
||||
match:
|
||||
- openclaw
|
||||
- gateway
|
||||
port: 18789
|
||||
role: gateway
|
||||
- key: vault
|
||||
name: Vault Server
|
||||
url: http://127.0.0.1:8200/ui
|
||||
openMode: external
|
||||
healthUrl: http://127.0.0.1:8200/ui
|
||||
description: Vault UI.
|
||||
icon: shield
|
||||
match:
|
||||
- vault
|
||||
port: 8200
|
||||
- key: terminal
|
||||
name: Terminal
|
||||
url: http://127.0.0.1:7681
|
||||
openMode: iframe
|
||||
healthUrl: http://127.0.0.1:7681
|
||||
description: Local ttyd terminal.
|
||||
icon: terminal
|
||||
match:
|
||||
- ttyd
|
||||
- terminal
|
||||
port: 7681
|
||||
tasks:
|
||||
- name: Install Google Chrome apt repository prerequisites
|
||||
ansible.builtin.apt:
|
||||
@ -130,6 +187,7 @@
|
||||
- "{{ 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"
|
||||
@ -390,6 +448,48 @@
|
||||
npm install && npm run build
|
||||
become_user: "{{ xworkspace_console_user }}"
|
||||
|
||||
- name: Deploy AI Workspace portal service configuration
|
||||
ansible.builtin.copy:
|
||||
dest: "{{ xworkspace_console_config_dir }}/portal-services.json"
|
||||
owner: "{{ xworkspace_console_user }}"
|
||||
group: "{{ xworkspace_console_user }}"
|
||||
mode: "0644"
|
||||
content: "{{ {'services': xworkspace_console_portal_services} | to_nice_json }}\n"
|
||||
|
||||
- name: Deploy AI Workspace portal token file
|
||||
ansible.builtin.copy:
|
||||
dest: "{{ xworkspace_console_config_dir }}/auth-token"
|
||||
owner: "{{ xworkspace_console_user }}"
|
||||
group: "{{ xworkspace_console_user }}"
|
||||
mode: "0600"
|
||||
content: "{{ xworkspace_console_auth_token }}\n"
|
||||
no_log: true
|
||||
|
||||
- name: Deploy AI Workspace shared auth token file
|
||||
ansible.builtin.copy:
|
||||
dest: "{{ xworkspace_console_home }}/.ai_workspace_auth_token"
|
||||
owner: "{{ xworkspace_console_user }}"
|
||||
group: "{{ xworkspace_console_user }}"
|
||||
mode: "0600"
|
||||
content: "{{ xworkspace_console_auth_token }}\n"
|
||||
no_log: true
|
||||
|
||||
- name: Deploy XWorkspace API environment
|
||||
ansible.builtin.copy:
|
||||
dest: "{{ xworkspace_console_config_dir }}/portal.env"
|
||||
owner: "{{ xworkspace_console_user }}"
|
||||
group: "{{ xworkspace_console_user }}"
|
||||
mode: "0600"
|
||||
content: |
|
||||
AI_WORKSPACE_AUTH_TOKEN={{ xworkspace_console_auth_token }}
|
||||
XWORKSPACE_CONSOLE_AUTH_TOKEN={{ xworkspace_console_auth_token }}
|
||||
BRIDGE_AUTH_TOKEN={{ xworkspace_console_auth_token }}
|
||||
BRIDGE_REVIEW_AUTH_TOKEN={{ xworkspace_console_review_auth_token }}
|
||||
XWORKMATE_BRIDGE_AUTH_TOKEN={{ xworkspace_console_auth_token }}
|
||||
INTERNAL_SERVICE_TOKEN={{ xworkspace_console_auth_token }}
|
||||
XWORKSPACE_PORTAL_SERVICES_FILE={{ xworkspace_console_config_dir }}/portal-services.json
|
||||
no_log: true
|
||||
|
||||
- name: Deploy XWorkspace Console service
|
||||
ansible.builtin.copy:
|
||||
dest: "{{ xworkspace_console_home }}/.config/systemd/user/xworkspace-console.service"
|
||||
@ -412,6 +512,29 @@
|
||||
[Install]
|
||||
WantedBy=default.target
|
||||
|
||||
- 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 }}"
|
||||
mode: "0644"
|
||||
content: |
|
||||
[Unit]
|
||||
Description=XWorkspace status API
|
||||
After=network-online.target
|
||||
Wants=network-online.target
|
||||
|
||||
[Service]
|
||||
Type=simple
|
||||
WorkingDirectory={{ xworkspace_console_api_dir }}
|
||||
EnvironmentFile={{ xworkspace_console_config_dir }}/portal.env
|
||||
ExecStart=/usr/bin/env go run .
|
||||
Restart=always
|
||||
RestartSec=2
|
||||
|
||||
[Install]
|
||||
WantedBy=default.target
|
||||
|
||||
- name: Deploy AI Agentic Workspace ttyd service
|
||||
ansible.builtin.copy:
|
||||
dest: "{{ xworkspace_console_home }}/.config/systemd/user/xworkspace-ttyd.service"
|
||||
@ -426,7 +549,7 @@
|
||||
|
||||
[Service]
|
||||
Type=simple
|
||||
ExecStart=/usr/bin/ttyd -i lo -p {{ xworkspace_console_ttyd_port }} -O login bash
|
||||
ExecStart={{ xworkspace_console_ttyd_binary_path }} -i lo -p {{ xworkspace_console_ttyd_port }} -O login bash
|
||||
Restart=always
|
||||
RestartSec=2
|
||||
|
||||
@ -440,6 +563,13 @@
|
||||
state: link
|
||||
become_user: "{{ xworkspace_console_user }}"
|
||||
|
||||
- name: Enable XWorkspace API service
|
||||
ansible.builtin.file:
|
||||
src: "{{ xworkspace_console_home }}/.config/systemd/user/xworkspace-api.service"
|
||||
dest: "{{ xworkspace_console_home }}/.config/systemd/user/default.target.wants/xworkspace-api.service"
|
||||
state: link
|
||||
become_user: "{{ xworkspace_console_user }}"
|
||||
|
||||
- name: Enable AI Agentic Workspace ttyd service
|
||||
ansible.builtin.file:
|
||||
src: "{{ xworkspace_console_home }}/.config/systemd/user/xworkspace-ttyd.service"
|
||||
@ -490,17 +620,34 @@
|
||||
|
||||
- name: Reload systemd user daemon
|
||||
ansible.builtin.shell: |
|
||||
su - {{ xworkspace_console_user }} -c "systemctl --user daemon-reload"
|
||||
uid="$(id -u {{ xworkspace_console_user }})"
|
||||
loginctl enable-linger {{ xworkspace_console_user }} || true
|
||||
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
|
||||
|
||||
- name: Restart xworkspace-console service
|
||||
ansible.builtin.shell: |
|
||||
su - {{ xworkspace_console_user }} -c "systemctl --user restart xworkspace-console.service"
|
||||
uid="$(id -u {{ xworkspace_console_user }})"
|
||||
loginctl enable-linger {{ xworkspace_console_user }} || true
|
||||
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
|
||||
|
||||
- name: Restart xworkspace-api service
|
||||
ansible.builtin.shell: |
|
||||
uid="$(id -u {{ xworkspace_console_user }})"
|
||||
loginctl enable-linger {{ xworkspace_console_user }} || true
|
||||
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
|
||||
|
||||
- name: Restart xworkspace-ttyd service
|
||||
ansible.builtin.shell: |
|
||||
su - {{ xworkspace_console_user }} -c "systemctl --user restart xworkspace-ttyd.service"
|
||||
uid="$(id -u {{ xworkspace_console_user }})"
|
||||
loginctl enable-linger {{ xworkspace_console_user }} || true
|
||||
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
|
||||
|
||||
- name: Hide XFCE desktop icons
|
||||
|
||||
Loading…
Reference in New Issue
Block a user