Compare commits

..

2 Commits

6
.gitignore vendored

@ -1,6 +0,0 @@
revert_changes_to_vmachine
push_to_vmachine*
.vscode
*.pyc
*.pyo
*.bak

@ -21,8 +21,6 @@ TTYNUM=${2:-7}
DISPLAYNUM=${3:-\:0}
MAINLOOP=1
XDMCMD=/usr/share/calculate/xdm/xdm
# write pid for init.d/xdm (detect X for this xautologin)
echo $BASHPID >/var/run/bash.pid
@ -96,10 +94,7 @@ do
XPID=$!
if waitX ${DISPLAYNUM}
then
if [[ -e ${XDMCMD} ]]
then
env USER=${XUSER} ${XDMCMD} --login || break
fi
env USER=${XUSER} /usr/share/calculate/xdm/xdm --login || break
# write pam enviroment for pam_ck_connector
cat >/home/${XUSER}/.pam_environment <<EOF
CKCON_DISPLAY_DEVICE=
@ -137,10 +132,7 @@ source /usr/bin/startx' &
then
sleep $WAITRELOGIN
fi
if [[ -e ${XDMCMD} ]]
then
env USER=${XUSER} ${XDMCMD} --logout
fi
env USER=${XUSER} /usr/share/calculate/xdm/xdm --logout
fi
[[ -n $XPID ]] && kill $XPID
wait $XPID

