--- # Update cloudbox.beawit.net Proxmox LXC containers and VMs # Usage: ansible-playbook -i inventory update-cloudbox-containers.yml - name: Update Cloudbox Containers and VMs hosts: cloudbox gather_facts: no vars: candidate_containers: - 101 # hosting-manager (LXC) candidate_vms: - 201 # tacticalrmm (VM) tasks: - name: Discover running LXC containers ansible.builtin.shell: cmd: | for ct in {{ candidate_containers | join(' ') }}; do if sudo /usr/sbin/pct status "$ct" 2>/dev/null | grep -q running; then echo "$ct" fi done register: running_cts check_mode: no changed_when: false - name: Discover running VMs ansible.builtin.shell: cmd: | for vm in {{ candidate_vms | join(' ') }}; do if sudo /usr/sbin/qm status "$vm" 2>/dev/null | grep -q running; then echo "$vm" fi done register: running_vms check_mode: no changed_when: false - name: Detect OS in running containers ansible.builtin.shell: cmd: | CT_ID="{{ 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: "{{ running_cts.stdout_lines }}" register: container_os check_mode: no changed_when: false when: running_cts.stdout_lines | length > 0 - name: Update running containers with OS-specific package manager ansible.builtin.shell: cmd: | set -e CT_ID="{{ item[0] }}" OS_TYPE="{{ item[1] }}" echo "=== Updating container $CT_ID (OS: $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 ($OS_TYPE), 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 "=== Container $CT_ID complete ===" loop: "{{ running_cts.stdout_lines | zip(container_os.results | default([]) | map(attribute='stdout')) | list }}" when: running_cts.stdout_lines | length > 0 - name: Update running VMs (assumed Debian/Ubuntu) ansible.builtin.shell: cmd: | VM_ID="{{ item }}" echo "=== Updating VM $VM_ID ===" sudo /usr/sbin/qm guest exec $VM_ID -- bash -c 'export DEBIAN_FRONTEND=noninteractive && apt-get update -qq && apt-get upgrade -y -qq' echo "=== VM $VM_ID complete ===" loop: "{{ running_vms.stdout_lines }}" when: running_vms.stdout_lines | length > 0 - name: Report results ansible.builtin.debug: msg: "[cloudbox] updates complete. Containers: {{ running_cts.stdout_lines | default([]) }}, VMs: {{ running_vms.stdout_lines | default([]) }}"