setup-disk.in 17.7 KB
Newer Older
Natanael Copa's avatar
Natanael Copa committed
1 2 3 4 5
#!/bin/sh

PREFIX=
. "$PREFIX/lib/libalpine.sh"

6
MBR=${MBR:-"/usr/share/syslinux/mbr.bin"}
Natanael Copa's avatar
Natanael Copa committed
7 8 9 10 11 12 13 14 15 16 17

in_list() {
	local i="$1"
	shift
	while [ $# -gt 0 ]; do
		[ "$i" = "$1" ] && return 0
		shift
	done
	return 1
}

18 19 20 21 22 23 24 25
# 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=
26 27 28
	case "$1" in
		/dev/md*) echo "$1" && return 0;;
	esac
29 30 31 32 33 34 35 36 37 38 39 40 41
	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
42
enumerate_fstab() {
43
	local mnt="$1"
44
	local fs_spec= fs_file= fs_vfstype= fs_mntops= fs_freq= fs_passno=
45
	[ -z "$mnt" ] && return
46 47
	local escaped_mnt=$(echo $mnt | sed 's:/:\\/:g')
	awk "\$2 ~ /^$escaped_mnt/ {print \$0}" /proc/mounts | \
48 49 50 51
		sed "s:$mnt:/:g; s: :\t:g" | sed 's:/\+:/:g' | \
		while read fs_spec fs_file fs_vfstype fs_mntops fs_freq fs_passno; do
			echo -e "$(uuid_or_device $fs_spec)\t${fs_file}\t${fs_vfstype}\t${fs_mntops} ${fs_freq} ${fs_passno}"
		done
52 53
}

54 55 56 57 58
is_vmware() {
	grep -q VMware /proc/scsi/scsi 2>/dev/null \
		|| grep -q VMware /proc/ide/hd*/model 2>/dev/null
}

59 60 61 62
is_xen() {
	[ -d /proc/xen ]
}

63 64 65 66 67
# return true (0) if given device is lvm
is_lvm() {
	lvs "$1" >/dev/null 2>&1
}

68 69
# Find the disk device from given partition
disk_from_part() {
70 71
	# we need convert cciss/c0d0* cciss!c0d0*...
	local i= part=$(echo ${1#/dev/} | sed 's:/:!:g')
72 73
	for i in /sys/block/*/$part; do
		i=${i%/*}
74
		# ...and back from cciss!c0d0 to cciss/c0d0
75 76 77 78
		if [ -b "/dev/${i##*/}" ]; then
			echo "/dev/${i##*/}" | sed 's:!:/:g'
			return 0
		fi
79 80 81 82
	done
	return 1
}

83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117
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
			echo -n "Continue anyway? [Y/n]: "
			read i
			case "$i" in
				n*|N*) return 1;;
			esac
		fi
		return 0 
	fi

	apk add -q 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
}

118 119 120 121 122 123 124 125
# 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() {
126
	local mnt="$1"
127 128 129 130
	awk "\$2 == \"$mnt\" { print \$1 }" /proc/mounts | tail -n 1
}

supported_boot_fs() {
131
	local supported="ext2 ext3 ext4 btrfs"
132 133 134 135 136 137 138 139 140 141
	local fs=
	for fs in $supported; do
		[ "$fs" = "$1" ] && return 0
	done
	echo "$1 is not supported. Only supported are: $supported" >&2
	return 1
}