@ -17,20 +17,15 @@ CL_VIDEO_INSTALL=/usr/libexec/calculate/cl-video-install
depend() {
need localmount root fsck modules
before keymaps consolefont dbus display-manager local
before keymaps consolefont dbus xdm
use swap hostname
keyword -timeout -docker -systemd-nspawn -vserver
keyword -timeout
}
check_install_ability()
{
local pkg=$1
if [[ -d "/var/db/repos/gentoo" ]]
then
FEATURES="-getbinpkg" FETCHCOMMAND=false DISTDIR=/var/calculate/distfiles emerge -fq $pkg &>/dev/null
else
FEATURES="-getbinpkg" FETCHCOMMAND=false DISTDIR=/usr/portage/distfiles emerge -fq $pkg &>/dev/null
fi
FEATURES="-getbinpkg" FETCHCOMMAND=false DISTDIR=/usr/portage/distfiles emerge -fq $pkg &>/dev/null
}
is_already_install()
@ -46,26 +41,15 @@ install_pkg()
{
local pkg=$1
ebegin "Installing $pkg"
if [[ -d "/var/db/repos/gentoo" ]]
then
FEATURES="-getbinpkg" FETCHCOMMAND=false DISTDIR=/var/calculate/distfiles emerge $pkg &>/dev/null
else
FEATURES="-getbinpkg" FETCHCOMMAND=false DISTDIR=/usr/portage/distfiles emerge $pkg &>/dev/null
fi
FEATURES="-getbinpkg" FETCHCOMMAND=false DISTDIR=/usr/portage/distfiles emerge $pkg &>/dev/null
}
new_install_pkg()
{
local pkg=$1
local mask=$2
pkg=`echo $pkg | cut -d\/ -f2`
ebegin "Installing $pkg"
if [[ -d "/var/db/repos/gentoo" ]]
then
FETCHCOMMAND=false DISTDIR=/var/calculate/distfiles PKGDIR=/var/calculate/packages ${CL_VIDEO_INSTALL} $pkg $mask &>/dev/null
else
FETCHCOMMAND=false DISTDIR=/usr/portage/distfiles PKGDIR=/usr/portage/packages ${CL_VIDEO_INSTALL} $pkg $mask &>/dev/null
fi
FETCHCOMMAND=false DISTDIR=/usr/portage/distfiles PKGDIR=/usr/portage/packages ${CL_VIDEO_INSTALL} $pkg &>/dev/null
eend $?
}
@ -84,11 +68,8 @@ install_video_driver()
;;
nvidia)
local nvidiamask=`variable_value install.os_nvidia_mask`
if [[ -n $nvidiamask ]]
then
[[ -d /etc/portage/package.mask ]] || mkdir /etc/portage/package.mask
[[ -n $nvidiamask ]] && \
echo $nvidiamask >/etc/portage/package.mask/nvidia
fi
local drv="x11-drivers/nvidia-drivers"
;;
*)
@ -101,7 +82,7 @@ install_video_driver()
then
if [[ -x ${CL_VIDEO_INSTALL} ]]
then
new_install_pkg $drv $nvidiamask
new_install_pkg $drv
else
check_install_ability $drv && install_pkg $drv
fi
@ -124,9 +105,8 @@ create_nonroot_user() {
local nonroot_user="guest"
ebegin "Creating ${nonroot_user} user"
LANG=C useradd -p "${nonroot_pw}" \
--groups users,wheel,audio,cdrom,video,cdrw,usb,plugdev,games,lp,lpadmin,scanner,uucp \
--groups users,wheel,audio,cdrom,video,cdrw,usb,plugdev,games,lp,scanner,uucp \
${nonroot_user}
chmod 700 /home/${nonroot_user}
eend $?
fi
}
@ -149,100 +129,45 @@ setup_alsautils() {
checkpath -q -d -m 0700 -o root:root ${alsahomedir}
mkdir -p "${alsastatedir}"
local osaudio=`variable_value install.os_audio`
if [[ $osaudio == "alsa" ]]
then
local vlevel="85%"
else
local vlevel="100%"
fi
einfo "Setting up ALSA Mixer Levels"
# set output volumes to 85% - 100%
amixer -c 0 scontrols | grep -v Mic | sed -nr "/Wave|Headphone|Master|Front|LFE|Center|Side|Speaker|Surround|PCM/ s/.*'([^']+)'.*/\\1/p" | xargs -I {} amixer -c 0 -q set "{}" $vlevel unmute &>/dev/null
# reduce beep
amixer -c 0 scontrols | sed -nr "/Beep/ s/.*'([^']+)'.*/\\1/p" | xargs -I {} amixer -c 0 -q set "{}" 10% mute &>/dev/null
# mute all mics
amixer -c 0 scontrols | sed -nr "/Mic/ s/.*'([^']+)'.*/\\1/p" | xargs -I {} amixer -c 0 -q set "{}" 0% mute &>/dev/null
LANG=C alsactl -E HOME="${alsahomedir}" -I -f "${alsastatedir}/asound.state" store
fi
}
restore_filecaps() {
if [[ -f /var/lib/calculate/filecaps ]] && type filecap &>/dev/null
start() {
local rootflash=`variable_value main.os_root_flash_dev`
local roottype=`variable_value main.os_root_type`
if [[ $roottype != "livecd" ]] || grep -e "video:nvidia" -e "video:fglrx" /proc/cmdline &>/dev/null
then
while read line;
do
filecap $line
done </var/lib/calculate/filecaps
install_video_driver
fi
rm -f /var/lib/calculate/filecaps
}
start() {
if rc-config list boot | grep -q -e "calculate " -e "calculate$"
setup_alsautils
LANG=C create_nonroot_user
LANG=C /usr/sbin/cl-core --method setup_system --no-progress --usenew-conf --live on
LANG=C configure_users
[[ -n $rootflash ]] && mount -o remount,rw $rootflash
# reinit net.* services
local rootdev=`variable_value main.os_root_dev`
if [[ $roottype == "livecd" ]] && [[ $rootdev == "/dev/nfs" ]]
then
local roottype=`variable_value main.os_root_type`
local subsystem=`variable_value main.os_subsystem`
local rootflash=`variable_value main.os_root_flash_dev`
[[ $subsystem == "lxc" ]] && restore_filecaps
if [[ $roottype != "livecd" ]] || grep "video:nvidia" /proc/cmdline &>/dev/null
then
install_video_driver
fi
setup_alsautils
LANG=C create_nonroot_user
if [[ $subsystem == "lxc" ]] || [[ $roottype == "livecd" ]]
then
LANG=C /usr/sbin/cl-core --method setup_system --no-progress --usenew-conf --live on --network on
else
LANG=C /usr/sbin/cl-core --method setup_system --no-progress --usenew-conf --live on
fi
LANG=C configure_users
[[ -n $rootflash ]] && mount -o remount,rw $rootflash
# reinit net.* services
local roottypeext=`variable_value main.os_root_type_ext`
if [[ $roottypeext == "nfs" ]]
then
touch /* /bin/* /sbin/*
fi
rc-update del calculate boot
# set en_US sort service order (make net.eth,net.br,net.wlan more preferable than NetworkManager)
LANG=en_US.utf8 /sbin/rc-update --update
udevadm control --reload
touch /* /bin/* /sbin/*
udevadm trigger --action="add" --subsystem-match=net
fi
if [[ $subsystem != "lxc" ]] && ! [[ -f /var/calculate/server/ca/server.key ]]
then
LANG=C /usr/sbin/cl-core --bootstrap
fi
if [[ $roottype == "livecd" ]]
then
LANG=C /usr/sbin/cl-core -u guest
fi
/sbin/rc-update --update
if [[ $roottype == "hdd" ]]
then
/usr/sbin/cl-core --clear-localuser-cert
if [[ -d "/var/db/repos/gentoo" ]]
then
local distdir="/var/calculate/distfiles"
local pkgdir="/var/calculate/packages"
else
local distdir="/usr/portage/distfiles"
local pkgdir="/usr/portage/packages"
fi
local video_script="/usr/local/sbin/cl-video-install"
local cache_video="/var/cache/calculate/video_drivers"
[[ -d "${distdir}" ]] && [[ -n "`ls ${distdir}`" ]] && rm ${distdir}/*
[[ -d "${pkgdir}" ]] && [[ -n "`ls ${pkgdir}`" ]] && rm -r ${pkgdir}/*
[[ -f "${video_script}" ]] && rm -f "${video_script}"
[[ -f "${cache_video}" ]] && rm -f "${cache_video}"
fi
else
ewarn "System already configured!"
local roottype=`variable_value main.os_root_type`
if [[ $roottype == "hdd" ]] && rc-config list boot | grep -q -e "calculate " -e "calculate$"
then
rc-update del calculate boot
local distdir="/usr/portage/distfiles"
local pkgdir="/usr/portage/packages"
local video_script="/usr/local/sbin/cl-video-install"
local cache_video="/var/cache/calculate/video_drivers"
[[ -d "${distdir}" ]] && [[ -n "`ls ${distdir}`" ]] && rm ${distdir}/*
[[ -d "${pkgdir}" ]] && [[ -n "`ls ${pkgdir}`" ]] && rm -r ${pkgdir}/*
[[ -f "${video_script}" ]] && rm -f "${video_script}"
[[ -f "${cache_video}" ]] && rm -f "${cache_video}"
fi
return 0

@ -1,8 +1,9 @@
#!/bin/bash
PKG=$1
MASK=$2
MASK=`cl-core --method core_variables_show --only-value install.os_nvidia_mask 2>/dev/null`
WORLD=/var/lib/portage/world
LOG=/dev/tty12
LOG=/var/log/calculate/video-install.log
:> $LOG
WRITEPKG=
[[ -z "$(tail -c1 $WORLD)" ]] || echo >> $WORLD
@ -12,36 +13,12 @@ do
then
if [[ $package_dir == "binary" ]]
then
binary_packages="$binary_packages =$category/$pn-$pv"
fi
fi
done </var/cache/calculate/video_drivers
if [[ -n $binary_packages ]]
then
if [[ -d "/var/db/repos/gentoo" ]]
then
ACCEPT_KEYWORDS="**" FEATURES="-getbinpkg" PKGDIR=/var/calculate/packages emerge -OK1 $binary_packages 2>&1 | cat &>>$LOG || exit 1
else
ACCEPT_KEYWORDS="**" FEATURES="-getbinpkg" PKGDIR=/usr/portage/packages emerge -OK1 $binary_packages 2>&1 | cat &>>$LOG || exit 1
fi
fi
while read category pn pv package_dir pkgname pkgmask;
do
if [[ $PKG == $pkgname ]] && [[ $MASK == $pkgmask ]]
then
if [[ $package_dir != "binary" ]]
then
ACCEPT_KEYWORDS="**" FEATURES="-getbinpkg" PKGDIR=/usr/portage/packages emerge -OK1 =$category/$pn-$pv &>>$LOG || exit 1
else
cd $package_dir
ebuild=$category/$pn/$pn-${pv}.ebuild
[[ -f $ebuild ]] || git checkout $(dirname $ebuild) 2>&1 | cat &>>$LOG
if [[ -d "/var/db/repos/gentoo" ]]
then
DISTDIR=/var/calculate/distfiles ebuild $ebuild merge --skip-manifest | grep --color=never -P "^>>> [^/]" 2>&1 | cat &>>$LOG || exit 1
else
DISTDIR=/usr/portage/distfiles ebuild $ebuild merge --skip-manifest | grep --color=never -P "^>>> [^/]" 2>&1 | cat &>>$LOG || exit 1
fi
[[ -f $ebuild ]] || git checkout $(dirname $ebuild) >>$LOG
DISTDIR=/usr/portage/distfiles ebuild $ebuild merge --skip-manifest &>>$LOG || exit 1
WRITEPKG="$category/$pn"
fi
fi

@ -35,10 +35,10 @@ pre {font-size:133% }
<li>CLDL - Calculate Linux Desktop LXQt</li>
<li>CLDM - Calculate Linux Desktop MATE</li>
<li>CLDX - Calculate Linux Desktop Xfce</li>
<li>CCM - Calculate Container Manager</li>
<li>CDS - Calculate Directory Server</li>
<li>CLS - Calculate Linux Scratch</li>
<li>CDS - Calculate Directory Server</li>
<li>CSS - Calculate Scratch Server</li>
<li>CMC - Calculate Media Center</li>
</ul>
@ -59,10 +59,10 @@ As for any other operation performed on the Utilities Server (and this is how yo
<h2 id="Partition-management">Partition management<a href="#Partition-management" class="wiki-anchor">&para;</a></h2>
<p>Before installing, you may need to edit partitions on your hard disk. If you intend to install CLD, CLDC, CLDL, CLDM or CLDX, we recommend that you use the partition of at least 15 GB. More detailed hardware requirements can be found <a href="https://www.calculate-linux.org/main/en/hardware_requirements" target="_blank">here</a>. The swap partition will normally be twice the size of RAM. If the swap partition already exists, the system will use it. Moreover, it is wise to have a separate partition for your personal files (i.e. for the <code>/home</code> directory). See more detailed instructions on partitioning <a href="https://www.calculate-linux.org/main/en/disk_partitioning" target="_blank">here</a>.</p>
<p>Before installing, you may need to edit partitions on your hard disk. If you intend to install CLD, CLDC, CLDL, CLDM or CLDX, we recommend that you use the partition of at least 10 GB. More detailed hardware requirements can be found <a href="http://www.calculate-linux.org/main/en/hardware_requirements" class="external">here</a>. The swap partition will normally be twice the size of RAM. If the swap partition already exists, the system will use it. Moreover, it is wise to have a separate partition for your personal files (i.e. for the <code>/home</code> directory). See more detailed instructions on partitioning <a href="http://www.calculate-linux.org/main/en/disk_partitioning" class="external">here</a>.</p>
<p>CLD, CLDC, CLDL, CLDM and CLDX provide <em>Gparted</em> to edit partitions with, while CLS, CSS and CDS feature only command line utilities for the same purposes, namely <code>fdisk</code>, <code>gdisk or <code>cfdisk</code>.</p>
<p>CLD, CLDC, CLDL, CLDM and CLDX provide <em>Gparted</em> to edit partitions with, while CLS, CSS and CDS feature only command line utilities for the same purposes, namely <code>fdisk</code>, <code>gdisk or @cfdisk</code>.</p>
<p>To list all existing partitions, open your terminal as <em>root</em> and type:<br /><pre>
@ -84,8 +84,8 @@ fdisk -l
We provide several tools that get you install Calculate Linux. You can choose between :
<ul>
<li>the GUI installer, <a href="https://www.calculate-linux.org/main/en/calculate-console-gui" target="_blank">cl-console-gui</a>,</li>
<li>the command line installer, <a href="https://www.calculate-linux.org/main/en/calculate-console" target="_blank">cl-console</a>,</li>
<li>the GUI installer, <a href="http://www.calculate-linux.org/main/en/calculate-console-gui" class="external">cl-console-gui</a>,</li>
<li>the command line installer, <a href="http://www.calculate-linux.org/main/en/calculate-console" class="external">cl-console</a>,</li>
</ul>
@ -106,7 +106,7 @@ startx
</pre></p>
<p>To become <em>root</em>, use the <code>su</code> command. More details on creating user accounts can be found on <a href="https://www.calculate-linux.org/main/en/create_system_users" target="_blank">this page</a>.</p>
<p>To become <em>root</em>, use the <code>su</code> command. More details on creating user accounts can be found on <a href="http://www.calculate-linux.org/main/en/create_system_users" class="external">this page</a>.</p>
<p>By default, you need to be root to log into the system remotely, via the ssh protocole. To add space for other users or to replace the root user edit the <em>AllowUsers</em> line in your <code>/etc/ssh/sshd_config</code>. We recommend that you disable remote root login.</p>
@ -115,7 +115,7 @@ startx
<h2 id="System-update">System update<a href="#System-update" class="wiki-anchor">&para;</a></h2>
<p>Calculate Linux is a rolling-release distribution. You can update the system virtually unlimited number of times with <a href="https://wiki.calculate-linux.org/en/system_update_guide" target="_blank">cl-update</a>.</p>
<p>Calculate Linux is a rolling-release distribution. You can update the system virtually unlimited number of times with <a href="http://www.calculate-linux.org/main/en/cl-update" class="external">cl-update</a>.</p>
<p>To sync the list of packages and update all of your software, simply run:<br /><pre>
@ -128,7 +128,7 @@ cl-update --sync-only
</pre></p>
<p>After that, you can install any other applications you need with <code>emerge</code>. A quick reference can be found <a href="https://www.calculate-linux.org/main/en/add_and_remove_programs" target="_blank">here</a>. It may also be of interest to read our <a href="https://www.calculate-linux.org/main/en/system_update_guide" target="_blank">System Update Guide</a>.</p>
<p>After that, you can install any other applications you need with <code>emerge</code>. A quick reference can be found <a href="http://www.calculate-linux.org/main/en/add_and_remove_programs" class="external">here</a>. It may also be of interest to read our <a href="http://www.calculate-linux.org/main/en/system_update_guide" class="external">System Update Guide</a>.</p>
<h2 id="Help">Help<a href="#Help" class="wiki-anchor">&para;</a></h2>
@ -137,9 +137,9 @@ cl-update --sync-only
<p>If you have any difficulties installing Calculate Linux, or if you want to share your impressions, feel free to visit our IRC community channel <code>#calculate</code> on FreeNode. You just have to click on the <em>Hexchat</em> icon on top of your desktop.</p>
<p>The project site: <a href="https://www.calculate-linux.org" target="_blank">https://www.calculate-linux.org</a><br />Our English-speaking IRC community: <a href="https://chat.calculate-linux.org/?channel=#chat" target="_blank">https://chat.calculate-linux.org</a></p>
<p>The project site: <noindex><a class="external" href="http://www.calculate-linux.org" ref="nofollow">http://www.calculate-linux.org</a></noindex><br />Our English-speaking IRC community: <noindex><a class="external" href="http://www.calculate-linux.org/irc" ref="nofollow">http://www.calculate-linux.org/irc</a></noindex></p>
<p>You can find like-minded people on Facebook, on the <a href="https://www.facebook.com/CalculateLinux" target="_blank">Calculate Linux</a> page.</p>
<p>You can find like-minded people on Facebook, on the <noindex><a href="https://www.facebook.com/CalculateLinux" class="external">Calculate Linux</a></noindex> page.</p>
<p>&nbsp;<br /><em>Enjoy!</em><br /><em>Calculate Linux Team.</em></p>
</body>

@ -33,10 +33,10 @@ pre {font-size:133% }
<li>CLDL - Calculate Linux Desktop LXQt</li>
<li>CLDM - Calculate Linux Desktop MATE</li>
<li>CLDX - Calculate Linux Desktop Xfce</li>
<li>CCM - Calculate Container Manager</li>
<li>CDS - Calculate Directory Server</li>
<li>CLS - Calculate Linux Scratch</li>
<li>CDS - Calculate Directory Server</li>
<li>CSS - Calculate Scratch Server</li>
<li>CMC - Calculate Media Center</li>
</ul>
@ -54,13 +54,13 @@ pre {font-size:133% }
</ul>
<p>Подробнее в разделе <a href="https://www.calculate-linux.ru/main/ru/setup_network" target="_blank">Настройка сети</a>.</p>
<p>Подробнее в разделе <a href="http://www.calculate-linux.ru/main/ru/setup_network" class="external">Настройка сети</a>.</p>
<h2 id="Разбивка-диска">Разбивка диска<a href="#Разбивка-диска" class="wiki-anchor">&para;</a></h2>
<p>Перед установкой вам может понадобиться изменить разделы жесткого диска. Для установки CLD, CLDC, CLDL, CLDM и CLDX мы рекомендуем использовать раздел не менее 15 Гб. Более подробно аппаратные требования можно узнать <a href="https://www.calculate-linux.ru/main/ru/hardware_requirements" target="_blank">здесь</a>. Раздел подкачки (swap), как правило, выделяется вдвое большим размера оперативной памяти. Если раздел под swap уже существует, система будет использовать его. Полезно иметь отдельный раздел для личных файлов (<code>/home</code>). Наши рекомендации по разбиению диска описаны <a href="https://www.calculate-linux.ru/main/ru/disk_partitioning" target="_blank">здесь</a>.</p>
<p>Перед установкой вам может понадобиться изменить разделы жесткого диска. Для установки CLD, CLDC, CLDL, CLDM и CLDX мы рекомендуем использовать раздел не менее 10 Гб. Более подробно аппаратные требования можно узнать <a href="http://www.calculate-linux.ru/main/ru/hardware_requirements" class="external">здесь</a>. Раздел подкачки (swap), как правило, выделяется вдвое большим размера оперативной памяти. Если раздел под swap уже существует, система будет использовать его. Полезно иметь отдельный раздел для личных файлов (<code>/home</code>). Наши рекомендации по разбиению диска описаны <a href="http://www.calculate-linux.ru/main/ru/disk_partitioning" class="external">здесь</a>.</p>
<p>В CLD, CLDC, CLDL, CLDM и CLDX для изменения разделов диска используется программа <em>Gparted</em>. В CDS, CSS и CLS входят только консольные утилиты: <em>fdisk</em>,<em>gdisk</em> или <em>cfdisk</em>.</p>
@ -85,13 +85,13 @@ fdisk -l
Установить систему Calculate Linux вы можете одним из перечисленных способов:
<ul>
<li>графическим клиентом <a href="https://www.calculate-linux.ru/main/ru/calculate-console-gui" target="_blank">cl-console-gui</a>,</li>
<li>консольным клиентом <a href="https://www.calculate-linux.ru/main/ru/calculate-console" target="_blank">cl-console</a>,</li>
<li>напрямую сервером утилит <a href="https://www.calculate-linux.ru/main/ru/calculate-core" target="_blank">cl-core</a>.</li>
<li>графическим клиентом <a href="http://www.calculate-linux.ru/main/ru/calculate-console-gui" class="external">cl-console-gui</a>,</li>
<li>консольным клиентом <a href="http://www.calculate-linux.ru/main/ru/calculate-console" class="external">cl-console</a>,</li>
<li>напрямую сервером утилит <a href="http://www.calculate-linux.ru/main/ru/calculate-core" class="external">cl-core</a>.</li>
</ul>
<p>Система может быть установлена из squashfs-образа, если Вы загрузились с liveCD или USB Flash, либо из ISO-файла, размещенного в директории <code>/var/calculate/linux</code>.</p>
<p>Система может быть установлена из squashfs-образа, если Вы загрузились с liveCD или USB Flash, либо из ISO-файла, размещенного в директории <code>/var/calculate/linux</code> или <code>/var/calculate/remote/linux</code>. Во втором случае Вы можете установить любую версию дистрибутива поддерживаемой архитектуры.</p>
<p>Сервер утилит, консольный и графический клиенты входят в состав Calculate Linux, но могут быть установлены из оверлея Calculate в любом Gentoo-совместимом дистрибутиве.</p>
@ -99,8 +99,8 @@ fdisk -l
Подробное описание установки смотрите в соответствующих разделах:
<ul>
<li><a href="https://www.calculate-linux.ru/main/ru/calculate_install" target="_blank">Установка на жёсткий диск</a></li>
<li><a href="https://www.calculate-linux.ru/main/ru/calculate_install_flash" target="_blank">Установка на Flash</a></li>
<li><a href="http://www.calculate-linux.ru/main/ru/calculate_install" class="external">Установка на жёсткий диск</a></li>
<li><a href="http://www.calculate-linux.ru/main/ru/calculate_install_flash" class="external">Установка на Flash</a></li>
</ul></p>
@ -115,7 +115,7 @@ startx
</pre></p>
<p>Для получения прав пользователя <em>root</em> используйте команду <code>su</code>. Добавление новых пользователей подробно описано <a href="https://www.calculate-linux.ru/main/ru/create_system_users" target="_blank">здесь</a>.</p>
<p>Для получения прав пользователя <em>root</em> используйте команду <code>su</code>. Добавление новых пользователей подробно описано <a href="http://www.calculate-linux.ru/main/ru/create_system_users" class="external">здесь</a>.</p>
<p>По умолчанию вы можете зайти в систему удаленно (по протоколу ssh) только как пользователь root. В файле <code>/etc/ssh/sshd_config</code> в значение параметра <em>AllowUsers</em> можно добавить другие учётные записи. Мы рекомендуем убрать права удаленного доступа к системе для пользователя <em>root</em>.</p>
@ -124,7 +124,7 @@ startx
<h2 id="Обновление">Обновление<a href="#Обновление" class="wiki-anchor">&para;</a></h2>
<p>Calculate Linux использует rolling-release модель обновлений. Вы можете обновлять систему практически неограниченное количество раз, используя утилиту обновления системы <a href="https://wiki.calculate-linux.org/ru/system_update_guide" target="_blank">cl-update</a>.</p>
<p>Calculate Linux использует rolling-release модель обновлений. Вы можете обновлять систему практически неограниченное количество раз, используя утилиту обновления системы <a href="http://www.calculate-linux.ru/main/ru/cl-update" class="external">cl-update</a>.</p>
<p>Для выполнения синхронизации списка пакетов и обновления программ, выполните:<br /><pre>
@ -137,18 +137,18 @@ cl-update --sync-only
</pre></p>
<p>После этого вы можете установить новые программы при помощи менеджера пакетов <em>emerge</em>. Краткая справка приведена <a href="https://www.calculate-linux.ru/main/ru/add_and_remove_programs" target="_blank">здесь</a>. Прочтите так же <a href="https://www.calculate-linux.ru/main/ru/system_update_guide" target="_blank">Руководство по обновлению системы</a>.</p>
<p>После этого вы можете установить новые программы при помощи менеджера пакетов <em>emerge</em>. Краткая справка приведена <a href="http://www.calculate-linux.ru/main/ru/add_and_remove_programs" class="external">здесь</a>. Прочтите так же <a href="http://www.calculate-linux.ru/main/ru/system_update_guide" class="external">Руководство по обновлению системы</a>.</p>
<h2 id="Помощь">Помощь<a href="#Помощь" class="wiki-anchor">&para;</a></h2>
<p>Если установка системы вызвала сложности или вы хотите поделиться своим впечатлением, зайдите в <em>IRC</em> чат <em>#chat-ru</em> (сервер irc.calculate.social) сообщества пользователей Calculate Linux. Для этого достаточно воспользоваться иконкой <em>Сообщество Calculate Linux</em> на вашем рабочем столе или перейдя по <a href="https://chat.calculate-linux.org/?channel=#chat-ru" target="_blank">ссылке.</a></p>
<p>Если установка системы вызвала сложности или вы хотите поделиться своим впечатлением, зайдите на <em>IRC</em> канал <em>#calculate-ru</em> (сервер FreeNode) сообщества пользователей Calculate Linux. Для этого достаточно воспользоваться иконкой <em>Hexchat</em> на вашем рабочем столе.</p>
<p>Сайт проекта: <a href="https://www.calculate-linux.ru" target="_blank">https://www.calculate-linux.ru</a></p>
<p>Сайт проекта: <noindex><a class="external" href="http://www.calculate-linux.ru" ref="nofollow">http://www.calculate-linux.ru</a></noindex><br />IRC чат: <noindex><a class="external" href="http://www.calculate-linux.ru/irc" ref="nofollow">http://www.calculate-linux.ru/irc</a></noindex></p>
<p>Найти единомышленников можно и в социальных сетях:<br><a href="https://calculate.social/@news_ru" target="_blank">Mastodon</a>, <a href="https://vk.com/calculatelinux" target="_blank">ВКонтакте</a>, <a href="https://www.facebook.com/CalculateLinux.ru">Facebook</a> или <a href="https://www.ok.ru/calculate" target="_blank">Одноклассники</a>.</p>
<p>Найти единомышленников можно и в социальных сетях:<br><noindex><a href="https://vk.com/calculatelinux" class="external">ВКонтакте</a></noindex>, <noindex><a href="https://www.facebook.com/CalculateLinux.ru" class="external">Facebook</a></noindex>, <noindex><a href="https://plus.google.com/communities/100511365552994940528" class="external">Google+</a></noindex>, <noindex><a href="http://www.ok.ru/calculate" rel="nofollow" target="_blank" class="external">Одноклассники</a></noindex> или <noindex><a href="http://twitter.com/calculatelinux" rel="nofollow" target="_blank" class="external">Twitter</a></noindex>.</p>
<p><em>Приятной работы!<br />Команда разработчиков Calculate Linux.</em></p>
</body>

@ -19,41 +19,35 @@ from random import choice
import string
import os
from time import sleep
import datetime
import re
import sys
import operator
import json
from shutil import copyfile, copytree
from subprocess import Popen, PIPE
from itertools import *
from functools import partial
from calculate.lib.datavars import VariableError
from .datavars import DataVarsInstall
from calculate.lib.utils.mount import isMount, Btrfs, BtrfsError
from calculate.lib.utils.files import (removeDir,
from calculate.lib.utils.files import (isMount, removeDir,
processProgress, STDOUT,
typeFile, pathJoin, process,
listDirectory, checkUtils,
MAGIC_COMPRESS, MAGIC_SYMLINK,
MAGIC_CONTINUE, makeDirectory,
isEmpty, check_rw, calculate_exclude,
PercentProgress, getProgPath, xztaropen)
import calculate.lib.utils.device as device
PercentProgress, getProgPath)
from calculate.lib.utils.device import (detectDeviceForPartition,
countPartitions)
getUdevDeviceInfo, countPartitions)
from calculate.lib.utils.tools import classproperty, Signal, traverse
from calculate.lib.utils.text import _u8
from calculate.lib.variables.linux import LinuxDataVars, Linux
from calculate.lib.cl_lang import setLocalTranslate, _
from functools import reduce
setLocalTranslate('cl_install3', sys.modules[__name__])
class DefaultMountPath():
class DefaultMountPath(object):
"""
Пути по умолчанию для монтирования образов
"""
@ -98,13 +92,13 @@ class cpProcessProgress(processProgress):
return 100
def processString(self, strdata):
if strdata.startswith(b"cp:") or strdata.startswith(b"/bin/cp:"):
self._cachedata.append(strdata.partition(b": ")[2])
if b"->" in strdata:
if strdata.startswith("cp:") or strdata.startswith("/bin/cp:"):
self._cachedata.append(strdata.partition(": ")[2])
if "->" in strdata:
self.value += 1
if self.maxfiles:
percent = 100 * self.value // self.maxfiles
percent = min(percent, 100)
percent = 100 * self.value / self.maxfiles
percent = min(percent, 99)
if percent > self.percent:
self.percent = percent
return percent
@ -117,10 +111,10 @@ def progressCopyFile(source, dest):
Copy file with progress
"""
size = int(os.lstat(source).st_size)
bufsize = (100 - (size % 100) + size) // 100
bufsize = (100 - (size % 100) + size) / 100
with open(source, 'rb') as infile:
with open(dest, 'wb') as outfile:
for i in range(1, 101):
with open(dest, 'w') as outfile:
for i in xrange(1, 101):
outfile.write(infile.read(bufsize))
yield i
@ -130,12 +124,12 @@ class DistributiveError(Exception):
pass
class Distributive():
class Distributive(object):
"""
Distributive object. Parent object for all distributive.
"""
class Type():
class Type(object):
Directory = "dir"
Partition = "part"
SquashFS = "squash"
@ -180,16 +174,11 @@ class Distributive():
return IsoDistributive(filename)
elif "7-zip" in ftype or \
"POSIX tar archive" in ftype:
if "rootfs.tar" in filename:
return ContainerDistributive(path.dirname(filename))
else:
return ArchiveDistributive(filename)
return ArchiveDistributive(filename)
elif "Squashfs filesystem" in ftype:
return SquashDistributive(filename)
elif path.isdir(filename):
if path.isfile(path.join(filename, "rootfs.tar.xz")):
return ContainerDistributive(filename)
elif path.isfile(path.join(filename, "livecd")):
if path.isfile(path.join(filename, "livecd")):
return IsoDistributive(filename)
else:
important_dirs = ("etc", "lib", "bin", "sbin", "var")
@ -303,10 +292,7 @@ class Distributive():
def getEfiDirectory(self):
"""Get directory which contains boot/efi"""
return self.getEfiDirectories()[0]
def getEfiDirectories(self):
return [path.join(self.getDirectory(), "boot/efi")]
return path.join(self.getDirectory(), "boot/efi")
def _makeDirectory(self, pathname):
"""Make directory and parent.
@ -321,10 +307,10 @@ class Distributive():
return False
os.mkdir(pathname)
return True
except Exception as e:
except Exception, e:
raise DistributiveError(_("Failed to create the directory") +
" '%s':\n%s" % (pathname, str(e)))
except KeyboardInterrupt as e:
except KeyboardInterrupt, e:
raise DistributiveError(_("Failed to create the directory") +
" '%s':\n%s" % (pathname, str(e)))
@ -358,10 +344,10 @@ class Distributive():
def _copytree(self, indir, outdir):
try:
copytree(indir, outdir, symlinks=True)
except Exception as e:
except Exception, e:
raise DistributiveError(_("Failed to copy") + " '%s' to '%s':\n%s" \
% (indir, outdir, str(e)))
except KeyboardInterrupt as e:
except KeyboardInterrupt, e:
raise DistributiveError(_("Failed to copy") + " '%s' to '%s':\n%s" \
% (indir, outdir, str(e)))
@ -375,10 +361,10 @@ class Distributive():
joinFrom = partial(path.join, fromdir)
params = [cpCmd, "-x"] + \
(["--no-preserve=mode,ownership"] if noperm else ["-a"]) + \
[joinFrom(x) for x
in filterfalse(byfile or operator.not_,
listDirectory(fromdir))] + \
[todir]
map(joinFrom,
ifilterfalse(byfile or operator.not_,
listDirectory(fromdir))) + \
[todir]
cpProcess = cpProcessProgress(*params,
maxfiles=filesnum, stderr=STDOUT)
for perc in cpProcess.progress():
@ -387,11 +373,12 @@ class Distributive():
errmes = cpProcess.read()
# copy by one file
if byfile:
percFiles = [x for x in listDirectory(fromdir) if byfile(x)]
percFiles = filter(byfile,
listDirectory(fromdir))
if len(percFiles) > 1:
maxPercOnFile = 100 // len(percFiles)
maxPercOnFile = 100 / len(percFiles)
recountPerc = \
lambda perc, num: perc // len(
lambda perc, num: perc / len(
percFiles) + maxPercOnFile * num
else:
recountPerc = lambda perc, num: perc
@ -400,7 +387,7 @@ class Distributive():
path.join(todir, copyfile)):
if callbackProgress:
callbackProgress(recountPerc(perc, i))
except Exception as e:
except Exception, e:
res = False
errmes = str(e)
if not res:
@ -425,13 +412,13 @@ class Distributive():
def performFormat(self):
pass
def formatPartition(self, dev, format="ext4", label="", purpose=None):
def formatPartition(self, dev, format="ext4", label=""):
pass
def rndString(self):
"""Get random string with len 8 char"""
return "".join([choice(string.ascii_letters + string.digits)
for i in range(0, 8)])
for i in xrange(0, 8)])
def _getSquashNum(self, reMatch):
if reMatch.groups()[1] and reMatch.groups()[1].isdigit():
@ -441,25 +428,28 @@ class Distributive():
def _getLastLive(self, directory):
"""Get last live squashfs image from directory"""
squashfiles = [x for x in map(self.reLive.search, listDirectory(directory)) if x]
squashfiles = filter(lambda x: x,
map(self.reLive.search,
listDirectory(directory)))
if squashfiles:
return max(squashfiles, key=self._getSquashNum).group()
return None
def _mountToDirectory(self, file, directory, mountopts="", count=2):
"""Mount squashfs to directory"""
# 2816 code return by mount if device is absent (update /dev by udev)
NO_SUCH_DEVICE = 2816
if isMount(directory):
raise DistributiveError(
_("Failed to mount to the directory: %s\n")
% directory + _("Directory already mounted"))
mountopts_list = [x for x in mountopts.split(" ") if x]
mountopts_list = filter(lambda x: x,
mountopts.split(" "))
mountProcess = process('/bin/mount', file, directory, *mountopts_list,
stderr=STDOUT)
if mountProcess.success():
return True
else:
# 2816 code return by mount if device is absent (update /dev by udev)
# try mount 3 times with interval 0.5 second
if mountProcess.returncode() == NO_SUCH_DEVICE and count:
sleep(0.5)
@ -507,6 +497,8 @@ class Distributive():
try:
if path.lexists(path.join(directory, 'lib64')):
d['os_arch_machine'] = 'x86_64'
elif path.lexists(path.join(directory, 'lib')):
d['os_arch_machine'] = 'i686'
else:
d['os_arch_machine'] = ''
dv = LinuxDataVars(systemRoot=directory)
@ -520,12 +512,6 @@ class Distributive():
d['cl_profile_name'] = dv.Get('cl_profile_name')
# make lazy call
d['os_linux_files'] = partial(dv.Get, 'os_linux_files')
d['os_chrootable_set'] = "off"
try:
if process("/usr/bin/chroot", directory, "/bin/true").success():
d['os_chrootable_set'] = "on"
except Exception:
pass
except VariableError:
pass
return d.copy()
@ -554,15 +540,8 @@ class Distributive():
mapExtName = {DirectoryDistributive: "dir",
IsoDistributive: "isodir",
FlashDistributive: "flash",
ContainerDistributive: "lxc",
PartitionDistributive: "partdir"}
extname = mapExtName.get(distr.__class__, "")
if isinstance(distr, ContainerDistributive):
d = distr.get_information()
d['ext'] = extname
return d.copy()
if isinstance(distr, ArchiveDistributive):
raise DistributiveError("Not for archive distributive")
image = distr.convertToDirectory()
except Exception as e:
# TODO: отладка почему образ не подходит
@ -643,10 +622,6 @@ class DirectoryDistributive(Distributive):
'type': 'bind',
'target': 'var/calculate/remote',
'source': '/var/calculate/remote'},
{'name': 'run',
'type': 'bind',
'target': 'run/',
'source': '/run'}
]
def __init__(self, directory, parent=None, mdirectory=None):
@ -658,36 +633,19 @@ class DirectoryDistributive(Distributive):
if not parent:
self._makeDirectory(self.directory)
def hasSystemDirectories(self):
return self.system_mounted or self.directory == '/'
def mountSystemDirectories(self, skip=("remote",)):
"""
Подключить к дистрибутиву системые ресурсы (/proc, /sys)
:return:
"""
if not self.system_mounted:
self.clVars = DataVarsInstall()
# Если в режиме EFI, добавить раздел efivarfs
if self.clVars.GetBool('main.os_uefi_set'):
efi_data = {'name': 'efivars',
'type': 'efivarfs',
'target': 'sys/firmware/efi/efivars',
'source': 'efivarfs'}
if not efi_data in self.data:
self.data.append(efi_data)
for obj in (x for x in self.data if x['name'] not in skip):
target_path = path.join(self.directory, obj['target'])
if obj['type'] == 'bind':
if not path.exists(target_path):
self._makeDirectory(target_path)
if not path.exists(obj['source']):
self._makeDirectory(obj['source'])
self._mountToBind(obj['source'], target_path)
else:
self._mountToDirectory(obj['source'], target_path,
"-t %s" % obj['type'])
self.system_mounted = True
for obj in filter(lambda x: x['name'] not in skip, self.data):
target_path = path.join(self.directory, obj['target'])
if obj['type'] == 'bind':
self._mountToBind(obj['source'], target_path)
else:
self._mountToDirectory(obj['source'], target_path,
"-t %s" % obj['type'])
self.system_mounted = True
def umountSystemDirectories(self):
for obj in reversed(self.data):
@ -697,7 +655,7 @@ class DirectoryDistributive(Distributive):
self.system_mounted = False
def getType(self):
return _("directory '%s'") % _u8(self.directory)
return _("directory '%s'") % self.directory
def bindDirectory(self, mdirectory):
for child in self.childs:
@ -778,7 +736,7 @@ class DirectoryDistributive(Distributive):
return ld
class DataPartition():
class DataPartition(object):
"""Data partition"""
dev = None
mountPoint = None
@ -798,8 +756,10 @@ class MultiPartitions:
"""Add partition in data partition list"""
dictDataPart = reduce(lambda x, y: \
x.update({y: getattr(DataPartition, y)}) or x,
[x for x in DataPartition.__dict__ if not x.startswith('_')], {})
updateAttrData = (x for x in dictDataPart.items() if x[1] is not None)
filter(lambda x: not x.startswith('_'),
DataPartition.__dict__), {})
updateAttrData = filter(lambda x: x[1] is not None,
dictDataPart.items())
defaultAttr = []
for attrName, attrValue in updateAttrData:
if not attrName in argv.keys():
@ -810,13 +770,14 @@ class MultiPartitions:
if notFoundAttr:
raise DistributiveError(_("The following attributes "
"are not specified: (%s)") \
% ", ".join(("DataPartition.%s" % x for x in notFoundAttr)))
% ", ".join(
map(lambda x: "DataPartition.%s" % x, notFoundAttr)))
unnecessaryAttr = (set(dictDataPart.keys()) ^ set(argv.keys())) - \
set(dictDataPart.keys())
if unnecessaryAttr:
raise DistributiveError(_("Failed to use attributes (%s) ") \
% ", ".join(
("DataPartition.%s" % x for x in unnecessaryAttr)))
map(lambda x: "DataPartition.%s" % x, unnecessaryAttr)))
else:
partObj = DataPartition()
for attr, value in argv.items():
@ -827,27 +788,27 @@ class MultiPartitions:
def getSystemId(self):
"""Get systemID for change [None,82,...]"""
return [x.systemId for x in self.listPartitions]
return map(lambda x: x.systemId, self.listPartitions)
def getPartitionTable(self):
"""Get systemID for change [dos,gpt,...]"""
return [x.partitionTable for x in self.listPartitions]
return map(lambda x: x.partitionTable, self.listPartitions)
def getIsFormat(self):
"""Get list is format [True,...]"""
return [x.isFormat for x in self.listPartitions]
return map(lambda x: x.isFormat, self.listPartitions)
def getFileSystems(self):
"""Get list filesystems ["reiserfs",...]"""
return [x.fileSystem for x in self.listPartitions]
return map(lambda x: x.fileSystem, self.listPartitions)
def getPartitions(self):
"""Get list partition ["/dev/sda",...]"""
return [x.dev for x in self.listPartitions]
return map(lambda x: x.dev, self.listPartitions)
def getMountPoints(self):
"""Get list mount point ["/boot",...]"""
return [x.mountPoint for x in self.listPartitions]
return map(lambda x: x.mountPoint, self.listPartitions)
class FormatProcess(process):
@ -855,29 +816,17 @@ class FormatProcess(process):
dos_id = "0"
gpt_id = "0"
def __init__(self, dev, label=None, purpose=None, compression=None):
def __init__(self, dev, label=None):
self.dev = dev
self._label = label
self.purpose = purpose
self.compression = compression
super().__init__(*self.format_command())
super(FormatProcess, self).__init__(*self.format_command())
def format_command(self):
cmd = getProgPath(self.format_util)
if not cmd:
raise DistributiveError(_("command '%s' not found") % cmd)
params = (self.bootparam()
if self.purpose in ("root", "boot")
else self.param())
return list(traverse(
[cmd] + [x for x in params if x]))
def postaction(self):
return True
def bootparam(self):
return self.param()
[cmd] + [x for x in self.param() if x]))
def param(self):
return self.get_label(), self.dev
@ -915,10 +864,6 @@ class FormatExt4(FormatExt2):
format_util = "/sbin/mkfs.ext4"
class FormatExfat(FormatProcessGeneric):
format_util = "/sbin/mkfs.exfat"
class FormatJfs(FormatProcessGeneric):
format_util = "/sbin/mkfs.jfs"
@ -926,15 +871,6 @@ class FormatJfs(FormatProcessGeneric):
return self.get_label(), "-f", self.dev
class FormatF2FS(FormatProcessGeneric):
format_util = "/usr/sbin/mkfs.f2fs"
def label(self):
return "-l", self._label
def param(self):
return self.get_label(), "-f", self.dev
class FormatReiserfs(FormatProcessGeneric):
format_util = "/sbin/mkfs.reiserfs"
@ -955,12 +891,6 @@ class FormatXfs(FormatProcessGeneric):
def param(self):
return self.get_label(), "-f", self.dev
def nosparse(self):
return "-i", "sparse=0"
def bootparam(self):
return self.get_label(), self.nosparse(), "-f", self.dev
class FormatVfat(FormatProcess):
dos_id = "0b"
@ -1012,9 +942,7 @@ class PartitionDistributive(Distributive):
'ext2': FormatExt2,
'ext3': FormatExt3,
'ext4': FormatExt4,
'exfat': FormatExfat,
'jfs': FormatJfs,
'f2fs': FormatF2FS,
'reiserfs': FormatReiserfs,
'btrfs': FormatBtrfs,
'nilfs2': FormatNilfs2,
@ -1023,16 +951,13 @@ class PartitionDistributive(Distributive):
'ntfs-3g': FormatNtfs,
'ntfs': FormatNtfs,
'uefi': FormatUefi,
'btrfs': FormatBtrfs,
'btrfs-compress': FormatBtrfs,
'swap': FormatSwap
}
def __init__(self, partition, parent=None, mdirectory=None,
check=False, multipartition=None, flagRemoveDir=True,
fileSystem="ext4", isFormat=True, systemId=None,
rootLabel="Calculate", partitionTable=None,
compression=None):
rootLabel="Calculate", partitionTable=None):
"""Initialize partition distributive
mdirectory - directory for mount
@ -1049,7 +974,6 @@ class PartitionDistributive(Distributive):
self.DirectoryObject = None
self.systemId = systemId
self.rootLabel = rootLabel
self.compression = compression
self.partitionTable = partitionTable
def getType(self):
@ -1094,7 +1018,8 @@ class PartitionDistributive(Distributive):
def postinstallMountBind(self):
"""Mount bind mount point and create mount dirs"""
if self.multipartition and self.DirectoryObject:
mulipartDataBind = [x for x in self.getMultipartData() if x[2] == "bind"]
mulipartDataBind = filter(lambda x: x[2] == "bind",
self.getMultipartData())
dirObj = self.DirectoryObject
mdirectory = dirObj.directory
for srcDir, destDir, fileSystem, isFormat, partTable \
@ -1109,45 +1034,35 @@ class PartitionDistributive(Distributive):
parent=dirObj)
DirectoryDistributive(realDestDir, parent=partObj)
def getEfiDirectories(self):
return [path.join(self.getDirectory(), x)
for x in self.multipartition.getMountPoints()
if x.startswith("/boot/efi")
]
def getMultipartData(self):
"""Get multipartition data"""
mulipartData = list(zip(self.multipartition.getPartitions(),
mulipartData = zip(self.multipartition.getPartitions(),
self.multipartition.getMountPoints(),
self.multipartition.getFileSystems(),
self.multipartition.getIsFormat(),
self.multipartition.getPartitionTable()))
self.multipartition.getPartitionTable())
return mulipartData
def convertToDirectory(self):
"""Convert partition to directory by mounting"""
mapFS = {'btrfs-compress': 'btrfs'}
mapOpts = {'btrfs-compress': ' -o compress=%s' % self.compression}
mdirectory = self.mdirectory
for child in self.childs:
if isinstance(child, DirectoryDistributive) and \
mdirectory in child.directory:
return child
mdirectory = self._getMntDirectory(mdirectory)
self._mountPartition(self.partition, mdirectory,
mapOpts.get(self.fileSystem,""))
self._mountPartition(self.partition, mdirectory)
dirObj = DirectoryDistributive(mdirectory, parent=self)
if self.multipartition:
mulipartDataNotBind = (x for x in self.getMultipartData() if x[2] != "bind")
mulipartDataNotBind = filter(lambda x: x[2] != "bind",
self.getMultipartData())
for dev, mountPoint, fileSystem, isFormat, partTable \
in sorted(mulipartDataNotBind, key=lambda x: x[1]):
realMountPoint = None
if fileSystem != "swap":
realMountPoint = pathJoin(mdirectory, mountPoint)
self._mountPartition(
dev, realMountPoint,
"-t %s" % mapFS.get(fileSystem,fileSystem) +
mapOpts.get(fileSystem,""))
self._mountPartition(dev, realMountPoint,
"-t %s" % fileSystem)
partObj = PartitionDistributive(dev, flagRemoveDir=False,
fileSystem=fileSystem,
isFormat=isFormat,
@ -1174,13 +1089,10 @@ class PartitionDistributive(Distributive):
self.multipartition.getMountPoints() + \
["/"])
# get partition which need format
formatPartitions = [(x[FS], x[DEV], x[NEWID], x[MP]) for x
in dataPartitions if x[NEEDFORMAT] and x[FS] != "bind"]
# if has separate /boot partition
bootmp = ["/boot", "/"]
purpose_map = {"/boot": "boot",
"/var/calculate": "calculate",
"/": "root"}
formatPartitions = map(lambda x: (x[FS], x[DEV], x[NEWID], x[MP]),
filter(
lambda x: x[NEEDFORMAT] and x[FS] != "bind",
dataPartitions))
# format all get partition
for fileSystem, dev, newID, mp in formatPartitions:
if fileSystem == "swap":
@ -1190,18 +1102,17 @@ class PartitionDistributive(Distributive):
fileSystem = "uefi"
if dev == self.partition:
self.formatPartition(dev, format=fileSystem,
label=self.rootLabel,
purpose=purpose_map.get(mp, None))
label=self.rootLabel)
else:
if mp == '/var/calculate':
self.formatPartition(dev, format=fileSystem,
label="Calculate")
else:
self.formatPartition(dev, format=fileSystem,
purpose=purpose_map.get(mp, None))
self.formatPartition(dev, format=fileSystem)
# change system id for partitions
changeidPartitions = [(x[NEWID], x[DEV], x[PARTTABLE]) for x
in dataPartitions if x[NEWID]]
changeidPartitions = map(lambda x: (x[NEWID], x[DEV], x[PARTTABLE]),
filter(lambda x: x[NEWID],
dataPartitions))
for systemid, dev, partTable in changeidPartitions:
self.changeSystemID(dev, systemid, partTable)
return True
@ -1212,27 +1123,26 @@ class PartitionDistributive(Distributive):
raise DistributiveError(
_("Failed to format %s: this partition is mounted") % dev)
def formatPartition(self, dev, format="ext4", label="", purpose=None):
def formatPartition(self, dev, format="ext4", label=""):
"""Format partition"""
if not format in self.format_map:
raise DistributiveError(
_("The specified format of '%s' is not supported") % format)
with open("/proc/swaps") as f:
if dev in (x.split(" ")[0] for x in f if x.startswith("/")):
raise DistributiveError(
_("Failed to format %s: this partition is used as swap") % dev)
if dev in map(lambda y: y.split(" ")[0],
filter(lambda x: x.startswith("/"),
open("/proc/swaps"))):
raise DistributiveError(
_("Failed to format %s: this partition is used as swap") % dev)
self._checkMount(dev)
if not os.access(dev, os.W_OK):
raise DistributiveError(_("Failed to format the partition") +
" %s:\n%s" % (dev, _("Permission denied")))
format_process = self.format_map[format](dev, label=label,
purpose=purpose, compression=self.compression)
format_process = self.format_map[format](dev, label)
if format_process.failed():
raise DistributiveError(
_("Failed to format the partition") +
" %s:\n%s" % (dev, format_process.readerr()))
format_process.postaction()
def performFormat(self):
"""Perform format for all partition of this distributive"""
@ -1240,7 +1150,7 @@ class PartitionDistributive(Distributive):
self.formatAllPartitions()
elif self.isFormat:
self.formatPartition(self.partition, format=self.fileSystem,
label=self.rootLabel, purpose="root")
label=self.rootLabel)
if self.systemId:
self.changeSystemID(self.partition, self.systemId,
self.partitionTable)
@ -1255,9 +1165,9 @@ class PartitionDistributive(Distributive):
elif deviceName == "":
return True
fdiskProg, gdiskProg = checkUtils('/sbin/fdisk', '/usr/sbin/gdisk')
info = device.udev.get_device_info(name=dev)
partitionNumber = (info.get('ID_PART_ENTRY_NUMBER','') or
info.get('UDISKS_PARTITION_NUMBER', ''))
partitionNumber = \
getUdevDeviceInfo(name=dev).get('ID_PART_ENTRY_NUMBER', '') or \
getUdevDeviceInfo(name=dev).get('UDISKS_PARTITION_NUMBER', '')
devicePartitionCount = countPartitions(deviceName)
if deviceName and not partitionNumber:
raise DistributiveError(
@ -1267,22 +1177,20 @@ class PartitionDistributive(Distributive):
pipe = Popen([fdiskProg, deviceName],
stdin=PIPE, stdout=PIPE, stderr=PIPE)
if devicePartitionCount > 1:
tmp = "t\n%s\n%s\nw\n" % (partitionNumber, systemid)
pipe.stdin.write(tmp.encode("UTF-8"))
pipe.stdin.write("t\n%s\n%s\nw\n" % (partitionNumber,
systemid))
else:
tmp = "t\n%s\nw\n" % systemid
pipe.stdin.write(tmp.encode("UTF-8"))
pipe.stdin.write("t\n%s\nw\n" % systemid)
pipe.stdin.close()
pipe.wait()
elif parttable == "gpt":
pipe = Popen([gdiskProg, deviceName],
stdin=PIPE, stdout=PIPE, stderr=PIPE)
if devicePartitionCount > 1:
tmp = "t\n%s\n%s\nw\ny\n" % (partitionNumber, systemid)
pipe.stdin.write(tmp.encode("UTF-8"))
pipe.stdin.write("t\n%s\n%s\nw\ny\n" % (partitionNumber,
systemid))
else:
tmp = "t\n%s\nw\ny\n" % systemid
pipe.stdin.write(tmp.encode("UTF-8"))
pipe.stdin.write("t\n%s\nw\ny\n" % systemid)
pipe.stdin.close()
pipe.wait()
for waittime in (0.1, 0.2, 0.5, 1, 2, 4):
@ -1296,12 +1204,12 @@ class PartitionDistributive(Distributive):
def formatSwapPartition(self, dev):
"""Format swap partition"""
with open("/proc/swaps") as f:
if dev in (x.split(" ")[0] for x in f if x.startswith("/")):
raise DistributiveError(
_("Failed to execute 'mkswap %s': "
"the swap partition is used "
"by the current system") % dev)
if dev in map(lambda y: y.split(" ")[0],
filter(lambda x: x.startswith("/"),
open("/proc/swaps"))):
raise DistributiveError(
_("Failed to execute 'mkswap %s': the swap partition is used "
"by the current system") % dev)
if isMount(dev):
raise DistributiveError(
_("Failed to format %s: this partition is mounted") % dev)
@ -1360,8 +1268,6 @@ class ArchiveDistributive(Distributive):
return "gzip"
elif "7-zip archive data" in p_file.read():
return "7z"
elif "XZ compressed data" in p_file.read():
return "xz"
elif file and file.endswith(".tar.lzma"):
if path.exists('/usr/bin/7za'):
return "7z"
@ -1394,9 +1300,6 @@ class ArchiveDistributive(Distributive):
elif archiveType == "gzip":
arch_cmd = getProgPath('/bin/gzip')
params = ["-dc"]
elif archiveType == "xz":
arch_cmd = getProgPath('/bin/xz')
params = ["-dc"]
else:
raise DistributiveError(_("Unknown archive type '%s'") %
archfile)
@ -1422,7 +1325,6 @@ class ArchiveDistributive(Distributive):
def convertToDirectory(self):
"""Get archive as directory (unpack to directory)"""
# check may be the archive already unpacked
raise DistributiveError(_("Unsupported"))
mdirectory = self.mdirectory
for child in self.childs:
if isinstance(child, DirectoryDistributive) and \
@ -1473,83 +1375,6 @@ class ArchiveDistributive(Distributive):
return ld
class ContainerDistributive(ArchiveDistributive):
def __init__(self, basedir, parent=None, exclude=None,
include=None,
mdirectory="/var/calculate/tmp/stage"):
Distributive.__init__(self, parent=parent)
self.basedirectory = basedir
self.file = path.join(basedir, "rootfs.tar.xz")
self.meta = path.join(basedir, "meta.tar.xz")
self.lxd = path.join(basedir, "lxd.tar.xz")
self.exclude = [] if not exclude else exclude
self.include = [] if not include else include
self.mdirectory = mdirectory
def mtime2build(self, fn):
if path.exists(fn):
build_time = datetime.datetime.fromtimestamp(os.stat(fn).st_mtime)
return build_time.strftime("%Y%m%d")
return ""
def packToArchive(self, directory, file):
if not path.exists(self.basedirectory):
self._makeDirectory(self.basedirectory)
tar_command = getProgPath("/usr/bin/tar")
params = ["cf", file, "-J", "-C", directory]
if self.exclude:
exclude_list = list(calculate_exclude(
directory, exclude=self.exclude, include=self.include))
params += ["--exclude=./%s" % x for x in exclude_list]
params += ["."]
#debug_file = "/var/calculate/tmp/rootfs.tar.xz"
#if path.exists(debug_file):
# p = process("/bin/cp", debug_file, file)
#else:
p = process(tar_command, *params, stderr=process.STDOUT)
try:
if p.failed():
raise DistributiveError(_("Failed to create the archive") +
" '%s':\n%s" % (file, p.read()))
except BaseException:
removeDir(self.basedirectory)
raise
def get_information(self):
if path.exists(self.lxd):
with xztaropen(self.lxd) as f:
try:
metadata_yaml = f.getmember("metadata.yaml")
metadata = json.load(f.extractfile(metadata_yaml))
return {
'os_linux_build':
metadata["calculate"]['os_linux_build'],
'os_arch_machine':
metadata["calculate"]['os_arch_machine'],
'os_linux_shortname':
metadata["calculate"]['os_linux_shortname'],
'os_linux_subname':
metadata["calculate"]['os_linux_subname'],
'cl_profile_name':
metadata["calculate"]['cl_profile_name'],
'os_linux_name':
metadata["calculate"]['os_linux_name'],
'os_linux_ver':
metadata["calculate"].get('os_linux_ver', "17"),
}
except (KeyError, ValueError) as e:
pass
return {
'os_linux_build': self.mtime2build(self.file),
'os_arch_machine': "x86_64",
'os_linux_shortname': 'Container',
'os_linux_subname': "",
'cl_profile_name': "",
'os_linux_name': _('Unknown Container')
}
class SquashDistributive(Distributive):
def __init__(self, file, parent=None, mdirectory=None, exclude=None,
compress="", include=None):
@ -1602,8 +1427,7 @@ class SquashDistributive(Distributive):
if self.exclude:
exclude_list = list(calculate_exclude(directory, exclude=self.exclude,
include=self.include))
if exclude_list:
cmd += ["-e"] + exclude_list
cmd += ["-e"] + exclude_list
# возможность использовать заранее подготовленный livecd.squashfs
if path.exists('/var/calculate/tmp/livecd.squashfs'):
os.system('cp -L /var/calculate/tmp/livecd.squashfs %s' % file)
@ -1697,8 +1521,6 @@ class IsoDistributive(Distributive):
self._makeDirectory(directory)
tf = typeFile(magic=MAGIC_COMPRESS | MAGIC_SYMLINK | MAGIC_CONTINUE)
ftype = tf.getMType(file)
if ftype is None:
raise DistributiveError(_("Failed to get Mtype of the iso file"))
if "block special" in ftype:
mopts = "-o ro"
else:
@ -1888,7 +1710,7 @@ class FlashDistributive(PartitionDistributive):
clear_match = re.compile(
r"^(boot|efi|isolinux|syslinux|id.*\.uefi|"
"ldlinux.c32|ldlinux.sys|livecd|livecd.squashfs)$")
for fn in [x for x in listDirectory(dn) if clear_match.match(x)]:
for fn in filter(clear_match.match, listDirectory(dn)):
full_path = path.join(dn, fn)
try:
if path.isdir(full_path):
@ -1899,7 +1721,7 @@ class FlashDistributive(PartitionDistributive):
raise DistributiveError(
_("Failed to remove %s") % fn)
else:
super().performFormat()
super(FlashDistributive, self).performFormat()
def getType(self):
return _("USB flash %s") % self.partition
@ -1932,7 +1754,7 @@ class FlashDistributive(PartitionDistributive):
d = DirectoryDistributive(mp)
d.no_unmount = True
return d
return super().convertToDirectory()
return super(FlashDistributive, self).convertToDirectory()
def releaseChild(self, child):
"""Umount child Directory distributive"""
@ -1998,7 +1820,7 @@ class LayeredDistributive(Distributive):
:param image_file: образ оригинала
:param parent: родительский дистрибутив
"""
super().__init__(parent=parent)
super(LayeredDistributive, self).__init__(parent=parent)
self.mdirectory = mdirectory
self.diff_directory = diff_directory
self.workdir = "%s-work" % self.diff_directory
@ -2026,8 +1848,6 @@ class LayeredDistributive(Distributive):
self._makeDirectory(target)
if not path.exists(self.diff_directory):
self._makeDirectory(self.diff_directory)
if path.exists(self.workdir):
self._removeDirectory(self.workdir)
if not path.exists(self.workdir):
self._makeDirectory(self.workdir)
self._mountToDirectory("none", target, mountopts=(

@ -22,85 +22,19 @@ from calculate.lib.cl_lang import setLocalTranslate
setLocalTranslate('cl_install3', sys.modules[__name__])
class FileSystemManager():
class FileSystemManager(object):
"""Convert dict install option"""
defaultOpt = ['noatime']
defaultBindOpts = ['bind']
#Python3 compat problem:
# dict keys() now sorted based on insertion order,
# instead of being sorted arbitrary by hash.
# Just so the order of keys could be the same as
# in older version, I swaped some pairs around.
supportFS = {
'f2fs': {'defaultopt': defaultOpt,
'format': '/usr/sbin/mkfs.f2fs',
'formatparam': '{labelparam} -f {device}',
'gpt': '8300',
'label': '-l {labelname}',
'msdos': '83',
'ssd': [],
'compress': None,
'type': ['hdd', 'usb-hdd']},
'btrfs': {'defaultopt': defaultOpt,
'format': '/sbin/mkfs.btrfs',
'formatparam': '{labelparam} -f {device}',
'gpt': '8300',
'label': '-L {labelname}',
'msdos': '83',
'ssd': ['ssd'],
'type': ['hdd', 'usb-hdd'],
'compress': None,
'compatible': ['btrfs-compress']},
'ntfs-3g': {'defaultopt': defaultOpt,
'format': '/usr/sbin/mkfs.ntfs',
'formatparam': '{labelparam} -FQ {device}',
'gpt': '8300',
'label': '-L {labelname}',
'ssd': [],
'auto': False,
'msdos': '7',
'compress': None,
'compatible': ['ntfs']},
'ntfs': {'defaultopt': defaultOpt,
'format': '/usr/sbin/mkfs.ntfs',
'formatparam': '{labelparam} -FQ {device}',
'gpt': '8300',
'label': '-L {labelname}',
'msdos': '7',
'auto': False,
'ssd': [],
'compress': None,
'compatible': ['ntfs-3g']},
'xfs': {'defaultopt': defaultOpt,
'format': '/sbin/mkfs.xfs',
'formatparam': '{labelparam} -f {device}',
'gpt': '8300',
'label': '-L {labelname}',
'msdos': '83',
'boot': '-i sparce=0',
'ssd': [],
'compress': None,
'type': ['hdd', 'usb-hdd']},
'btrfs-compress': {'defaultopt': defaultOpt,
'format': '/sbin/mkfs.btrfs',
'orig': 'btrfs',
'compress': "compress=%s",
'formatparam': '{labelparam} -f {device}',
'gpt': '8300',
'label': '-L {labelname}',
'msdos': '83',
'ssd': ['ssd'],
'type': ['hdd', 'usb-hdd'],
'compatible': ['btrfs']},
'ext4': {'defaultopt': defaultOpt,
'format': '/sbin/mkfs.ext4',
'ext2': {'defaultopt': defaultOpt,
'format': '/sbin/mkfs.ext2',
'formatparam': '{labelparam} {device}',
'gpt': '8300',
'label': '-L {labelname}',
'ssd': [],
'msdos': '83',
'compress': None,
'type': ['hdd', 'usb-hdd']},
'ext3': {'defaultopt': defaultOpt,
'format': '/sbin/mkfs.ext3',
@ -109,45 +43,46 @@ class FileSystemManager():
'label': '-L {labelname}',
'ssd': [],
'msdos': '83',
'compress': None,
'type': ['hdd', 'usb-hdd']},
'ext2': {'defaultopt': defaultOpt,
'format': '/sbin/mkfs.ext2',
'ext4': {'defaultopt': defaultOpt,
'format': '/sbin/mkfs.ext4',
'formatparam': '{labelparam} {device}',
'gpt': '8300',
'label': '-L {labelname}',
'ssd': [],
'ssd': ['discard'],
'msdos': '83',
'compress': None,
'type': ['hdd', 'usb-hdd']},
'uefi': {'defaultopt': defaultOpt,
'format': '/usr/sbin/mkfs.vfat',
'formatparam': '{labelparam} -F 32 {device}',
'gpt': 'EF00',
'label': '-n {labelname}',
'msdos': '0b',
'ssd': [],
'auto': False,
'compress': None,
'type': ['hdd']},
'vfat': {'defaultopt': defaultOpt,
'format': '/usr/sbin/mkfs.vfat',
'formatparam': '{labelparam} -F 32 {device}',
'gpt': '0700',
'label': '-n {labelname}',
'msdos': '0b',
'auto': False,
'ssd': [],
'compress': None,
'type': ['flash']},
'reiserfs': {'defaultopt': defaultOpt,
'format': '/sbin/mkfs.reiserfs',
'formatparam': '{labelparam} -f {device}',
'gpt': '8300',
'label': '-l {labelname}',
'msdos': '83',
'ssd': [],
'type': ['hdd', 'usb-hdd']},
'btrfs': {'defaultopt': defaultOpt,
'format': '/sbin/mkfs.btrfs',
'formatparam': '{labelparam} -f {device}',
'gpt': '8300',
'label': '-L {labelname}',
'msdos': '83',
'ssd': ['ssd', 'discard', 'space_cache'],
'type': ['hdd', 'usb-hdd']},
'jfs': {'defaultopt': defaultOpt,
'format': '/sbin/mkfs.jfs',
'formatparam': '{labelparam} -f {device}',
'gpt': '8300',
'label': '-L {labelname}',
'msdos': '83',
'ssd': [],
'compress': None,
'ssd': ['discard'],
'type': ['hdd', 'usb-hdd']},
'xfs': {'defaultopt': defaultOpt,
'format': '/sbin/mkfs.xfs',
'formatparam': '{labelparam} -f {device}',
'gpt': '8300',
'label': '-L {labelname}',
'msdos': '83',
'ssd': ['discard'],
'type': ['hdd', 'usb-hdd']},
# 'nilfs2': {'defaultopt': defaultOpt,
# 'format': '/sbin/mkfs.nilfs2',
@ -163,15 +98,41 @@ class FileSystemManager():
'gpt': '8200',
'label': '',
'ssd': [],
'auto': False,
'compress': None,
'msdos': '82'},
}
'uefi': {'defaultopt': defaultOpt,
'format': '/usr/sbin/mkfs.vfat',
'formatparam': '{labelparam} -F 32 {device}',
'gpt': 'EF00',
'label': '-n {labelname}',
'msdos': '0b',
'ssd': [],
'type': ['hdd']},
'vfat': {'defaultopt': defaultOpt,
'format': '/usr/sbin/mkfs.vfat',
'formatparam': '{labelparam} -F 32 {device}',
'gpt': '0700',
'label': '-n {labelname}',
'msdos': '0b',
'ssd': ['discard'],
'type': ['flash']},
'ntfs': {'defaultopt': defaultOpt,
'format': '/usr/sbin/mkfs.ntfs',
'formatparam': '{labelparam} -FQ {device}',
'gpt': '8300',
'label': '-L {labelname}',
'msdos': '7',
'ssd': [],
'compatible': ['ntfs-3g']},
'ntfs-3g': {'defaultopt': defaultOpt,
'format': '/usr/sbin/mkfs.ntfs',
'formatparam': '{labelparam} -FQ {device}',
'gpt': '8300',
'label': '-L {labelname}',
'ssd': [],
'msdos': '7',
'compatible': ['ntfs']}}
default_param = {'defaultopt': defaultOpt,
'gpt': '8300',
'msdos': '83',
'compress': None,
'ssd': []}
@classmethod
@ -182,27 +143,29 @@ class FileSystemManager():
else:
return ""
@classmethod
def get_default_fs(cls, dv, installtype):
if installtype == 'flash':
return 'vfat'
filesystems = dv.Get('install.cl_install_fs')
for fs in filesystems:
if fs in cls.supportFS and path.exists(cls.supportFS[fs]['format']):
return fs
return 'ext3'
defaultFS = {
'hdd': ("ext4"
if path.exists(supportFS['ext4']['format']) else
"reiserfs"
if path.exists(supportFS['reiserfs']['format']) else
"ext3"),
'flash': "vfat",
'usb-hdd': ("ext4"
if path.exists(supportFS['ext4']['format']) else
"reiserfs"
if path.exists(supportFS['reiserfs']['format']) else
"ext3")
}
@classmethod
def getDefaultOpt(cls, fs, ssd=False, compress=None):
fsopts = cls.supportFS.get(fs, cls.default_param)
return ",".join(fsopts['defaultopt'] +
(fsopts['ssd'] if ssd else []) +
([fsopts['compress'] % compress]
if fsopts['compress'] and compress else []))
def getDefaultOpt(cls, fs, ssd=False):
return ",".join(cls.supportFS.get(fs, cls.default_param)['defaultopt'] +
(cls.supportFS.get(fs, cls.default_param)['ssd']
if ssd else []))
@classmethod
def checkFSForTypeMount(cls, fs, roottype, mp):
if mp.startswith('/boot/efi'):
if mp == '/boot/efi':
if fs not in ('uefi', 'vfat'):
return False
else:

@ -25,31 +25,26 @@ import glob
import shutil
from time import sleep
from calculate.core.server.func import MethodsInterface
from calculate.core.server.admin import Admins
from calculate.lib.utils.mount import isMount
from calculate.lib.utils.system import SystemPath
from calculate.lib.utils.files import (pathJoin,
process, listDirectory, writeFile,
isMount, process, listDirectory,
checkUtils, readFile, find, copyWithPath,
readLinesFile, getProgPath)
from collections import deque
import calculate.lib.utils.device as device
from calculate.lib.utils.device import (detectDeviceForPartition,
countPartitions)
from calculate.lib.utils.partition import DiskFactory
from .datavars import DataVarsInstall
getUdevDeviceInfo, refreshLVM,
refreshUdev, countPartitions)
from datavars import DataVarsInstall
from calculate.install.variables.autopartition import AutoPartition
from .distr import DistributiveError, PartitionDistributive
from distr import DistributiveError
from subprocess import Popen, PIPE, STDOUT
from itertools import *
from calculate.lib.utils.tools import traverse
class InstallError(Exception):
"""Installation Error"""
from .migrate_users import migrate
from migrate_users import migrate
from calculate.lib.cl_lang import setLocalTranslate, getLazyLocalTranslate, _
@ -63,9 +58,9 @@ class Install(MethodsInterface):
def __init__(self):
self.clVars = None
# refresh information about LVM
device.lvm.refresh()
refreshLVM()
# refresh information about device in udevadm info
device.udev.refresh()
refreshUdev()
def initVars(self, datavars=None):
"""Primary initialization of variables"""
@ -79,8 +74,10 @@ class Install(MethodsInterface):
def canInstallGrub2(self, target):
"""Check that system has grub2 in current and installed system"""
if self.clVars.Get('os_grub2_path'):
return bool([x for x in listDirectory('/var/db/pkg/sys-boot')
if (x.startswith('grub-1.99') or x.startswith('grub-2'))])
return bool(
filter(lambda x: (x.startswith('grub-1.99') or
x.startswith('grub-2')),
listDirectory('/var/db/pkg/sys-boot')))
return False
def prepareBoot(self, target_distr):
@ -115,10 +112,10 @@ class Install(MethodsInterface):
partition_table = self.clVars.Select('os_device_table',
where='os_device_dev',
eq=disk, limit=1)
info = device.udev.get_device_info(name=partition)
partition_number = (
info.get('ID_PART_ENTRY_NUMBER', '') or
info.get('UDISKS_PARTITION_NUMBER', ''))
getUdevDeviceInfo(name=partition).get('ID_PART_ENTRY_NUMBER', '') or
getUdevDeviceInfo(name=partition).get('UDISKS_PARTITION_NUMBER', '')
)
device_partition_count = countPartitions(device_name)
if device_name and not partition_number:
@ -129,78 +126,56 @@ class Install(MethodsInterface):
if partition_table == "dos":
fdisk = process(fdisk_cmd, "-l", device_name)
DEVICENUM, AFLAG = 0, 1
# change_active = map(
# lambda x: x[DEVICENUM],
# filter(
# lambda x: (x[DEVICENUM] != partition_number and
# x[AFLAG] == "*" or
# x[DEVICENUM] == partition_number and
# not x[AFLAG] == "*"),
# list(map(
# lambda x: [str(x[0]), x[1][1].strip()],
# # enumerate partitions
# enumerate(filter(None, map(
# lambda x: x.split()[:2],
# # drop string before information about partitions
# dropwhile(
# lambda x: not x.lstrip().startswith(
# "Device"),
# fdisk.readlines()))))))[1:]))
change_active = [x[DEVICENUM] for x
in [[str(y[0]), y[1][1].strip()] for y
in enumerate([z for z
in [o.split()[:2] for o
in dropwhile(lambda x: not x.lstrip().startswith("Device"),fdisk.readlines())]
if z])][1:]
if x[DEVICENUM] != partition_number and
x[AFLAG] == "*" or
x[DEVICENUM] == partition_number and
not x[AFLAG] == "*"]
change_active = map(
lambda x: x[DEVICENUM],
filter(
lambda x: (x[DEVICENUM] != partition_number and
x[AFLAG] == "*" or
x[DEVICENUM] == partition_number and
not x[AFLAG] == "*"),
list(map(
lambda x: [str(x[0]), x[1][1].strip()],
# enumerate partitions
enumerate(filter(None, map(
lambda x: x.split()[:2],
# drop string before information about partitions
dropwhile(
lambda x: not x.lstrip().startswith(
"Device"),
fdisk.readlines()))))))[1:]))
else:
parted = process(parted_cmd, "-m", device_name, "print")
DEVICENUM, FLAGS = 0, 6
# change_active = map(
# lambda x: x[DEVICENUM], filter(
# lambda x: (x[DEVICENUM] != partition_number and
# boot_flag in x[FLAGS].strip(';').split(', ') or
# x[DEVICENUM] == partition_number and
# boot_flag not in
# x[FLAGS].strip(';').split(', ')),
# filter(lambda x: len(x) >= 7,
# map(lambda x: x.split(':'),
# parted.readlines()[2:]))))
change_active = [x[DEVICENUM] for x
in [y for y
in [z.split(':') for z
in parted.readlines()[2:]]
if len(y) >= 7]
if x[DEVICENUM] != partition_number and
boot_flag in x[FLAGS].strip(';').split(', ') or
x[DEVICENUM] == partition_number and
boot_flag not in
x[FLAGS].strip(';').split(', ')]
change_active = map(
lambda x: x[DEVICENUM], filter(
lambda x: (x[DEVICENUM] != partition_number and
boot_flag in x[FLAGS].strip(';').split(', ') or
x[DEVICENUM] == partition_number and
boot_flag not in
x[FLAGS].strip(';').split(', ')),
filter(lambda x: len(x) >= 7,
map(lambda x: x.split(':'),
parted.readlines()[2:]))))
if not change_active:
return True
if partition_table == "dos":
pipe = Popen([fdisk_cmd, device_name],
stdin=PIPE, stdout=PIPE, stderr=PIPE)
for part_num in change_active:
write_str = "a\n%s\n" % part_num
pipe.stdin.write(write_str.encode("UTF-8"))
pipe.stdin.write(b"w\n")
pipe.stdin.write("a\n%s\n" % part_num)
pipe.stdin.write("w\n")
pipe.stdin.close()
pipe.wait()
elif partition_table == "gpt":
pipe = Popen([gdisk_cmd, device_name],
stdin=PIPE, stdout=PIPE, stderr=PIPE)
if device_partition_count > 1:
pipe.stdin.write(b"x\n")
pipe.stdin.write("x\n")
for part_num in change_active:
write_str = "a\n%s\n2\n\n" % part_num
pipe.stdin.write(write_str.encode("UTF-8"))
pipe.stdin.write(b"w\nY\n")
pipe.stdin.write("a\n%s\n2\n\n" % part_num)
pipe.stdin.write("w\nY\n")
else:
pipe.stdin.write(b"x\na\n2\n\nw\nY\n")
pipe.stdin.write("x\na\n2\n\nw\nY\n")
pipe.stdin.close()
pipe.wait()
for wait_time in (0.1, 0.2, 0.5, 1, 2, 4):
@ -226,17 +201,14 @@ class Install(MethodsInterface):
raise DistributiveError(
_("Failed to write the master boot record\n%s") %
dd_process.read())
target.close()
# выполнить установку syslinux загрузчика
install_root_dev = self.clVars.Get('os_install_root_dev')
mount_path = target.convertToDirectory()
syslinux_process = process("/usr/bin/extlinux", '--install',
mount_path.directory, stderr=STDOUT)
syslinux_process = process("/usr/bin/syslinux",
install_root_dev, stderr=STDOUT)
if syslinux_process.failed():
raise DistributiveError(_("Failed to install syslinux\n%s") %
syslinux_process.read())
target.close()
# выполнить установку syslinux загрузчика
# установить загрузочный раздел активным
return self.setActivePartition(self.clVars.Get('os_install_root_dev'))
@ -261,11 +233,6 @@ class Install(MethodsInterface):
self.install_grub_uefi(cmd_grub_install, prefix_boot, target)
# не UEFI установка
else:
# необходимо удалить запись /boot/efi из текущей системы
# при выполнении cl-setup-boot --mbr
if self.clVars.Get('os_uefi'):
self.update_efi_fstab()
self.mount_efi_fstab()
self.install_grub_biosboot(cmd_grub_install, prefix_boot, target)
def install_grub_biosboot(self, cmd_grub_install, prefix_boot, target):
@ -282,204 +249,59 @@ class Install(MethodsInterface):
self.setActivePartition(boot_disk)
break
chroot_cmd = getProgPath('/usr/bin/chroot')
chroot_dn = target.getDirectory()
if chroot_dn == '/':
chrooting = []
else:
chrooting = [chroot_cmd, chroot_dn]
# если GRUB2 версии 2.00 и выше, обычная установка требует
# параметра --target=i386-pc, иначе GRUB2 может попытаться
# прописать себя как UEFI
if [x for x
in process(*traverse([chrooting, cmd_grub_install, '--version']))
if "2." in x]:
if filter(lambda x: "2." in x,
process(cmd_grub_install, '--version')):
platform = ["--target=i386-pc"]
else:
platform = []
# прописать GRUB2 на все указанные диски
targetdir = target.convertToDirectory()
if not targetdir.hasSystemDirectories():
targetdir.mountSystemDirectories()
try:
for mbr_disk in self.clVars.Get('os_install_mbr'):
grub_process = process(
*traverse([chrooting,
cmd_grub_install,
"--boot-directory=/%s" % path.relpath(target.getBootDirectory(),
chroot_dn),
mbr_disk, "--force",platform]),
stderr=STDOUT, envdict=os.environ)
if grub_process.failed():
raise DistributiveError(
_("Failed to install the bootloader"))
finally:
if targetdir.system_mounted:
targetdir.umountSystemDirectories()
def update_efi_fstab(self):
"""
Обновляем (или удаляем) запись /boot/efi в текущем /etc/fstab
Удаление используется в случае, если выполняется обновление загрузчика
в не EFI системе, хотя до этого она была установлена как EFI
"""
fstab_fn = pathJoin(self.clVars.Get('cl_chroot_path'), "/etc/fstab")
re_efi_record = re.compile("^(# /boot/efi|\S+\s/boot/efi).*\n",
flags=re.M)
efidata = self.clVars.Get('os_install_fstab_efi_conf')
if path.exists(fstab_fn):
data = readFile(fstab_fn)
m = re_efi_record.search(data)
newdata = re_efi_record.sub("", data)
if efidata:
if m:
newdata = "%s%s\n%s" % (newdata[:m.start()],
efidata, newdata[m.start():])
else:
newdata = "%s%s\n" % (newdata, efidata)
if data != newdata:
with writeFile(fstab_fn) as f:
f.write(newdata)
def format_efi(self):
formatdisk = [(dev, fs)
for dev, mp, fs, make in self.clVars.ZipVars(
'os_install_disk_dev',
'os_install_disk_mount',
'os_install_disk_format',
'os_install_disk_perform_format')
if mp.startswith('/boot/efi') and make == 'on'
]
if formatdisk:
self.startTask(_("Formatting the partitions"), progress=True,
num=len(formatdisk))
i = 1
for dev, fs in formatdisk:
self.formatPartition(dev, format="vfat")
self.setProgress(i)
i += 1
self.endTask(True)
def umountDirectory(self, directory):
return PartitionDistributive(None)._umountDirectory(directory)
def makeDirectory(self, directory):
return PartitionDistributive(None)._makeDirectory(directory)
def mountToDirectory(self, dev, mp):
return PartitionDistributive(None)._mountToDirectory(dev, mp)
def formatPartition(self, dev, format="ext4", label=""):
return PartitionDistributive(None).formatPartition(dev, format, label)
def mount_efi_fstab(self):
"""
Подключить /boot/efi (или отключить) согласно новым данным
Используется как для подключения /boot/efi, так и для отключения.
"""
oldmp_efi = self.clVars.select('os_disk_mount',
os_disk_mount__startswith="/boot/efi")
for dev, mp in self.clVars.ZipVars('os_install_disk_dev',
'os_install_disk_mount'):
if mp.startswith("/boot/efi"):
curdev = isMount(mp)
if curdev != dev:
if curdev:
self.umountDirectory(mp)
self.makeDirectory(mp)
self.mountToDirectory(dev, mp)
if mp in oldmp_efi:
oldmp_efi.remove(mp)
for mp in oldmp_efi:
self.umountDirectory(mp)
for mbr_disk in self.clVars.Get('os_install_mbr'):
grub_process = process(cmd_grub_install,
"--boot-directory=%s" % pathJoin(
prefix_boot,
target.getBootDirectory()),
mbr_disk, "--force", *platform,
stderr=STDOUT, envdict=os.environ)
if grub_process.failed():
raise DistributiveError(
_("Failed to install the bootloader"))
def install_grub_uefi(self, cmd_grub_install, prefix_boot, target):
if self.clVars.Get('cl_action') != "system":
self.format_efi()
self.update_efi_fstab()
self.mount_efi_fstab()
efidirs = [x for x in self.clVars.Get('os_install_disk_mount')
if x.startswith('/boot/efi')]
if len(efidirs) > 1:
labels = ["calculate%d" % i for i in range(1, len(efidirs) + 1)]
else:
labels = ["calculate"]
for efiname, efidir in reversed(list(zip(labels, efidirs))):
self._install_grub_uefi(cmd_grub_install, prefix_boot, target,
efidir, efiname)
# удаляем устаревшие
efi_boot_mgr = getProgPath('/usr/sbin/efibootmgr')
p_efibootmgr = process(efi_boot_mgr, "-v")
data = p_efibootmgr.read()
for num, label in re.findall(r"Boot(\d+).*(calculate\d*)", data):
if label not in labels:
process(efi_boot_mgr, "-b", num, "-B").success()
def _install_grub_uefi(
self, cmd_grub_install, prefix_boot, target, efidir, efiname):
"""
Установить grub с UEFI загрузчиком
"""
chroot_cmd = getProgPath('/usr/bin/chroot')
chroot_dn = target.getDirectory()
if chroot_dn == '/':
chrooting = []
else:
chrooting = [chroot_cmd, chroot_dn]
grub_params = [
"--boot-directory=/%s" % path.relpath(target.getBootDirectory(),
chroot_dn),
"--bootloader-id=%s" % efiname,
"--boot-directory=%s" % pathJoin(
prefix_boot,
target.getBootDirectory()),
"--target=x86_64-efi",
"--efi-directory=%s" % efidir,
"--efi-directory=%s" %
target.getEfiDirectory(),
"--force"]
# проверяем наличие в nv-ram нужной нам записи для исключения повтора
efi_boot_mgr = getProgPath('/usr/sbin/efibootmgr')
efi_disk = self.clVars.Select("os_install_disk_dev",
where="os_install_disk_mount",
eq=efidir, limit=1)
if efi_disk:
efi_uuid = device.udev.get_device_info(
name=efi_disk).get("ID_PART_ENTRY_UUID", "")
if efi_uuid:
p_efibootmgr = process(efi_boot_mgr, "-v")
data = p_efibootmgr.read()
if re.search(r"Boot.*{label}\s.*GPT,{uuid}.*{efipath}".format(
label=efiname,
uuid=efi_uuid,
efipath=r"\\EFI\\%s\\grubx64.efi" % efiname),
data, flags=re.M | re.I):
grub_params.append("--no-nvram")
# в случае установки на usb-hdd EFI загрузчик не прописывается
# в efivars
if self.clVars.Get('os_install_root_type') == 'usb-hdd':
grub_params.append("--removable")
targetdir = target.convertToDirectory()
if not targetdir.hasSystemDirectories():
targetdir.mountSystemDirectories()
try:
grub_process = process(
*traverse([
chrooting,
cmd_grub_install,
grub_params]), stderr=STDOUT,
envdict=os.environ)
if grub_process.failed():
raise DistributiveError(_("Failed to install the bootloader"))
finally:
if targetdir.system_mounted:
targetdir.umountSystemDirectories()
if self.clVars.Get('cl_action') != "system" and \
not isMount('/boot/efi'):
raise DistributiveError(_("Failed to install the bootloader. "
"/boot/efi is not mounted."))
grub_process = process(cmd_grub_install,
*grub_params, stderr=STDOUT,
envdict=os.environ)
if grub_process.failed():
raise DistributiveError(_("Failed to install the bootloader"))
# проверяем успешность создания загрузочной записи
# если среди загрузочных записей отсутствует запись
# calculate и dmesg содержит сообщение об ошибке efivars -
# запись создать не удалось
efi_boot_mgr = getProgPath('/usr/sbin/efibootmgr')
dmesg = getProgPath('/bin/dmesg')
if efi_boot_mgr and dmesg:
if not re.search('Boot.*%s\s' % efiname,
if not re.search('Boot.*calculate',
process(efi_boot_mgr).read(), re.M) and \
re.search('efivars.*set_variable.*failed',
process(dmesg).read(), re.M):
@ -519,6 +341,40 @@ class Install(MethodsInterface):
if grub_process.failed():
raise DistributiveError(_("Failed to install the bootloader"))
def setupOpenGL(self):
"""
Выполнить выбор opengl для текущего видеодрайвера
"""
default_gl = "xorg-x11"
path_gl_modules = path.join(self.clVars.Get('cl_chroot_path'),
'usr/lib/opengl')
open_gl_env = path.join(self.clVars.Get('cl_chroot_path'),
'etc/env.d/03opengl')
open_gl_mods = filter(lambda x: x != "global",
listDirectory(path_gl_modules))
map_gl_drivers = {'fglrx': ("ati" if "ati" in open_gl_mods
else default_gl),
'nvidia': "nvidia" if "nvidia" in open_gl_mods
else default_gl}
x11_driver = self.clVars.Get('os_install_x11_video_drv')
if x11_driver in map_gl_drivers:
new_module_name = map_gl_drivers[x11_driver]
else:
new_module_name = default_gl
current_module_name = map(
lambda x: x.strip().rpartition('=')[-1].strip('"\''),
filter(lambda x: x.startswith("OPENGL_PROFILE="),
readLinesFile(open_gl_env)))
if current_module_name:
current_module_name = current_module_name[-1]
else:
current_module_name = ""
if current_module_name == new_module_name:
return True
return process('/usr/bin/eselect', 'opengl', 'set',
new_module_name).success()
def checkVideoDriver(self):
"""
Проверить видео драйвер, и если это nvidia, то
@ -531,14 +387,13 @@ class Install(MethodsInterface):
# если package.mask является файлом - делаем его директорией
if path.isfile(mask_file):
os.rename(mask_file, mask_file + "2")
os.mkdir(mask_file, mode=0o755)
os.mkdir(mask_file, mode=0755)
os.rename(mask_file + "2", path.join(mask_file, "default"))
current_nvidia_mask = readFile(nvidia_mask_file).strip()
new_nvidia_mask = self.clVars.Get('os_nvidia_mask')
if new_nvidia_mask == current_nvidia_mask:
return True
with open(nvidia_mask_file, 'w') as f:
f.write(new_nvidia_mask)
open(nvidia_mask_file, 'w').write(new_nvidia_mask)
return True
def changeScheduler(self, scheduler):
@ -549,89 +404,28 @@ class Install(MethodsInterface):
where='os_disk_mount',
eq='/', limit=1)
try:
sysname = device.udev.get_syspath(name=root_dev)
if device.sysfs.exists(sysname, device.sysfs.Path.BlockScheduler):
device.sysfs.write(
sysname, device.sysfs.Path.BlockScheduler, scheduler)
scheduler_path = (
"/sys%s/queue/scheduler" %
(getUdevDeviceInfo(name=root_dev).get('DEVPATH', '')))
if path.exists(scheduler_path):
open(scheduler_path, 'w').write(scheduler)
except Exception:
raise InstallError(_("Unable to change the I/O scheduler"))
return True
def clearLvm(self, devices):
dv = self.clVars
def get_vgs():
for pv, vg, pvbase in dv.ZipVars('os_lvm_pvname',
'os_lvm_vgname',
'os_lvm_pvname_parent'):
if (pv in devices or
any(x in devices for x in pvbase.split(','))):
yield vg
remove_vgs = set(get_vgs())
remove_pvs = set(self.clVars.select('os_lvm_pvname',
os_lvm_vgname__in=remove_vgs))
remove_lvs = set(self.clVars.select('os_lvm_vgname', 'os_lvm_lvname',
os_lvm_vgname__in=remove_vgs))
failed = False
for vg, lv in sorted(remove_lvs):
failed |= not device.lvm.remove_lv(vg, lv)
for vg in sorted(remove_vgs):
failed |= not device.lvm.remove_vg(vg)
for pv in sorted(remove_pvs):
failed |= not device.lvm.remove_pv(pv)
return not failed
def clearRaid(self, devices):
dv = self.clVars
def generate_remove_raids():
for raid, parents in dv.select('os_device_dev', 'os_device_parent',
os_device_type__startswith="raid"):
parents = parents.split(',')
if any(x in devices for x in parents):
yield raid, set(parents)
remove_raids = deque(generate_remove_raids())
failed = False
while remove_raids:
raid, parents = remove_raids.popleft()
# если среди прочих удаляемых RAID есть те, которые используют
# текущий - откладываем его в конец
if any(raid in _parents for _raid, _parents in remove_raids):
remove_raids.append((raid, parents))
else:
failed |= not device.raid.remove_raid(raid)
return not failed
def wait_devices(self, disks):
def autopartition(self, table, devices, data, lvm, lvm_vgname, bios_grub,
bios_grub_size):
"""
Ожидание одного из указанных устройств
Авторазметка диска с таблицей разделов 'table', диски указываются
'device', параметры таблицы 'data', 'lvm' использование LVM,
'lvm_vgname' название группы томов LVM, bios_grub - создавать
bios_grub раздел, bios_grub_size - раздел bios grub раздела в байтах
"""
for waittime in (0.1, 0.2, 0.5, 1, 2, 4):
disks = [x for x in disks if x and not path.exists(x)]
if not disks:
break
else:
sleep(waittime)
if disks:
raise InstallError(
_("Failed to found partition %s after creating "
"the partition table")
% ",".join(disks))
def autopartition(self, scheme_builder, devices, disks):
"""
Авторазметка диска входящая переменная - SchemeBuilder
"""
self.clearLvm(devices)
self.clearRaid(devices)
scheme_builder.process(DiskFactory())
self.wait_devices(disks)
ap = AutoPartition()
ap.clearLvm(devices, self.clVars)
ap.clearRaid(devices, self.clVars)
ap.recreateSpace(table, devices, data, lvm,
lvm_vgname, bios_grub, bios_grub_size)
return True
def format(self, target):
@ -661,10 +455,10 @@ class Install(MethodsInterface):
"""
target_dir = target.getDirectory()
source_dir = source.getDirectory()
for f in (x for x
in chain(*[find(pathJoin(source_dir, y), filetype="f") for y
in cltpath])
if x.endswith('.clt')):
for f in filter(lambda x: x.endswith('.clt'),
chain(*map(lambda x: find(pathJoin(source_dir, x),
filetype="f"),
cltpath))):
copyWithPath(f, target_dir, prefix=source_dir)
return True
@ -672,14 +466,14 @@ class Install(MethodsInterface):
"""
Скопировать прочие настройки из текущей системы в новую
"""
file_mask = re.compile("(/etc/ssh/ssh_host_.*|/etc/machine-id|"
"/root/.ssh/(id_.*|known_hosts))(?!\.old)")
file_mask = re.compile("(/etc/ssh/ssh_host_.*|"
"/root/.ssh/(id_.*|known_hosts))")
target_dir = target.getDirectory()
source_dir = source.getDirectory()
for f in (x for x
in chain(*(find(pathJoin(source_dir, y), filetype="f") for y
in ["/etc", "/root/.ssh"]))
if file_mask.search(x)):
for f in filter(file_mask.search,
chain(*map(lambda x: find(pathJoin(source_dir, x),
filetype="f"),
["/etc", "/root/.ssh"]))):
copyWithPath(f, target_dir, prefix=source_dir)
return True
@ -689,7 +483,7 @@ class Install(MethodsInterface):
"""
"""Get random string with len 8 char"""
return "".join([choice(string.ascii_letters + string.digits)
for i in range(0, 8)])
for i in xrange(0, 8)])
def _getFreeDirectory(self, directory):
"""
@ -741,9 +535,7 @@ class Install(MethodsInterface):
установка пароля пользователя root
"""
migrator = migrate(target.getDirectory())
if not migrator.migrate([[x[0],x[2],x[3]] for x in migrate_data if x],
root_pwd, [], [], ):
if not migrator.migrate(migrate_data, root_pwd, [], [], ):
raise InstallError(_("Failed to migrate users onto the new system"))
return True
@ -764,25 +556,3 @@ class Install(MethodsInterface):
os.unlink(new_name)
shutil.move(fn, new_name)
return True
def update_admin_ini(self):
"""
Обновить список локальных администраторов при установке
"""
aliases = {
'update': 'system_update',
}
install_admin = Admins(self.clVars, chroot=True)
install_admin.clear()
for k,v in self.clVars.select('install.cl_migrate_user',
'install.cl_migrate_admin',
install_cl_migrate_admin__ne=""):
install_admin[k] = aliases.get(v,v)
install_admin.save()
return True
def init_themes(self):
self.clVars.Get('cl_splash_image_hash')
self.clVars.Get('cl_grub_image_hash')
return True

@ -17,10 +17,9 @@
import os, sys, re, time
from calculate.lib.encrypt import encrypt
from os import path
from calculate.lib.utils.files import pathJoin, FilePermission
from calculate.lib.utils.files import pathJoin
from calculate.lib.cl_lang import setLocalTranslate, _
from functools import reduce
setLocalTranslate('cl_install3', sys.modules[__name__])
@ -29,17 +28,16 @@ class MigrationError(Exception):
pass
class _shareData():
class _shareData(object):
"""Share class"""
_reNumb = re.compile("^\d+$")
def getDataInFile(self, fileName='', lenData=7):
"""Get data list from file"""
with open(fileName) as f:
return [x[:lenData] for x
in (y.rstrip().split(":") for y
in f)
if len(x) >= lenData]
return map(lambda x: x[:lenData],
filter(lambda x: len(x) >= lenData,
map(lambda x: x.rstrip().split(":"),
open(fileName))))
class migrateGroups(_shareData):
@ -59,39 +57,46 @@ class migrateGroups(_shareData):
def getThisData(self):
"""Get data migrate groups in this system"""
return [x for x in self.getData()
if self._reNumb.match(x[2]) and self.minGid <= int(x[2]) <= self.maxGid]
return filter(lambda x: \
self._reNumb.match(x[2]) and self.minGid <= int(
x[2]) <= self.maxGid,
self.getData())
def getNewData(self):
"""Get data migrate groups in new system"""
fileName = pathJoin(self.prefixNewSystem, self.fileGroups)
return [x for x in self.getData(fileName=fileName)
if self._reNumb.match(x[2]) and self.minGid <= int(x[2]) <= self.maxGid]
return filter(lambda x: \
self._reNumb.match(x[2]) and self.minGid <= int(
x[2]) <= self.maxGid,
self.getData(fileName=fileName))
def getNewDataSystemGroups(self):
"""Get data system groups in new system"""
fileName = pathJoin(self.prefixNewSystem, self.fileGroups)
return [x for x in self.getData(fileName=fileName)
if self._reNumb.match(x[2]) and (int(x[2]) > self.maxGid or int(x[2]) < self.minGid)]
return filter(lambda x: \
self._reNumb.match(x[2]) and \
(int(x[2]) > self.maxGid or int(x[2]) < self.minGid),
self.getData(fileName=fileName))
def getNewProcessedData(self):
"""Get processed data migrate groups in new system"""
# data this Group no users
dataThisGroupsNoUsers = [x[:3] + [""] for x in self.getThisData()]
dataThisGroupsNoUsers = map(lambda x: x[:3] + [""], self.getThisData())
dataNewGroups = self.getNewData()
namesNewGroups = [x[0] for x in dataNewGroups]
gidsNewGroups = [x[2] for x in dataNewGroups]
namesNewGroups = map(lambda x: x[0], dataNewGroups)
gidsNewGroups = map(lambda x: x[2], dataNewGroups)
for data in dataThisGroupsNoUsers:
nameGroup = data[0]
gid = data[2]
if nameGroup in namesNewGroups:
dataNewGroups = [x for x in dataNewGroups if x[0] != nameGroup]
namesNewGroups = [x[0] for x in dataNewGroups]
gidsNewGroups = [x[2] for x in dataNewGroups]
dataNewGroups = filter(lambda x: x[0] != nameGroup,
dataNewGroups)
namesNewGroups = map(lambda x: x[0], dataNewGroups)
gidsNewGroups = map(lambda x: x[2], dataNewGroups)
if gid in gidsNewGroups:
dataNewGroups = [x for x in dataNewGroups if x[2] != gid]
namesNewGroups = [x[0] for x in dataNewGroups]
gidsNewGroups = [x[2] for x in dataNewGroups]
dataNewGroups = filter(lambda x: x[2] != gid, dataNewGroups)
namesNewGroups = map(lambda x: x[0], dataNewGroups)
gidsNewGroups = map(lambda x: x[2], dataNewGroups)
systemGroupsNewData = self.getNewDataSystemGroups()
return systemGroupsNewData, dataNewGroups, dataThisGroupsNoUsers
@ -113,67 +118,81 @@ class migrateUsers(_shareData):
def getThisData(self):
"""Get data migrate users in this system"""
return [x for x in self.getData()
if self._reNumb.match(x[2]) and self.minId <= int(x[2]) <= self.maxId]
return filter(lambda x: \
self._reNumb.match(x[2]) and self.minId <= int(
x[2]) <= self.maxId,
self.getData())
def getNewData(self):
"""Get data migrate users in new system"""
fileName = pathJoin(self.prefixNewSystem, self.filePasswd)
return [x for x in self.getData(fileName=fileName)
if self._reNumb.match(x[2]) and self.minId <= int(x[2]) <= self.maxId]
return filter(lambda x: \
self._reNumb.match(x[2]) and self.minId <= int(
x[2]) <= self.maxId,
self.getData(fileName=fileName))
def getNewDataSystemUsers(self):
"""Get data system users in new system"""
fileName = pathJoin(self.prefixNewSystem, self.filePasswd)
return [x for x in self.getData(fileName=fileName)
if self._reNumb.match(x[2]) and (int(x[2]) > self.maxId or int(x[2]) < self.minId)]
return filter(lambda x: \
self._reNumb.match(x[2]) and \
(int(x[2] > self.maxId) or int(x[2]) < self.minId),
self.getData(fileName=fileName))
def getThisDataSystemUsers(self):
"""Get data system users in this system"""
fileName = self.filePasswd
return [x for x in self.getData(fileName=fileName)
if self._reNumb.match(x[2]) and (int(x[2]) > self.maxId or int(x[2]) < self.minId)]
return filter(lambda x: \
self._reNumb.match(x[2]) and \
(int(x[2] > self.maxId) or int(x[2]) < self.minId),
self.getData(fileName=fileName))
def getNewProcessedData(self, migrateUsers=()):
"""Get processed data migrate users in new system"""
dataThisUsers = self.getThisData()
if migrateUsers:
dataThisUsers = [x for x in dataThisUsers if x[0] in migrateUsers]
dataThisUsers = filter(lambda x: x[0] in migrateUsers,
dataThisUsers)
dataNewUsers = self.getNewData()
namesNewUsers = [x[0] for x in dataNewUsers]
uidsNewUsers = [x[2] for x in dataNewUsers]
namesNewUsers = map(lambda x: x[0], dataNewUsers)
uidsNewUsers = map(lambda x: x[2], dataNewUsers)
for data in dataThisUsers:
nameUser = data[0]
uid = data[2]
if nameUser in namesNewUsers:
dataNewUsers = [x for x in dataNewUsers if x[0] != nameUser]
namesNewUsers = [x[0] for x in dataNewUsers]
uidsNewUsers = [x[2] for x in dataNewUsers]
dataNewUsers = filter(lambda x: x[0] != nameUser, dataNewUsers)
namesNewUsers = map(lambda x: x[0], dataNewUsers)
uidsNewUsers = map(lambda x: x[2], dataNewUsers)
if uid in uidsNewUsers:
dataNewUsers = [x for x in dataNewUsers if x[2] != uid]
namesNewUsers = [x[0] for x in dataNewUsers]
uidsNewUsers = [x[2] for x in dataNewUsers]
dataNewUsers = filter(lambda x: x[2] != uid, dataNewUsers)
namesNewUsers = map(lambda x: x[0], dataNewUsers)
uidsNewUsers = map(lambda x: x[2], dataNewUsers)
systemUsersNewData = self.getNewDataSystemUsers()
systemUsersNewNames = [x[0] for x in systemUsersNewData]
systemUsersNewUids = [x[2] for x in systemUsersNewData]
systemUsersNewNames = map(lambda x: x[0], systemUsersNewData)
systemUsersNewUids = map(lambda x: x[2], systemUsersNewData)
systemUsersThisData = []
if migrateUsers:
# this users < minId
systemUsersThisData = [x for x in self.getThisDataSystemUsers()
if int(x[2]) < self.minId and x[0] in migrateUsers]
systemUsersThisData = filter(lambda x: int(x[2]) < self.minId and \
x[0] in migrateUsers,
self.getThisDataSystemUsers())
for data in systemUsersThisData:
nameUser = data[0]
uid = data[2]
if nameUser in systemUsersNewNames:
systemUsersNewData = [x for x in systemUsersNewData
if x[0] != nameUser]
systemUsersNewNames = [x[0] for x in systemUsersNewData]
systemUsersNewUids = [x[2] for x in systemUsersNewData]
systemUsersNewData = filter(lambda x: x[0] != nameUser,
systemUsersNewData)
systemUsersNewNames = map(lambda x: x[0],
systemUsersNewData)
systemUsersNewUids = map(lambda x: x[2],
systemUsersNewData)
if uid in systemUsersNewUids:
systemUsersNewData = [x for x in systemUsersNewData
if x[2] != uid]
systemUsersNewNames = [x[0] for x in systemUsersNewData]
systemUsersNewUids = [x[2] for x in systemUsersNewData]
systemUsersNewData = filter(lambda x: x[2] != uid,
systemUsersNewData)
systemUsersNewNames = map(lambda x: x[0],
systemUsersNewData)
systemUsersNewUids = map(lambda x: x[2],
systemUsersNewData)
return (systemUsersThisData, systemUsersNewData,
dataNewUsers, dataThisUsers)
@ -199,48 +218,48 @@ class migrateShadow(_shareData):
def getThisData(self):
"""Get data migrate users in this system"""
return [x for x in self.getData()
if x[0] in self.thisMigrateUsers]
return filter(lambda x: x[0] in self.thisMigrateUsers, self.getData())
def getNewData(self):
"""Get data migrate users in new system"""
return [x for x in self.getData(fileName=self.newFileName)
if x[0] in self.newMigrateUsers]
return filter(lambda x: x[0] in self.newMigrateUsers,
self.getData(fileName=self.newFileName))
def getNewDataSystemShadow(self):
"""Get data system users in new system"""
return [x for x in self.getData(fileName=self.newFileName)
if x[0] in self.sysNewMigrateUsers]
return filter(lambda x: x[0] in self.sysNewMigrateUsers,
self.getData(fileName=self.newFileName))
def getThisDataSystemShadow(self):
"""Get data system users in this system"""
return [x for x in self.getData() if x[0] in self.sysThisMigrateUsers]
return filter(lambda x: x[0] in self.sysThisMigrateUsers,
self.getData())
def getNewProcessedData(self):
"""Get processed data migrate shadow in new system"""
dataThisShadow = self.getThisData()
dataNewShadow = self.getNewData()
namesNewShadow = [x[0] for x in dataNewShadow]
namesNewShadow = map(lambda x: x[0], dataNewShadow)
for data in dataThisShadow:
nameUser = data[0]
if nameUser in namesNewShadow:
dataNewShadow = [x for x in dataNewShadow if x[0] != nameUser]
namesNewShadow = [x[0] for x in dataNewShadow]
dataNewShadow = filter(lambda x: x[0] != nameUser,
dataNewShadow)
namesNewShadow = map(lambda x: x[0], dataNewShadow)
systemShadowNewData = self.getNewDataSystemShadow()
systemShadowThisData = self.getThisDataSystemShadow()
systemShadowNewNames = [x[0] for x in systemShadowNewData]
systemShadowNewNames = map(lambda x: x[0], systemShadowNewData)
for data in systemShadowThisData:
nameUser = data[0]
if nameUser in systemShadowNewNames:
systemShadowNewData = [x for x
in systemShadowNewData if x[0] != nameUser]
systemShadowNewNames = [x[0] for x in systemShadowNewData]
systemShadowNewData = filter(lambda x: x[0] != nameUser,
systemShadowNewData)
systemShadowNewNames = map(lambda x: x[0], systemShadowNewData)
return (systemShadowThisData, systemShadowNewData, dataNewShadow,
dataThisShadow)
class migrate():
class migrate(object):
"""Migrate users ang groups to new system"""
templateShadow = "%(user)s:%(hash)s:%(days)s:0:%(maxDays)s:%(warnDays)s:::"
templateUser = "%(user)s:x:%(id)s:%(gid)s::/home/%(user)s:/bin/bash"
@ -254,8 +273,8 @@ class migrate():
minGid = 1000
minSysId = 1000
newUserGroups = ["audio", "cdrom", "cdrw", "games", "lp", "lpadmin",
"plugdev", "scanner" "usb", "users", "video", "wheel"]
newUserGroups = ["audio", "cdrom", "cdrw", "games", "lp", "plugdev",
"scanner" "usb", "users", "video", "wheel"]
def __init__(self, prefixNewSystem):
self.prefixNewSystem = prefixNewSystem
@ -265,12 +284,14 @@ class migrate():
def addThisUsersToGroups(self, users):
"""Add users to groups"""
thisGroupsData = self.objGroups.getData()
thisGroupsData = [(x[0], x[3].split(',')) for x in thisGroupsData]
thisGroupsData = map(lambda x: (x[0], x[3].split(',')),
thisGroupsData)
dataGroups = []
for data in self.dataGroups:
groupName = data[0]
thisUsersInGroup = [x[1] for x in thisGroupsData if x[0] == groupName]
#??? whats the point of this?
thisUsersInGroup = map(lambda x: x[1],
filter(lambda x: x[0] == groupName,
thisGroupsData))
thisUsersInGroup = reduce(lambda x, y: x + y, thisUsersInGroup, [])
addUsers = list(set(thisUsersInGroup) & set(users))
if addUsers:
@ -278,30 +299,36 @@ class migrate():
for user in addUsers:
if not user in newUsersInGroup:
newUsersInGroup.append(user)
data[3] = ','.join((x for x in newUsersInGroup if x))
data[3] = ','.join(filter(lambda x: x, newUsersInGroup))
dataGroups.append(data)
self.dataGroups = dataGroups
return self.dataGroups
def getNextUid(self):
"""get next uid"""
listUid = [int(x[2]) for x in self.dataUsers
if self.objUsers._reNumb.match(x[2]) and self.minId <= int(x[2]) <= self.maxId]
listUid = map(lambda x: int(x[2]),
filter(lambda x: \
self.objUsers._reNumb.match(x[2]) and \
self.minId <= int(x[2]) <= self.maxId,
self.dataUsers))
if listUid:
return max(listUid) + 1
return self.minId
def getNextGid(self):
"""get next gid"""
listGid = [int(x[2]) for x in self.dataGroups
if self.objUsers._reNumb.match(x[2]) and self.minGid <= int(x[2]) <= self.maxGid]
listGid = map(lambda x: int(x[2]),
filter(lambda x: \
self.objGroups._reNumb.match(x[2]) and \
self.minGid <= int(x[2]) <= self.maxGid,
self.dataGroups))
if listGid:
return max(listGid) + 1
return self.minGid
def isSystemUser(self, userName):
if [x for x in self.dataUsers
if (x[0] == userName and int(x[2]) <= self.minSysId)]:
if filter(lambda x: x[0] == userName and int(x[2]) <= self.minSysId,
self.dataUsers):
return True
return False
@ -315,7 +342,7 @@ class migrate():
usersInGroup = data[3].split(',')
if not userName in usersInGroup:
usersInGroup.append(userName)
data[3] = ','.join((x for x in usersInGroup if x))
data[3] = ','.join(filter(lambda x: x, usersInGroup))
dataGroups.append(data)
self.dataGroups = dataGroups
return self.dataGroups
@ -325,7 +352,7 @@ class migrate():
return self.addUserToGroups(userName, self.newUserGroups)
def changePassword(self, userName, pwdHash, maxDays="99999", warnDays="7"):
if not [x for x in self.dataUsers if x[0] == userName]:
if not filter(lambda x: x[0] == userName, self.dataUsers):
raise MigrationError(_("User %s not found") % userName)
indexFoundUser = False
for i, data in enumerate(self.dataShadow):
@ -352,14 +379,14 @@ class migrate():
def addUser(self, userName, userGroups, pwdHash):
"""Add user"""
# find user
if [x for x in self.dataUsers if x[0] == userName]:
if filter(lambda x: x[0] == userName, self.dataUsers):
return "EXISTS"
else:
strUid = str(self.getNextUid())
strGid = str(self.getNextGid())
groupName = userName
dataExistGroup = [x for x in self.dataGroups
if x[0] == groupName]
dataExistGroup = filter(lambda x: x[0] == groupName,
self.dataGroups)
if dataExistGroup:
strGid = dataExistGroup[0][2]
else:
@ -384,25 +411,27 @@ class migrate():
"""Check permission files"""
checkThisFiles = [migrateGroups.fileGroups, migrateUsers.filePasswd,
migrateShadow.fileShadow]
checkNewFiles = [pathJoin(self.prefixNewSystem, x) for x in checkThisFiles]
checkNewFiles = map(lambda x: pathJoin(self.prefixNewSystem, x),
checkThisFiles)
parentDir = lambda x: "".join(os.path.split(x)[:-1])
notRead = lambda x: not os.access(x, os.R_OK)
notWrite = lambda x: not os.access(x, os.W_OK)
filesNotRead = [x for x in checkThisFiles if notRead(x)]
filesNotRead = filter(notRead, checkThisFiles)
if filesNotRead:
raise MigrationError(_("Failed to read files") + _(": ") +
", ".join(filesNotRead))
filesNotWrite = [x for x in checkNewFiles if notWrite(x)]
filesNotWrite = filter(notWrite, checkNewFiles)
if filesNotWrite:
raise MigrationError(_("Failed to write to files") + _(": ") +
", ".join(filesNotWrite))
# Check permissions backup files
checkNewBackupFiles = (pathJoin(self.prefixNewSystem, x + "-") for x
in checkThisFiles)
checkNewBackupFiles = map(
lambda x: pathJoin(self.prefixNewSystem, x + "-"),
checkThisFiles)
notWriteBackup = lambda x: not os.access(x, os.W_OK) and \
(os.path.exists(x) or
not os.access(os.path.dirname(x), os.W_OK))
filesNotWrite = [x for x in checkNewBackupFiles if notWriteBackup(x)]
filesNotWrite = filter(notWriteBackup, checkNewBackupFiles)
if filesNotWrite:
raise MigrationError(_("Failed to write to files") + _(": ") +
", ".join(filesNotWrite))
@ -413,20 +442,20 @@ class migrate():
listFilesThisSystem = [migrateGroups.fileGroups,
migrateUsers.filePasswd,
migrateShadow.fileShadow]
listFiles = [(pathJoin(self.prefixNewSystem, x),
pathJoin(self.prefixNewSystem, x + "-")) for x
in listFilesThisSystem]
listFiles = map(lambda x: (pathJoin(self.prefixNewSystem, x),
pathJoin(self.prefixNewSystem, x + "-")),
listFilesThisSystem)
listData = [self.dataGroups, self.dataUsers, self.dataShadow]
allData = zip(listFiles, listData)
for fileNames, data in allData:
buff = "\n".join((":".join(x) for x in data)) + "\n"
buff = "\n".join(map(lambda x: ":".join(x), data)) + "\n"
for fileName in fileNames:
FD = open(fileName, "w+")
FD.write(buff)
FD.close()
def createUserGuest(self):
if [x for x in self.dataUsers if int(x[2]) >= self.minSysId]:
if filter(lambda x: int(x[2]) >= self.minSysId, self.dataUsers):
return True
else:
# add user guest
@ -443,17 +472,17 @@ class migrate():
"""Create home directories for all migreate users"""
def createHome(userdata):
perms = FilePermission.UserAll
if not userdata[5].startswith('/dev/'):
homedir = pathJoin(self.prefixNewSystem, userdata[5])
if not path.exists(homedir):
os.mkdir(homedir)
os.chown(homedir, int(userdata[2]), int(userdata[3]))
os.chmod(homedir, perms)
users = list(set([x[0] for x in addUsersList] + existsMigrateUsers) - {"root"})
users = list(
set(map(lambda x: x[0],
addUsersList) + existsMigrateUsers) - {"root"})
try:
# map(createHome, (x for x in self.dataUsers if x[0] in users))
[createHome(x) for x in self.dataUsers if x[0] in users]
map(createHome, filter(lambda x: x[0] in users, self.dataUsers))
except Exception as e:
raise MigrationError(
_("Failed to create the user's home directory"))
@ -471,9 +500,8 @@ class migrate():
existsMigrateUsers = []
if not self.checkPermFiles():
return False
migrateUsers = (["root"] + [x[0] for x in addUsersList + pwdUsersList])
migrateUsers = (["root"] +
map(lambda x: x[0], addUsersList + pwdUsersList))
for existMigrUser in existsMigrateUsers:
if existMigrUser not in migrateUsers:
migrateUsers.append(existMigrUser)
@ -481,7 +509,7 @@ class migrate():
dataUsers = self.objUsers.getNewProcessedData(migrateUsers)
dataGroups = self.objGroups.getNewProcessedData()
thisSystemUsers, newSystemUsers, newUsers, thisUsers = \
[[y[0] for y in x] for x in dataUsers]
map(lambda x: map(lambda y: y[0], x), dataUsers)
objShadow = migrateShadow(thisSystemUsers, newSystemUsers, newUsers,
thisUsers, self.prefixNewSystem)
dataShadow = objShadow.getNewProcessedData()
@ -517,7 +545,7 @@ class currentUsers(migrate):
"""Current users"""
def __init__(self):
super().__init__('/')
super(currentUsers, self).__init__('/')
def addUsers(self, *users_passwd):
"""Added users and groups to current system"""
@ -544,5 +572,7 @@ class currentUsers(migrate):
if not self.checkPermFiles():
return False
getDataInFile = _shareData().getDataInFile
self.dataUsers = [x[0] for x in getDataInFile(fileName=migrateUsers.filePasswd,lenData=7)]
self.dataUsers = map(lambda x: x[0],
getDataInFile(fileName=migrateUsers.filePasswd,
lenData=7))
return set(self.dataUsers) >= set(users)

@ -16,14 +16,13 @@
import sys
from calculate.core.server.func import Action, Tasks
from ..distr import DistributiveError
from ..migrate_users import MigrationError
from ..variables.autopartition import AutopartitionError
from calculate.lib.utils.partition import VolumesError
from calculate.install.distr import DistributiveError
from calculate.install.migrate_users import MigrationError
from calculate.install.variables.autopartition import AutopartitionError
from calculate.lib.cl_lang import setLocalTranslate, getLazyLocalTranslate, _
from calculate.lib.cl_template import TemplatesError
from calculate.lib.utils.files import FilesError
from ..install import InstallError
from calculate.install.install import InstallError
setLocalTranslate('cl_install3', sys.modules[__name__])
__ = getLazyLocalTranslate(_)
@ -34,7 +33,7 @@ class ClInstallAction(Action):
Установка системы
"""
# ошибки, которые отображаются без подробностей
native_error = (FilesError, MigrationError, TemplatesError, VolumesError,
native_error = (FilesError, MigrationError, TemplatesError,
InstallError, AutopartitionError, DistributiveError)
successMessage = None
failedMessage = None
@ -45,9 +44,11 @@ class ClInstallAction(Action):
# авторазметка диска
{'name': 'autopartition',
'message': __("Creating a new partition table"),
'method': "Install.autopartition(cl_autopartition_scheme_builder,"
"cl_autopartition_device,"
"cl_autopartition_disk_dev)",
'method': "Install.autopartition(cl_autopartition_table,"
"cl_autopartition_device,cl_autopartition_disk_data,"
"cl_autopartition_lvm_set,cl_autopartition_lvm_vgname,"
"cl_autopartition_bios_grub_set,"
"cl_autopartition_bios_grub_size)",
'condition': lambda dv: dv.Get('cl_autopartition_set') == 'on'},
# форматирование разделов на которые устанавливается дистрибутив
{'name': 'format',
@ -114,10 +115,6 @@ class ClInstallAction(Action):
'method': 'Install.userMigrate(cl_target,cl_migrate_data,'
'cl_migrate_root_pwd)',
},
# прописывание локальных администраторов
{'name': 'hdd:write_admins',
'method': 'Install.update_admin_ini()',
},
# подготовка загрузчика
{'name': 'prepare_boot',
'message': __("Preparing the system for reboot"),

@ -16,14 +16,14 @@
import sys
from calculate.core.server.func import Action
from ..distr import DistributiveError
from ..migrate_users import MigrationError
from calculate.install.distr import DistributiveError
from calculate.install.migrate_users import MigrationError
from calculate.lib.cl_lang import setLocalTranslate, getLazyLocalTranslate, _
from calculate.lib.cl_template import TemplatesError
from calculate.lib.utils.files import FilesError
from calculate.lib.utils.portage import isPkgInstalled
from ..install import InstallError
from ..variables.autopartition import AutopartitionError
from calculate.install.install import InstallError
from calculate.install.variables.autopartition import AutopartitionError
setLocalTranslate('cl_install3', sys.modules[__name__])
__ = getLazyLocalTranslate(_)
@ -58,6 +58,11 @@ class ClSetupVideoAction(Action):
'method': 'Install.checkVideoDriver()',
'condition': lambda: isPkgInstalled('xorg-server')
},
{'name': 'setup_opengl',
'message': __("Configuring OpenGL"),
'method': 'Install.setupOpenGL()',
'condition': lambda: isPkgInstalled('xorg-server')
},
{'name': 'setupvideo',
'condition': lambda Get: Get('cl_setup') == 'video'
},
@ -119,21 +124,6 @@ class ClSetupAudioAction(ClSetupSystemAction):
failedMessage = __("Failed to configure the audio parameters!")
class ClSetupThemesAction(ClSetupSystemAction):
"""
Действие для настройки тем
"""
addon_tasks = []
prev_tasks = [
{'name': 'init_themes',
'method': 'Install.init_themes()'
},
]
templateTaskMessage = __("The themes are being configured")
successMessage = __("Themes configured!")
failedMessage = __("Theme configuration failed!")
class ClSetupLocaleAction(ClSetupSystemAction):
"""
Действие для настройки языковых параметров
@ -189,4 +179,13 @@ class ClSetupBootAction(ClSetupSystemAction):
'warning': _("The builder mode is no longer supported"),
'condition': lambda Get: Get('os_install_scratch') == 'on'
},
# изменить IO планировщик
{'name': 'change_ioscheduler',
'message': _("Changing the I/O scheduler"),
'method': 'Install.changeScheduler(os_install_kernel_scheduler)',
'condition': (lambda dv: dv.Get('os_root_type') != 'livecd' and
dv.Select('os_disk_parent',
where='os_disk_mount',
eq='/', limit=1))
},
]

@ -18,13 +18,9 @@ import os
import sys
import re
from os import path
import hashlib
import glob
from calculate.lib.datavars import Variable, VariableError, ReadonlyVariable
from calculate.lib.utils.portage import isPkgInstalled
from calculate.lib.utils.files import readFile, readFileEx
from calculate.lib.utils.tools import get_best_nearest_resolution
import calculate.lib.utils.device as device
from calculate.lib.utils.files import readFile
from calculate.lib.utils.common import (getVideoFromXorgLog,
getVideoFromXorgConf,
getVideoFromCmdLine,
@ -33,8 +29,7 @@ from calculate.lib.utils.common import (getVideoFromXorgLog,
getVideoFromModules,
getVideoFromVendor, getInstalledVideo,
CmdlineParams)
from calculate.lib.utils.video import get_edid_data, EdidInfoError, EdidInfo
from ..distr import DistributiveError
from calculate.install.distr import DistributiveError
import fcntl
import struct
from collections import OrderedDict
@ -51,14 +46,14 @@ class VideoVariable(Variable):
xorg_need = True
default_video = "default"
driver_names = OrderedDict([
('default', _("Auto detection")),
('default', _("X.Org Server auto detection")),
('radeon', _("AMD Radeon (radeon)")),
('amdgpu', _("AMD AMDGPU (amdgpu)")),
('modesetting', _("Framebuffer device (modesetting)")),
('vesa', _("Generic VESA (vesa)")),
('fglrx', _("AMD Catalyst (fglrx)")),
('intel', _("Intel (intel)")),
('nouveau', _("Nvidia Nouveau (nouveau)")),
('nvidia', _("Nvidia Graphics Driver (nvidia)")),
('vesa', _("Generic VESA (vesa)")),
])
def uncompatible(self):
@ -90,7 +85,8 @@ class ResolutionVariable(VideoVariable):
"1600x900", "1600x1200", "2048x1152", "2560x1440",
"2560x1600"]
if self.fbres:
return ["%s-32" % x for x in resolutions]
return map(lambda x: "%s-32" % x,
resolutions)
else:
return resolutions
@ -105,7 +101,7 @@ class ResolutionVariable(VideoVariable):
example="(%s:%s)" % (_("Example"), "1024x768")))
class VariableOsInstallX11ResolutionPreferred(ResolutionVariable):
class VariableOsInstallX11Resolution(ResolutionVariable):
"""
X.org resolution
"""
@ -114,7 +110,7 @@ class VariableOsInstallX11ResolutionPreferred(ResolutionVariable):
metavalue = "<width>x<height>"
# разрешение по умолчанию пустое - это нужно для livecd
# для автоопределения разрешения xorg сервером
preferred_resolution = ""
fallback_resolution = ""
def init(self):
self.help = _("set the Xorg resolution")
@ -123,37 +119,12 @@ class VariableOsInstallX11ResolutionPreferred(ResolutionVariable):
def get(self):
# get resolution from xorg.log
res = self.Get('os_x11_resolution')
if res:
return res
if res or self.Get('install.os_install_root_type') in (
'livecd', 'usb-hdd'):
return res or self.fallback_resolution
else:
return self.preferred_resolution
class VariableOsInstallX11Resolution(ResolutionVariable):
"""
X.org resolution
"""
fallback_resolution = "1024x768"
FBIOGET_VSCREENINFO = 0x4600
def framebuffer_resolution(self):
try:
fbdev = os.open('/dev/fb0', os.O_RDONLY)
data = fcntl.ioctl(fbdev, self.FBIOGET_VSCREENINFO, " " * 8)
res = struct.unpack("II", data)
return "%sx%s" % (res[0], res[1])
except (IOError, OSError):
pass
return ""
return self.fallback_resolution
def get(self):
# get resolution from xorg.log
res = self.Get('install.os_install_x11_resolution_preferred')
if res:
return res
res = self.framebuffer_resolution()
if res:
return res
return self.fallback_resolution
class VariableOsInstallX11VideoAvailable(VideoVariable):
"""
@ -161,8 +132,7 @@ class VariableOsInstallX11VideoAvailable(VideoVariable):
"""
type = "list"
# supported = ["nvidia", "fglrx", "amdgpu", "nouveau", "intel", "radeon"]
supported = ["nvidia", "amdgpu","modesetting",
"nouveau", "intel", "radeon", "vesa"]
supported = ["nvidia", "fglrx", "amdgpu", "nouveau", "intel", "radeon"]
def get(self):
image = self.Get('cl_image')
@ -180,7 +150,7 @@ class VariableOsInstallX11VideoAvailable(VideoVariable):
return []
def humanReadable(self):
return [self.driver_names.get(x, x) for x in self.Get()]
return map(lambda x: self.driver_names.get(x, x), self.Get())
class VariableOsX11KmsVideoDrv(ReadonlyVariable):
@ -188,7 +158,7 @@ class VariableOsX11KmsVideoDrv(ReadonlyVariable):
Список KMS драйверов
"""
type = "list"
value = ["radeon", "intel", "nouveau", "amdgpu", "modesetting"]
value = ["radeon", "intel", "nouveau", "amdgpu"]
class VariableOsInstallX11VideoDrv(VideoVariable):
@ -203,22 +173,14 @@ class VariableOsInstallX11VideoDrv(VideoVariable):
self.help = _("set the video driver")
self.label = _("Video driver")
def nox_video_drivers(self):
values = self.Get('os_x11_kms_video_drv')
for drv, drvinfo in self.pkgDrvMap.items():
_, pkgdrv = drvinfo
if isPkgInstalled(pkgdrv, prefix=self.Get('cl_chroot_path')):
values.append(drv)
return [self.default_video] + list(sorted(values))
def choice(self):
"""Get available (already installed or installable drivers"""
if self.Get('os_install_x11_server_set') == 'on':
values = self.Get('os_install_x11_video_available')
else:
values = self.nox_video_drivers()
return [(x, self.driver_names.get(x, x)) for x
in [y for y in self.driver_names.keys() if y in values]]
values = self.Get('os_x11_kms_video_drv') + [self.default_video]
return map(lambda x: (x, self.driver_names.get(x, x)),
(x for x in self.driver_names.keys() if x in values))
def get(self):
if self.Get('os_install_x11_server_set') == 'on':
@ -236,8 +198,8 @@ class VariableOsInstallX11VideoDrv(VideoVariable):
# test current video driver for install system
methods = ((getVideoFromXorgLog, ('/', list_video)),
(getVideoFromXorgConf, ('/',)),
(getVideoFromCmdLine, ()),
(getVideoFromModules, ()),
(getVideoFromCmdLine, ()),
(getVideoFromVendor,
(self.Get('hr_video'), list_video)))
for func, args in methods:
@ -246,9 +208,9 @@ class VariableOsInstallX11VideoDrv(VideoVariable):
return drv
return self.default_video
else:
for drv in (x[0] for x in self.choice()):
refcnt = device.sysfs.read(
device.sysfs.Path.Module, drv, "refcnt").strip()
for drv in map(lambda x: x[0], self.choice()):
videoSysPath = path.join("/sys/module", drv, "refcnt")
refcnt = readFile(videoSysPath).strip()
if refcnt.isdigit() and int(refcnt) > 0:
return {'i915': 'intel'}.get(drv, drv)
else:
@ -275,7 +237,8 @@ class VariableOsInstallX11VideoDrv(VideoVariable):
error += "\n" + ("emerge %s" % self.pkgDrvMap[value][1])
raise VariableError(error)
else:
availDrivers = self.nox_video_drivers()
availDrivers = self.Get('os_x11_kms_video_drv') + [
self.default_video]
if not value in availDrivers:
raise VariableError("Only %s drivers are available" %
",".join(availDrivers))
@ -317,8 +280,7 @@ class VariableOsInstallX11Composite(VideoVariable):
def get(self):
"""On/off composite"""
defaultCompositeOn = ("nvidia", "intel", "fglrx", "amdgpu",
"modesetting",
defaultCompositeOn = ("nvidia", "intel", "fglrx", # "amdgpu",
"nouveau", "radeon", "default")
composite = getValueFromCmdLine(CmdlineParams.Calculate,
CmdlineParams.Composite)
@ -344,30 +306,6 @@ class VariableOsInstallX11Composite(VideoVariable):
state = None
return composite or state or defaultComposite
class VariableOsInstallFbResolutionPreferred(ResolutionVariable):
"""
Framebuffer resolution
"""
type = 'choiceedit'
opt = ['--fb']
metavalue = "<width>x<height>"
xorg_need = False
fbres = True
value = "auto"
def init(self):
self.help = _("set the framebuffer resolution")
self.label = _("Framebuffer resolution")
def choice(self):
yield ("auto", _("Auto"))
for i in ResolutionVariable.choice(self):
yield (i,i)
def check(self, value):
if value == "auto":
return
ResolutionVariable.check(self, value)
class VariableOsInstallFbResolution(ResolutionVariable):
"""
@ -378,174 +316,20 @@ class VariableOsInstallFbResolution(ResolutionVariable):
metavalue = "<width>x<height>"
xorg_need = False
fbres = True
fallback_resolution = "1024x768"
def init(self):
self.help = _("set the framebuffer resolution")
self.label = _("Framebuffer resolution")
def using_kms(self):
drv = self.Get('install.os_install_x11_video_drv')
kms = self.Get('install.os_x11_kms_video_drv')
return drv in kms
def using_uefi(self):
return self.GetBool('install.os_install_uefi_set')
def get(self):
custom = self.Get('os_install_fb_resolution_preferred')
if custom != "auto":
return custom
x11res = self.Get('os_install_x11_resolution')
if self.using_kms() or self.using_uefi():
return x11res
hwinfo = device.Hwinfo()
try:
return get_best_nearest_resolution(
x11res, hwinfo.resolutions()) or self.fallback_resolution
except (ZeroDivisionError, device.HwinfoError):
return self.fallback_resolution
class VariableClGrubImageHash(ReadonlyVariable):
"""
Контрольная сумма изображения для grub
"""
grub_image = "/boot/grub/grub-calculate.png"
theme_data = "/etc/grub.d/05_theme"
def get_image_md5(self, source):
return hashlib.md5(readFile(source, binary=True)).hexdigest()
def get_config_md5(selfself, source):
return hashlib.md5(readFileEx(source, grab=True)).hexdigest()
def get_checksum(self):
data = []
if path.exists(self.grub_image):
data.append(self.get_image_md5(self.grub_image))
else:
data.append("-")
if path.exists(self.theme_data):
data.append(self.get_config_md5(self.theme_data))
else:
data.append("-")
return "".join(data)
def get(self):
if self.Get('cl_setup') == 'themes':
return self.get_checksum()
return ""
class VariableClGrubImageUpdateSet(VariableClGrubImageHash):
"""
Изображение для grub обновлилось
"""
def get(self):
if self.Get('cl_setup') == 'themes':
newmd5 = self.get_checksum()
return "on" if newmd5 != self.Get('cl_grub_image_hash') else "off"
return "off"
class VariableClSplashImageHash(ReadonlyVariable):
"""
Контрольные суммы изображений для splashutils
"""
hash_files = ("/etc/splash/calculate/images/verbose.md5",
"/etc/splash/calculate/images/silent.md5",
"/usr/share/plymouth/themes/calculate/boot.md5",
"/usr/share/plymouth/themes/calculate/boot/md5sum",
"/usr/share/plymouth/themes/calculate/calculate.plymouth")
cfg_files = "/etc/splash/calculate/*.cfg"
def get_config_md5(selfself, source):
return hashlib.md5(readFileEx(source, grab=True)).hexdigest()
def get_hash_data(self, sources):
data = []
for fn in sources:
data.append(self.get_config_md5(fn))
for fn in glob.glob(self.cfg_files):
data.append(self.get_config_md5(fn))
break
return "".join(data)
def get(self):
if self.Get('cl_setup') == 'themes':
return self.get_hash_data(self.hash_files)
return ""
class VariableClSplashImageUpdateSet(VariableClSplashImageHash):
"""
Изображение для splash dracut обновлилось
"""
def get(self):
if self.Get('cl_setup') == 'themes':
newmd5 = self.get_hash_data(self.hash_files)
return "on" if newmd5 != self.Get('cl_splash_image_hash') else "off"
return "off"
class VariableClInstallEdidData(ReadonlyVariable):
type = Variable.Types.Object
def get(self):
edid_data = get_edid_data()
if not edid_data:
return {}
try:
ei = EdidInfo()
ei.set_data(edid_data)
return {
"resolution": ei.resolution,
"ratio": ei.ratio,
"screensize": ei.screensize
}
except EdidInfoError as e:
return {}
class VariableClInstallEdidResolution(ReadonlyVariable):
def get(self):
return self.Get('cl_install_edid_data').get('resolution','')
class VariableClInstallEdidScreensize(ReadonlyVariable):
def get(self):
return self.Get('cl_install_edid_data').get('screensize','')
class VariableClInstallCalculateDpi(Variable):
def get(self):
inch = 25.4
screensize = self.Get('cl_install_edid_screensize')
resolution = self.Get('os_install_x11_resolution')
if screensize and resolution:
cx = screensize.partition("x")[0]
cxres = resolution.partition("x")[0]
if cx.isdigit() and cxres.isdigit():
cx = float(cx)
cxres = float(cxres)
return str(int(inch * cxres / cx))
return ""
class VariableClInstallDpi(Variable):
def get(self):
calculate_dpi = self.Get('cl_install_calculate_dpi')
try:
if calculate_dpi:
calculate_dpi = int(calculate_dpi)
if calculate_dpi > 100:
return "108"
except ValueError:
pass
return "96"
FBIOGET_VSCREENINFO = 0x4600
class VariableClInstallScaling(Variable):
def get(self):
dpi = self.Get('cl_install_dpi')
"""Get current framebuffer resolution"""
try:
if dpi:
dpi = int(dpi)
if dpi > 100:
return "hi"
except ValueError:
fbdev = os.open('/dev/fb0', os.O_RDONLY)
data = fcntl.ioctl(fbdev, self.FBIOGET_VSCREENINFO, " " * 8)
res = struct.unpack("II", data)
return "%sx%s" % (res[0], res[1])
except (IOError, OSError):
pass
return "normal"
return "1024x768"

@ -14,17 +14,17 @@
# See the License for the specific language governing permissions and
# limitations under the License.
from . import action
from . import disk
from . import locale
from . import linux
from . import distr
from . import kernel
from . import net
from . import system
from . import X11
from . import lvm
from . import autopartition
from . import audio
import action
import disk
import locale
import linux
import distr
import kernel
import net
import system
import X11
import lvm
import autopartition
import audio
section = "install"

@ -21,7 +21,6 @@ from calculate.lib.cl_lang import setLocalTranslate
setLocalTranslate('cl_install3', sys.modules[__name__])
ServerSetup = "server_setup"
class VariableAcInstallMerge(ActionVariable):
"""
@ -34,8 +33,7 @@ class VariableAcInstallMerge(ActionVariable):
self.Get('os_install_root_type') != 'flash' and
self.Get('os_install_pxe') == 'off' and
self.Get('cl_live') == 'off' or
cl_action in (ServerSetup, "sync",
"domain", "undomain",)
cl_action in ("sync", "domain", "undomain")
and self.Get('cl_merge_pkg')):
return "on"
return "off"
@ -53,24 +51,12 @@ class VariableAcInstallLive(ActionVariable):
if (cl_action in ("system", "merge") and
self.Get('os_install_root_type') != 'flash' and
self.Get('os_install_pxe') == 'off' or
cl_action in (ServerSetup,
"sync", "domain", "undomain",)
cl_action in ("sync", "domain", "undomain")
and self.Get('cl_merge_pkg')):
return "on"
return "off"
class VariableAcInstallConfig(ActionVariable):
"""
Action variable which has value "on" for emerge --config
cl-config
"""
def action(self, cl_action):
if cl_action in ("config",):
return "on"
return "off"
class VariableAcInstallDisk(ActionVariable):
"""
Action variable which has value "on" for installation on hdd

@ -19,11 +19,9 @@ import re
from calculate.lib.datavars import (Variable, ReadonlyVariable,
ReadonlyTableVariable, FieldValue,
HumanReadable)
from calculate.lib.utils.common import getValueFromCmdLine, CmdlineParams
from calculate.lib.utils.portage import isPkgInstalled
from calculate.lib.utils.files import readFile, readLinesFile
from ..distr import DistributiveError
import glob
from calculate.lib.utils.files import readFile
from calculate.install.distr import DistributiveError
from calculate.lib.cl_lang import setLocalTranslate, _
@ -43,33 +41,13 @@ class VariableOsAudio(Variable):
self.help = _("set the audio system")
def get(self):
"""
pipewire по умолчанию если доступно или вписано в /etc/asound.conf
"""
avail = [x[0] for x in self.Get('os_audio_available')]
if "pipewire" in avail:
audio = getValueFromCmdLine(CmdlineParams.Calculate,
CmdlineParams.Audio)
return self.choice()[0][0]
if audio and audio == "alsa":
return "alsa"
else:
return "pipewire"
return "alsa"
def set(self, value):
return {'none': ''}.get(value, value)
def choice(self):
return self.Get('os_audio_available')
def uncompatible(self):
"""
Audio setting up unavailable for flash installation
"""
if self.Get('os_install_root_type') == 'flash':
return _("Audio configuration unavailable for Flash install")
if self.Get('os_install_alsa_set') == 'off':
return _("This distribution does not provide the ALSA sound")
return ""
return self.Get('os_audio_available') or [('',_('None'))]
class VariableOsAudioAvailable(Variable):
@ -79,32 +57,21 @@ class VariableOsAudioAvailable(Variable):
type = "list"
def get(self):
mapAudioConf = (
('alsa', None, _('ALSA')),
('pipewire', 'media-video/pipewire', _("PipeWire")),
)
mapAudioConf = (('pulseaudio', 'media-sound/pulseaudio',
_("PulseAudio")),
('alsa', 'media-sound/alsa-utils', _('ALSA')))
image = self.Get('cl_image')
if image:
with image as distr:
try:
distrPath = image.getDirectory()
return [x[0::2] for x
in mapAudioConf
if not x[1] or isPkgInstalled(x[1], prefix=distrPath)]
return map(lambda x:x[0::2],
filter(lambda x: not x[1] or isPkgInstalled(x[1],
prefix=distrPath),
mapAudioConf))
except DistributiveError as e:
pass
return sorted((x[0::2] for x in mapAudioConf[-1:]), key=lambda x: x[1])
class VariableOsAudioCardMap(ReadonlyVariable):
"""
Соответствие номеров звуковых карт именам
"""
type = Variable.Types.Table
def get(self):
return [(cardid[17:-3], readFile(cardid).strip())
for cardid in glob.glob('/proc/asound/card[0-9]*/id')]
return sorted(map(lambda x:x[0::2], mapAudioConf[-1:]), key=lambda x:x[1])
class VariableOsAudioData(ReadonlyTableVariable):
@ -114,28 +81,11 @@ class VariableOsAudioData(ReadonlyTableVariable):
source = ['os_audio_id',
'os_audio_name']
def generate_cards(self, cards):
for card_id, card_name in cards:
for playback_info in glob.glob(
"/proc/asound/card%s/pcm[0-9]p/info" % card_id):
dInfo = (x.partition(":")[::2]
for x in readLinesFile(playback_info))
dInfo = {x.strip(): y.strip() for x, y in dInfo}
if all(x in dInfo for x in ('card', 'device', 'name')):
if card_name == dInfo['name']:
yield ("%s,%s" % (dInfo['card'], dInfo['device']),
"%s" % card_name)
else:
yield ("%s,%s" % (dInfo['card'], dInfo['device']),
"%s, %s" % (card_name, dInfo['name']))
def get(self, hr=HumanReadable.No):
# /proc/asound/card*/pcm*p/info
data = readFile('/proc/asound/cards')
cards = re.findall('^\s*(\d+).*\s-\s(.+)\n\s+\S.* at .*$',
data, re.M)
cards = re.findall('^\s*(\d+).*\n\s+(\S.*) at .*$', data, re.M)
if cards:
return list(self.generate_cards(cards))
return map(list, cards)
else:
return [[]]
@ -160,85 +110,44 @@ class VariableOsAudioName(FieldValue, ReadonlyVariable):
column = 1
class VariableOsAudioCardDefault(Variable):
class VariableOsAudioDefaultSet(ReadonlyVariable):
"""
Идентификатор карты по умолчанию
Force write in config 0
"""
def get(self):
audio_default = self.Get('os_audio_default')
if audio_default and audio_default != "none":
cardmap = dict(self.Get("os_audio_card_map"))
cardnum = audio_default.split(',')[0]
if cardnum in cardmap:
return cardmap[cardnum]
return "0"
return ""
type = "bool"
class VariableOsAudioDeviceDefault(Variable):
"""
Номер устройства по умолчанию
"""
def get(self):
res = self.Select('os_audio_id', where='os_audio_name',
notlike='HDMI', limit=1)
audio_default = self.Get('os_audio_default')
if audio_default and audio_default != "none":
return self.Get('os_audio_default').split(',')[1]
return ""
class VariableOsAudioCardNameDefault(Variable):
"""
Название карты используемое в настройках KDE
"""
def get(self):
try:
audio_default = self.Get('os_audio_default')
if audio_default and audio_default != "none":
cardnum = int(audio_default.split(',')[0])
audionames = self.Get('os_audio_name')
if cardnum < len(audionames):
return audionames[cardnum].split(',')[0]
except ValueError:
pass
return ""
if (audio_default != '0' or
res and res != "0" and audio_default == '0' or
audio_default != self.Get('os_audio_current')):
return 'on'
return 'off'
class VariableOsAudioHw(Variable):
class VariableOsAudioCurrent(ReadonlyVariable):
"""
Current default audio card
"""
def get_deprecated(self):
asound_data = readFile('/etc/asound.conf')
def get(self):
default_card_re = re.compile('defaults.ctl.card\s+(\d+)')
entry = default_card_re.search(asound_data)
entry = default_card_re.search(readFile('/etc/asound.conf'))
if entry and entry.groups()[0] in self.Get('os_audio_id'):
return "%s,0" % entry.groups()[0]
default_card_re = re.compile(
'pcm.!default {[^}]+card\s+(\d+)[^}]+device\s+(\d+)[^}]+}')
entry = default_card_re.search(asound_data)
if entry:
entry = "%s,%s" % entry.groups()
if entry in self.Get('os_audio_id'):
return entry
return ""
return entry.groups()[0]
res = self.Select('os_audio_id', where='os_audio_name',
notlike='HDMI', limit=1)
return res or '0'
def get(self):
cardmap = dict(self.Get("os_audio_card_map"))
value = self.get_deprecated()
if not value:
value = self.Select('os_audio_id', where='os_audio_name',
notlike='HDMI', limit=1) or "0,0"
cardnum, devicenum = value.split(",")
if cardnum in cardmap:
return "{},{}".format(cardmap[cardnum], devicenum)
return ""
class VariableOsAudioDefault(Variable):
"""
Current default audio card
"""
type = "choice"
opt = ['--card']
opt = ['--audio-card']
metavalue = "CARD"
def init(self):
@ -246,22 +155,13 @@ class VariableOsAudioDefault(Variable):
self.help = _("set the default audio")
def get(self):
current = self.Get('os_audio_hw')
if current and "," in current:
cardmap = {y:x for x, y in self.Get("os_audio_card_map")}
cardid, devicenum = current.split(",")
if cardid in cardmap:
return "{},{}".format(cardmap[cardid], devicenum)
data = self.Get('os_audio_data')
if data and data[0]:
return "0,0"
return "none"
return self.Get('os_audio_current')
def choice(self):
data = self.Get('os_audio_data')
if data and data[0]:
return self.Get('os_audio_data')
return [("none", _("Not available"))]
return []
def uncompatible(self):
"""
@ -270,5 +170,6 @@ class VariableOsAudioDefault(Variable):
if self.Get('os_install_root_type') == 'flash':
return _("Audio configuration unavailable for Flash install")
if self.Get('os_install_alsa_set') == 'off':
return _("This distribution does not provide the ALSA sound")
return \
_("This distribution does not provide the ALSA sound")
return ""

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

@ -21,30 +21,26 @@ import re
import operator
from operator import itemgetter
from calculate.lib.datavars import (Variable, VariableError, ReadonlyVariable,
CommonVariableError, BuildAlreadyInstalledError)
CommonVariableError)
from calculate.lib.utils.common import (getSupportArch, getTupleVersion,
cmpVersion, cmp)
cmpVersion)
from calculate.lib.utils.files import listDirectory, pathJoin
from calculate.lib.utils.grub import GrubCommand
from calculate.lib.variables.linux import Linux
from ..distr import (Distributive, PartitionDistributive,
from calculate.install.distr import (Distributive, PartitionDistributive,
DirectoryDistributive, DefaultMountPath,
DistributiveError, FlashDistributive,
ArchiveDistributive,
MultiPartitions, PxeDistributive)
from calculate.lib.cl_lang import setLocalTranslate, _
from ..fs_manager import FileSystemManager
from functools import reduce, cmp_to_key
from calculate.install.fs_manager import FileSystemManager
setLocalTranslate('cl_install3', sys.modules[__name__])
class DistroRepository(Linux):
contentCache = {}
marches = ['x86_64']
marches = ['i686', 'x86_64']
extensiton = ['iso', 'tar.bz2', 'tar.gz', 'tar.7z', 'tar.lzma']
@ -95,10 +91,11 @@ class DistroRepository(Linux):
def _getAvailableShortnames(self, dirs):
"""Get available distributives shortnames"""
distros = [x for x
in map(self.reDistName.search, self._getAvailableDistributives(dirs))
if x]
return sorted(list(set([x.groupdict()['name'] for x in distros])))
distros = filter(lambda x: x,
map(self.reDistName.search,
self._getAvailableDistributives(dirs)))
return sorted(list(set(map(lambda x: x.groupdict()['name'], distros))))
def opcompareByString(self, buf):
if buf:
reOp = re.compile("^(!=|=|==|<=|>=|>|<)?(\d+.*)$")
@ -162,27 +159,29 @@ class DistroRepository(Linux):
return [pathname]
else:
# discard inner directories
return [x for x in listDirectory(pathname) if not path.isdir(path.join(pathname, x))]
return filter(lambda x: not path.isdir(path.join(pathname, x)),
listDirectory(pathname))
# get lists files in directories
allFiles = [[path.join(x, y) for y in listdistr(x)] for x in dirs]
allFiles = map(lambda x: map(lambda y: path.join(x, y),
listdistr(x)),
dirs)
# filter distributives
# join files lists to one list
return [x for x in reduce(lambda x, y: x + y, allFiles, []) if distfilter(x)]
return filter(distfilter,
# join files lists to one list
reduce(lambda x, y: x + y,
allFiles, []))
@staticmethod
def extcomparator(ext1, ext2):
def extcomparator(self, *exts):
"""Compare extensions"""
mapExts = {'iso': 0,
'flash': -1,
'isodir': -2,
'partdir': -3,
'dir': -4}
return cmp(mapExts.get(ext1, -4), mapExts.get(ext2, -4))
return cmp(mapExts.get(exts[0], -4), mapExts.get(exts[1], -4))
@staticmethod
def sortdistrfunc(x, y):
def sortdistrfunc(self, x, y):
"""Func of comparing two distributive"""
ver1, ver2 = x[1].get('os_linux_ver', ""), y[1].get('os_linux_ver', "")
if ver1 and ver2 and ver1 != "0" and ver2 != "0" and ver1 != ver2:
@ -198,7 +197,7 @@ class DistroRepository(Linux):
return cmp(int(ser1), int(ser2))
ext1 = x[1].get('ext', "")
ext2 = y[1].get('ext', "")
return DistroRepository.extcomparator(ext1, ext2)
return self.extcomparator(ext1, ext2)
def getAvailableDristibutives(self, dirs, system=None, shortname=None,
march=None, version=None, build=None,
@ -209,10 +208,12 @@ class DistroRepository(Linux):
availDistrs = self._getAvailableDistributives(dirs, system, shortname,
march, version,
build)
availDistrs = (x for x
in [(y, self._getDistrInfo(y)) for y in availDistrs]
if x[1] and "ext" in x[1] and not x[1]["ext"] in discardType)
return [x[0] for x in sorted(availDistrs, key=cmp_to_key(DistroRepository.sortdistrfunc), reverse=True)]
availDistrs = filter(lambda x: x[1] and "ext" in x[1] and
not x[1]["ext"] in discardType,
map(lambda x: (x, self._getDistrInfo(x)),
availDistrs))
return map(lambda x: x[0],
sorted(availDistrs, self.sortdistrfunc, reverse=True))
def getBestDistributive(self, dirs, system=None, shortname=None, march=None,
version=None, build=None, discardType=()):
@ -228,13 +229,13 @@ class DistroRepository(Linux):
def _findLatestFile(self, dirs, reMatch, keyfunc):
"""Find latest file in dirs, which match by reMatch,
comparable part get by keyfunc"""
existsdirs = list(filter(path.exists, dirs))
listimgs = reduce(lambda x, y: x + list(map(
existsdirs = filter(path.exists, dirs)
listimgs = reduce(lambda x, y: x + map(
lambda x: reMatch.search(
path.join(y, x)),
listDirectory(y))),
listDirectory(y)),
existsdirs, [])
listimgs = [x for x in listimgs if x]
listimgs = filter(lambda x: x, listimgs)
if listimgs:
return max(listimgs, key=keyfunc).group()
return ""
@ -314,21 +315,11 @@ class VariableClImageFilename(DistroRepository, Variable):
"""Set image file"""
if self.Get('cl_action') == 'system' and not isoimage:
raise VariableError(_("You need to select a distribution image"))
try:
d = Distributive.fromFile(isoimage)
if isinstance(d, ArchiveDistributive):
raise VariableError(_("Wrong image file"))
except DistributiveError:
pass
imageData = Distributive().getInfo(isoimage)
if not ("os_linux_shortname" in imageData and
imageData.get('os_linux_build', '') and
"os_arch_machine" in imageData):
raise VariableError(_("Wrong image file"))
if imageData["os_chrootable_set"] == 'off':
raise VariableError(
_("The image is not compatible with the current kernel"))
def humanImageName(self, distroinfo, filepath):
if all(x in distroinfo for x in ("os_linux_shortname",
@ -380,7 +371,9 @@ class VariableClImageFilename(DistroRepository, Variable):
discardType=discardType)
if self.wasSet and not self.value in distros:
distros.append(self.value)
return sorted(((x, self.humanImageName(self._getDistrInfo(x), x)) for x in distros), key=itemgetter(1))
return sorted(map(lambda x: (
x, self.humanImageName(self._getDistrInfo(x), x)), distros),
key=itemgetter(1))
class VariableClImageArchMachine(DistroRepository, Variable):
@ -391,7 +384,7 @@ class VariableClImageArchMachine(DistroRepository, Variable):
type = 'choice'
opt = ['--march']
metavalue = "ARCH"
available_arch = ["x86_64"]
available_arch = ["i686", "x86_64"]
def init(self):
self.label = "%s %s" % (_("Filter"), _("by processor architecture"))
@ -495,17 +488,21 @@ class VariableClImagePath(ReadonlyVariable):
livedistr = ['/run/initramfs/squashfs',
'/run/initramfs/live',
'/mnt/cdrom']
livedistr = [x for x in livedistr if listDirectory(x)][:1]
livedistr = filter(listDirectory,
livedistr)[:1]
else:
livedistr = []
# search all partition for source installation distributive
rootDev = self.Get('os_install_root_dev')
livedistr += [x[0] for x
in zip(self.Get('os_disk_dev'), self.Get('os_disk_content'))
if " live" in x[1] and x[0] != rootDev]
livedistr += \
map(lambda x: x[0],
filter(lambda x: " live" in x[1] and x[0] != rootDev,
zip(self.Get('os_disk_dev'),
self.Get('os_disk_content'))))
# add to standard path
return [x for x in ['/var/calculate/remote/linux',
'/var/calculate/linux'] + livedistr if path.exists(x)]
return filter(path.exists,
['/var/calculate/remote/linux',
'/var/calculate/linux'] + livedistr)
class VariableClSource(ReadonlyVariable):
@ -523,7 +520,6 @@ class VariableClTarget(ReadonlyVariable):
Target distributive
"""
type = "object"
filesystem = "cl_target_fs"
def get(self):
listVars = ['os_install_disk_dev', 'os_install_disk_mount',
@ -537,10 +533,9 @@ class VariableClTarget(ReadonlyVariable):
flashLabel = "{short}-{build}".format(
short="CL", build=self.Get('os_install_linux_build'))
disk = self.Get('os_install_disk_single')
fileSystem = self.Get(self.filesystem) or 'ntfs'
#fileSystem = "vfat"
fileSystem = "vfat"
systemId = FileSystemManager.supportFS.get(
fileSystem, {}).get('msdos', '0b')
'vfat', {}).get('msdos', '0b')
isFormat = self.GetBool('os_install_format_single_set')
partTable = self.select('os_disk_part',
os_disk_dev=disk, limit=1)
@ -569,8 +564,7 @@ class VariableClTarget(ReadonlyVariable):
rootLabel=rootLabel,
isFormat=self.isTrue(isFormat),
systemId=systemId,
partitionTable=partTable,
compression=self.Get('os_install_btrfs_compression'))
partitionTable=partTable)
multiPartition = None
diskData = self.Select(listVars,
where='os_install_disk_mount',
@ -601,27 +595,6 @@ class VariableClTarget(ReadonlyVariable):
return target
class VariableClTargetFs(Variable):
type = 'choice'
opt = ['--fs']
disk = 'os_install_disk_single'
value = 'auto'
metavalue = 'FS_NAME'
def init(self):
self.label = _("File system on flash device")
self.help = _("Create new FS on flash device(formating req)")
def get(self):
if self.value != 'auto':
return self.value
return 'vfat'
def choice(self):
return ['vfat', 'btrfs', 'ntfs', 'ext4',
'ext3', 'ext2', 'xfs']
class VariableClImageNewOnly(Variable):
"""
Distributive image filename
@ -657,13 +630,10 @@ class VariableClImageNewOnly(Variable):
except Exception as e:
raise VariableError(_("Wrong image file"))
if imageData.get('os_linux_build', '') <= \
self.Get('os_linux_build'): #or \
# imageData.get('os_linux_build',
# '') <= self.installedBuild():
self.Get('os_linux_build') or \
imageData.get('os_linux_build',
'') <= self.installedBuild():
raise CommonVariableError(_("The image for update not found"))
if imageData.get('os_linux_build', '') <= self.installedBuild():
raise BuildAlreadyInstalledError(_("Build already installed"))
class VariableClInstallPathFrom(ReadonlyVariable):

@ -24,7 +24,6 @@ from calculate.lib.datavars import (Variable, ReadonlyVariable,
from calculate.lib.utils.files import (readFile,
typeFile, process, listDirectory,
MAGIC_SYMLINK, MAGIC_COMPRESS)
from calculate.lib.utils.kernel import InitrdFile
from calculate.lib.cl_lang import setLocalTranslate
@ -36,7 +35,7 @@ from calculate.lib.utils.files import readLinesFile
from calculate.lib.utils.common import (getKernelUid, getTupleVersion,
getValueFromCmdLine, CmdlineParams)
from itertools import *
from ..distr import DistributiveError
from calculate.install.distr import DistributiveError
class VariableOsInstallKernelScheduler(Variable):
@ -57,10 +56,10 @@ class VariableOsInstallKernelScheduler(Variable):
eq='on')
def get_default(self):
root_devs = self.Select('os_install_disk_parent',
root_dev = self.Select('os_install_disk_parent',
where='os_install_disk_mount',
eq='/', limit=1).split(',')
for root_dev in root_devs:
eq='/', limit=1)
if root_dev:
dev_ssd, dev_virtual = self.Select(['os_device_ssd_set',
'os_device_virtual_set'],
where='os_device_dev',
@ -77,7 +76,7 @@ class VariableOsInstallKernelScheduler(Variable):
else:
currentScheduler = getValueFromCmdLine(
CmdlineParams.IOScheduler)
if currentScheduler in (x[0] for x in self.choice()):
if currentScheduler in map(lambda x: x[0], self.choice()):
return currentScheduler
return self.Get('os_install_kernel_schedule_default')
@ -104,7 +103,7 @@ class VariableOsInstallKernelScheduler(Variable):
return _("I/O scheduler unavailable for Flash install")
class KernelConfig():
class KernelConfig:
def __init__(self, kernel_config):
self.data = readFile(kernel_config).split('\n')
self.config = kernel_config
@ -115,9 +114,6 @@ class KernelConfig():
def __str__(self):
return "kernel config (%s)" % self.config
def __len__(self):
return len(self.data)
def __contains__(self, item):
if "=" in item:
if item.endswith("=n"):
@ -224,9 +220,9 @@ class VariableOsInstallKernelScheduleData(ReadonlyTableVariable):
'CONFIG_IOSCHED_NOOP=y': 'noop',
'CONFIG_IOSCHED_CFQ=y': 'cfq',
'CONFIG_IOSCHED_DEADLINE=y': 'deadline'}
installed = [schedulers.get(x) for x
in self.Get('os_install_kernel_config')
if x in schedulers] or ['cfq']
installed = map(schedulers.get,
filter(lambda x: x in schedulers,
self.Get('os_install_kernel_config'))) or ['cfq']
return [[x, "on" if x in installed else "off"]
for x in sorted(schedulers.values())]
@ -277,32 +273,25 @@ class VariableOsInstallKernelBfqSet(ReadonlyVariable):
return "off"
class VariableOsInstallNomodeset(Variable):
type = "bool"
def get(self):
cmdLine = '/proc/cmdline'
if 'nomodeset' in readFile(cmdLine):
return "on"
return "off"
class VariableOsInstallKernelAttr(Variable):
"""
Install kernel attributes
"""
def get(self):
def generate():
# 5 sec for usb hdd boot
if self.GetBool('os_install_nomodeset'):
yield "nomodeset"
if self.Get('os_install_root_type') == 'usb-hdd':
yield "scandelay=5"
if (self.GetBool('os_install_mdadm_set') or
self.GetBool('os_install_lvm_set')):
yield "rd.auto"
yield "rd.retry=40"
return " ".join(generate())
# on usb-hdd install must be "delay=5"
attr = ""
rdauto = ""
if self.Get('os_install_root_type') == 'usb-hdd':
attr = " scandelay=5"
if self.Get('os_install_mdadm_set') == 'on':
attr += " domdadm"
rdauto = " rd.auto"
if self.Get('os_install_lvm_set') == 'on':
attr += " dolvm"
if not rdauto:
rdauto = " rd.auto"
return attr + rdauto
class VariableOsInstallKernelResume(ReadonlyVariable):
@ -312,18 +301,14 @@ class VariableOsInstallKernelResume(ReadonlyVariable):
def get(self):
"""install kernel resume parameter"""
for dev, partuuid, install in zip(self.Get('os_install_disk_use'),
self.Get('os_install_disk_partuuid'),
self.Get('os_install_disk_mount')):
for dev, install in zip(self.Get('os_install_disk_use'),
self.Get('os_install_disk_mount')):
if install == "swap":
if self.Get('os_install_kernel_tuxonice_set') == 'on':
return "tuxonice tuxonice_resume=%s real_resume=%s" % (
dev, dev)
else:
if partuuid:
return "resume=PARTUUID=%s" % partuuid
else:
return "resume=%s" % dev
return "real_resume=%s" % dev
return ""
@ -336,14 +321,12 @@ class KernelHelper(VariableInterface):
def getFilesByType(self, pathname, descr):
"""Get files from "pathname" has "descr" in descriptions"""
filelist = [path.join(pathname, x) for x in os.listdir(pathname)]
filelist = map(lambda x: path.join(pathname, x), os.listdir(pathname))
ftype = typeFile(magic=MAGIC_COMPRESS | MAGIC_SYMLINK).getMType
filesWithType = [(x, ftype(x)) for x in filelist if path.exists(x)]
return [x for x in filesWithType if x[1] and descr in x[1]]
def getInitrdFiles(self, pathname):
filelist = [path.join(pathname, x) for x in os.listdir(pathname)]
return [x for x in filelist if path.exists(x) and InitrdFile.is_cpio(x)]
filesWithType = map(lambda x: (x, ftype(x)),
filter(path.exists,
filelist))
return filter(lambda x: descr in x[1], filesWithType)
def getInitrd(self, arch, shortname, chroot, kernel, suffix="",
notsuffix=""):
@ -369,13 +352,15 @@ class KernelHelper(VariableInterface):
origKernelVer = resKernelVer.group()
bootdir = path.join(chroot, 'boot')
initramfsFiles = self.getInitrdFiles(bootdir)
initramfsWithVer = [x for x
in [(y, initrd_version_by_name(y)) for y in initramfsFiles]
if (kernelVersion in x[1] or
origKernelVer in x[1]) and
x[0].endswith(suffix) and
(not notsuffix or not x[0].endswith(notsuffix))]
initramfsFiles = self.getFilesByType(bootdir, "ASCII cpio archive")
initramfsWithVer = \
filter(lambda x: (kernelVersion in x[1] or
origKernelVer in x[1]) and \
x[0].endswith(suffix) and \
(
not notsuffix or not x[0].endswith(notsuffix)),
map(lambda x: (x[0], initrd_version_by_name(x[0])),
initramfsFiles))
if initramfsWithVer:
return path.split(min(initramfsWithVer,
key=itemgetter(0))[0])[-1]
@ -393,28 +378,18 @@ class VariableOsInstallKernel(ReadonlyVariable, KernelHelper):
validKernel = listDirectory(modulesdir)
kernelFiles = self.getFilesByType(bootdir, "Linux kernel")
installMarch = self.Get('os_install_arch_machine')
# kernelsWithVer = \
# list(map(lambda x: (
# x[0], (getTupleVersion("".join(x[1].groups()[0:3:2])),
# path.getmtime(x[0]))),
# # convert version to tuple( versionTuple, mtime)
# # version detect, for this version lib contains moudules
# # kernel arch equal install arch
# filter(lambda x: x[1] and x[1].group() in validKernel and
# installMarch in x[0].rpartition('/')[2],
# # (filename,version)
# map(lambda x: (x[0], self.reFindVer.search(x[1])),
# kernelFiles))))
kernelsWithVer = [(x[0],
(getTupleVersion("".join(x[1].groups()[0:3:2])),
path.getmtime(x[0]))) for x
# convert version to tuple( versionTuple, mtime)
# version detect, for this version lib contains moudules
# kernel arch equal install arch
in [y for y
# (filename,version)
in [(z[0], self.reFindVer.search(z[1])) for z in kernelFiles]
if y[1] and y[1].group() in validKernel and installMarch in y[0].rpartition('/')[2]]]
kernelsWithVer = \
map(lambda x: (
x[0], (getTupleVersion("".join(x[1].groups()[0:3:2])),
path.getmtime(x[0]))),
# convert version to tuple( versionTuple, mtime)
# version detect, for this version lib contains moudules
# kernel arch equal install arch
ifilter(lambda x: x[1] and x[1].group() in validKernel and
installMarch in x[0].rpartition('/')[2],
# (filename,version)
imap(lambda x: (x[0], self.reFindVer.search(x[1])),
kernelFiles)))
if kernelsWithVer:
return path.split(max(kernelsWithVer, key=itemgetter(1))[0])[-1]
else:
@ -475,8 +450,9 @@ class VariableOsInstallKernelCpufreq(ReadonlyVariable):
def get(self):
"""Get cpufreq (and other from modules_3= param) from conf.d/modules"""
cpufreqmods = [x.partition('=')[2].strip("\n '\"") for x
in readLinesFile('/etc/conf.d/modules') if x.startswith('modules_3')]
cpufreqmods = map(lambda x: x.partition('=')[2].strip("\n '\""),
filter(lambda x: x.startswith('modules_3'),
readLinesFile('/etc/conf.d/modules')))
if cpufreqmods:
return cpufreqmods[0]
else:
@ -497,19 +473,3 @@ class VariableClInstallKernelBuild(Variable):
Переменная используемся для GRP дистрибутивов и сборки нескольких ядер
"""
value = ""
class VariableClInstallKernelVersion(VariableOsInstallKernelConfig):
"""
Версия ядра в /usr/src/linux
"""
def get(self):
image = self.Get('cl_image')
if image:
with image:
try:
distrPath = image.getDirectory()
return self.get_kernel_src(distrPath)
except DistributiveError as e:
return ""
return ""

@ -47,14 +47,6 @@ class InstallLinux(Linux, VariableInterface):
"""Get by distroinfo or current info"""
return self.__getFromImageOrCurrent(self.current_variable)
class VariableOsInstallChrootableSet(InstallLinux, ReadonlyVariable):
"""Можно ли выполнить chroot в систему"""
current_variable = "os_chrootable_set"
class VariableOsChrootableSet(ReadonlyVariable):
"""Можно ли выполнить chroot в систему"""
type = "boolean"
value = "on"
class VariableOsInstallLinuxShortname(InstallLinux, ReadonlyVariable):
"""Shortname of system"""

@ -53,23 +53,27 @@ class VariableOsInstallLinguas(LocaleVariable):
def get(self):
def get_linguas(lines):
linguas = [x.strip().rpartition('=')[-1].strip('"\'') for x
in lines if x.startswith("LINGUAS=")]
linguas = map(lambda x: x.strip().rpartition('=')[-1].strip('"\''),
filter(lambda x: x.startswith("LINGUAS="),
lines))
return linguas[-1] if linguas else ""
makeconf = '/etc/make.conf'
emerge_config = self.Get('cl_emerge_config')
if emerge_config and "LINGUAS" in emerge_config:
return emerge_config['LINGUAS']
return emerge_config['LINGUAS'].encode('UTF-8')
infocommand = ['emerge', '--info']
defaultLinguas = "bg en de es fr it pl pt_BR nl ru uk"
# get linguas from make.conf, emerge --info or default
curlanguage = self.Get('os_install_locale_language')
return get_linguas(readLinesFile(makeconf)) or \
" ".join((x for x in get_linguas(process(*infocommand).readlines() or "").split() if x == "en" or x == curlanguage)) or defaultLinguas
" ".join(filter(lambda x: x == "en" or x == curlanguage,
get_linguas(
process(
*infocommand).readlines() or "").split())) or \
defaultLinguas
class VariableOsInstallLocaleConsolefont(LocaleVariable):
@ -78,15 +82,38 @@ class VariableOsInstallLocaleConsolefont(LocaleVariable):
"""
def get(self):
return self.getConsolefont(self.Get('os_install_locale_keyboard_layout'))
return self.getFieldByKeymap("consolefont",
self.Get('os_install_locale_keymap'))
class VariableOsInstallLocaleKeymap(LocaleVariable):
"""
Keymap of locale (used for /etc/conf.d/keymaps)
"""
def fix_keymap(self, value):
"""
Исправить название раскладки в зависимости от версии keymap
"""
kbd_ver = isPkgInstalled("sys-apps/kbd", prefix=self.Get('cl_chroot_path'))
map_names = {}
if kbd_ver:
kbd_ver = kbd_ver[0]["PV"]
if cmpVersion(kbd_ver,"2.0.3") < 0:
map_names = {
'-u ruwin_cplk-UTF-8': '-u ruwin_cplk-utf8',
'fi': 'fi-latin9'}
return map_names.get(value,value)
def get(self):
return self.getKeymap(self.Get('os_install_locale_keyboard_layout'))
# get keymap from boot calculate param (keymap specified
# by lang)
keymap = getValueFromCmdLine(CmdlineParams.Calculate,
CmdlineParams.Keymap)
if self.isLangExists(keymap):
return self.fix_keymap(self.getFieldByLang('keymap', keymap))
return self.fix_keymap(self.getFieldByLang("keymap",
self.Get("os_install_locale_lang")))
class VariableOsInstallLocaleDumpkeys(LocaleVariable):
@ -97,12 +124,11 @@ class VariableOsInstallLocaleDumpkeys(LocaleVariable):
def get(self):
# is specified keymap support by locale hash
if self.Get('os_install_locale_keymap') in self.getFields('keymap'):
return self.getDumpkeys_charset(
self.getKeyboardLayout(
keymap=self.Get('os_install_locale_keymap')))
return self.getFieldByKeymap("dumpkeys_charset",
self.Get('os_install_locale_keymap'))
else:
return self.getDumpkeys_charset(
self.Get('os_install_locale_keyboard_layout'))
return self.getFieldByLang("dumpkeys_charset",
self.Get('os_install_locale_lang'))
class VariableOsInstallLocaleLocale(LocaleVariable):
@ -112,7 +138,8 @@ class VariableOsInstallLocaleLocale(LocaleVariable):
def get(self):
"""locale (example: ru_RU.utf8)"""
return self.getLocale(self.Get('os_install_locale_lang'))
return self.getFieldByLang("locale",
self.Get('os_install_locale_lang'))
class VariableOsInstallLocaleLang(LocaleVariable):
@ -133,35 +160,8 @@ class VariableOsInstallLocaleLang(LocaleVariable):
return self.Get('os_locale_lang')
def choice(self):
return list(zip(self.Get('os_lang'),
map(str, self.Get('os_lang', humanreadable=True))))
class VariableOsInstallLocaleKeyboardLayout(LocaleVariable):
"""
Full language (at example: ru_RU)
"""
mode = 'w'
metavalue = "KEYMAP"
type = 'choice'
opt = ["--keymap", "-k"]
def init(self):
self.label = _("Keyboard layout")
self.help = _("set the keyboard layout")
def get(self):
"""lang (example: ru_RU)"""
selected_lang = self.Get('os_install_locale_lang')
current_lang = self.Get('os_locale_lang')
if selected_lang != current_lang:
return self.getKeyboardLayout(lang=self.Get('os_install_locale_lang'))
else:
return self.Get('os_locale_keyboard_layout')
def choice(self):
return list(zip(self.Get('os_keyboard_layout'),
map(str, self.Get('os_keyboard_layout', humanreadable=True))))
return zip(self.Get('os_lang'),
map(str, self.Get('os_lang', humanreadable=True)))
class VariableOsInstallLocaleLanguage(LocaleVariable):
@ -170,7 +170,8 @@ class VariableOsInstallLocaleLanguage(LocaleVariable):
"""
def get(self):
return self.getLanguage(self.Get('os_install_locale_lang'))
return self.getFieldByLang("language",
self.Get('os_install_locale_lang'))
class VariableOsInstallLocaleXkb(LocaleVariable):
@ -179,7 +180,8 @@ class VariableOsInstallLocaleXkb(LocaleVariable):
"""
def get(self):
return self.getXkblayout(self.Get('os_install_locale_keyboard_layout'))
return self.getFieldByLang("xkblayout",
self.Get('os_install_locale_lang'))
class VariableOsInstallLocaleXkbname(LocaleVariable):
@ -271,7 +273,6 @@ class VariableOsInstallClockTimezone(LocaleVariable):
"Africa/Tunis",
"Europe/Kaliningrad",
"Asia/Amman",
"Europe/Athens",
"Europe/Istanbul",
"Asia/Beirut",
"Europe/Helsinki",
@ -333,9 +334,11 @@ class VariableOsInstallClockTimezone(LocaleVariable):
try:
lang = self.Get(self.locale_varname).split('_')[1]
nativeTZ = [x for x in country_timezones[lang]]
nativeTZ = map(lambda x: x.encode('utf-8'),
country_timezones[lang])
source = nativeTZ + ["---"] + \
sorted([x for x in source if not x in nativeTZ], key=sortkey)
sorted(filter(lambda x: not x in nativeTZ, source),
key=sortkey)
except (KeyError, IndexError) as e:
pass
return list(self.generateComments(source))
@ -347,40 +350,14 @@ class VariableOsInstallClockType(Variable):
"""
mode = 'w'
type = 'choice'
opt = ["--hwclock"]
metavalue = "CLOCK"
fallback_value = "local"
opt = ["--clocktype"]
metavalue = "CLOCKTYPE"
def init(self):
self.label = _("Hardware clock type")
self.help = _("set hardware clock type")
def exclude_value(self):
"""
Исключения
"""
root_type = self.Get('os_root_type')
hr_virtual = self.Get('hr_virtual')
# oracle virtualbox по умолчанию для linux систем выставляет
# использование UTC
if root_type == "livecd" and hr_virtual == "virtualbox":
return "UTC"
return None
self.label = _("Clock type")
def get(self):
"""type of clock (UTC or local)"""
# в первую очередь смотрим на параметры загрузки системы
cmdtype = getValueFromCmdLine(CmdlineParams.Calculate,
CmdlineParams.Clock)
if cmdtype and cmdtype in self.choice():
return cmdtype
# во вторую очередь исключения (например для livecd и virtualbox)
clocktype = self.exclude_value()
if clocktype:
return clocktype
# получаем значение из конфигурационных файлов hwclock
clockTypeFile = ['/etc/conf.d/clock', '/etc/conf.d/hwclock']
for f in clockTypeFile:
clock = getValueFromConfig(f, "clock")
@ -389,8 +366,7 @@ class VariableOsInstallClockType(Variable):
return clock.upper()
elif clock.lower() == 'local':
return clock.lower()
# запасное значение
return self.fallback_value
return "local"
def choice(self):
return ["local", "UTC"]

@ -18,38 +18,39 @@ import sys
from calculate.lib.datavars import (Variable, VariableInterface,
ReadonlyVariable, ReadonlyTableVariable,
FieldValue, HumanReadable)
from calculate.lib.utils import device
from calculate.lib.utils.files import (process, checkUtils)
from calculate.lib.cl_lang import setLocalTranslate
setLocalTranslate('cl_install3', sys.modules[__name__])
class LvmHelper(VariableInterface):
def getLvmData(self):
for vg, lv, pv in device.lvm.pvdisplay_full():
yield lv, vg, pv
"""Get route table, exclude specifed iface"""
pvDisplayProg = checkUtils('/sbin/pvdisplay')
pvDisplay = process(pvDisplayProg, "--noh", "-Co",
"lv_name,vg_name,pv_name")
for line in pvDisplay:
line = line.split()
if len(line) == 3:
yield line
#######################################################
# Devices variables
#######################################################
class VariableOsLvmData(ReadonlyTableVariable, LvmHelper):
"""
Information about LVM
Information about disk devices
"""
source = ['os_lvm_lvname',
'os_lvm_vgname',
'os_lvm_pvname',
'os_lvm_pvname_parent'
]
'os_lvm_pvname']
def get(self, hr=HumanReadable.No):
"""LVM hash"""
def generator():
for lvname, vgname, pvname in self.getLvmData():
all_base = device.udev.get_all_base_devices(name=pvname)
full_base = ",".join(all_base)
yield lvname, vgname, pvname, full_base
return list(generator()) or [[]]
return list(self.getLvmData()) or [[]]
setValue = Variable.setValue
@ -79,11 +80,3 @@ class VariableOsLvmPvname(FieldValue, ReadonlyVariable):
type = "list"
source_variable = "os_lvm_data"
column = 2
class VariableOsLvmPvnameParent(FieldValue, ReadonlyVariable):
"""
Phisical volumes names
"""
type = "list"
source_variable = "os_lvm_data"
column = 3

