Provisioning action

This commit is contained in:
Mitchell Hashimoto 2010-02-15 15:07:27 -08:00
parent 86524048ae
commit e8df988d94
3 changed files with 77 additions and 81 deletions

View File

@ -0,0 +1,56 @@
module Vagrant
module Actions
class Provision < Base
def execute!
chown_provisioning_folder
setup_json
setup_solo_config
run_chef_solo
end
def chown_provisioning_folder
logger.info "Setting permissions on provisioning folder..."
SSH.execute do |ssh|
ssh.exec!("sudo chown #{Vagrant.config.ssh.username} #{Vagrant.config.chef.provisioning_path}")
end
end
def setup_json
logger.info "Generating JSON and uploading..."
json = { :project_directory => Vagrant.config.vm.project_directory }.merge(Vagrant.config.chef.json).to_json
SSH.upload!(StringIO.new(json), File.join(Vagrant.config.chef.provisioning_path, "dna.json"))
end
def setup_solo_config
solo_file = <<-solo
file_cache_path "#{Vagrant.config.chef.provisioning_path}"
cookbook_path "#{cookbooks_path}"
solo
logger.info "Uploading chef-solo configuration script..."
SSH.upload!(StringIO.new(solo_file), File.join(Vagrant.config.chef.provisioning_path, "solo.rb"))
end
def run_chef_solo
logger.info "Running chef recipes..."
SSH.execute do |ssh|
ssh.exec!("cd #{Vagrant.config.chef.provisioning_path} && sudo chef-solo -c solo.rb -j dna.json") do |channel, data, stream|
# TODO: Very verbose. It would be easier to save the data and only show it during
# an error, or when verbosity level is set high
logger.info("#{stream}: #{data}")
end
end
end
def cookbooks_path
File.join(Vagrant.config.chef.provisioning_path, "cookbooks")
end
def collect_shared_folders
["vagrant-provisioning", File.expand_path(Vagrant.config.chef.cookbooks_path, Env.root_path), cookbooks_path]
end
end
end
end

View File

@ -1,60 +0,0 @@
module Vagrant
class Provisioning
include Vagrant::Util
def initialize(vm)
@vm = vm
# Share the cookbook folder. We'll use the provisioning path exclusively for
# chef stuff.
@vm.share_folder("vagrant-provisioning", File.expand_path(Vagrant.config.chef.cookbooks_path, Env.root_path), cookbooks_path)
end
def run
chown_provisioning_folder
setup_json
setup_solo_config
run_chef_solo
end
def chown_provisioning_folder
logger.info "Setting permissions on provisioning folder..."
SSH.execute do |ssh|
ssh.exec!("sudo chown #{Vagrant.config.ssh.username} #{Vagrant.config.chef.provisioning_path}")
end
end
def setup_json
logger.info "Generating JSON and uploading..."
json = { :project_directory => Vagrant.config.vm.project_directory }.merge(Vagrant.config.chef.json).to_json
SSH.upload!(StringIO.new(json), File.join(Vagrant.config.chef.provisioning_path, "dna.json"))
end
def setup_solo_config
solo_file = <<-solo
file_cache_path "#{Vagrant.config.chef.provisioning_path}"
cookbook_path "#{cookbooks_path}"
solo
logger.info "Uploading chef-solo configuration script..."
SSH.upload!(StringIO.new(solo_file), File.join(Vagrant.config.chef.provisioning_path, "solo.rb"))
end
def run_chef_solo
logger.info "Running chef recipes..."
SSH.execute do |ssh|
ssh.exec!("cd #{Vagrant.config.chef.provisioning_path} && sudo chef-solo -c solo.rb -j dna.json") do |channel, data, stream|
# TODO: Very verbose. It would be easier to save the data and only show it during
# an error, or when verbosity level is set high
logger.info("#{stream}: #{data}")
end
end
end
def cookbooks_path
File.join(Vagrant.config.chef.provisioning_path, "cookbooks")
end
end
end

View File