install_mounted_root() {
	local mnt="$1" mnt_boot="$1" boot_fs= root_fs=
142
	local initfs_features="ata base ide scsi usb virtio"
143

144
	rootdev=$(find_mount_dev "$mnt")
145 146 147 148
	if [ -z "$rootdev" ]; then
		echo "$mnt does not seem to be a mount point" >&2
		return 1
	fi
149
	root_fs=$(find_mount_fs "$mnt")
150 151 152 153 154 155
	initfs_features="$initfs_features $root_fs"

	if is_lvm "$rootdev"; then
		initfs_features="$initfs_features lvm"
	fi

156

157 158 159 160 161 162 163 164 165 166
	bootdev=$(find_mount_dev "$mnt"/boot)
	if [ -z "$bootdev" ]; then
		bootdev=$rootdev
	else
		mnt_boot="$mnt"/boot
		bootdev=$(find_mount_dev "$mnt_boot")
	fi
	boot_fs=$(find_mount_fs "$mnt_boot")
	supported_boot_fs "$boot_fs" || return 1

167
	mbrdisk=$(disk_from_part $bootdev)
168 169
	if [ -e "/sys/block/${rootdev#/dev/}/md" ]; then
		local md=${rootdev#/dev/}
170
		initfs_features="$initfs_features raid"
171 172 173 174
		raidmod=$(cat /sys/block/$md/md/level)
		raidmod=",$raidmod"
		raidopt="-r"
		# get a list of slaves
175
		mbrdisk=
176 177 178
		for i in /sys/block/$md/slaves/*; do
			j=${i##*/}
			i=${j%[0-9]*}
179 180 181
			if [ -b "/dev/$i" ]; then
				mbrdisk="$mbrdisk /dev/${i}"
			fi
182
		done
183
	fi
184 185 186 187 188
	if [ -n "$VERBOSE" ]; then
		echo "Root device:     $rootdev"
		echo "Root filesystem: $root_fs"
		echo "Boot device:     $bootdev"
		echo "Boot filesystem: $boot_fs"
189
		echo "MBR disk(s):    $mbrdisk"
190
	fi
191

192
	if [ -z "$APKOVL" ]; then
193 194
		ovlfiles=/tmp/ovlfiles
		lbu package - | tar -C "$mnt" -zxv > "$ovlfiles"
195 196
	else
		echo "Restoring backup from $APKOVL to $rootdev..."
197
		unpack_apkovl "$APKOVL" "$mnt" || return 1
198
	fi
199

200 201 202 203
	# generate mkinitfs.conf
	mkdir -p "$mnt"/etc/mkinitfs
	echo "features=\"$initfs_features\"" > "$mnt"/etc/mkinitfs/mkinitfs.conf

204 205 206 207 208 209 210 211 212 213 214
	# generate the fstab
	if [ -f "$mnt"/etc/fstab ]; then
		mv "$mnt"/etc/fstab "$mnt"/etc/fstab.old
	fi
	enumerate_fstab "$mnt" >> "$mnt"/etc/fstab
	cat >>"$mnt"/etc/fstab <<EOF
/dev/cdrom	/media/cdrom	iso9660	noauto,ro 0 0
/dev/fd0	/media/floppy	vfat	noauto	0 0
/dev/usbdisk	/media/usb	vfat	noauto	0 0
EOF

215 216
	# remove the installed db in case its there so we force re-install
	rm -f "$mnt"/var/lib/apk/installed
217
	echon "Installing system on $rootdev: "
218 219 220 221
	# 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/

222

223 224
	local apkflags="--quiet --progress --update-cache --clean-protected"
	local pkgs=$(cat "$mnt"/var/lib/apk/world)
225
	pkgs="$pkgs acct linux-$KERNEL_FLAVOR alpine-base"
226 227 228 229 230
	local repos=$(sed -e 's/\#.*//' /etc/apk/repositories)
	local repoflags=
	for i in $repos; do
		repoflags="$repoflags --repository $i"
	done
231 232
	
	apk add --root "$mnt" $apkflags --overlay-from-stdin \
233
		$repoflags $pkgs <$ovlfiles>/dev/null || return 1
234
	echo ""
235

236
	# make things bootable
237 238 239 240 241 242
	if is_vmware; then
		pax_nouderef="pax_nouderef "
	else
		pax_nouderef=
	fi

243 244 245 246 247 248 249
	if is_xen; then
		# create a menu.lst
		mkdir -p "$mnt"/boot/grub
		cat >"$mnt"/boot/grub/menu.lst <<EOF
default 0
title $KERNEL_FLAVOR
root (hd0,0)
250
kernel /boot/$KERNEL_FLAVOR root=$(uuid_or_device $rootdev) modules=${root_fs}${raidmod} quiet xen BOOT_IMAGE=/boot/$KERNEL_FLAVOR
251 252 253 254 255
initrd=/boot/initramfs-$KERNEL_FLAVOR
EOF
	else
		# create an extlinux.conf
		cat >"$mnt"/boot/extlinux.conf <<EOF
256 257
timeout 20
prompt 1
258 259 260
default $KERNEL_FLAVOR
label $KERNEL_FLAVOR
	kernel /boot/vmlinuz-$KERNEL_FLAVOR
261
	append initrd=/boot/initramfs-$KERNEL_FLAVOR root=$(uuid_or_device $rootdev) modules=sd-mod,usb-storage,${root_fs}${raidmod} ${pax_nouderef}quiet
262
EOF
263 264
	fi

265 266
	# install extlinux
	apk add -q syslinux
267
	is_xen || extlinux -i $raidopt "$mnt"/boot/
268 269 270 271
}

unmount_partitions() {
	local mnt="$1"
272 273 274

	# unmount the partitions
	umount $(awk '{print $2}' /proc/mounts | grep ^"$mnt" | sort -r)
275
}
276

277
fix_mbr_all_disks() {
278
	# fix mbr for all disk devices
279
	for i in $mbrdisk; do
280 281 282 283
		local errmsg
		echo "Writing MBR to $i"
		errmsg=$(dd if="$MBR" of=$i 2>&1) \
			|| echo "$errmsg"
284
	done
285 286
}

287 288
# figure out decent default swap size in mega bytes
find_swap_size() {
289 290 291
	if [ -n "$SWAP_SIZE" ]; then
		return
	fi
292 293 294 295 296 297 298
	local memtotal_kb=$(awk '$1 == "MemTotal:" {print $2}' /proc/meminfo)
	# use 2 * avaiable ram
	echo $(( $memtotal_kb * 2 / 1024 ))
}

has_mounted_part() {
	local p
Natanael Copa's avatar
Natanael Copa committed
299
	# parse /proc/mounts for mounted devices
300 301
	for p in $(awk '$1 ~ /^\/dev\// {gsub("/dev/", "", $1); print $1}' \
			/proc/mounts); do
302
		[ "$p" = "$1" ] && return 0
Natanael Copa's avatar
Natanael Copa committed
303
		[ -e /sys/block/$1/$p ] && return 0
304 305 306 307
	done
	return 1
}

Natanael Copa's avatar
Natanael Copa committed
308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327
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
328 329 330 331
	if has_holders /sys/block/$b; then
		[ -n "$USE_RAID" ] && echo "Warning: $dev is part of a running raid" >&2
		return 1
	fi
Natanael Copa's avatar
Natanael Copa committed
332 333 334 335 336 337 338

	# check so its not an md device
	[ -e /sys/block/$b/md ] && return 1

	return 0
}

339
find_disks() {
Natanael Copa's avatar
Natanael Copa committed
340
	local p=
341
	for p in $(awk '$1 ~ /[0-9]+/ {print $4}' /proc/partitions); do
Natanael Copa's avatar
Natanael Copa committed
342
		is_available_disk $p && echo -n " $p"
343 344 345
	done
}

346 347 348 349 350 351 352
stop_all_raid() {
	local rd
	for rd in /dev/md*; do
		[ -b $rd ] && mdadm --stop $rd
	done
}

353
native_disk_install() {
354
	local rootdisk_dev="$1"
Natanael Copa's avatar
Natanael Copa committed
355
	local i size
356
	local boot_size=100 boot_part_type="83" 
357
	local swap_size="$SWAP_SIZE" swap_part_type="82"
358 359
	local root_part_type="83"
	local raidpkg= partitions=
360 361
	local minimum_root_size=$(($boot_size * 2))
	local rootfs=ext4 bootfs=ext4
362 363 364 365 366 367 368 369

	if [ -n "$USE_RAID" ]; then
		boot_part_type="fd"
		swap_part_type="fd"
		root_part_type="fd"
		raidpkg="mdadm"
	fi

370 371
	dmesg -n1
	apk_add -q sfdisk e2fsprogs $raidpkg || return 1
372 373 374 375 376 377 378 379 380 381 382 383
	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 ""
384 385 386
	if [ -n "$APKOVL" ]; then
		echo "System from $APKOVL will be restored"
	fi
387 388 389 390 391 392
	echo -n "WARNING: All contents of $rootdisk_dev will be erased. Continue? [y/N]: "
	read i
	case "$i" in
		y*|Y*);;
		*) return 1;;
	esac