@ -22,7 +22,6 @@ from calculate.lib.datavars import (Variable, VariableError, ReadonlyVariable,
VariableInterface, HumanReadable)
from calculate.lib.cl_lang import setLocalTranslate, _
from calculate.lib.variables.system import RootType
setLocalTranslate('cl_install3', sys.modules[__name__])
@ -30,14 +29,13 @@ from calculate.lib.utils.ip import (getInterfaces, getIp, getMask, getMac,
cidrToMask, maskToCidr, getIpNet, isDhcpIp,
checkIp, checkMask, isSlaveInterface,
getOperState, getPlugged)
import calculate.lib.utils.device as device
from calculate.lib.utils.device import lspci
from calculate.lib.utils.files import (listDirectory, readLinesFile)
from calculate.lib.utils import ip
from calculate.lib.utils.portage import isPkgInstalled
from operator import itemgetter
from itertools import *
from ..distr import DistributiveError
from calculate.install.distr import DistributiveError
class NetHelper(VariableInterface):
@ -58,58 +56,9 @@ class NetHelper(VariableInterface):
_notin=('off', 'dhcp'), limit=1):
return _("Network routing configuration is not available if all "
"interfaces are set to DHCP")
if self.Get('cl_network_migrate_set') == 'on':
return _("Network settings unavailable with use settings migration")
return ""
class VariableClNetworkConfigureSet(Variable):
"""
Выполнять ли настройку сети шаблонами
"""
type = "bool"
opt = ["--network"]
def init(self):
self.label = _("Reconfigure network")
self.help = _("reconfigure network")
def get(self):
if self.GetBool("cl_network_migrate_set"):
return "off"
else:
return "on"
class VariableClNetworkMigrateSet(Variable):
"""
Использовать миграцию для переноса настроек
"""
type = "bool"
element = "radio"
def init(self):
self.label = _("Network")
self.help = _("use the network migration")
def choice(self):
return [("on", _("Migrate network settings")),
("off", _("Manually network configuration"))]
def get(self):
for manvar in ("os_install_net_conf",
"os_install_net_data",
"os_install_net_fqdn",
"os_install_ntp",
"os_install_net_dns",
"os_install_net_dns_search",
"os_install_net_route_data"):
if self.is_console_set(manvar):
return "off"
else:
return "on"
class VariableOsInstallNtp(NetHelper, Variable):
"""
NTP server for system
@ -130,22 +79,6 @@ class VariableOsInstallProxy(NetHelper, Variable):
value = ""
class VariableOsInstallNetType(NetHelper, ReadonlyVariable):
"""
Тип сетевого устройства: сейчас eth или wlan
"""
type = "list"
def _getType(self, iface):
if ip.isWireless(iface):
return "wlan"
return "eth"
def get(self):
interfaces = self.Get('os_install_net_interfaces')
return [self._getType(x) for x in interfaces]
class VariableOsInstallNetInterfaces(NetHelper, ReadonlyVariable):
"""
Net interface devices
@ -188,7 +121,8 @@ class VariableOsNetInterfacesInfo(NetHelper, ReadonlyVariable):
else:
listInterfacesInfo.append((interface,
ipaddr if ipaddr else _("Off")))
return ", ".join(("%s (%s)" % (x[0], x[1]) for x in listInterfacesInfo))
return ", ".join(map(lambda x: "%s (%s)" % (x[0], x[1]),
listInterfacesInfo))
class VariableOsInstallNetData(NetHelper, TableVariable):
@ -253,8 +187,6 @@ class VariableOsInstallNetFqdn(NetHelper, Variable):
def check(self, value):
maxfqdn = 254
if " " in value:
raise VariableError(_("Wrong hostname"))
if len(value) > maxfqdn:
raise VariableError(
_("The hostname length should be less than %d") % maxfqdn)
@ -299,9 +231,8 @@ class VariableOsInstallNetName(NetHelper, ReadonlyVariable):
rePci = re.compile(r"(\d\d:\d\d\.\d)(?:/[^/]+){2}$")
def getPci(interface):
pathname = path.realpath(
device.sysfs.syspath(device.sysfs.Path.ClassNet, interface))
pathname = path.realpath(path.join('/sys/class/net',
interface))
pci = rePci.search(pathname)
if pci:
return pci.group(1)
@ -309,31 +240,11 @@ class VariableOsInstallNetName(NetHelper, ReadonlyVariable):
return ""
pciEthernet = lspci(shortInfo=True)
return ["{vendor} {name}".format(**x) for x
in [pciEthernet.get(getPci(y), {'vendor': _("Unknown"), 'name': _("vendor")}) for y
in self.Get('os_install_net_interfaces')]]
class VariableOsInstallNetMacType(NetHelper, ReadonlyVariable):
"""
Net devices mac (Example: local/OUI)
"""
type = "list"
reLocal = re.compile("^.[2367abef]:.*$", re.I)
def init(self):
self.label = _("Mac type")
def _mactype(self, mac):
if not mac:
return ""
if not self.reLocal.match(mac):
return "OUI"
else:
return "local"
def get(self):
return [self._mactype(x) for x in self.Get('os_install_net_mac')]
return map(lambda x: "{vendor} {name}".format(**x),
map(lambda x: pciEthernet.get(getPci(x),
{'vendor': _("Unknown"),
'name': _("vendor")}),
self.Get('os_install_net_interfaces')))
class VariableOsInstallNetMac(NetHelper, ReadonlyVariable):
@ -346,7 +257,8 @@ class VariableOsInstallNetMac(NetHelper, ReadonlyVariable):
self.label = _("MAC")
def get(self):
return [getMac(x).lower() for x in self.Get('os_install_net_interfaces')]
return map(lambda x: getMac(x).lower(),
self.Get('os_install_net_interfaces'))
class VariableOsInstallNetStatus(NetHelper, Variable):
@ -359,7 +271,8 @@ class VariableOsInstallNetStatus(NetHelper, Variable):
self.label = _("IP address")
def get(self):
return [self.getDefaultValue(x) for x in self.Get('os_install_net_interfaces')]
return map(self.getDefaultValue,
self.Get('os_install_net_interfaces'))
def getDefaultValue(self, iface):
def statusValue(ipaddr, dhcp):
@ -382,14 +295,16 @@ class VariableOsInstallNetStatus(NetHelper, Variable):
if rootDevNfs or isDhcpIp(iface) else "off")
def set(self, value):
value = (x.lower() if x else x for x in value)
value = map(lambda x: x.lower() if x else x, value)
ifaces = self.Get('os_install_net_interfaces')
return [self.getDefaultValue(x[1]) if x[0] == "auto" else x[0] for x
in zip(value, ifaces)]
return map(lambda x: self.getDefaultValue(x[1]) \
if x[0] == "auto" else x[0],
zip(value, ifaces))
def check(self, value):
for status in value:
if status not in (x[0] for x in self.choice()) and not checkIp(status):
if status not in map(lambda x: x[0], self.choice()) and \
not checkIp(status):
raise VariableError(_("Wrong IP address %s") % status)
def choice(self):
@ -408,10 +323,10 @@ class VariableOsInstallNetIp(NetHelper, ReadonlyVariable):
self.label = _("IP address")
def get(self):
return ["" if x[1].lower() == "off" else
getIp(x[0]) if x[1].lower() == "dhcp" else x[1] for x
in zip(self.Get('os_install_net_interfaces'),
self.Get('os_install_net_status'))]
return map(lambda x: "" if x[1].lower() == "off" else
getIp(x[0]) if x[1].lower() == "dhcp" else x[1],
zip(self.Get('os_install_net_interfaces'),
self.Get('os_install_net_status')))
# def check(self,value):
# dhcps = self.Get('os_install_net_dhcp_set')
@ -432,9 +347,9 @@ class VariableOsInstallNetNetwork(NetHelper, ReadonlyVariable):
self.label = _("Network")
def get(self):
return [getIpNet(x[0], x[1]) if x[0] and x[1] else "" for x
in zip(self.Get('os_install_net_ip'),
self.Get('os_install_net_mask'))]
return map(lambda x: getIpNet(x[0], x[1]) if x[0] and x[1] else "",
zip(self.Get('os_install_net_ip'),
self.Get('os_install_net_mask')))
class VariableOsInstallNetCidr(NetHelper, ReadonlyVariable):
@ -450,7 +365,8 @@ class VariableOsInstallNetCidr(NetHelper, ReadonlyVariable):
"""
Get CIDR of ip,net (Example: 24)
"""
return [maskToCidr(x) if x else '' for x in self.Get('os_install_net_mask')]
return map(lambda x: maskToCidr(x) if x else '',
self.Get('os_install_net_mask'))
class VariableOsInstallNetMask(NetHelper, Variable):
@ -463,8 +379,8 @@ class VariableOsInstallNetMask(NetHelper, Variable):
self.label = _("Mask")
def get(self):
return [cidrToMask(getMask(x)) for x
in self.Get('os_install_net_interfaces')]
return map(lambda x: cidrToMask(getMask(x)),
self.Get('os_install_net_interfaces'))
def set(self, value):
"""
@ -477,13 +393,14 @@ class VariableOsInstallNetMask(NetHelper, Variable):
else:
return x
res = [convertCidrToMask(x) for x in value]
res = map(convertCidrToMask, value)
return res
def check(self, value):
dhcps = self.Get('os_install_net_status')
wrongMask = [x for x in zip(value, dhcps)
if (x[0] or not x[1] in ("off", "dhcp")) and not checkMask(x[0])]
wrongMask = filter(lambda x: (x[0] or not x[1] in ("off", "dhcp")) and \
not checkMask(x[0]),
zip(value, dhcps))
if wrongMask:
raise VariableError(_("Wrong mask %s") % wrongMask[0][0])
@ -505,8 +422,8 @@ class VariableOsInstallNetDhcpSet(NetHelper, Variable):
self.label = _("DHCP")
def get(self):
return ["on" if x == "dhcp" else "off" for x
in self.Get('os_install_net_status')]
return map(lambda x: "on" if x == "dhcp" else "off",
self.Get('os_install_net_status'))
class VariableOsInstallNetRouteData(NetHelper, TableVariable):
@ -528,25 +445,26 @@ class VariableOsInstallNetRouteData(NetHelper, TableVariable):
self.label = _("Routing")
self.help = \
_("add a routing rule (specified as "
"NETWORK:GATEWAY[:DEV[:SOURCE]])")
"NETWORK:[GATEWAY][:DEV[:SOURCE]])")
def get(self, hr=HumanReadable.No):
"""Routing hash"""
interfaces = self.Get('os_install_net_interfaces')
interfaces_status = self.Get('os_install_net_status')
interfaces_network = self.Get('os_install_net_network')
staticInterface = [itemgetter(0, 2)(x) for x
in zip(interfaces, interfaces_status, interfaces_network)
if not x[1] in ("off", "dhcp")]
staticInterface = \
map(itemgetter(0, 2),
filter(lambda x: not x[1] in ("off", "dhcp"),
zip(interfaces, interfaces_status, interfaces_network)))
route_data = []
if staticInterface:
staticInterface, skipNet = list(zip(*staticInterface))
return [[x[0],
x[1].get('via', ''),
x[1].get('dev', ''),
x[1].get('src', '')] for x
in ip.getRouteTable(staticInterface)
if not x[0] in skipNet] or [[]]
staticInterface, skipNet = zip(*staticInterface)
return map(lambda x: [x[0],
x[1].get('via', ''),
x[1].get('dev', ''),
x[1].get('src', '')],
ifilter(lambda x: not x[0] in skipNet,
ip.getRouteTable(staticInterface))) or [[]]
return [[]]
def getHumanReadableAuto(self):
@ -556,13 +474,7 @@ class VariableOsInstallNetRouteData(NetHelper, TableVariable):
"""
Standard action for set value
"""
interfaces = self.Get('os_install_net_interfaces')
if len(interfaces) == 1:
wrapper = lambda x: x if not x else [x[0],x[1],interfaces[0],x[3]]
else:
wrapper = lambda x: x
self.value = self.set([wrapper(x) for x in value])
self.value = self.set(value)
self.wasSet = True
self.invalid = False
# run check
@ -588,11 +500,12 @@ class VariableOsInstallNetRouteNetwork(NetHelper, FieldValue, Variable):
##########################
# detect duplicate network
##########################
for wrongnet in filterfalse(ip.checkNet,
filter("default".__ne__,
for wrongnet in ifilterfalse(ip.checkNet,
ifilter("default".__ne__,
value)):
raise VariableError(_("Wrong network %s") % wrongnet)
dupNetwork = list(set([x for x in value if value.count(x) > 1]))
dupNetwork = list(set(filter(lambda x: value.count(x) > 1,
value)))
if dupNetwork:
raise VariableError(
_("Network '%s' is used more than once") % dupNetwork[0])
@ -615,14 +528,19 @@ class VariableOsInstallNetRouteGw(NetHelper, FieldValue, Variable):
NET, GW = 0, 1
netsGw = zip(self.Get('os_install_net_route_network'),
value)
nets = [x for x in chain(self.Get('os_install_net_route_network'),
self.Get('os_install_net_network'))
if x and x != "default"]
nets = filter(lambda x: x and x != "default",
chain(self.Get('os_install_net_route_network'),
self.Get('os_install_net_network')))
for wrongip in filterfalse(ip.checkIp, value):
for wrongip in ifilterfalse(ip.checkIp, value):
raise VariableError(_("Wrong gateway IP %s") % wrongip)
wrongGws = [x[GW] for x in [y for y in netsGw if y[GW]]
if not ip.isIpInNet(x[GW], *(set(nets) - set(x[NET])))]
wrongGws = map(lambda x: x[GW],
filter(lambda x: not ip.isIpInNet(x[GW],
*(set(nets) - set(
x[NET]))),
filter(lambda x: x[GW],
netsGw)))
if wrongGws:
raise VariableError(_("Gateways %s are unreachable") %
(",".join(wrongGws)))
@ -658,11 +576,12 @@ class VariableOsInstallNetRouteSrc(NetHelper, FieldValue, Variable):
return [""] + self.Get('os_install_net_ip')
def check(self, value):
for wrongip in filterfalse(ip.checkIp,
filter(None, value)):
for wrongip in ifilterfalse(ip.checkIp,
ifilter(None, value)):
raise VariableError(_("Wrong source IP %s") % wrongip)
ipAddrs = self.Get('os_install_net_ip')
wrongIps = [x for x in value if x and not x in ipAddrs]
wrongIps = filter(lambda x: x and not x in ipAddrs,
value)
if wrongIps:
raise VariableError(
_("Wrong IP address %s in the specified source IP") %
@ -675,18 +594,19 @@ class VariableOsInstallNetRoute(NetHelper, ReadonlyVariable):
"""
def performRouteData(self, performFunc):
routeMatrix = list(zip(self.Get('os_install_net_route_network'),
routeMatrix = zip(self.Get('os_install_net_route_network'),
self.Get('os_install_net_route_gw'),
self.Get('os_install_net_route_dev'),
self.Get('os_install_net_route_src')))
self.Get('os_install_net_route_src'))
DEV, IP, CIDR, NET = 0, 1, 2, 1
return [performFunc(x[DEV], x[NET], routeMatrix) for x
# ip and mask to ip/net
in [(y[DEV], ip.getIpNet(y[IP], cidr=y[CIDR]))
if y[IP] and y[CIDR] else (y[DEV], "") for y
in zip(self.Get('os_install_net_interfaces'),
return map(lambda x: performFunc(x[DEV], x[NET], routeMatrix),
# union ip and mask to ip/net
map(lambda x: (x[DEV], ip.getIpNet(x[IP], cidr=x[CIDR])) \
if x[IP] and x[CIDR] else (x[DEV], ""),
# filter(lambda x:x[IP] and x[CIDR],
zip(self.Get('os_install_net_interfaces'),
self.Get('os_install_net_ip'),
self.Get('os_install_net_cidr'))]]
self.Get('os_install_net_cidr'))))
def get(self):
"""Route info for conf.d/net"""
@ -699,25 +619,17 @@ class VariableOsInstallNetRoute(NetHelper, ReadonlyVariable):
def getRouteForInterfaceConf(interface, net, routeMatrix):
NET, GW, DEV, SRC = 0, 1, 2, 3
# filter by interface and discard direct routes
# example: for 192.168.1.5/24 discard 192.168.1.0/24 net
route_list = [x for x in routeMatrix
if (interface == x[DEV] or
defaultDev and
interface == defaultDev) and
net != x[NET]]
nets = []
route_list_uniqnet = []
for net, gw, dev, src in route_list:
if net not in nets:
route_list_uniqnet.append([net, gw, dev, src])
nets.append(net)
route_strs = ("{net}{gateway}{src}".format(net=x[NET], gateway=" via %s" % x[GW]
if x[GW] else "", src=" src %s" % x[SRC] if x[SRC] else "") for x
in route_list_uniqnet)
# build string for route from net,gateway,dev and src
return "\n".join(route_strs)
return "\n".join(
# build string for route from net,gateway,dev and src
map(lambda x: "{net}{gateway}{src}".format(
net=x[NET],
gateway=" via %s" % x[GW] if x[GW] else "",
src=" src %s" % x[SRC] if x[SRC] else ""),
# filter by interface and discard direct routes
# example: for 192.168.1.5/24 discard 192.168.1.0/24 net
filter(lambda x: (interface == x[DEV] or defaultDev and
interface == defaultDev) \
and net != x[NET], routeMatrix)))
return self.performRouteData(getRouteForInterfaceConf)
@ -739,42 +651,29 @@ class VariableOsInstallNetNmroute(VariableOsInstallNetRoute):
def getRouteForInterfaceNM(interface, net, routeMatrix):
NET, GW, DEV, SRC = 0, 1, 2, 3
defaultGw = ["%s;" % x[GW] for x in routeMatrix
if interface == x[DEV] and x[NET] == "default"]
# return "{0}\n".format(defaultGw[0] if defaultGw else "") + \
# "\n".join(
# # build string for route from net,gateway,dev and src
# map(lambda
# x: "routes{num}={ip};{cidr};{gateway};0;".format(
# num=x[0] + 1,
# ip=x[1][NET].partition('/')[0],
# cidr=x[1][NET].partition('/')[2],
# gateway=x[1][GW] if x[1][GW] else "0.0.0.0"),
# # filter by interface and discard direct routes
# # example: for 192.168.1.5/24 discard 192.168.1.0/24 net
# enumerate(
# filter(lambda x: (interface == x[
# DEV] or defaultDev and
# interface == defaultDev) and net !=
# x[
# NET] and \
# x[NET] != "default",
# routeMatrix))))
return "{0}\n".format(defaultGw[0] if defaultGw else "") + "\n".join(
# build string for route from net,gateway,dev and src
("routes{num}={ip};{cidr};{gateway};0;".format(
defaultGw = map(lambda x: "%s;" % x[GW],
filter(lambda x: interface == x[DEV] and \
x[NET] == "default",
routeMatrix))
return "{0}\n".format(defaultGw[0] if defaultGw else "") + \
"\n".join(
# build string for route from net,gateway,dev and src
map(lambda
x: "routes{num}={ip};{cidr};{gateway};0;".format(
num=x[0] + 1,
ip=x[1][NET].partition('/')[0],
cidr=x[1][NET].partition('/')[2],
gateway=x[1][GW] if x[1][GW] else "0.0.0.0") for x
# filter by interface and discard direct routes
# example: for 192.168.1.5/24 discard 192.168.1.0/24 net
in enumerate((x for x in routeMatrix
if (interface == x[DEV] or
defaultDev and
interface == defaultDev) and
net !=x[NET] and
x[NET] != "default"))))
gateway=x[1][GW] if x[1][GW] else "0.0.0.0"),
# filter by interface and discard direct routes
# example: for 192.168.1.5/24 discard 192.168.1.0/24 net
enumerate(
filter(lambda x: (interface == x[
DEV] or defaultDev and
interface == defaultDev) and net !=
x[
NET] and \
x[NET] != "default",
routeMatrix))))
return self.performRouteData(getRouteForInterfaceNM)
@ -794,8 +693,10 @@ class VariableOsInstallNetConfAvailable(NetHelper, Variable):
with image as distr:
try:
distrPath = image.getDirectory()
return [itemgetter(0, 2)(x) for x in mapNetConf
if not x[1] or isPkgInstalled(x[1], prefix=distrPath)]
return map(itemgetter(0, 2),
filter(lambda x: not x[1] or isPkgInstalled(x[1],
prefix=distrPath),
mapNetConf))
except DistributiveError as e:
pass
return sorted(map(itemgetter(0, 2), mapNetConf[-1:]), key=itemgetter(1))
@ -815,9 +716,10 @@ class VariableOsInstallNetConf(NetHelper, Variable):
def get(self):
"""Net setup (networkmanager or openrc)"""
if [x for x in listDirectory('/etc/runlevels/boot') +
listDirectory('/etc/runlevels/default')
if x.lower() == "networkmanager"] or self.Get('os_root_type') == "livecd":
if filter(lambda x: x.lower() == "networkmanager",
listDirectory('/etc/runlevels/boot') +
listDirectory('/etc/runlevels/default')) \
or self.Get('os_root_type') == "livecd":
nm = "networkmanager"
else:
nm = ""
@ -859,9 +761,10 @@ class VariableOsInstallNetDnsSearch(NetHelper, Variable):
def get(self):
"""Get current name servers"""
dnsSearch = " ".join((x.strip().partition("search")[2].strip() for x
in readLinesFile('/etc/resolv.conf')
if x.lstrip().startswith("search")))
dnsSearch = " ".join(
map(lambda x: x.strip().partition("search")[2].strip(),
filter(lambda x: x.lstrip().startswith("search"),
readLinesFile('/etc/resolv.conf'))))
return "" if self.isDNSByDHCP() else dnsSearch
def humanReadable(self):
@ -885,16 +788,17 @@ class VariableOsInstallNetDns(VariableOsInstallNetDnsSearch):
return " ".join(re.split('[; ,]', value))
def get(self):
dnsIps = (x for x
in (y.strip().partition("nameserver")[2].strip() for y
in readLinesFile('/etc/resolv.conf')
if y.lstrip().startswith("nameserver"))
if ip.checkIp(x))
dnsIps = filter(ip.checkIp,
map(lambda x: x.strip().partition("nameserver")[
2].strip(),
filter(
lambda x: x.lstrip().startswith("nameserver"),
readLinesFile('/etc/resolv.conf'))))
return "" if self.isDNSByDHCP() else " ".join(dnsIps)
def check(self, value):
reIp = re.compile(ip.IP_ADDR)
if any(filterfalse(reIp.match, value.split(' '))):
if any(ifilterfalse(reIp.match, value.split(' '))):
raise VariableError(_("Wrong IP address for DNS"))
def humanReadable(self):
@ -927,12 +831,10 @@ class VariableOsInstallPxeIp(Variable):
self.help = "set IP address for PXE server"
def get(self):
ips = self.Get('os_net_ip').split(',')
for ipaddr in filter(None, ips):
for ipaddr in ifilter(None, self.Get('os_install_net_ip')):
return ipaddr
else:
return ""
def choice(self):
ips = self.Get('os_net_ip').split(',')
return [x for x in ips if x]
return filter(None, self.Get('os_install_net_ip'))

