Skip to content

Instantly share code, notes, and snippets.

@erikh
Created April 29, 2013 01:41
Show Gist options
  • Save erikh/5479244 to your computer and use it in GitHub Desktop.
Save erikh/5479244 to your computer and use it in GitHub Desktop.
#!ruby
#
# small vagrant wannabe. uses ova files, imports the box if necessary, starts
# boxes if they aren't already started and starts a port forward based on their
# number. Does this in nice multithreaded ways so you could, you know, get more
# things done in less time.
#
# Cleaning up machines isn't solved -- you'll need to do that in the vbox
# console atm.
#
# usage: ruby <script> <machine count> <base port for forwarding>
#
require 'timeout'
require 'thread'
require 'socket'
$mutex = Mutex.new
def log(text)
$mutex.synchronize do
puts text
end
rescue ThreadError
puts text
end
def run(operation, command)
log operation + "..." if operation
rd, wr = IO.pipe
pid = Process.spawn(
{},
command,
:in => :close,
:out => wr,
:err => wr,
:close_others => true
)
unless Process.waitpid2(pid).last.exitstatus == 0
raise command + " failed"
end
wr.close
str = rd.read
rd.close
log "done performing '#{operation}'." if operation
return str
end
number, box, base_port = ARGV
number = number ? number.to_i : 1
box ||= "box-test"
base_port = base_port ? base_port.to_i : 2200
output = run nil, "VBoxManage list vms"
boxes = output.split(/\n/).map { |s| s.match(/^"([^"]+)"/)[1] rescue nil }.compact
unless boxes.include?(box)
run "importing box #{box}", "VBoxManage import '#{box}.ova' --vsys 0 -vmname '#{box}' --options keepnatmacs"
end
threads =
(1..number).map do |n|
Thread.new do
box_name = "#{box}-#{n}"
port = (base_port + n).to_s # FIXME no bind check yet, so this could break.
unless boxes.include?(box_name)
run "cloning #{box} for vm #{n}", "VBoxManage clonevm #{box} --options keepnatmacs --name #{box_name}"
run "registering #{box} vm #{n}", "VBoxManage registervm ~/VirtualBox\\ VMs/#{box_name}/#{box_name}.vbox"
run "configuring #{box_name} port forward for #{port}", "VBoxManage modifyvm #{box_name} --natpf1 ssh-forward,tcp,,#{port},,22"
run "starting box #{box} ##{n}", "VBoxManage startvm #{box_name} --type headless"
begin
log "checking port forward for #{port}"
socket = TCPSocket.open("localhost", port)
socket.recv(1)
rescue => e
sleep 5
retry
end
end
true
end
end
threads.all?(&:value)
exit 0
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment