lib/rspec-system/node_set/vagrant.rb in rspec-system-0.0.2 vs lib/rspec-system/node_set/vagrant.rb in rspec-system-0.1.0
- old
+ new
@@ -1,6 +1,7 @@
require 'fileutils'
+require 'systemu'
module RSpecSystem
# A NodeSet implementation for Vagrant.
class NodeSet::Vagrant < RSpecSystem::NodeSet::Base
include RSpecSystem::Log
@@ -12,78 +13,132 @@
@vagrant_path = File.expand_path(File.join(RSpec.configuration.system_tmp, 'vagrant_projects', setname))
end
# Setup the NodeSet by starting all nodes.
def setup
- log.info "Begin setting up vagrant"
+ log.info "[Vagrant#setup] Begin setting up vagrant"
create_vagrantfile
- log.info "Running 'vagrant destroy'"
- vagrant("destroy", "--force")
+ log.info "[Vagrant#setup] Running 'vagrant destroy'"
+ vagrant("destroy --force")
- log.info "Running 'vagrant up'"
+ log.info "[Vagrant#setup] Running 'vagrant up'"
vagrant("up")
end
# Shutdown the NodeSet by shutting down or pausing all nodes.
def teardown
- log.info "Running 'vagrant destroy'"
- vagrant("destroy", "--force")
+ log.info "[Vagrant#teardown] Running 'vagrant destroy'"
+ vagrant("destroy --force")
end
# Run a command on a host in the NodeSet.
- def run(dest, command)
+ #
+ # @param opts [Hash] options
+ def run(opts)
+ #log.debug("[Vagrant#run] called with #{opts.inspect}")
+
+ dest = opts[:n].name
+ cmd = opts[:c]
+
result = ""
Dir.chdir(@vagrant_path) do
- result = `vagrant ssh #{dest} --command 'cd /tmp && #{command}'`
+ cmd = "vagrant ssh #{dest} --command \"cd /tmp && sudo -i #{cmd}\""
+ log.debug("[vagrant#run] Running command: #{cmd}")
+ result = systemu cmd
+ log.debug("[Vagrant#run] Finished running command: #{cmd}. Result is #{result}.")
end
result
end
+ # Transfer files to a host in the NodeSet.
+ #
+ # @param opts [Hash] options
+ def rcp(opts)
+ #log.debug("[Vagrant@rcp] called with #{opts.inspect}")
+
+ dest = opts[:d].name
+ source = opts[:sp]
+ dest_path = opts[:dp]
+
+ # TODO: This is damn ugly, because we ssh in as vagrant, we copy to a
+ # temp path then move later. This pattern at the moment only really works
+ # on dirs.
+ log.info("[Vagrant#rcp] Transferring files from #{source} to #{dest}:#{dest_path}")
+
+ # TODO: The static temp path here is definately insecure
+ cmd = "scp -r -F #{ssh_config} #{source} #{dest}:/tmp/tmpxfer"
+ log.debug("[Vagrant#rcp] Running command: #{cmd}")
+ systemu cmd
+
+ # Now we move the file into place
+ run(:n => opts[:d], :c => "mv /tmp/tmpxfer #{dest_path}")
+ end
+
# Create the Vagrantfile for the NodeSet.
+ #
# @api private
def create_vagrantfile
- log.info "Creating vagrant file here: #{@vagrant_path}"
+ log.info "[Vagrant#create_vagrantfile] Creating vagrant file here: #{@vagrant_path}"
FileUtils.mkdir_p(@vagrant_path)
File.open(File.expand_path(File.join(@vagrant_path, "Vagrantfile")), 'w') do |f|
f.write('Vagrant::Config.run do |c|')
- @config['nodes'].each do |k,v|
+ nodes.each do |k,v|
log.debug "Filling in content for #{k}"
f.write(<<-EOS)
c.vm.define '#{k}' do |vmconf|
-#{template_prefabs(v["prefab"])}
+ vmconf.vm.host_name = "#{k}"
+#{template_node(v.provider_specifics['vagrant'])}
end
EOS
end
f.write('end')
end
- log.debug "Finished creating vagrant file"
+ log.debug "[Vagrant#create_vagrantfile] Finished creating vagrant file"
end
- # Provide Vagrantfile templates for prefabs.
+ # Here we get vagrant to drop the ssh_config its using so we can monopolize
+ # it for transfers and custom stuff. We drop it into a single file, and
+ # since its indexed based on our own node names its quite ideal.
+ #
# @api private
- def template_prefabs(prefab)
- case prefab
- when 'centos-58-x64'
- <<-EOS
- vmconf.vm.box = 'centos-58-x64'
- vmconf.vm.box_url = 'http://puppet-vagrant-boxes.puppetlabs.com/centos-58-x64.box'
- EOS
- when 'debian-606-x64'
- <<-EOS
- vmconf.vm.box = 'debian-606-x64'
- vmconf.vm.box_url = 'http://puppet-vagrant-boxes.puppetlabs.com/debian-606-x64.box'
- EOS
- else
- raise 'Unknown prefab'
+ def ssh_config
+ ssh_config_path = File.expand_path(File.join(@vagrant_path, "ssh_config"))
+ begin
+ File.unlink(ssh_config_path)
+ rescue Errno::ENOENT
end
+ self.nodes.each do |k,v|
+ Dir.chdir(@vagrant_path) do
+ result = systemu("vagrant ssh-config #{k} >> #{ssh_config_path}")
+ puts result.inspect
+ end
+ end
+ ssh_config_path
end
+ # Provide Vagrantfile templates from node definition.
+ #
+ # @api private
+ # @param settings [Hash] provider specific settings for vagrant
+ def template_node(settings)
+ template = <<-EOS
+ vmconf.vm.box = '#{settings['box']}'
+ vmconf.vm.box_url = '#{settings['box_url']}'
+ EOS
+ end
+
# Execute vagrant command in vagrant_path
+ #
# @api private
- def vagrant(*args)
+ # @param args [String] args to vagrant
+ # @todo This seems a little too specific these days, might want to
+ # generalize. It doesn't use systemu, because we want to see the output
+ # immediately, but still - maybe we can make systemu do that.
+ def vagrant(args)
Dir.chdir(@vagrant_path) do
- system("vagrant", *args)
+ system("vagrant #{args}")
end
+ nil
end
end
end