setup-disk.in 18.8 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
	# remove the installed db in case its there so we force re-install
216
	rm -f "$mnt"/var/lib/apk/installed "$mnt"/lib/apk/db/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
	local apkflags="--quiet --progress --update-cache --clean-protected"
224
	local pkgs=$(cat "$mnt"/etc/apk/world "$mnt"/var/lib/apk/world 2>/dev/null)
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
# install needed programs
init_progs() {
	local raidpkg=
	[ -n "$USE_RAID" ] && raidpkg="mdadm"
	apk_add -q sfdisk e2fsprogs lvm2 $raidpkg
}

481 482 483 484 485 486 487
show_disk_info() {
	local disk=
	for disk in $@; do
		# TODO: extend ifo with size, model etc...
		echo "  $disk"
	done
}
488

489 490 491 492 493 494
confirm_erase() {
	local answer=
	echo "WARNING: the following disks will be erased:"
	show_disk_info $@
	echo -n "WARNING: Erase the above disks and continue? [y/N]: "
	
495 496
	read answer
	case "$answer" in
497
		y*|Y*) return 0;;
498
	esac
499 500 501 502 503 504 505 506 507 508
	return 1	
}

# setup disk dev in $1 for LVM usage.
# usage: setup_partitions <diskdev> size1,type1 [size2,type2 ...] 
setup_partitions() {
	local diskdev="$1"
	shift

	echo "Initializing partitions on $diskdev..."
509 510 511 512 513 514 515

	# 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

516 517
	local start=0
	local line=
518 519
	# create new partitions
	(
520 521 522 523
		for line in "$@"; do
			echo "$start,$line"
			start=
		done
524 525 526 527 528 529 530 531 532 533 534 535
	) | 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
536
# this is not marked as bootable and is type 8e
537 538 539 540 541
find_lvm_partition() {
	local type=8e
	sfdisk -d $1 | grep -v bootable | awk "/Id=$type/ {print \$1}"
}

542
# set up boot device. We only use raid1 for boot devices if any raid
543 544
setup_boot_dev() {
	local bootfs=ext4
545 546 547 548
	local disk= bootdev=
	local part=$(for disk in $@; do find_boot_partition $disk; done)
	set -- $part
	bootdev=$1
549 550
	[ -z "$bootdev" ] && return 1
	if [ -n "$USE_RAID" ]; then
551 552 553 554 555 556 557 558
		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
559 560 561
		bootdev=/dev/md0
	fi
	mkfs.$bootfs -q $bootdev
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
	BOOT_DEV="$bootdev"
}

# $1 = index
# $2... = disk devices
find_nth_non_boot_raid_parts() {
	local idx=$1
	local disk=
	shift
	for disk in $@; do
		sfdisk -d $disk | grep -v bootable \
			| awk "/Id=fd/ { i++; if (i==$idx) print \$1 }"
	done
}

setup_non_boot_raid_dev() {
	local md_dev=$1
	local idx=${md_dev#/dev/md}
	shift
	local level=1
	local numdevs=$#
	local missing=
	local raid_parts=$(find_nth_non_boot_raid_parts $idx $@)
	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 /dev/md$idx --level=$level --raid-devices=$num \
		--quiet --run $@ $missing || return 1
595 596 597 598
}

# setup device for lvm, create raid array if needed
setup_lvm_volume_group() {
599 600 601
	local vgname="$1"
	shift
	local lvmdev=
602 603

	if [ -n "$USE_RAID" ]; then
604 605 606 607
		setup_non_boot_raid_dev /dev/md1 $@ || return 1
		lvmdev=/dev/md1
	else	
		lvmdev=$(find_lvm_partition $1)
608 609 610 611 612
	fi

	# be quiet on success
	local errmsg=$(dd if=/dev/zero of=$lvmdev bs=1k count=1 2>&1) \
		|| echo "$errmsg"
613 614 615 616 617 618 619 620 621 622 623 624 625 626
	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
	for swap_dev in "$@"; do
		mkswap $swap_dev >/dev/null
		echo -e "$swap_dev\tswap\t\tswap\tdefaults 0 0" >> /etc/fstab
	done
	swapon -a
	rc-update --quiet add swap boot
627 628 629
}

# setup and enable swap on given volumegroup if needed
630
setup_lvm_swap() {
631
	local vgname="$1"
632
	local swapname=lv_swap
633 634 635
	if [ -z "$SWAP_SIZE" ] || [ "$SWAP_SIZE" -eq 0 ]; then
		return
	fi
636 637
	lvcreate --quiet -n $swapname -L ${SWAP_SIZE}MB $vgname
	setup_swap_dev /dev/$vgname/$swapname
638 639 640 641 642 643 644 645 646 647
}

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

648
data_only_disk_install() {
649
	local diskdev=
650 651 652
	local varfs=ext4
	local vgname=vg0
	local var_dev=/dev/$vgname/lv_var
653 654 655 656
	local lvm_part_type="8e"
	local raid_part_type="fd"
	local part_type=$lvm_part_type
	local size=
657 658

	init_progs || return 1
659
	confirm_erase $@ || return 1
660

661 662 663 664
	if [ "$USE_RAID" ]; then
		part_type=$raid_part_type
		stop_all_raid
	fi
665

666 667 668 669 670 671 672
	for diskdev in "$@"; do
		setup_partitions $diskdev "$size,$part_type" || return 1
	done
	
	setup_lvm_volume_group $vgname $@ || return 1

	setup_lvm_swap $vgname
673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688

	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
689
	/etc/init.d/syslog --quiet restart
690 691
}

Natanael Copa's avatar
Natanael Copa committed
692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707
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
}

708
diskselect_help() {
709 710
	cat <<__EOF__

711
TODO
712 713 714 715

__EOF__
}

716
diskmode_help() {
717 718
	cat <<__EOF__

719
TODO
720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747

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

748 749 750
KERNEL_FLAVOR=grsec
case "$(uname -r)" in
	*-vs[0-9]*) KERNEL_FLAVOR=vserver;;
751
	*-pae) KERNEL_FLAVOR=pae;;
