---
- name: Развернуть сервер AWatch-rus
hosts: aw_server
become: true
gather_facts: true
vars:
aw_release_root: "/opt/activitywatch/releases"
aw_release_dir: "{{ aw_release_root }}/{{ aw_server_version }}"
aw_archive_path: "/tmp/activitywatch-{{ aw_server_version }}.zip"
aw_bootstrap_dir: "/tmp/aw-rus-bootstrap"
aw_release_install_dir: "{{ aw_release_root }}/aw-server-rust-{{ aw_server_version }}"
aw_ru_patch_cache_bust: "{{ lookup('file', aw_repo_root + '/aw-server/aw-ru-patch.js') | hash('sha1') | truncate(12, true, '') }}"
aw_sw_cleanup_cache_bust: "{{ lookup('file', aw_repo_root + '/aw-server/aw-sw-cleanup.js') | hash('sha1') | truncate(12, true, '') }}"
aw_worktime_classes: "{{ lookup('file', aw_repo_root + '/aw-server/settings/classes-worktime.json') | from_json }}"
aw_default_views: "{{ lookup('file', aw_repo_root + '/aw-server/settings/views-default.json') | from_json }}"
aw_rust_release_dir: "{{ (lookup('env', 'CARGO_TARGET_DIR') | default(aw_repo_root + '/adk-rust/target', true)) + '/release' }}"
tasks:
- name: Установить базовые пакеты
ansible.builtin.apt:
name:
- curl
- python3-venv
- python3-pip
- rsync
- tesseract-ocr
- tesseract-ocr-rus
- unzip
- jq
state: present
update_cache: true
- name: Установить пакеты для browser smoke проверки
ansible.builtin.apt:
name:
- chromium
- nodejs
- node-playwright
state: present
when: aw_browser_smoke_enabled | default(true) | bool
- name: Создать системную группу сервиса
ansible.builtin.group:
name: "{{ aw_server_group }}"
system: true
state: present
- name: Создать системную учётную запись сервиса
ansible.builtin.user:
name: "{{ aw_server_user }}"
group: "{{ aw_server_group }}"
home: "{{ aw_server_data_dir }}"
shell: /usr/sbin/nologin
system: true
create_home: false
- name: Создать обязательные каталоги
ansible.builtin.file:
path: "{{ item }}"
state: directory
mode: "0755"
loop:
- "{{ aw_release_root }}"
- "{{ aw_release_dir }}"
- "{{ aw_release_install_dir }}"
- /opt/activitywatch
- /opt/activitywatch/bin
- "{{ aw_server_webui_dir }}"
- "{{ aw_server_webui_dir }}/js"
- "{{ aw_server_data_dir }}"
- "{{ aw_server_db_path | dirname }}"
- "{{ aw_server_data_dir }}/.config"
- "{{ aw_server_data_dir }}/.config/activitywatch"
- "{{ aw_server_data_dir }}/.config/activitywatch/aw-server-rust"
- "{{ aw_server_data_dir }}/backups"
- "{{ aw_server_data_dir }}/slo"
- "{{ aw_server_data_dir }}/browser-smoke"
- "{{ aw_rus_health_state_dir }}"
- "{{ aw_rus_health_validation_dir }}"
- "{{ aw_server_log_dir }}"
- /etc/activitywatch
- /usr/local/lib/aw-rus-browser-smoke
- "{{ aw_bootstrap_dir }}"
- name: Настроить каталоги ActivityWatch с владельцем сервиса
ansible.builtin.file:
path: "{{ item }}"
state: directory
owner: "{{ aw_server_user }}"
group: "{{ aw_server_group }}"
mode: "0755"
loop:
- /opt/activitywatch
- /opt/activitywatch/bin
- "{{ aw_release_root }}"
- "{{ aw_release_dir }}"
- "{{ aw_release_install_dir }}"
- "{{ aw_server_webui_dir }}"
- "{{ aw_server_webui_dir }}/js"
- "{{ aw_server_data_dir }}"
- "{{ aw_server_db_path | dirname }}"
- "{{ aw_server_data_dir }}/.config"
- "{{ aw_server_data_dir }}/.config/activitywatch"
- "{{ aw_server_data_dir }}/.config/activitywatch/aw-server-rust"
- "{{ aw_server_data_dir }}/backups"
- "{{ aw_server_data_dir }}/slo"
- "{{ aw_server_data_dir }}/browser-smoke"
- "{{ aw_rus_health_state_dir }}"
- "{{ aw_rus_health_validation_dir }}"
- "{{ aw_server_log_dir }}"
- name: Проверить существующие health state files
ansible.builtin.stat:
path: "{{ item }}"
loop:
- "{{ aw_rus_health_state_dir }}/aw-rus-health.json"
- "{{ aw_rus_health_state_dir }}/aw-rus-health.txt"
- "{{ aw_rus_health_state_dir }}/dlp-health-check-counters.json"
register: aw_rus_health_state_files
- name: Нормализовать владельца существующих health state files
ansible.builtin.file:
path: "{{ item.stat.path }}"
owner: "{{ aw_server_user }}"
group: "{{ aw_server_group }}"
mode: "0644"
loop: "{{ aw_rus_health_state_files.results }}"
when: item.stat.exists | default(false)
- name: Удалить устаревшие Python entrypoints после Rust migration
ansible.builtin.file:
path: "{{ item }}"
state: absent
loop:
- /opt/activitywatch/aw-rus-ops/health-check.sh
- /opt/activitywatch/aw-rus-ops/hayabusa/aw-hayabusa-autoprocess.py
- /opt/activitywatch/aw-rus-ops/hayabusa/aw-hayabusa-case-alert.py
- /opt/activitywatch/aw-rus-ops/hayabusa/aw-hayabusa-from-windows.py
- /opt/activitywatch/aw-rus-ops/hayabusa/aw-hayabusa-link-case.py
- /opt/activitywatch/dlp-case-management/.venv
- /opt/activitywatch/dlp-case-management/case_rules.py
- /opt/activitywatch/dlp-case-management/case_schema.py
- /opt/activitywatch/dlp-case-management/case_service.py
- /opt/activitywatch/dlp-case-management/case_storage.py
- /opt/activitywatch/dlp-case-management/evidence_chain.py
- /opt/activitywatch/dlp-compliance/compliance_scheduler.py
- /opt/activitywatch/dlp-compliance/report_generator.py
- /opt/activitywatch/dlp-compliance/.venv
- /opt/activitywatch/dlp-integrations/cef_exporter.py
- /opt/activitywatch/dlp-integrations/syslog_forwarder.py
- /opt/activitywatch/dlp-integrations/webhook_sender.py
- /opt/activitywatch/dlp-integrations/.venv
- /opt/activitywatch/dlp-policy-engine/.venv
- /opt/activitywatch/dlp-policy-engine/policy_distributor.py
- /opt/activitywatch/dlp-policy-engine/policy_schema.py
- /opt/activitywatch/dlp-policy-engine/policy_service.py
- /opt/activitywatch/dlp-policy-engine/policy_storage.py
- /opt/activitywatch/scripts/aggregate_dlp_events.py
- /usr/local/bin/aw-dlp-influx-exporter.py
- /usr/local/bin/aw-extract-ioc-from-sigma.py
- /usr/local/bin/aw-rus-healthd.py
- /usr/local/bin/aw-slo-monitor.py
- /usr/local/bin/aw-worktime-afk-bridge.py
- /usr/local/bin/aw-worktime-api.py
- /usr/local/bin/aw-worktime-influx-exporter.py
- /usr/local/bin/aw-worktime-ui-bridge.py
- /usr/local/bin/dlp-admin-cli.py
- /usr/local/bin/merge_aw_server_dbs.py
- name: Установить prune script для локального state
ansible.builtin.copy:
src: "{{ aw_repo_root }}/aw-server/aw-prune-local-state.sh"
dest: /usr/local/bin/aw-prune-local-state.sh
owner: root
group: root
mode: "0755"
- name: Положить legacy prune script в server-side ops bundle
ansible.builtin.copy:
src: "{{ aw_repo_root }}/scripts/legacy/aw-prune-local-state.sh"
dest: /opt/activitywatch/aw-rus-ops/aw-prune-local-state.sh
owner: root
group: root
mode: "0755"
- name: Проверить локальный Rust prune local state
ansible.builtin.stat:
path: "{{ aw_rust_release_dir }}/aw-prune-local-state"
delegate_to: localhost
register: aw_prune_local_state_rust_binary
become: false
- name: Установить Rust prune local state
ansible.builtin.copy:
src: "{{ aw_rust_release_dir }}/aw-prune-local-state"
dest: /usr/local/bin/aw-prune-local-state-rust
owner: root
group: root
mode: "0755"
when: aw_prune_local_state_rust_binary.stat.exists | default(false)
- name: Ограничить рост journald на aw-server
ansible.builtin.copy:
dest: /etc/systemd/journald.conf.d/aw-rus-retention.conf
owner: root
group: root
mode: "0644"
content: |
[Journal]
SystemMaxUse={{ aw_server_journal_system_max_use }}
RuntimeMaxUse={{ aw_server_journal_runtime_max_use }}
SystemKeepFree={{ aw_server_journal_system_keep_free }}
register: aw_journald_dropin
- name: Установить systemd service prune локального state
ansible.builtin.copy:
dest: /etc/systemd/system/aw-prune-local-state.service
owner: root
group: root
mode: "0644"
content: |
[Unit]
Description=Prune ActivityWatch local backups and temp state
[Service]
Type=oneshot
Environment=AW_DATA_DIR={{ aw_server_data_dir }}
Environment=AW_BACKUP_RETENTION_DAYS={{ aw_server_backup_retention_days }}
Environment=AW_BACKUP_KEEP_LAST_DB={{ aw_server_backup_keep_last_db }}
Environment=AW_BACKUP_KEEP_LAST_JSON={{ aw_server_backup_keep_last_json }}
ExecStart=/usr/local/bin/aw-prune-local-state.sh
- name: Установить systemd timer prune локального state
ansible.builtin.copy:
dest: /etc/systemd/system/aw-prune-local-state.timer
owner: root
group: root
mode: "0644"
content: |
[Unit]
Description=Daily prune of ActivityWatch local backups and temp state
[Timer]
OnCalendar=*-*-* 04:40:00
Persistent=true
[Install]
WantedBy=timers.target
- name: Перечитать systemd после retention unit/drop-in
ansible.builtin.systemd:
daemon_reload: true
- name: Включить и запустить timer prune локального state
ansible.builtin.systemd:
name: aw-prune-local-state.timer
enabled: true
state: started
- name: Применить journald retention без простоя
ansible.builtin.command:
argv:
- systemctl
- restart
- systemd-journald
when: aw_journald_dropin.changed
failed_when: false
- name: Сжать существующий journald до нового лимита
ansible.builtin.command:
argv:
- journalctl
- --vacuum-size={{ aw_server_journal_system_max_use }}
changed_when: true
failed_when: false
- name: (Check mode) Пропустить установку релиза ActivityWatch
ansible.builtin.debug:
msg: "ansible_check_mode=true: download/unarchive/install of ActivityWatch release is skipped."
when: ansible_check_mode
- name: Установить релиз ActivityWatch (download/unarchive/install)
when: not ansible_check_mode
block:
- name: Скачать архив релиза ActivityWatch
ansible.builtin.get_url:
url: "{{ aw_server_download_url }}"
dest: "{{ aw_archive_path }}"
mode: "0644"
- name: Распаковать релиз ActivityWatch
ansible.builtin.unarchive:
src: "{{ aw_archive_path }}"
dest: "{{ aw_release_dir }}"
remote_src: true
extra_opts: ["-o"]
- name: Удалить временный архив ActivityWatch после распаковки
ansible.builtin.file:
path: "{{ aw_archive_path }}"
state: absent
- name: Найти распакованный каталог ActivityWatch
ansible.builtin.find:
paths: "{{ aw_release_dir }}"
recurse: true
file_type: directory
patterns: "activitywatch*"
register: aw_release_find
- name: Найти бинарный файл AW server
ansible.builtin.find:
paths: "{{ aw_release_dir }}"
recurse: true
file_type: file
patterns:
- aw-server-rust
- aw-server
register: aw_server_binary_find
- name: Найти index.html WebUI
ansible.builtin.find:
paths: "{{ aw_release_dir }}"
recurse: true
file_type: file
patterns:
- index.html
register: aw_webui_index_find
- name: Сохранить пути распакованного релиза (binary + webui index)
ansible.builtin.set_fact:
aw_release_extracted: "{{ (aw_release_find.files | default([]) | sort(attribute='path') | map(attribute='path') | list | first) | default('') }}"
aw_server_binary_path: >-
{{
(
(
(aw_server_binary_find.files | default([]) | sort(attribute='path') | map(attribute='path') | list)
| select('match', '.*/aw-server-rust$') | list | first
)
| default(
(
(aw_server_binary_find.files | default([]) | sort(attribute='path') | map(attribute='path') | list | first)
),
true
)
) | default('')
}}
aw_webui_index_path: >-
{{
(
(
(aw_webui_index_find.files | default([]) | sort(attribute='path') | map(attribute='path') | list)
| select('search', '/static/index\\.html$') | list | first
)
| default(
(
(aw_webui_index_find.files | default([]) | sort(attribute='path') | map(attribute='path') | list | first)
),
true
)
) | default('')
}}
- name: Сохранить каталог WebUI (dirname index.html)
ansible.builtin.set_fact:
aw_webui_source_path: "{{ aw_webui_index_path | dirname }}"
- name: Проверить, что компоненты релиза найдены
ansible.builtin.assert:
that:
- aw_release_extracted is defined
- aw_release_extracted | length > 0
- aw_server_binary_path is defined
- aw_server_binary_path | length > 0
- aw_webui_source_path is defined
- aw_webui_source_path | length > 0
fail_msg: "Не удалось найти бинарный файл или WebUI в распакованном релизе ActivityWatch."
- name: Создать каталог установленного релиза
ansible.builtin.file:
path: "{{ aw_release_install_dir }}"
state: directory
owner: "{{ aw_server_user }}"
group: "{{ aw_server_group }}"
mode: "0755"
- name: Установить бинарный файл AW server
ansible.builtin.copy:
remote_src: true
src: "{{ aw_server_binary_path }}"
dest: "{{ aw_release_install_dir }}/aw-server-rust"
owner: "{{ aw_server_user }}"
group: "{{ aw_server_group }}"
mode: "0755"
- name: Создать ссылку на активный бинарный файл AW server
ansible.builtin.file:
src: "{{ aw_release_install_dir }}/aw-server-rust"
dest: /opt/activitywatch/bin/aw-server-rust
owner: "{{ aw_server_user }}"
group: "{{ aw_server_group }}"
state: link
force: true
- name: Синхронизировать WebUI в RU каталог
ansible.builtin.command:
cmd: "rsync -a {{ aw_webui_source_path }}/ {{ aw_server_webui_dir }}/"
- name: Настроить владельца файлов /opt/activitywatch
ansible.builtin.file:
path: /opt/activitywatch
state: directory
owner: "{{ aw_server_user }}"
group: "{{ aw_server_group }}"
recurse: true
- name: Установить systemd service из шаблона репозитория
ansible.builtin.copy:
dest: /etc/systemd/system/activitywatch-server.service
mode: "0644"
content: >-
{{
lookup('file', aw_repo_root + '/aw-server/activitywatch-server.service')
| replace('__AW_SERVER_USER__', aw_server_user)
| replace('__AW_SERVER_GROUP__', aw_server_group)
| replace('__AW_SERVER_DATA_DIR__', aw_server_data_dir)
}}
notify:
- Перезагрузить systemd
- Перезапустить activitywatch
- name: (Check mode) Пропустить WebUI patch и запуск сервиса
ansible.builtin.debug:
msg: "ansible_check_mode=true: WebUI patch + service start + API checks are skipped."
when: ansible_check_mode
- name: Применить WebUI RU patch и запустить сервис
when: not ansible_check_mode
block:
- name: Скопировать RU patch файлы WebUI из репозитория
ansible.builtin.copy:
src: "{{ item.src }}"
dest: "{{ item.dest }}"
mode: "{{ item.mode }}"
owner: "{{ aw_server_user }}"
group: "{{ aw_server_group }}"
loop:
- { src: "{{ aw_repo_root }}/aw-server/aw-ru-patch.js", dest: "{{ aw_server_webui_dir }}/js/ru-patch-v5.js", mode: "0644" }
- { src: "{{ aw_repo_root }}/aw-server/aw-sw-cleanup.js", dest: "{{ aw_server_webui_dir }}/js/sw-cleanup.js", mode: "0644" }
- { src: "{{ aw_repo_root }}/aw-server/aw-worktime-panel.js", dest: "{{ aw_server_webui_dir }}/js/aw-worktime-panel.js", mode: "0644" }
- { src: "{{ aw_repo_root }}/aw-server/aw-host-groups.json", dest: "{{ aw_server_webui_dir }}/js/aw-host-groups.json", mode: "0644" }
- name: Создать каталог /opt/detmir/bootstrap для apply_webui_ru_patch.sh
ansible.builtin.file:
path: /opt/detmir/bootstrap
state: directory
mode: "0755"
- name: Скопировать RU patch файлы для apply_webui_ru_patch.sh (хотфиксы compiled JS чанков)
ansible.builtin.copy:
src: "{{ item.src }}"
dest: "{{ item.dest }}"
mode: "{{ item.mode }}"
loop:
- { src: "{{ aw_repo_root }}/aw-server/aw-ru-patch.js", dest: "/opt/detmir/bootstrap/aw-ru-patch.js", mode: "0644" }
- { src: "{{ aw_repo_root }}/aw-server/aw-sw-cleanup.js", dest: "/opt/detmir/bootstrap/aw-sw-cleanup.js", mode: "0644" }
- { src: "{{ aw_repo_root }}/aw-server/aw-worktime-panel.js", dest: "/opt/detmir/bootstrap/aw-worktime-panel.js", mode: "0644" }
- { src: "{{ aw_repo_root }}/aw-server/aw-host-groups.json", dest: "/opt/detmir/bootstrap/aw-host-groups.json", mode: "0644" }
- name: Скопировать apply_webui_ru_patch.sh скрипт
ansible.builtin.copy:
src: "{{ aw_repo_root }}/aw-server/apply_webui_ru_patch.sh"
dest: /opt/activitywatch/aw-server/apply_webui_ru_patch.sh
mode: "0755"
- name: Создать server-side ops bundle для ранних health helpers
ansible.builtin.file:
path: /opt/activitywatch/aw-rus-ops
state: directory
owner: root
group: root
mode: "0755"
- name: Установить wrapper aw-health-check до Influx проверок
ansible.builtin.copy:
src: "{{ aw_repo_root }}/aw-server/aw-health-check-wrapper.sh"
dest: /usr/local/bin/aw-health-check
owner: root
group: root
mode: "0755"
- name: Проверить локальный Rust aw-health-check до Influx проверок
ansible.builtin.stat:
path: "{{ aw_rust_release_dir }}/aw-health-check"
delegate_to: localhost
register: aw_health_check_rust_binary_early
become: false
- name: Установить Rust aw-health-check до Influx проверок
ansible.builtin.copy:
src: "{{ aw_rust_release_dir }}/aw-health-check"
dest: /usr/local/bin/aw-health-check-rust
owner: root
group: root
mode: "0755"
when: aw_health_check_rust_binary_early.stat.exists | default(false)
- name: Требовать Rust aw-health-check до Influx проверок
ansible.builtin.assert:
that:
- aw_health_check_rust_binary_early.stat.exists | default(false)
fail_msg: "Rust aw-health-check artifact is required at {{ aw_rust_release_dir }}/aw-health-check"
- name: Проверить локальный Rust aw-db-health до Influx проверок
ansible.builtin.stat:
path: "{{ aw_rust_release_dir }}/aw-db-health"
delegate_to: localhost
register: aw_db_health_rust_binary_early
become: false
- name: Установить Rust aw-db-health до Influx проверок
ansible.builtin.copy:
src: "{{ aw_rust_release_dir }}/aw-db-health"
dest: /usr/local/bin/aw-db-health
owner: root
group: root
mode: "0755"
when: aw_db_health_rust_binary_early.stat.exists | default(false)
- name: Проверить локальный Rust aw-ensure-reliability до Influx проверок
ansible.builtin.stat:
path: "{{ aw_rust_release_dir }}/aw-ensure-reliability"
delegate_to: localhost
register: aw_ensure_reliability_rust_binary_early
become: false
- name: Установить Rust aw-ensure-reliability до Influx проверок
ansible.builtin.copy:
src: "{{ aw_rust_release_dir }}/aw-ensure-reliability"
dest: /usr/local/bin/aw-ensure-reliability
owner: root
group: root
mode: "0755"
when: aw_ensure_reliability_rust_binary_early.stat.exists | default(false)
- name: Проверить локальный Rust aw-db-maintenance до Influx проверок
ansible.builtin.stat:
path: "{{ aw_rust_release_dir }}/aw-db-maintenance"
delegate_to: localhost
register: aw_db_maintenance_rust_binary_early
become: false
- name: Установить Rust aw-db-maintenance до Influx проверок
ansible.builtin.copy:
src: "{{ aw_rust_release_dir }}/aw-db-maintenance"
dest: /usr/local/bin/aw-db-maintenance
owner: root
group: root
mode: "0755"
when: aw_db_maintenance_rust_binary_early.stat.exists | default(false)
- name: Установить aw-db-maintenance service до Influx проверок
ansible.builtin.copy:
src: "{{ aw_repo_root }}/aw-server/aw-db-maintenance.service"
dest: /etc/systemd/system/aw-db-maintenance.service
owner: root
group: root
mode: "0644"
when: aw_db_maintenance_rust_binary_early.stat.exists | default(false)
- name: Установить aw-db-maintenance timer до Influx проверок
ansible.builtin.copy:
src: "{{ aw_repo_root }}/aw-server/aw-db-maintenance.timer"
dest: /etc/systemd/system/aw-db-maintenance.timer
owner: root
group: root
mode: "0644"
when: aw_db_maintenance_rust_binary_early.stat.exists | default(false)
- name: Включить weekly aw-db-maintenance timer до Influx проверок
ansible.builtin.systemd:
name: aw-db-maintenance.timer
enabled: true
state: started
daemon_reload: true
when: aw_db_maintenance_rust_binary_early.stat.exists | default(false)
- name: Прочитать текущий aw-server.env для сохранения Influx token
ansible.builtin.slurp:
path: /etc/activitywatch/aw-server.env
register: aw_existing_server_env_raw
failed_when: false
no_log: true
- name: Подготовить effective runtime values без вывода секретов
ansible.builtin.set_fact:
aw_existing_server_env_text: "{{ aw_existing_server_env_raw.content | default('') | b64decode }}"
aw_existing_worktime_influx_token: "{{ (aw_existing_server_env_raw.content | default('') | b64decode | regex_search('(?m)^AW_WORKTIME_INFLUX_TOKEN=.*$') | default('', true) | regex_replace('^AW_WORKTIME_INFLUX_TOKEN=', '')) }}"
aw_existing_dlp_influx_token: "{{ (aw_existing_server_env_raw.content | default('') | b64decode | regex_search('(?m)^AW_DLP_INFLUX_TOKEN=.*$') | default('', true) | regex_replace('^AW_DLP_INFLUX_TOKEN=', '')) }}"
aw_existing_monitored_windows_host: "{{ (aw_existing_server_env_raw.content | default('') | b64decode | regex_search('(?m)^AW_MONITORED_WINDOWS_HOST=.*$') | default('', true) | regex_replace('^AW_MONITORED_WINDOWS_HOST=', '')) }}"
aw_existing_monitored_windows_hostname: "{{ (aw_existing_server_env_raw.content | default('') | b64decode | regex_search('(?m)^AW_MONITORED_WINDOWS_HOSTNAME=.*$') | default('', true) | regex_replace('^AW_MONITORED_WINDOWS_HOSTNAME=', '')) }}"
no_log: true
- name: Выбрать effective Influx tokens
ansible.builtin.set_fact:
aw_effective_worktime_influx_token: "{{ (aw_worktime_influx_token | default('') | string) if ((aw_worktime_influx_token | default('') | string | length) > 0) else aw_existing_worktime_influx_token }}"
aw_effective_dlp_influx_token: "{{ (aw_dlp_influx_token | default('') | string) if ((aw_dlp_influx_token | default('') | string | length) > 0) else aw_existing_dlp_influx_token }}"
no_log: true
- name: Выбрать effective monitored Windows target
ansible.builtin.set_fact:
aw_effective_monitored_windows_host: >-
{{
(aw_monitored_windows_host | default('') | string)
if (
(aw_monitored_windows_host | default('') | string | length) > 0
and (aw_monitored_windows_host | default('') | string | regex_search('192\\.0\\.2\\.|198\\.51\\.100\\.|203\\.0\\.113\\.|<|>|HOST-EXAMPLE|WINDOWS_USER_EXAMPLE')) is none
)
else aw_existing_monitored_windows_host
}}
aw_effective_monitored_windows_hostname: >-
{{
(aw_monitored_windows_hostname | default('') | string)
if (
(aw_monitored_windows_hostname | default('') | string | length) > 0
and (aw_monitored_windows_hostname | default('') | string | regex_search('192\\.0\\.2\\.|198\\.51\\.100\\.|203\\.0\\.113\\.|<|>|HOST-EXAMPLE|WINDOWS_USER_EXAMPLE')) is none
)
else aw_existing_monitored_windows_hostname
}}
no_log: true
- name: Выбрать effective worktime host
ansible.builtin.set_fact:
aw_effective_worktime_host: >-
{{
(aw_worktime_host | default('') | string)
if (
(aw_worktime_host | default('') | string | length) > 0
and (aw_worktime_host | default('') | string | regex_search('192\\.0\\.2\\.|198\\.51\\.100\\.|203\\.0\\.113\\.|<|>|HOST-EXAMPLE|WINDOWS_USER_EXAMPLE')) is none
)
else aw_effective_monitored_windows_hostname
}}
no_log: true
- name: Проверить monitored Windows target для production healthd
ansible.builtin.assert:
that:
- (aw_effective_monitored_windows_host | default('') | string | length) > 0
- (aw_effective_monitored_windows_host | default('') | string | regex_search('192\\.0\\.2\\.|198\\.51\\.100\\.|203\\.0\\.113\\.|<|>|HOST-EXAMPLE|WINDOWS_USER_EXAMPLE')) is none
- (aw_effective_monitored_windows_hostname | default('') | string | length) > 0
- (aw_effective_monitored_windows_hostname | default('') | string | regex_search('192\\.0\\.2\\.|198\\.51\\.100\\.|203\\.0\\.113\\.|<|>|HOST-EXAMPLE|WINDOWS_USER_EXAMPLE')) is none
- (aw_effective_worktime_host | default('') | string | length) > 0
- (aw_effective_worktime_host | default('') | string | regex_search('192\\.0\\.2\\.|198\\.51\\.100\\.|203\\.0\\.113\\.|<|>|HOST-EXAMPLE|WINDOWS_USER_EXAMPLE')) is none
fail_msg: "aw-rus-healthd получил public example/TEST-NET Windows target. Задайте live значения в private inventory/env или сохраните их в runtime /etc/activitywatch/aw-server.env."
when: aw_server_post_deploy_health_check_enabled | default(true) | bool
- name: Проверить Influx token для AW worktime exporter
ansible.builtin.assert:
that:
- aw_effective_worktime_influx_token is defined
- aw_effective_worktime_influx_token | length > 0
- (aw_effective_worktime_influx_token | string | lower | regex_search('^(change_me|changeme|replace-me|replace_me|token|secret|password|api_key|influx_token|write_token|your_.*|<.*>)$')) is none
fail_msg: "aw_worktime_influx_enabled=true, но token пуст и в локальном env, и в текущем /etc/activitywatch/aw-server.env. Exporter будет падать и Grafana не получит worktime-ряды."
when: aw_worktime_influx_enabled | default(false) | bool
- name: Проверить Influx token для AW DLP exporter
ansible.builtin.assert:
that:
- aw_effective_dlp_influx_token is defined
- aw_effective_dlp_influx_token | length > 0
- (aw_effective_dlp_influx_token | string | lower | regex_search('^(change_me|changeme|replace-me|replace_me|token|secret|password|api_key|influx_token|write_token|your_.*|<.*>)$')) is none
fail_msg: "aw_dlp_influx_enabled=true, но token пуст и в локальном env, и в текущем /etc/activitywatch/aw-server.env. Exporter будет падать и Grafana не получит DLP-ряды."
when: aw_dlp_influx_enabled | default(false) | bool
- name: Проверить destination для AW worktime Influx exporter
ansible.builtin.assert:
that:
- (aw_worktime_influx_url | default('') | string | length) > 0
- "'192.0.2.' not in (aw_worktime_influx_url | default('') | string)"
- "'198.51.100.' not in (aw_worktime_influx_url | default('') | string)"
- "'203.0.113.' not in (aw_worktime_influx_url | default('') | string)"
- (aw_worktime_influx_org | default('') | string | length) > 0
- (aw_worktime_influx_org | default('') | string | lower | regex_search('example|change_me|changeme|replace-me|replace_me|your_|<|>')) is none
- (aw_worktime_influx_bucket | default('') | string | length) > 0
- (aw_worktime_influx_bucket | default('') | string | lower | regex_search('example|change_me|changeme|replace-me|replace_me|your_|<|>')) is none
- (aw_worktime_influx_hosts | default('') | string | length) > 0
- "'HOST-EXAMPLE' not in (aw_worktime_influx_hosts | default('') | string)"
- "'WINDOWS_USER_EXAMPLE' not in (aw_worktime_influx_hosts | default('') | string)"
fail_msg: "aw_worktime_influx_enabled=true, но URL/org/bucket/hosts похожи на public example/TEST-NET значения. Задайте live значения в private inventory/env, не в public repo."
when: aw_worktime_influx_enabled | default(false) | bool
- name: Проверить destination для AW DLP Influx exporter
ansible.builtin.assert:
that:
- (aw_dlp_influx_url | default('') | string | length) > 0
- "'192.0.2.' not in (aw_dlp_influx_url | default('') | string)"
- "'198.51.100.' not in (aw_dlp_influx_url | default('') | string)"
- "'203.0.113.' not in (aw_dlp_influx_url | default('') | string)"
- (aw_dlp_influx_org | default('') | string | length) > 0
- (aw_dlp_influx_org | default('') | string | lower | regex_search('example|change_me|changeme|replace-me|replace_me|your_|<|>')) is none
- (aw_dlp_influx_bucket | default('') | string | length) > 0
- (aw_dlp_influx_bucket | default('') | string | lower | regex_search('example|change_me|changeme|replace-me|replace_me|your_|<|>')) is none
- (aw_dlp_influx_hosts | default('') | string | length) > 0
- "'HOST-EXAMPLE' not in (aw_dlp_influx_hosts | default('') | string)"
- "'WINDOWS_USER_EXAMPLE' not in (aw_dlp_influx_hosts | default('') | string)"
fail_msg: "aw_dlp_influx_enabled=true, но URL/org/bucket/hosts похожи на public example/TEST-NET значения. Задайте live значения в private inventory/env, не в public repo."
when: aw_dlp_influx_enabled | default(false) | bool
- name: Записать /etc/activitywatch/aw-server.env перед хотфиксами
ansible.builtin.copy:
dest: /etc/activitywatch/aw-server.env
mode: "0640"
owner: root
group: root
content: |
AW_SERVER_BIND_HOST={{ aw_server_bind_host }}
AW_SERVER_PORT={{ aw_server_port }}
AW_SERVER_DATA_DIR={{ aw_server_data_dir }}
AW_SERVER_DB_PATH={{ aw_server_db_path }}
AW_SERVER_LOG_DIR={{ aw_server_log_dir }}
AW_SERVER_WEBUI_DIR={{ aw_server_webui_dir }}
AW_SERVER_USER={{ aw_server_user }}
AW_SERVER_GROUP={{ aw_server_group }}
AW_WORKTIME_REPORT_BASE={{ aw_worktime_report_base }}
AW_WORKTIME_TZ={{ aw_worktime_timezone }}
AW_WORKTIME_HOST={{ aw_effective_worktime_host | default(aw_effective_monitored_windows_hostname | default('HOST-EXAMPLE')) }}
AW_DLP_IOC_DIR={{ aw_dlp_ioc_workdir }}/output
AW_DLP_POLICY_ENGINE_BIND_HOST={{ aw_dlp_policy_engine_bind_host }}
AW_DLP_POLICY_ENGINE_PORT={{ aw_dlp_policy_engine_port }}
AW_DLP_POLICY_ENGINE_DB_PATH={{ aw_dlp_policy_engine_db_path }}
AW_DLP_CASE_BIND_HOST={{ aw_dlp_case_bind_host }}
AW_DLP_CASE_PORT={{ aw_dlp_case_port }}
AW_DLP_CASE_DB_PATH={{ aw_dlp_case_db_path }}
AW_DLP_COMPLIANCE_REPORT_DIR={{ aw_dlp_compliance_report_dir }}
AW_DLP_COMPLIANCE_TEMPLATE={{ aw_dlp_compliance_template_path }}
AW_SERVER_URL=http://127.0.0.1:5600
XDG_DATA_HOME={{ aw_server_data_dir }}/.local/share
XDG_CONFIG_HOME={{ aw_server_data_dir }}/.config
AW_WORKTIME_INFLUX_ENABLED={{ 'true' if (aw_worktime_influx_enabled | default(false) | bool) else 'false' }}
AW_WORKTIME_INFLUX_URL={{ aw_worktime_influx_url | default('') }}
AW_WORKTIME_INFLUX_ORG={{ aw_worktime_influx_org | default('proxmox') }}
AW_WORKTIME_INFLUX_BUCKET={{ aw_worktime_influx_bucket | default('aw_metrics') }}
AW_WORKTIME_INFLUX_HOSTS={{ aw_worktime_influx_hosts | default('HOST-EXAMPLE') }}
AW_WORKTIME_INFLUX_DAYS={{ aw_worktime_influx_days | default('today,yesterday') }}
AW_WORKTIME_INFLUX_TOKEN={{ aw_effective_worktime_influx_token | default('') }}
AW_WORKTIME_MANAGEMENT_HISTORY_DIR={{ aw_worktime_management_history_dir | default(aw_server_data_dir ~ '/worktime-management-history') }}
AW_WORKTIME_MANAGEMENT_HISTORY_DAYS={{ aw_worktime_management_history_days | default(31) }}
AW_WORKTIME_MANAGEMENT_HISTORY_RETENTION_DAYS={{ aw_worktime_management_history_retention_days | default(120) }}
AW_WORKTIME_MANAGER_OVERLOAD_COVERAGE_PCT={{ aw_worktime_manager_overload_coverage_pct | default(115) }}
AW_WORKTIME_MANAGER_TREND_MIN_POINTS={{ aw_worktime_manager_trend_min_points | default(3) }}
AW_WORKTIME_MANAGER_TREND_DELTA_PCT={{ aw_worktime_manager_trend_delta_pct | default(10) }}
AW_WORKTIME_MANAGER_OFF_HOURS_THRESHOLD_SECONDS={{ aw_worktime_manager_off_hours_threshold_seconds | default(1800) }}
AW_WORKTIME_MANAGER_INTERPRETATION_POLICY={{ aw_worktime_interpretation_policy_path | default('/etc/activitywatch/worktime-interpretation-policy.json') }}
AW_DLP_INFLUX_ENABLED={{ 'true' if (aw_dlp_influx_enabled | default(false) | bool) else 'false' }}
AW_DLP_INFLUX_URL={{ aw_dlp_influx_url | default('') }}
AW_DLP_INFLUX_ORG={{ aw_dlp_influx_org | default('proxmox') }}
AW_DLP_INFLUX_BUCKET={{ aw_dlp_influx_bucket | default('aw_metrics') }}
AW_DLP_INFLUX_HOSTS={{ aw_dlp_influx_hosts | default('HOST-EXAMPLE') }}
AW_DLP_INFLUX_LOOKBACK_DAYS={{ aw_dlp_influx_lookback_days | default(30) }}
AW_DLP_INFLUX_EVENT_LIMIT={{ aw_dlp_influx_event_limit | default(2000) }}
AW_DLP_INFLUX_TOKEN={{ aw_effective_dlp_influx_token | default('') }}
AW_DLP_AW_API_BASE=http://127.0.0.1:5600/api/0
AW_DLP_CASE_API_BASE=http://127.0.0.1:5602/api/0/dlp/cases
AW_EXPECT_START_OF_DAY={{ aw_worktime_start_of_day | default('') }}
AW_EXPECT_ALWAYS_ACTIVE_PATTERN={{ aw_server_always_active_pattern | default('') }}
AW_EXPECT_LANDINGPAGE={{ aw_server_landingpage | default('') }}
AW_HEALTH_STRICT_FILEOPS={{ aw_health_strict_fileops | default(0) }}
AW_MONITORED_WINDOWS_HOST={{ aw_effective_monitored_windows_host }}
AW_MONITORED_WINDOWS_HOSTNAME={{ aw_effective_monitored_windows_hostname }}
AW_RUS_HEALTH_WORKTIME_API={{ aw_rus_health_worktime_api_base | default('http://127.0.0.1:5610') }}
AW_RUS_HEALTH_STATE_DIR={{ aw_rus_health_state_dir }}
AW_RUS_HEALTH_VALIDATION_DIR={{ aw_rus_health_validation_dir }}
AW_RUS_HEALTH_SESSION_EVENTS_MAX_AGE_SECONDS={{ aw_rus_health_session_events_max_age_seconds | default(86400) }}
AW_RUS_HEALTH_GUARD_MAX_AGE_SECONDS={{ aw_rus_health_guard_max_age_seconds | default(300) }}
AW_RUS_HEALTH_GUARD_REQUIRED={{ 1 if (aw_rus_health_guard_required | default(true) | bool) else 0 }}
AW_RUS_SLO_STATE_DIR={{ aw_server_data_dir }}/slo
AW_RUS_SLO_AW_BASE=http://127.0.0.1:5600
AW_RUS_SLO_WORKTIME_BASE={{ aw_rus_health_worktime_api_base | default('http://127.0.0.1:5610') }}
AW_RUS_SLO_TARGET_PERCENT={{ aw_rus_slo_target_percent | default('99.97') }}
AW_BROWSER_SMOKE_AW_BASE=http://127.0.0.1:5600
AW_BROWSER_SMOKE_WORKTIME_BASE={{ aw_rus_health_worktime_api_base | default('http://127.0.0.1:5610') }}
AW_BROWSER_SMOKE_HOST={{ aw_effective_monitored_windows_hostname }}
AW_BROWSER_SMOKE_OUTPUT_DIR={{ aw_server_data_dir }}/browser-smoke
AW_BROWSER_SMOKE_ENGINE={{ aw_browser_smoke_engine | default('chromium-cli') }}
AW_BROWSER_SMOKE_TIMEOUT_MS={{ aw_browser_smoke_timeout_ms | default(20000) }}
AW_BROWSER_SMOKE_RENDER_TIMEOUT_MS={{ aw_browser_smoke_render_timeout_ms | default(15000) }}
AW_HAYABUSA_AUTO_CASE_ENABLED={{ 'true' if (aw_hayabusa_auto_case_enabled | default(true) | bool) else 'false' }}
AW_HAYABUSA_AUTO_CASE_MIN_SEVERITY={{ aw_hayabusa_auto_case_min_severity | default('medium') }}
AW_HAYABUSA_TELEGRAM_ENABLED={{ 'true' if (aw_hayabusa_telegram_enabled | default(false) | bool) else 'false' }}
AW_HAYABUSA_TELEGRAM_MIN_SEVERITY={{ aw_hayabusa_telegram_min_severity | default('high') }}
AW_HAYABUSA_TELEGRAM_BOT_TOKEN={{ aw_hayabusa_telegram_bot_token | default('') }}
AW_HAYABUSA_TELEGRAM_CHAT_IDS={{ aw_hayabusa_telegram_chat_ids | default('') }}
- name: Создать каталог DLP policy engine
ansible.builtin.file:
path: /opt/activitywatch/dlp-policy-engine
state: directory
owner: "{{ aw_server_user }}"
group: "{{ aw_server_group }}"
mode: "0755"
when: aw_dlp_policy_engine_enabled | default(false) | bool
- name: Установить systemd unit DLP policy engine
ansible.builtin.copy:
src: "{{ aw_repo_root }}/aw-server/dlp-policy-engine/dlp-policy-engine.service"
dest: /etc/systemd/system/aw-dlp-policy-engine.service
owner: root
group: root
mode: "0644"
when: aw_dlp_policy_engine_enabled | default(false) | bool
- name: Проверить локальный Rust DLP policy engine
ansible.builtin.stat:
path: "{{ aw_rust_release_dir }}/dlp-policy-engine"
delegate_to: localhost
register: aw_dlp_policy_engine_rust_binary
become: false
when: aw_dlp_policy_engine_enabled | default(false) | bool
- name: Требовать Rust DLP policy engine artifact
ansible.builtin.assert:
that:
- aw_dlp_policy_engine_rust_binary.stat.exists | default(false)
fail_msg: "Missing Rust artifact: {{ aw_rust_release_dir }}/dlp-policy-engine"
when: aw_dlp_policy_engine_enabled | default(false) | bool
- name: Установить Rust DLP policy engine
ansible.builtin.copy:
src: "{{ aw_rust_release_dir }}/dlp-policy-engine"
dest: /usr/local/bin/aw-dlp-policy-engine-rust
owner: root
group: root
mode: "0755"
when:
- aw_dlp_policy_engine_enabled | default(false) | bool
- aw_dlp_policy_engine_rust_binary.stat.exists | default(false)
- name: Создать каталог DLP content analysis
ansible.builtin.file:
path: /opt/activitywatch/dlp-content-analysis
state: directory
owner: "{{ aw_server_user }}"
group: "{{ aw_server_group }}"
mode: "0755"
when: aw_dlp_content_analysis_enabled | default(true) | bool
- name: Скопировать файлы DLP content analysis
ansible.builtin.copy:
src: "{{ aw_repo_root }}/aw-server/dlp-content-analysis/"
dest: /opt/activitywatch/dlp-content-analysis/
owner: "{{ aw_server_user }}"
group: "{{ aw_server_group }}"
mode: "0644"
when: aw_dlp_content_analysis_enabled | default(true) | bool
- name: Установить wrapper запуска DLP content analysis через virtualenv
ansible.builtin.copy:
src: "{{ aw_repo_root }}/aw-server/dlp-content-analysis/aw-dlp-content-analyzer.sh"
dest: /usr/local/bin/aw-dlp-content-analyzer
owner: root
group: root
mode: "0755"
when: aw_dlp_content_analysis_enabled | default(true) | bool
- name: Проверить локальный Rust DLP content analyzer
ansible.builtin.stat:
path: "{{ aw_rust_release_dir }}/dlp-content-analyzer"
delegate_to: localhost
register: dlp_content_analyzer_rust_binary
become: false
when: aw_dlp_content_analysis_enabled | default(true) | bool
- name: Установить Rust DLP content analyzer
ansible.builtin.copy:
src: "{{ aw_rust_release_dir }}/dlp-content-analyzer"
dest: /usr/local/bin/aw-dlp-content-analyzer-rust
owner: root
group: root
mode: "0755"
when:
- aw_dlp_content_analysis_enabled | default(true) | bool
- dlp_content_analyzer_rust_binary.stat.exists | default(false)
- name: Создать virtualenv DLP content analysis
ansible.builtin.command:
cmd: python3 -m venv /opt/activitywatch/dlp-content-analysis/.venv
args:
creates: /opt/activitywatch/dlp-content-analysis/.venv/bin/python
when: aw_dlp_content_analysis_enabled | default(true) | bool
- name: Установить зависимости DLP content analysis
ansible.builtin.pip:
requirements: /opt/activitywatch/dlp-content-analysis/requirements.txt
virtualenv: /opt/activitywatch/dlp-content-analysis/.venv
when: aw_dlp_content_analysis_enabled | default(true) | bool
- name: Создать каталог DLP integrations
ansible.builtin.file:
path: /opt/activitywatch/dlp-integrations
state: directory
owner: "{{ aw_server_user }}"
group: "{{ aw_server_group }}"
mode: "0755"
when: aw_dlp_integrations_enabled | default(true) | bool
- name: Скопировать файлы DLP integrations
ansible.builtin.copy:
src: "{{ aw_repo_root }}/aw-server/dlp-integrations/{{ item }}"
dest: "/opt/activitywatch/dlp-integrations/{{ item }}"
owner: "{{ aw_server_user }}"
group: "{{ aw_server_group }}"
mode: "0644"
loop:
- cef-config.yaml
- syslog-forwarder-config.yaml
- webhook-config.yaml
when: aw_dlp_integrations_enabled | default(true) | bool
- name: Создать state каталог DLP integrations
ansible.builtin.file:
path: /var/lib/activitywatch/dlp-integrations
state: directory
owner: "{{ aw_server_user }}"
group: "{{ aw_server_group }}"
mode: "0755"
when: aw_dlp_integrations_enabled | default(true) | bool
- name: Установить systemd unit CEF exporter
ansible.builtin.copy:
src: "{{ aw_repo_root }}/aw-server/dlp-integrations/cef-exporter.service"
dest: /etc/systemd/system/aw-dlp-cef-exporter.service
owner: root
group: root
mode: "0644"
when: aw_dlp_integrations_enabled | default(true) | bool
- name: Установить systemd timer CEF exporter
ansible.builtin.copy:
src: "{{ aw_repo_root }}/aw-server/dlp-integrations/cef-exporter.timer"
dest: /etc/systemd/system/aw-dlp-cef-exporter.timer
owner: root
group: root
mode: "0644"
when: aw_dlp_integrations_enabled | default(true) | bool
- name: Проверить локальный Rust CEF exporter
ansible.builtin.stat:
path: "{{ aw_rust_release_dir }}/dlp-cef-exporter"
delegate_to: localhost
register: dlp_cef_exporter_rust_binary
become: false
when: aw_dlp_integrations_enabled | default(true) | bool
- name: Требовать Rust CEF exporter artifact
ansible.builtin.assert:
that:
- dlp_cef_exporter_rust_binary.stat.exists | default(false)
fail_msg: "Missing Rust artifact: {{ aw_rust_release_dir }}/dlp-cef-exporter"
when: aw_dlp_integrations_enabled | default(true) | bool
- name: Установить Rust CEF exporter
ansible.builtin.copy:
src: "{{ aw_rust_release_dir }}/dlp-cef-exporter"
dest: /usr/local/bin/dlp-cef-exporter-rust
owner: root
group: root
mode: "0755"
when:
- aw_dlp_integrations_enabled | default(true) | bool
- dlp_cef_exporter_rust_binary.stat.exists | default(false)
- name: Установить systemd unit syslog forwarder
ansible.builtin.copy:
src: "{{ aw_repo_root }}/aw-server/dlp-integrations/syslog-forwarder.service"
dest: /etc/systemd/system/aw-dlp-syslog-forwarder.service
owner: root
group: root
mode: "0644"
when: aw_dlp_integrations_enabled | default(true) | bool
- name: Установить systemd timer syslog forwarder
ansible.builtin.copy:
src: "{{ aw_repo_root }}/aw-server/dlp-integrations/syslog-forwarder.timer"
dest: /etc/systemd/system/aw-dlp-syslog-forwarder.timer
owner: root
group: root
mode: "0644"
when: aw_dlp_integrations_enabled | default(true) | bool
- name: Проверить локальный Rust syslog forwarder
ansible.builtin.stat:
path: "{{ aw_rust_release_dir }}/dlp-syslog-forwarder"
delegate_to: localhost
register: dlp_syslog_forwarder_rust_binary
become: false
when: aw_dlp_integrations_enabled | default(true) | bool
- name: Требовать Rust syslog forwarder artifact
ansible.builtin.assert:
that:
- dlp_syslog_forwarder_rust_binary.stat.exists | default(false)
fail_msg: "Missing Rust artifact: {{ aw_rust_release_dir }}/dlp-syslog-forwarder"
when: aw_dlp_integrations_enabled | default(true) | bool
- name: Установить Rust syslog forwarder
ansible.builtin.copy:
src: "{{ aw_rust_release_dir }}/dlp-syslog-forwarder"
dest: /usr/local/bin/dlp-syslog-forwarder-rust
owner: root
group: root
mode: "0755"
when:
- aw_dlp_integrations_enabled | default(true) | bool
- dlp_syslog_forwarder_rust_binary.stat.exists | default(false)
- name: Установить systemd unit webhook sender
ansible.builtin.copy:
src: "{{ aw_repo_root }}/aw-server/dlp-integrations/webhook-sender.service"
dest: /etc/systemd/system/aw-dlp-webhook-sender.service
owner: root
group: root
mode: "0644"
when: aw_dlp_integrations_enabled | default(true) | bool
- name: Установить systemd timer webhook sender
ansible.builtin.copy:
src: "{{ aw_repo_root }}/aw-server/dlp-integrations/webhook-sender.timer"
dest: /etc/systemd/system/aw-dlp-webhook-sender.timer
owner: root
group: root
mode: "0644"
when: aw_dlp_integrations_enabled | default(true) | bool
- name: Проверить локальный Rust webhook sender
ansible.builtin.stat:
path: "{{ aw_rust_release_dir }}/dlp-webhook-sender"
delegate_to: localhost
register: dlp_webhook_sender_rust_binary
become: false
when: aw_dlp_integrations_enabled | default(true) | bool
- name: Требовать Rust webhook sender artifact
ansible.builtin.assert:
that:
- dlp_webhook_sender_rust_binary.stat.exists | default(false)
fail_msg: "Missing Rust artifact: {{ aw_rust_release_dir }}/dlp-webhook-sender"
when: aw_dlp_integrations_enabled | default(true) | bool
- name: Установить Rust webhook sender
ansible.builtin.copy:
src: "{{ aw_rust_release_dir }}/dlp-webhook-sender"
dest: /usr/local/bin/dlp-webhook-sender-rust
owner: root
group: root
mode: "0755"
when:
- aw_dlp_integrations_enabled | default(true) | bool
- dlp_webhook_sender_rust_binary.stat.exists | default(false)
- name: Создать каталог DLP case management
ansible.builtin.file:
path: /opt/activitywatch/dlp-case-management
state: directory
owner: "{{ aw_server_user }}"
group: "{{ aw_server_group }}"
mode: "0755"
when: aw_dlp_case_management_enabled | default(true) | bool
- name: Установить systemd unit DLP case management
ansible.builtin.copy:
src: "{{ aw_repo_root }}/aw-server/dlp-case-management/case-service.service"
dest: /etc/systemd/system/aw-dlp-case-management.service
owner: root
group: root
mode: "0644"
when: aw_dlp_case_management_enabled | default(true) | bool
- name: Проверить локальный Rust DLP case management
ansible.builtin.stat:
path: "{{ aw_rust_release_dir }}/dlp-case-management"
delegate_to: localhost
register: aw_dlp_case_management_rust_binary
become: false
when: aw_dlp_case_management_enabled | default(true) | bool
- name: Требовать Rust DLP case management artifact
ansible.builtin.assert:
that:
- aw_dlp_case_management_rust_binary.stat.exists | default(false)
fail_msg: "Missing Rust artifact: {{ aw_rust_release_dir }}/dlp-case-management"
when: aw_dlp_case_management_enabled | default(true) | bool
- name: Установить Rust DLP case management
ansible.builtin.copy:
src: "{{ aw_rust_release_dir }}/dlp-case-management"
dest: /usr/local/bin/aw-dlp-case-management-rust
owner: root
group: root
mode: "0755"
when:
- aw_dlp_case_management_enabled | default(true) | bool
- aw_dlp_case_management_rust_binary.stat.exists | default(false)
- name: Создать каталоги DLP compliance
ansible.builtin.file:
path: "{{ item }}"
state: directory
owner: "{{ aw_server_user }}"
group: "{{ aw_server_group }}"
mode: "0755"
loop:
- /opt/activitywatch/dlp-compliance
- /opt/activitywatch/dlp-compliance/templates
- "{{ aw_dlp_compliance_report_dir }}"
when: aw_dlp_compliance_enabled | default(true) | bool
- name: Скопировать файлы DLP compliance
ansible.builtin.copy:
src: "{{ aw_repo_root }}/aw-server/dlp-compliance/{{ item.src }}"
dest: "{{ item.dest }}"
owner: "{{ aw_server_user }}"
group: "{{ aw_server_group }}"
mode: "{{ item.mode }}"
loop:
- { src: "templates/152-fz-report.html", dest: "/opt/activitywatch/dlp-compliance/templates/152-fz-report.html", mode: "0644" }
- { src: "templates/pci-dss-report.html", dest: "/opt/activitywatch/dlp-compliance/templates/pci-dss-report.html", mode: "0644" }
- { src: "report-scheduler.service", dest: "/etc/systemd/system/aw-dlp-report-scheduler.service", mode: "0644" }
- { src: "report-scheduler.timer", dest: "/etc/systemd/system/aw-dlp-report-scheduler.timer", mode: "0644" }
when: aw_dlp_compliance_enabled | default(true) | bool
- name: Проверить локальный Rust DLP compliance
ansible.builtin.stat:
path: "{{ aw_rust_release_dir }}/dlp-compliance"
delegate_to: localhost
register: aw_dlp_compliance_rust_binary
become: false
when: aw_dlp_compliance_enabled | default(true) | bool
- name: Требовать Rust DLP compliance artifact
ansible.builtin.assert:
that:
- aw_dlp_compliance_rust_binary.stat.exists | default(false)
fail_msg: "Missing Rust artifact: {{ aw_rust_release_dir }}/dlp-compliance"
when: aw_dlp_compliance_enabled | default(true) | bool
- name: Установить Rust DLP compliance
ansible.builtin.copy:
src: "{{ aw_rust_release_dir }}/dlp-compliance"
dest: /usr/local/bin/aw-dlp-compliance-rust
owner: root
group: root
mode: "0755"
when:
- aw_dlp_compliance_enabled | default(true) | bool
- aw_dlp_compliance_rust_binary.stat.exists | default(false)
- name: Проверить локальный Rust dlp-admin-cli
ansible.builtin.stat:
path: "{{ aw_rust_release_dir }}/dlp-admin-cli"
delegate_to: localhost
register: aw_dlp_admin_cli_rust_binary
- name: Требовать Rust dlp-admin-cli artifact
ansible.builtin.assert:
that:
- aw_dlp_admin_cli_rust_binary.stat.exists | default(false)
fail_msg: "Missing Rust artifact: {{ aw_rust_release_dir }}/dlp-admin-cli"
- name: Установить Rust dlp-admin-cli
ansible.builtin.copy:
src: "{{ aw_rust_release_dir }}/dlp-admin-cli"
dest: /usr/local/bin/dlp-admin-cli
owner: root
group: root
mode: "0755"
when: aw_dlp_admin_cli_rust_binary.stat.exists
- name: Создать каталог daily history для AW worktime management
ansible.builtin.file:
path: "{{ aw_worktime_management_history_dir | default(aw_server_data_dir ~ '/worktime-management-history') }}"
state: directory
owner: "{{ aw_server_user }}"
group: "{{ aw_server_group }}"
mode: "0750"
- name: Установить initial policy интерпретации Workforce если отсутствует
ansible.builtin.copy:
dest: "{{ aw_worktime_interpretation_policy_path | default('/etc/activitywatch/worktime-interpretation-policy.json') }}"
owner: root
group: root
mode: "0644"
force: false
content: "{{ lookup('file', aw_repo_root + '/configs/worktime-interpretation-policy.example.json') }}"
- name: Проверить локальный Rust AW worktime API
ansible.builtin.stat:
path: "{{ aw_rust_release_dir }}/worktime-api"
delegate_to: localhost
register: aw_worktime_api_rust_binary
become: false
- name: Требовать Rust AW worktime API artifact
ansible.builtin.assert:
that:
- aw_worktime_api_rust_binary.stat.exists | default(false)
fail_msg: "Missing Rust artifact: {{ aw_rust_release_dir }}/worktime-api"
- name: Установить Rust AW worktime API
ansible.builtin.copy:
src: "{{ aw_rust_release_dir }}/worktime-api"
dest: /usr/local/bin/aw-worktime-api-rust
owner: root
group: root
mode: "0755"
when: aw_worktime_api_rust_binary.stat.exists | default(false)
- name: Установить systemd unit AW worktime API
ansible.builtin.copy:
src: "{{ aw_repo_root }}/aw-server/aw-worktime-api.service"
dest: /etc/systemd/system/aw-worktime-api.service
owner: root
group: root
mode: "0644"
- name: Проверить локальный Rust AW worktime UI bridge
ansible.builtin.stat:
path: "{{ aw_rust_release_dir }}/worktime-ui-bridge"
delegate_to: localhost
register: aw_worktime_ui_bridge_rust_binary
become: false
- name: Требовать Rust AW worktime UI bridge artifact
ansible.builtin.assert:
that:
- aw_worktime_ui_bridge_rust_binary.stat.exists | default(false)
fail_msg: "Missing Rust artifact: {{ aw_rust_release_dir }}/worktime-ui-bridge"
- name: Установить Rust AW worktime UI bridge
ansible.builtin.copy:
src: "{{ aw_rust_release_dir }}/worktime-ui-bridge"
dest: /usr/local/bin/aw-worktime-ui-bridge-rust
owner: root
group: root
mode: "0755"
when: aw_worktime_ui_bridge_rust_binary.stat.exists | default(false)
- name: Проверить локальный Rust AW worktime autoheal
ansible.builtin.stat:
path: "{{ aw_rust_release_dir }}/worktime-autoheal"
delegate_to: localhost
register: aw_worktime_autoheal_rust_binary
become: false
- name: Требовать Rust AW worktime autoheal artifact
ansible.builtin.assert:
that:
- aw_worktime_autoheal_rust_binary.stat.exists | default(false)
fail_msg: "Missing Rust artifact: {{ aw_rust_release_dir }}/worktime-autoheal"
- name: Установить Rust AW worktime autoheal
ansible.builtin.copy:
src: "{{ aw_rust_release_dir }}/worktime-autoheal"
dest: /usr/local/bin/aw-worktime-autoheal-rust
owner: root
group: root
mode: "0755"
when: aw_worktime_autoheal_rust_binary.stat.exists | default(false)
- name: Проверить локальный Rust AW worktime prewarm
ansible.builtin.stat:
path: "{{ aw_rust_release_dir }}/worktime-prewarm"
delegate_to: localhost
register: aw_worktime_prewarm_rust_binary
become: false
- name: Требовать Rust AW worktime prewarm artifact
ansible.builtin.assert:
that:
- aw_worktime_prewarm_rust_binary.stat.exists | default(false)
fail_msg: "Missing Rust artifact: {{ aw_rust_release_dir }}/worktime-prewarm"
- name: Установить Rust AW worktime prewarm
ansible.builtin.copy:
src: "{{ aw_rust_release_dir }}/worktime-prewarm"
dest: /usr/local/bin/aw-worktime-prewarm-rust
owner: root
group: root
mode: "0755"
when: aw_worktime_prewarm_rust_binary.stat.exists | default(false)
- name: Создать server-side ops bundle для AW ops helpers
ansible.builtin.file:
path: /opt/activitywatch/aw-rus-ops
state: directory
owner: root
group: root
mode: "0755"
- name: Установить скрипт aw-health-check
ansible.builtin.copy:
src: "{{ aw_repo_root }}/aw-server/aw-health-check-wrapper.sh"
dest: /usr/local/bin/aw-health-check
owner: root
group: root
mode: "0755"
- name: Проверить локальный Rust aw-health-check
ansible.builtin.stat:
path: "{{ aw_rust_release_dir }}/aw-health-check"
delegate_to: localhost
register: aw_health_check_rust_binary
become: false
- name: Установить Rust aw-health-check
ansible.builtin.copy:
src: "{{ aw_rust_release_dir }}/aw-health-check"
dest: /usr/local/bin/aw-health-check-rust
owner: root
group: root
mode: "0755"
when: aw_health_check_rust_binary.stat.exists | default(false)
- name: Требовать Rust aw-health-check artifact
ansible.builtin.assert:
that:
- aw_health_check_rust_binary.stat.exists | default(false)
fail_msg: "Rust aw-health-check artifact is required at {{ aw_rust_release_dir }}/aw-health-check"
- name: Проверить локальный Rust aw-db-health
ansible.builtin.stat:
path: "{{ aw_rust_release_dir }}/aw-db-health"
delegate_to: localhost
register: aw_db_health_rust_binary
become: false
- name: Установить Rust aw-db-health
ansible.builtin.copy:
src: "{{ aw_rust_release_dir }}/aw-db-health"
dest: /usr/local/bin/aw-db-health
owner: root
group: root
mode: "0755"
when: aw_db_health_rust_binary.stat.exists | default(false)
- name: Установить скрипт check-aw-data
ansible.builtin.copy:
src: "{{ aw_repo_root }}/aw-server/check-aw-data-wrapper.sh"
dest: /usr/local/bin/check-aw-data
owner: root
group: root
mode: "0755"
- name: Положить legacy check-aw-data в server-side ops bundle
ansible.builtin.copy:
src: "{{ aw_repo_root }}/scripts/legacy/check-aw-data.sh"
dest: /opt/activitywatch/aw-rus-ops/check-aw-data.sh
owner: root
group: root
mode: "0755"
- name: Проверить локальный Rust check-aw-data
ansible.builtin.stat:
path: "{{ aw_rust_release_dir }}/check-aw-data"
delegate_to: localhost
register: check_aw_data_rust_binary
become: false
- name: Установить Rust check-aw-data
ansible.builtin.copy:
src: "{{ aw_rust_release_dir }}/check-aw-data"
dest: /usr/local/bin/check-aw-data-rust
owner: root
group: root
mode: "0755"
when: check_aw_data_rust_binary.stat.exists | default(false)
- name: Проверить локальный Rust dlp-health-check
ansible.builtin.stat:
path: "{{ aw_rust_release_dir }}/dlp-health-check"
delegate_to: localhost
register: dlp_health_check_rust_binary
become: false
- name: Установить Rust dlp-health-check
ansible.builtin.copy:
src: "{{ aw_rust_release_dir }}/dlp-health-check"
dest: /usr/local/bin/dlp-health-check
owner: root
group: root
mode: "0755"
when: dlp_health_check_rust_binary.stat.exists | default(false)
- name: Проверить локальный Rust AW-RUS healthd
ansible.builtin.stat:
path: "{{ aw_rust_release_dir }}/aw-rus-healthd"
delegate_to: localhost
register: aw_rus_healthd_rust_binary
become: false
- name: Проверить локальный Rust AW-RUS SLO monitor
ansible.builtin.stat:
path: "{{ aw_rust_release_dir }}/aw-slo-monitor"
delegate_to: localhost
register: aw_slo_monitor_rust_binary
become: false
- name: Требовать Rust dlp-health-check artifact
ansible.builtin.assert:
that:
- dlp_health_check_rust_binary.stat.exists | default(false)
fail_msg: "Missing Rust artifact: {{ aw_rust_release_dir }}/dlp-health-check"
- name: Требовать Rust AW-RUS healthd artifact
ansible.builtin.assert:
that:
- aw_rus_healthd_rust_binary.stat.exists | default(false)
fail_msg: "Missing Rust artifact: {{ aw_rust_release_dir }}/aw-rus-healthd"
- name: Требовать Rust AW-RUS SLO monitor artifact
ansible.builtin.assert:
that:
- aw_slo_monitor_rust_binary.stat.exists | default(false)
fail_msg: "Missing Rust artifact: {{ aw_rust_release_dir }}/aw-slo-monitor"
- name: Установить Rust AW-RUS healthd
ansible.builtin.copy:
src: "{{ aw_rust_release_dir }}/aw-rus-healthd"
dest: /usr/local/bin/aw-rus-healthd-rust
owner: root
group: root
mode: "0755"
- name: Установить Rust AW-RUS SLO monitor
ansible.builtin.copy:
src: "{{ aw_rust_release_dir }}/aw-slo-monitor"
dest: /usr/local/bin/aw-slo-monitor-rust
owner: root
group: root
mode: "0755"
when: aw_slo_monitor_rust_binary.stat.exists | default(false)
- name: Установить browser smoke скрипт
ansible.builtin.copy:
src: "{{ aw_repo_root }}/scripts/aw-webui-browser-smoke.mjs"
dest: /usr/local/lib/aw-rus-browser-smoke/aw-webui-browser-smoke.mjs
owner: root
group: root
mode: "0755"
when: aw_browser_smoke_enabled | default(true) | bool
- name: Установить systemd unit AW worktime UI bridge
ansible.builtin.copy:
src: "{{ aw_repo_root }}/aw-server/aw-worktime-ui-bridge.service"
dest: /etc/systemd/system/aw-worktime-ui-bridge.service
owner: root
group: root
mode: "0644"
- name: Установить systemd timer AW worktime UI bridge
ansible.builtin.copy:
src: "{{ aw_repo_root }}/aw-server/aw-worktime-ui-bridge.timer"
dest: /etc/systemd/system/aw-worktime-ui-bridge.timer
owner: root
group: root
mode: "0644"
- name: Установить systemd unit AW worktime autoheal
ansible.builtin.copy:
src: "{{ aw_repo_root }}/aw-server/aw-worktime-autoheal.service"
dest: /etc/systemd/system/aw-worktime-autoheal.service
owner: root
group: root
mode: "0644"
- name: Установить systemd timer AW worktime autoheal
ansible.builtin.copy:
src: "{{ aw_repo_root }}/aw-server/aw-worktime-autoheal.timer"
dest: /etc/systemd/system/aw-worktime-autoheal.timer
owner: root
group: root
mode: "0644"
- name: Установить systemd unit AW worktime prewarm
ansible.builtin.copy:
src: "{{ aw_repo_root }}/aw-server/aw-worktime-prewarm.service"
dest: /etc/systemd/system/aw-worktime-prewarm.service
owner: root
group: root
mode: "0644"
- name: Установить systemd timer AW worktime prewarm
ansible.builtin.copy:
src: "{{ aw_repo_root }}/aw-server/aw-worktime-prewarm.timer"
dest: /etc/systemd/system/aw-worktime-prewarm.timer
owner: root
group: root
mode: "0644"
- name: Установить systemd unit AW-RUS healthd
ansible.builtin.copy:
src: "{{ aw_repo_root }}/aw-server/aw-rus-healthd.service"
dest: /etc/systemd/system/aw-rus-healthd.service
owner: root
group: root
mode: "0644"
- name: Установить systemd timer AW-RUS healthd
ansible.builtin.copy:
src: "{{ aw_repo_root }}/aw-server/aw-rus-healthd.timer"
dest: /etc/systemd/system/aw-rus-healthd.timer
owner: root
group: root
mode: "0644"
- name: Установить systemd unit AW-RUS SLO monitor
ansible.builtin.copy:
src: "{{ aw_repo_root }}/aw-server/aw-slo-monitor.service"
dest: /etc/systemd/system/aw-slo-monitor.service
owner: root
group: root
mode: "0644"
- name: Установить systemd timer AW-RUS SLO monitor
ansible.builtin.copy:
src: "{{ aw_repo_root }}/aw-server/aw-slo-monitor.timer"
dest: /etc/systemd/system/aw-slo-monitor.timer
owner: root
group: root
mode: "0644"
- name: Установить systemd unit AW-RUS browser smoke
ansible.builtin.copy:
src: "{{ aw_repo_root }}/aw-server/aw-browser-smoke.service"
dest: /etc/systemd/system/aw-browser-smoke.service
owner: root
group: root
mode: "0644"
when: aw_browser_smoke_enabled | default(true) | bool
- name: Установить systemd timer AW-RUS browser smoke
ansible.builtin.copy:
src: "{{ aw_repo_root }}/aw-server/aw-browser-smoke.timer"
dest: /etc/systemd/system/aw-browser-smoke.timer
owner: root
group: root
mode: "0644"
when: aw_browser_smoke_enabled | default(true) | bool
- name: Установить systemd unit AW worktime Influx exporter
ansible.builtin.copy:
src: "{{ aw_repo_root }}/aw-server/aw-worktime-influx-exporter.service"
dest: /etc/systemd/system/aw-worktime-influx-exporter.service
owner: root
group: root
mode: "0644"
when: aw_worktime_influx_enabled | default(false) | bool
- name: Проверить локальный Rust AW worktime Influx exporter
ansible.builtin.stat:
path: "{{ aw_rust_release_dir }}/worktime-influx-exporter"
delegate_to: localhost
register: aw_worktime_influx_exporter_rust_binary
become: false
when: aw_worktime_influx_enabled | default(false) | bool
- name: Требовать Rust AW worktime Influx exporter artifact
ansible.builtin.assert:
that:
- aw_worktime_influx_exporter_rust_binary.stat.exists | default(false)
fail_msg: "Missing Rust artifact: {{ aw_rust_release_dir }}/worktime-influx-exporter"
when: aw_worktime_influx_enabled | default(false) | bool
- name: Установить Rust AW worktime Influx exporter
ansible.builtin.copy:
src: "{{ aw_rust_release_dir }}/worktime-influx-exporter"
dest: /usr/local/bin/aw-worktime-influx-exporter-rust
owner: root
group: root
mode: "0755"
when:
- aw_worktime_influx_enabled | default(false) | bool
- aw_worktime_influx_exporter_rust_binary.stat.exists | default(false)
- name: Установить systemd timer AW worktime Influx exporter
ansible.builtin.copy:
src: "{{ aw_repo_root }}/aw-server/aw-worktime-influx-exporter.timer"
dest: /etc/systemd/system/aw-worktime-influx-exporter.timer
owner: root
group: root
mode: "0644"
when: aw_worktime_influx_enabled | default(false) | bool
- name: Установить systemd unit AW DLP Influx exporter
ansible.builtin.copy:
src: "{{ aw_repo_root }}/aw-server/aw-dlp-influx-exporter.service"
dest: /etc/systemd/system/aw-dlp-influx-exporter.service
owner: root
group: root
mode: "0644"
when: aw_dlp_influx_enabled | default(false) | bool
- name: Проверить локальный Rust AW DLP Influx exporter
ansible.builtin.stat:
path: "{{ aw_rust_release_dir }}/dlp-influx-exporter"
delegate_to: localhost
register: aw_dlp_influx_exporter_rust_binary
become: false
when: aw_dlp_influx_enabled | default(false) | bool
- name: Требовать Rust AW DLP Influx exporter artifact
ansible.builtin.assert:
that:
- aw_dlp_influx_exporter_rust_binary.stat.exists | default(false)
fail_msg: "Missing Rust artifact: {{ aw_rust_release_dir }}/dlp-influx-exporter"
when: aw_dlp_influx_enabled | default(false) | bool
- name: Установить Rust AW DLP Influx exporter
ansible.builtin.copy:
src: "{{ aw_rust_release_dir }}/dlp-influx-exporter"
dest: /usr/local/bin/aw-dlp-influx-exporter-rust
owner: root
group: root
mode: "0755"
when:
- aw_dlp_influx_enabled | default(false) | bool
- aw_dlp_influx_exporter_rust_binary.stat.exists | default(false)
- name: Установить systemd timer AW DLP Influx exporter
ansible.builtin.copy:
src: "{{ aw_repo_root }}/aw-server/aw-dlp-influx-exporter.timer"
dest: /etc/systemd/system/aw-dlp-influx-exporter.timer
owner: root
group: root
mode: "0644"
when: aw_dlp_influx_enabled | default(false) | bool
- name: Проверить локальный Rust DetMir readiness checker
ansible.builtin.stat:
path: "{{ aw_rust_release_dir }}/detmir-readiness"
delegate_to: localhost
register: detmir_readiness_rust_binary
become: false
- name: Требовать Rust DetMir readiness checker artifact
ansible.builtin.assert:
that:
- detmir_readiness_rust_binary.stat.exists | default(false)
fail_msg: "Missing Rust artifact: {{ aw_rust_release_dir }}/detmir-readiness"
- name: Установить Rust DetMir readiness checker
ansible.builtin.copy:
src: "{{ aw_rust_release_dir }}/detmir-readiness"
dest: /usr/local/bin/detmir-readiness
owner: root
group: root
mode: "0755"
when: detmir_readiness_rust_binary.stat.exists | default(false)
- name: Создать private каталог DetMir readiness signing
ansible.builtin.file:
path: /etc/detmir-readiness
state: directory
owner: root
group: root
mode: "0700"
- name: Проверить private key DetMir readiness signing
ansible.builtin.stat:
path: /etc/detmir-readiness/signing-key.pem
register: detmir_readiness_signing_key
- name: Сгенерировать private key DetMir readiness signing
ansible.builtin.command:
argv:
- openssl
- genpkey
- -algorithm
- RSA
- -pkeyopt
- rsa_keygen_bits:3072
- -out
- /etc/detmir-readiness/signing-key.pem
when: not (detmir_readiness_signing_key.stat.exists | default(false))
no_log: true
- name: Зафиксировать права private key DetMir readiness signing
ansible.builtin.file:
path: /etc/detmir-readiness/signing-key.pem
owner: root
group: root
mode: "0600"
- name: Создать private env DetMir readiness
ansible.builtin.copy:
dest: /etc/detmir-readiness.env
content: ""
owner: root
group: root
mode: "0600"
force: false
- name: Настроить private env DetMir readiness signing
ansible.builtin.blockinfile:
path: /etc/detmir-readiness.env
marker: "# {mark} ANSIBLE MANAGED DETMIR READINESS"
block: |
DETMIR_READINESS_SIGNING_KEY=/etc/detmir-readiness/signing-key.pem
DETMIR_READINESS_REQUIRE_SIGNATURE=true
DETMIR_READINESS_RETENTION_DAYS={{ detmir_readiness_retention_days | default(30) }}
owner: root
group: root
mode: "0600"
- name: Установить systemd service DetMir readiness bundle
ansible.builtin.copy:
src: "{{ aw_repo_root }}/aw-server/detmir-readiness.service"
dest: /etc/systemd/system/detmir-readiness.service
owner: root
group: root
mode: "0644"
- name: Установить systemd timer DetMir readiness bundle
ansible.builtin.copy:
src: "{{ aw_repo_root }}/aw-server/detmir-readiness.timer"
dest: /etc/systemd/system/detmir-readiness.timer
owner: root
group: root
mode: "0644"
- name: Создать каталог Prometheus rules для DetMir readiness
ansible.builtin.file:
path: /etc/prometheus/rules
state: directory
owner: root
group: root
mode: "0755"
- name: Установить Prometheus alerts DetMir readiness
ansible.builtin.copy:
src: "{{ aw_repo_root }}/aw-server/detmir-readiness-alerts.yml"
dest: /etc/prometheus/rules/detmir-readiness-alerts.yml
owner: root
group: root
mode: "0644"
- name: Перезагрузить systemd после установки AW worktime API
ansible.builtin.systemd:
daemon_reload: true
- name: Включить таймер AW-RUS healthd
ansible.builtin.systemd:
name: aw-rus-healthd.timer
enabled: true
state: started
- name: Включить таймер AW-RUS SLO monitor
ansible.builtin.systemd:
name: aw-slo-monitor.timer
enabled: true
state: started
- name: Включить daily DetMir readiness bundle timer
ansible.builtin.systemd:
name: detmir-readiness.timer
enabled: true
state: started
- name: Включить таймер AW-RUS browser smoke
ansible.builtin.systemd:
name: aw-browser-smoke.timer
enabled: true
state: started
when: aw_browser_smoke_enabled | default(true) | bool
- name: Включить и перезапустить DLP policy engine
ansible.builtin.systemd:
name: aw-dlp-policy-engine.service
enabled: true
state: restarted
when: aw_dlp_policy_engine_enabled | default(false) | bool
- name: Включить и перезапустить timer CEF exporter
ansible.builtin.systemd:
name: aw-dlp-cef-exporter.timer
enabled: true
state: restarted
when: aw_dlp_integrations_enabled | default(true) | bool
- name: Включить и перезапустить timer syslog forwarder
ansible.builtin.systemd:
name: aw-dlp-syslog-forwarder.timer
enabled: true
state: restarted
when: aw_dlp_integrations_enabled | default(true) | bool
- name: Включить и перезапустить timer webhook sender
ansible.builtin.systemd:
name: aw-dlp-webhook-sender.timer
enabled: true
state: restarted
when: aw_dlp_integrations_enabled | default(true) | bool
- name: Включить и перезапустить DLP case management
ansible.builtin.systemd:
name: aw-dlp-case-management.service
enabled: true
state: restarted
when: aw_dlp_case_management_enabled | default(true) | bool
- name: Включить и перезапустить timer DLP compliance report
ansible.builtin.systemd:
name: aw-dlp-report-scheduler.timer
enabled: true
state: restarted
when: aw_dlp_compliance_enabled | default(true) | bool
- name: Выполнить разовый прогон DLP compliance report
ansible.builtin.systemd:
name: aw-dlp-report-scheduler.service
state: started
failed_when: false
when: aw_dlp_compliance_enabled | default(true) | bool
- name: Включить и перезапустить AW worktime API
ansible.builtin.systemd:
name: aw-worktime-api.service
enabled: true
state: restarted
- name: Отключить legacy timer aw-worktime-afk-bridge (если есть)
ansible.builtin.systemd:
name: aw-worktime-afk-bridge.timer
enabled: false
state: stopped
failed_when: false
- name: Включить и перезапустить AW worktime UI bridge timer
ansible.builtin.systemd:
name: aw-worktime-ui-bridge.timer
enabled: true
state: restarted
- name: Выполнить разовый прогон AW worktime UI bridge
ansible.builtin.systemd:
name: aw-worktime-ui-bridge.service
state: started
failed_when: false
- name: Включить и перезапустить AW worktime autoheal timer
ansible.builtin.systemd:
name: aw-worktime-autoheal.timer
enabled: true
state: restarted
- name: Выполнить разовый прогон AW worktime autoheal
ansible.builtin.systemd:
name: aw-worktime-autoheal.service
state: started
failed_when: false
- name: Включить и перезапустить AW worktime prewarm timer
ansible.builtin.systemd:
name: aw-worktime-prewarm.timer
enabled: true
state: restarted
- name: Выполнить разовый прогон AW worktime prewarm
ansible.builtin.systemd:
name: aw-worktime-prewarm.service
state: started
failed_when: false
- name: Включить и перезапустить AW worktime Influx exporter timer
ansible.builtin.systemd:
name: aw-worktime-influx-exporter.timer
enabled: true
state: restarted
when: aw_worktime_influx_enabled | default(false) | bool
- name: Выполнить разовый прогон AW worktime Influx exporter
ansible.builtin.systemd:
name: aw-worktime-influx-exporter.service
state: started
when: aw_worktime_influx_enabled | default(false) | bool
- name: Включить и перезапустить AW DLP Influx exporter timer
ansible.builtin.systemd:
name: aw-dlp-influx-exporter.timer
enabled: true
state: restarted
when: aw_dlp_influx_enabled | default(false) | bool
- name: Выполнить разовый прогон AW DLP Influx exporter
ansible.builtin.systemd:
name: aw-dlp-influx-exporter.service
state: started
when: aw_dlp_influx_enabled | default(false) | bool
- name: Применить хотфиксы compiled JS чанков (Trends, Timespiral, Category helper)
ansible.builtin.command:
cmd: "/opt/activitywatch/aw-server/apply_webui_ru_patch.sh"
register: apply_ru_patch_result
failed_when: false
- name: Вывести результат применения хотфиксов
ansible.builtin.debug:
msg: "apply_webui_ru_patch.sh: {{ apply_ru_patch_result.stdout }}"
- name: Проверить наличие index.html после копирования
ansible.builtin.stat:
path: "{{ aw_server_webui_dir }}/index.html"
register: aw_webui_ru_index
- name: Проверить, что index.html доступен для RU patch
ansible.builtin.assert:
that:
- aw_webui_ru_index.stat.exists
- (aw_webui_ru_index.stat.size | default(0) | int) > 0
fail_msg: "Не найден index.html WebUI для применения RU patch."
- name: Проверить, что index.html не опустел после применения RU patch
ansible.builtin.stat:
path: "{{ aw_server_webui_dir }}/index.html"
register: aw_webui_ru_index_after_patch
- name: Подтвердить, что index.html остался непустым
ansible.builtin.assert:
that:
- aw_webui_ru_index_after_patch.stat.exists
- (aw_webui_ru_index_after_patch.stat.size | default(0) | int) > 0
fail_msg: "index.html WebUI пуст после RU patch."
- name: Удалить старые теги RU patch из index.html
ansible.builtin.replace:
path: "{{ aw_server_webui_dir }}/index.html"
regexp: ''
replace: ''
- name: Добавить cleanup script RU patch в index.html
ansible.builtin.replace:
path: "{{ aw_server_webui_dir }}/index.html"
regexp: ''
replace: ''
- name: Добавить загрузчик RU patch перед закрытием body
ansible.builtin.replace:
path: "{{ aw_server_webui_dir }}/index.html"
regexp: '