--- - name: Provision Proxmox CT and deploy AWatch-rus hosts: proxmox gather_facts: false vars: proxmox_bootstrap_dir: "/tmp/aw-rus-bootstrap" proxmox_ct_net0: >- name=eth0,bridge={{ proxmox_ct_bridge }},ip={{ proxmox_ct_ip }},gw={{ proxmox_ct_gw }}{% if proxmox_ct_vlan | default('') | length > 0 %},tag={{ proxmox_ct_vlan }}{% endif %} aw_bootstrap_files: - install_aw_server.sh - apply_webui_ru_patch.sh - activitywatch-server.service - aw-server.env.example - aw-ru-patch.js - aw-sw-cleanup.js tasks: - name: Validate required Proxmox variables ansible.builtin.assert: that: - proxmox_ct_id is defined - proxmox_ct_hostname is defined - proxmox_ct_storage is defined - proxmox_ct_template is defined - proxmox_ct_rootfs_size is defined - proxmox_ct_cores is defined - proxmox_ct_memory is defined - proxmox_ct_swap is defined - proxmox_ct_bridge is defined - proxmox_ct_ip is defined - proxmox_ct_gw is defined - proxmox_ct_password is defined - proxmox_ct_unprivileged is defined - proxmox_ct_onboot is defined - proxmox_ct_features is defined - aw_repo_root is defined - aw_server_version is defined - aw_server_download_url is defined - aw_server_bind_host is defined - aw_server_port is defined - aw_server_webui_dir is defined - aw_server_data_dir is defined - aw_server_log_dir is defined - aw_server_user is defined - aw_server_group is defined fail_msg: "Missing required variables in ansible/group_vars/*.yml" - name: Check whether CT already exists ansible.builtin.command: argv: - pct - status - "{{ proxmox_ct_id }}" register: ct_status_check failed_when: false changed_when: false - name: Create CT when absent ansible.builtin.command: argv: - pct - create - "{{ proxmox_ct_id }}" - "{{ proxmox_ct_template }}" - --hostname - "{{ proxmox_ct_hostname }}" - --cores - "{{ proxmox_ct_cores }}" - --memory - "{{ proxmox_ct_memory }}" - --swap - "{{ proxmox_ct_swap }}" - --rootfs - "{{ proxmox_ct_storage }}:{{ proxmox_ct_rootfs_size }}" - --password - "{{ proxmox_ct_password }}" - --unprivileged - "{{ proxmox_ct_unprivileged }}" - --onboot - "{{ proxmox_ct_onboot }}" - --features - "{{ proxmox_ct_features }}" - --net0 - "{{ proxmox_ct_net0 }}" - --nameserver - "{{ proxmox_ct_nameserver | default('') }}" - --searchdomain - "{{ proxmox_ct_searchdomain | default('') }}" - --ostype - debian when: ct_status_check.rc != 0 - name: Check current CT runtime state ansible.builtin.command: argv: - pct - status - "{{ proxmox_ct_id }}" register: ct_runtime_status changed_when: false - name: Start CT when stopped ansible.builtin.command: argv: - pct - start - "{{ proxmox_ct_id }}" when: "'stopped' in ct_runtime_status.stdout" - name: Ensure bootstrap directory on Proxmox host ansible.builtin.file: path: "{{ proxmox_bootstrap_dir }}" state: directory mode: "0700" - name: Copy AW bootstrap files to Proxmox host temp ansible.builtin.copy: src: "{{ aw_repo_root }}/aw-server/{{ item }}" dest: "{{ proxmox_bootstrap_dir }}/{{ item }}" mode: "0644" loop: "{{ aw_bootstrap_files }}" - name: Bootstrap CT OS dependencies ansible.builtin.command: argv: - pct - exec - "{{ proxmox_ct_id }}" - -- - bash - -lc - | set -euo pipefail export DEBIAN_FRONTEND=noninteractive apt-get update apt-get install -y curl ca-certificates bash unzip xz-utils jq rsync openssh-server mkdir -p /root/bootstrap /etc/activitywatch systemctl enable ssh || true systemctl restart ssh || true - name: Push bootstrap files into CT ansible.builtin.command: argv: - pct - push - "{{ proxmox_ct_id }}" - "{{ proxmox_bootstrap_dir }}/{{ item }}" - "/root/bootstrap/{{ item }}" loop: "{{ aw_bootstrap_files }}" - name: Write AW server env file on Proxmox host temp ansible.builtin.copy: dest: "{{ proxmox_bootstrap_dir }}/aw-server.env" mode: "0600" content: | AW_SERVER_VERSION={{ aw_server_version }} AW_SERVER_DOWNLOAD_URL={{ aw_server_download_url }} AW_SERVER_BIND_HOST={{ aw_server_bind_host }} AW_SERVER_PORT={{ aw_server_port }} AW_SERVER_WEBUI_DIR={{ aw_server_webui_dir }} AW_SERVER_DATA_DIR={{ aw_server_data_dir }} AW_SERVER_LOG_DIR={{ aw_server_log_dir }} AW_SERVER_USER={{ aw_server_user }} AW_SERVER_GROUP={{ aw_server_group }} - name: Push AW server env into CT ansible.builtin.command: argv: - pct - push - "{{ proxmox_ct_id }}" - "{{ proxmox_bootstrap_dir }}/aw-server.env" - /etc/activitywatch/aw-server.env - name: Set mode for env inside CT ansible.builtin.command: argv: - pct - exec - "{{ proxmox_ct_id }}" - -- - chmod - "0600" - /etc/activitywatch/aw-server.env - name: Install server and apply RU patch inside CT ansible.builtin.command: argv: - pct - exec - "{{ proxmox_ct_id }}" - -- - bash - -lc - | set -euo pipefail chmod +x /root/bootstrap/install_aw_server.sh /root/bootstrap/apply_webui_ru_patch.sh bash /root/bootstrap/install_aw_server.sh bash /root/bootstrap/apply_webui_ru_patch.sh systemctl restart activitywatch-server.service - name: Validate AW API from inside CT ansible.builtin.command: argv: - pct - exec - "{{ proxmox_ct_id }}" - -- - bash - -lc - "curl -fsS http://127.0.0.1:{{ aw_server_port }}/api/0/info >/dev/null" - name: Validate RU patch hooks in index ansible.builtin.command: argv: - pct - exec - "{{ proxmox_ct_id }}" - -- - bash - -lc - "grep -q 'ru-patch-v5.js' {{ aw_server_webui_dir }}/index.html && grep -q 'sw-cleanup.js' {{ aw_server_webui_dir }}/index.html" - name: Show final endpoint ansible.builtin.debug: msg: - "CT {{ proxmox_ct_id }} is provisioned and configured." - "ActivityWatch endpoint: http://{{ proxmox_ct_ip | regex_replace('/[0-9]+$', '') }}:{{ aw_server_port }}"