1462 lines
37 KiB
Bash
1462 lines
37 KiB
Bash
#!/bin/sh
|
|
|
|
PREFIX=/usr
|
|
: ${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:-rw quiet}
|
|
SYSROOT=${SYSROOT:-/mnt}
|
|
SHAANFS=/media/cdrom/boot/shaanfs.squashfs
|
|
|
|
repos="$(sed -e 's/\#.*//' "/etc/apk/repositories" 2>/dev/null)"
|
|
repoflags=
|
|
for i in $repos; do
|
|
repoflags="$repoflags --repository $i"
|
|
done
|
|
|
|
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
|
|
}
|
|
|
|
_blkid() {
|
|
blkid | grep "^$1:"
|
|
}
|
|
|
|
uuid_or_device() {
|
|
local i=
|
|
for i in $NO_DISK_UUID; do
|
|
if [ "$i" = "$1" ]; then
|
|
echo "$1" && return 0
|
|
fi
|
|
done
|
|
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
|
|
}
|
|
|
|
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}" "${ROOT}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
|
|
printf "%s\t%s\t%s\t%s %s %s\n" \
|
|
"$(uuid_or_device $fs_spec)" "$fs_file" "$fs_vfstype" "$fs_mntops" $fs_freq $fs_passno
|
|
done
|
|
}
|
|
|
|
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_lvm() {
|
|
lvs "$1" >/dev/null 2>&1
|
|
}
|
|
|
|
is_efi() {
|
|
[ -d "${ROOT}sys/firmware/efi" ] && return 0
|
|
return 1
|
|
}
|
|
|
|
is_rpi() {
|
|
grep -q "Raspberry Pi" /proc/device-tree/model 2>/dev/null
|
|
}
|
|
|
|
partition_id() {
|
|
local id
|
|
if [ "$DISKLABEL" = "gpt" ]; then
|
|
case "$1" in
|
|
biosboot) id=21686148-6449-6E6F-744E-656564454649 ;;
|
|
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() {
|
|
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)
|
|
if [ -n "$USE_EFI" ]; then
|
|
search=$(partition_id esp)
|
|
elif [ "$DISKLABEL" = "gpt" ]; then
|
|
search="LegacyBIOSBootable"
|
|
else
|
|
search=bootable
|
|
fi
|
|
sfdisk -d "${ROOT}${dev#/}" | awk '/'$search'/ {print $1}'
|
|
;;
|
|
*)
|
|
search=$(partition_id "$type")
|
|
sfdisk -d "${ROOT}${dev#/}" | awk '/type='$search'/ {print $1}'
|
|
;;
|
|
esac
|
|
}
|
|
|
|
find_mount_fs() {
|
|
local mount_point="$1"
|
|
awk "\$2 == \"$mount_point\" {print \$3}" "${ROOT}proc/mounts" | tail -n 1
|
|
}
|
|
|
|
find_mount_dev() {
|
|
local mnt="$1"
|
|
awk "\$2 == \"$mnt\" { print \$1 }" "${ROOT}proc/mounts" | tail -n 1
|
|
}
|
|
|
|
supported_boot_fs() {
|
|
local supported="ext2 ext3 ext4 btrfs xfs vfat"
|
|
if [ "$BOOTLOADER" = "grub" ]; then
|
|
local supported="$supported zfs"
|
|
fi
|
|
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 sys; do
|
|
mkdir -p "$mnt"/$i
|
|
$MOCK mount --bind /$i "$mnt"/$i
|
|
done
|
|
}
|
|
|
|
cleanup_chroot_mounts() {
|
|
local mnt="$1" i=
|
|
for i in proc dev sys; 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
|
|
}
|
|
|
|
find_efi_directory() {
|
|
local mnt="$1" dir=
|
|
for dir in efi boot/efi boot; do
|
|
case "$(find_mount_fs "$mnt"/$dir)" in
|
|
vfat|fat|msdos)
|
|
echo "$mnt"/$dir
|
|
return
|
|
;;
|
|
esac
|
|
done
|
|
return 1
|
|
}
|
|
|
|
extract_squashfs() {
|
|
SQUASHFS_FILE="$1"
|
|
TARGET_DIR="$2"
|
|
SQUASH_MOUNT="/mnt/squash"
|
|
|
|
# Create mount and target directories
|
|
if ! mkdir -p "$SQUASH_MOUNT" || ! mkdir -p "$TARGET_DIR"; then
|
|
echo "Error: Could not create directories."
|
|
return 1
|
|
fi
|
|
|
|
# Mount the squashfs file
|
|
echo "Mounting squashfs file..."
|
|
if ! mount -t squashfs -o loop "$SQUASHFS_FILE" "$SQUASH_MOUNT"; then
|
|
echo "Error: Could not mount squashfs file."
|
|
rmdir "$SQUASH_MOUNT" 2>/dev/null
|
|
return 1
|
|
fi
|
|
|
|
# Copy files and show progress
|
|
echo -n "Copying files to target directory..."
|
|
# Run cp in the background and display progress dots
|
|
cp -a "$SQUASH_MOUNT/." "$TARGET_DIR"/ 2>/dev/null &
|
|
CP_PID=$!
|
|
while kill -0 $CP_PID 2>/dev/null; do
|
|
echo -n "."
|
|
sleep 0.5
|
|
done
|
|
echo " done."
|
|
|
|
# Check if copy was successful
|
|
if ! wait $CP_PID; then
|
|
echo "Error: Could not copy files."
|
|
umount "$SQUASH_MOUNT"
|
|
rmdir "$SQUASH_MOUNT" 2>/dev/null
|
|
return 1
|
|
fi
|
|
|
|
# Clean up mount point
|
|
echo "Unmounting mount point..."
|
|
if ! umount "$SQUASH_MOUNT"; then
|
|
echo "Error: Could not unmount mount point."
|
|
return 1
|
|
fi
|
|
rmdir "$SQUASH_MOUNT" 2>/dev/null
|
|
|
|
echo "Squashfs file successfully extracted to: $TARGET_DIR"
|
|
return 0
|
|
}
|
|
setup_grub() {
|
|
local mnt="$1" root="$2" modules="$3" kernel_opts="$4" bootdev="$5"
|
|
local disk=
|
|
shift 5
|
|
if [ -n "$USE_EFI" ]; then
|
|
local target fwa
|
|
local efi_directory=$(find_efi_directory "$mnt")
|
|
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 ;;
|
|
loongarch64) target=loongarch64-efi ; fwa=loongarch64 ;;
|
|
esac
|
|
grub-install --target=$target --efi-directory="$efi_directory" \
|
|
--bootloader-id=alpine --boot-directory="$mnt"/boot --no-nvram
|
|
install -D "$efi_directory"/EFI/alpine/grub$fwa.efi \
|
|
"$efi_directory"/EFI/boot/boot$fwa.efi
|
|
elif [ "$ARCH" = "ppc64le" ]; then
|
|
for disk in "$@"; do
|
|
prep=$(find_partitions "$disk" "prep")
|
|
grub-install --boot-directory="$mnt"/boot $prep
|
|
done
|
|
else
|
|
case "$ARCH" in
|
|
x86|x86_64)
|
|
for disk in "$@"; do
|
|
grub-install --boot-directory="$mnt"/boot \
|
|
--target=i386-pc "$disk"
|
|
done
|
|
;;
|
|
*) die "Cannot install GRUB in BIOS mode for $ARCH" ;;
|
|
esac
|
|
fi
|
|
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
|
|
if [ "$(openrc --sys)" = "XEN0" ]; then
|
|
echo "GRUB_DEFAULT=1" >> "$mnt"/etc/default/grub
|
|
fi
|
|
case "$initfs_features" in
|
|
*zfs*) echo "GRUB_FS=zfs" >> "$mnt"/etc/default/grub;;
|
|
esac
|
|
}
|
|
|
|
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
|
|
if [ -e "${ROOT}sys/block/${bootdev#/dev/}/md" ]; then
|
|
extlinux_raidopt="--raid"
|
|
fi
|
|
extlinux $extlinux_raidopt --install "$mnt"/boot
|
|
}
|
|
|
|
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 Chronalinux
|
|
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
|
|
update-u-boot
|
|
}
|
|
|
|
setup_raspberrypi_bootloader() {
|
|
local mnt="$1" root="$2" modules="$3" kernel_opts="$4"
|
|
mkdir -p "$mnt"/boot
|
|
echo "root=$root modules=$modules $kernel_opts" > "$mnt"/boot/cmdline.txt
|
|
}
|
|
|
|
select_firmware_pkgs() {
|
|
local firmware_pkgs="$( (cd "${ROOT}sys/module/" 2>/dev/null && echo *) \
|
|
| xargs modinfo -F firmware 2>/dev/null \
|
|
| awk -F/ '{print $1 == $0 ? "linux-firmware-other" : "linux-firmware-"$1}' \
|
|
| sort -u)"
|
|
# filter out non-existing packages like linux-firmware-b43
|
|
# https://gitlab.alpinelinux.org/alpine/alpine-conf/-/issues/10530
|
|
apk search --quiet --exact ${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="$(realpath "$1")"
|
|
local squashfs_file="$2"
|
|
shift 2
|
|
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"
|
|
[ "$ARCH" = "aarch64" ] && initfs_features="$initfs_features phy"
|
|
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 [ "$root_fs" = "zfs" ]; then
|
|
initfs_features="$initfs_features keymap"
|
|
fi
|
|
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 [ "$BOOTLOADER" != none ] && ! supported_boot_fs "$boot_fs"; then
|
|
[ -z "$FORCE_BOOTFS" ] && return 1
|
|
echo "Continuing at your own risk."
|
|
fi
|
|
extract_squashfs "$squashfs_file" "$mnt"
|
|
if [ -f "$mnt"/etc/fstab ]; then
|
|
mv "$mnt"/etc/fstab "$mnt"/etc/fstab.old
|
|
fi
|
|
mkdir -p "$mnt"/etc
|
|
enumerate_fstab "$mnt" >> "$mnt"/etc/fstab
|
|
if [ -n "$SWAP_DEVICES" ]; then
|
|
local swap_dev
|
|
for swap_dev in $SWAP_DEVICES; do
|
|
printf "%s\tnone\tswap\tdefaults\t0 0\n" \
|
|
"$(uuid_or_device $swap_dev)" \
|
|
>> "$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 "${ROOT}sys/block"/dm-*/slaves/*; then
|
|
initfs_features="$initfs_features nvme"
|
|
fi
|
|
fi
|
|
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
|
|
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
|
|
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"
|
|
if [ -e /sys/module/vmd ]; then
|
|
modules="$modules,vmd"
|
|
fi
|
|
;;
|
|
esac
|
|
init_chroot_mounts "$mnt"
|
|
rc_add() {
|
|
mkdir -p "$mnt"/etc/runlevels/"$2"
|
|
ln -sf /etc/init.d/"$1" "$mnt"/etc/runlevels/"$2"/"$1"
|
|
}
|
|
# Essential sysinit services
|
|
for svc in devfs dmesg mdev hwdrivers; do
|
|
rc_add "$svc" sysinit
|
|
done
|
|
# Core boot services
|
|
for svc in modules sysctl hostname bootmisc syslog localmount; do
|
|
[ -e ""$mnt"/etc/init.d/$svc" ] && rc_add "$svc" boot
|
|
done
|
|
# Shutdown services
|
|
for svc in mount-ro killprocs savecache; do
|
|
rc_add "$svc" shutdown
|
|
done
|
|
# Optional services
|
|
for svc in dbus networkmanager alsa; do
|
|
[ -e ""$mnt"/etc/init.d/$svc" ] && rc_add "$svc" boot
|
|
done
|
|
case "$BOOTLOADER" in
|
|
none) ;;
|
|
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
|
|
local apkflags="--quiet --allow-untrusted --no-interactive --progress"
|
|
pkgs="linux-lts $(select_bootloader_pkg) $(select_firmware_pkgs)"
|
|
if [ "$(openrc --sys)" = "XEN0" ]; then
|
|
pkgs="$pkgs xen-hypervisor"
|
|
fi
|
|
if is_rpi; then
|
|
pkgs="$pkgs dosfstools"
|
|
fi
|
|
apk add --root "$mnt" $apkflags $repoflags $pkgs
|
|
cleanup_chroot_mounts "$mnt"
|
|
}
|
|
|
|
unmount_partitions() {
|
|
local mnt="$1"
|
|
umount $(awk '{print $2}' "${ROOT}proc/mounts" | grep -E "^$mnt(/|\$)" | sort -r)
|
|
if [ -n "$USE_CRYPT" ]; then
|
|
if [ -n "$USE_LVM" ]; then
|
|
vgchange -a n
|
|
fi
|
|
cryptsetup close /dev/mapper/root
|
|
fi
|
|
}
|
|
|
|
find_swap_size() {
|
|
local memtotal_kb="$(awk '$1 == "MemTotal:" {print $2}' /proc/meminfo)"
|
|
local size="$(( $memtotal_kb * 2 / 1024 ))"
|
|
local disk= disksize=
|
|
for disk in $@; do
|
|
local sysfsdev="$(echo ${disk#/dev/} | sed 's:/:!:g')"
|
|
local sysfspath="${ROOT}sys/block/$sysfsdev/size"
|
|
maxsize=$(awk '{ printf "%i", $0 / 8192 }' $sysfspath )
|
|
if [ $size -gt $maxsize ]; then
|
|
size=$maxsize
|
|
fi
|
|
done
|
|
if [ $size -gt 4096 ]; then
|
|
size=4096
|
|
elif [ $size -lt 64 ]; then
|
|
size=0
|
|
fi
|
|
echo $size
|
|
}
|
|
|
|
find_efi_size() {
|
|
local blocksize=$(cat $(echo "$@" | sed -E "s:/?dev/([^ ]+):${ROOT}sys/block/\1/queue/logical_block_size:g") \
|
|
| sort -n | tail -n 1 || echo 512)
|
|
local disksize_blk=$(cat $(echo "$@" | sed -E "s:/?dev/([^ ]+):${ROOT}sys/block/\1/size:g") \
|
|
| sort -n | tail -n 1 || echo 0)
|
|
local disksize_mb=$(( blocksize * disksize_blk / 1024 / 1024 ))
|
|
local min_size=$(( blocksize * 64 / 1000 + 2 ))
|
|
local size=160
|
|
if [ $disksize_mb -gt 8192 ]; then
|
|
size=512
|
|
elif [ $disksize_mb -gt 2048 ]; then
|
|
size=264
|
|
fi
|
|
echo $(( size > min_size ? size : min_size ))
|
|
}
|
|
|
|
has_mounted_part() {
|
|
local p
|
|
local sysfsdev="$(echo ${1#/dev/} | sed 's:/:!:g')"
|
|
for p in $(awk '$1 ~ /^\/dev\// {gsub("/dev/", "", $1); gsub("/", "!", $1); print $1}' \
|
|
"${ROOT}proc/mounts" 2>/dev/null); do
|
|
[ "$p" = "$sysfsdev" ] && return 0
|
|
[ -e "${ROOT}sys/block/$sysfsdev/$p" ] && return 0
|
|
done
|
|
return 1
|
|
}
|
|
|
|
has_holders() {
|
|
local i
|
|
for i in $1/holders/* $1/*/holders/*; do
|
|
[ -e "$i" ] && return 0
|
|
done
|
|
return 1
|
|
}
|
|
|
|
is_available_disk() {
|
|
local dev="$1"
|
|
has_mounted_part $dev && return 1
|
|
if has_holders "${ROOT}sys/block/$dev"; then
|
|
[ -n "$USE_RAID" ] && echo "Warning: $dev is part of a running raid" >&2
|
|
return 1
|
|
fi
|
|
return 0
|
|
}
|
|
|
|
find_disks() {
|
|
local p=
|
|
for p in "${ROOT}sys/block"/*/device; do
|
|
local dev="${p%/device}"
|
|
dev=${dev#*/sys/block/}
|
|
if is_available_disk "$dev"; then
|
|
printf %s " $dev"
|
|
fi
|
|
done
|
|
}
|
|
|
|
stop_all_raid() {
|
|
local rd
|
|
for rd in /dev/md*; do
|
|
[ -b $rd ] && mdadm --stop $rd
|
|
done
|
|
}
|
|
|
|
select_bootloader_pkg() {
|
|
if [ "$BOOTLOADER" = none ]; then
|
|
return
|
|
fi
|
|
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"
|
|
}
|
|
|
|
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
|
|
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 --allow-untrusted $repoflags sfdisk squashfs-tools $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 "${ROOT}sys/block/$d/device/vendor" 2>/dev/null)
|
|
model=$(cat "${ROOT}sys/block/$d/device/model" 2>/dev/null)
|
|
busid=$(readlink -f "${ROOT}sys/block/$d/device" 2>/dev/null)
|
|
size=$(awk '{gb = ($1 * 512)/1000000000; printf "%.1f GB\n", gb}' "${ROOT}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
|
|
printf "\n"
|
|
echo "WARNING: The following disk(s) will be erased:"
|
|
show_disk_info $@
|
|
printf "\n"
|
|
ask_yesno "WARNING: Erase the above disk(s) and continue? (y/n)" n
|
|
}
|
|
|
|
setup_partitions() {
|
|
local diskdev="${ROOT}${1#/}"
|
|
shift
|
|
supported_part_label "$DISKLABEL" || return 1
|
|
echo "label: $DISKLABEL" | sfdisk --quiet "$diskdev"
|
|
if [ "$BOOTLOADER" = "syslinux" ] && [ -f "$MBR" ]; then
|
|
cat "$MBR" > "$diskdev"
|
|
fi
|
|
(
|
|
for line in "$@"; do
|
|
case "$line" in
|
|
0M*) ;;
|
|
*=*) echo "$line";;
|
|
*) echo ",$line" ;;
|
|
esac
|
|
done
|
|
) | sfdisk --quiet --wipe-partitions always --label "$DISKLABEL" "$diskdev" || return 1
|
|
}
|
|
|
|
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
|
|
for disk in $disks; do
|
|
echo ',,,*' | sfdisk --quiet $disk -N1
|
|
echo ',,,-' | sfdisk --quiet $disk -N2
|
|
done
|
|
$MOCK mdev -s
|
|
fi
|
|
echo "Creating file systems..."
|
|
if [ -n "$USE_RAID" ]; then
|
|
local missing=
|
|
local num=$#
|
|
if [ $# -eq 1 ]; then
|
|
missing="missing"
|
|
num=2
|
|
fi
|
|
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";;
|
|
btrfs) mkfs_args="";;
|
|
ext4) mkfs_args="$mkfs_args -O ^64bit";;
|
|
esac
|
|
$MOCK mkfs.$BOOTFS $MKFS_OPTS_BOOT $mkfs_args $bootdev
|
|
BOOT_DEV="$bootdev"
|
|
}
|
|
|
|
find_nth_non_boot_parts() {
|
|
local idx="$1" id="$2" disk= type=bootable
|
|
shift 2
|
|
local disks="$@"
|
|
local search="bootable"
|
|
if [ -n "$USE_EFI" ]; then
|
|
search="$(partition_id esp)"
|
|
elif [ "$DISKLABEL" = "gpt" ]; then
|
|
search="LegacyBIOSBootable"
|
|
fi
|
|
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 "${ROOT}${disk#/}" | grep -v "$search" \
|
|
| 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
|
|
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
|
|
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_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
|
|
printf "target=var\nsource='%s'\n" "$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
|
|
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
|
|
}
|
|
|
|
setup_swap_dev() {
|
|
local swap_dev=
|
|
sed -i -e '/swap/d' "${ROOT}etc/fstab"
|
|
SWAP_DEVICES=
|
|
for swap_dev in "$@"; do
|
|
$MOCK mkswap $swap_dev >/dev/null
|
|
printf "%s\tnone\t\tswap\tdefaults 0 0\n" \
|
|
"$(uuid_or_device $swap_dev)" >> "${ROOT}etc/fstab"
|
|
SWAP_DEVICES="$SWAP_DEVICES $swap_dev"
|
|
done
|
|
swapon -a
|
|
rc-update --quiet add swap boot
|
|
}
|
|
|
|
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
|
|
}
|
|
|
|
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
|
|
}
|
|
|
|
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
|
|
printf "%s\t/var\t\t%s\tdefaults 1 2\n" \
|
|
"$(uuid_or_device $var_dev)" "$varfs" >> /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
|
|
$MOCK mdev -s
|
|
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
|
|
$MOCK mdev -s
|
|
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
|
|
printf "target=var\nsource='%s'\n" "$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_root() {
|
|
local root_dev="$1" boot_dev="$2" squashfs_file="$3"
|
|
shift 3
|
|
local disks="$@" mkfs_args="-q"
|
|
local sysroot="${ROOT}${SYSROOT#/}"
|
|
[ "$ROOTFS" = "btrfs" ] && mkfs_args=""
|
|
$MOCK mkfs.$ROOTFS $MKFS_OPTS_ROOT $mkfs_args "$root_dev"
|
|
mkdir -p "$sysroot"
|
|
mount -t "$ROOTFS" "$root_dev" "$sysroot" || return 1
|
|
if [ -n "$boot_dev" ]; then
|
|
if [ -n "$USE_EFI" ] && [ -z "$USE_CRYPT" ]; then
|
|
mkdir -p "$sysroot"/boot/efi
|
|
mount -t "$BOOTFS" "$boot_dev" "$sysroot"/boot/efi || return 1
|
|
else
|
|
mkdir -p "$sysroot"/boot
|
|
mount -t "$BOOTFS" "$boot_dev" "$sysroot"/boot || return 1
|
|
fi
|
|
fi
|
|
setup_mdadm_conf
|
|
install_mounted_root "$sysroot" "$squashfs_file" "$disks" || return 1
|
|
$MOCK 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:-300}"
|
|
local lvm_size="$LVM_SIZE"
|
|
local root_dev=/dev/$vgname/lv_root
|
|
local biosboot=
|
|
local squashfs_file="$SHAANFS"
|
|
init_progs $(select_bootloader_pkg) || return 1
|
|
confirm_erase $@ || return 1
|
|
if [ "$BOOTFS" = "vfat" ] && [ "$DISKLABEL" = "dos" ]; 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)
|
|
elif [ "$DISKLABEL" = "gpt" ]; then
|
|
biosboot="2M,$(partition_id biosboot)"
|
|
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 \
|
|
$biosboot \
|
|
"${boot_size}M,$boot_part_type,*" \
|
|
"${lvm_size}${lvm_size:+M},$lvm_part_type" || return 1
|
|
if [ "$DISKLABEL" = "gpt" ] && [ -z "$USE_EFI" ]; then
|
|
sfdisk --part-attrs "${ROOT}${diskdev#/}" 2 LegacyBIOSBootable
|
|
fi
|
|
fi
|
|
done
|
|
$MOCK mdev -s
|
|
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" "$squashfs_file" "$@"
|
|
}
|
|
|
|
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
|
|
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:-300}"
|
|
local swap_size="${SWAP_SIZE}"
|
|
local root_size="${ROOT_SIZE}"
|
|
local root_dev= boot_dev= swap_dev= biosboot=
|
|
local squashfs_file="$SHAANFS"
|
|
init_progs $(select_bootloader_pkg) || return 1
|
|
confirm_erase $@ || return 1
|
|
if [ "$BOOTFS" = "vfat" ] && [ "$DISKLABEL" = "dos" ]; 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)
|
|
elif [ "$DISKLABEL" = "gpt" ]; then
|
|
biosboot="2M,$(partition_id biosboot)"
|
|
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 \
|
|
$biosboot \
|
|
"${boot_size}M,$boot_part_type,*" \
|
|
"${swap_size}M,$swap_part_type" \
|
|
"${root_size}${root_size:+M},$root_part_type" \
|
|
|| return 1
|
|
if [ "$DISKLABEL" = "gpt" ] && [ -z "$USE_EFI" ]; then
|
|
sfdisk --part-attrs "${ROOT}${diskdev#/}" 2 LegacyBIOSBootable
|
|
fi
|
|
fi
|
|
done
|
|
$MOCK mdev -s
|
|
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
|
|
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 "$squashfs_file" $@
|
|
}
|
|
|
|
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_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 "$@"
|
|
printf "\n"
|
|
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]
|
|
[-w FILE] [MOUNTPOINT | DISKDEV...]
|
|
|
|
Install Chronalinux on harddisk using squashfs.
|
|
|
|
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
|
|
more 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 (not used with squashfs)
|
|
-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
|
|
-w Write selected install mode to FILE
|
|
|
|
__EOF__
|
|
exit $1
|
|
}
|
|
|
|
write_disk_mode() {
|
|
if [ -n "$WRITE_DISK_MODE_FILE" ]; then
|
|
echo "$DISK_MODE" > "$WRITE_DISK_MODE_FILE"
|
|
fi
|
|
}
|
|
|
|
kver=$(uname -r)
|
|
case $kver in
|
|
*-rc[0-9]*) KERNEL_FLAVOR=lts;;
|
|
*-[a-z]*) KERNEL_FLAVOR=${kver##*-};;
|
|
*) KERNEL_FLAVOR=lts;;
|
|
esac
|
|
|
|
if [ -n "$SETUP_DISK_TESTFUNC" ]; then
|
|
$SETUP_DISK_TESTFUNC "$@"
|
|
exit
|
|
fi
|
|
|
|
USE_CRYPT=
|
|
DISK_MODE=
|
|
USE_LVM=
|
|
while getopts "hek:Lm:o:qrs:vw:" 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;;
|
|
w) WRITE_DISK_MODE_FILE="$OPTARG";;
|
|
'?') 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
|
|
fi
|
|
|
|
if [ "$DISKLABEL" = "gpt" ]; then
|
|
: ${BOOTLOADER:=grub}
|
|
fi
|
|
|
|
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
|
|
apk add --quiet --allow-untrusted $repoflags $(select_bootloader_pkg)
|
|
install_mounted_root "${1%/}" "$SHAANFS" || exit
|
|
if [ -z "$USE_EFI" ] && [ "$ARCH" = "x86_64" -o "$ARCH" = x86 ]; then
|
|
echo "You might need fix the MBR to be able to boot" >&2
|
|
fi
|
|
write_disk_mode
|
|
exit 0
|
|
fi
|
|
|
|
reset_var
|
|
$MOCK swapoff -a
|
|
$MOCK vgchange --ignorelockingfailure -a n >/dev/null 2>&1
|
|
|
|
if [ -n "$USE_RAID" ]; then
|
|
stop_all_raid
|
|
fi
|
|
|
|
check_dasd
|
|
|
|
diskdevs=
|
|
while [ -z "$disks" ]; do
|
|
disks=$(find_disks)
|
|
[ -n "$disks" ] && break
|
|
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
|
|
for i in "$@"; do
|
|
j=$(readlink -f "$i" | sed 's:^/dev/::; s:/:!:g')
|
|
if ! [ -e "${ROOT}sys/block/$j/device" ]; then
|
|
die "$i is not a block device suitable for partitioning"
|
|
fi
|
|
diskdevs="$diskdevs $i"
|
|
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 [ -z "$SWAP_SIZE" ]; then
|
|
SWAP_SIZE=$(find_swap_size $diskdevs)
|
|
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
|
|
printf "\nThe following %s selected" "$disk_is_or_disks_are"
|
|
[ -n "$USE_CRYPT" ] && [ -z "$USE_LVM" ] && printf %s " (with encryption)"
|
|
[ -z "$USE_CRYPT" ] && [ -n "$USE_LVM" ] && printf %s " (with LVM)"
|
|
[ -n "$USE_CRYPT" ] && [ -n "$USE_LVM" ] && printf %s " (with LVM on LUKS)"
|
|
printf ":\n"
|
|
show_disk_info $diskdevs
|
|
_crypt=$([ -z "$USE_CRYPT" ] && [ -z "$USE_LVM" ] && echo ", 'crypt'")
|
|
_lvm=${USE_LVM:-", 'lvm'"}
|
|
printf "\n"
|
|
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"
|
|
if [ "$SWAP_SIZE" -gt 0 ]; then
|
|
USE_LVM="_lvm"
|
|
fi
|
|
;;
|
|
nocrypt) USE_CRYPT="";;
|
|
lvmsys|lvmdata)
|
|
resp=${resp#lvm}
|
|
USE_LVM="_lvm"
|
|
break
|
|
;;
|
|
cryptsys)
|
|
resp=${resp#crypt}
|
|
USE_CRYPT="_crypt"
|
|
if [ "$SWAP_SIZE" -gt 0 ]; then
|
|
USE_LVM="_lvm"
|
|
fi
|
|
break
|
|
;;
|
|
esac
|
|
done
|
|
DISK_MODE="$resp"
|
|
fi
|
|
|
|
if [ -n "$USE_EFI" ] && [ -z "$USE_CRYPT" ] && [ -z "$BOOT_SIZE" ]; then
|
|
BOOT_SIZE=$(find_efi_size $diskdevs)
|
|
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
|
|
|
|
write_disk_mode
|
|
|
|
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
|