Weekly sync: July 12-19 changes
- Updated DREAMS.md and MEMORY.md with new entries - Added daily dreaming session corpus (2026-07-05 through 2026-07-18) - Added deep/light/REM dream analysis files for July 6-19 - Added Intune rollout outputs for KMCC client - Added Vault API integration scripts and documentation - Added container update playbook (update-containers.yml) - Added .gitignore for generated/noise files
This commit is contained in:
@@ -0,0 +1,414 @@
|
||||
---
|
||||
# Update bve (lab node) Proxmox LXC containers and VMs
|
||||
# Integrates features from community-scripts/ProxmoxVE update-lxcs script
|
||||
# Usage: ansible-playbook -i inventory/proxmox update-containers.yml
|
||||
|
||||
- name: Update bve Lab LXC Containers and VMs
|
||||
hosts: bve
|
||||
gather_facts: no
|
||||
vars:
|
||||
candidate_containers:
|
||||
- 101 # chief-executive-officer
|
||||
- 103 # semaphore
|
||||
- 104 # cyberchef
|
||||
- 107 # shlink
|
||||
- 108 # paperclip
|
||||
candidate_vms:
|
||||
- 102 # mikrotik-routeros-chr
|
||||
- 106 # freepbx
|
||||
- 112 # dockploy
|
||||
- 200 # proxmox
|
||||
- 8000 # debian-13-cloud
|
||||
- 8001 # ubuntu-24.04-cloud
|
||||
- 8002 # docker-vm
|
||||
|
||||
tasks:
|
||||
# ============================================================
|
||||
# PHASE 1: Discover container/VM statuses and filter templates
|
||||
# ============================================================
|
||||
- name: Check status and template status for candidate containers
|
||||
ansible.builtin.shell:
|
||||
cmd: |
|
||||
set -e
|
||||
CT_ID="{{ item }}"
|
||||
# Check if it's a template (skip templates)
|
||||
TEMPLATE_CHECK=$(sudo /usr/sbin/pct config "$CT_ID" 2>/dev/null | grep -i "template:" | head -1 || true)
|
||||
if echo "$TEMPLATE_CHECK" | grep -qi "template: 1"; then
|
||||
echo "TEMPLATE:$CT_ID"
|
||||
else
|
||||
# Check running status
|
||||
if sudo /usr/sbin/pct status "$CT_ID" 2>/dev/null | grep -q running; then
|
||||
echo "RUNNING:$CT_ID"
|
||||
elif sudo /usr/sbin/pct status "$CT_ID" 2>/dev/null | grep -q stopped; then
|
||||
echo "STOPPED:$CT_ID"
|
||||
else
|
||||
echo "MISSING:$CT_ID"
|
||||
fi
|
||||
fi
|
||||
loop: "{{ candidate_containers }}"
|
||||
register: container_statuses
|
||||
check_mode: no
|
||||
changed_when: false
|
||||
|
||||
- name: Check status for candidate VMs
|
||||
ansible.builtin.shell:
|
||||
cmd: |
|
||||
set -e
|
||||
VM_ID="{{ item }}"
|
||||
if sudo /usr/sbin/qm status "$VM_ID" 2>/dev/null | grep -q running; then
|
||||
echo "RUNNING:$VM_ID"
|
||||
elif sudo /usr/sbin/qm status "$VM_ID" 2>/dev/null | grep -q stopped; then
|
||||
echo "STOPPED:$VM_ID"
|
||||
else
|
||||
echo "MISSING:$VM_ID"
|
||||
fi
|
||||
loop: "{{ candidate_vms }}"
|
||||
register: vm_statuses
|
||||
check_mode: no
|
||||
changed_when: false
|
||||
|
||||
- name: Categorize containers by status
|
||||
ansible.builtin.set_fact:
|
||||
running_containers: "{{ container_statuses.results | map(attribute='stdout') | select('match', '^RUNNING:') | map('regex_replace', '^RUNNING:', '') | list }}"
|
||||
stopped_containers: "{{ container_statuses.results | map(attribute='stdout') | select('match', '^STOPPED:') | map('regex_replace', '^STOPPED:', '') | list }}"
|
||||
template_containers: "{{ container_statuses.results | map(attribute='stdout') | select('match', '^TEMPLATE:') | map('regex_replace', '^TEMPLATE:', '') | list }}"
|
||||
running_vms: "{{ vm_statuses.results | map(attribute='stdout') | select('match', '^RUNNING:') | map('regex_replace', '^RUNNING:', '') | list }}"
|
||||
stopped_vms: "{{ vm_statuses.results | map(attribute='stdout') | select('match', '^STOPPED:') | map('regex_replace', '^STOPPED:', '') | list }}"
|
||||
|
||||
- name: Show templates being skipped
|
||||
ansible.builtin.debug:
|
||||
msg: "Skipping template containers: {{ template_containers | join(', ') }}"
|
||||
when: template_containers | length > 0
|
||||
|
||||
# ============================================================
|
||||
# PHASE 2: Process running containers with OS detection
|
||||
# ============================================================
|
||||
- name: Detect OS in running containers
|
||||
ansible.builtin.shell:
|
||||
cmd: |
|
||||
set -e
|
||||
CT_ID="{{ item }}"
|
||||
# Detect OS by checking /etc/os-release
|
||||
OS_INFO=$(sudo /usr/sbin/pct exec "$CT_ID" -- cat /etc/os-release 2>/dev/null || echo "")
|
||||
if echo "$OS_INFO" | grep -qi "alpine"; then
|
||||
echo "alpine"
|
||||
elif echo "$OS_INFO" | grep -qi "arch"; then
|
||||
echo "arch"
|
||||
elif echo "$OS_INFO" | grep -qi "debian"; then
|
||||
echo "debian"
|
||||
elif echo "$OS_INFO" | grep -qi "ubuntu"; then
|
||||
echo "ubuntu"
|
||||
elif echo "$OS_INFO" | grep -qi "devuan"; then
|
||||
echo "devuan"
|
||||
elif echo "$OS_INFO" | grep -qi "fedora"; then
|
||||
echo "fedora"
|
||||
elif echo "$OS_INFO" | grep -qi "rocky"; then
|
||||
echo "rocky"
|
||||
elif echo "$OS_INFO" | grep -qi "centos"; then
|
||||
echo "centos"
|
||||
elif echo "$OS_INFO" | grep -qi "alma"; then
|
||||
echo "alma"
|
||||
elif echo "$OS_INFO" | grep -qi "suse"; then
|
||||
echo "opensuse"
|
||||
else
|
||||
# Default to debian/ubuntu if detection fails
|
||||
echo "unknown"
|
||||
fi
|
||||
loop: "{{ running_containers }}"
|
||||
register: container_os_detection
|
||||
check_mode: no
|
||||
changed_when: false
|
||||
when: running_containers | length > 0
|
||||
|
||||
- name: Get disk usage for running containers
|
||||
ansible.builtin.shell:
|
||||
cmd: |
|
||||
set -e
|
||||
CT_ID="{{ item }}"
|
||||
sudo /usr/sbin/pct exec "$CT_ID" -- df -h / 2>/dev/null | tail -1 | awk '{print $5}'
|
||||
loop: "{{ running_containers }}"
|
||||
register: container_disk_usage
|
||||
check_mode: no
|
||||
changed_when: false
|
||||
when: running_containers | length > 0
|
||||
|
||||
- name: Update running containers with OS-specific package manager
|
||||
ansible.builtin.shell:
|
||||
cmd: |
|
||||
set -e
|
||||
CT_ID="{{ item.item }}"
|
||||
OS_TYPE="{{ item.stdout }}"
|
||||
|
||||
echo "=== Container $CT_ID ==="
|
||||
echo "OS Type: $OS_TYPE"
|
||||
|
||||
# Get disk usage
|
||||
DISK_USAGE=$(sudo /usr/sbin/pct exec "$CT_ID" -- df -h / 2>/dev/null | tail -1 | awk '{print $5}' || echo "unknown")
|
||||
echo "Boot disk usage: $DISK_USAGE"
|
||||
echo "Starting update..."
|
||||
|
||||
case "$OS_TYPE" in
|
||||
alpine)
|
||||
sudo /usr/sbin/pct exec "$CT_ID" -- sh -c 'apk update && apk upgrade -a'
|
||||
;;
|
||||
arch)
|
||||
sudo /usr/sbin/pct exec "$CT_ID" -- bash -c 'pacman -Syyu --noconfirm'
|
||||
;;
|
||||
fedora|rocky|centos|alma)
|
||||
sudo /usr/sbin/pct exec "$CT_ID" -- bash -c 'dnf -y update && dnf -y upgrade'
|
||||
;;
|
||||
ubuntu|debian|devuan)
|
||||
sudo /usr/sbin/pct exec "$CT_ID" -- bash -c 'export DEBIAN_FRONTEND=noninteractive && apt-get update -qq && apt-get -yq dist-upgrade'
|
||||
;;
|
||||
opensuse)
|
||||
sudo /usr/sbin/pct exec "$CT_ID" -- bash -c 'zypper ref && zypper --non-interactive dup'
|
||||
;;
|
||||
*)
|
||||
echo "Unknown OS, trying apt..."
|
||||
sudo /usr/sbin/pct exec "$CT_ID" -- bash -c 'export DEBIAN_FRONTEND=noninteractive && apt-get update -qq && apt-get -yq dist-upgrade'
|
||||
;;
|
||||
esac
|
||||
|
||||
echo "Update complete for container $CT_ID"
|
||||
loop: "{{ container_os_detection.results | default([]) }}"
|
||||
loop_control:
|
||||
label: "{{ item.item }}"
|
||||
register: container_update_output
|
||||
when: running_containers | length > 0
|
||||
|
||||
- name: Check if reboot is required in containers
|
||||
ansible.builtin.shell:
|
||||
cmd: |
|
||||
set -e
|
||||
CT_ID="{{ item.item }}"
|
||||
OS_TYPE="{{ item.stdout }}"
|
||||
|
||||
REBOOT_NEEDED="no"
|
||||
# Check reboot-required file (Debian/Ubuntu style)
|
||||
if [ "$OS_TYPE" = "ubuntu" ] || [ "$OS_TYPE" = "debian" ] || [ "$OS_TYPE" = "devuan" ]; then
|
||||
if sudo /usr/sbin/pct exec "$CT_ID" -- test -f /var/run/reboot-required 2>/dev/null; then
|
||||
REBOOT_NEEDED="yes"
|
||||
fi
|
||||
fi
|
||||
# Check for needs-restarting (RHEL/Fedora style)
|
||||
if [ "$OS_TYPE" = "fedora" ] || [ "$OS_TYPE" = "rocky" ] || [ "$OS_TYPE" = "centos" ] || [ "$OS_TYPE" = "alma" ]; then
|
||||
if sudo /usr/sbin/pct exec "$CT_ID" -- bash -c 'which needs-restarting > /dev/null 2>&1 && needs-restarting -r' 2>/dev/null; then
|
||||
REBOOT_NEEDED="yes"
|
||||
fi
|
||||
fi
|
||||
|
||||
echo "$CT_ID:$OS_TYPE:$REBOOT_NEEDED"
|
||||
loop: "{{ container_os_detection.results | default([]) }}"
|
||||
register: container_reboot_status
|
||||
check_mode: no
|
||||
changed_when: false
|
||||
when: running_containers | length > 0
|
||||
|
||||
- name: Run patchmon-agent report if present
|
||||
ansible.builtin.shell:
|
||||
cmd: |
|
||||
set -e
|
||||
CT_ID="{{ item.item }}"
|
||||
sudo /usr/sbin/pct exec "$CT_ID" -- bash -c 'if [ -x /usr/local/bin/patchmon-agent ]; then /usr/local/bin/patchmon-agent report; fi' 2>/dev/null || true
|
||||
loop: "{{ container_os_detection.results | default([]) }}"
|
||||
register: patchmon_results
|
||||
failed_when: false
|
||||
changed_when: false
|
||||
when: running_containers | length > 0
|
||||
|
||||
# ============================================================
|
||||
# PHASE 3: Process running VMs (assumed Debian/Ubuntu with apt)
|
||||
# ============================================================
|
||||
- name: Get disk usage for running VMs
|
||||
ansible.builtin.shell:
|
||||
cmd: |
|
||||
set -e
|
||||
VM_ID="{{ item }}"
|
||||
sudo /usr/sbin/qm guest exec "$VM_ID" -- bash -c "df -h / | tail -1 | awk '{print \$5}'" 2>/dev/null | jq -r '."out-data" // empty' | tr -d '\n' || echo "unknown"
|
||||
loop: "{{ running_vms }}"
|
||||
register: vm_disk_usage
|
||||
check_mode: no
|
||||
changed_when: false
|
||||
when: running_vms | length > 0
|
||||
|
||||
- name: Update running VMs
|
||||
ansible.builtin.shell:
|
||||
cmd: |
|
||||
set -e
|
||||
VM_ID="{{ item }}"
|
||||
|
||||
echo "=== VM $VM_ID ==="
|
||||
|
||||
# Get disk usage
|
||||
DISK_USAGE=$(sudo /usr/sbin/qm guest exec "$VM_ID" -- bash -c "df -h / | tail -1 | awk '{print \$5}'" 2>/dev/null | jq -r '."out-data" // empty' | tr -d '\n' || echo "unknown")
|
||||
echo "Boot disk usage: $DISK_USAGE"
|
||||
|
||||
sudo /usr/sbin/qm guest exec "$VM_ID" -- bash -c 'export DEBIAN_FRONTEND=noninteractive && apt-get update -qq && apt-get -yq dist-upgrade'
|
||||
echo "Update complete for VM $VM_ID"
|
||||
loop: "{{ running_vms }}"
|
||||
register: vm_update_output
|
||||
when: running_vms | length > 0
|
||||
|
||||
- name: Check if reboot is required in VMs
|
||||
ansible.builtin.shell:
|
||||
cmd: |
|
||||
set -e
|
||||
VM_ID="{{ item }}"
|
||||
if sudo /usr/sbin/qm guest exec "$VM_ID" -- test -f /var/run/reboot-required 2>/dev/null | grep -q '"exitcode": "OK"'; then
|
||||
echo "$VM_ID:yes"
|
||||
else
|
||||
echo "$VM_ID:no"
|
||||
fi
|
||||
loop: "{{ running_vms }}"
|
||||
register: vm_reboot_status
|
||||
check_mode: no
|
||||
changed_when: false
|
||||
when: running_vms | length > 0
|
||||
|
||||
- name: Run patchmon-agent report if present on VMs
|
||||
ansible.builtin.shell:
|
||||
cmd: |
|
||||
set -e
|
||||
VM_ID="{{ item }}"
|
||||
sudo /usr/sbin/qm guest exec "$VM_ID" -- bash -c 'if [ -x /usr/local/bin/patchmon-agent ]; then /usr/local/bin/patchmon-agent report; fi' 2>/dev/null || true
|
||||
loop: "{{ running_vms }}"
|
||||
register: vm_patchmon_results
|
||||
failed_when: false
|
||||
changed_when: false
|
||||
when: running_vms | length > 0
|
||||
|
||||
# ============================================================
|
||||
# PHASE 4: Process stopped containers (start, update, stop)
|
||||
# ============================================================
|
||||
- name: Start stopped containers for update
|
||||
ansible.builtin.shell:
|
||||
cmd: |
|
||||
set -e
|
||||
CT_ID="{{ item }}"
|
||||
echo "Starting container $CT_ID..."
|
||||
sudo /usr/sbin/pct start "$CT_ID"
|
||||
# Wait for container to be ready
|
||||
for i in {1..30}; do
|
||||
if sudo /usr/sbin/pct exec "$CT_ID" -- echo "ready" 2>/dev/null; then
|
||||
break
|
||||
fi
|
||||
sleep 2
|
||||
done
|
||||
echo "Container $CT_ID is running"
|
||||
loop: "{{ stopped_containers }}"
|
||||
register: started_containers
|
||||
when: stopped_containers | length > 0
|
||||
|
||||
- name: Detect OS in newly started containers
|
||||
ansible.builtin.shell:
|
||||
cmd: |
|
||||
set -e
|
||||
CT_ID="{{ item.item }}"
|
||||
OS_INFO=$(sudo /usr/sbin/pct exec "$CT_ID" -- cat /etc/os-release 2>/dev/null || echo "")
|
||||
if echo "$OS_INFO" | grep -qi "alpine"; then
|
||||
echo "alpine"
|
||||
elif echo "$OS_INFO" | grep -qi "arch"; then
|
||||
echo "arch"
|
||||
elif echo "$OS_INFO" | grep -qi "debian"; then
|
||||
echo "debian"
|
||||
elif echo "$OS_INFO" | grep -qi "ubuntu"; then
|
||||
echo "ubuntu"
|
||||
elif echo "$OS_INFO" | grep -qi "devuan"; then
|
||||
echo "devuan"
|
||||
elif echo "$OS_INFO" | grep -qi "fedora"; then
|
||||
echo "fedora"
|
||||
elif echo "$OS_INFO" | grep -qi "rocky"; then
|
||||
echo "rocky"
|
||||
elif echo "$OS_INFO" | grep -qi "centos"; then
|
||||
echo "centos"
|
||||
elif echo "$OS_INFO" | grep -qi "alma"; then
|
||||
echo "alma"
|
||||
elif echo "$OS_INFO" | grep -qi "suse"; then
|
||||
echo "opensuse"
|
||||
else
|
||||
echo "unknown"
|
||||
fi
|
||||
loop: "{{ started_containers.results | default([]) }}"
|
||||
register: stopped_container_os
|
||||
check_mode: no
|
||||
changed_when: false
|
||||
when: stopped_containers | length > 0
|
||||
|
||||
- name: Update stopped containers (now running)
|
||||
ansible.builtin.shell:
|
||||
cmd: |
|
||||
set -e
|
||||
CT_ID="{{ item.item }}"
|
||||
OS_TYPE="{{ item.stdout }}"
|
||||
|
||||
echo "=== Container $CT_ID (was stopped, now updating) ==="
|
||||
echo "OS Type: $OS_TYPE"
|
||||
|
||||
case "$OS_TYPE" in
|
||||
alpine)
|
||||
sudo /usr/sbin/pct exec "$CT_ID" -- sh -c 'apk update && apk upgrade -a'
|
||||
;;
|
||||
arch)
|
||||
sudo /usr/sbin/pct exec "$CT_ID" -- bash -c 'pacman -Syyu --noconfirm'
|
||||
;;
|
||||
fedora|rocky|centos|alma)
|
||||
sudo /usr/sbin/pct exec "$CT_ID" -- bash -c 'dnf -y update && dnf -y upgrade'
|
||||
;;
|
||||
ubuntu|debian|devuan)
|
||||
sudo /usr/sbin/pct exec "$CT_ID" -- bash -c 'export DEBIAN_FRONTEND=noninteractive && apt-get update -qq && apt-get -yq dist-upgrade'
|
||||
;;
|
||||
opensuse)
|
||||
sudo /usr/sbin/pct exec "$CT_ID" -- bash -c 'zypper ref && zypper --non-interactive dup'
|
||||
;;
|
||||
*)
|
||||
echo "Unknown OS, trying apt..."
|
||||
sudo /usr/sbin/pct exec "$CT_ID" -- bash -c 'export DEBIAN_FRONTEND=noninteractive && apt-get update -qq && apt-get -yq dist-upgrade'
|
||||
;;
|
||||
esac
|
||||
|
||||
echo "Update complete for container $CT_ID"
|
||||
loop: "{{ stopped_container_os.results | default([]) }}"
|
||||
loop_control:
|
||||
label: "{{ item.item }}"
|
||||
register: stopped_container_update
|
||||
when: stopped_containers | length > 0
|
||||
|
||||
- name: Stop containers that were started for update
|
||||
ansible.builtin.shell:
|
||||
cmd: |
|
||||
set -e
|
||||
CT_ID="{{ item.item }}"
|
||||
echo "Stopping container $CT_ID..."
|
||||
sudo /usr/sbin/pct stop "$CT_ID"
|
||||
echo "Container $CT_ID stopped"
|
||||
loop: "{{ started_containers.results | default([]) }}"
|
||||
when: stopped_containers | length > 0
|
||||
|
||||
# ============================================================
|
||||
# PHASE 5: Report summary
|
||||
# ============================================================
|
||||
- name: Build update summary
|
||||
ansible.builtin.set_fact:
|
||||
summary_report:
|
||||
host: "bve"
|
||||
templates_skipped: "{{ template_containers }}"
|
||||
running_containers_updated: "{{ running_containers }}"
|
||||
running_vms_updated: "{{ running_vms }}"
|
||||
stopped_containers_updated: "{{ stopped_containers }}"
|
||||
containers_needing_reboot: "{{ container_reboot_status.results | default([]) | selectattr('stdout', 'search', ':yes') | map(attribute='stdout') | map('regex_replace', ':(.*):yes', '') | list }}"
|
||||
vms_needing_reboot: "{{ vm_reboot_status.results | default([]) | selectattr('stdout', 'search', ':yes') | map(attribute='stdout') | map('regex_replace', ':(.*):yes', '') | list }}"
|
||||
|
||||
- name: Display update summary
|
||||
ansible.builtin.debug:
|
||||
msg:
|
||||
- "=========================================="
|
||||
- "BVE UPDATE SUMMARY"
|
||||
- "=========================================="
|
||||
- "Templates skipped: {{ summary_report.templates_skipped | default([]) | join(', ') | default('None') }}"
|
||||
- "Running containers updated: {{ summary_report.running_containers_updated | default([]) | join(', ') | default('None') }}"
|
||||
- "Running VMs updated: {{ summary_report.running_vms_updated | default([]) | join(', ') | default('None') }}"
|
||||
- "Stopped containers updated (and stopped): {{ summary_report.stopped_containers_updated | default([]) | join(', ') | default('None') }}"
|
||||
- "---"
|
||||
- "Containers requiring reboot: {{ summary_report.containers_needing_reboot | default([]) | join(', ') | default('None') }}"
|
||||
- "VMs requiring reboot: {{ summary_report.vms_needing_reboot | default([]) | join(', ') | default('None') }}"
|
||||
- "=========================================="
|
||||
Reference in New Issue
Block a user