fix(awooop): add momo backup user ansible repair
Some checks failed
Ansible Lint / lint (push) Failing after 32s
CD Pipeline / tests (push) Successful in 1m18s
Code Review / ai-code-review (push) Successful in 12s
CD Pipeline / build-and-deploy (push) Successful in 5m55s
CD Pipeline / post-deploy-checks (push) Successful in 1m32s
Some checks failed
Ansible Lint / lint (push) Failing after 32s
CD Pipeline / tests (push) Successful in 1m18s
Code Review / ai-code-review (push) Successful in 12s
CD Pipeline / build-and-deploy (push) Successful in 5m55s
CD Pipeline / post-deploy-checks (push) Successful in 1m32s
This commit is contained in:
@@ -59,6 +59,31 @@ _CATALOG: tuple[dict[str, Any], ...] = (
|
||||
"approval_required": True,
|
||||
"risk_level": "medium",
|
||||
},
|
||||
{
|
||||
"catalog_id": "ansible:188-momo-backup-user",
|
||||
"playbook_path": "infra/ansible/playbooks/188-momo-backup-user.yml",
|
||||
"check_mode_playbook_path": "infra/ansible/playbooks/188-momo-backup-user.yml",
|
||||
"inventory_hosts": ["host_188"],
|
||||
"domains": ["momo_backup", "postgresql", "cron", "awooop_notification"],
|
||||
"keywords": [
|
||||
"188",
|
||||
"momo",
|
||||
"momopostgresbackupfailed",
|
||||
"postgres",
|
||||
"postgresql",
|
||||
"backup",
|
||||
"momo pg_backup",
|
||||
"momo postgres backup",
|
||||
"pg_backup",
|
||||
"momo-pg-backup",
|
||||
"cron",
|
||||
"crontab",
|
||||
],
|
||||
"supports_check_mode": True,
|
||||
"auto_apply_enabled": False,
|
||||
"approval_required": True,
|
||||
"risk_level": "low",
|
||||
},
|
||||
{
|
||||
"catalog_id": "ansible:188-ai-web",
|
||||
"playbook_path": "infra/ansible/playbooks/188-ai-web.yml",
|
||||
|
||||
@@ -927,11 +927,11 @@ def test_ansible_truth_surfaces_audited_check_mode_record() -> None:
|
||||
assert truth["records"][0]["dry_run_result"] == {"changed": 1}
|
||||
assert "ansible_check_mode_executed" in truth["audit_contract"]["operation_types"]
|
||||
assert truth["candidate_catalog"]["decision_effect"] == "none"
|
||||
assert truth["candidate_catalog"]["candidates"][0]["catalog_id"] == "ansible:188-ai-web"
|
||||
assert truth["candidate_catalog"]["candidates"][0]["catalog_id"] == "ansible:188-momo-backup-user"
|
||||
assert truth["candidate_catalog"]["candidates"][0]["auto_apply_enabled"] is False
|
||||
assert (
|
||||
truth["candidate_catalog"]["candidates"][0]["check_mode_playbook_path"]
|
||||
== "infra/ansible/playbooks/188-ai-web-readonly.yml"
|
||||
== "infra/ansible/playbooks/188-momo-backup-user.yml"
|
||||
)
|
||||
|
||||
|
||||
@@ -1011,12 +1011,13 @@ def test_ansible_decision_audit_payload_exposes_check_mode_safety_flags() -> Non
|
||||
)
|
||||
|
||||
candidate = payload["input"]["executor_candidates"][0]
|
||||
assert candidate["catalog_id"] == "ansible:188-ai-web"
|
||||
assert candidate["catalog_id"] == "ansible:188-momo-backup-user"
|
||||
assert candidate["supports_check_mode"] is True
|
||||
assert candidate["playbook_path"] == "infra/ansible/playbooks/188-ai-web.yml"
|
||||
assert candidate["check_mode_playbook_path"] == "infra/ansible/playbooks/188-ai-web-readonly.yml"
|
||||
assert candidate["playbook_path"] == "infra/ansible/playbooks/188-momo-backup-user.yml"
|
||||
assert candidate["check_mode_playbook_path"] == "infra/ansible/playbooks/188-momo-backup-user.yml"
|
||||
assert candidate["auto_apply_enabled"] is False
|
||||
assert candidate["approval_required"] is True
|
||||
assert candidate["risk_level"] == "low"
|
||||
|
||||
|
||||
def test_ansible_check_mode_claim_input_keeps_apply_locked() -> None:
|
||||
@@ -1050,6 +1051,35 @@ def test_ansible_check_mode_claim_input_keeps_apply_locked() -> None:
|
||||
assert claim["playbook_path"] == "infra/ansible/playbooks/188-ai-web-readonly.yml"
|
||||
|
||||
|
||||
def test_ansible_check_mode_claim_input_accepts_momo_backup_user_catalog() -> None:
|
||||
candidate_input = {
|
||||
"incident_id": "INC-MOMO",
|
||||
"executor": "ansible",
|
||||
"executor_candidates": [
|
||||
{
|
||||
"catalog_id": "ansible:188-momo-backup-user",
|
||||
"playbook_path": "infra/ansible/playbooks/188-momo-backup-user.yml",
|
||||
"inventory_hosts": ["host_188"],
|
||||
"risk_level": "low",
|
||||
}
|
||||
],
|
||||
}
|
||||
|
||||
claim = build_ansible_check_mode_claim_input(
|
||||
source_candidate_op_id="00000000-0000-0000-0000-000000000003",
|
||||
candidate_input=candidate_input,
|
||||
)
|
||||
|
||||
assert claim["execution_mode"] == "check_mode"
|
||||
assert claim["apply_enabled"] is False
|
||||
assert claim["catalog_id"] == "ansible:188-momo-backup-user"
|
||||
assert claim["risk_level"] == "low"
|
||||
assert claim["catalog_playbook_path"] == "infra/ansible/playbooks/188-momo-backup-user.yml"
|
||||
assert claim["source_candidate_playbook_path"] == "infra/ansible/playbooks/188-momo-backup-user.yml"
|
||||
assert claim["check_mode_playbook_path"] == "infra/ansible/playbooks/188-momo-backup-user.yml"
|
||||
assert claim["playbook_path"] == "infra/ansible/playbooks/188-momo-backup-user.yml"
|
||||
|
||||
|
||||
def test_ansible_check_mode_claim_rejects_non_check_mode_catalog() -> None:
|
||||
candidate_input = {
|
||||
"incident_id": "INC-SSH",
|
||||
|
||||
113
infra/ansible/playbooks/188-momo-backup-user.yml
Normal file
113
infra/ansible/playbooks/188-momo-backup-user.yml
Normal file
@@ -0,0 +1,113 @@
|
||||
---
|
||||
# AWOOOI Ansible - 192.168.0.188 MOMO PostgreSQL backup user-level repair.
|
||||
# This playbook intentionally avoids become/sudo and only manages ollama-owned
|
||||
# backup scripts plus the ollama user's crontab.
|
||||
|
||||
- name: "192.168.0.188 MOMO PostgreSQL backup user-level repair"
|
||||
hosts: host_188
|
||||
gather_facts: false
|
||||
become: false
|
||||
|
||||
vars:
|
||||
momo_backup_script_source: "{{ playbook_dir }}/../../../scripts/backup/backup-momo-188-pg.sh"
|
||||
momo_notify_helper_source: "{{ playbook_dir }}/../../../scripts/ops/notify-awoooi-ops.sh"
|
||||
momo_scripts_dir: /home/ollama/momo-pro/scripts
|
||||
momo_backup_script_path: /home/ollama/momo-pro/scripts/pg_backup.sh
|
||||
momo_notify_helper_path: /home/ollama/momo-pro/scripts/notify-awoooi-ops.sh
|
||||
momo_backup_dir: /home/ollama/momo_backups
|
||||
momo_backup_cron_name: AWOOOI momo PostgreSQL daily backup
|
||||
momo_backup_cron_job: "PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin /home/ollama/momo-pro/scripts/pg_backup.sh >> /home/ollama/momo_backups/backup.log 2>&1"
|
||||
momo_legacy_bin_cron_line: "0 2 * * * /home/ollama/bin/momo-pg-backup.sh >> /home/ollama/momo_backups/backup.log 2>&1"
|
||||
momo_legacy_direct_cron_line: "0 2 * * * /home/ollama/momo-pro/scripts/pg_backup.sh >> /home/ollama/momo_backups/backup.log 2>&1"
|
||||
|
||||
tasks:
|
||||
- name: Ensure MOMO script and backup directories exist
|
||||
ansible.builtin.file:
|
||||
path: "{{ item }}"
|
||||
state: directory
|
||||
mode: "0755"
|
||||
loop:
|
||||
- "{{ momo_scripts_dir }}"
|
||||
- "{{ momo_backup_dir }}"
|
||||
|
||||
- name: Install AWOOI/AwoooP notification helper for MOMO backup
|
||||
ansible.builtin.copy:
|
||||
src: "{{ momo_notify_helper_source }}"
|
||||
dest: "{{ momo_notify_helper_path }}"
|
||||
mode: "0755"
|
||||
|
||||
- name: Install MOMO PostgreSQL backup script
|
||||
ansible.builtin.copy:
|
||||
src: "{{ momo_backup_script_source }}"
|
||||
dest: "{{ momo_backup_script_path }}"
|
||||
mode: "0755"
|
||||
|
||||
- name: Validate deployed MOMO backup shell scripts
|
||||
ansible.builtin.command:
|
||||
argv:
|
||||
- bash
|
||||
- -n
|
||||
- "{{ momo_backup_script_path }}"
|
||||
- "{{ momo_notify_helper_path }}"
|
||||
changed_when: false
|
||||
check_mode: false
|
||||
when: not ansible_check_mode
|
||||
|
||||
- name: Read current ollama crontab
|
||||
ansible.builtin.command:
|
||||
argv:
|
||||
- crontab
|
||||
- -l
|
||||
register: momo_crontab
|
||||
changed_when: false
|
||||
failed_when: momo_crontab.rc not in [0, 1]
|
||||
check_mode: false
|
||||
|
||||
- name: Remove unmanaged legacy MOMO backup cron entries
|
||||
ansible.builtin.shell: |
|
||||
set -euo pipefail
|
||||
tmp="$(mktemp)"
|
||||
old_one='{{ momo_legacy_bin_cron_line }}'
|
||||
old_two='{{ momo_legacy_direct_cron_line }}'
|
||||
crontab -l 2>/dev/null | awk -v old_one="$old_one" -v old_two="$old_two" '$0 != old_one && $0 != old_two' > "$tmp"
|
||||
crontab "$tmp"
|
||||
rm -f "$tmp"
|
||||
args:
|
||||
executable: /bin/bash
|
||||
changed_when: true
|
||||
when:
|
||||
- not ansible_check_mode
|
||||
- momo_legacy_bin_cron_line in momo_crontab.stdout or momo_legacy_direct_cron_line in momo_crontab.stdout
|
||||
|
||||
- name: Manage MOMO PostgreSQL daily backup cron entry
|
||||
ansible.builtin.cron:
|
||||
name: "{{ momo_backup_cron_name }}"
|
||||
minute: "0"
|
||||
hour: "2"
|
||||
job: "{{ momo_backup_cron_job }}"
|
||||
|
||||
- name: Inspect deployed MOMO backup script
|
||||
ansible.builtin.stat:
|
||||
path: "{{ momo_backup_script_path }}"
|
||||
register: momo_backup_script_stat
|
||||
check_mode: false
|
||||
|
||||
- name: Read ollama crontab after MOMO backup management
|
||||
ansible.builtin.command:
|
||||
argv:
|
||||
- crontab
|
||||
- -l
|
||||
register: momo_crontab_after
|
||||
changed_when: false
|
||||
failed_when: momo_crontab_after.rc != 0
|
||||
check_mode: false
|
||||
|
||||
- name: Summarize MOMO backup user-level repair state
|
||||
ansible.builtin.debug:
|
||||
msg:
|
||||
apply_executed: "{{ not ansible_check_mode }}"
|
||||
backup_script_path: "{{ momo_backup_script_path }}"
|
||||
backup_script_exists: "{{ momo_backup_script_stat.stat.exists | default(false) }}"
|
||||
backup_script_mode: "{{ momo_backup_script_stat.stat.mode | default('unknown') }}"
|
||||
managed_cron_present: "{{ momo_backup_cron_name in momo_crontab_after.stdout }}"
|
||||
legacy_bin_cron_present: "{{ momo_legacy_bin_cron_line in momo_crontab_after.stdout }}"
|
||||
Reference in New Issue
Block a user