Script tu update debian LXC

cryonie

Member
May 8, 2020
40
6
13
43
Hello,

I just wanted to share a script I made to manage the update of my LXC.
First of all some information :
- All my LXC are on Debian
- There might be cases with bugs and so on ... I'm using it since 6 month one time a week and nothing bugged apparently
- The code may be really bad and could greatly be optimized.

Knowing this, here is what the script should do :
- For each LXC
-- Trim it
-- if it stopped, ask if you want to run it for the update process
-- apt update + list the updates pending visually
-- ask you if you want to make the apt upgrade
--- ask you if you want to make a snapshot before the upgrade (never not snapshot before an upgrade in case of :))
-- upgrade
-- if LXC was stopped, ask you if you want to stop it back
-- go to the next LXC

It log things on 1 general log per script run and one log file per LXC per run.

So now here is the code :

Bash:
#!/bin/bash

#Putty : enable "Implicit LF in every CR" to have fine screen reading

ct=$(sudo pct list | awk '/^[0-9]/ {print $1}')
dt="$(date '+%d-%m-%Y_%H-%M-%S')"
log_file_global="general - $dt.log"
log_file_LXC=""
GREEN=$'\e[0;32m'
NC=$'\e[0m'

function log_general() {
    echo "${GREEN}$1${NC}"
    echo "$(date '+%d-%m-%Y_%H-%M-%S') - $1" >> "$log_file_global"
}

function log() {
    echo "${GREEN}$1${NC}"
    echo "$(date '+%d-%m-%Y_%H-%M-%S') - $1" >> "$log_file_LXC"
}

function execScreenLog () {
    eval $1 2>&1 | tee -a "$log_file_LXC"
}

function execLog() {
    eval $1 >> "$log_file_LXC"
}

function snapshotLXC () {
    log "Creating Snapshot for container: $container"
    # Ctrl of free space could be good
    execScreenLog "pct snapshot $container \"Update_$(date '+%Y%m%d_%H%M%S')\""
}

function aptUpgrade () {
    question "Create snapshot ?" "snapshotLXC $container" "log No snapshot created for container: $container"
    execScreenLog "pct exec $container -- bash -c \"apt -q upgrade -y\""
}

function question () {
    log "$1"
    select yn in "Yes" "No"; do
            case $yn in
                    Yes ) log "Yes"; $2; break;;
                    No ) log "No"; $3; break;;
            esac
    done
}

function statusLXC () {
        execScreenLog "pct status $container | grep -oP '(?<=status: ).*'"
}

function startLXC() {
        execScreenLog "pct start $1"
    #Should be changed.
    #Testing statuxLXC is not enough because LXC is "running" immediately (even if network is not working in the LXC)" ... for my LXC 5 seconds are enough for them to respond
    sleep 5
}

function aptUpdate () {
       execScreenLog "pct exec $container -- bash -c \"apt -q update\""
    execScreenLog "pct exec $container -- bash -c \"apt -q list --upgradable\""
}

function stopLXC () {
    execScreenLog "pct shutdown $container"
}

#Begining of the script
printf "\033c"
log_general "Script Start"

for container in $ct
do
    wasStopped=0
    log_general "Maintenance Start on container: $container"
    log_file_LXC="$container - $dt.log"
    log "Maintenance Start on container: $container"
    log "FsTrim on container: $container"
    execScreenLog "pct fstrim $container"
    case $(statusLXC $container) in
        "running") log "Container running: $container";;
        "stopped")
            question "Launch container: $container?" "startLXC $container" "log Container kept stopped: $container"
            wasStopped=1
            case $(statusLXC $container) in
                "stopped") printf "\033c"; continue;;
            esac;;
        *) log "Container $container unknown status"; continue;;
    esac
    #Find a way to count the line number and don't ask if there is no update pending
    aptUpdate
        question "Upgrade container: $container ?" "aptUpgrade" "log Container $container not updated"
    if [ "$wasStopped" = "1" ]
    then
        question "Stop back container : $container" "stopLXC $container" "log Container $container ketp running"
    fi
    #Find a way to ask for snapshot deletion ? Like update is made, you test your service while the script is waiting and then you ask for snapshot deletion
    log "Maintenance End on container: $container"
    log_general "Maintenance End on container: $container"
    read -p "Appuyer sur une touche pour continuer ..."
    printf "\033c"
done

log_general "Script finished"


Eh ! I told you it was ... like raw :D
Someday i'll try to do something like this but for the VM ... someday.
Firstly i thought about publishing it on a git or something so people can fork it / propose some optimization but i'm not used to code and git things at all so i'll just let it there.
Feel free to share things that are not well done or so on, i'm always looking for improvement.

Have a nice day
 
  • Like
Reactions: BJ78945
But I personally don't like to use it for all updates. I use it to only autoinstall security patches so the vulnerabilities get fixed as fast as possible. The normal updates I want to do by hand, so I can read the changelogs first and compare the config files to make sure the upgrade won't break anything. And then test the services after upgrade if everything is still working as intended.
 
The normal updates I want to do by hand, so I can read the changelogs first and compare the config files to make sure the upgrade won't break anything. And then test the services after upgrade if everything is still working as intended.
Its ok ;)
My script runs normally in "interactive" mode, so everybody can chack the changes.
With the config file, it is also possible to exclude machines from update.
It also creates an log file, to check all afterwards.
 
Last edited:

About

The Proxmox community has been around for many years and offers help and support for Proxmox VE, Proxmox Backup Server, and Proxmox Mail Gateway.
We think our community is one of the best thanks to people like you!

Get your subscription!

The Proxmox team works very hard to make sure you are running the best software and getting stable updates and security enhancements, as well as quick enterprise support. Tens of thousands of happy customers have a Proxmox subscription. Get yours easily in our online shop.

Buy now!