#!/bin/bash

SCRIPT_NAME=`basename $0`

SCRIPTVERSION=19
NEEDSPACE=160000

DATADIR="/usr/share/libvznbdmig"

. $DATADIR/ct2vmlib

VEID=$1
NBD_PATH=$2
MSG_LEVEL=$3
CHECK_PACKAGES=$4

OPTS=`getopt -o b: \
 --long boot_device: \
 -n $SCRIPT_NAME -- "$@"`

if [ $? != 0 ] ; then usage; exit 1 ; fi

eval set -- "$OPTS"

while true ; do
	case "$1" in
		--boot_device)
			NBD_GRUB_PDEV=$2
			shift
			;;
		--)
			shift
			break
			;;
		*)
			break
			;;
	esac
done

#getmigscript $SCRIPT_NAME >/dev/null 2>&1
TMPLOSNAME="debian"
TMPLVERSION="7.0"
TMPLARCH="x86_64"

if [ $TMPLARCH = x86 ]; then
	TMPLENV="dpkg"
else
	TMPLENV="dpkgx64"
fi

RUN_FROM_CHROOT="$DATADIR/run_from_chroot /vz/pkgenv/$TMPLENV"
INITRD="initrd_createinitrd.img"
USE_UPSTART="no"
CT2VM_PACKAGES2_ADD=""

