#!/bin/bash # # Leo Eraly # echo "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!" echo "" echo "While running this script no other tasks should be performed on this system" echo "" echo "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!" INITIAL_CONFIG=/tmp/xen-config-start.tmp HD_FILE_ROOT="/var/lib/xen/images" CONFIG_ROOT="/etc/xen/vm/" function write_initial_config() { # default xen vm configuration file cat > $INITIAL_CONFIG << EOF disk = [ 'file:/var/lib/xen/images/#NAME#/#VIRTUAL_DISK#,#VIRTUAL_DISK#,w', 'phy:/dev/hdc,hdb,r' ] memory = 256 vcpus = 1 builder = 'linux' name = '#NAME#' vif = [ 'mac=#MAC#' ] localtime = 0 on_poweroff = 'destroy' on_reboot = 'restart' on_crash = 'restart' extra = ' TERM=xterm' bootloader = '/usr/lib/xen/boot/domUloader.py' bootentry = '#ROOT_PARTITION#:/boot/vmlinuz-xen,/boot/initrd-xen' EOF echo "Wrote $INITIAL_CONFIG" } # start of new random mac address MAC_START="00:16:3e" #function to generate mac address function generate_mac() { /usr/bin/perl << EOF \$string = "0123456789abcdef"; \$k = (substr(\$string , rand(16) , 1)) . substr(\$string , rand(16) , 1); print(\$k); EOF } NEW_MAC="$MAC_START:$(generate_mac):$(generate_mac):$(generate_mac)" function blocks_to_mb() { K=$[$1/1024] echo $K } NEW_MACHINE_NAME=$(ls -1 /etc/xen/vm/ | tail -1 | awk -F [a-zA-Z] '{ print $3}') NEW_MACHINE_NAME=$[$NEW_MACHINE_NAME+1] NEW_MACHINE_NAME="vm$NEW_MACHINE_NAME" #we need to have rsync installed RSYNC_BIN=/usr/bin/rsync test -x $RSYNC_BIN || echo "$RSYNC_BIN not installed"; ROOT_DEV=$(grep " / " /proc/mounts | grep -v rootfs | cut -d" " -f1) VIRTUAL_DISK=$(echo $ROOT_DEV | sed -e s/[0-9]// | cut -d/ -f3 ) ROOT_PARTITION=$(echo $ROOT_DEV | sed -e s/\\/dev\\///) ROOTFS=$(grep " / " /proc/mounts | grep -v rootfs | cut -d" " -f3) ROOT_DEV_SIZE=$(sfdisk -s $ROOT_DEV) ROOT_DEV_USED=$(df | grep "$ROOT_DEV" | tr -s " " ":" | cut -d: -f3) ROOT_DEV_AVAIL=$(df | grep "$ROOT_DEV" | tr -s " " ":" | cut -d: -f4) MAIN_DEV=$(echo $ROOT_DEV | sed -e "s/[0-9]//") ROOT_CYLINDERS=$(sfdisk -q -l $MAIN_DEV 2> /dev/null | grep $ROOT_DEV | tail -1 | tr -s " " ":" | cut -d: -f 5) ROOT_CYLINDERS=$(echo $ROOT_CYLINDERS | sed -e "s/[-|+]//") SWAP_DEV=$(tail -1 /proc/swaps | cut -d" " -f1) SWAP_DEV_SIZE=$(sfdisk -s $SWAP_DEV) SWAP_CYLINDERS=$( sfdisk -q -l $MAIN_DEV 2> /dev/null | grep $SWAP_DEV | tail -1 | tr -s " " ":" | cut -d: -f 4) SWAP_CYLINDERS=$(echo $SWAP_CYLINDERS | sed -e "s/[-|+]//") # this is added to the current size currently in use on the root device EXTRA_SIZE=1000 NEW_ROOT_SIZE=$[$ROOT_DEV_USED+$EXTRA_SIZE+SWAP_DEV_SIZE] echo "Partition which contains root fs: $ROOT_DEV" echo "Type of root fs: $ROOTFS" echo "Size of root partition (blocks): $ROOT_DEV_SIZE" echo "Size of root partition currently in use (blocks): $ROOT_DEV_USED" echo "Size of root partition in VM (blocks - to be created): $NEW_ROOT_SIZE" if [ $NEW_ROOT_SIZE -lt $ROOT_DEV_AVAIL ] then echo "We have enough space available. Continuing..." else echo "We don't have enough space available to create a VM" echo "We need $NEW_ROOT_SIZE but only $ROOT_DEV_AVAIL available (blocks)" exit 1 fi TEMP_ROOT_FILE=$(mktemp) echo "Creating file ($TEMP_ROOT_FILE) which will hold new vm" dd if=/dev/zero of=$TEMP_ROOT_FILE bs=1k count=$NEW_ROOT_SIZE if [ $? -eq 0 ] then echo "File was created successfully" else "Failed to create file ($TEMP_ROOT_FILE)" rm $TEMP_ROOT_FILE exit 1 fi echo "Setting up loopback device" #get list of existing loop devices LAST_LOOP=$(losetup -a | cut -d: -f1 | tail -1 | awk -F 'loop' '{print $2}') LAST_LOOP=$[$LAST_LOOP+1] LOOP_DEVICE="/dev/loop$LAST_LOOP" if [ $LAST_LOOP -lt 7 ] then echo "Creating loop device" losetup $LOOP_DEVICE $TEMP_ROOT_FILE else echo "No available loop devices" exit 1 fi if [ $? -eq 0 ] then echo "Successfully created loop device under $LOOP_DEVICE" else echo "Failed to create loop device" exit 1 fi #create empty dos partition table echo "Creating (msdos) disk label on $LOOP_DEVICE" parted -s $LOOP_DEVICE mklabel msdos if [ $? -eq 0 ] then echo "Successfully created disk label on $LOOP_DEVICE" else echo "Failed to create disk label" exit 1 fi echo "Creating an initial partition table" SWAP_MB=`blocks_to_mb "$SWAP_DEV_SIZE"` parted -s $LOOP_DEVICE mkpartfs primary linux-swap 0 $SWAP_MB > /dev/null 2>&1 SWAP_MB=$[$SWAP_MB+1] ROOT_MB=`blocks_to_mb "$NEW_ROOT_SIZE"` parted -s $LOOP_DEVICE mkpart primary $SWAP_MB $ROOT_MB > /dev/null 2>&1 parted -s $LOOP_DEVICE print echo "Creating device mappings for the partitions" kpartx -a $LOOP_DEVICE > /dev/null 2>&1 if [ $? -eq 0 ] then echo "Successfully created device mappings" else echo "Failed to create device mappings" exit 1 fi ROOT_MAPPING=$(kpartx -l $LOOP_DEVICE | tr -s " " ":" | cut -d: -f1 | tail -1) ROOT_MAPPING="/dev/mapper/$ROOT_MAPPING" SWAP_MAPPING=$(kpartx -l $LOOP_DEVICE | tr -s " " ":" | cut -d: -f1 | head -1) SWAP_MAPPING="/dev/mapper/$SWAP_MAPPING" echo "Creating root filesystem on $TEMP_ROOT_FILE ($ROOT_MAPPING)" if [ -b "$ROOT_MAPPING" ] then echo "Device mapping for root partition exists" else echo "No device mapping for root partition created" exit 1 fi case "$ROOTFS" in reiserfs) mkfs.reiserfs -fff $ROOT_MAPPING > /dev/null 2>&1 ;; ext2|ext3) mkfs.ext3 -F $ROOT_MAPPING > /dev/null 2>&1 ;; xfs) mkfs.xfs -f $ROOT_MAPPING > /dev/null 2>&1 ;; esac if [ $? -eq 0 ] then echo "Successfully created filesystem on $ROOT_MAPPING ($ROOTFS)" else echo "Failed to create filesystem" exit 1 fi echo "Creating swap on $SWAP_MAPPING" if [ -b "$SWAP_MAPPING" ] then echo "Device mapping for swap partition exists" else echo "No device mapping for swap partition created" exit 1 fi mkswap $SWAP_MAPPING if [ $? -eq 0 ] then echo "Successfully created swap on $SWAP_MAPPING" else echo "Failed to create swap" exit 1 fi # now loopback mount the filesystem in a temporary directory echo "Trying to (loopback) mount the filesystem" TEMP_MOUNT_DIR=/mnt/xen-temp if [ -d "$TEMP_MOUNT_DIR" ] then echo "Temp mount dir: $TEMP_MOUNT_DIR exists" else echo "Creating $TEMP_MOUNT_DIR" mkdir $TEMP_MOUNT_DIR fi mount -o loop $ROOT_MAPPING $TEMP_MOUNT_DIR if [ $? -eq 0 ] then echo "Successfully mounted $ROOT_MAPPING on $TEMP_MOUNT_DIR" else echo "Failed to mount $TEMP_ROOT_FILE on $TEMP_MOUNT_DIR" exit 1 fi # syncing root fs to virtual disk file echo "Trying to sync the root fs to the virtual disk file" $RSYNC_BIN -azvp --exclude=/proc --exclude=/sys --exclude=/mnt --exclude=/tmp --exclude=/var/lib/xen/images / $TEMP_MOUNT_DIR if [ $? -eq 0 ] then echo "Successfully synced" mkdir "$TEMP_MOUNT_DIR/mnt" "$TEMP_MOUNT_DIR/sys" "$TEMP_MOUNT_DIR/proc" "$TEMP_MOUNT_DIR/tmp" else echo "Failed to sync root fs" exit 1 fi umount $TEMP_MOUNT_DIR if [ $? -eq 0 ] then echo "Successfully unmounted $TEMP_MOUNT_DIR" else echo "Failed to unmount $TEMP_MOUNT_DIR" exit 1 fi echo "Creating images directory" HD_DIR="$HD_FILE_ROOT/$NEW_MACHINE_NAME" HD_FILE="$HD_FILE_ROOT/$NEW_MACHINE_NAME/$VIRTUAL_DISK" CONFIG_FILE="$CONFIG_ROOT/$NEW_MACHINE_NAME" mkdir -p $HD_DIR if [ $? -eq 0 ] then echo "Successfully created $HD_DIR" else echo "Failed to create $HD_DIR" exit 1 fi echo "Removing temporary device mappings" kpartx -d $LOOP_DEVICE > /dev/null 2>&1 if [ $? -eq 0 ] then echo "Successfully removed device mappings" else echo "Failed to remove device mappings" exit 1 fi echo "Removing loop devices" losetup -d $LOOP_DEVICE > /dev/null 2>&1 if [ $? -eq 0 ] then echo "Successfully removed loop device ($LOOP_DEVICE)" else echo "Failed to remove loop device ($LOOP_DEVICE)" exit 1 fi echo "Moving image file to permanent location ($VIRTUAL_DISK)" mv $TEMP_ROOT_FILE $HD_FILE if [ $? -eq 0 ] then echo "Successfully moved image file to $HD_FILE" else echo "Failed to move image file to $HD_FILE" exit 1 fi echo "Writing configuration" write_initial_config echo "Writing configuration with following values" echo "-------------------------------------------" echo -e "Machine name\t\t : $NEW_MACHINE_NAME" echo -e "Mac address\t\t : $NEW_MAC" echo -e "Hard disk file\t\t : $HD_FILE" echo -e "Virtual disk name\t : $VIRTUAL_DISK" echo -e "Root partition\t\t : $ROOT_PARTITION" sed -e s/#NAME#/$NEW_MACHINE_NAME/g $INITIAL_CONFIG | sed -e s/#MAC#/$NEW_MAC/ | sed -e s/#VIRTUAL_DISK#/$VIRTUAL_DISK/g | sed -e s/#ROOT_PARTITION#/$ROOT_PARTITION/ > $CONFIG_FILE if [ $? -eq 0 ] then echo "Successfully created configuration file ($CONFIG_FILE)" rm $INITIAL_CONFIG else echo "Failed to create configuration file ($CONFIG_FILE)" rm $INITIAL_CONFIG exit 1 fi #/bin/rm $TEMP_ROOT_FILE