#!/bin/sh PREFIX= . "$PREFIX/lib/libalpine.sh" MBR=${MBR:-"/usr/share/syslinux/mbr.bin"} in_list() { local i="$1" shift while [ $# -gt 0 ]; do [ "$i" = "$1" ] && return 0 shift done return 1 } enumerate_fstab() { local mnt="$1" [ -z "$mnt" ] && return local escaped_mnt=$(echo $mnt | sed 's:/:\\/:g') awk "\$2 ~ /^$escaped_mnt/ {print \$0}" /proc/mounts | \ sed "s:$mnt:/:g; s: :\t:g" | sed 's:/\+:/:g' } install_mounted_root() { local mnt="$1" local features="ata base bootchart cdrom ext2 ext3 ide scsi usb" rootdev=$(awk "\$2 == \"$mnt\" { print \$1 }" /proc/mounts) if [ -z "$rootdev" ]; then echo "$mnt does not seem to be a mount point" >&2 return 1 fi local fs=$(awk "\$1 == \"$rootdev\" {print \$3}" /proc/mounts) if [ "$fs" != "ext2" ] && [ "$fs" != "ext3" ]; then echo "$fs is not supported. Only ext2 and ext3 are supported" >&2 return 1 fi rootdisk=${rootdev%[0-9]*} echon "Installing system on $rootdev: " lbu package - | tar -C "$mnt" -zx # apk reads config from target root so we need to copy the config mkdir -p "$mnt"/etc/apk/keys/ cp /etc/apk/keys/* "$mnt"/etc/apk/keys/ apk add -q --progress --update-cache --root "$mnt" \ $(cat "$mnt"/var/lib/apk/world) \ acct linux-grsec alpine-base >/dev/null || return 1 echo "" # make things bootable kernel=$(ls "$mnt"/lib/modules) if [ "$rootdisk" = "/dev/md" ]; then local md=${rootdev#/dev/} features="$features raid" raidmod=$(cat /sys/block/$md/md/level) raidmod=",$raidmod" raidopt="-r" # get a list of slaves rootdisk= for i in /sys/block/$md/slaves/*; do j=${i##*/} i=${j%[0-9]*} rootdisk="$rootdisk /dev/${i}" done fi ln -s boot/grsec.gz "$mnt"/grsec.gz ln -s boot/grsec "$mnt"/grsec # create an extlinux.conf sed -e '/append initrd/d' \ -e ':kernel /boot/grsec:d' \ /media/*/syslinux.cfg > "$mnt"/boot/extlinux.conf cat >"$mnt"/boot/extlinux.conf <> "$mnt"/etc/fstab # install extlinux apk add -q syslinux extlinux -i $raidopt "$mnt"/boot/ # unmount the partitions umount $(awk '{print $2}' /proc/mounts | grep ^"$mnt" | sort -r) # fix mbr for all disk devices for i in $rootdisk; do local errmsg echo "Writing MBR to $i" errmsg=$(dd if="$MBR" of=$i 2>&1) \ || echo "$errmsg" done echo "" echo "Installation is done. Please reboot." apk del -q syslinux } # figure out decent default swap size in mega bytes find_swap_size() { local memtotal_kb=$(awk '$1 == "MemTotal:" {print $2}' /proc/meminfo) # use 2 * avaiable ram echo $(( $memtotal_kb * 2 / 1024 )) } has_mounted_part() { local p # parse /proc/mounts for moutned devices for p in $(awk '$1 ~ /^\/dev\// {gsub("/dev/", "", $1); print $1}' \ /proc/mounts); do if [ -e /sys/block/$1/$p ]; then return 0 fi done return 1 } find_disks() { local p= disks= for p in $(awk '$1 ~ /[0-9]+/ {print $4}' /proc/partitions); do b=$(echo $p | sed 's:/:!:g') if [ -e /sys/block/$b/device ] && ! has_mounted_part $p; then disks="$disks $p" fi done echo $disks } useall() { local rootdisk_dev="$1" local i size local boot_size=100 boot_part_type="83" local swap_size=$(find_swap_size) swap_part_type="82" local root_part_type="83" local raidpkg= partitions= local minimum_root_size=$(($boot_size * 2)); if [ -n "$USE_RAID" ]; then boot_part_type="fd" swap_part_type="fd" root_part_type="fd" raidpkg="mdadm" fi dmesg -n1 apk_add -q sfdisk e2fsprogs $raidpkg || return 1 local root_size=$(( $(sfdisk -s $rootdisk_dev) / 1024 - $swap_size - $boot_size)) if [ "$root_size" -lt "$minimum_root_size" ]; then echo "The $rootdisk_dev is too small. At least $(( $boot_size + $swap_size + $minimum_root_size)) is needed." >&2 return 1 fi echo "" echo "Creating the following partitions on $rootdisk_dev:" echo " /boot ${boot_size}MB" echo " swap ${swap_size}MB" echo " / ${root_size}MB" echo "" echo -n "WARNING: All contents of $rootdisk_dev will be erased. Continue? [y/N]: " read i case "$i" in y*|Y*);; *) return 1;; esac echo "Initializing partitions..." if [ -n "$USE_RAID" ]; then local rd for rd in md0 md1 md2; do [ -b /dev/$rd ] && mdadm --stop /dev/$rd done fi # create new partitions (cat <>/tmp/sfdisk.out || return 1 # create device nodes if not exist mdev -s if [ -n "$USE_RAID" ]; then local p= rd= for p in $(sfdisk -l $rootdisk_dev 2>/dev/null \ | awk '/Linux raid/ {print $1}'); do case "$p" in *1) rd=/dev/md0; boot_dev=/dev/md0;; *2) rd=/dev/md1; swap_dev=/dev/md1;; *3) rd=/dev/md2; root_dev=/dev/md2;; esac mdadm --create $rd --level=1 --raid-devices=2 \ --quiet --run $p missing done else local p= for p in $(sfdisk -l $rootdisk_dev 2>/dev/null \ | awk '$1 ~ /^\/dev/ {print $1}'); do case "$p" in *1) boot_dev=$p;; *2) swap_dev=$p;; *3) root_dev=$p;; esac done fi mkfs.ext3 -q $boot_dev >/dev/null \ && mkswap $swap_dev >/dev/null \ && mkfs.ext3 -q >/dev/null $root_dev \ || return 1 mkdir -p /mnt mount -t ext3 $root_dev /mnt || return 1 mkdir -p /mnt/boot mount -t ext3 $boot_dev /mnt/boot || return 1 if [ -n "$USE_RAID" ]; then mdadm --detail --scan > /etc/mdadm.conf rc-update --quiet add mdadm-raid boot fi rc-update --quiet add swap boot # the func to generate fstab does not detect swap. add it manually sed -i -e '/swap/d' /etc/fstab echo -e "$swap_dev\tswap\t\tswap\tdefaults 0 0" >> /etc/fstab install_mounted_root /mnt } # Parse args while getopts "r" opt; do case $opt in r) USE_RAID=1;; esac done shift $(( OPTIND - 1)) if [ -d "$1" ]; then # install to given mounted root install_mounted_root "${1%/}" exit $? fi disks=$(find_disks) # no disks so lets exit quietly. [ -z "$disks" ] && exit 0 if [ $# -gt 0 ]; then # check that they are for i in "$@"; do j=$(readlink -f "$i" | sed 's:^/dev/::; s:/:!:g') if ! [ -e "/sys/block/$j/device" ]; then echo "$i is not a suitable for partining" exit 1 fi done else set -- $disks rootdisk= while ! in_list "$rootdisk" $disks "none" "abort"; do echo "Available disks are: $disks" echon "Which one is the root disk? (or none) [$1] " default_read rootdisk $1 done case "$rootdisk" in none|abort) exit 0;; esac fi #echon "Do you want use *all* of $rootdisk for Alpine? (y/n) [n] " #default_read useall "n" #case "$useall" in # [Yy]*) useall="yes";; #esac # #if [ "x$useall" != "xyes" ]; then # echo "Only 'use all' option is available at the moment. Sorry" # exit 1 #fi rootdisk_dev=${rootdisk_dev:-"/dev/$rootdisk"} if ! [ -b "$rootdisk_dev" ]; then echo "$rootdisk_dev is not a block device" >&2 exit 1 fi useall $rootdisk_dev