#!/bin/bash
# Matt McCarrell 2009

ext_script_dir="/xen/generic/scripts"
generic_vm="/xen/generic/ubuntu/2009-11-18/ubuntu-8.04-generic"
conf_dir="/xen/confs"
disk_dir="/xen/images"
admin_email="request@cslabs.clarkson.edu"

vm_name=$1
cpus=$2
mem=$3
user=$4
email=$5
ip=$6
ip2=$7
ip3=$8

CP=`which cp`
CHROOT=/usr/sbin/chroot
SED=`which sed`
AWK=`which awk`
ECHO=`which echo`
LS=`which ls`
XM=/usr/sbin/xm
PWGEN=`which pwgen`
GREP=`which grep`
PRINTF=`which printf`
MAIL=`which mail`
HOSTNAME=`which hostname`
DATE=`which date`
RM=`which rm`

rootpass=`${PWGEN} -ncs 16`
userpass=`${PWGEN} -nc 8`
freemem=`${XM} info | ${GREP} free_memory | ${AWK} '{print $3}'`
totalcpus=`${XM} info | ${GREP} nr_cpus | ${AWK} '{print $3}'`
dom0=`${HOSTNAME}`
date=`${DATE}`

if [ "$#" -lt "6" ]
then
  ${ECHO} "Error: At least the following options must be specified:  ./create_ubuntu_vm.sh VMNAME CPUS MEM USER EMAIL IP IP2 IP3"
  ${PRINTF} "%b" "An error occurred while creating your new virtual machine.\n\nError: The correct arguments were not supplied to the creation script on the dom0.  Please try to create your VM again.\n\nError Time: ${date}\nDom0 User: ${SUDO_USER}\n\nVM Name: ${vm_name}\nIP(s): ${ip} ${ip2} ${ip3}\nHostname: ${vm_name}.cslabs.clarkson.edu\nCPUs: ${cpus}\nRAM: ${mem}\nOS: Ubuntu 8.04\ndom0: ${dom0}\n\nMaintainer: ${user}\nEmail: ${email}\n\nIf you are unable to successfully create your new virtual machine after a second attempt or have a question, please respond to this email.\n\nThank you,\nYour friendly CSLabs VM Creator." | ${MAIL} -s "** New VM: ${vm_name} - Creation Error **" ${email},${admin_email} -- -f "${admin_email}"
  exit 1
fi

if [ ${cpus} -eq ${cpus} 2> /dev/null ]
then
  if [ ${cpus} -gt ${totalcpus} ]
  then
    ${PRINTF} "%b" "An error occurred while creating your new virtual machine.\n\nError: You specified a greater number of CPUs then what is available on the system.  Please specify something less than or equal to ${totalcpus} for CPUs and attempt to create your VM again.\n\nError Time: ${date}\nDom0 User: ${SUDO_USER}\n\nVM Name: ${vm_name}\nIP(s): ${ip} ${ip2} ${ip3}\nHostname: ${vm_name}.cslabs.clarkson.edu\nCPUs: ${cpus}\nRAM: ${mem}\nOS: Ubuntu 8.04\ndom0: ${dom0}\n\nMaintainer: ${user}\nEmail: ${email}\n\nIf you are unable to successfully create your new virtual machine after a second attempt or have a question, please respond to this email.\n\nThank you,\nYour friendly CSLabs VM Creator." | ${MAIL} -s "** New VM: ${vm_name} - Creation Error **" ${email},${admin_email} -- -f "${admin_email}"
    exit 1
  fi
else
  ${PRINTF} "%b" "An error occurred while creating your new virtual machine.\n\nError: You must specify the number of CPUs for the VM as a digit.  Please attempt to create your VM again specifying the number of CPUs as a digit.\n\nError Time: ${date}\nDom0 User: ${SUDO_USER}\n\nVM Name: ${vm_name}\nIP(s): ${ip} ${ip2} ${ip3}\nHostname: ${vm_name}.cslabs.clarkson.edu\nCPUs: ${cpus}\nRAM: ${mem}\nOS: Ubuntu 8.04\ndom0: ${dom0}\n\nMaintainer: ${user}\nEmail: ${email}\n\nIf you are unable to successfully create your new virtual machine after a second attempt or have a question, please respond to this email.\n\nThank you,\nYour friendly CSLabs VM Creator." | ${MAIL} -s "** New VM: ${vm_name} - Creation Error **" ${email},${admin_email} -- -f "${admin_email}"
  exit 1
