#!/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