case "$TMPLOSNAME" in
	debian)
		if [ $TMPLARCH = x86 ]; then
			CT2VM_PACKAGES_ADD="linux-image-2.6-686 grub linux-headers-2.6-686 gcc make"
		else
			CT2VM_PACKAGES_ADD="linux-image-2.6-amd64 grub linux-headers-2.6-amd64 gcc make"
		fi
		if [ "$TMPLVERSION" = "5.0" ]; then
			if [ "x$NBD_GRUB_PDEV" = "x" ]; then
				INSTDEVICE="/dev/hda1"
				DEVMAJOR=3
				DEVMINOR=1
				BOOT="/boot"
			else
				INSTDEVICE="/dev/hda2"
				DEVMAJOR=3
				DEVMINOR=2
				GRUB_DEVICE="/dev/hda1"
				GRUB_DEVMAJOR=3
				GRUB_DEVMINOR=1
				BOOT=""
			fi
		else
			if [ "x$NBD_GRUB_PDEV" = "x" ]; then
				INSTDEVICE="/dev/sda1"
				DEVMAJOR=8
				DEVMINOR=1
				BOOT="/boot"
			else
				INSTDEVICE="/dev/sda2"
				DEVMAJOR=8
				DEVMINOR=2
				GRUB_DEVICE="/dev/sda1"
				GRUB_DEVMAJOR=8
				GRUB_DEVMINOR=1
				BOOT=""
			fi
		fi
		case "$TMPLVERSION" in
			5.0)
				TMPLTITLE="Debian 5.0"
				ADD_MODULES="ide-core.ko ide-pci-generic.ko piix.ko ide-disk.ko jbd.ko mbcache.ko ext3.ko"
				;;
			6.0)
				TMPLTITLE="Debian 6.0"
				ADD_MODULES="scsi_mod.ko libata.ko ahci.ko ata_piix.ko crc-t10dif.ko sd_mod.ko jbd.ko mbcache.ko ext3.ko"
				if [ $TMPLARCH = x86 ]; then
					CT2VM_PACKAGES_ADD="linux-image-2.6-686 grub-legacy linux-headers-2.6-686 gcc make"
				else
					CT2VM_PACKAGES_ADD="linux-image-2.6-amd64 grub-legacy linux-headers-2.6-amd64 gcc make"
				fi
				;;
			7.0)
				TMPLTITLE="Debian 7.0"
				ADD_MODULES="scsi_mod.ko libata.ko libahci.ko ahci.ko ata_piix.ko crc-t10dif.ko sd_mod.ko jbd.ko mbcache.ko ext3.ko"
				if [ $TMPLARCH = x86 ]; then
					CT2VM_PACKAGES_ADD="linux-image-2.6-686-pae grub-legacy linux-headers-2.6-686-pae gcc make dkms e2fsprogs"
				else
					CT2VM_PACKAGES_ADD="linux-image-2.6-amd64 grub-legacy linux-headers-2.6-amd64 gcc make dkms e2fsprogs"
				fi
				;;
			*)
				TMPLTITLE="Debian"
				ADD_MODULES="ide-core.ko ide-pci-generic.ko piix.ko ide-disk.ko jbd.ko mbcache.ko ext3.ko"
				;;
		esac
		;;
	ubuntu)
		CT2VM_PACKAGES_ADD="linux grub linux-headers-generic gcc make"
		if [ "x$NBD_GRUB_PDEV" = "x" ]; then
			INSTDEVICE="/dev/sda1"
			DEVMAJOR=8
			DEVMINOR=1
			BOOT="/boot"
		else
			INSTDEVICE="/dev/sda2"
			DEVMAJOR=8
			DEVMINOR=2
			GRUB_DEVICE="/dev/sda1"
			GRUB_DEVMAJOR=8
			GRUB_DEVMINOR=1
			BOOT=""
		fi
		case "$TMPLVERSION" in
			13.04)
				TMPLTITLE="Ubuntu 13.04"
				ADD_MODULES=""
				if [ $TMPLARCH = x86 ]; then
					CT2VM_PACKAGES_ADD="linux grub e2fsprogs linux-headers-generic-pae gcc dkms"
				else
					CT2VM_PACKAGES_ADD="linux grub e2fsprogs linux-headers-generic gcc dkms"
				fi
				ADD_MODULES="libahci.ko ahci.ko"
				REMOVE_CONSOLE_SCREEN="y"
				;;
			12.10)
				TMPLTITLE="Ubuntu 12.10"
				ADD_MODULES=""
				if [ $TMPLARCH = x86 ]; then
					CT2VM_PACKAGES_ADD="linux grub e2fsprogs linux-headers-generic-pae gcc"
				else
					CT2VM_PACKAGES_ADD="linux grub e2fsprogs linux-headers-generic gcc"
				fi
				REMOVE_CONSOLE_SCREEN="y"
				;;
			12.04)
				TMPLTITLE="Ubuntu 12.04"
				ADD_MODULES=""
				if [ $TMPLARCH = x86 ]; then
					CT2VM_PACKAGES_ADD="linux grub e2fsprogs linux-headers-generic-pae gcc"
				else
					CT2VM_PACKAGES_ADD="linux grub e2fsprogs linux-headers-generic gcc"
				fi
				REMOVE_CONSOLE_SCREEN="y"
				;;
			11.10)
				TMPLTITLE="Ubuntu 11.10"
				ADD_MODULES=""
				USE_UPSTART="yes"
				CT2VM_PACKAGES_ADD="linux grub e2fsprogs linux-headers-generic gcc"
				REMOVE_CONSOLE_SCREEN="y"
				;;
			11.04)
				TMPLTITLE="Ubuntu 11.04"
				ADD_MODULES=""
				USE_UPSTART="yes"
				CT2VM_PACKAGES_ADD="linux grub e2fsprogs linux-headers-generic gcc make"
				REMOVE_CONSOLE_SCREEN="y"
				if [ $TMPLARCH = x86 ]; then
					TMPLENV="dpkg_ma"
				else
					TMPLENV="dpkg_max64"
				fi
				;;
			10.10)
				TMPLTITLE="Ubuntu 10.10"
				ADD_MODULES=""
				USE_UPSTART="yes"
				CT2VM_PACKAGES_ADD="linux grub e2fsprogs linux-headers-generic gcc make"
				;;
			10.04)
				TMPLTITLE="Ubuntu 10.04"
				ADD_MODULES="ahci.ko"
				USE_UPSTART="yes"
				;;
			9.10)
				TMPLTITLE="Ubuntu 9.10"
				ADD_MODULES=""
				USE_UPSTART="yes"
				;;
			9.04)
				TMPLTITLE="Ubuntu 9.04"
				ADD_MODULES=""
				;;
			8.10)
				TMPLTITLE="Ubuntu 8.10"
				ADD_MODULES="scsi_mod.ko dock.ko libata.ko ata_piix.ko crc-t10dif.ko sd_mod.ko jbd.ko mbcache.ko ext3.ko"
				;;
			8.04)
				TMPLTITLE="Ubuntu 8.04"
				ADD_MODULES="scsi_mod.ko dock.ko libata.ko ata_piix.ko sd_mod.ko jbd.ko mbcache.ko ext3.ko"
				;;
			*)
				TMPLTITLE="Ubuntu"
				ADD_MODULES="scsi_mod.ko dock.ko libata.ko ata_piix.ko crc-t10dif.ko sd_mod.ko jbd.ko mbcache.ko ext3.ko"
				;;
		esac
		;;