393 394
	
	echo "Initializing partitions..."
395
	[ -n "$USE_RAID" ] && stop_all_raid
396

397 398 399 400 401 402
	# new disks does not have an DOS signature in sector 0
	# this makes sfdisk complain. We can workaround this by letting
	# fdisk create that DOS signature, by just do a "w", a write.
	# http://bugs.alpinelinux.org/issues/show/145
	echo "w" | fdisk $rootdisk_dev >/dev/null

403 404 405 406 407 408
	# create new partitions
	(cat <<EOF
0,$boot_size,$boot_part_type,*
,$swap_size,$swap_part_type
,,$root_part_type
EOF
409
	) | sfdisk -q -L -uM $rootdisk_dev >>/tmp/sfdisk.out || return 1
410 411

	# create device nodes if not exist
Natanael Copa's avatar
Natanael Copa committed
412 413
	mdev -s

414 415 416 417
	if [ -n "$USE_RAID" ]; then
		local p= rd=
		for p in $(sfdisk -l $rootdisk_dev 2>/dev/null \
				| awk '/Linux raid/ {print $1}'); do
418
			local opt="--metadata=0.90"
419 420
			case "$p" in
				*1) rd=/dev/md0; boot_dev=/dev/md0;;
421 422
				*2) rd=/dev/md1; swap_dev=/dev/md1
				    opt= ;;
423 424 425
				*3) rd=/dev/md2; root_dev=/dev/md2;;
			esac
			mdadm --create $rd --level=1 --raid-devices=2 \
426
				$opt --quiet --run $p missing
427 428 429 430 431 432 433 434 435 436 437 438
		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
439
	mkfs.$bootfs -q $boot_dev >/dev/null \
440
		&& mkswap $swap_dev >/dev/null \
441
		&& mkfs.$rootfs -q >/dev/null $root_dev \
442 443 444
		|| return 1

	mkdir -p /mnt
445
	mount -t $rootfs $root_dev /mnt || return 1
446
	mkdir -p /mnt/boot
447
	mount -t $bootfs $boot_dev /mnt/boot || return 1
448 449 450 451
	if [ -n "$USE_RAID" ]; then
		mdadm --detail --scan > /etc/mdadm.conf
		rc-update --quiet add mdadm-raid boot
	fi
452 453

	# manually add swap to local fstab and swapon (in case the install needs swap)
454
	sed -i -e '/swap/d' /etc/fstab
455
	echo -e "$(uuid_or_device $swap_dev)\tswap\t\tswap\tdefaults 0 0" >> /etc/fstab
456 457 458 459 460 461
	swapon -a

	install_mounted_root /mnt || return 1

	# manually add swap to mounted fstab and add the swap service to the boot runlevel
	echo -e "$(uuid_or_device $swap_dev)\tswap\t\tswap\tdefaults 0 0" >> /mnt/etc/fstab
462 463
	chroot /mnt rc-update --quiet add swap boot
	chroot /mnt rc-update --quiet add urandom boot
464 465 466 467 468 469 470 471

	unmount_partitions /mnt
	swapoff -a
	fix_mbr_all_disks

	echo ""
	echo "Installation is done. Please reboot."
	apk del -q syslinux
Natanael Copa's avatar
Natanael Copa committed
472 473
}

474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605
# install needed programs
init_progs() {
	local raidpkg=
	[ -n "$USE_RAID" ] && raidpkg="mdadm"
	apk_add -q sfdisk e2fsprogs lvm2 $raidpkg
}