@ -21,23 +21,20 @@ from os import path
from calculate.lib.datavars import (Variable, VariableError, ReadonlyVariable,
TableVariable, PasswordError,
DataVarsError, VariableInterface)
from ..fs_manager import FileSystemManager
from calculate.install.fs_manager import FileSystemManager
from calculate.lib.utils.files import (readFile, getProgPath, process,
readLinesFile, readFileEx)
from calculate.lib.utils.common import (getPasswdUsers, getUserGroups,
getGroups, CmdlineParams)
readLinesFile)
from calculate.lib.utils.common import getPasswdUsers, getUserGroups, getGroups, \
CmdlineParams
from calculate.lib.utils.common import getValueFromConfig, getValueFromCmdLine
from calculate.lib.utils.common import getUserPrimaryGroup
from calculate.lib.utils.portage import isPkgInstalled
import calculate.lib.utils.device as device
from calculate.lib.encrypt import sha256_crypt
from calculate.lib.variables.system import RootType
import calculate.lib.variables.env as libenv
from calculate.lib.encrypt import get_shadow_hash, get_grub_hash
from calculate.core.server.admin import Admins
from calculate.lib.utils.device import getUdevDeviceInfo
from crypt import crypt
from autopartition import SchemeOpt, SchemeDevices
from calculate.lib.encrypt import encrypt
import calculate.lib.cl_ini_parser as cl_ini_parser
from calculate.lib.cl_template import SystemIni
from .distr import DistributiveError
from calculate.lib.cl_lang import setLocalTranslate, _
setLocalTranslate('cl_install3', sys.modules[__name__])
@ -48,7 +45,6 @@ class UserHelper(VariableInterface):
Locale variables not using for flash installation
"""
xorg_need = False
stub_hash_value = "{SHA256}"
def uncompatible(self):
"""
@ -61,43 +57,6 @@ class UserHelper(VariableInterface):
return ""
class GrubHelper(VariableInterface):
grub_passwd_file = "/etc/grub.d/07_passwd"
def read_hash_from_passwd(self):
"""
Получить пароль из конфигурационного файла grub
"""
data = readFile(self.grub_passwd_file)
reRootPwd = re.compile("password_pbkdf2 root (\S+)")
pwd = reRootPwd.search(data)
if pwd:
return pwd.group(1)
return ""
class VariableOsInstallLibPath(ReadonlyVariable):
"""
Использовать lib или lib64
"""
def get(self):
if self.Get('os_install_arch_machine') == 'x86_64':
return "lib64"
else:
return "lib"
class VariableOsInstallPython(libenv.VariableOsPython):
"""
Текущий python
"""
def get_root(self):
return self.Get('cl_chroot_path')
def get_usrlib(self):
return "/usr/%s" % self.Get('os_install_lib_path')
class VariableOsInstallScratch(ReadonlyVariable):
"""
Install system in scratch mode
@ -121,7 +80,7 @@ class VariableOsFormatType(ReadonlyVariable):
def get(self):
"""Filesystem format support by calcualte-install"""
return list(FileSystemManager.supportFS.keys())
return FileSystemManager.supportFS.keys()
class VariableOsFormatUse(ReadonlyVariable):
@ -141,10 +100,10 @@ class VariableOsFormatUse(ReadonlyVariable):
return "no"
def get(self):
return [self.checkFunc(x) for x in self.Get('os_format_type')]
return map(self.checkFunc, self.Get('os_format_type'))
class VariableClMigrateRootPwdPlain(GrubHelper, UserHelper, Variable):
class VariableClMigrateRootPwd(UserHelper, Variable):
"""
Root password
"""
@ -152,146 +111,42 @@ class VariableClMigrateRootPwdPlain(GrubHelper, UserHelper, Variable):
opt = ["--root-password"]
metavalue = 'PASSWORD'
untrusted = True
check_after = ["cl_grub"]
def get(self):
shadow_pwd = self.Get('cl_migrate_root_shadow_pwd')
if shadow_pwd:
return self.stub_hash_value
return ""
def init(self):
self.help = _("specify the root password")
self.label = _("Root password")
def check(self, value):
if not value and not self.Get('cl_migrate_root_shadow_pwd'):
raise PasswordError(_("Enter password for user %s") % "root")
# если plain пароля нет (есть только хэш), но требуется установить
# пароль на grub (cl_grub_passwd_set), при этом нет 07_passwd
if (value == self.stub_hash_value and
not self.read_hash_from_passwd() and
self.GetBool('cl_grub_passwd_set')):
raise PasswordError(_("Please enter a root password for Grub"))
class VariableClMigrateRootPwd(ReadonlyVariable):
"""
Хэш root пароля
"""
def get(self):
value = self.Get('cl_migrate_root_pwd_plain')
if value and value != UserHelper.stub_hash_value:
return get_shadow_hash().hash(value)
return self.Get('cl_migrate_root_shadow_pwd')
class VariableClMigrateRootShadowPwd(ReadonlyVariable):
"""
Хэш root пароля из файла /etc/shadow. Если пароль root, то
содержит пустую строку
"""
def get(self):
rootPasswd = [x[1] for x
in [y.split(':')[0:2] for y in readLinesFile('/etc/shadow')]
if "root".__eq__(x)]
rootPasswd = map(lambda x: x[1],
filter("root".__eq__,
map(lambda x: x.split(':')[0:2],
readLinesFile('/etc/shadow'))))
if rootPasswd:
rootPasswd = rootPasswd[0]
else:
rootPasswd = ""
# if root password is "root"
enc = get_shadow_hash()
if rootPasswd:
if enc.identify(rootPasswd):
if enc.verify("root", rootPasswd):
rootPasswd = ""
else:
salt = "".join(rootPasswd.rpartition("$")[:1])
if salt and crypt("root", salt) == rootPasswd:
rootPasswd = ""
return rootPasswd or ""
class VariableClGrubPasswdSet(GrubHelper, Variable):
"""
Использовать при установке системы пароль root как пароль для grub
"""
type = 'bool'
opt = ["--grub-passwd"]
def init(self):
self.help = _("use the root password to edit Grub")
self.label = _("Use the root password to edit Grub")
def get(self):
if (self.read_hash_from_passwd() or
self.Get('os_root_type_ext') in RootType.Live):
return Variable.On
else:
return Variable.Off
class VariableClGrubPwd(GrubHelper, Variable):
"""
Хэш пароля на grub
"""
opt = ["--passwd"]
type = "password"
def init(self):
self.help = _("set grub password")
self.label = _("Grub password")
def get(self):
system_action = self.Get('cl_action') == "system"
if self.GetBool('cl_grub_remove_pwd_set'):
return ""
use_grub_passwd = self.GetBool('cl_grub_passwd_set')
passwd_hash = self.read_hash_from_passwd()
if passwd_hash:
if not system_action or use_grub_passwd:
return passwd_hash
if use_grub_passwd:
value = self.Get('cl_migrate_root_pwd_plain')
if value and value != UserHelper.stub_hash_value:
enc = get_grub_hash()
return enc.hash(value)
return ""
def set(self, value):
"""
Поддержка использвания как шифрованного хэша так и plain
Encrypt password
"""
enc = get_grub_hash()
# используется hash
if enc.identify(value):
reCheck = re.compile("^\$[^$]+\$[^$]+\$.*$")
encryptObj = encrypt()
if reCheck.match(value) or not value:
return value
# отключение
if value in ("", "none"):
return ""
# используется plain
return enc.hash(value)
else:
return encryptObj.getHashPasswd(value, "shadow_ssha256")
def check(self, value):
if value and self.GetBool('cl_grub_remove_pwd_set'):
raise VariableError(
_("You cannot set a password and remove the "
"existing password at a time"))
class VariableClGrubRemovePwdSet(Variable):
"""
Удалить пароль из grub
"""
type = "bool"
guitype = "hidden"
value = Variable.Off
opt = ["--remove-passwd"]
def init(self):
self.help = _("remove the password protection for editing the Grub menu")
self.label = _("Remove the password protection on Grub")
if not value:
raise PasswordError(_("Password for user %s missing") % "root")
class VariableClInstallHomeCryptSet(UserHelper, Variable):
@ -319,41 +174,21 @@ class VariableClMigrateData(UserHelper, TableVariable):
"""
type = 'table'
opt = ["--user", "-u"]
metavalue = 'USER[:ADMIN[:GROUPS]]'
source = ['cl_migrate_user', 'cl_migrate_admin',
'cl_migrate_user_groups',
metavalue = 'USER[:GROUPS]'
source = ['cl_migrate_user', 'cl_migrate_user_groups',
'cl_migrate_user_pwd']
untrusted = True
def init(self):
self.help = _("add a user to the installed system. USER is username. "
"ADMIN is administrator rights ({alllist}, "
"{none_value} by default). "
"GROUPS is list user supplimentary groups "
"(comma delimeter). "
"Use '{none_value}' value to discard user migration").format(
alllist="none, update, all", none_value="none")
self.help = _("add a user to the installed system")
self.label = _("Migrating users")
def set(self, value):
value = [
[x[0],
VariableClMigrateAdmin.pre_set(x[1]),
VariableClMigrateUserGroups.pre_set(x[2]),
x[3]]
for x in value
]
if len(value) == 1:
if len(value[0]) > 1 and value[0][0] == 'none':
return [[]]
return value
class VariableClMigrateDataBrief(UserHelper, TableVariable):
"""
User migrate data table for brief view
"""
source = ['cl_migrate_user', 'cl_migrate_admin', 'cl_migrate_user_groups']
source = ['cl_migrate_user', 'cl_migrate_user_groups']
def init(self):
self.label = _("Migrating users")
@ -366,116 +201,34 @@ class VariableClMigrateUser(UserHelper, Variable):
type = 'list'
def init(self):
self.label = _("User")
self.label = _("Users")
def get(self):
"""
Migrating users (users above 1000 uid)
"""
cached_users = getPasswdUsers(
datafile="var/lib/calculate/calculate-client/cache/create_passwd")
return [x for x in getPasswdUsers() if x != "root" and x not in cached_users]
return filter("root".__ne__, getPasswdUsers())
def check(self, value):
"""
Проверка на корректное имя пользователя
"""
if any(not x for x in value):
raise VariableError(_("Username is missing"))
class VariableClMigrateAdmin(UserHelper, Variable):
"""
Migrate users list
"""
type = 'choice-list'
default_value = ""
aliases = {'system_update': 'update'}
def init(self):
self.label = _("Administrator")
def choice(self):
return [
("", ""),
("update", _("System update")),
("all", _("Full access")),
]
@classmethod
def pre_set(cls, value):
return {'none':''}.get(value, value)
def get_alias(self, value):
return self.aliases.get(value, value)
def get(self):
"""
Migrating users (users above 1000 uid)
"""
admins = Admins(self.parent)
return [self.get_alias(admins[x]) or self.default_value
for x in self.Get('cl_migrate_user')]
def set(self, value):
return [x if x else self.default_value for x in value]
class VariableOsAvailableGroups(ReadonlyVariable):
"""
Список доступных в дистрибутиве групп
"""
type = 'list'
def get(self):
image = self.Get('cl_image')
if image:
with image:
try:
distrPath = image.getDirectory()
return getGroups(distrPath)
except DistributiveError:
pass
return getGroups()
class VariableClMigrateUserGroups(UserHelper, Variable):
"""
Migrate users groups
"""
type = 'choice-list-list'
defaultGroupList = sorted(["users", "audio", "cdrom", "video",
"cdrw", "usb", "plugdev", "games", "lp", "lpadmin",
"scanner", "uucp"])
default_value = "default"
@classmethod
def pre_set(cls, value):
"""
Обработать значение до передачи его из таблицы в поле
"""
if not any(value):
return [cls.default_value]
else:
return value
defaultGroupList = ["users", "wheel", "audio", "cdrom", "video",
"cdrw", "usb", "plugdev", "games", "lp", "scanner",
"uucp"]
def getDefaultGroups(self):
return list(set(self.defaultGroupList) & set(self.Get('os_available_groups')))
return list(set(self.defaultGroupList) & set(getGroups()))
def init(self):
self.label = _("Groups")
def process_groups(self, values):
groupslist = list(set(self.defaultGroupList)
& set(self.Get('os_available_groups')))
for value in values:
if value == self.default_value:
for i in groupslist:
yield i
else:
yield value
def set(self, value):
value = [sorted(list(set(self.process_groups(x)))) for x in value]
value = map(lambda x: (filter(None, x) if x and any(x)
else self.getDefaultGroups()),
value)
return value
def getPrimaryGroup(self, username):
@ -489,16 +242,17 @@ class VariableClMigrateUserGroups(UserHelper, Variable):
User groups
"""
passwdList = getPasswdUsers()
return [sorted(self.getPrimaryGroup(x) + (getUserGroups(x)
if x in passwdList else self.getDefaultGroups())) for x
in self.Get('cl_migrate_user')]
return map(lambda x: (self.getPrimaryGroup(x) +
(getUserGroups(x)
if x in passwdList else
self.getDefaultGroups())),
self.Get('cl_migrate_user'))
def choice(self):
"""
Available groups
"""
return [(self.default_value,
_("Default"))] + sorted([(x, x) for x in getGroups()])
return [("", _("Default"))] + [(x, x) for x in getGroups()]
class VariableClMigrateUserPwd(UserHelper, Variable):
@ -520,20 +274,18 @@ class VariableClMigrateUserPwd(UserHelper, Variable):
migrateusers = self.Get("cl_migrate_user")
if migrateusers:
lenData = 9
with open(fileName) as f:
shadowData = [x for x in [y.rstrip().split(":") for y in f] if len(x) == lenData]
shadowData = [x for x in shadowData if x[0] in migrateusers]
shadowData = [(x[0], x[1]) for x in shadowData]
shadowUsers = [x[0] for x in shadowData]
shadowData = filter(lambda x: len(x) == lenData,
map(lambda x: x.rstrip().split(":"),
open(fileName)))
shadowData = filter(lambda x: x[0] in migrateusers, shadowData)
shadowData = map(lambda x: (x[0], x[1]), shadowData)
shadowUsers = map(lambda x: x[0], shadowData)
for userName in migrateusers:
if userName in shadowUsers:
userData = [x for x in shadowData if x[0] == userName]
userData = filter(lambda x: x[0] == userName,
shadowData)
hashPwd = userData[0][1]
if (sha256_crypt.identify(hashPwd) and
sha256_crypt.verify("guest", hashPwd)):
retList.append("")
else:
retList.append(hashPwd)
retList.append(hashPwd)
else:
retList.append("")
return retList
@ -545,16 +297,18 @@ class VariableClMigrateUserPwd(UserHelper, Variable):
for user, pwd in zip(self.Get('cl_migrate_user'), value):
if not pwd:
raise PasswordError(
_("Enter password for user %s") % user)
_("Password for user %s missing") % user)
def set(self, value):
"""
Encrypt passwords
"""
shadow_hash = get_shadow_hash()
reCheck = re.compile("^\$[^$]+\$[^$]+\$.*$")
encryptObj = encrypt()
return [x if shadow_hash.identify(x) or not x else shadow_hash.hash(x) for x in value]
return map(lambda x: x if reCheck.match(x) or not x else \
encryptObj.getHashPasswd(x, "shadow_ssha256"),
value)
class VariableClAutologin(UserHelper, Variable):
@ -581,8 +335,8 @@ class VariableClAutologin(UserHelper, Variable):
if (not cmdDomainSet and
self.Get('os_install_root_type') == "livecd") or \
self.Get('os_install_linux_shortname') == "CMC":
nonRootUsers = [x for x in self.Get('cl_migrate_user') if x != "root"]
nonRootUsers = filter(lambda x: x != "root",
self.Get('cl_migrate_user'))
if nonRootUsers:
return nonRootUsers[0]
else:
@ -688,16 +442,19 @@ class VariableClInstallDevFrom(Variable):
If device in calculate3.env dev_from not exists set ''
"""
if value:
value = device.udev.get_device_info(
name=value).get('DEVNAME', value)
value = getUdevDeviceInfo(name=value).get('DEVNAME', value)
if value in self.Get('os_disk_dev'):
return value
else:
return ""
def get(self):
if self.Get('cl_autopartition_set') == 'on':
return self.Get('cl_autopartition_factory').dev_from
if (self.Get('cl_autopartition_set') == 'on' and
SchemeOpt.Update in self.Get('cl_autopartition_scheme')):
return self.Select('cl_autopartition_disk_dev',
where='cl_autopartition_disk_scheme',
eq=SchemeDevices.Root2,
limit=1)
return ""
@ -706,19 +463,7 @@ class VariableOsNvidiaMask(ReadonlyVariable):
Get nvidia card mask versions
"""
def get_cards_id(self):
category = "0300"
vendor = "10de:"
lsPciProg = getProgPath("/usr/sbin/lspci")
nvidiacards = [x for x in process(lsPciProg, "-d", vendor, "-n")
if " %s: " % category in x]
cardsid = [x.groups()[0] for x
in [re.search("[0-9a-fA-F]{4}:([0-9a-fA-F]{4})", y) for y in nvidiacards] if x]
if not cardsid:
return set()
return set(cardsid)
def get_legacy(self):
def get(self):
image = self.Get('cl_image')
try:
if image:
@ -726,60 +471,44 @@ class VariableOsNvidiaMask(ReadonlyVariable):
chrootPath = image.getDirectory()
else:
chrootPath = self.Get("cl_chroot_path")
if os.path.isdir(path.join(self.Get('cl_chroot_path'), 'var/db/repos/gentoo')):
nvidiaeclass = path.join(chrootPath,
'var/db/repos/gentoo/eclass/nvidia-driver.eclass')
else:
nvidiaeclass = path.join(chrootPath,
'usr/portage/eclass/nvidia-driver.eclass')
nvidiaeclass = path.join(chrootPath,
'usr/portage/eclass/nvidia-driver.eclass')
if not os.access(nvidiaeclass, os.R_OK):
return ""
#TODO investigate
#there used to be a typo - nvidiacards instead of... ?
# (nvidiacards wasn't defined)
# if not nvidiacards:
# return ""
if not nvidiaeclass:
category = "0300"
vendor = "10de:"
lsPciProg = getProgPath("/usr/sbin/lspci")
nvidiacards = filter(lambda x: " %s: " % category in x,
process(lsPciProg, "-d", vendor, "-n"))
if not nvidiacards:
return ""
cardsid = self.get_cards_id()
cardsid = \
map(lambda x: x.groups()[0],
filter(lambda x: x,
map(lambda x: re.search(
"[0-9a-fA-F]{4}:([0-9a-fA-F]{4})", x),
nvidiacards)))
if not cardsid:
return ""
eclassdata = readFile(nvidiaeclass)
reBlock = re.compile(
r"if has \$\{nvidia_gpu\}\s+\\([^;]+);\s*then(.*?)fi", re.S)
reMask = re.compile('>=x11-drivers/nvidia-drivers[^"]+')
masks = []
for block in reBlock.findall(eclassdata):
nvidia_ids, mask_data = block
nvidia_ids = nvidia_ids.strip().replace('\\','')
nvidia_ids = {x for x in nvidia_ids.split() if x}
m = reMask.search(mask_data)
if m:
mask_str = m.group()
if cardsid & nvidia_ids:
return mask_str
drv_categories = re.findall('^drv_([^=]+)="', eclassdata, re.M)
drvs = map(lambda x: (x[0], x[1].replace('\\\n', '').split()),
re.findall(
'\ndrv_(%s)="(.*?)"' % "|".join(drv_categories),
eclassdata, re.S))
mask_categories = re.findall('^mask_([^=]+)="', eclassdata, re.M)
masks = dict(map(lambda x: (x[0], x[1].replace('\\\n', '')),
re.findall('\nmask_(%s)="(.*?)"' % "|".join(
drv_categories),
eclassdata, re.S)))
drvsForCardsid = filter(lambda x: set(x[1]) & set(cardsid), drvs)
if drvsForCardsid and drvsForCardsid[0][0] in masks:
return masks[drvsForCardsid[0][0]]
finally:
if image:
image.close()
return ""
def get_new(self, ini):
cardsid = self.get_cards_id()
for nvidia_serie in ini.getKeys('nvidia'):
nvidia_ids = set(ini.getVar('nvidia', nvidia_serie).split(','))
if cardsid & nvidia_ids:
if nvidia_serie.isdigit():
return ">=x11-drivers/nvidia-drivers-{}".format(int(nvidia_serie)+1)
return ""
def get(self):
ini = SystemIni(self.parent)
if ini.getKeys('nvidia'):
return self.get_new(ini)
else:
return self.get_legacy()
class VariableOsInstallLvmSet(ReadonlyVariable):
"""
@ -831,17 +560,13 @@ class VariableOsGrub2Path(Variable):
def get(self):
# find grub2-install
chroot_path = self.Get('cl_chroot_path')
chroot_cmd = getProgPath('/usr/bin/chroot')
grubInstall = getProgPath('/usr/sbin/grub2-install', prefix=chroot_path)
grubInstall = getProgPath('/usr/sbin/grub2-install')
if grubInstall:
return grubInstall
# find grub-install and check, that this is grub2-install (ver 1.99)
grubInstall = getProgPath('/usr/sbin/grub-install', prefix=chroot_path)
if grubInstall and [x for x
in process(chroot_cmd, chroot_path, grubInstall, '--version')
if "1.99" in x or "2." in x]:
grubInstall = getProgPath('/usr/sbin/grub-install')
if grubInstall and filter(lambda x: "1.99" in x or "2." in x,
process(grubInstall, '--version')):
return grubInstall
return ""
@ -855,7 +580,7 @@ class VariableClSetup(Variable):
def choice(self):
return ["audio", "network", "locale", "video", "boot", "users",
"session", "themes", ""]
"session", ""]
def humanReadable(self):
mapType = {'network': _("network settings"),
@ -863,7 +588,6 @@ class VariableClSetup(Variable):
'video': _("video settings"),
'boot': _("boot parameters"),
'audio': _("audio parameters"),
'themes': _("update themes"),
'session': _("session settings"),
'users': _("user settings")}
return mapType.get(self.Get(), "")
@ -907,15 +631,13 @@ class VariableOsInstallPxe(Variable):
raise VariableError(
_("For PXE install, you need to install package %s")
% pkg)
for env_fn in ('/etc/calculate/calculate.env',
'/var/lib/calculate/calculate.env'):
try:
config = cl_ini_parser.iniParser(env_fn)
val = config.getVar('server', 'sr_dhcp_set')
if val.encode('utf-8') == "on" or val == "on":
return
except Exception:
pass
try:
config = cl_ini_parser.iniParser('/etc/calculate/calculate.env')
val = config.getVar('server', 'sr_dhcp_set')
if val.encode('utf-8') == "on":
return
except Exception:
pass
raise VariableError(
_("PXE install is only available if the DHCP "
"service has been configured first"))
@ -938,11 +660,68 @@ class VariableOsInstallUefiSet(Variable):
"""
Install in UEFI
"""
type = "bool"
opt = ['--uefi']
def init(self):
self.label = _("UEFI boot")
self.help = _("use UEFI boot")
def get(self):
if self.Get('os_install_uefi'):
return "on"
if self.Get('cl_autopartition_set') == 'on':
return self.Get('cl_autopartition_uefi_set')
else:
return "off"
if self.Get('os_install_disk_efi') or \
"/boot/efi" in self.Get('os_location_dest'):
if self.Get('os_install_arch_machine') == 'x86_64' and \
self.Get('os_install_root_type') != 'flash':
return self.Get('os_uefi_set')
return 'off'
def check(self, value):
if value == 'on':
if self.Get('os_uefi_set') == 'off' and \
self.Get('os_install_root_type') == 'hdd':
raise VariableError(
_("Your system must be loaded in UEFI for using this "
"bootloader"))
if not 'gpt' in self.Get('os_device_table'):
raise VariableError(
_("GPT is needed for using the UEFI bootloader"))
if not (self.Get('os_install_disk_efi') or
"/boot/efi" in self.Get('os_location_dest')):
raise VariableError(
_("A EF00 partition is needed for using "
"the UEFI bootloader"))
if self.Get('os_install_arch_machine') != 'x86_64':
raise VariableError(
_("Architecture of the target system must be x86_64"))
if self.Get('os_install_root_type') == 'flash':
raise VariableError(
_("This option not used for Flash install"))
def uncompatible(self):
"""
Uncompatible with autopartition
"""
if self.Get('cl_autopartition_set') == "on":
return \
_("The layout is not available with autopartitioning")
if self.Get('os_install_root_type') == 'flash':
return \
_("This option not used for Flash install")
return ""
class VariableOsInstallUefiBriefSet(VariableOsInstallUefiSet):
def uncompatible(self):
if self.Get('os_install_root_type') == 'flash':
return _("This option not used for Flash install")
return ""
def get(self):
return self.Get('os_install_uefi_set')
class VariableOsInstallGrubTerminal(Variable):
"""
@ -1026,21 +805,6 @@ class VariableOsInstallX11ServerSet(PackageCheckVariable):
package = "x11-base/xorg-server"
class VariableOsInstallSplashSet(Variable):
"""
Переменная отображать splash при загрузки
"""
type = "bool"
value = "on"
class VariableClInstallFs(Variable):
"""
Preferred fs
"""
type = "list"
value = ["btrfs", "ext4", "reiserfs", "ext3"]
class FlashUncompatible(VariableInterface):
def uncompatible(self):
"""
@ -1052,35 +816,6 @@ class FlashUncompatible(VariableInterface):
return ""
class VariableClInstallUpdatePkgSet(Variable):
"""
При установке системы создать сценарии запуска cl-update в конце
первой загрузки
"""
type = "bool"
opt = ["--update-pkg","-K"]
def system_has_ip(self):
return bool(self.Get('os_net_ip'))
def custom_set_has_packages(self):
install_short = self.Get('os_install_linux_shortname')
now_short = self.Get('os_linux_shortname')
setfile = "/etc/portage/sets/custom.{}".format(now_short.lower())
if readFileEx(setfile, grab=True) and install_short == now_short:
return True
return False
def get(self):
if self.system_has_ip() and self.custom_set_has_packages():
return "on"
return "off"
def init(self):
self.help = _("update packages at first boot")
self.label = _("Update packages at first boot")
try:
import calculate.update.variables.update as update