esac

. /etc/vz/conf/$VEID.conf
. /etc/vz/vz.conf

function usage() {
	echo "Usage: $0 CTID NBD_PATH MSG_LEVEL [ CHECK_PACKAGES ] [ --grub_device=NBD_GRUB_PDEV ]"
}

function cleanup(){
	return 0
}

if [ "x$VEID" = "x" ]; then
	usage
	error_msg "You should give CT_IT" $ERR_TMPL
fi

if [ "x$CHECK_PACKAGES" = "xcheck_packages" ]; then
	$VZPKG install $VEID -q -n -p $CT2VM_PACKAGES_ADD >/dev/null 2>&1
	if [ $? -ne 0 ]; then
		error_msg "Can't download packages: $VZPKG install $VEID -q -n -p $CT2VM_PACKAGES_ADD failed" $ERR_TMPL
	else
		exit 0
	fi
fi

if [ ! -d $NBD_PATH ] || [ "x$NBD_PATH" = "x" ] || [ "x$NBD_PATH" = "/" ]; then
	usage
	error_msg "You should give right NBD_PATH ($NBD_PATH)" $ERR_TMPL
fi

if [ "x$INSTDEVICE" = "x" ]; then
	usage
	error_msg "You should give device" $ERR_TMPL
fi

# Create devices
/bin/mknod $NBD_PATH/dev/null c 1 3 >/dev/null 2>&1
/bin/chmod 666 $NBD_PATH/dev/null >/dev/null 2>&1

# Create /etc/kernel-img.conf
if [ "$TMPLOSNAME-$TMPLVERSION" = "debian-5.0" ]; then
	echo "do_initrd = Yes
" > $NBD_PATH/etc/kernel-img.conf
fi

# Install packages
install_packages_deb


install_debian_tools_script

# Umount tmpfs that mounted by some kernels post-install
MOUNT_DIR=`cat /proc/mounts | grep "^tmpfs $NBD_PATH" | awk '{ print $2 }'`
if [ "x$MOUNT_DIR " != "x" ]; then
	umount $MOUNT_DIR >/dev/null 2>&1
fi

# Remove /etc/kernel-img.conf
if [ "$TMPLOSNAME-$TMPLVERSION" = "debian-5.0" ]; then
	rm -f $NBD_PATH/etc/kernel-img.conf
fi

msg $MSG_INFO "Changing config files..."

