Update all containers
My basement full of random servers has slowly consolidated into containers running on a Proxmox server. Containers are a light weight virtuals leveraging the host kernel, similar to Jails on FreeBSD. Proxmox provides pct to manage these containers.
So the goal here is to script up apt updating and upgrading all containers. This will also provide a template on iterating and executing commands on multiple containers.
As all things on Unix there are a few ways to skin a cat, so while I could use ssh to get things started on the containers I’m going to defer to pct exec
which takes a container id and execs a command as root inside that container. For example:
$ sudo pct exec 100 apt update
Next we will need to get a list of container ids to iterate through. Again a couple million ways to do this, some based on file system /etc/pve/nodes/sinistar/lxc/
or /var/lib/lxc/
but again I will defer to pct list
to provide this information. The output looks like this:
VMID Status Lock Name
100 running dvr
101 running timecapsule
102 running gitlab
104 running wintersetpta
105 running mail
So we will need to cut the ids out of it with a little help of cut
and tail
$ sudo pct list | tail -n +2 | cut -f1 -d' '
Will do the trick.
Now since we are issuing commands within another command ( pct exec
) we will have to find the incantation to escape the code we want executed on the remote machine. After a little googling looks like wrapping them up in bash will do the trick:
$ sudo pct exec 100 -- bash -c "apt update && apt upgrade -y"
Now lets assemble all the parts from above and create a little script to do our bidding!
#!/bin/bash
# update all containers
# list of container ids we need to iterate through
containers=$(pct list | tail -n +2 | cut -f1 -d' ')
function update_container() {
container=$1
echo "Updating $container..."
# to chain commands within one exec we will need to wrap them in bash
pct exec $container -- bash -c "apt update && apt upgrade -y"
}
for container in $containers
do
update_container $container
done