fi

if [ ${mem} -eq ${mem} 2> /dev/null ]
then
  if [ ${mem} -gt ${freemem} ]
  then
    ${PRINTF} "%b" "An error occurred while creating your new virtual machine.\n\nError: There is not enough RAM available on this dom0 for your VM.  Please specify a smaller amount of RAM that is equal to or less than ${freemem} MB or choose a different dom0 and attempt to create your VM again.\n\nError Time: ${date}\nDom0 User: ${SUDO_USER}\n\nVM Name: ${vm_name}\nIP(s): ${ip} ${ip2} ${ip3}\nHostname: ${vm_name}.cslabs.clarkson.edu\nCPUs: ${cpus}\nRAM: ${mem}\nOS: Ubuntu 8.04\ndom0: ${dom0}\n\nMaintainer: ${user}\nEmail: ${email}\n\nIf you are unable to successfully create your new virtual machine after a second attempt or have a question, please respond to this email.\n\nThank you,\nYour friendly CSLabs VM Creator." | ${MAIL} -s "** New VM: ${vm_name} - Creation Error **" ${email},${admin_email} -- -f "${admin_email}"
    exit 1
  fi
else
  ${PRINTF} "%b" "An error occurred while creating your new virtual machine.\n\nError: You must specify the amount of RAM for the VM with digits.  Please attempt to create your VM again specifying the amount of RAM with digits.\n\nError Time: ${date}\nDom0 User: ${SUDO_USER}\n\nVM Name: ${vm_name}\nIP(s): ${ip} ${ip2} ${ip3}\nHostname: ${vm_name}.cslabs.clarkson.edu\nCPUs: ${cpus}\nRAM: ${mem}\nOS: Ubuntu 8.04\ndom0: ${dom0}\n\nMaintainer: ${user}\nEmail: ${email}\n\nIf you are unable to successfully create your new virtual machine after a second attempt or have a question, please respond to this email.\n\nThank you,\nYour friendly CSLabs VM Creator." | ${MAIL} -s "** New VM: ${vm_name} - Creation Error **" ${email},${admin_email} -- -f "${admin_email}"
  exit 1
fi

if [[ "${ip}" =~ "128\.153\.145\.([01]?[0-9]?[0-9]|2[0-4][0-9]|25[0-5])$" ]]
then
  ${ECHO} "Do nothing" > /dev/null
else
  ${PRINTF} "%b" "An error occurred while creating your new virtual machine.\n\nError: You entered an invalid primary IP address.  Please choose an IP on the 145 subnet (128.153.145.0-255) and attempt to create your VM again.\n\nError Time: ${date}\nDom0 User: ${SUDO_USER}\n\nVM Name: ${vm_name}\nIP(s): ${ip} ${ip2} ${ip3}\nHostname: ${vm_name}.cslabs.clarkson.edu\nCPUs: ${cpus}\nRAM: ${mem}\nOS: Ubuntu 8.04\ndom0: ${dom0}\n\nMaintainer: ${user}\nEmail: ${email}\n\nIf you are unable to successfully create your new virtual machine after a second attempt or have a question, please respond to this email.\n\nThank you,\nYour friendly CSLabs VM Creator." | ${MAIL} -s "** New VM: ${vm_name} - Creation Error **" ${email},${admin_email} -- -f "${admin_email}"
  exit 1
fi

if [ -s ${conf_dir}/${vm_name} ] || [ -s ${disk_dir}/${vm_name}.disk ]
then
  ${PRINTF} "%b" "An error occurred while creating your new virtual machine.\n\nError: A VM with this name already exists.  Please choose a different name and attempt to create your VM again.\n\nError Time: ${date}\nDom0 User: ${SUDO_USER}\n\nVM Name: ${vm_name}\nIP(s): ${ip} ${ip2} ${ip3}\nHostname: ${vm_name}.cslabs.clarkson.edu\nCPUs: ${cpus}\nRAM: ${mem}\nOS: Ubuntu 8.04\ndom0: ${dom0}\n\nMaintainer: ${user}\nEmail: ${email}\n\nIf you are unable to successfully create your new virtual machine after a second attempt or have a question, please respond to this email.\n\nThank you,\nYour friendly CSLabs VM Creator." | ${MAIL} -s "** New VM: ${vm_name} - Creation Error **" ${email},${admin_email} -- -f "${admin_email}"
  exit 1
else
  ${CP} ${generic_vm} ${conf_dir}/${vm_name}
  if [ -s ${conf_dir}/${vm_name} ]
  then
    ${SED} -i "s/\"`${ECHO} "${generic_vm}" | ${AWK} 'BEGIN {FS = "/"} ; {print $NF}'`\"/\"${vm_name}\"/g" ${conf_dir}/${vm_name}
    ${SED} -i "s/maxmem = [0-9]*/maxmem = ${mem}/g" ${conf_dir}/${vm_name}
    ${SED} -i "s/memory = [0-9]*/memory = ${mem}/g" ${conf_dir}/${vm_name}
    ${SED} -i "s/vcpus = [0-9]*/vcpus = ${cpus}/g" ${conf_dir}/${vm_name}
    ${SED} -i '$d' ${conf_dir}/${vm_name}
    ${ECHO} "disk = [ \"tap:aio:${disk_dir}/${vm_name}.disk,xvda,w\" ]" >> ${conf_dir}/${vm_name}
  else
    ${PRINTF} "%b" "An error occurred while creating your new virtual machine.\n\nError: The system was unable to copy the generic config file for your VM.  Please attempt to create your VM again.\n\nError Time: ${date}\nDom0 User: ${SUDO_USER}\n\nVM Name: ${vm_name}\nIP(s): ${ip} ${ip2} ${ip3}\nHostname: ${vm_name}.cslabs.clarkson.edu\nCPUs: ${cpus}\nRAM: ${mem}\nOS: Ubuntu 8.04\ndom0: ${dom0}\n\nMaintainer: ${user}\nEmail: ${email}\n\nIf you are unable to successfully create your new virtual machine after a second attempt or have a question, please respond to this email.\n\nThank you,\nYour friendly CSLabs VM Creator." | ${MAIL} -s "** New VM: ${vm_name} - Creation Error **" ${email},${admin_email} -- -f "${admin_email}"
    ${RM} ${conf_dir}/${vm_name}
    exit 1
  fi
  ${CP} ${generic_vm}.disk ${disk_dir}/${vm_name}.disk
  if [ -s ${disk_dir}/${vm_name}.disk ]
  then
    ${ext_script_dir}/mount_disk_ubuntu.sh ${disk_dir}/${vm_name}.disk /mnt/newvm$$
    if [ -d /mnt/newvm$$ ] && [ "$(${LS} -A /mnt/newvm$$)" ]
    then
      ${CHROOT} /mnt/newvm$$ /usr/sbin/dpkg-reconfigure openssh-server
      ${CHROOT} /mnt/newvm$$ /usr/sbin/make-ssl-cert generate-default-snakeoil --force-overwrite
      ${CHROOT} /mnt/newvm$$ /bin/echo -e "${rootpass}\n${rootpass}" | ${CHROOT} /mnt/newvm$$ /usr/bin/passwd root
      ${CHROOT} /mnt/newvm$$ /usr/sbin/useradd -m ${user}
      ${CHROOT} /mnt/newvm$$ /bin/echo -e "${userpass}\n${userpass}" | ${CHROOT} /mnt/newvm$$ /usr/bin/passwd ${user}
      ${ECHO} "${user} ALL=(ALL) ALL" >> /mnt/newvm$$/etc/sudoers
      ${ECHO} -e "${vm_name}: ${rootpass} - As of ${date}\n" >> /root/vms
      ${SED} -i "s/generic-vm/${vm_name}/g" /mnt/newvm$$/etc/postfix/main.cf
      ${SED} -i "s/generic-vm/${vm_name}/g" /mnt/newvm$$/etc/mailname
      ${SED} -i "s/address 128.153.145.[0-9]*/address ${ip}/g" /mnt/newvm$$/etc/network/interfaces
      ${SED} -i "s/128.153.145.[0-9]*/${ip}/g" /mnt/newvm$$/etc/hosts
      ${SED} -i "s/generic-vm/${vm_name}/g" /mnt/newvm$$/etc/hosts
      ${SED} -i "s/generic-vm/${vm_name}/g" /mnt/newvm$$/etc/hostname
      if [[ "${ip2}" =~ "10\.0\.1\.([01]?[0-9]?[0-9]|2[0-4][0-9]|25[0-5])$" ]]
      then
	${SED} -i "s/\(vif = \[ '.*'\) \]/\1,'bridge=xenbr1' \]/g" ${conf_dir}/${vm_name}
	${ECHO} -e "\nauto eth1\niface eth1 inet static\n  address ${ip2}\n  netmask 255.255.255.0" >> /mnt/newvm$$/etc/network/interfaces
	${ECHO} "${ip2} ${vm_name}.sr.cslabs.clarkson.edu ${vm_name}.sr.cslabs ${vm_name}.sr" >> /mnt/newvm$$/etc/hosts
	${SED} -i "s/\(sshd.*\)/\1 10.0.1./g" >> /mnt/newvm$$/etc/hosts.allow
	if [[ "${ip3}" =~ "10\.0\.0\.([01]?[0-9]?[0-9]|2[0-4][0-9]|25[0-5])$" ]]
	then
	  ${SED} -i "s/\(vif = \[ '.*'\) \]/\1,'bridge=xenbr2' \]/g" ${conf_dir}/${vm_name}
	  ${ECHO} -e "\nauto eth2\niface eth2 inet static\n  address ${ip3}\n  netmask 255.255.255.0" >> /mnt/newvm$$/etc/network/interfaces
	  ${ECHO} "${ip3} ${vm_name}.int.cslabs.clarkson.edu ${vm_name}.int.cslabs ${vm_name}.int" >> /mnt/newvm$$/etc/hosts
	fi
      elif [[ "${ip2}" =~ "10\.0\.0\.([01]?[0-9]?[0-9]|2[0-4][0-9]|25[0-5])$" ]]
      then
	${SED} -i "s/\(vif = \[ '.*'\) \]/\1,'bridge=xenbr2' \]/g" ${conf_dir}/${vm_name}
	${ECHO} -e "\nauto eth1\niface eth1 inet static\n  address ${ip2}\n  netmask 255.255.255.0" >> /mnt/newvm$$/etc/network/interfaces
	${ECHO} "${ip2} ${vm_name}.int.cslabs.clarkson.edu ${vm_name}.int.cslabs ${vm_name}.int" >> /mnt/newvm$$/etc/hosts
	if [[ "${ip3}" =~ "10\.0\.1\.([01]?[0-9]?[0-9]|2[0-4][0-9]|25[0-5])$" ]]
        then
          ${SED} -i "s/\(vif = \[ '.*'\) \]/\1,'bridge=xenbr1' \]/g" ${conf_dir}/${vm_name}
	  ${ECHO} -e "\nauto eth2\niface eth2 inet static\n  address ${ip3}\n  netmask 255.255.255.0" >> /mnt/newvm$$/etc/network/interfaces
	  ${ECHO} "${ip3} ${vm_name}.sr.cslabs.clarkson.edu ${vm_name}.sr.cslabs ${vm_name}.sr" >> /mnt/newvm$$/etc/hosts
	  ${SED} -i "s/\(sshd.*\)/\1 10.0.1./g" >> /mnt/newvm$$/etc/hosts.allow
        fi
      fi
    else
      ${PRINTF} "%b" "An error occurred while creating your new virtual machine.\n\nError: The system was unable to successfully mount your VM to make needed changes.  Please attempt to create your VM again.\n\nError Time: ${date}\nDom0 User: ${SUDO_USER}\n\nVM Name: ${vm_name}\nIP(s): ${ip} ${ip2} ${ip3}\nHostname: ${vm_name}.cslabs.clarkson.edu\nCPUs: ${cpus}\nRAM: ${mem}\nOS: Ubuntu 8.04\ndom0: ${dom0}\n\nMaintainer: ${user}\nEmail: ${email}\n\nIf you are unable to successfully create your new virtual machine after a second attempt or have a question, please respond to this email.\n\nThank you,\nYour friendly CSLabs VM Creator." | ${MAIL} -s "** New VM: ${vm_name} - Creation Error **" ${email},${admin_email} -- -f "${admin_email}"
      ${ext_script_dir}/umount_disk.sh ${disk_dir}/${vm_name}.disk /mnt/newvm$$
      ${RM} ${conf_dir}/${vm_name}
      ${RM} ${disk_dir}/${vm_name}.disk
      exit 1
    fi
    ${ext_script_dir}/umount_disk.sh ${disk_dir}/${vm_name}.disk /mnt/newvm$$
    ${XM} create ${conf_dir}/${vm_name}
    ${PRINTF} "%b" "Your new virtual machine has been successfully created.\nInformation about your new virtual machine and your temporary login credentials are listed below.\n\nVM Name: ${vm_name}\nIP(s): ${ip} ${ip2} ${ip3}\nHostname: ${vm_name}.cslabs.clarkson.edu\nCPUs: ${cpus}\nRAM: ${mem}\ndom0: ${dom0}\n\nUser: ${user}\nPassword: ${userpass}\n\nYour new VM can be accessed via ssh from isengard.  SSH access should remain locked down to the 145 subnet for security reasons. Please be sure to change your password at your earliest convenience. It is also recommended that you run an apt-get update & apt-get upgrade on your VM to make sure it is fully patched\n\nIf you experience any problems or have any questions, please respond to this email.\n\nThank you,\nYour friendly CSLabs VM Creator." | ${MAIL} -s "** New VM: ${vm_name} - Created Successfully **" ${email} -- -f "${admin_email}"
    ${PRINTF} "%b" "The following new virtual machine was successfully created.\nPlease be sure to add it to Nagios, Cacti, the logwatch email account, the list of static IPs (wiki), and the list of VMs (wiki).\n\nCreated: ${date}\nDom0 User: ${SUDO_USER}\n\nVM Name: ${vm_name}\nIP(s): ${ip} ${ip2} ${ip3}\nHostname: ${vm_name}.cslabs.clarkson.edu\nCPUs: ${cpus}\nRAM: ${mem}\nOS: Ubuntu 8.04\ndom0: ${dom0}\n\nMaintainer: ${user}\nEmail: ${email}\n\nThe root password has been saved in a temporary location and should be deleted once it has been permanently recorded.\n\nThank you,\nYour friendly CSLabs VM Creator." | ${MAIL} -s "** New VM: ${vm_name} - Created Successfully **" ${admin_email} -- -f "${admin_email}"
  else
    ${PRINTF} "%b" "An error occurred while creating your new virtual machine.\n\nError: The system was unable to copy the generic image for your VM.  Please attempt to create your VM again.\n\nError Time: ${date}\nDom0 User: ${SUDO_USER}\n\nVM Name: ${vm_name}\nIP(s): ${ip} ${ip2} ${ip3}\nHostname: ${vm_name}.cslabs.clarkson.edu\nCPUs: ${cpus}\nRAM: ${mem}\nOS: Ubuntu 8.04\ndom0: ${dom0}\n\nMaintainer: ${user}\nEmail: ${email}\n\nIf you are unable to successfully create your new virtual machine after a second attempt or have a question, please respond to this email.\n\nThank you,\nYour friendly CSLabs VM Creator." | ${MAIL} -s "** New VM: ${vm_name} - Creation Error **" ${email},${admin_email} -- -f "${admin_email}"
      ${RM} ${conf_dir}/${vm_name}
      ${ext_script_dir}/umount_disk.sh ${disk_dir}/${vm_name}.disk /mnt/newvm$$
      ${RM} ${disk_dir}/${vm_name}.disk
    exit 1
  fi
fi

exit 0
