You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
calculate-toolkit/cl-lxc

885 lines
25 KiB

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

#!/bin/bash
# Copyright 2022 Mir Calculate. http://www.calculate-linux.org
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
TEXTDOMAIN=cl_lxc
export PATH="/lib/rc/bin:$PATH"
set -ueo pipefail
check_simultaneous_run(){ # Проверим на повторный запуск
lock=/tmp/cl-lxc.lock
if ! mkdir $lock &>/dev/null; then
echo $"Script launched!" >&2
exit 1
fi
trap "rm -rf $lock" EXIT
true
}
print_help(){
usage=$(printf $"SYNOPSIS: %s [PARAMETERS?] [name]" ${0##*/})
if [[ "$1" == "all" ]]; then
echo $"$usage
${0##*/} installation, configuration and update of an LXC container with Calculate Linux on board
Parameters:
-P, --profile select profile flavour ('list' to view all that applies)
-c, --create create new container
--path path to container
-p, --prepare get rootfs ready for update
-u, --upgrade update container rootfs
--diff diff two rootfs packages
-R, --clear_cache clear cache
-m, --mirror mirror address
-h, --help show this help page
"
else
echo $usage
fi
true
}
get_args(){
check_val(){
if [[ "$#" == "1" || "$2" =~ ^- ]]; then
echo $"Parameter '$1' contains no value!" >&2
exit 1
fi
}
profile_=
create_=0
path_=
prepare_=0
upgrade_=0
diff_=0
clear_=0
mirror_=mirror.calculate-linux.org
while (( $# > 0 )); do
case "$1" in
-P|--profile)
check_val $@
profile_=$2
shift
;;
-c|--create)
create_=1
;;
--path)
check_val $@
path_=$2
shift
;;
-p|--prepare)
prepare_=1
;;
-u|--upgrade)
upgrade_=1
;;
--diff)
diff_=1
;;
-R|--clear_cache)
clear_=1
;;
-m|--mirror)
check_val $@
mirror_=$2
shift
;;
-h|--help)
print_help "all"
exit
;;
--)
shift
break
;;
*)
if ! [[ $1 =~ ^- ]]; then
break
fi
printf $"Invalid option '%s'.\n" $1 >&2
exit 1
;;
esac
shift
done
if [ "$profile_" == 'list' ]; then
print_profile
exit 0
elif (( $# == 1 )); then
lxc_=$1
if [[ $lxc_ =~ [^A-Za-z0-9_\._\-] ]]; then
echo $"Container name contains wrong characters." >&2
exit 1
fi
if [[ $lxc_ = 'scratch' ]]; then
echo $"The name '$lxc_' is reserved. Use a different container name." >&2
exit 1
fi
else
print_help "usage"
exit 1
fi
true
}
print_profile(){
local profile_dir
if [[ -e /var/db/repos/container/profiles/profiles.desc ]]; then
profile_dir=/var/db/repos/container
elif [[ -e /var/calculate/repos/container/profiles/profiles.desc ]]; then
profile_dir=/var/calculate/repos/container
else
profile_dir=/var/calculate/tmp/update/container
if [[ ! -d $profile_dir ]]; then
git clone https://github.com/calculatelinux/container $profile_dir &>/dev/null
else
git -C $profile_dir pull &>/dev/null
fi
fi
# Отобразим список доступных профилей или проверим наличие запрошенного
if (( $# == 0 )); then
echo $"Profile:"
grep "^amd64" ${profile_dir}/profiles/profiles.desc | awk '{print " * " $2, $3}' OFS=' (' ORS=')\n'
return
else
if ! grep -q "^amd64\s*${1}/" ${profile_dir}/profiles/profiles.desc; then
return 1
fi
fi
}
set_vars(){
cl_lxc_ver=$(ls -d /var/db/pkg/sys-apps/calculate-toolkit-* 2>/dev/null) \
&& cl_lxc_ver=${cl_lxc_ver:39} \
|| cl_lxc_ver=
net_domain=$(hostname -f)
path_def=$(lxc-config lxc.lxcpath 2>/dev/null) || (
printf $"To run the script, install the '%s' package.\n" app-containers/lxc >&2
exit 1
)
if ! [[ $prepare_ == 1 || $upgrade_ == 1 ]]; then
name_lxc=$lxc_
name_upgrading=
name_rootfs=
status_lxc=
else
name_lxc="${lxc_}_new"
name_upgrading=$lxc_
name_rootfs="rootfs-${lxc_}"
if [[ $(lxc-info -s $lxc_ 2>&1 | grep RUNNING) ]]; then
status_lxc='RUNNING'
else
status_lxc='STOPPED'
fi
fi
if [ -L $path_def/$lxc_ ]; then
path_work=$(sed 's/\/[^/]*$//' <<< $(realpath $path_def/$lxc_))
if [ -n "$path_" ] && [ $path_ != "$path_work" ]; then
printf $"Wrong --path parameter, container created in '%s'.\n" $path_work >&2
exit 1
fi
elif [ -n "$path_" ] && [ "$path_" != "$path_def" ]; then
path_work=$path_
else
path_work=$path_def
fi
path_lxc=$path_work/$name_lxc
path_cache=$path_work/.cache
path_lxc_prepare=$path_cache/rootfs-$lxc_
if [ $path_def = "$path_work" ]; then
path_change=
if [ ! -d $path_work ]; then
mkdir -p $path_work
fi
else
path_change=$path_work
if [ ! -d $path_work ]; then
printf $"Directory '%s' is not found.\n" $path_work >&2
exit 1
fi
fi
type_fs=$(df -Th $path_work | awk 'NR==2 {print $2}')
if [[ $prepare_ == 1 || $upgrade_ == 1 ]] && [ -f $path_work/$lxc_/config ]; then
# Считаем номер текущего корня обновляемой системы и определим новый
num_cur=$(grep lxc.rootfs.path $path_work/$lxc_/config | sed 's/.*rootfs//')
num_next=$(ls -d $path_work/$lxc_/rootfs* | sed 's/.*rootfs//' | sort -n | tail -n 1)
let "num_next+=1"
else
num_cur=
num_next=
fi
# taiga/amd64/20 -> taiga
lxc_profile=${profile_%%/*}
if [[ $lxc_profile == "" ]]; then
if [[ $prepare_ == 1 || $upgrade_ == 1 ]]; then
lxc_profile=$(file $path_work/$lxc_/rootfs$num_cur/etc/portage/make.profile | \
awk -F '/profiles/' '{ print $2 }' | awk -F '/' '{ print $1 }')
# совместимость со старыми системами
case "$lxc_profile" in
CCS|CDS)
lxc_profile=scratch
;;
CCG)
lxc_profile=games
;;
esac
else
lxc_profile=scratch
fi
else
print_profile $lxc_profile || {
echo $"Wrong --profile parameter, use 'list' to view accepted values." >&2
exit 1
}
fi
true
}
debug_vars(){
local log=/var/log/calculate/cl-lxc.log
cat > /var/log/calculate/cl-lxc.log <<-EOF
cl_lxc_ver = $cl_lxc_ver
net_domain = $net_domain
path_def = $path_def
name_lxc = $name_lxc
name_upgrading = $name_upgrading
name_rootfs = $name_rootfs
status_lxc = $status_lxc
path_work = $path_work
path_lxc = $path_lxc
path_cache = $path_cache
path_lxc_prepare = $path_lxc_prepare
path_change = $path_change
type_fs = $type_fs
num_cur = $num_cur
num_next = $num_next
lxc_profile = $lxc_profile
EOF
}
show(){
echo ---------------------------------------------
echo $@
echo ---------------------------------------------
}
launch_message(){
printf $"Your container is ready. To start it, please run 'lxc-start %s'.\n" $name_lxc
}
check_vars(){
program_name=${0##*/}
if [ "$path_" != '' ] && ! [ -d "$path_" ]; then
printf $"Failed to find directory '%s'.\n" $path_ >&2
exit 1
fi
if [ $create_ == 1 ] && [[ -e $path_lxc || -e $path_def/$name_lxc ]]; then
printf $"Wrong parameter %s, container '%s' exists already!\n" --create $name_lxc >&2
exit 1
fi
if [ $create_ == 0 ] && [ -n "$path_" ]; then
printf $"Parameter %s should be used to create a container.\n" --path >&2
exit 1
fi
if [[ $prepare_ == 1 || $upgrade_ == 1 ]] && [ ! -e $path_work/$name_upgrading ]; then
local param_name='--upgrade'
if [ $prepare_ == 1 ]; then
param_name='--prepare'
fi
printf $"Wrong parameter %s, container '%s' does not exist!\n" $param_name $name_upgrading >&2
exit 1
fi
if [[ $upgrade_ == 1 && $prepare_ == 0 && ! -d $path_lxc_prepare ]] ||
[[ $upgrade_ == 1 && $prepare_ == 0 && $clear_ == 1 ]]
then
printf $"Before update, prepare an image using option %s. This operation may be combined with others.\n" \
--prepare >&2
exit 1
fi
if [ $create_ == 0 ] && [ $prepare_ == 0 ] && [ $upgrade_ == 0 ]; then
if [ ! -e $path_lxc ]; then
printf $"No operation specified. Call %s to create a container.\n" \
"'$program_name -c $name_lxc'" >&2
exit 1
elif [ ! -d $path_lxc_prepare ]; then
printf $"No operation specified. Call %s to prepare an update image for the container.\n" \
"'$program_name -p $name_lxc'" >&2
exit 1
elif [ -d $path_lxc_prepare ]; then
printf $"No operation specified. Call %s to update the container.\n" \
"'$program_name -u $name_lxc'" >&2
exit 1
else
print_help "usage" >&2
exit 1
fi
fi
if [ $path_def != '/var/calculate/lxc' ]; then
printf $"lxc.lxcpath must contain the path to '/var/calculate/lxc'.\n" >&2
exit 1
fi
true
}
create_base(){
ebegin $"Downloading Calculate Linux"
# Создадим подтом, чтобы контейнер не участвовал в бэкапе btrbk
if [ ! -e $path_cache ]; then
if [ $type_fs = 'btrfs' ]; then
btrfs subvolume create $path_cache &>/dev/null
else
mkdir $path_cache
fi
fi
trap "rm -rf $path_def/scratch" SIGINT
lxc-create -n scratch -t download -- --server $mirror_ \
--arch x86_64 --dist scratch --release live \
2>>/var/log/calculate/cl-lxc-error.log >/dev/null || {
eend $? || true
eerror $"Failed to run lxc-create" >&2
exit $?
}
eend
trap - SIGINT
mv $path_def/scratch $path_cache/scratch
true
}
create_lxc(){
echo $"Creating container $name_lxc"
if [ $type_fs = 'btrfs' ]; then
btrfs subvolume create $path_lxc >/dev/null || {
eend $? || true
eerror $"Failed to create subvolume $path_lxc" >&2
exit $?
}
else
mkdir $path_lxc
fi
chmod 700 $path_lxc
local reflink='' && [ $type_fs = 'btrfs' ] && reflink='--reflink'
if [ -d "$path_lxc_prepare" ]; then
ebegin $"Restoring rootfs image from cache"
cp -a $reflink $path_lxc_prepare $path_lxc/rootfs
eend
else
ebegin $"Copying base rootfs"
cp -a $reflink $path_cache/scratch/rootfs $path_lxc/rootfs
eend
fi
if [ -n "$path_change" ]; then
ln -s $path_lxc $path_def/$name_lxc
fi
ebegin $"Preparing base mount paths"
for path_res in usr/portage \
var/cache/edb/binhost \
var/calculate/distfiles \
var/calculate/packages \
var/db/repos/calculate \
var/db/repos/gentoo
do
path_res=${path_lxc}/rootfs/${path_res}
if [ -e $path_res ]; then
rm -rf $path_res
mkdir $path_res
fi
done
eend
local calculate_mount= calculate_dir=
if [ $prepare_ == 0 ]; then
ebegin $"Moving /var/calculate to a separate mount point"
# Очистка и создание пути для монтирования ресурсов из хостовой машины
mv $path_lxc/rootfs/var/calculate $path_lxc
mkdir $path_lxc/rootfs/var/calculate
calculate_mount="lxc.mount.entry = ${path_lxc}/calculate var/calculate none rw,bind 0 0"
calculate_dir="${path_lxc}/calculate"
eend
else
calculate_dir="${path_lxc}/rootfs/var/calculate"
fi
local portage_mount= gentoo_from= gentoo_to=
if [ -d /var/db/repos/gentoo ]; then
gentoo_from='/var/db/repos/gentoo'
else
gentoo_from='/usr/portage'
fi
if [ -d $path_lxc/rootfs/var/db/repos/gentoo ]; then
gentoo_to='var/db/repos/gentoo'
else
gentoo_to='usr/portage'
fi
portage_mount="lxc.mount.entry = ${gentoo_from} ${gentoo_to} none ro,bind 0 0"
if [[ ! -e /var/db/repos/container ]]; then
container_mount="lxc.mount.entry = /var/calculate/repos/container var/db/repos/container none ro,bind 0 0"
if [[ -e /var/calculate/repos/container ]]; then
rm -rf ${path_lxc}/rootfs/var/db/repos/container
else
mv $path_lxc/rootfs/var/db/repos/container /var/calculate/repos
if grep -q github.com $path_lxc/rootfs/etc/portage/repos.conf/zz-calculate.conf; then
local repo_container='https://github.com/calculatelinux/container'
else
local repo_container='https://git.calculate-linux.org/calculate/container-overlay'
fi
cat <<- EOF > /etc/portage/repos.conf/cl-lxc.conf
[container]
priority = 50
sync-uri = $repo_container
location = /var/calculate/repos/container
auto-sync = Yes
sync-type = git
EOF
fi
else
# для совместимости с предыдушими установками
container_mount="lxc.mount.entry = /var/db/repos/container var/db/repos/container none ro,bind 0 0"
rm -rf ${path_lxc}/rootfs/var/db/repos/container
fi
mkdir $path_lxc/rootfs/var/db/repos/container
ebegin $"Running container setup"
local net_conf=
if [ $prepare_ == 1 ] || [ ! -L /sys/class/net/br0 ]; then
net_conf=none
network_conf="lxc.net.0.type = none"
cp /etc/resolv.conf $path_lxc/rootfs/etc
echo -e "\nrc_provide=\"net\"" >> $path_lxc/rootfs/etc/conf.d/net
else
net_conf=veth
local random_mac=$(printf '06:%02X:%02X:%02X:%02X:%02X\n' \
$((RANDOM%256)) $((RANDOM%256)) $((RANDOM%256)) $((RANDOM%256)) $((RANDOM%256)))
local veth_pair="lxc.net.0.veth.pair = lxc-${name_lxc::11}"
if grep -q "$veth_pair" -r ${path_def}/*/config &>/dev/null; then
# исключим настройку сетевого имени, если такое уже используется
veth_pair="#${veth_pair}"
fi
network_conf=$(cat <<- EOF
lxc.net.0.type = veth
lxc.net.0.flags = up
lxc.net.0.name = eth0
lxc.net.0.link = br0
lxc.net.0.hwaddr = ${random_mac}
${veth_pair}
EOF
)
fi
cat <<- EOF >> ${path_lxc}/config
#------------------------------------------------------------------------------
# Modified cl-lxc-${cl_lxc_ver}
# For additional config options, please look at lxc.container.conf(5)
#------------------------------------------------------------------------------
# Distribution configuration
lxc.include = /usr/share/lxc/config/common.conf
lxc.arch = x86_64
lxc.mount.entry = none dev/shm tmpfs rw,nosuid,nodev,create=dir
# Container specific configuration
lxc.rootfs.path = dir:/var/calculate/lxc/${name_lxc}/rootfs
lxc.uts.name = ${name_lxc}
# Network configuration
${network_conf}
# Mount points
${calculate_mount}
${container_mount}
lxc.mount.entry = /var/db/repos/calculate var/db/repos/calculate none ro,bind 0 0
${portage_mount}
lxc.mount.entry = /var/cache/edb/binhost var/cache/edb/binhost none ro,bind 0 0
lxc.mount.entry = /var/calculate/packages var/calculate/packages none rw,bind 0 0
lxc.mount.entry = /var/calculate/distfiles var/calculate/distfiles none rw,bind 0 0
EOF
eend
ebegin $"Configuring utility variables"
cat <<- EOF > ${calculate_dir}/calculate.env
[update]
cl_update_rep_name =
cl_update_rep_url =
cl_update_eixupdate_force = force
cl_update_force_fix_set = on
EOF
eend
ebegin $"Preparing first boot setup script"
cat <<- EOF > $path_lxc/rootfs/etc/local.d/firststart.start
rm /etc/local.d/firststart.start
rm /etc/calculate/calculate.env
EOF
chmod 755 $path_lxc/rootfs/etc/local.d/firststart.start
cat <<- EOF > $path_lxc/rootfs/etc/calculate/calculate.env
# Parameters for firststart.start
[install]
os_install_net_hostname = ${name_lxc}
os_install_net_domain = ${net_domain}
os_install_locale_lang = ${LANG/.UTF-8/}
os_install_clock_timezone = $(cat /etc/timezone)
EOF
eend
ebegin $"Creating templates"
mkdir -p ${calculate_dir}/templates/default
cat <<- EOF > ${calculate_dir}/templates/default/.calculate_directory
# Calculate env=install ac_install_live==on append=skip
EOF
if [ $net_conf == veth ]; then
cat <<- EOF > ${calculate_dir}/templates/default/runlevel.eth0
# Calculate mergepkg(sys-apps/openrc)!= path=/etc/runlevels/default name=net.eth0 protected link=/etc/init.d/net.lo symbolic
EOF
fi
cat <<- EOF > ${calculate_dir}/templates/default/portage.binhost
# Calculate mergepkg(sys-apps/portage)!= path=/etc/portage/make.conf name=binhost protected comment=#
$(emerge --info 2>/dev/null | grep PORTAGE_BINHOST)
EOF
eend
if [[ -z "$name_upgrading" && $lxc_profile == 'scratch' ]]; then
launch_message
fi
}
start_container(){
ebegin $"Starting container"
lxc-start $name_lxc
# ожидание первоначальной настройки контейнера
while ! lxc-attach $name_lxc -- ps ax | grep 'init \[3\]' > /dev/null; do
sleep 0.1
done
eend
}
change_profile(){
echo
echo $"Change the profile to $lxc_profile"
start_container
cl-update -s
lxc-attach $name_lxc -- cl-update-profile -f $lxc_profile
echo
echo $"Install packages from profile $lxc_profile"
einfo $"Launching package update"
lxc-attach $name_lxc -- cl-update -f
eend
launch_message
}
update_prepare(){
#printf $"Package update for container %s\n" $name_lxc
ebegin $"Moving installed packages, flags and masks from main container"
for migrate_file in /etc/portage/package.accept_keywords/custom \
/etc/portage/package.mask/custom \
/etc/portage/package.unmask/custom \
/etc/portage/package.use/custom \
/etc/portage/sets/custom
do
cp ${path_work}/${name_upgrading}/rootfs${num_cur}${migrate_file} \
${path_lxc}/rootfs${migrate_file} &>/dev/null || true
done
eend
ebegin $"Creating mount points"
for mount_point in $(grep '^lxc.mount.entry' $path_work/$name_upgrading/config | awk {'print $4'}); do
if [ ! -e "$path_lxc/rootfs/$mount_point" ]; then
mkdir -p "$path_lxc/rootfs/$mount_point"
fi
done
eend
ebegin $"Preparing first boot setup script"
cat <<- EOF > $path_lxc/rootfs/etc/local.d/firststart.start
rm /etc/local.d/firststart.start
rm /etc/calculate/calculate.env
EOF
chmod 755 $path_lxc/rootfs/etc/local.d/firststart.start
# если обновляемый контейнер ни разу не запускался, возьем временный конфиг
if [[ -e ${path_work}/${name_upgrading}/rootfs${num_cur}/etc/calculate/calculate.env ]]; then
cp ${path_work}/${name_upgrading}/rootfs${num_cur}/etc/calculate/calculate.env \
$path_lxc/rootfs/etc/calculate
else
local lxc_host=$(grep localhost ${path_work}/${name_upgrading}/rootfs${num_cur}/etc/hosts | awk '{print $2}')
local os_install_net_hostname=${lxc_host%%.*}
local os_install_net_domain=${lxc_host#*.}
local os_install_locale_lang=$(grep 'LANG=' ${path_work}/${name_upgrading}/rootfs${num_cur}/etc/env.d/02locale)
local os_install_clock_timezone=$(cat ${path_work}/${name_upgrading}/rootfs${num_cur}/etc/timezone)
cat <<- EOF > $path_lxc/rootfs/etc/calculate/calculate.env
# Parameters for firststart.start
[install]
os_install_net_hostname = ${os_install_net_hostname}
os_install_net_domain = ${os_install_net_domain}
os_install_locale_lang = ${os_install_locale_lang:6:5}
os_install_clock_timezone = ${os_install_clock_timezone}
EOF
fi
eend
start_container
cl-update -s
if [[ $(file $path_lxc/rootfs/etc/portage/make.profile | \
awk -F '/profiles/' '{ print $2 }' | awk -F '/' '{ print $1 }') != $lxc_profile ]]
then
echo
echo $"Change profile to $lxc_profile"
lxc-attach $name_lxc -- cl-update-profile -f $lxc_profile
fi
echo
echo $"Launching package update"
lxc-attach $name_lxc -- cl-update -f
rm -rf "$path_lxc/rootfs/var/calculate/{tmp/*,templates/*}"
find $path_lxc/rootfs/etc/init.d -type l -name net.* -exec unlink {} \;
cd $path_lxc/rootfs/etc/runlevels/boot
ln -s /etc/init.d/calculate .
cd - &>/dev/null
ebegin $"Stopping container"
lxc-stop $name_lxc
eend
ebegin $"Saving image for update"
if [ -d $path_lxc_prepare ]; then
rm -r $path_lxc_prepare
fi
mv $path_lxc/rootfs $path_lxc_prepare
eend
ebegin $"Removing temporary container directory $name_lxc"
if [ $type_fs = 'btrfs' ]; then
btrfs subvolume delete $path_lxc &>/dev/null
if [ -n "$path_change" ]; then
rm $path_def/$name_lxc # удалим символическую ссылку
fi
else
rm -rf $path_lxc
fi
eend
[ $diff_ == 1 ] && diff_pkg
einfo $"Image for update ready. Now you can run '$program_name -u $name_upgrading' to update."
return
}
upgrade_lxc(){
echo $"Preparing to start new root"
ebegin $"Moving image to $name_upgrading/rootfs$num_next"
local reflink=
if [ $type_fs = 'btrfs' ]; then
reflink='--reflink'
fi
cp -a $reflink $path_lxc_prepare $path_work/$name_upgrading/rootfs$num_next
rm -rf $path_work/$name_upgrading/rootfs$num_next/var/calculate/*
eend
ebegin $"Copying network settings from main container"
cp $path_work/$name_upgrading/rootfs$num_cur/etc/conf.d/net \
$path_work/$name_upgrading/rootfs$num_next/etc/conf.d/net
eend
ebegin $"Copying hash of root password"
root=$(grep '^root:' $path_work/$name_upgrading/rootfs$num_cur/etc/shadow | sed 's/:/\\:/g')
sed -i "s:^root\:.*$:$root:" $path_work/$name_upgrading/rootfs$num_next/etc/shadow
eend
ebegin $"Copying ssh keys"
cp $path_work/$name_upgrading/rootfs$num_cur/etc/ssh/ssh_*key* \
$path_work/$name_upgrading/rootfs$num_next/etc/ssh 2>/dev/null || true
eend
ebegin $"Preparing first boot setup script"
cat <<- EOF > $path_work/$name_upgrading/rootfs$num_next/etc/local.d/firststart.start
cl-core --method setup_system --no-progress --usenew-conf --network on
openrc
rm /etc/local.d/firststart.start
EOF
chmod 755 $path_work/$name_upgrading/rootfs$num_next/etc/local.d/firststart.start
eend
ebegin $"New root setup"
sed -i "s#$path_def/$name_upgrading/rootfs[0-9]*#$path_def/$name_upgrading/rootfs$num_next#" \
$path_work/$name_upgrading/config
eend
if [ ! -z $(lxc-ls --running --filter "^$name_upgrading$") ]; then
einfo $"Stopping container $name_upgrading"
lxc-stop $name_upgrading
eend
fi
if [ "$status_lxc" = 'RUNNING' ]; then
einfo $"Launching container $name_upgrading"
lxc-start $name_upgrading
eend
fi
[ $diff_ == 1 ] && diff_pkg # Отобразим разницу в пакетах
while ! (test -a $path_work/$name_upgrading/rootfs$num_next/etc/resolv.conf); do
sleep 0.1
done
einfo $(lxc-info -i $name_upgrading)
printf $"Container updated."
if [ "$status_lxc" = 'STOPPED' ]; then
printf ' '
printf $"To start it, please run 'lxc-start %s'.\n" $name_upgrading
else
echo
fi
true
}
diff_pkg(){
# Считаем версии сборок
cur_ver=$(grep os_linux_build $path_work/$name_upgrading/rootfs$num_cur/var/lib/calculate/calculate.env | sed 's/.*os_linux_build\s*=\s*//')
next_ver=$(grep os_linux_build $path_lxc_prepare/var/lib/calculate/calculate.env | sed 's/.*os_linux_build\s*=\s*//')
printf $"Diffs between %s and %s versions:\n" $cur_ver $next_ver
find $path_work/$name_upgrading/rootfs$num_cur/var/db/pkg/ -type d | sed 's/.*db\/pkg\///' | grep \/ | sort > $lock/cur
find $path_lxc_prepare/var/db/pkg/ -type d | sed 's/.*db\/pkg\///' | grep \/ | sort > $lock/new
cp $lock/new $lock/work
while IFS= read -r pkg; do
if grep -q $pkg$ $lock/cur; then
sed -i "/$pkg/d" $lock/new
sed -i "/$pkg/d" $lock/cur
fi
done <<< $(awk -F / '{print $2}' $lock/work)
if [ ! -s $lock/new ] && [ ! -s $lock/cur ]; then
einfo $"No difference detected"
else
diff $lock/new $lock/cur || true
echo
fi
true
}
clear_cache(){
ebegin $"Clearing cache"
rm -rf /var/cache/lxc/download/*
if [[ -e /var/calculate/lxc/.cache ]]; then
if [[ $(df -Th /var/calculate/lxc | awk 'NR==2 {print $2}') == btrfs ]]; then
btrfs subvolume delete /var/calculate/lxc/.cache > /dev/null
else
rm -rf /var/calculate/lxc/.cache
fi
fi
for i in /var/calculate/lxc/*; do
if [[ $i == /var/calulate/lxc/* ]]; then
break
fi
# разыменуем символические ссылки чтобы почистить кэши на других разделах
if [[ -L $i ]]; then
cache_dir=$(realpath $i)
cache_dir=${cache_dir%/*}
if [[ -e $cache_dir/.cache ]]; then
if [[ $(df -Th $cache_dir | awk 'NR==2 {print $2}') == btrfs ]]; then
btrfs subvolume delete $cache_dir/.cache > /dev/null
else
rm -rf $cache_dir/.cache
fi
fi
fi
done
eend
}
# Обработка параметров вызова скрипта
save=$IFS
IFS=$' =\n'
get_args $@
IFS=$save
# Проверка одновременного запуска
check_simultaneous_run
# Установка значений переменных
set_vars
# Логирование значений переменных
debug_vars
# Проверка параметров запуска
check_vars
# Чистка кэша
# пустой файл partial когда lxc-create был прерван
if [[ $clear_ == 1 ]]; then
clear_cache
fi
# Создание базового контейнера
if [[ $create_ == 1 || $prepare_ == 1 ]] && [ ! -d "$path_cache/scratch" ]; then
create_base
fi
# Создание контейнера
if [[ $create_ == 1 || $prepare_ == 1 ]]; then
create_lxc
# если задан профиль при создании контейнера:
# запустим контейнер, обновим оверлеи (container), выберем профиль и обновим пакеты
if [[ $prepare_ == 0 && $lxc_profile != 'scratch' ]]; then
change_profile
fi
fi
# Обновление пакетов контейнера
if [ $prepare_ == 1 ]; then
update_prepare
fi
# Обновление контейнера
if [ $upgrade_ == 1 ]; then
upgrade_lxc
fi
true