diff --git a/Makefile b/Makefile index ce4ebc4..6334ab8 100644 --- a/Makefile +++ b/Makefile @@ -18,4 +18,4 @@ install: all subdirs @${INSTALL} -D -m 0755 cl-check-templates ${DESTDIR}/usr/sbin/cl-check-templates @${INSTALL} -D -m 0755 cl-system-dump ${DESTDIR}/usr/sbin/cl-system-dump @${INSTALL} -D -m 0755 cl-wikicolor ${DESTDIR}/usr/bin/cl-wikicolor - + @${INSTALL} -D -m 0755 cl-lxc ${DESTDIR}/usr/sbin/cl-lxc diff --git a/cl-lxc b/cl-lxc new file mode 100755 index 0000000..023f2bc --- /dev/null +++ b/cl-lxc @@ -0,0 +1,726 @@ +#!/bin/sh +# 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: + -D, --distro select distribution 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 + } + distro_= + create_=0 + path_= + prepare_=0 + upgrade_=0 + diff_=0 + clear_=0 + mirror_=mirror.calculate-linux.org + while (( $# > 0 )) + do + case "$1" in + -D|--distro) + check_val $@ + distro_=$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 [ "$distro_" == 'list' ] + then + print_distro + exit 0 + elif (( $# == 1 )) + then + lxc_=$1 + if [[ $lxc_ =~ [^A-Za-z0-9_\.] ]] + then + echo $"Container name contains wrong characters." >&2 + exit 1 + fi + else + print_help "usage" + exit 1 + fi + + true +} + +print_distro(){ + if (( $# == 0 )) + then + echo $"Distributive: + [CCS] Calculate Container Scratch (by default) + [CCG] Calculate Container Games" + return + fi + + case "$1" in + CCS) + echo "Calculate Container Scratch" + ;; + CCG) + echo "Calculate Container Games" + ;; + esac +} + +set_vars(){ + lxc_release=22.0.1 + net_domain=$(hostname -f) + path_def=$(lxc-config lxc.lxcpath) + + 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= + else + path_change=$path_work + 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 + + case "$distro_" in + CCS|ccs) + lxc_distro=CCS + ;; + CCG|ccg) + lxc_distro=CCG + ;; + '') + if [ $prepare_ == 1 ] || [ $upgrade_ == 1 ] + then + lxc_distro=$(file $path_work/$lxc_/rootfs$num_cur/etc/portage/make.profile | \ + awk -F '/profiles/' '{ print $2 }' | awk -F '/' '{ print $1 }') + else + lxc_distro=CCS + fi + ;; + *) + echo $"Wrong --distro parameter, use 'list' to view accepted values." >&2 + exit 1 + ;; + esac + + true +} + +debug_vars(){ + local log=/var/log/calculate/cl-lxc.log + cat > /var/log/calculate/cl-lxc.log <&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" $(print_distro $lxc_distro) + + # Создадим подтом, чтобы контейнер не участвовал в бэкапе btrbk + if [ ! -e $path_cache ] + then + if [ $type_fs = 'btrfs' ] + then + btrfs subvolume create $path_cache &>/dev/null + else + mkdir $path_cache + fi + fi + + # Удалим кэш LXC + if [ $clear_ == 1 ] + then + rm -rf /var/cache/lxc/download/$lxc_distro + fi + + lxc-create -n $lxc_distro -t download -- --server $mirror_ \ + --no-validate --arch x86_64 --dist $lxc_distro --release $lxc_release &>/dev/null || { + eend $? || true + eerror $"Failed to run lxc-create" >&2 + rm -rf $path_cache + exit $? + } + eend + mv $path_def/$lxc_distro $path_cache/$lxc_distro + 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/$lxc_distro/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" + rm -rf $path_lxc/rootfs/usr/portage; mkdir $path_lxc/rootfs/usr/portage + rm -rf $path_lxc/rootfs/var/db/repos/calculate; mkdir $path_lxc/rootfs/var/db/repos/calculate + rm -rf $path_lxc/rootfs/var/cache/edb/binhost; mkdir $path_lxc/rootfs/var/cache/edb/binhost + rm -rf $path_lxc/rootfs/var/calculate/packages; mkdir $path_lxc/rootfs/var/calculate/packages + rm -rf $path_lxc/rootfs/var/calculate/distfiles;mkdir $path_lxc/rootfs/var/calculate/distfiles + eend + + 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_mount="" + calculate_dir="${path_lxc}/rootfs/var/calculate" + fi + + local container_mount="" + if ! [ -d /var/db/repos/container ] + then + ewarn $"Skipping mounting Container overlay" + container_mount="#lxc.mount.entry = /var/db/repos/container var/db/repos/container none ro,bind 0 0 +" + else + rm -rf $path_lxc/rootfs/var/db/repos/container; mkdir $path_lxc/rootfs/var/db/repos/container + container_mount="lxc.mount.entry = /var/db/repos/container var/db/repos/container none ro,bind 0 0 +" + fi + + 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 + else + net_conf=veth + local random_mac=$(echo -n '02:'; hexdump -n5 -e '/1 ":%02X"' /dev/random | sed s/^://g) + network_conf="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} +lxc.net.0.veth.pair = lxc-${name_lxc}" + fi + + # перенесем базовый config удалив настройку сети + cp $path_cache/$lxc_distro/config ${path_lxc}/config + sed -i '/lxc.net.0.type = empty/d' ${path_lxc}/config + sed -i "s/${lxc_distro}/${name_lxc}/g" ${path_lxc}/config + + cat << EOL >> ${path_lxc}/config +${network_conf} + +${calculate_mount}lxc.mount.entry = /usr/portage usr/portage none ro,bind 0 0 +lxc.mount.entry = /var/db/repos/calculate var/db/repos/calculate none ro,bind 0 0 +${container_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 +EOL + eend + + ebegin $"Configuring utility variables" + cat << EOL > ${calculate_dir}/calculate.env +[install] +os_install_net_hostname = ${name_lxc} +os_install_net_domain = ${net_domain} +os_install_locale_lang = ${LANG/.utf8/} +os_install_clock_timezone = $(cat /etc/timezone) + +[update] +cl_update_rep_name = +cl_update_rep_url = +cl_update_rep_sync = +cl_update_eixupdate_force = force +cl_update_force_fix_set = on +EOL + eend + + ebegin $"Creating templates" + mkdir -p ${calculate_dir}/templates/default + cat << EOL > ${calculate_dir}/templates/default/.calculate_directory +# Calculate env=install ac_install_live==on append=skip +EOL + if [ $net_conf == veth ] + then + cat << EOL > ${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 +EOL + fi + cat << EOL > ${calculate_dir}/templates/default/portage.binhost +# Calculate mergepkg(sys-apps/portage)!= path=/etc/portage/make.conf name=binhost protected comment=# +$(emerge --info | grep PORTAGE_BINHOST) +EOL + eend + [ -z "$name_upgrading" ] && printf $"Your container is ready. To start it, please run 'lxc-start %s'.\n" $name_lxc + true +} + +update_prepare() { + printf $"Package update for container %s\n" $name_lxc + + ebegin $"Moving installed packages, flags and masks from main container" + cp $path_work/$name_upgrading/rootfs$num_cur/etc/portage/sets/custom $path_lxc/rootfs/etc/portage/sets/custom &>/dev/null || true + cp $path_work/$name_upgrading/rootfs$num_cur/etc/portage/package.accept_keywords/custom \ + $path_lxc/rootfs/etc/portage/package.accept_keywords/custom &>/dev/null || true + cp $path_work/$name_upgrading/rootfs$num_cur/etc/portage/package.use/custom \ + $path_lxc/rootfs/etc/portage/package.use/custom &>/dev/null || true + cp $path_work/$name_upgrading/rootfs$num_cur/etc/portage/package.mask/custom \ + $path_lxc/rootfs/etc/portage/package.mask/custom &>/dev/null || true + cp $path_work/$name_upgrading/rootfs$num_cur/etc/portage/package.unmask/custom \ + $path_lxc/rootfs/etc/portage/package.unmask/custom &>/dev/null || true + eend + + ebegin $"Creating mount points" + for mount_point in $(grep lxc.mount.entry $path_work/$name_upgrading/config | awk {'print $4'}) + do + mkdir -p "$path_lxc/rootfs/$mount_point" + done + eend + + 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 + + cl-update -s + einfo $"Launching package update" + lxc-attach $name_lxc -- cl-update -f + + 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 + 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 $"Preparing first boot setup script" +cat << EOL > $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 +EOL + 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 CSS %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 +} + + +# Проверка одновременного запуска +check_simultaneous_run + +# Обработка параметров вызова скрипта +save=$IFS +IFS=$' =\n' +get_args $@ +IFS=$save + +# Установка значений переменных +set_vars + +# Логирование значений переменных +debug_vars + +# Проверка параметров запуска +check_vars + +# Чистка кэша базового контейнера +# пустой файл partial когда lxc-create был прерван +if [[ $clear_ == 1 && -d "$path_cache/$lxc_distro" ]] +then + ebegin $"Clearing Calculate Container cache" + rm -rf "$path_cache/$lxc_distro" + eend +fi + +# Создание базового контейнера +if [[ $create_ == 1 || $prepare_ == 1 || $clear_ == 1 ]] && + [ ! -d "$path_cache/$lxc_distro" ] +then + create_base +fi + +# Создание контейнера +if [[ $create_ == 1 || $prepare_ == 1 ]] +then + if [ -d "$path_lxc_prepare" ] + then + if [ $clear_ == 1 ] + then + ebegin $"Clearing container cache" + rm -r "$path_lxc_prepare" + eend + fi + fi + create_lxc +fi + +# Обновление пакетов контейнера +if [ $prepare_ == 1 ] +then + update_prepare +fi + +# Обновление контейнера +if [ $upgrade_ == 1 ] +then + upgrade_lxc +fi + +true diff --git a/po/cl-lxc.po b/po/cl-lxc.po new file mode 100644 index 0000000..ec7d339 --- /dev/null +++ b/po/cl-lxc.po @@ -0,0 +1,263 @@ +msgid "" +msgstr "" +"Project-Id-Version: cl-lxc\n" +"Report-Msgid-Bugs-To: support@calculate.ru\n" +"Last-Translator: Mir Calculate , Elena Gavrilova \n" +"Language-Team: Russian \n" +"Language: ru\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" + +#: cl-lxc:35 +msgid "" +"$usage\n" +"\n" +"${0##*/} installation, configuration and update of an LXC container with Calculate Linux on board\n" +"\n" +"Parameters:\n" +" -D, --distro\t\tselect distribution flavour ('list' to view all that applies)\n" +" -c, --create\t\tcreate new container\n" +" --path\t\tpath to container\n" +" -p, --prepare\t\tget rootfs ready for update\n" +" -u, --upgrade\t\tupdate container rootfs\n" +" --diff\t\tdiff two rootfs packages\n" +" -R, --clear_cache\tclear cache\n" +" -m, --mirror\t\tmirror address\n" +" -h, --help\t\tshow this help page\n" +msgstr "" +"$usage\n" +"\n" +"${0##*/} установка, настройка и обновление LXC контейнера с Calculate Linux\n" +"\n" +"Параметры :\n" +" -D, --distro\t\tвыбор дистрибутива ('list' для отображения возможных значений)\n" +" -c, --create\t\tсоздать новый контейнер\n" +" --path\t\tпуть к контейнеру\n" +" -p, --prepare\t\tподготовить rootfs для обновления\n" +" -u, --upgrade\t\tобновить rootfs контейнера\n" +" --diff\t\tотобразить разницу в пакетах двух rootfs\n" +" -R, --clear_cache\tочистить кэш\n" +" -m, --mirror\t\tадрес зеркала\n" +" -h, --help\t\tпоказать эту справку\n" + +#: cl-lxc:305 +msgid "Before update, prepare an image using option %s. This operation may be combined with others.\\n" +msgstr "Перед обновлением, подготовьте образ используя опцию %s. Действие можно совместить.\\n" + +#: cl-lxc:687 +msgid "Clearing Calculate Container cache" +msgstr "Очистим кэш Calculate Container" + +#: cl-lxc:706 +msgid "Clearing container cache" +msgstr "Очистка кэша контейнера" + +#: cl-lxc:470 +msgid "Configuring utility variables" +msgstr "Настройка переменных утилит" + +#: cl-lxc:133 +msgid "Container name contains wrong characters." +msgstr "Недопустимые символы в имени контейнера." + +#: cl-lxc:625 +msgid "Container updated." +msgstr "Контейнер обновлён." + +#: cl-lxc:392 +msgid "Copying base rootfs" +msgstr "Копирование базового rootfs" + +#: cl-lxc:586 +msgid "Copying network settings from main container" +msgstr "Перенос сетевых настроек с рабочего контейнера" + +#: cl-lxc:372 +#, sh-format +msgid "Creating container $name_lxc" +msgstr "Создание контейнера $name_lxc" + +#: cl-lxc:522 +msgid "Creating mount points" +msgstr "Создание путей монтирования" + +#: cl-lxc:487 +msgid "Creating templates" +msgstr "Создание шаблонов" + +#: cl-lxc:641 +msgid "Diffs between CSS %s and %s versions:\\n" +msgstr "Отличия между версиями CSS %s и %s:\\n" + +#: cl-lxc:147 +msgid "" +"Distributive:\n" +" [CCS]\t\tCalculate Container Scratch (by default)\n" +" [CCG]\t\tCalculate Container Games" +msgstr "" +"Дистрибутив:\n" +" [CCS]\t\tCalculate Container Scratch (по умолчанию)\n" +" [CCG]\t\tCalculate Container Games" + +#: cl-lxc:340 +msgid "Downloading" +msgstr "Загрузка" + +#: cl-lxc:377 +#, sh-format +msgid "Failed to create subvolume $path_lxc" +msgstr "Ошибка создания подтома $path_lxc" + +#: cl-lxc:278 +msgid "Failed to find directory '%s'.\\n" +msgstr "Не найдена директория '%s'.\\n" + +#: cl-lxc:362 +msgid "Failed to run lxc-create" +msgstr "Ошибка выполнения lxc-create" + +#: cl-lxc:569 +#, sh-format +msgid "Image for update ready. Now you can run '$program_name -u $name_upgrading' to update." +msgstr "Образ с обновлением готов! Выполните '$program_name -u $name_upgrading' для обновления контейнера." + +#: cl-lxc:118 +msgid "Invalid option '%s'.\\n" +msgstr "Недопустимый параметр '%s'.\\n" + +#: cl-lxc:613 +#, sh-format +msgid "Launching container $name_upgrading" +msgstr "Запуск контейнера $name_upgrading" + +#: cl-lxc:539 +msgid "Launching package update" +msgstr "Запуск обновления пакетов" + +#: cl-lxc:412 +msgid "Moving /var/calculate to a separate mount point" +msgstr "Перенос /var/calculate в отдельную точку монтирования" + +#: cl-lxc:577 +#, sh-format +msgid "Moving image to $name_upgrading/rootfs$num_next" +msgstr "Перенос подготовленного образа в $name_upgrading/rootfs$num_next" + +#: cl-lxc:510 +msgid "Moving installed packages, flags and masks from main container" +msgstr "Перенос установленных пакетов, флагов и масок с рабочего контейнера" + +#: cl-lxc:600 +msgid "New root setup" +msgstr "Настройка пути к новому корню" + +#: cl-lxc:656 +msgid "No difference detected" +msgstr "Нет отличий" + +#: cl-lxc:313 +msgid "No operation specified. Call %s to create a container.\\n" +msgstr "Не задано действие! Для создания контейнера используйте вызов %s.\\n" + +#: cl-lxc:318 +msgid "No operation specified. Call %s to prepare an update image for the container.\\n" +msgstr "Не задано действие! Для подготовки образа обновления используйте вызов %s.\\n" + +#: cl-lxc:323 +msgid "No operation specified. Call %s to update the container.\\n" +msgstr "Не задано действие! Для обновления контейнера используйте вызов %s.\\n" + +#: cl-lxc:508 +msgid "Package update for container %s\\n" +msgstr "Обновление пакетов контейнера %s\\n" + +#: cl-lxc:288 +msgid "Parameter %s should be used to create a container.\\n" +msgstr "Параметр %s следует использовать при создании контейнера.\\n" + +#: cl-lxc:60 +msgid "Parameter '$1' contains no value!" +msgstr "Параметр '$1' не содержит значения!" + +#: cl-lxc:402 +msgid "Preparing base mount paths" +msgstr "Подготовка базовых путей монтирования" + +#: cl-lxc:591 +msgid "Preparing first boot setup script" +msgstr "Подготовка скрипта настройки первой загрузки" + +#: cl-lxc:575 +msgid "Preparing to start new root" +msgstr "Подготовка к запуску нового корня контейнера" + +#: cl-lxc:554 +#, sh-format +msgid "Removing temporary container directory $name_lxc" +msgstr "Удаление директории временного контейнера $name_lxc" + +#: cl-lxc:388 +msgid "Restoring rootfs image from cache" +msgstr "Восстановление подготовленного образа rootfs из кэша" + +#: cl-lxc:436 +msgid "Running container setup" +msgstr "Создание настроек контейнера" + +#: cl-lxc:32 +msgid "SYNOPSIS: %s [PARAMETERS?] [name]" +msgstr "СИНТАКСИС: cl-lxc [ПАРАМЕТРЫ?] [имя]" + +#: cl-lxc:546 +msgid "Saving image for update" +msgstr "Сохранение образа для обновления" + +#: cl-lxc:24 +msgid "Script launched!" +msgstr "Скрипт запущен!" + +#: cl-lxc:427 +msgid "Skipping mounting Container overlay" +msgstr "Пропуск монтирования оверлея Container" + +#: cl-lxc:529 +msgid "Starting container" +msgstr "Запуск контейнера" + +#: cl-lxc:542 +msgid "Stopping container" +msgstr "Остановка контейнера" + +#: cl-lxc:606 +#, sh-format +msgid "Stopping container $name_upgrading" +msgstr "Остановка контейнера $name_upgrading" + +#: cl-lxc:629 +msgid "To start it, please run 'lxc-start %s'.\\n" +msgstr "Для запуска выполните 'lxc-start %s'.\\n" + +#: cl-lxc:243 +msgid "Wrong --distro parameter, use 'list' to view accepted values." +msgstr "Ошибка параметра --distro, используйте 'list' для отображения допустимых значений." + +#: cl-lxc:191 +msgid "Wrong --path parameter, container created in '%s'.\\n" +msgstr "Ошибка параметра --path, контейнер создан в директории '%s'.\\n" + +#: cl-lxc:299 +msgid "Wrong parameter %s, container '%s' does not exist!\\n" +msgstr "Ошибка параметра %s, контейнера с именем '%s' нет!\\n" + +#: cl-lxc:283 +msgid "Wrong parameter %s, container '%s' exists already!\\n" +msgstr "Ошибка параметра %s, контейнер с именем '%s' уже есть!\\n" + +#: cl-lxc:503 +msgid "Your container is ready. To start it, please run 'lxc-start %s'.\\n" +msgstr "Контейнер готов! Для запуска выполните 'lxc-start %s'.\\n" + +#: cl-lxc:333 +msgid "lxc.lxcpath must contain the path to '/var/calculate/lxc'.\\n" +msgstr "Переменная lxc.lxcpath должна содержать путь '/var/calculate/lxc'.\\n"