@ -1,27 +1,27 @@
require File.join(File.dirname(__FILE__), '..', 'test_helper') require File.join(File.dirname(__FILE__), '..', '..', 'test_helper')
class ProvisioningTest < Test::Unit::TestCase class ProvisionActionTest < Test::Unit::TestCase
setup do setup do
# Stub upload so nothing happens @mock_vm, @vm, @action = mock_action(Vagrant::Actions::Provision)
Vagrant::SSH.stubs(:execute)
Vagrant::SSH.stubs(:upload!) Vagrant::SSH.stubs(:upload!)
vm = mock("vm") mock_config
vm.stubs(:share_folder)
@prov = Vagrant::Provisioning.new(vm)
end end
context "initializing" do context "shared folders" do
should "setup shared folder on VM for the cookbooks" do should "setup shared folder on VM for the cookbooks" do
File.expects(:expand_path).with(Vagrant.config.chef.cookbooks_path, Vagrant::Env.root_path).returns("foo") File.expects(:expand_path).with(Vagrant.config.chef.cookbooks_path, Vagrant::Env.root_path).returns("foo")
Vagrant::Provisioning.any_instance.expects(:cookbooks_path).returns("bar") @action.expects(:cookbooks_path).returns("bar")
vm = mock("vm") assert_equal ["vagrant-provisioning", "foo", "bar"], @action.collect_shared_folders
vm.expects(:share_folder).with("vagrant-provisioning", "foo", "bar") end
Vagrant::Provisioning.new(vm)
end end
context "cookbooks path" do
should "return the proper cookbook path" do should "return the proper cookbook path" do
cookbooks_path = File.join(Vagrant.config.chef.provisioning_path, "cookbooks") cookbooks_path = File.join(Vagrant.config.chef.provisioning_path, "cookbooks")
assert_equal cookbooks_path, @prov.cookbooks_path assert_equal cookbooks_path, @action.cookbooks_path
end end
end end
@ -30,14 +30,14 @@ class ProvisioningTest < Test::Unit::TestCase
ssh = mock("ssh") ssh = mock("ssh")
ssh.expects(:exec!).with("sudo chown #{Vagrant.config.ssh.username} #{Vagrant.config.chef.provisioning_path}") ssh.expects(:exec!).with("sudo chown #{Vagrant.config.ssh.username} #{Vagrant.config.chef.provisioning_path}")
Vagrant::SSH.expects(:execute).yields(ssh) Vagrant::SSH.expects(:execute).yields(ssh)
@prov.chown_provisioning_folder @action.chown_provisioning_folder
end end
end end
context "generating and uploading json" do context "generating and uploading json" do
should "convert the JSON config to JSON" do should "convert the JSON config to JSON" do
Hash.any_instance.expects(:to_json).once.returns("foo") Hash.any_instance.expects(:to_json).once.returns("foo")
@prov.setup_json @action.setup_json
end end
should "add the project directory to the JSON" do should "add the project directory to the JSON" do
@ -47,14 +47,14 @@ class ProvisioningTest < Test::Unit::TestCase
true true
end end
@prov.setup_json @action.setup_json
end end
should "upload a StringIO to dna.json" do should "upload a StringIO to dna.json" do
StringIO.expects(:new).with(anything).returns("bar") StringIO.expects(:new).with(anything).returns("bar")
File.expects(:join).with(Vagrant.config.chef.provisioning_path, "dna.json").once.returns("baz") File.expects(:join).with(Vagrant.config.chef.provisioning_path, "dna.json").once.returns("baz")
Vagrant::SSH.expects(:upload!).with("bar", "baz").once Vagrant::SSH.expects(:upload!).with("bar", "baz").once
@prov.setup_json @action.setup_json
end end
end end
@ -62,19 +62,19 @@ class ProvisioningTest < Test::Unit::TestCase
should "upload properly generate the configuration file using configuration data" do should "upload properly generate the configuration file using configuration data" do
expected_config = <<-config expected_config = <<-config
file_cache_path "#{Vagrant.config.chef.provisioning_path}" file_cache_path "#{Vagrant.config.chef.provisioning_path}"
cookbook_path "#{@prov.cookbooks_path}" cookbook_path "#{@action.cookbooks_path}"
config config
StringIO.expects(:new).with(expected_config).once StringIO.expects(:new).with(expected_config).once
@prov.setup_solo_config @action.setup_solo_config
end end
should "upload this file as solo.rb to the provisioning folder" do should "upload this file as solo.rb to the provisioning folder" do
@prov.expects(:cookbooks_path).returns("cookbooks") @action.expects(:cookbooks_path).returns("cookbooks")
StringIO.expects(:new).returns("foo") StringIO.expects(:new).returns("foo")
File.expects(:join).with(Vagrant.config.chef.provisioning_path, "solo.rb").once.returns("bar") File.expects(:join).with(Vagrant.config.chef.provisioning_path, "solo.rb").once.returns("bar")
Vagrant::SSH.expects(:upload!).with("foo", "bar").once Vagrant::SSH.expects(:upload!).with("foo", "bar").once
@prov.setup_solo_config @action.setup_solo_config
end end
end end
@ -83,7 +83,7 @@ config
ssh = mock("ssh") ssh = mock("ssh")
ssh.expects(:exec!).with("cd #{Vagrant.config.chef.provisioning_path} && sudo chef-solo -c solo.rb -j dna.json").once ssh.expects(:exec!).with("cd #{Vagrant.config.chef.provisioning_path} && sudo chef-solo -c solo.rb -j dna.json").once
Vagrant::SSH.expects(:execute).yields(ssh) Vagrant::SSH.expects(:execute).yields(ssh)
@prov.run_chef_solo @action.run_chef_solo
end end
end end
end end