# Move back upstart configs
if [ "$USE_UPSTART" = "yes" ]; then
	mv -f $NBD_PATH/etc/init.removed/* $NBD_PATH/etc/init >/dev/null 2>&1
fi

# Fix fstab
mv -f $NBD_PATH/etc/fstab $NBD_PATH/etc/fstab.orig
cat $NBD_PATH/etc/fstab.orig | grep -v " / " | grep -v "/dev/pts" > $NBD_PATH/etc/fstab
echo "
$INSTDEVICE / ext3 defaults 1 1
" >> $NBD_PATH/etc/fstab

if [ "x$GRUB_DEVICE" != "x" ]; then
	echo "
$GRUB_DEVICE /boot ext3 defaults 0 1
" >> $NBD_PATH/etc/fstab
fi

# Add back gettys to /etc/inittab

cat $NBD_PATH/etc/inittab | grep -e ^[1-6]: >/dev/null 2>&1

if [ $? -ne 0 ]; then
	echo "
1:2345:respawn:/sbin/getty 38400 tty1
2:2345:respawn:/sbin/getty 38400 tty2
3:2345:respawn:/sbin/getty 38400 tty3
4:2345:respawn:/sbin/getty 38400 tty4
5:2345:respawn:/sbin/getty 38400 tty5
6:2345:respawn:/sbin/getty 38400 tty6
" >> $NBD_PATH/etc/inittab
fi

# Remove vzreboot
rm -f $NBD_PATH/etc/rc6.d/S00vzreboot >/dev/null 2>&1

# Remove console-screen.sh
if [ "x$REMOVE_CONSOLE_SCREEN" != "x" ]; then
	rm -f $NBD_PATH/etc/rcS.d/S90console-screen.sh >/dev/null 2>&1
fi

# Create /selinux
if [ ! -d $NBD_PATH/selinux ]; then
	mkdir $NBD_PATH/selinux
fi

# Tune grub.conf
echo "
timeout=5
default=1
" > $NBD_PATH/boot/grub/grub.conf

if [ ! -f $NBD_PATH/boot/grub/menu.lst ]; then
	ln -s ./grub.conf $NBD_PATH/boot/grub/menu.lst
fi

msg $MSG_INFO "Configuring network..."

mv -f $NBD_PATH/etc/network/interfaces $NBD_PATH/etc/network/interfaces_pre_migrate \
>/dev/null 2>&1
cp $NBD_PATH/etc/network/interfaces.template $NBD_PATH/etc/network/interfaces \
>/dev/null 2>&1

if [ "x$IP_ADDRESS" = "x0.0.0.0" ]; then
	IP_ADDRESS=""
fi

# Preserve netif settings
NETIF_IPV4_LIST=`echo $NETIF | grep ip= | \
sed -e "s,.*ip=,,g" -e "s,\,.*,,g" -e "s,:, ,g" 2>/dev/null`

NETIF_IPV6_LIST=`echo $NETIF | grep ip6= | \
sed -e "s,.*ip6=,,g" -e "s,\,, ,g" -e "s,\"$,,g" 2>/dev/null`

NETIF_IPV4_DHCP=1
echo $NETIF | grep dhcp=yes >/dev/null 2>&1
NETIF_IPV4_DHCP=$?

if [ "x$NETIF_IPV4_LIST" != "x" ] || [ "x$NETIF_IPV6_LIST" != "x" ]; then
	IP_ADDRESS="$IP_ADDRESS $NETIF_IPV4_LIST $NETIF_IPV6_LIST"
fi

if [ "x$IP_ADDRESS" != "x" ] || [ $NETIF_IPV4_DHCP -eq 0 ]; then
	ipv4addr=""
	ipv4mask=""
	ipv6addr=""
	NETDEVICE="eth0"
	NETDEVICE_COUNT=1
	if [ $NETIF_IPV4_DHCP -eq 0 ]; then
		echo "
auto lo
iface lo inet loopback

auto $NETDEVICE
iface $NETDEVICE inet dhcp" > $NBD_PATH/etc/network/interfaces
	else
		echo "
auto lo
iface lo inet loopback

auto $NETDEVICE
iface $NETDEVICE inet static
	address 127.0.0.1
	netmask 255.255.255.255
	broadcast 0.0.0.0" > $NBD_PATH/etc/network/interfaces
	fi

	# Setup IPV6 first
	for i in $IP_ADDRESS; do
		ipv6addr=`echo $i | grep ":"`
		if [ "x$ipv6addr" != "x" ]; then
			if `echo $ipv6addr | grep -v "/" >/dev/null 2>&1`; then
				ipv6addr="$ipv6addr/128"
			fi
			echo "	up ip addr add $ipv6addr dev $NETDEVICE" \
				>> $NBD_PATH/etc/network/interfaces
		fi
	done

	echo "	up route add default dev $NETDEVICE" \
		>> $NBD_PATH/etc/network/interfaces

	# Then setup IPV4
	for i in $IP_ADDRESS; do
		ipv4addr=`echo $i | grep "\."`
		if [ "x$ipv4addr" != "x" ]; then
			if [ $NETDEVICE_COUNT -gt 0 ]; then
				NETDEVICE="eth0:$((NETDEVICE_COUNT-1))"
			fi
			if `echo $ipv4addr | grep "/" >/dev/null 2>&1`; then
				ipv4addr=`echo $i | sed "s,/.*,,g" 2>/dev/null`
				ipv4mask=`echo $i | sed "s,.*/,,g" 2>/dev/null`
			else
				ipv4mask="255.255.255.0"
			fi
			echo "