# setup disk dev in $1 for LVM usage.
# usage: setup_partitions <diskdev> <bootsize>
# if <boot_size> is set, then will a partition for boot be created.
setup_partitions() {
	local diskdev="$1"
	local answer=
	local boot_size="$2" boot_part_type="83"
	local lvm_part_type="8e"
	local minimum_lvm_size=$(($boot_size * 2))

	if [ -n "$USE_RAID" ]; then
		boot_part_type="fd"
		lvm_part_type="fd"
	fi

	local lvm_size=$(( $(sfdisk -s $diskdev) / 1024 - $boot_size))
	if [ "$lvm_size" -lt "$minimum_lvm_size" ]; then
		echo "The $diskdev is too small. At least $(( $boot_size + $minimum_lvm_size)) is needed." >&2
		return 1
	fi

	echo -n "WARNING: All contents of $diskdev will be erased. Continue? [y/N]: "
	read answer
	case "$answer" in
		y*|Y*);;
		*) return 1;;
	esac
	
	echo "Initializing partitions..."
	[ -n "$USE_RAID" ] && stop_all_raid

	# new disks does not have an DOS signature in sector 0
	# this makes sfdisk complain. We can workaround this by letting
	# fdisk create that DOS signature, by just do a "w", a write.
	# http://bugs.alpinelinux.org/issues/show/145
	echo "w" | fdisk $diskdev >/dev/null

	# create new partitions
	(
		if [ $boot_size -gt 0 ]; then
			echo "0,$boot_size,$boot_part_type,*"
		fi
		echo ",,$lvm_part_type"
	) | sfdisk -q -L -uM $diskdev >>/tmp/sfdisk.out || return 1

	# create device nodes if not exist
	mdev -s
}

# find the bootable partition on given disk
find_boot_partition() {
	sfdisk -d $1 | awk '/bootable/ {print $1}'
}

# find the partition(s) for LVM
# this is not marked as bootable and is either type 8e of fd depending on
# if raid is used or not
find_lvm_partition() {
	local type=8e
	[ -n "$USE_RAID" ] && type=fd
	sfdisk -d $1 | grep -v bootable | awk "/Id=$type/ {print \$1}"
}

# set up boot device
setup_boot_dev() {
	local bootfs=ext4
	local diskdev="$1"
	local part=$(find_boot_partition $diskdev)
	local bootdev=$part
	[ -z "$bootdev" ] && return 1
	if [ -n "$USE_RAID" ]; then
		mdadm --create /dev/md0 --level=1 --raid-devices=2 \
			--metadata=0.90 --quiet --run $part missing || return 1
		bootdev=/dev/md0
	fi
	mkfs.$bootfs -q $bootdev
	BOOT_DEV="$boot_dev"
}

# setup device for lvm, create raid array if needed
setup_lvm_volume_group() {
	local diskdev="$1"
	local vgname="$2"
	local part=$(find_lvm_partition $diskdev)
	local lvmdev=$part

	if [ -n "$USE_RAID" ]; then
		if [ -n "$BOOT_DEV" ]; then
			lvmdev=/dev/md1
		else
			lvmdev=/dev/md0
		fi
		mdadm --create $lvmdev --level=1 --raid-devices=2 \
			--quiet --run $part missing || 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
}

# setup and enable swap on given volumegroup if needed
setup_swap() {
	local vgname="$1"
	local swap_dev=/dev/$vgname/lv_swap
	if [ -z "$SWAP_SIZE" ] || [ "$SWAP_SIZE" -eq 0 ]; then
		return
	fi
	lvcreate --quiet -n lv_swap -L ${SWAP_SIZE}MB $vgname
	mkswap $swap_dev >/dev/null
	sed -i -e '/swap/d' /etc/fstab
	echo -e "$swap_dev\tswap\t\tswap\tdefaults 0 0" >> /etc/fstab
	swapon -a
	rc-update --quiet add swap boot
}

# 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
}

