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