Собственно, хочу довести развертывание линуксов до уровня "вставил флешку и включил комп", на данный момент загвоздка в том, что все известные мне утилиты, которые могут размечать жесткий диск работают в интерактивном режиме. Есть ли какой-то способ размечать ЖД из скрипта без всяких этих ваших интерактивностей?
Пример скрипта - создает разделы /, /var, /tmp, swap, /opt
Насчет рабочий или нет - тести на виртуалке
/smile.gif\' class=\'bbc_emoticon\' alt=\':)\' />
[codebox]
#!/bin/sh
#
# preparedisk.sh
#
# This script prepares the disk for installation. It will
# re-partition the disk, thus ALL DATA ON THE DISK WILL BE LOST.
#
MKFSARGS2="-q -b 4096 -i 8192 -O sparse_super,filetype,resize_inode,dir_index"
MKFSARGS3="-j $MKFSARGS2"
err() {
local message=$1
echo "ERROR: $1"
echo "ERROR: $1" >> /tmp/preparedisk.log
exit 1
}
echox() {
echo "$*"
echo "$*" >> /tmp/preparedisk.log
}
echonx() {
echo -n "$*"
echo "$*" >> /tmp/preparedisk.log
}
warn() {
local message=$1
echo "WARNING: $1"
echo "WARNING: $1" >> /tmp/preparedisk.log
}
log() {
echo "$*" >> /tmp/preparedisk.log
}
log_file() {
echo "=== $1" >> /tmp/preparedisk.log
cat $1 >> /tmp/preparedisk.log
echo "===" >> /tmp/preparedisk.log
}
run() {
local status
echo "*** $*" >> /tmp/preparedisk.log
LIBC_FATAL_STDERR_=1 MALLOC_CHECK_=3 $* >> /tmp/preparedisk.log 2>&1
status=$?
if [ $status -ne 0 ]; then
echo "ERROR: $*"
echo "ERROR: $*" >> /tmp/preparedisk.log
fi
return $status
}
clear_lvm() {
local volumes=$(lvm pvs --noheadings -o pv_name)
if [ -n "$volumes" ]; then
echox "Existing lvm volumes found; clearing..."
run lvm pvremove -y -ff $volumes;
fi
}
#
# setup swap lvm with 3 * memory. maximum 16G or free space on
# volume group. minimum 8GB.
#
# vg: the volume group to use
# minfree: minimum free space in GiB to leave on vg after creating swap
#
setup_swap_on_vg() {
local minswap=$((8 * 1024 * 1024))
local maxswap=$((16 * 1024 * 1024))
local vg=$1
local minfree=$2
if [ -n "$minfree" ]; then
minfree=$(( $minfree * 1024 * 1024 ))
else
minfree=0
fi
echox "Setting up swap space."
local free=$(lvm vgs --noheadings --nosuffix --units k -o vg_free $vg | cut -d. -f1)
if [ $? -ne 0 ]; then
warn "Could not determine free space in volume group $vg"
return 1
fi
if [ $free -lt $minfree ]; then
warn "Not enough space to create swap in $vg"
return 1
fi
local memsize=$(awk '/^MemTotal:/ { print $2 }' < /proc/meminfo)
if [ -z "$memsize" ]; then
return 1
fi
local swapsize=$(( $memsize * 3 ))
if [ $swapsize -gt $maxswap ]; then
swapsize=$maxswap
fi
if [ $swapsize -lt $minswap ]; then
swapsize=$minswap
fi
local freeleft=$(( $free - $swapsize ))
if [ $freeleft -lt $minfree ]; then
swapsize=$(( $free - $minfree ))
fi
if [ $swapsize -lt $minswap ]; then
warn "Not enough space to create swap in $vg"
return 1
fi
swapsize="${swapsize}K"
if ! run lvm lvcreate -n swap -L "${swapsize}" $vg; then
warn "Could not create LV swap of size ${swapsize}"
return 1
fi
if ! run mkswap /dev/$vg/swap; then
warn "Could not initialize swap space"
return 1
fi
return 0
}
setup_big_disk() {
local bootdev=$1
local size=$2
local partitionpath=$3
log "*** setup_big_disk $1 $2 $3"
local lvmpart="${partitionpath}2"
local volgroup00="vg00"
local rootsize=""
local varsize=""
local tmpsize=""
if [ $size -lt 59392 ]; then
# 5G / + 5G /var + 5G /tmp + 5G /opt + min 8G swap = 28G
rootsize="5G"
varsize="5G"
tmpsize="5G"
optmin="5"
else
# 10G / + 15G /var + 5G /tmp + 10G /opt + max 16G swap = 56G
rootsize="10G"
varsize="15G"
tmpsize="5G"
optmin="10"
fi
PARTED=parted
run $PARTED --script -- $bootdev "mkpart primary ext2 2048s $rootsize"
run $PARTED --script -- $bootdev "mkpart primary ext2 $rootsize -1"
run $PARTED --script -- $bootdev "set 1 boot on"
run $PARTED --script -- $bootdev "set 2 lvm on"
run partprobe -s > /dev/null
echox "Setting up LVM."
local instdevice=$(imtool -d)
if [ -n "$instdevice" ]; then
mkdir -p /etc/lvm
echo "devices { filter = [ \"r|$instdevice|\" ] }" > /etc/lvm/lvm.conf
fi
run dd if=/dev/zero of=$lvmpart bs=2048 count=1 >/dev/null
run lvm pvcreate -y -ff $lvmpart
run lvm vgcreate $volgroup00 $lvmpart
run lvm lvcreate -n tmp -L$tmpsize $volgroup00
run lvm lvcreate -n var -L$varsize $volgroup00
cat >> /tmp/installdiskinfo <<EOF
ROOTFS=${partitionpath}1
volgroup=${volgroup00}
VAR=/dev/mapper/${volgroup00}-var
TMP=/dev/mapper/${volgroup00}-tmp
OPT=/dev/mapper/${volgroup00}-opt
SWAP=/dev/mapper/${volgroup00}-swap
INSTALLDEST=/mnt
EOF
local volgroup01="vg01"
if ! setup_additional_disk $volgroup01 $bootdev ; then
volgroup01=$volgroup00
fi
setup_swap_on_vg $volgroup00 $optmin
run lvm lvcreate -n opt -l 100%FREE $volgroup00
. /tmp/installdiskinfo
echonx "Creating file systems:"
run mke2fs $MKFSARGS3 $ROOTFS
[ $? -eq 0 ] && echonx " " || echonx " !"
echonx "root"
run mke2fs $MKFSARGS3 $VAR
[ $? -eq 0 ] && echonx " " || echonx " !"
echonx "var"
run mke2fs $MKFSARGS3 $TMP
[ $? -eq 0 ] && echonx " " || echonx " !"
echonx "tmp"
run mke2fs $MKFSARGS3 $OPT
[ $? -eq 0 ] && echonx " " || echonx " !"
echonx "opt"
echox
run mount -t ext3 $ROOTFS $INSTALLDEST
mkdir -p $INSTALLDEST/var
mkdir -p $INSTALLDEST/tmp
mkdir -p $INSTALLDEST/opt
mkdir -p $INSTALLDEST/proc
mkdir -p $INSTALLDEST/sys
mount -t ext3 "$VAR" $INSTALLDEST/var
mount -t ext3 "$TMP" $INSTALLDEST/tmp
mount -t ext3 "$OPT" $INSTALLDEST/opt
mount -t proc proc $INSTALLDEST/proc
mount -t sysfs none $INSTALLDEST/sys
mkdir -p $INSTALLDEST/etc
cat >> $INSTALLDEST/etc/fstab.inst <<EOF
proc /proc proc defaults 0 0
tmpfs /dev/shm tmpfs defaults 0 0
devpts /dev/pts devpts gid=5,mode=620 0 0
$ROOTFS / ext3 defaults,errors=remount-ro 1 1
$VAR /var ext3 nosuid,nodev,errors=remount-ro 0 2
$TMP /tmp ext3 nosuid,nodev,errors=remount-ro 0 2
$OPT /opt ext3 nosuid,nodev,errors=remount-ro 0 2
$SWAP none swap sw 0 0
EOF
}
setup_small_disk() {
local bootdev=$1
local size=$2
local partitionpath=$3
log "*** setup_small_disk $1 $2 $3"
PARTED=parted
run $PARTED --script -- $bootdev 'mkpart primary ext2 2048s -2G'
run $PARTED --script -- $bootdev 'mkpart primary linux-swap -2G -1'
run $PARTED --script -- $bootdev 'set 1 boot on'
run partprobe -s > /dev/null
echox "Setting up swap space."
if ! run mkswap ${partitionpath}2; then
warn "Could initialize swap space"
fi
cat >> /tmp/installdiskinfo <<EOF
ROOTFS=${partitionpath}1
SWAP=${partitionpath}2
INSTALLDEST=/mnt
EOF
. /tmp/installdiskinfo
echonx "Creating file systems:"
run mke2fs $MKFSARGS3 $ROOTFS
[ $? -eq 0 ] && echonx " " || echonx " !"
echonx "root"
echox
mount -t ext3 $ROOTFS $INSTALLDEST
mkdir -p $INSTALLDEST/var
mkdir -p $INSTALLDEST/tmp
mkdir -p $INSTALLDEST/opt
mkdir -p $INSTALLDEST/proc
mount -t proc proc $INSTALLDEST/proc
mkdir -p $INSTALLDEST/etc
cat >> $INSTALLDEST/etc/fstab.inst <<EOF
proc /proc proc defaults 0 0
tmpfs /dev/shm tmpfs defaults 0 0
devpts /dev/pts devpts gid=5,mode=620 0 0
$ROOTFS / ext3 defaults,errors=remount-ro 1 1
$SWAP none swap sw 0 0
EOF
}
#
# check that size of device is greater than given min
# device: sysfs device name (e.g. hda, sda, cciss!c0d0)
# min: size in blocks of 512 bytes
#
check_size() {
local device=$1
local min=$2
size=$(cat /sys/block/$device/size)
size=$(( $size / 2048 ))
if [ $size -lt $min ]; then
return 1
else
return 0
fi
}
#
# search disks in defined order and skip all devices until
# optional device given in skip parameter is reached
# skip: device after which to start searching (optional)
#
find_firstdisk() {
local skip=$1
local installdevice=
local bestdisk=
local found=""
if [ -z "$skip" ]; then
found="1"
fi
for disk in hda hdb hdc hdd hde hdf hdg hdh vda; do
[ "$disk" = "$installdevice" ] && continue
[ ! -e /sys/block/$disk ] && continue
[ "$(cat /sys/block/$disk/removable)" = "1" ] && continue
if [ -n "$found" ]; then
if check_size $disk 10240; then
echo $disk
return
fi
fi
if [ -n "$skip" ] && [ "$skip" = "$disk" ]; then
found="1"
fi
done
for disk in sda sdb sdc sdd sde sdf sdg sdh; do
[ "$disk" = "$installdevice" ] && continue
[ ! -e /sys/block/$disk ] && continue
[ "$(cat /sys/block/$disk/removable)" = "1" ] && continue
if [ -n "$found" ]; then
if check_size $disk 10240; then
echo $disk
return
fi
fi
if [ -n "$skip" ] && [ "$skip" = "$disk" ]; then
found="1"
fi
done
echo ""
}
#
# search for additional disk and create volume group vg01 on it
# bootdev: primary disk which should be skipped
#
setup_additional_disk() {
local volgroup=$1
local bootdev=$2
echo -n "Searching for additional disks:"
local disk=$(basename $bootdev)
disk=$(find_firstdisk $disk)
if [ -z "$disk" ]; then
echo "."
return 1
fi
echo -n " $disk"
echo "."
run dd if=/dev/zero of=/dev/${disk} bs=512 count=1 >/dev/null
run parted --script -- /dev/${disk} 'mklabel msdos'
run partprobe -s > /dev/null
PARTED=parted
run $PARTED --script -- /dev/${disk} "mkpart primary ext2 2048s -1"
run $PARTED --script -- /dev/${disk} "set 1 lvm on"
run partprobe -s > /dev/null
run dd if=/dev/zero of=/dev/${disk}1 bs=2048 count=1 >/dev/null
run lvm pvcreate -y -ff /dev/${disk}1
echo "DISK01=/dev/${disk}" >> /etc/installdiskinfo
if lvm vgs --noheadings -o vg_name | grep -q $volgroup ; then
run lvm vgextend $volgroup /dev/${disk}1
else
echo "VOLGROUP01=$volgroup" >> /etc/installdiskinfo
run lvm vgcreate $volgroup /dev/${disk}1
fi
return 0
}
. /tmp/installdiskinfo
log_file /tmp/installdiskinfo
clear_lvm
echox "Writing disklabel."
run dd if=/dev/zero of=$BOOTDEV bs=512 count=1 >/dev/null
run parted --script -- $BOOTDEV 'mklabel msdos'
run partprobe -s > /dev/null
BOOTDEVSIZE=$(sfdisk -s $BOOTDEV)
BOOTDEVSIZE=$(( $BOOTDEVSIZE / 1024 ))
log "BOOTDEVSIZE=$BOOTDEVSIZE"
echox "Creating partitions."
if [ "$BOOTDEVSIZE" -lt 29696 ] || grep -q -E "\bforcesinglepartition\b" /proc/cmdline ; then
# < 29G: small disk scheme, single partition
echox "Using small disk scheme ($(($BOOTDEVSIZE / 1024)) GiB)."
setup_small_disk $BOOTDEV $BOOTDEVSIZE $PARTITIONPATH
elif [ "$BOOTDEVSIZE" -lt 59392 ]; then
# < 58G: medium disk scheme, full partition set, reduced size
echox "Using medium disk scheme ($(($BOOTDEVSIZE / 1024)) GiB)."
setup_big_disk $BOOTDEV $BOOTDEVSIZE $PARTITIONPATH
else
# >= 58G: big disk scheme, full partition set
echox "Using big disk scheme ($(($BOOTDEVSIZE / 1024)) GiB)."
setup_big_disk $BOOTDEV $BOOTDEVSIZE $PARTITIONPATH
fi
log_file /tmp/installdiskinfo
cp /tmp/installdiskinfo $INSTALLDEST/etc/installdiskinfo
[/codebox]
Сударь, Вы разуплотнили мой мозг... Вроде бы всё просто и очевидно, но чёрт возьми! Мне бы в голову такое никогда не пришло. Будем тестить...