@ -17,21 +17,20 @@
import sys
from calculate.lib.datavars import VariableError, DataVarsError
from .distr import DistributiveError
from calculate.install.distr import DistributiveError
from . import install
import install
from calculate.lib.cl_lang import setLocalTranslate, getLazyLocalTranslate, _
setLocalTranslate('cl_install3', sys.modules[__name__])
__ = getLazyLocalTranslate(_)
from calculate.core.server.func import WsdlBase
from calculate.lib.utils.partition import VolumesError
from .utils.cl_install import ClInstallAction
from .utils.cl_setup import (
from calculate.install.utils.cl_install import ClInstallAction
from calculate.install.utils.cl_setup import (
ClSetupLocaleAction, ClSetupVideoAction, ClSetupSystemAction,
ClSetupBootAction, ClSetupNetworkAction, ClSetupAudioAction,
ClSetupSessionAction, ClSetupThemesAction)
ClSetupSessionAction)
class Wsdl(WsdlBase):
@ -57,20 +56,17 @@ class Wsdl(WsdlBase):
'action': ClInstallAction,
# объект переменных
'datavars': "install",
'native_error': (VariableError, DistributiveError, VolumesError,
'native_error': (VariableError, DistributiveError,
DataVarsError, install.InstallError),
# значения по умолчанию для переменных этого метода
'setvars': {'cl_action!': 'system',
'cl_chroot_status!': 'off', 'cl_install_type': 'hdd',
'setvars': {'cl_action!': 'system', 'cl_install_type': 'hdd',
'cl_dispatch_conf': 'usenew'},
# описание груп (список лямбда функций)
'groups': [
lambda group: group(_("Language and locale"),
image="welcome",
normal=('os_install_locale_lang',
'os_install_clock_timezone'),
expert=('os_install_locale_keyboard_layout',
'os_install_clock_type',)),
'os_install_clock_timezone')),
lambda group: group(_("Distribution"),
normal=('cl_image_filename',),
hide=('cl_image_linux_shortname',
@ -79,51 +75,39 @@ class Wsdl(WsdlBase):
expert=('cl_image_linux_shortname',
'cl_image_arch_machine',
'cl_image_new_only')),
lambda group: group(_("Installation type"),
lambda group: group(_("Allocate drive space"),
normal=('cl_autopartition_set',),
hide=('cl_autopartition_set',
'cl_autopartition_root_size',
'cl_autopartition_root_format',
'cl_autopartition_calculate_format',
'cl_autopartition_swap_size',),
hide=('cl_autopartition_set',),
brief=('cl_autopartition_brief_set',),
expert=('cl_autopartition_scheme',
'cl_autopartition_root_format',
'cl_autopartition_calculate_format',
'cl_autopartition_table',
'cl_autopartition_root_size',
'cl_autopartition_swap_size',
'cl_autopartition_device'),
expert_label=_(
"Click to select partitions to be created")
),
lambda group: group(_("Layout"),
"Click to set up autopartition options")),
lambda group: group(_("Mount points"),
normal=('os_location_data',),
hide=('os_location_data', 'os_install_mbr',
'os_install_uefi'),
'os_install_uefi_set'),
brief_force=('os_location_brief_data',
'os_install_bootloader'),
brief=('os_install_uefi',),
brief=('os_install_uefi_brief_set',),
expert=('cl_uuid_set',
'os_install_mbr',
'os_install_uefi')),
'os_install_uefi_set',
'os_install_kernel_scheduler')),
lambda group: group(_("Network settings"),
normal=(
'cl_network_migrate_set',),
expert=('os_install_net_conf',
'os_install_net_conf',
'os_install_net_data',
'os_install_net_fqdn', 'os_install_ntp',
'os_install_net_dns',
'os_install_net_dns_search',
'os_install_net_route_data'),
expert_label=_(
"Click to select network settings")
),
'os_install_net_fqdn', 'os_install_ntp'),
expert=('os_install_net_dns',
'os_install_net_dns_search',
'os_install_net_route_data')),
lambda group: group(_("Users"),
normal=(
'cl_migrate_root_pwd_plain',
'cl_grub_passwd_set',
'cl_migrate_data',
'cl_migrate_root_pwd', 'cl_migrate_data',
'cl_autologin'),
expert=('cl_install_home_crypt_set',),
hide=('cl_migrate_data',),
@ -134,17 +118,16 @@ class Wsdl(WsdlBase):
lambda group: group(_("Video"),
normal=('os_install_x11_video_drv',
'os_install_x11_composite',
'os_install_x11_resolution_preferred',
'os_install_grub_terminal'),
expert=('os_install_fb_resolution_preferred',)),
'os_install_x11_resolution',
'os_install_fb_resolution',
'os_install_grub_terminal')),
lambda group: group(_("Update"),
normal=('cl_install_autocheck_set',
'cl_install_autocheck_interval',
'cl_install_cleanpkg_set',
'cl_install_other_set'),
expert=('cl_install_update_pkg_set',))],
'cl_install_other_set'))],
# действие выводит информацию перед запуском
'brief': {'next': __("Run"),
'brief': {'next': __("Perform"),
'image': 'finish',
'name': __("Start installing")}},
# установка на Flash
@ -152,8 +135,7 @@ class Wsdl(WsdlBase):
'method_name': "install_flash",
'category': __("Installation"),
'title': __("Flash Install"),
'image': ('calculate-install-flash,'
'drive-removable-media-usb-pendrive,'
'image': ('drive-removable-media-usb-pendrive,'
'drive-removable-media-usb,media-flash'),
'command': 'cl-install-flash',
'gui': True,
@ -161,30 +143,25 @@ class Wsdl(WsdlBase):
'logic': {'Install': install.Install},
'action': ClInstallAction,
'datavars': "install",
'native_error': (VariableError, DistributiveError, VolumesError,
'native_error': (VariableError, DistributiveError,
DataVarsError, install.InstallError),
'setvars': {'cl_action!': 'system',
'cl_chroot_status!': 'off',
'cl_install_type': 'flash',
'setvars': {'cl_action!': 'system', 'cl_install_type': 'flash',
'cl_protect_use_set!': 'off',
'cl_autopartition_set!': 'off',
'cl_dispatch_conf': 'usenew'},
'groups': [
lambda group: group(_("Flash install"),
normal=('cl_image_filename',
'os_install_disk_single',
'cl_target_fs',
'os_install_format_single_set'),
next_label=_("Run"))],
'brief': {'next': __("Run"),
next_label=_("Perform"))],
'brief': {'next': __("Perform"),
'name': __("Start installing")}},
# PXE установка
{
'method_name': "install_pxe",
'category': __("Installation"),
'title': __("PXE Install"),
'image': ('calculate-install-pxe,gnome-network-properties,'
'network-server,'
'image': ('gnome-network-properties,network-server,'
'preferences-desktop-remote-desktop'),
'command': 'cl-install-pxe',
'gui': True,
@ -206,13 +183,13 @@ class Wsdl(WsdlBase):
normal=('cl_image_filename',),
expert=('os_install_pxe_path',
'os_install_pxe_ip'),
next_label=_("Run"))]},
next_label=_("Perform"))]},
# настройка загрузки системы
{
'method_name': "setup_boot",
'category': __("Configuration"),
'title': __("Boot"),
'image': 'calculate-setup-boot,stock_save,drive-harddisk',
'image': 'stock_save,drive-harddisk',
'command': 'cl-setup-boot',
'gui': True,
'rights': ['setupboot'],
@ -226,12 +203,9 @@ class Wsdl(WsdlBase):
'groups': [
lambda group: group(_("Boot"),
normal=(
'os_install_mbr',
'os_install_uefi',
'os_install_grub_terminal',
'cl_grub_pwd',
'cl_grub_remove_pwd_set',
),
'os_install_mbr', 'os_install_uefi_set',
'os_install_kernel_scheduler',
'os_install_grub_terminal'),
expert=(
'cl_templates_locate',
'cl_dispatch_conf',
@ -242,7 +216,7 @@ class Wsdl(WsdlBase):
'method_name': "setup_network",
'category': __("Configuration"),
'title': __("Network"),
'image': 'calculate-setup-network,network-workgroup,'
'image': 'network-workgroup,'
'network-idle,preferences-system-network',
'command': 'cl-setup-network',
'gui': True,
@ -253,7 +227,6 @@ class Wsdl(WsdlBase):
'native_error': (
VariableError, DataVarsError, install.InstallError),
'setvars': {'cl_action!': 'merge', 'cl_merge_pkg!': [None],
'cl_network_migrate_set': 'off',
'cl_merge_set!': "on", 'cl_setup': 'network'},
'groups': [
lambda group: group(_("Network"),
@ -273,8 +246,7 @@ class Wsdl(WsdlBase):
'method_name': "setup_system",
'category': __("Configuration"),
'title': __("System"),
'image': 'calculate-setup-system,run-build,applications-ide,'
'system-run,system,computer',
'image': 'run-build,applications-ide,system-run,system,computer',
'command': 'cl-setup-system',
'gui': True,
'rights': ['setupsystem'],
@ -286,8 +258,7 @@ class Wsdl(WsdlBase):
'setvars': {'cl_action!': 'merge', 'cl_live': 'off'},
'groups': [
lambda group: group(_("Update system settings"),
normal=('cl_live',
'cl_network_configure_set'),
normal=('cl_live',),
expert=(
'cl_templates_locate',
'cl_dispatch_conf',
@ -298,8 +269,7 @@ class Wsdl(WsdlBase):
'method_name': "setup_video",
'category': __("Configuration"),
'title': __("Video"),
'image': 'calculate-setup-video,system-config-display,'
'video-display,gnome-multimedia',
'image': 'system-config-display,video-display,gnome-multimedia',
'command': 'cl-setup-video',
'gui': True,
'rights': ['setupvideo'],
@ -311,23 +281,22 @@ class Wsdl(WsdlBase):
'setvars': {'cl_action!': 'merge', 'cl_merge_pkg!': [None],
'cl_merge_set!': "on", 'cl_setup': 'video'},
'groups': [
lambda group: group(
_("Video"),
normal=('os_install_x11_video_drv',
'os_install_x11_resolution_preferred',
'os_install_x11_composite'),
expert=(
'os_install_fb_resolution_preferred',
'cl_templates_locate',
'cl_dispatch_conf',
'cl_verbose_set'),
next_label=_("Save"))]},
lambda group: group(_("Video"),
normal=('os_install_x11_video_drv',
'os_install_x11_resolution',
'os_install_x11_composite',
'os_install_fb_resolution'),
expert=(
'cl_templates_locate',
'cl_dispatch_conf',
'cl_verbose_set'),
next_label=_("Save"))]},
{
# настройка звука
'method_name': "setup_audio",
'category': __("Configuration"),
'title': __("Audio"),
'image': 'calculate-setup-audio,audio-card',
'image': 'audio-card',
'command': 'cl-setup-audio',
'gui': True,
'rights': ['setupaudio'],
@ -352,7 +321,7 @@ class Wsdl(WsdlBase):
'method_name': "setup_locale",
'category': __("Configuration"),
'title': __("Locale"),
'image': 'calculate-setup-locale,locale,preferences-desktop-locale',
'image': 'locale,preferences-desktop-locale',
'command': 'cl-setup-locale',
'gui': True,
'rights': ['setuplocale'],
@ -368,8 +337,6 @@ class Wsdl(WsdlBase):
normal=('os_install_locale_lang',
'os_install_clock_timezone'),
expert=(
'os_install_locale_keyboard_layout',
'os_install_clock_type',
'cl_templates_locate',
'cl_dispatch_conf',
'cl_verbose_set'),
@ -379,7 +346,7 @@ class Wsdl(WsdlBase):
'method_name': "setup_session",
'category': __("Configuration"),
'title': __("Session"),
'image': 'calculate-setup-session,system-lock-screen',
'image': 'system-lock-screen',
'command': 'cl-setup-session',
'gui': True,
'rights': ['setupsession'],
@ -394,30 +361,6 @@ class Wsdl(WsdlBase):
lambda group: group(_("Session"),
normal=('cl_autologin',
'cl_install_home_crypt_set'),
expert=(
'cl_templates_locate',
'cl_dispatch_conf',
'cl_verbose_set'),
next_label=_("Save"))]},
{
# настройка тем
'method_name': "setup_theme",
'category': None,
'title': __("Themes"),
'image': None,
'command': 'cl-setup-themes',
'gui': True,
'rights': ['setupthemes'],
'logic': {'Install': install.Install},
'action': ClSetupThemesAction,
'datavars': "install",
'native_error': (
VariableError, DataVarsError, install.InstallError),
'setvars': {'cl_action!': 'merge', 'cl_merge_pkg!': [None],
'cl_merge_set!': "on", 'cl_setup': 'themes'},
'groups': [
lambda group: group(_("Session"),
normal=(),
expert=(
'cl_templates_locate',
'cl_dispatch_conf',

@ -72,12 +72,12 @@ class install_data(module_install_data.install_data):
data_files = []
data_files += [('/etc/init.d', [('data/calculate',0o755)]),
('/usr/bin',[('bin/xautologin',0o755)]),
data_files += [('/etc/init.d', [('data/calculate',0755)]),
('/usr/bin',[('bin/xautologin',0755)]),
('/usr/share/calculate/doc', ['data/handbook-en.html',
'data/handbook-ru.html']),
('/usr/libexec/calculate', [('data/cl-video-install', 0o755)]),
('/bin',[('bin/bashlogin',0o755)])]
('/usr/libexec/calculate', [('data/cl-video-install', 0755)]),
('/bin',[('bin/bashlogin',0755)])]
packages = [
"calculate."+str('.'.join(root.split(os.sep)[1:]))

Loading…
Cancel
Save