752 753
esac

754
SWAP_SIZE=$(find_swap_size)
755
# Parse args
756
while getopts "hk:Lo:qrs:v" opt; do
757
	case $opt in
758
		k) KERNEL_FLAVOR="$OPTARG";;
759
		L) USE_LVM=1;;
760
		o) APKOVL="$OPTARG";;
761 762
		q) QUIET=1;;
		r) USE_RAID=1;;
763
		s) SWAP_SIZE="$OPTARG";;
764
		v) VERBOSE=1;;
Natanael Copa's avatar
Natanael Copa committed
765
		*) usage;;
766 767
	esac
done
768
shift $(( $OPTIND - 1))
769

770 771
if [ -d "$1" ]; then
	# install to given mounted root
772
	install_mounted_root "${1%/}"
773 774 775
	exit $?
fi

776 777 778 779 780 781 782 783 784 785
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

786
disks=$(find_disks)
787
diskdevs=
Natanael Copa's avatar
Natanael Copa committed
788 789

# no disks so lets exit quietly.
790 791 792 793
if [ -z "$disks" ]; then
	[ -z "$QUIET" ] && echo "No disks found." >&2
	exit 0
fi
Natanael Copa's avatar
Natanael Copa committed
794

795 796 797 798 799
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
800
			echo "$i is not a suitable for partitioning"
801 802
			exit 1
		fi
803
		diskdevs="$diskdevs /dev/$j"
804 805
	done
else
806 807
	ask_disk "Which disk would you like to use? (or '?' for help or 'none')" \
		diskselect_help $disks
808 809 810
	if [ "$answer" != none ]; then
		diskdevs=/dev/$answer
	fi
811
fi
Natanael Copa's avatar
Natanael Copa committed
812

813
diskmode=
814
if [ -n "$diskdevs" ]; then
815 816
	answer=
	while true; do
817 818 819
		echo "The following disks are selected:"
		show_disk_info $diskdevs
		echon "How would you like to use them? ('root', 'data' or '?' for help) [?] "
820 821 822 823 824 825 826
		default_read answer '?'
		case "$answer" in
		'?') diskmode_help;;
		root|data) break;;
		esac
	done
	diskmode="$answer"
827
fi
Natanael Copa's avatar
Natanael Copa committed
828

829 830 831 832
set -- $diskdevs
if [ $# -gt 1 ]; then
	USE_RAID=1
fi
833

834 835
dmesg -n1

836 837
# native disk install
case "$diskmode" in
838 839
root) native_disk_install $diskdevs;;
data) data_only_disk_install $diskdevs;;
840
esac
Natanael Copa's avatar
Natanael Copa committed
841