You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
208 lines
6.7 KiB
208 lines
6.7 KiB
#!/bin/bash
|
|
#------------------------------------------------------------------------------
|
|
# cl-builder
|
|
# Copyright ©2009 Mir Calculate Ltd.
|
|
#
|
|
# This program is free software: you can redistribute it and/or modify
|
|
# it under the terms of the GNU General Public License as published by
|
|
# the Free Software Foundation, either version 3 of the License, or
|
|
# (at your option) any later version.
|
|
#
|
|
# This program is distributed in the hope that it will be useful,
|
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
# GNU General Public License for more details.
|
|
#
|
|
# You should have received a copy of the GNU General Public License
|
|
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
#------------------------------------------------------------------------------
|
|
|
|
# выбор строки перемонтирования разделов в зависимости от используемого модуля
|
|
BUILDER=/mnt/builder
|
|
if [[ -n `mount | grep " / type aufs"` ]];
|
|
then
|
|
REMOUNT="mount -t aufs -o remount,br:/ none /"
|
|
REMOUNTBUILDER="mount -t aufs -o remount,br:/ none $BUILDER"
|
|
else
|
|
REMOUNT="mount -t unionfs -o remount,dirs=/ unionfs /"
|
|
REMOUNTBUILDER=":"
|
|
fi
|
|
TIMERUN=`python -c "import time;print str(time.time())[:10]"`
|
|
EMERGELOG=${BUILDER}/var/log/emerge.log
|
|
TAILEMERGELOG="tail -f ${EMERGELOG}"
|
|
|
|
#------------------------------------------------------------------------------
|
|
# Обновление Unionfs в течение сборки пакетов
|
|
#------------------------------------------------------------------------------
|
|
watching() {
|
|
$TAILEMERGELOG |
|
|
while read line;
|
|
do
|
|
if [ `echo "$line" | awk -F: '{print $1;}'` -ge $TIMERUN ] &&
|
|
[ "`echo "$line" | grep -e "unemerge success" -e "completed emerge"`" ]
|
|
then
|
|
$REMOUNT &>/dev/null
|
|
fi
|
|
done
|
|
}
|
|
|
|
#------------------------------------------------------------------------------
|
|
# Монтируем ресурсы
|
|
#------------------------------------------------------------------------------
|
|
mountres() {
|
|
mount -o bind /usr/calculate/share ${BUILDER}/usr/calculate/share &&
|
|
mount -t proc none ${BUILDER}/proc &&
|
|
mount -o bind /dev ${BUILDER}/dev &&
|
|
mount -t sysfs none ${BUILDER}/sys &&
|
|
mount -o bind /dev/pts ${BUILDER}/dev/pts && return 0
|
|
return 1
|
|
}
|
|
|
|
#------------------------------------------------------------------------------
|
|
# Выполним emerge
|
|
#------------------------------------------------------------------------------
|
|
runchroot() {
|
|
touch $EMERGELOG
|
|
watching & 2>/dev/null
|
|
chroot $BUILDER /bin/bash --rcfile /usr/calculate/install/config/chroot.rc
|
|
WATCHINGPID=`ps axo pid,cmd | sed -nr "s|^\s*([0-9]+)\s+${TAILEMERGELOG}.*|\1|p"`
|
|
[ "${WATCHINGPID}" ] && kill -9 $WATCHINGPID &>/dev/null
|
|
$REMOUNT &>/dev/null
|
|
}
|
|
|
|
#------------------------------------------------------------------------------
|
|
# Отмонтируем ресурсы
|
|
#------------------------------------------------------------------------------
|
|
umountres() {
|
|
# перебираем строку в обратном порядке
|
|
MOUNTDIRS=`mount | grep -Po "${BUILDER}/[^ ]+" | sed "{N;s/\n/ /}"`
|
|
for MOUNTDIR in $( echo $MOUNTDIRS | rev )
|
|
do
|
|
umount $(echo $MOUNTDIR | rev) || exit
|
|
done
|
|
}
|
|
|
|
|
|
#------------------------------------------------------------------------------
|
|
# Выполним проверки
|
|
#------------------------------------------------------------------------------
|
|
checkrun() {
|
|
if [[ `/usr/bin/id -u` -ne 0 ]]
|
|
then
|
|
echo "Only root can perform system building."
|
|
exit;
|
|
fi
|
|
#не запустим если загрузка не в Scrach режиме
|
|
if ! mount | grep /mnt/scratch &>/dev/null
|
|
then
|
|
echo "This program only works in the system, installed by Calculate with the option '--build'."
|
|
exit;
|
|
fi
|
|
|
|
#не запустим второй раз
|
|
if mount | grep "/dev/pts on /mnt/builder/dev/pts " &>/dev/null
|
|
then
|
|
if [ `ps ax | grep -v grep | grep -c "/bin/bash /usr/bin/cl-builder"` -gt 3 ];
|
|
then
|
|
echo "This program is already run."
|
|
exit;
|
|
else
|
|
umountres
|
|
fi
|
|
fi
|
|
|
|
#не запустим из chroot
|
|
if [ `mount | grep -c "devpts on /dev/pts "` -ne 1 ];
|
|
then
|
|
echo "This program can't be run from Scratch layer."
|
|
exit;
|
|
fi
|
|
}
|
|
|
|
#------------------------------------------------------------------------------
|
|
# Выполним предварительные настройки
|
|
#------------------------------------------------------------------------------
|
|
configure() {
|
|
# Перенесем resolv.conf
|
|
if [ -f /etc/resolv.conf ]
|
|
then
|
|
mkdir -p ${BUILDER}/etc
|
|
cp /etc/resolv.conf ${BUILDER}/etc/
|
|
fi
|
|
}
|
|
|
|
checkrun
|
|
configure
|
|
$REMOUNTBUILDER &>/dev/null
|
|
mountres && runchroot
|
|
umountres
|
|
|
|
ROOTDIR=/
|
|
UPDATE_DIRS="/boot /lib/modules /lib/firmware"
|
|
#------------------------------------------------------------------------------
|
|
# Ask: whether to replace the old file
|
|
#------------------------------------------------------------------------------
|
|
ask_replace() {
|
|
[[ $REPLACE_ANSWER == "yes" ]] && return 0
|
|
[[ $REPLACE_ANSWER == "no" ]] && return 1
|
|
local destfile=$1
|
|
echo "File '$destfile' in builder is newer than in workspace"
|
|
local line
|
|
while true
|
|
do
|
|
echo -n "Do you want replace old file (Yes/No/All/None):"
|
|
read line <&1
|
|
case $line in
|
|
All|all) REPLACE_ANSWER=yes;return 0;;
|
|
None|none) REPLACE_ANSWER=no;return 1;;
|
|
Y*|y*) return 0 ;;
|
|
N*|n*) return 1 ;;
|
|
esac
|
|
done
|
|
}
|
|
|
|
#------------------------------------------------------------------------------
|
|
# Compare modify time of the first and second file
|
|
#------------------------------------------------------------------------------
|
|
test_newer() {
|
|
# [[ file1 -nt file2 ]] not correct work with symbolic link, because
|
|
# get modify time of target file
|
|
if [[ -L $1 || -L $2 ]]
|
|
then
|
|
[[ `stat -c %Y $1` -gt `stat -c %Y $2` ]]
|
|
else
|
|
[[ $1 -nt $2 ]]
|
|
fi
|
|
}
|
|
|
|
#------------------------------------------------------------------------------
|
|
# Compare modify time, ask user for update and update file
|
|
#------------------------------------------------------------------------------
|
|
try_update_file() {
|
|
[[ -e $2 || -L $2 ]] && test_newer $1 $2 &&
|
|
ask_replace $2 && cp -P $1 $2
|
|
}
|
|
|
|
#------------------------------------------------------------------------------
|
|
# Find in first directory files and symbolic links with modify time great than
|
|
# same files in the second directory
|
|
#------------------------------------------------------------------------------
|
|
update_from_builder() {
|
|
basesrc=${1%/}
|
|
basedest=${2%/}
|
|
shift 2
|
|
for place in $*
|
|
do
|
|
src=$basesrc/${place#/}
|
|
dest=$basedest/${place#/}
|
|
find $src -type f -o -type l |
|
|
while read srcfile;
|
|
do
|
|
dstfile=${dest}/${srcfile#${src}/}
|
|
try_update_file $srcfile $dstfile
|
|
done
|
|
done
|
|
}
|
|
|
|
update_from_builder $BUILDER $ROOTDIR $UPDATE_DIRS
|