auto $NETDEVICE
iface $NETDEVICE inet static
	address $ipv4addr
	netmask $ipv4mask
	broadcast 0.0.0.0
" >> $NBD_PATH/etc/network/interfaces
			NETDEVICE_COUNT=$((NETDEVICE_COUNT+1))
		fi
	done
fi

set_nameserver

msg $MSG_INFO "Configuring kernel..."

AVAILABLE_KERNELS=`find $NBD_PATH/boot -name vmlinuz*`

[ "x$AVAILABLE_KERNELS" = "x" ] && error_msg "No any kernel available" \
$ERR_TMPL

# Make root device
for i in $INSTDEVICE /dev/root; do
	/bin/mknod $NBD_PATH/$i b $DEVMAJOR $DEVMINOR >/dev/null 2>&1
	/bin/chmod 660 $NBD_PATH/$i >/dev/null 2>&1
done

# Make grub device
if [ "x$GRUB_DEVICE" != "x" ]; then
	/bin/mknod $NBD_PATH/$GRUB_DEVICE b $GRUB_DEVMAJOR $GRUB_DEVMINOR \
	>/dev/null 2>&1
	/bin/chmod 660 $NBD_PATH/$GRUB_DEVICE >/dev/null 2>&1
fi

# Create empty custom modules file
touch $NBD_PATH/etc/initramfs-tools/modules

#remove init script
/usr/sbin/chroot $NBD_PATH update-rc.d -f modules_dep.sh remove  >/dev/null 2>&1
/bin/rm -f $NBD_PATH/etc/init.d/modules_dep.sh  >/dev/null 2>&1

# Get kernel version and write it to grub
for i in $AVAILABLE_KERNELS; do
	KERN_VERSION=`echo $i | sed "s,.*vmlinuz-,,g"`;

	# Update depmod
	/usr/sbin/chroot $NBD_PATH /sbin/depmod $KERN_VERSION >/dev/null 2>&1

	INITRDTEMPDIR=`mktemp -d /tmp/migrate_initrdXXXXXX`

	[ "x$INITRDTEMPDIR" = "x" ] || [ ! -d $INITRDTEMPDIR ] && \
	error_msg "Failed to create temporary dir" $ERR_TMPL

	cp -a $DATADIR/initrd $INITRDTEMPDIR

	for i in $ADD_MODULES; do
		MODULE=`find $NBD_PATH/lib/modules/*$KERN_VERSION* -name $i 2>/dev/null`
		if [ -f "$MODULE" ]; then
			cp $MODULE $INITRDTEMPDIR/initrd/lib/ >/dev/null 2>&1
		else
			error_msg "Failed to find module $i" $ERR_TMPL
		fi
	done

	echo "#!/bin/nash