606
data_only_disk_install() {
607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633
	local diskdev="$1"
	local varfs=ext4
	local vgname=vg0
	local var_dev=/dev/$vgname/lv_var

	init_progs || return 1

	setup_partitions $diskdev 0 || return 1
	setup_lvm_volume_group $diskdev $vgname || return 1

	setup_swap $vgname

	lvcreate --quiet -n ${var_dev##*/} -l 100%FREE $vgname
	mkfs.$varfs -q $var_dev >/dev/null || return 1
	sed -i -e '/[[:space:]]\/var[[:space:]]/d' /etc/fstab
	echo -e "${var_dev}\t/var\t\t${varfs}\tdefaults 1 2" >> /etc/fstab

	mv /var /.var
	mkdir /var
	mount /var
	mv /.var/* /var/
	rmdir /.var

	if [ -n "$USE_RAID" ]; then
		mdadm --detail --scan > /etc/mdadm.conf
		rc-update --quiet add mdadm-raid boot
	fi
634
	/etc/init.d/syslog --quiet restart
635 636
}

Natanael Copa's avatar
Natanael Copa committed
637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652
usage() {
	cat <<__EOF__
usage: setup-disk [-hr] [-k kernelflavor] [-o apkovl] [MOUNTPOINT]

Install alpine on harddisk.

options:
 -h  Show this help
 -o  Restore system from given apkovl file
 -k  Use kernelflavor instead of $KERNEL_FLAVOR
 -r  Enable software raid1 with single disk

__EOF__
	exit 1
}

653
diskselect_help() {
654 655
	cat <<__EOF__

656
TODO
657 658 659 660

__EOF__
}

661
diskmode_help() {
662 663
	cat <<__EOF__

664
TODO
665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692

__EOF__
}

# ask for a root or data disk
# returns answer in global variable $answer
ask_disk() {
	local prompt="$1"
	local help_func="$2"
	shift 2
	answer=

	while ! in_list "$answer" $@ "none" "abort"; do
		echo "Available disks are: $@"
		echon "$prompt [$1] "
		default_read answer $1
		case "$answer" in
			'abort') exit 0;;
			'none') return 0;;
			'?') $help_func;;
			*) if ! [ -b "/dev/$answer" ]; then
				echo "/dev/$answer is not a block device" >&2
				answer=
			   fi;;
		esac
	done
}

693 694 695
KERNEL_FLAVOR=grsec
case "$(uname -r)" in
	*-vs[0-9]*) KERNEL_FLAVOR=vserver;;
696
	*-pae) KERNEL_FLAVOR=pae;;
697 698
esac

699
SWAP_SIZE=$(find_swap_size)
700
# Parse args
701
while getopts "hk:o:qrs:v" opt; do
702
	case $opt in
703
		k) KERNEL_FLAVOR="$OPTARG";;
704
		o) APKOVL="$OPTARG";;
705 706
		q) QUIET=1;;
		r) USE_RAID=1;;
707
		s) SWAP_SIZE="$OPTARG";;
708
		v) VERBOSE=1;;
Natanael Copa's avatar
Natanael Copa committed
709
		*) usage;;
710 711
	esac
done
712
shift $(( $OPTIND - 1))
713

714 715
if [ -d "$1" ]; then
	# install to given mounted root
716
	install_mounted_root "${1%/}"
717 718 719
	exit $?
fi

720 721 722 723 724 725 726 727 728 729
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

730
disks=$(find_disks)
731
disk=none
Natanael Copa's avatar
Natanael Copa committed
732 733

# no disks so lets exit quietly.
734 735 736 737
if [ -z "$disks" ]; then
	[ -z "$QUIET" ] && echo "No disks found." >&2
	exit 0
fi
Natanael Copa's avatar
Natanael Copa committed
738

739 740 741 742 743
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
744
			echo "$i is not a suitable for partitioning"
745 746 747
			exit 1
		fi
	done
748
	disk=${1##/dev/}
749
else
750 751 752
	ask_disk "Which disk would you like to use? (or '?' for help or 'none')" \
		diskselect_help $disks
	disk=$answer
753
fi
Natanael Copa's avatar
Natanael Copa committed
754

755 756 757 758 759 760 761 762 763 764 765 766
diskmode=
if [ "$disk" != none ]; then
	answer=
	while true; do
		echon "How would you like to use $disk? ('root', 'data' or '?' for help) [?] "
		default_read answer '?'
		case "$answer" in
		'?') diskmode_help;;
		root|data) break;;
		esac
	done
	diskmode="$answer"
767
fi
Natanael Copa's avatar
Natanael Copa committed
768

769

770 771
dmesg -n1

772 773 774 775 776
# native disk install
case "$diskmode" in
root) native_disk_install /dev/$disk;;
data) data_only_disk_install /dev/$disk;;
esac
Natanael Copa's avatar
Natanael Copa committed
777