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

1 year ago
#!/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)
1 year ago
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
1 year ago
mkdir -p $path_work
fi
else
path_change=$path_work
if [ ! -d $path_work ]; then
1 year ago
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
1 year ago
cat > /var/log/calculate/cl-lxc.log <<-EOF
cl_lxc_ver = $cl_lxc_ver
1 year ago
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
1 year ago
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"
1 year ago
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
1 year ago
rm -rf $path_res
mkdir $path_res
fi
done
eend
1 year ago
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
1 year ago
local portage_mount= gentoo_from= gentoo_to=
if [ -d /var/db/repos/gentoo ]; then
1 year ago
gentoo_from='/var/db/repos/gentoo'
else
1 year ago
gentoo_from='/usr/portage'
fi
if [ -d $path_lxc/rootfs/var/db/repos/gentoo ]; then
1 year ago
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
1 year ago
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
1 year ago
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
1 year ago
local random_mac=$(printf '06:%02X:%02X:%02X:%02X:%02X\n' \
$((RANDOM%256)) $((RANDOM%256)) $((RANDOM%256)) $((RANDOM%256)) $((RANDOM%256)))
1 year ago
local veth_pair="lxc.net.0.veth.pair = lxc-${name_lxc::11}"
if grep -q "$veth_pair" -r ${path_def}/*/config &>/dev/null; then
1 year ago
# исключим настройку сетевого имени, если такое уже используется
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
1 year ago
${network_conf}
# Mount points
${calculate_mount}
${container_mount}
1 year ago
lxc.mount.entry = /var/db/repos/calculate var/db/repos/calculate none ro,bind 0 0
${portage_mount}
1 year ago
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"
1 year ago
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
1 year ago
cat <<- EOF > ${calculate_dir}/templates/default/.calculate_directory
# Calculate env=install ac_install_live==on append=skip
EOF
if [ $net_conf == veth ]; then
1 year ago
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
1 year ago
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"
1 year ago
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
1 year ago
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
1 year ago
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
1 year ago
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
1 year ago
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
1 year ago
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
1 year ago
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
1 year ago
eend
ebegin $"Preparing first boot setup script"
1 year ago
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
}
1 year ago
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
1 year ago
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
1 year ago
break
fi
# разыменуем символические ссылки чтобы почистить кэши на других разделах
if [[ -L $i ]]; then
1 year ago
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
1 year ago
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
1 year ago
# Чистка кэша
# пустой файл partial когда lxc-create был прерван
if [[ $clear_ == 1 ]]; then
1 year ago
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