040-clone-vm
#!/bin/bash
#
# Clone VM
#
if [ $UID -eq 0 ]; then
  echo "This script should NOT be run as root."
  exit 1
fi
#
# Source config file
if [ ! -f ~/.vbconfig ]; then
    echo "Config File ~/.vbconfig not found!"
    echo "Run: set-folders to create .vbconfig"
    exit 1
fi
. ~/.vbconfig
#
echo -e "\e[0;32mList of VMs ... \e[0m"
echo -e "\e[0;33m"
VBoxManage list vms|sort
echo -e "\e[0m"
read -p "Source VM Name: " VB_VM_NAME
read -p "Target VM Name: " VB_VM_NEW_NAME
read -e -p "CPU Count     : " -i "1" VB_VM_NEW_CPU
read -e -p "Memory in MB  : " -i "256" VB_VM_NEW_MEM
read -e -p "VRDE Port     : " -i "4010" VB_VM_NEW_VRDEPORT
#
VM_EXISTS=`VBoxManage list vms|grep -c '^"'${VB_VM_NAME}'"'`
if [ $VM_EXISTS -eq 0 ]; then
  echo "Source VM $VB_VM_NAME not found!"
  echo "Exiting ..."
  exit 1
fi
 
VM_EXISTS=`VBoxManage list vms|grep -c '^"'${VB_VM_NEW_NAME}'"'`
if [ $VM_EXISTS -eq 1 ]; then
  echo "Target VM $VB_VM_NAME already exists!"
  echo "Exiting ..."
  exit 1
fi
 
VB_VM_GUEST_NAME=`VBoxManage getextradata ${VB_VM_NAME} GuestHostName|cut -d" " -f2`
VB_VM_GUEST_USER=`VBoxManage getextradata ${VB_VM_NAME} GuestUser|cut -d" " -f2`
VB_VM_GUEST_PASS=`VBoxManage getextradata ${VB_VM_NAME} GuestPass|cut -d" " -f2`
#
VB_VM_GUEST_VM_CMD="/usr/local/bin/vmname"
#
echo
echo "Consider Updating/Upgrading Source VM ($VB_VM_NAME) before cloning
  aptitude update
  aptitude -y upgrade
 
Also make sure the Guest Additions is the same version as VirtualBox
 
"
VB_VM_NO_SNAP_MSG="This machine does not have any snapshots"
VB_VM_NO_SNAP=`VBoxManage snapshot "${VB_VM_NAME}" list|grep -c "$VB_VM_NO_SNAP_MSG"`
if [ $VB_VM_NO_SNAP -eq 0 ]; then
  echo "VM $VB_VM_NAME has snapshots. This usually messes up new disknames!"
  echo "Exiting ..."
  exit 1
fi
#
VM_POWERED_ON=`VBoxManage list runningvms|grep -c '^"'${VB_VM_NAME}'"'`
if [ $VM_POWERED_ON -eq 1 ]; then
  echo "VM $VB_VM_NAME is up. Please power-down VM to continue"
  echo "Exiting ..."
  exit 1
fi
#
echo
echo "Review parameters for New VM"
echo
echo "CPU            : $VB_VM_NEW_CPU"
echo "Memory (MB)    : $VB_VM_NEW_MEM"
echo "New VM Name    : $VB_VM_NEW_NAME"
echo "VM VRDE Port   : $VB_VM_NEW_VRDEPORT"
echo
read -p "Press [Enter] key to continue or [Ctrl-C] to break ..."
echo
#
# Clone VM
VBoxManage clonevm "$VB_VM_NAME" --name "$VB_VM_NEW_NAME" \
  --register --options keepdisknames
#
# Update Metadata
NOW=$(date +"%Y-%m-%d-%H-%M-%S")
VBoxManage setextradata ${VB_VM_NEW_NAME} CloneDateTime $NOW
#
# Modify CPU, Memory VRP Port
VBoxManage modifyvm "${VB_VM_NEW_NAME}" \
  --memory ${VB_VM_NEW_MEM} --cpus ${VB_VM_NEW_CPU}
VBoxManage modifyvm "${VB_VM_NEW_NAME}" \
  --vrdeport $VB_VM_NEW_VRDEPORT
#
# Update Guest Host Name and Guest User Password
echo "Current Guest Host Name is ${VB_VM_GUEST_NAME}."
read -p "Enter New Guest Host Name: " VB_VM_NEW_GUEST_NAME
VBoxManage setextradata ${VB_VM_NEW_NAME} \
  GuestHostName $VB_VM_NEW_GUEST_NAME
echo "Current Guest User Name is ${VB_VM_GUEST_USER}."
read -p "Enter Guest User New password: " VB_VM_NEW_GUEST_PASS
echo "Use the same password when resetting the
Guest password for Guest User $VB_VM_GUEST_USER"
VBoxManage setextradata ${VB_VM_NEW_NAME} GuestPass $VB_VM_NEW_GUEST_PASS
#
echo "Powering New Clone VM (${VB_VM_NEW_NAME}) on ..."
VBoxManage startvm ${VB_VM_NEW_NAME} --type headless
echo "Log into Guest and update: Host Name, Host User Password, 
Regenerate SSH Keys, Network IP, etc."
echo "Guest Credentials is $VB_VM_GUEST_USER / $VB_VM_GUEST_PASS"
echo "Sleeping/waiting for VM to power on ..."
sleep 30
echo "Guest IP:"
VBoxManage guestcontrol $VB_VM_NEW_NAME exec --image /sbin/ifconfig \
  --username $VB_VM_GUEST_USER --password $VB_VM_GUEST_PASS \
  --wait-stdout | grep "inet addr"
echo
echo "Use the script below (as root):
#
# Change Host Name and Guest VM Name
sed -i 's/$VB_VM_GUEST_NAME/$VB_VM_NEW_GUEST_NAME/g' /etc/hostname
sed -i 's/$VB_VM_GUEST_NAME/$VB_VM_NEW_GUEST_NAME/g' /etc/hosts
sed -i 's/$VB_VM_NAME/$VB_VM_NEW_NAME/g' ${VB_VM_GUEST_VM_CMD}
#
# Regenerate SSH Keys
/bin/rm /etc/ssh/ssh_host_*
dpkg-reconfigure openssh-server
#
# Reset password to $VB_VM_NEW_GUEST_PASS
passwd $VB_VM_GUEST_USER
#
# Network configuration - Update static address as required
vim /etc/network/interfaces
#
# Mail configuration - update postfic config as required
vim /etc/postfix/main.cf
# sed -i 's/$VB_VM_GUEST_NAME/$VB_VM_NEW_GUEST_NAME/g' /etc/postfix/main.cf
# sed -i 's/$VB_VM_GUEST_NAME/$VB_VM_NEW_GUEST_NAME/g' /etc/mailname
#
# Set Guest Name
# This step is redundant if ${VB_VM_GUEST_VM_CMD} was already defined in Guest
echo '#!/bin/bash' > ${VB_VM_GUEST_VM_CMD}
echo 'echo $VB_VM_NEW_NAME' >> ${VB_VM_GUEST_VM_CMD}
chmod 755 ${VB_VM_GUEST_VM_CMD}
#
"
echo
echo "Waiting to complete 1st set of configuration on Guest ..."
echo "Reboot server when completed"
read -p "Press [Enter] key to continue or [Ctrl-C] to break ..."
#
echo "Summary info for you VM saved in ExtraData ..."
VBoxManage getextradata $VB_VM_NEW_NAME enumerate
echo "For security reasons, feel free to delete some of this 
user-defined info from the configuration."
echo
echo "All done. Enjoy your new VM!"
exit