Привет, я просто хотел поделиться скриптом, который я сделал для управления обновлением моего LXC. Сначала немного информации: - Все мои LXC на Debian - Могут быть случаи с ошибками и так далее... Я использую его последние 6 месяцев раз в неделю, и, кажется, ничего не ломалось - Код может быть действительно плохим и его можно значительно оптимизировать. Учитывая это, вот что должен делать скрипт: - Для каждого LXC -- Очищать его -- если он остановлен, спрашивать, хотите ли вы запустить его для процесса обновления -- apt update + визуально показывать ожидающие обновления -- спрашивать, хотите ли вы сделать apt upgrade -- спрашивать, хотите ли вы сделать снимок перед обновлением (никогда не забывайте делать снимок перед обновлением на всякий случай) -- обновлять -- если LXC был остановлен, спрашивать, хотите ли вы снова его остановить -- переходить к следующему LXC. Он записывает все в один общий лог за выполнение скрипта и один лог-файл на каждый LXC за выполнение. Так что вот код: Bash: #!/bin/bash
#Putty : включите "Implicit LF in every CR", чтобы было удобно читать на экране
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 "Создание снимка для контейнера: $container"
# Можно было бы проверить свободное место
execScreenLog "pct snapshot $container \"Update_$(date '+%Y%m%d_%H%M%S')\""
}
function aptUpgrade () {
question "Создать снимок?" "snapshotLXC $container" "log Снимок не создан для контейнера: $container"
execScreenLog "pct exec $container -- bash -c \"apt -q upgrade -y\""
}
function question () {
log "$1"
select yn in "Да" "Нет"; do
case $yn in
Да ) log "Да"; $2; break;;
Нет ) log "Нет"; $3; break;;
esac
done
}
function statusLXC () {
execScreenLog "pct status $container | grep -oP '(?<=status: ).*'"
}
function startLXC() {
execScreenLog "pct start $1"
# Это нужно изменить.
# Проверка статуса LXC недостаточно, потому что LXC "работает" немедленно (даже если сеть не работает в LXC)" ... для моего LXC 5 секунд достаточно, чтобы они ответили
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"
}
# Начало скрипта
printf "\033c"
log_general "Начало скрипта"
for container in $ct
do
wasStopped=0
log_general "Начало обслуживания контейнера: $container"
log_file_LXC="$container - $dt.log"
log "Начало обслуживания контейнера: $container"
log "FsTrim на контейнере: $container"
execScreenLog "pct fstrim $container"
case $(statusLXC $container) in
"running") log "Контейнер работает: $container";;
"stopped")
question "Запустить контейнер: $container?" "startLXC $container" "log Контейнер оставлен остановленным: $container"
wasStopped=1
case $(statusLXC $container) in
"stopped") printf "\033c"; continue;;
esac;;
*) log "Пользовательский контейнер $container неизвестного статуса"; continue;;
esac
# Найти способ подсчитать количество строк и не спрашивать, если нет ожидающего обновления
aptUpdate
question "Обновить контейнер: $container?" "aptUpgrade" "log Контейнер $container не обновлен"
if [ "$wasStopped" = "1" ]
then
question "Остановить контейнер: $container" "stopLXC $container" "log Контейнер $container оставлен работающим"
fi
# Найти способ спросить о удалении снимка? Например, обновление завершено, вы тестируете свою службу, пока скрипт ждет, а затем вы спрашиваете об удалении снимка
log "Конец обслуживания контейнера: $container"
log_general "Конец обслуживания контейнера: $container"
read -p "Нажмите любую клавишу для продолжения ..."
printf "\033c"
done
log_general "Скрипт завершен" Эй! Я же говорил, что это... как бы сыровато. Когда-нибудь я попробую сделать что-то подобное, но для виртуальной машины... когда-нибудь. Сначала я думал опубликовать это на git или что-то вроде этого, чтобы люди могли форкать и предлагать оптимизацию, но я совсем не разбираюсь в коде и git, поэтому просто оставлю это здесь. Не стесняйтесь делиться замечаниями о том, что сделано не очень хорошо и так далее, я всегда ищу возможности для улучшения. Хорошего дня!
#Putty : включите "Implicit LF in every CR", чтобы было удобно читать на экране
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 "Создание снимка для контейнера: $container"
# Можно было бы проверить свободное место
execScreenLog "pct snapshot $container \"Update_$(date '+%Y%m%d_%H%M%S')\""
}
function aptUpgrade () {
question "Создать снимок?" "snapshotLXC $container" "log Снимок не создан для контейнера: $container"
execScreenLog "pct exec $container -- bash -c \"apt -q upgrade -y\""
}
function question () {
log "$1"
select yn in "Да" "Нет"; do
case $yn in
Да ) log "Да"; $2; break;;
Нет ) log "Нет"; $3; break;;
esac
done
}
function statusLXC () {
execScreenLog "pct status $container | grep -oP '(?<=status: ).*'"
}
function startLXC() {
execScreenLog "pct start $1"
# Это нужно изменить.
# Проверка статуса LXC недостаточно, потому что LXC "работает" немедленно (даже если сеть не работает в LXC)" ... для моего LXC 5 секунд достаточно, чтобы они ответили
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"
}
# Начало скрипта
printf "\033c"
log_general "Начало скрипта"
for container in $ct
do
wasStopped=0
log_general "Начало обслуживания контейнера: $container"
log_file_LXC="$container - $dt.log"
log "Начало обслуживания контейнера: $container"
log "FsTrim на контейнере: $container"
execScreenLog "pct fstrim $container"
case $(statusLXC $container) in
"running") log "Контейнер работает: $container";;
"stopped")
question "Запустить контейнер: $container?" "startLXC $container" "log Контейнер оставлен остановленным: $container"
wasStopped=1
case $(statusLXC $container) in
"stopped") printf "\033c"; continue;;
esac;;
*) log "Пользовательский контейнер $container неизвестного статуса"; continue;;
esac
# Найти способ подсчитать количество строк и не спрашивать, если нет ожидающего обновления
aptUpdate
question "Обновить контейнер: $container?" "aptUpgrade" "log Контейнер $container не обновлен"
if [ "$wasStopped" = "1" ]
then
question "Остановить контейнер: $container" "stopLXC $container" "log Контейнер $container оставлен работающим"
fi
# Найти способ спросить о удалении снимка? Например, обновление завершено, вы тестируете свою службу, пока скрипт ждет, а затем вы спрашиваете об удалении снимка
log "Конец обслуживания контейнера: $container"
log_general "Конец обслуживания контейнера: $container"
read -p "Нажмите любую клавишу для продолжения ..."
printf "\033c"
done
log_general "Скрипт завершен" Эй! Я же говорил, что это... как бы сыровато. Когда-нибудь я попробую сделать что-то подобное, но для виртуальной машины... когда-нибудь. Сначала я думал опубликовать это на git или что-то вроде этого, чтобы люди могли форкать и предлагать оптимизацию, но я совсем не разбираюсь в коде и git, поэтому просто оставлю это здесь. Не стесняйтесь делиться замечаниями о том, что сделано не очень хорошо и так далее, я всегда ищу возможности для улучшения. Хорошего дня!
