automating vmware guest deployment with capistrano

This will get some more work, but I didn’t find much out there so this is a good starting point for someone

It appears straightforward enough, but feel free to ask any questions. You’ll need the rest of your operations platform pre-built, such as existing vmware hosts, pxe booting a debian install, etc.

I don’t think blogger is killing anything important. Some day I’ll setup an actual repository instead of using blogger for this crap. On the new server, next vacation. 🙂


# Capistrano recipe to build a vmware guest
# Bryan McLellan -- bryanm@widemile.com

require 'erb'

logger.info("Vmware guest creation script logs in as root")
set(:user, "root")

vmxtemplate = %q{
#!/usr/bin/vmware
config.version = "8"
virtualHW.version = "4"
scsi0.present = "TRUE"
scsi0.virtualDev = "<%=disktype %>"
scsi0:0.present = "TRUE"
scsi0:0.redo = ""
priority.grabbed = "normal"
priority.ungrabbed = "normal"
guestOS = "other26xlinux-64"
ide1:0.startConnected = "FALSE"
floppy0.startConnected = "FALSE"

displayName = "<%=fqdn %>"
scsi0:0.fileName = "<%=fqdn %>.vmdk"
memsize = "<%=memory %>"

Ethernet0.present = "TRUE"
Ethernet0.virtualDev = "e1000"
ethernet0.addressType = "generated"
ethernet0.generatedAddressOffset = "0"
Ethernet0.connectionType = "custom"
Ethernet0.vnet = "<%=eth0 %>"

Ethernet1.present = "TRUE"
Ethernet1.virtualDev = "e1000"
ethernet1.addressType = "generated"
ethernet1.generatedAddressOffset = "10"
Ethernet1.connectionType = "custom"
Ethernet1.vnet = "<%=eth1 %>"

tools.syncTime = "TRUE"
}

pxetemplate = %q{
DEFAULT etch_i386_install_auto
TIMEOUT 100

LABEL etch_i386_install_auto
kernel debian/etch/i386/linux
append vga=normal initrd=debian/etch/i386/initrd.gz preseed/url=http://debian.example.org/preseed/autoserver-etch.cfg debian-installer/locale=en_US console-keymaps-at/keymap=us hostname=<%=hostname %> domain=<%=domain %> interface=eth0 --
}

def lastdhcpip(ourmac)
curLeaseIp = nil
curLeaseMac = nil
lastip = nil

f = File.open("/var/lib/dhcp/dhcpd.leases")
f.each do |line|
case line
when /lease (.*) \{/
curLeaseIp = $1
when /hardware ethernet (.*);/
curLeaseMac = $1
if ourmac == curLeaseMac
lastip = curLeaseIp
end
end
end

f.close
return lastip
end

set(:disktype, "lsilogic")
set(:disksize, "3Gb")
set(:memory, "768")

#set(:hostname, fqdn.match(/^[0-9A-Za-z-]*/))
#puts("hostname: #{hostname}")

task :build, :roles => :host do
set(:host) do
Capistrano::CLI.ui.ask "vmware hostname: "
end unless exists?(:host)

role :host, host

set(:hostname) do
Capistrano::CLI.ui.ask "guest hostname (vm16-dev-ots04): "
end unless exists?(:hostname)

set(:network) do
Capistrano::CLI.ui.ask "guest network (prod/corp/test): "
end unless exists?(:network)

case network
when /prod/
set(:fqdn, "#{hostname}.prod.example.org")
set(:domain, "prod.example.org")
set(:eth0, "/dev/vmnet4")
set(:eth1, "/dev/vmnet11")
when /corp/
set(:fqdn, "#{hostname}.corp.example.org")
set(:domain, "corp.example.org")
set(:eth0, "/dev/vmnet0")
set(:eth1, "/dev/vmnet0")
when /test/
set(:fqdn, "#{hostname}.test.example.org")
set(:domain, "test.example.org")
set(:eth0, "/dev/vmnet2")
set(:eth1, "/dev/vmnet14")
end
puts("fqdn: #{fqdn}")

result = ERB.new(vmxtemplate).result(binding)

run("mkdir /srv/vmware/#{fqdn}")
logger.info("Building vmx configuration file")
put(result, "/srv/vmware/#{fqdn}/#{fqdn}.vmx", :mode => 0755)

logger.info("Creating virtual disk")
run("/usr/bin/vmware-vdiskmanager -c -a #{disktype} -s #{disksize} -t 2 /srv/vmware/#{fqdn}/#{fqdn}.vmdk")

# start and stop vm to generate uuid and MACs
logger.info("starting VM")
#run("/usr/bin/vmware-cmd -s unregister /srv/vmware/#{fqdn}/#{fqdn}.vmx")
run("/usr/bin/vmware-cmd -s register /srv/vmware/#{fqdn}/#{fqdn}.vmx")
run("/usr/bin/vmware-cmd /srv/vmware/#{fqdn}/#{fqdn}.vmx start")
sleep 1
run("/usr/bin/vmware-cmd /srv/vmware/#{fqdn}/#{fqdn}.vmx stop hard")
macaddr0 = nil
run("cat /srv/vmware/#{fqdn}/#{fqdn}.vmx") do |ch, stream, data|
case data
when /ethernet0.generatedAddress = "(.+)"/
macaddr0 = $1
end
end
macaddr0dash = macaddr0.gsub(/:/, "-");

pxeConfig = File.new("/srv/tftp/pxelinux.cfg/01-#{macaddr0dash}", "w", 0644)
result = ERB.new(pxetemplate).result(binding)
pxeConfig.puts(result)
pxeConfig.close

# Box gets a different ip sometimes on install than on first boot. annoying
run("/usr/bin/vmware-cmd /srv/vmware/#{fqdn}/#{fqdn}.vmx start")
logger.info("Sleeping 30 seconds for network startup")
sleep 30
ipaddr0 = lastdhcpip(macaddr0)
logger.info("host #{fqdn} is now building and we be available at #{ipaddr0}")
File.delete("/srv/tftp/pxelinux.cfg/01-#{macaddr0dash}")
end

2 thoughts on “automating vmware guest deployment with capistrano

  1. theinventor

    what kind of things do you use vmware for? I myself have domain controllers and reporting boxes on it.. are you automating development environments? staging? i’m looking for more uses..

  2. btm

    Everything possible these days. Mostly debian linux guests, running our products, as well as filling IT needs such as anti-spam mail gateways, web servers, file servers, etc.

    Everything that isn’t super memory/processor intensive goes in a guest, so we can move them around the blades to actually take use of these fancy new dual processor quad core blades and whatnot.

    Everything that we’re going to make more than one of I try to get into puppet.

Leave a Reply

Your email address will not be published. Required fields are marked *

Time limit is exhausted. Please reload the CAPTCHA.