mknod $INSTDEVICE b $DEVMAJOR $DEVMINOR
" > $INITRDTEMPDIR/initrd/bin/load_modules

for ADD_MODULE in $ADD_MODULES; do
	echo "
echo \"Loading $ADD_MODULE module\"
insmod /lib/$ADD_MODULE
" >> $INITRDTEMPDIR/initrd/bin/load_modules
done

	chmod 0755 $INITRDTEMPDIR/initrd/bin/load_modules

	pushd $INITRDTEMPDIR/initrd >/dev/null 2>&1
	find * | cpio -c -o > ../$INITRD 2>/dev/null
	popd >/dev/null 2>&1

	if [ ! -f $INITRDTEMPDIR/$INITRD ]; then
		rm -rf $INITRDTEMPDIR >/dev/null 2>&1
		error_msg "Failed to create initrd" $ERR_TMPL
	fi

	mv $INITRDTEMPDIR/$INITRD $NBD_PATH/boot/$INITRD-$KERN_VERSION >/dev/null 2>&1

	rm -rf $INITRDTEMPDIR >/dev/null 2>&1

	mkdir -p $NBD_PATH/$DATADIR >/dev/null 2>&1
	echo "#!/bin/bash

PATH=\"/sbin:/usr/sbin:\$PATH\"
export PATH

mount -o remount,rw /

" > $NBD_PATH/$DATADIR/create_initrd

if [ "x$GRUB_DEVICE" != "x" ]; then
	echo "mount /boot

" >> $NBD_PATH/$DATADIR/create_initrd
fi

echo "# Remove old initrd if exists
rm -f /boot/initrd.img-\`uname -r\`

# Create proper initrd
/usr/sbin/update-initramfs -c -k all

if [ \$? -eq 0 ]; then
	echo \"
timeout=5
default=0

title $TMPLTITLE (\`uname -r\`)
	root (hd0,0)
	kernel $BOOT/vmlinuz-\`uname -r\` ro root=$INSTDEVICE quiet splash
	initrd $BOOT/initrd.img-\`uname -r\`
\" > /boot/grub/grub.conf

fi

" >> $NBD_PATH/$DATADIR/create_initrd

if [ -x "$NBD_PATH/etc/init.d/udev" ]; then
	/usr/sbin/chroot $NBD_PATH update-rc.d udev defaults >/dev/null 2>&1
fi
if [ -x "$NBD_PATH/etc/init.d/udev-mtab" ]; then
	/usr/sbin/chroot $NBD_PATH update-rc.d udev-mtab defaults  >/dev/null 2>&1
fi
if [ -x "$NBD_PATH/etc/init.d/umountroot" ]; then
	/usr/sbin/chroot $NBD_PATH update-rc.d umountroot defaults  >/dev/null 2>&1
fi


if [ "x$GRUB_DEVICE" != "x" ]; then
	echo "umount /boot

" >> $NBD_PATH/$DATADIR/create_initrd
fi

echo "mount -o remount,ro /

sync

reboot -fn
" >> $NBD_PATH/$DATADIR/create_initrd

	chmod 0755 $NBD_PATH/$DATADIR/create_initrd >/dev/null 2>&1

	touch $NBD_PATH/var/lib/initramfs-tools/$KERN_VERSION

	echo "
title Create Initrd ($KERN_VERSION)
	root (hd0,0)
	kernel $BOOT/vmlinuz-$KERN_VERSION ro root=$INSTDEVICE init=$DATADIR/create_initrd
	initrd $BOOT/$INITRD-$KERN_VERSION
" >> $NBD_PATH/boot/grub/grub.conf

done

exit 0
