scribble

Managing Chaos

About Skills Rabbit Holes Email GitHub

21 Oct 2014
Proxmox - Automatic Provisioning


Having the ability to rapidly provision VMs into a Proxmox environment in a repeatable, scriptable, versionable way is of great advantage.

To this end I created a script to do just that. This scipt will need a “base vm” to copy and then modify, and I will admit I don’t like that aspect.


#!/bin/bash

DEFAULT_DISK_SIZE=32
DEFAULT_MEMORY=2048
DEFAULT_SOCKETS=1
DEFAULT_CORES=2
DEFAULT_ISO='ubuntu-14.04-server-amd64.iso'
DEFAULT_VMBR='vmbr0'

# download jq parser
if [[ ! -f /usr/bin/jq ]]; then
    /usr/bin/wget http://stedolan.github.io/jq/download/linux64/jq -P /usr/bin
    /bin/chmod u+x /usr/bin/jq
fi

usage() {
  echo -e "Pass required options to vm_create \n-n {nodename}\n-d {disk size - in GBs, ONLY numeric value}\n-h {hostname}\n-b {vmbr[0-9]}\n-m {memory - in MBs, ONLY numeric value)\n-s {sockets}\n-c {cores}"
  exit 1
}

if (($# == 0)); then
  usage
fi

while getopts ":n:d:b:h:m:s:c:" opt; do
  case $opt in
    n)
      NODE=$OPTARG
      #echo "-n was triggered, Parameter: $OPTARG" >&2
      ;;
    d)
      SIZE=$OPTARG
      #echo "-s was triggered, Parameter: $OPTARG" >&2
      ;;
    b)
      VMBR=$OPTARG
      #echo "-b was triggered, Parameter: $OPTARG" >&2
      ;;
    h)
      HOSTNAME=$OPTARG
      #echo "-s was triggered, Parameter: $OPTARG" >&2
      ;;
    m)
      MEMORY=$OPTARG
      #echo "-s was triggered, Parameter: $OPTARG" >&2
      ;;
    s)
      SOCKETS=$OPTARG
      #echo "-s was triggered, Parameter: $OPTARG" >&2
      ;;
    c)
      CORES=$OPTARG
      #echo "-s was triggered, Parameter: $OPTARG" >&2
      ;;
    \?)
      echo "Invalid option: -$OPTARG" >&2
      usage
      exit 1
      ;;
    :)
      echo "Option -$OPTARG requires an argument." >&2
      exit 1
      ;;
  esac
done

create_base_vm(){
  # get next available vmid
  echo "Getting next available vm id..."
  VMID=`/usr/bin/pvesh get /cluster/nextid | tr -d '"'`

  # create storage
  echo "Creating vm storage object..."
  /usr/bin/pvesh create /nodes/$NODE/storage/local/content \
  -filename vm-$VMID-disk-0.qcow2 \
  -format qcow2 \
  -size $DEFAULT_DISK_SIZE"G" \
  -vmid $VMID

  # create vm
  echo "Creating VM..."
  pvesh create /nodes/$NODE/qemu \
  -name 'base.example.com' \
  -vmid $VMID \
  -memory $DEFAULT_MEMORY \
  -sockets $DEFAULT_SOCKETS \
  -cores $DEFAULT_CORES \
  -net0 virtio,bridge=$DEFAULT_VMBR \
  -virtio0 local:$VMID/vm-$VMID-disk-0.qcow2 \
  -ide1 isostore:iso/$DEFAULT_ISO,media=cdrom
}

check_for_base_vm(){
  /usr/bin/pvesh get /nodes/$NODE/qemu | jq '.[] | {name: .name, vmid: .vmid} | tostring' | grep 'base.example.com'
}

clone_base_vm(){
  # get base vmid
  VMID=`/usr/bin/pvesh get /nodes/$NODE/qemu | /usr/bin/jq '.[] | {name: .name, vmid: .vmid} | tostring' | grep 'base.example.com' | grep -o '[0-9]*'`

  # get next vmid
  NEXTID=`/usr/bin/pvesh get /cluster/nextid | grep -o '[0-9]*'`

  # clone base vm
  /usr/bin/pvesh create /nodes/$NODE/qemu/$VMID/clone -newid $NEXTID -name $HOSTNAME
}

configure_cloned_vm(){
  # tweak needed settings
  if [[ $SIZE -gt $DEFAULT_DISK_SIZE ]]; then
    echo -e "\nUpdating disk size..."
    /usr/bin/pvesh set /nodes/$NODE/qemu/$NEXTID/resize -disk virtio0 -size $SIZE"G"
  fi

  if [[ $MEMORY -gt $DEFAULT_MEMORY ]]; then
    echo -e "\nUpdating memory..."
    /usr/bin/pvesh create /nodes/$NODE/qemu/$NEXTID/config -memory $MEMORY
  fi

  if [[ $VMBR != $DEFAULT_VMBR ]]; then
    echo -e "\nUpdating network bridge..."
    /usr/bin/pvesh create /nodes/$NODE/qemu/$NEXTID/config -net0 $VMBR
  fi

  if [[ $SOCKETS -gt $DEFAULT_SOCKETS ]]; then
    echo -e "\nUpdating socket count..."
    /usr/bin/pvesh create /nodes/$NODE/qemu/$NEXTID/config -sockets $SOCKETS
  fi

  if [[ $CORES -gt $DEFAULT_CORES ]]; then
    echo -e "\nUpdating core count..."
    /usr/bin/pvesh create /nodes/$NODE/qemu/$NEXTID/config -cores $CORES
  fi
}

if check_for_base_vm; then
  clone_base_vm
  configure_cloned_vm
  exit 0
else
  create_base_vm
  echo -e "\n***Now connect to base.example.com and configure as needed. Then run this script again.***"
  exit 1
fi

Til next time,
Travis Dolan at 02:36

scribble

About Skills Rabbit Holes Email GitHub