Skip to content

Instantly share code, notes, and snippets.

@nghia4007
Last active February 25, 2024 13:28
Show Gist options
  • Save nghia4007/c4fb37b578b8d490e863d9cb9a8fb69c to your computer and use it in GitHub Desktop.
Save nghia4007/c4fb37b578b8d490e863d9cb9a8fb69c to your computer and use it in GitHub Desktop.
setup_alpine.sh
#!/bin/sh
PREFIX=
: ${LIBDIR=$PREFIX/lib}
. "$LIBDIR/libalpine.sh"
. "$LIBDIR/dasd-functions.sh"
MBR=${MBR:-"/usr/share/syslinux/mbr.bin"}
ROOTFS=${ROOTFS:-ext4}
BOOTFS=${BOOTFS:-ext4}
VARFS=${VARFS:-ext4}
DISKLABEL=${DISKLABEL:-dos}
KERNELOPTS=${KERNELOPTS:-quiet}
# default location for mounted root
SYSROOT=${SYSROOT:-/mnt}
in_list() {
local i="$1"
shift
while [ $# -gt 0 ]; do
[ "$i" = "$1" ] && return 0
shift
done
return 1
}
all_in_list() {
local needle="$1"
local i
[ -z "$needle" ] && return 1
shift
for i in $needle; do
in_list "$i" $@ || return 1
done
return 0
}
# wrapper to only show given device
_blkid() {
blkid | grep "^$1:"
}
# if given device have an UUID display it, otherwise return the device
uuid_or_device() {
local i=
case "$1" in
/dev/md*) echo "$1" && return 0;;
esac
for i in $(_blkid "$1"); do
case "$i" in
UUID=*) eval $i;;
esac
done
if [ -n "$UUID" ]; then
echo "UUID=$UUID"
else
echo "$1"
fi
}
# generate an fstab from a given mountpoint. Convert to UUID if possible
enumerate_fstab() {
local mnt="$1"
local fs_spec= fs_file= fs_vfstype= fs_mntops= fs_freq= fs_passno=
[ -z "$mnt" ] && return
local escaped_mnt=$(echo $mnt | sed -e 's:/*$::' -e 's:/:\\/:g')
awk "\$2 ~ /^$escaped_mnt(\/|\$)/ {print \$0}" /proc/mounts | \
sed "s:$mnt:/:g; s: :\t:g" | sed -E 's:/+:/:g' | \
while read fs_spec fs_file fs_vfstype fs_mntops fs_freq fs_passno; do
if [ "$fs_file" = / ]; then
fs_passno=1
else
fs_passno=2
fi
echo -e "$(uuid_or_device $fs_spec)\t${fs_file}\t${fs_vfstype}\t${fs_mntops} ${fs_freq} ${fs_passno}"
done
}
# given an fstab on stdin, determine if any of the mountpoints are encrypted
crypt_required() {
while read -r devname mountpoint fstype mntops freq passno; do
if [ -z "$devname" ] || [ "${devname###}" != "$devname" ]; then
continue
fi
uuid="${devname##UUID=}"
if [ "$uuid" != "$devname" ]; then
devname="$(blkid --uuid "$uuid")"
fi
local devnames="$devname"
if is_lvm "$devname"; then
local vg=$(find_volume_group "$devname")
devnames=$(find_pvs_in_vg $vg)
fi
for dev in $devnames; do
mapname="${dev##/dev/mapper/}"
if [ "$mapname" != "$dev" ]; then
if cryptsetup status "$mapname" >&1 >/dev/null; then
return 0
fi
fi
done
done
return 1
}
is_vmware() {
grep -q VMware /proc/scsi/scsi 2>/dev/null \
|| grep -q VMware /proc/ide/hd*/model 2>/dev/null
}
# return true (0) if given device is lvm
is_lvm() {
lvs "$1" >/dev/null 2>&1
}
is_efi() {
[ -d "/sys/firmware/efi" ] && return 0
return 1
}
is_rpi() {
grep -q "Raspberry Pi" /proc/device-tree/model 2>/dev/null
}
# Find the disk device from given partition
disk_from_part() {
local path=${1%/*}
local dev=${1##*/}
echo $path/$(basename "$(readlink -f "/sys/class/block/$dev/..")")
}
# $1 partition type (swap,linux,raid,lvm,prep,esp)
# return partition type id based on table type
partition_id() {
local id
if [ "$DISKLABEL" = "gpt" ]; then
case "$1" in
swap) id=0657FD6D-A4AB-43C4-84E5-0933C84B4F4F ;;
linux) id=0FC63DAF-8483-4772-8E79-3D69D8477DE4 ;;
raid) id=A19D880F-05FC-4D3B-A006-743F0F84911E ;;
lvm) id=E6D6D379-F507-44C2-A23C-238F2A3DF928 ;;
prep) id=9E1A2d38-C612-4316-AA26-8B49521E5A8B ;;
esp) id=C12A7328-F81F-11D2-BA4B-00A0C93EC93B ;;
*) die "Partition id \"$1\" is not supported!" ;;
esac
elif [ "$DISKLABEL" = "dos" ]; then
case "$1" in
swap) id=82 ;;
linux) id=83 ;;
raid) id=fd ;;
lvm) id=8e ;;
prep) id=41 ;;
esp) id=EF ;;
vfat) id=0c ;;
*) die "Partition id \"$1\" is not supported!" ;;
esac
elif [ "$DISKLABEL" = "eckd" ]; then
case "$1" in
native|lvm|swap|raid|gpfs) id="$1" ;;
esac
else
die "Partition label \"$DISKLABEL\" is not supported!"
fi
echo $id
}
# find partitions based on partition type from specified disk
# type can be any type from partition_id or the literal string "boot"
find_partitions() {
local dev="$1" type="$2" search=
if is_dasd "$dev" eckd; then
case "$type" in
boot) echo "$dev"1 ;;
*) fdasd -p "$dev" | grep "Linux $(partition_id "$type")" | awk '{print $1}' | tail -n 1 ;;
esac
return 0
fi
case "$type" in
boot)
search=bootable
[ -n "$USE_EFI" ] && search=$(partition_id esp)
sfdisk -d "$dev" | awk '/'$search'/ {print $1}'
;;
*)
search=$(partition_id "$type")
sfdisk -d "$dev" | awk '/type='$search'/ {print $1}'
;;
esac
}
unpack_apkovl() {
local ovl="$1"
local dest="$2"
local suffix=${ovl##*.}
local i
ovlfiles=/tmp/ovlfiles
if [ "$suffix" = "gz" ]; then
if ! tar -C "$dest" --numeric-owner -zxvf "$ovl" > $ovlfiles; then
if ! ask_yesno "Continue anyway? (y/n)"; then
return 1
fi
fi
return 0
fi
apk add --quiet openssl
if ! openssl list-cipher-commands | grep "^$suffix$" > /dev/null; then
errstr="Cipher $suffix is not supported"
return 1
fi
local count=0
# beep
echo -e "\007"
while [ $count -lt 3 ]; do
openssl enc -d -$suffix -in "$ovl" | tar --numeric-owner \
-C "$dest" -zxv >$ovlfiles 2>/dev/null && return 0
count=$(( $count + 1 ))
done
ovlfiles=
return 1
}
# find filesystem of given mounted dir
find_mount_fs() {
local mount_point="$1"
awk "\$2 == \"$mount_point\" {print \$3}" /proc/mounts | tail -n 1
}
# find device for given mounted dir
find_mount_dev() {
local mnt="$1"
awk "\$2 == \"$mnt\" { print \$1 }" /proc/mounts | tail -n 1
}
supported_boot_fs() {
local supported="ext2 ext3 ext4 btrfs xfs vfat"
local fs=
if is_rpi; then
supported=vfat
fi
for fs in $supported; do
[ "$fs" = "$1" ] && return 0
done
echo "$1 is not supported. Only supported are: $supported" >&2
return 1
}
supported_part_label() {
case "$1" in
dos|gpt|eckd) return 0 ;;
*) die "Partition label \"$DISKLABEL\" is not supported!" ;;
esac
}
find_volume_group() {
local lv=${1##*/}
lvs --noheadings "$1" | awk '{print $2}'
}
find_pvs_in_vg() {
local vg="$1"
pvs --noheadings | awk "\$2 == \"$vg\" {print \$1}"
}
init_chroot_mounts() {
local mnt="$1" i=
for i in proc dev; do
mkdir -p "$mnt"/$i
mount --bind /$i "$mnt"/$i
done
}
cleanup_chroot_mounts() {
local mnt="$1" i=
for i in proc dev; do
umount "$mnt"/$i
done
}
get_bootopt() {
local opt="$1"
set -- $(cat /proc/cmdline)
for i; do
case "$i" in
"$opt"|"$opt"=*) echo "${i#*=}"; break;;
esac
done
}
# setup GRUB bootloader
setup_grub() {
local mnt="$1" root="$2" modules="$3" kernel_opts="$4" bootdev="$5"
# install GRUB efi mode
if [ -n "$USE_EFI" ]; then
local target fwa
local efi_directory="$mnt"/boot/efi
case "$ARCH" in
x86_64) target=x86_64-efi ; fwa=x64 ;;
x86) target=i386-efi ; fwa=ia32 ;;
arm*) target=arm-efi ; fwa=arm ;;
aarch64) target=arm64-efi ; fwa=aa64 ;;
riscv64) target=riscv64-efi ; fwa=riscv64 ;;
esac
if [ -n "$USE_CRYPT" ]; then
efi_directory="$mnt"/boot
fi
# currently disabling nvram so grub doesnt call efibootmgr
# installing to alpine directory so other distros dont overwrite it
grub-install --target=$target --efi-directory="$efi_directory" \
--bootloader-id=alpine --boot-directory="$mnt"/boot --no-nvram
# fallback mode will use boot/boot${fw arch}.efi
install -D "$efi_directory"/EFI/alpine/grub$fwa.efi \
"$efi_directory"/EFI/boot/boot$fwa.efi
# install GRUB for ppc64le
elif [ "$ARCH" = "ppc64le" ]; then
shift 5
local disks="${@}"
for disk in $disks; do
prep=$(find_partitions "$disk" "prep")
echo "Installing grub on $prep"
grub-install --boot-directory="$mnt"/boot $prep
done
# install GRUB in bios mode
else
local bootdisk=$(disk_from_part $bootdev)
case "$ARCH" in
x86|x86_64) grub-install --boot-directory="$mnt"/boot \
--target=i386-pc $bootdisk ;;
*) die "Cannot install GRUB in BIOS mode for $ARCH" ;;
esac
fi
# setup GRUB config. trigger will generate final grub.cfg
install -d "$mnt"/etc/default/
cat > "$mnt"/etc/default/grub <<- EOF
GRUB_TIMEOUT=2
GRUB_DISABLE_SUBMENU=y
GRUB_DISABLE_RECOVERY=true
GRUB_CMDLINE_LINUX_DEFAULT="modules=$modules $kernel_opts"
EOF
}
# setup syslinux bootloader
setup_syslinux() {
local mnt="$1" root="$2" modules="$3" kernel_opts="$4" bootdev="$5"
local exlinux_raidopt=
sed -e "s:^root=.*:root=$root:" \
-e "s:^default_kernel_opts=.*:default_kernel_opts=\"$kernel_opts\":" \
-e "s:^modules=.*:modules=$modules:" \
/etc/update-extlinux.conf > "$mnt"/etc/update-extlinux.conf
# Check if we boot from raid so we can pass proper option to
# extlinux later.
if [ -e "/sys/block/${bootdev#/dev/}/md" ]; then
extlinux_raidopt="--raid"
fi
extlinux $extlinux_raidopt --install "$mnt"/boot
}
# setup u-boot bootloader
setup_uboot() {
local mnt="$1" root="$2" modules="$3" kernel_opts="$4"
local parameters="root=$root modules=$modules $kernel_opts"
mkdir -p "$mnt"/boot/extlinux
cat > "$mnt/boot/extlinux/extlinux.conf" <<- EOF
menu title Alpine Linux
timeout 50
default $KERNEL_FLAVOR
label $KERNEL_FLAVOR
menu label Linux $KERNEL_FLAVOR
kernel /vmlinuz-$KERNEL_FLAVOR
initrd /initramfs-$KERNEL_FLAVOR
fdtdir /dtbs-$KERNEL_FLAVOR
append $parameters
EOF
# Rely on update-u-boot to automatically determine the
# board, imagedir, etc. this may not work in all cases.
update-u-boot
}
rpi_gen_config() {
cat <<-EOF
# do not modify this file as it will be overwritten on upgrade.
# create and/or modify usercfg.txt instead.
# https://www.raspberrypi.com/documentation/computers/config_txt.html
EOF
case "$ARCH" in
armhf)
cat <<-EOF
[pi0]
kernel=vmlinuz-rpi
initramfs initramfs-rpi
[pi0w]
kernel=vmlinuz-rpi
initramfs initramfs-rpi
[pi1]
kernel=vmlinuz-rpi
initramfs initramfs-rpi
[pi02]
kernel=vmlinuz-rpi2
initramfs initramfs-rpi2
[pi2]
kernel=vmlinuz-rpi2
initramfs initramfs-rpi2
[pi3]
kernel=vmlinuz-rpi2
initramfs initramfs-rpi2
[pi3+]
kernel=vmlinuz-rpi2
initramfs initramfs-rpi2
[all]
include usercfg.txt
EOF
;;
armv7)
cat <<-EOF
[pi02]
kernel=vmlinuz-rpi2
initramfs initramfs-rpi2
[pi2]
kernel=vmlinuz-rpi2
initramfs initramfs-rpi2
[pi3]
kernel=vmlinuz-rpi2
initramfs initramfs-rpi2
[pi3+]
kernel=vmlinuz-rpi2
initramfs initramfs-rpi2
[pi4]
kernel=vmlinuz-rpi4
initramfs initramfs-rpi4
[all]
include usercfg.txt
EOF
;;
aarch64)
cat <<-EOF
[pi02]
kernel=vmlinuz-rpi
initramfs initramfs-rpi
[pi3]
kernel=vmlinuz-rpi
initramfs initramfs-rpi
[pi3+]
kernel=vmlinuz-rpi
initramfs initramfs-rpi
[pi4]
enable_gic=1
kernel=vmlinuz-rpi4
initramfs initramfs-rpi4
[all]
arm_64bit=1
include usercfg.txt
EOF
;;
esac
}
# setup rpi bootloader
setup_raspberrypi_bootloader() {
local mnt="$1" root="$2" modules="$3" kernel_opts="$4"
rpi_gen_config > "$mnt"/boot/config.txt
echo "root=$root modules=$modules $kernel_opts" > "$mnt"/boot/cmdline.txt
}
# detect which firmware packages to install, if any
select_firmware_pkgs() {
local firmware_pkgs=$( (cd /sys/module/ && echo *) \
| xargs modinfo -F firmware 2>/dev/null \
| awk -F/ '{print $1 == $0 ? "linux-firmware-other" : "linux-firmware-"$1}' \
| sort -u)
echo ${firmware_pkgs:-linux-firmware-none}
}
is_nvme_dev() {
local i
for i; do
case ${i##*/} in
nvme*) return 0;;
esac
done
return 1
}
install_mounted_root() {
local mnt="$1"
shift 1
local disks="${@}" mnt_boot= boot_fs= root_fs= use_crypt=
local initfs_features="ata base ide scsi usb virtio"
local pvs= dev= rootdev= cryptdev= bootdev= extlinux_raidopt= root= modules=
local kernel_opts="$KERNELOPTS"
[ "$ARCH" = "s390x" ] && initfs_features="$initfs_features qeth dasd_mod"
is_rpi && initfs_features="base mmc usb"
rootdev=$(find_mount_dev "$mnt")
if [ -z "$rootdev" ]; then
echo "$mnt does not seem to be a mount point" >&2
return 1
fi
root_fs=$(find_mount_fs "$mnt")
initfs_features="$initfs_features $root_fs"
if is_lvm "$rootdev"; then
initfs_features="$initfs_features lvm"
local vg=$(find_volume_group "$rootdev")
pvs=$(find_pvs_in_vg $vg)
cryptdev=$(cryptsetup status $pvs 2>&1 | awk '/device:/ { print $2 }')
else
cryptdev=$(cryptsetup status "$rootdev" 2>&1 | awk '/device:/ { print $2 }')
fi
bootdev=$(find_mount_dev "$mnt"/boot)
if [ -z "$bootdev" ]; then
bootdev=$rootdev
mnt_boot="$mnt"
else
mnt_boot="$mnt"/boot
fi
boot_fs=$(find_mount_fs "$mnt_boot")
if ! supported_boot_fs "$boot_fs"; then
[ -z "$FORCE_BOOTFS" ] && return 1
echo "Continuing at your own risk."
fi
# check if our root is on raid so we can feed mkinitfs and
# bootloader conf with the proper kernel module params
for dev in $rootdev $pvs $cryptdev; do
# check if we need hardware raid drivers
case $dev in
/dev/cciss/*)
initfs_features="${initfs_features% raid} raid"
;;
/dev/nvme*)
initfs_features="${initfs_features% nvme} nvme"
;;
/dev/mmc*)
initfs_features="${initfs_features% mmc} mmc"
;;
esac
local md=${dev#/dev/}
[ -e "/sys/block/$md/md" ] || continue
if is_nvme_dev /sys/block/$md/slaves/*; then
initfs_features="${initfs_features% nvme} nvme"
fi
initfs_features="${initfs_features% raid} raid"
local level=$(cat /sys/block/$md/md/level)
case "$level" in
raid1) raidmod="${raidmod%,raid1},raid1";;
raid[456]) raidmod="${raidmod%,raid456},raid456";;
esac
done
if [ -n "$VERBOSE" ]; then
echo "Root device: $rootdev"
echo "Root filesystem: $root_fs"
echo "Boot device: $bootdev"
echo "Boot filesystem: $boot_fs"
fi
if [ -z "$APKOVL" ]; then
ovlfiles=/tmp/ovlfiles
lbu package - | tar -C "$mnt" -zxv > "$ovlfiles"
# comment out local repositories
if [ -f "$mnt"/etc/apk/repositories ]; then
sed -i -e 's:^/:#/:' "$mnt"/etc/apk/repositories
fi
else
echo "Restoring backup from $APKOVL to $rootdev..."
unpack_apkovl "$APKOVL" "$mnt" || return 1
fi
# we should not try start modloop on sys install
rm -f "$mnt"/etc/runlevels/*/modloop
# generate the fstab
if [ -f "$mnt"/etc/fstab ]; then
mv "$mnt"/etc/fstab "$mnt"/etc/fstab.old
fi
enumerate_fstab "$mnt" >> "$mnt"/etc/fstab
if [ -n "$SWAP_DEVICES" ]; then
local swap_dev
for swap_dev in $SWAP_DEVICES; do
echo -e "$(uuid_or_device ${swap_dev})\tswap\tswap\tdefaults\t0 0" \
>> "$mnt"/etc/fstab
done
fi
cat >>"$mnt"/etc/fstab <<-__EOF__
/dev/cdrom /media/cdrom iso9660 noauto,ro 0 0
/dev/usbdisk /media/usb vfat noauto 0 0
tmpfs /tmp tmpfs nosuid,nodev 0 0
__EOF__
if crypt_required <"$mnt"/etc/fstab; then
use_crypt=1
initfs_features="$initfs_features cryptsetup keymap"
if is_nvme_dev /sys/block/dm-*/slaves/*; then
initfs_features="$initfs_features nvme"
fi
fi
# generate mkinitfs.conf
mkdir -p "$mnt"/etc/mkinitfs/features.d
echo "features=\"$initfs_features\"" > "$mnt"/etc/mkinitfs/mkinitfs.conf
if [ -n "$raidmod" ]; then
echo "/sbin/mdadm" > "$mnt"/etc/mkinitfs/features.d/raid.files
echo "/etc/mdadm.conf" >> "$mnt"/etc/mkinitfs/features.d/raid.files
fi
# generate update-extlinux.conf
root=$(uuid_or_device $rootdev)
kernel_opts="$kernel_opts rootfstype=$root_fs"
if [ -n "$(get_bootopt nomodeset)" ]; then
kernel_opts="nomodeset $kernel_opts"
fi
if [ "$use_crypt" ]; then
# Boot to encrypted root
if [ $(echo "$pvs" | wc -w) -gt 1 ]; then
echo "Root logical volume spans more than one physical volume."
echo "This is currently unsupported."
echo "Proceed manually or retry with root on a single physical volume."
exit 1
fi
local cryptroot=${pvs:-"$rootdev"}
if cryptsetup status "$cryptroot" 2>&1 >/dev/null; then
cryptroot=$(cryptsetup status "$cryptroot" | awk '/device:/ { print $2 }')
cryptroot=$(uuid_or_device $cryptroot)
kernel_opts="cryptroot=$cryptroot cryptdm=root $kernel_opts"
root=$([ -n "$pvs" ] && echo "$rootdev" || echo "/dev/mapper/root")
fi
fi
modules="sd-mod,usb-storage,${root_fs}${raidmod}"
case "$initfs_features" in
*nvme*) modules="$modules,nvme";;
esac
# remove the installed db in case its there so we force re-install
rm -f "$mnt"/var/lib/apk/installed "$mnt"/lib/apk/db/installed
echo "Installing system on $rootdev:"
case "$BOOTLOADER" in
grub) setup_grub "$mnt" "$root" "$modules" "$kernel_opts" "$bootdev" $disks ;;
syslinux) setup_syslinux "$mnt" "$root" "$modules" "$kernel_opts" "$bootdev" ;;
zipl) setup_zipl "$mnt" "$root" "$modules" "$kernel_opts" ;;
raspberrypi-bootloader) setup_raspberrypi_bootloader "$mnt" "$root" "$modules" "$kernel_opts" ;;
u-boot) setup_uboot "$mnt" "$root" "$modules" "$kernel_opts" ;;
*) die "Bootloader \"$BOOTLOADER\" not supported!" ;;
esac
# 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/
local apkflags="--initdb --quiet --progress --update-cache --clean-protected"
local pkgs=$(grep -h -v -w sfdisk "$mnt"/etc/apk/world \
"$mnt"/var/lib/apk/world 2>/dev/null)
pkgs="$pkgs acct linux-$KERNEL_FLAVOR alpine-base $(select_bootloader_pkg) $(select_firmware_pkgs)"
if [ "$(rc --sys)" = "XEN0" ]; then
pkgs="$pkgs xen-hypervisor"
fi
if is_rpi; then
pkgs="$pkgs dosfstools"
fi
local repos=$(sed -e 's/\#.*//' /etc/apk/repositories)
local repoflags=
for i in $repos; do
repoflags="$repoflags --repository $i"
done
init_chroot_mounts "$mnt"
apk add --root "$mnt" $apkflags --overlay-from-stdin \
$repoflags $pkgs <$ovlfiles
local ret=$?
cleanup_chroot_mounts "$mnt"
return $ret
}
unmount_partitions() {
local mnt="$1"
# unmount the partitions
umount $(awk '{print $2}' /proc/mounts | egrep "^$mnt(/|\$)" | sort -r)
if [ -n "$USE_CRYPT" ]; then
if [ -n "$USE_LVM" ]; then
vgchange -a n
fi
cryptsetup close /dev/mapper/root
fi
}
# 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 or no more than 1/3 of smallest disk space
local size=$(( $memtotal_kb * 2 / 1024 ))
local disk= disksize=
for disk in $@; do
local sysfsdev=$(echo ${disk#/dev/} | sed 's:/:!:g')
local sysfspath=/sys/block/$sysfsdev/size
# disksize = x * 512 / (1024 * 1024) = x / 2048
# maxsize = $disksize / 4 = x / (2048 * 4) = x / 8192
maxsize=$(awk '{ printf "%i", $0 / 8192 }' $sysfspath )
if [ $size -gt $maxsize ]; then
size=$maxsize
fi
done
if [ $size -gt 4096 ]; then
# dont ever use more than 4G
size=4096
elif [ $size -lt 64 ]; then
# dont bother create swap smaller than 64MB
size=0
fi
echo 0
}
has_mounted_part() {
local p
local sysfsdev=$(echo ${1#/dev/} | sed 's:/:!:g')
# parse /proc/mounts for mounted devices
for p in $(awk '$1 ~ /^\/dev\// {gsub("/dev/", "", $1); gsub("/", "!", $1); print $1}' \
/proc/mounts); do
[ "$p" = "$sysfsdev" ] && return 0
[ -e /sys/block/$sysfsdev/$p ] && return 0
done
return 1
}
has_holders() {
local i
# check if device is used by any md devices
for i in $1/holders/* $1/*/holders/*; do
[ -e "$i" ] && return 0
done
return 1
}
is_available_disk() {
local dev=$1
local b=$(echo $p | sed 's:/:!:g')
# check if its a "root" block device and not a partition
[ -e /sys/block/$b ] || return 1
# check so it does not have mounted partitions
has_mounted_part $dev && return 1
# check so its not part of an md setup
if has_holders /sys/block/$b; then
[ -n "$USE_RAID" ] && echo "Warning: $dev is part of a running raid" >&2
return 1
fi
# check so its not an md device
[ -e /sys/block/$b/md ] && return 1
return 0
}
find_disks() {
local p=
# filter out ramdisks (major=1)
for p in $(awk '$1 != 1 && $1 ~ /[0-9]+/ {print $4}' /proc/partitions); do
is_available_disk $p && echo -n " $p"
done
}
stop_all_raid() {
local rd
for rd in /dev/md*; do
[ -b $rd ] && mdadm --stop $rd
done
}
select_bootloader_pkg() {
local bootloader="$BOOTLOADER"
if [ "$ARCH" = "ppc64le" ]; then
bootloader=grub-ieee1275
elif [ "$ARCH" = "s390x" ]; then
bootloader=s390-tools
elif [ -n "$USE_EFI" ]; then
bootloader=grub-efi
elif [ "$BOOTLOADER" = "grub" ]; then
bootloader=grub-bios
fi
echo "$bootloader"
}
# install needed programs
init_progs() {
local raidpkg= lvmpkg= cryptpkg= fs= fstools= grub=
[ -n "$USE_RAID" ] && raidpkg="mdadm"
[ -n "$USE_LVM" ] && lvmpkg="lvm2"
[ -n "$USE_CRYPT" ] && cryptpkg="cryptsetup blkid"
for fs in $BOOTFS $ROOTFS $VARFS; do
# we need load btrfs module early to avoid the error message:
# 'failed to open /dev/btrfs-control'
if ! grep -q -w "$fs" /proc/filesystems; then
modprobe $fs
fi
case $fs in
xfs) fstools="$fstools xfsprogs";;
ext*) fstools="$fstools e2fsprogs";;
btrfs) fstools="$fstools btrfs-progs";;
vfat) fstools="$fstools dosfstools";;
esac
done
apk add --quiet sfdisk $cryptpkg $lvmpkg $raidpkg $fstools $@
}
show_disk_info() {
local disk= vendor= model= d= size= busid=
for disk in $@; do
local dev=${disk#/dev/}
d=$(echo $dev | sed 's:/:!:g')
vendor=$(cat /sys/block/$d/device/vendor 2>/dev/null)
model=$(cat /sys/block/$d/device/model 2>/dev/null)
busid=$(readlink -f /sys/block/$d/device 2>/dev/null)
size=$(awk '{gb = ($1 * 512)/1000000000; printf "%.1f GB\n", gb}' /sys/block/$d/size 2>/dev/null)
if is_dasd $dev eckd; then
echo " $dev ($size $vendor ${busid##*/})"
else
echo " $dev ($size $vendor $model)"
fi
done
}
confirm_erase() {
local erasedisks="$@"
if [ "$ERASE_DISKS" = "$erasedisks" ]; then
return 0
fi
echo "WARNING: The following disk(s) will be erased:"
show_disk_info $@
ask_yesno "WARNING: Erase the above disk(s) and continue? (y/n)" n
}
# setup partitions on given disk dev in $1.
# usage: setup_partitions <diskdev> size1,type1 [size2,type2 ...]
setup_partitions() {
local diskdev="$1" start=1M line=
shift
supported_part_label "$DISKLABEL" || return 1
# initialize MBR for syslinux only
if [ "$BOOTLOADER" = "syslinux" ] && [ -f "$MBR" ]; then
cat "$MBR" > $diskdev
fi
# create new partitions
(
for line in "$@"; do
case "$line" in
0M*) ;;
*) echo "$start,$line"; start= ;;
esac
done
) | sfdisk --quiet --label $DISKLABEL $diskdev || return 1
# create device nodes if not exist
mdev -s
}
# set up optional raid and create filesystem on boot device.
setup_boot_dev() {
local disks="$@" disk= bootdev= mkfs_args=
[ "$BOOTFS" != "vfat" ] && mkfs_args="-q"
local part=$(for disk in $disks; do find_partitions "$disk" "boot"; done)
set -- $part
bootdev=$1
[ -z "$bootdev" ] && return 1
if [ "$ARCH" = "ppc64le" ]; then
# Change bootable partition to PReP partition
for disk in $disks; do
echo ',,,*' | sfdisk --quiet $disk -N1
echo ',,,-' | sfdisk --quiet $disk -N2
mdev -s
done
fi
echo "Creating file systems..."
if [ -n "$USE_RAID" ]; then
local missing=
local num=$#
if [ $# -eq 1 ]; then
missing="missing"
num=2
fi
# we only use raid level 1 for boot devices
mdadm --create /dev/md0 --level=1 --raid-devices=$num \
--metadata=0.90 --quiet --run $@ $missing || return 1
bootdev=/dev/md0
fi
case "$BOOTFS" in
vfat) mkfs_args="-F 32";; # UEFI firmware often only support FAT32
btrfs) mkfs_args="";;
ext4) mkfs_args="$mkfs_args -O ^64bit";; # pv-grub does not support 64bit
esac
mkfs.$BOOTFS $MKFS_OPTS_BOOT $mkfs_args $bootdev
BOOT_DEV="$bootdev"
}
# $1 = index
# $2 = partition type
# $3... = disk devices
find_nth_non_boot_parts() {
local idx=$1 id=$2 disk= type=bootable
shift 2
local disks="$@"
[ -n "$USE_EFI" ] && type=$(partition_id esp)
for disk in $disks; do
if is_dasd $disk eckd; then
fdasd -p $disk | grep "Linux $id" | awk '{print $1}' | tail -n 1
else
sfdisk -d $disk | grep -v $type \
| awk "/(Id|type)=$id/ { i++; if (i==$idx) print \$1 }"
fi
done
}
setup_non_boot_raid_dev() {
local md_dev=$1
local idx=${md_dev#/dev/md}
[ -z "$md_dev" ] && return 0
if [ "$ARCH" = "ppc64le" ]; then
# increment idx as PReP partition is
# the bootable partition in ppc64le
idx=$((idx+1))
fi
shift
local level=1
local missing=
local pid=$(partition_id raid)
local raid_parts=$(find_nth_non_boot_parts $idx $pid $@)
set -- $raid_parts
# how many disks do we have?
case $# in
0) echo "No Raid partitions found" >&2; return 1;;
1) level=1; missing="missing"; num=2;;
2) level=1; missing= ; num=2;;
*) level=5; missing= ; num=$#;;
esac
mdadm --create $md_dev --level=$level --raid-devices=$num \
--quiet --run $@ $missing || return 1
}
# setup device for lvm, create raid array if needed
setup_lvm_volume_group() {
local vgname="$1"
shift
local lvmdev=
if [ -n "$USE_RAID" ]; then
setup_non_boot_raid_dev /dev/md1 $@ || return 1
lvmdev=/dev/md1
else
lvmdev=$(find_partitions "$1" "lvm")
fi
if [ -n "$USE_CRYPT" ] && [ "$DISK_MODE" = "data" ]; then
echo -e "target=var\nsource='$lvmdev'" > /etc/conf.d/dmcrypt
lvmdev=$(setup_crypt $lvmdev var) || return 1
rc-update add dmcrypt boot
fi
if [ -n "$USE_CRYPT" ] && [ "$DISK_MODE" = "sys" ]; then
lvmdev=$(setup_crypt $lvmdev root) || return 1
fi
# be quiet on success
local errmsg=$(dd if=/dev/zero of=$lvmdev bs=1k count=1 2>&1) \
|| echo "$errmsg"
pvcreate --quiet $lvmdev \
&& vgcreate --quiet $vgname $lvmdev >/dev/null
}
# set up swap on given device(s)
setup_swap_dev() {
local swap_dev=
sed -i -e '/swap/d' /etc/fstab
SWAP_DEVICES=
for swap_dev in "$@"; do
mkswap $swap_dev >/dev/null
echo -e "$(uuid_or_device $swap_dev)\tswap\t\tswap\tdefaults 0 0" >> /etc/fstab
SWAP_DEVICES="$SWAP_DEVICES $swap_dev"
done
swapon -a
rc-update --quiet add swap boot
}
# setup and enable swap on given volumegroup if needed
setup_lvm_swap() {
local vgname="$1"
local swapname=lv_swap
if [ -z "$SWAP_SIZE" ] || [ "$SWAP_SIZE" -eq 0 ]; then
return
fi
lvcreate --quiet -n $swapname -L ${SWAP_SIZE}MB $vgname
setup_swap_dev /dev/$vgname/$swapname
}
# if /var is mounted, move out data and umount it
reset_var() {
[ -z "$(find_mount_dev /var)" ] && return 0
mkdir /.var
mv /var/* /.var/ 2>/dev/null
umount /var && rm -rf /var && mv /.var /var && rm -rf /var/lost+found
}
# set up /var on given device
setup_var() {
local var_dev="$1"
local varfs=${VARFS}
echo "Creating file systems..."
mkfs.$varfs $MKFS_OPTS_VAR $var_dev >/dev/null || return 1
sed -i -e '/[[:space:]]\/var[[:space:]]/d' /etc/fstab
echo -e "$(uuid_or_device ${var_dev})\t/var\t\t${varfs}\tdefaults 1 2" >> /etc/fstab
mv /var /.var
mkdir /var
mount /var
mv /.var/* /var/
rmdir /.var
service syslog --quiet condrestart
setup_mdadm_conf
}
setup_mdadm_conf() {
local mods= mod=
if [ -n "$USE_RAID" ]; then
mdadm --detail --scan > /etc/mdadm.conf
rc-update --quiet add mdadm-raid boot
mods=$(awk '/^raid/ {print $1}' /proc/modules)
for mod in $mods; do
if ! grep -q "^$mod" /etc/modules; then
echo $mod >> /etc/modules
fi
done
fi
}
data_only_disk_install_lvm() {
local diskdev=
local vgname=vg0
local var_dev=/dev/$vgname/lv_var
local lvm_part_type=$(partition_id lvm)
local size=$LVM_SIZE
unset BOOTLOADER
init_progs || return 1
confirm_erase $@ || return 1
if [ "$USE_RAID" ]; then
lvm_part_type=$(partition_id raid)
stop_all_raid
fi
for diskdev in "$@"; do
setup_partitions $diskdev "${size}${size:+M},$lvm_part_type" || return 1
done
setup_lvm_volume_group $vgname $@ || return 1
setup_lvm_swap $vgname
lvcreate --quiet -n ${var_dev##*/} -l 100%FREE $vgname
setup_mdadm_conf
rc-update add lvm boot
setup_var $var_dev
}
data_only_disk_install() {
local diskdev=
local var_dev=
local var_part_type=$(partition_id linux)
local swap_part_type=$(partition_id swap)
local size=
local swap_dev= var_dev=
unset BOOTLOADER
init_progs || return 1
confirm_erase $@ || return 1
if [ "$USE_RAID" ]; then
var_part_type=$(partition_id raid)
swap_part_type=$(partition_id raid)
stop_all_raid
fi
for diskdev in "$@"; do
setup_partitions $diskdev \
"${SWAP_SIZE}M,$swap_part_type" \
"${size}${size:+M},$var_part_type" || return 1
done
if [ "$USE_RAID" ]; then
if [ $SWAP_SIZE -gt 0 ]; then
swap_dev=/dev/md1
var_dev=/dev/md2
else
swap_dev=
var_dev=/dev/md1
fi
setup_non_boot_raid_dev "$swap_dev" $@ || return 1
setup_non_boot_raid_dev "$var_dev" $@ || return 1
else
swap_dev=$(find_nth_non_boot_parts 1 "$swap_part_type" $@)
var_dev=$(find_nth_non_boot_parts 1 "$var_part_type" $@)
fi
if [ -n "$USE_CRYPT" ]; then
echo -e "target=var\nsource='$var_dev'" > /etc/conf.d/dmcrypt
var_dev=$(setup_crypt $var_dev var) || return 1
rc-update add dmcrypt boot
fi
[ $SWAP_SIZE -gt 0 ] && setup_swap_dev $swap_dev
setup_var $var_dev
}
# setup
setup_root() {
local root_dev="$1" boot_dev="$2"
shift 2
local disks="$@" mkfs_args="-q"
[ "$ROOTFS" = "btrfs" ] && mkfs_args=""
mkfs.$ROOTFS $MKFS_OPTS_ROOT $mkfs_args "$root_dev"
mkdir -p "$SYSROOT"
mount -t $ROOTFS $root_dev "$SYSROOT" || return 1
if [ -n "$boot_dev" ] && ([ -z "$USE_EFI" ] || [ -n "$USE_CRYPT" ]); then
mkdir -p "$SYSROOT"/boot
mount -t $BOOTFS $boot_dev "$SYSROOT"/boot || return 1
fi
if [ -n "$boot_dev" ] && [ -n "$USE_EFI" ] && [ -z "$USE_CRYPT" ]; then
mkdir -p "$SYSROOT"/boot/efi
mount -t $BOOTFS $boot_dev "$SYSROOT"/boot/efi || return 1
fi
setup_mdadm_conf
install_mounted_root "$SYSROOT" "$disks" || return 1
swapoff -a
unmount_partitions "$SYSROOT"
echo ""
echo "Installation is complete. Please reboot."
}
native_disk_install_lvm() {
local diskdev= vgname=vg0
local lvm_part_type=$(partition_id lvm)
local boot_part_type=$(partition_id linux)
local boot_size=${BOOT_SIZE:-100}
local lvm_size=$LVM_SIZE
local root_dev=/dev/$vgname/lv_root
init_progs $(select_bootloader_pkg) || return 1
confirm_erase $@ || return 1
if [ "$BOOTFS" = "vfat" ] && [ -z "$USE_EFI" ]; then
boot_part_type=$(partition_id vfat)
fi
if [ -n "$USE_RAID" ]; then
boot_part_type=$(partition_id raid)
lvm_part_type=$(partition_id raid)
stop_all_raid
fi
if [ -n "$USE_EFI" ]; then
boot_part_type=$(partition_id esp)
fi
for diskdev in "$@"; do
if is_dasd $diskdev eckd; then
root_part_type="lvm"
setup_partitions_eckd $diskdev \
$boot_size 0 $root_part_type || return 1
else
setup_partitions $diskdev \
"${boot_size}M,$boot_part_type,*" \
"${lvm_size}${lvm_size:+M},$lvm_part_type" || return 1
fi
done
# will find BOOT_DEV for us
setup_boot_dev $@
setup_lvm_volume_group $vgname $@ || return 1
setup_lvm_swap $vgname
lvcreate --quiet -n ${root_dev##*/} -l ${ROOT_SIZE:-100%FREE} $vgname
rc-update add lvm boot
setup_root $root_dev $BOOT_DEV
}
setup_crypt() {
local dev="$1" local dmname="$2"
mkdir -p /run/cryptsetup
while true; do
echo "Preparing partition for encryption." >&2
echo "You will be prompted for your password at boot." >&2
echo "If you forget your password, your data will be lost." >&2
cryptsetup luksFormat --batch-mode --verify-passphrase \
--type luks2 "$dev" >&2
# Error codes are: 1 wrong parameters, 2 no permission (bad
# passphrase), 3 out of memory, 4 wrong device specified, 5 device
# already exists or device is busy.
# https://man7.org/linux/man-pages/man8/cryptsetup.8.html#RETURN_CODES
case $? in
2) continue;;
0) ;;
*) return 1;;
esac
echo "Enter password again to unlock disk for installation." >&2
cryptsetup open "$dev" "$dmname" >&2 \
&& break
echo "" >&2
done
echo "/dev/mapper/$dmname"
return 0
}
native_disk_install() {
local prep_part_type=$(partition_id prep)
local root_part_type=$(partition_id linux)
local swap_part_type=$(partition_id swap)
local boot_part_type=$(partition_id linux)
local prep_size=8
local boot_size=${BOOT_SIZE:-100}
local swap_size=${SWAP_SIZE}
local root_size=${ROOT_SIZE}
local root_dev= boot_dev= swap_dev=
init_progs $(select_bootloader_pkg) || return 1
confirm_erase $@ || return 1
if [ "$BOOTFS" = "vfat" ] && [ -z "$USE_EFI" ]; then
boot_part_type=$(partition_id vfat)
fi
if [ -n "$USE_RAID" ]; then
boot_part_type=$(partition_id raid)
root_part_type=$(partition_id raid)
swap_part_type=$(partition_id raid)
stop_all_raid
fi
if [ -n "$USE_EFI" ]; then
boot_part_type=$(partition_id esp)
fi
for diskdev in "$@"; do
if [ "$ARCH" = "ppc64le" ]; then
setup_partitions $diskdev \
"${prep_size}M,$prep_part_type" \
"${boot_size}M,$boot_part_type,*" \
"${swap_size}M,$swap_part_type" \
"${root_size}${root_size:+M},$root_part_type" \
|| return 1
elif is_dasd $diskdev eckd; then
swap_part_type="swap"
root_part_type="native"
setup_partitions_eckd $diskdev \
$boot_size $swap_size $root_part_type || return 1
else
setup_partitions $diskdev \
"${boot_size}M,$boot_part_type,*" \
"${swap_size}M,$swap_part_type" \
"${root_size}${root_size:+M},$root_part_type" \
|| return 1
fi
done
# will find BOOT_DEV for us
setup_boot_dev $@
if [ "$USE_RAID" ]; then
if [ $SWAP_SIZE -gt 0 ]; then
swap_dev=/dev/md1
root_dev=/dev/md2
else
swap_dev=
root_dev=/dev/md1
fi
setup_non_boot_raid_dev "$swap_dev" $@ || return 1
setup_non_boot_raid_dev "$root_dev" $@ || return 1
else
swap_dev=$(find_nth_non_boot_parts 1 "$swap_part_type" $@)
local index=
case "$ARCH" in
# use the second non-bootable partition on ppc64le,
# as PReP partition is the bootable partition
ppc64le) index=2;;
*) index=1;;
esac
root_dev=$(find_nth_non_boot_parts $index "$root_part_type" $@)
fi
if [ -n "$USE_CRYPT" ]; then
root_dev=$(setup_crypt $root_dev root) || return 1
fi
[ $SWAP_SIZE -gt 0 ] && setup_swap_dev $swap_dev
setup_root $root_dev $BOOT_DEV $@
}
diskselect_help() {
cat <<-__EOF__
The disk you select can be used for a traditional disk install or for a
data-only install.
The disk will be erased.
Enter 'none' if you want to run diskless.
__EOF__
}
diskmode_help() {
cat <<-__EOF__
You can select between 'sys', 'data', 'crypt', 'cryptsys', 'lvm', 'lvmsys'
or 'lvmdata'.
sys:
This mode is a traditional disk install. The following partitions will be
created on the disk: /boot, / (filesystem root) and swap.
This mode may be used for development boxes, desktops, virtual servers, etc.
data:
This mode uses your disk(s) for data storage, not for the operating system.
The system itself will run from tmpfs (RAM).
Use this mode if you only want to use the disk(s) for a mailspool, databases,
logs, etc.
crypt:
Enable encryption with cryptsetup and ask again for 'sys' or 'data'.
You will be prompted to enter a decryption password, and will need to
use this password to boot up the operating system after installation.
cryptsys:
Same as 'sys' but also enable encryption.
lvm:
Enable logical volume manager and ask again for 'sys' or 'data'.
lvmsys:
Same as 'sys' but use logical volume manager for partitioning.
lvmdata:
Same as 'data' but use logical volume manager for partitioning.
__EOF__
}
# ask for a root or data disk
# returns response in global variable $resp
ask_disk() {
local prompt="$1"
local help_func="$2"
local i=
shift 2
local default_disk=${DEFAULT_DISK:-$1}
resp=
while ! all_in_list "$resp" $@ "none" "abort"; do
echo "Available disks are:"
show_disk_info "$@"
ask "$prompt" "$default_disk"
case "$resp" in
'abort') exit 0;;
'none') return 0;;
'?') $help_func;;
*) for i in $resp; do
if ! [ -b "/dev/$i" ]; then
echo "/dev/$i is not a block device" >&2
resp=
fi
done;;
esac
done
}
usage() {
cat <<-__EOF__
usage: setup-disk [-hLqrve] [-k kernelflavor] [-m MODE] [-o apkovl] [-s SWAPSIZE]
[MOUNTPOINT | DISKDEV...]
Install alpine on harddisk.
If MOUNTPOINT is specified, then do a traditional disk install with MOUNTPOINT
as root.
If DISKDEV is specified, then use the specified disk(s) without asking. If
multiple disks are specified then set them up in a RAID array. If there are
mode than 2 disks, then use raid level 5 instead of raid level 1.
options:
-h Show this help
-e Encrypt disk
-m Use disk for MODE without asking, where MODE is either 'data' or 'sys'
-o Restore system from given apkovl file
-k Use kernelflavor instead of $KERNEL_FLAVOR
-L Use LVM to manage partitions
-q Exit quietly if no disks are found
-r Enable software raid1 with single disk
-s Use SWAPSIZE MB instead of autodetecting swap size (Use 0 to disable swap)
-v Be more verbose about what is happening
If BOOTLOADER is specified, the specified bootloader will be used.
If no bootloader is specified, the default bootloader is syslinux(extlinux)
except when EFI is detected or explicitly set by USE_EFI which will select grub.
Supported bootloaders are: grub, syslinux
If KERNELOPTS is specified, it will be appended to the kernel boot parameters.
Default is: quiet
If DISKLABEL is specified, the specified partition label will be used.
if no partition label is specified, the default label will be dos
except when EFI is detected or explicitly set by USE_EFI which will select gpt.
Supported partition labels are: dos, gpt
If BOOTFS, ROOTFS, VARFS are specified, then format a partition with specified
filesystem. If not specified, the default filesystem is ext4.
Supported filesystems for
boot: ext2, ext3, ext4, btrfs, xfs, vfat(EFI)
root: ext2, ext3, ext4, btrfs, xfs
var: ext2, ext3, ext4, btrfs, xfs
__EOF__
exit $1
}
kver=$(uname -r)
case $kver in
*-rc[0-9]*) KERNEL_FLAVOR=lts;;
*-[a-z]*) KERNEL_FLAVOR=${kver##*-};;
*) KERNEL_FLAVOR=lts;;
esac
USE_CRYPT=
DISK_MODE=
USE_LVM=
# Parse args
while getopts "hek:Lm:o:qrs:v" opt; do
case $opt in
e) USE_CRYPT="_crypt";;
h) usage 0;;
m) DISK_MODE="$OPTARG";;
k) KERNEL_FLAVOR="$OPTARG";;
L) USE_LVM="_lvm";;
o) APKOVL="$OPTARG";;
q) QUIET=1;;
r) USE_RAID=1;;
s) SWAP_SIZE="$OPTARG";;
v) VERBOSE=1;;
'?') usage "1" >&2;;
esac
done
shift $(( $OPTIND - 1))
if [ "$DISK_MODE" = "none" ] || [ "$1" = "none" ]; then
exit 0
fi
if is_rpi; then
: ${BOOTLOADER:=raspberrypi-bootloader}
BOOTFS=vfat
SWAP_SIZE=0
fi
if is_efi || [ -n "$USE_EFI" ]; then
USE_EFI=1
DISKLABEL=gpt
BOOTFS=vfat
: ${BOOTLOADER:=grub}
fi
# machine arch
ARCH=$(apk --print-arch)
case "$ARCH" in
x86*) : ${BOOTLOADER:=syslinux};;
ppc64le) : ${BOOTLOADER:=grub};;
s390x) : ${BOOTLOADER:=zipl};;
arm*|aarch64) : ${BOOTLOADER:=u-boot};;
esac
if [ -d "$1" ]; then
# install to given mounted root
[ "$BOOTLOADER" = "syslinux" ] && apk add --quiet syslinux
[ "$BOOTLOADER" = "u-boot" ] && apk add --quiet u-boot
install_mounted_root "${1%/}" \
&& echo "You might need fix the MBR to be able to boot" >&2
exit $?
fi
reset_var
swapoff -a
# stop all volume groups in use
vgchange --ignorelockingfailure -a n >/dev/null 2>&1
if [ -n "$USE_RAID" ]; then
stop_all_raid
fi
check_dasd
diskdevs=
# no disks so lets exit quietly.
while [ -z "$disks" ]; do
disks=$(find_disks)
[ -n "$disks" ] && break
# ask to unmount the boot mmc for rpi and similar
modloop_media=$(find_modloop_media)
if [ -z "$modloop_media" ] || ! ask_yesno "No disks available. Try boot media $modloop_media? (y/n)" n; then
[ -z "$QUIET" ] && echo "No disks found." >&2
exit 0
fi
DO_UMOUNT=1 modloop_media=$modloop_media copy-modloop
done
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
die "$i is not a suitable for partitioning"
fi
diskdevs="$diskdevs /dev/${j//!//}"
done
else
ask_disk "Which disk(s) would you like to use? (or '?' for help or 'none')" \
diskselect_help $disks
if [ "$resp" = "none" ]; then
exit 0
fi
for i in $resp; do
diskdevs="$diskdevs /dev/$i"
done
fi
if [ -n "$diskdevs" ] && [ -z "$DISK_MODE" ]; then
resp=
disk_is_or_disks_are="disk is"
it_them="it"
set -- $diskdevs
if [ $# -gt 1 ]; then
disk_is_or_disks_are="disks are"
it_them="them"
fi
while true; do
echo -n "The following $disk_is_or_disks_are selected"
[ -n "$USE_CRYPT" ] && [ -z "$USE_LVM" ] && echo -n " (with encryption)"
[ -z "$USE_CRYPT" ] && [ -n "$USE_LVM" ] && echo -n " (with LVM)"
[ -n "$USE_CRYPT" ] && [ -n "$USE_LVM" ] && echo -n " (with LVM on LUKS)"
echo ":"
show_disk_info $diskdevs
_crypt=$([ -z "$USE_CRYPT" ] && [ -z "$USE_LVM" ] && echo ", 'crypt'")
_lvm=${USE_LVM:-", 'lvm'"}
ask "How would you like to use $it_them? ('sys', 'data'$_crypt${_lvm#_lvm} or '?' for help)" "?"
case "$resp" in
'?') diskmode_help;;
sys|data) break;;
lvm) USE_LVM="_lvm" ;;
nolvm) USE_LVM="";;
crypt) USE_CRYPT="_crypt" ;;
nocrypt) USE_CRYPT="";;
lvmsys|lvmdata)
resp=${resp#lvm}
USE_LVM="_lvm"
break
;;
cryptsys)
resp=${resp#crypt}
USE_CRYPT="_crypt"
break
;;
esac
done
DISK_MODE="$resp"
fi
if [ -z "$SWAP_SIZE" ]; then
SWAP_SIZE=$(find_swap_size $diskdevs)
fi
if [ -n "$USE_EFI" ] && [ -z "$BOOT_SIZE" ]; then
blocksize=$(cat $(echo $diskdevs | sed -E -e 's:/dev/([^ ]+):/sys/block/\1/queue/logical_block_size:g') | sort -n | tail -n 1)
# calculate minimal FAT32 size
# for block size 512 minimal size is 32MB
# for block size 4096, minimal size is 260M
BOOT_SIZE=$(( ${blocksize:-0} * 64 / 1000 + 2 ))
fi
set -- $diskdevs
if is_dasd $1 eckd; then
DISKLABEL=eckd
fi
if [ $# -gt 1 ]; then
USE_RAID=1
fi
$MOCK dmesg -n1
if [ -n "$USE_LVM" ] && ! grep -w -q device-mapper /proc/misc; then
modprobe dm-mod
fi
# native disk install
case "$DISK_MODE" in
sys) native_disk_install$USE_LVM $diskdevs;;
data) data_only_disk_install$USE_LVM $diskdevs;;
none) exit 0;;
*) die "Not a valid install mode: $DISK_MODE" ;;
esac
RC=$?
echo "$DISK_MODE" > /tmp/alpine-install-diskmode.out
exit $RC
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment