Class: ChefMetal::Provisioner::VagrantProvisioner
- Inherits:
-
ChefMetal::Provisioner
- Object
- ChefMetal::Provisioner
- ChefMetal::Provisioner::VagrantProvisioner
- Includes:
- Chef::Mixin::ShellOut
- Defined in:
- lib/chef_metal/provisioner/vagrant_provisioner.rb
Overview
Provisions machines in vagrant.
Instance Attribute Summary collapse
-
#cluster_path ⇒ Object
readonly
Returns the value of attribute cluster_path.
Class Method Summary collapse
-
.inflate(node) ⇒ Object
Inflate a provisioner from node information; we don’t want to force the driver to figure out what the provisioner really needs, since it varies from provisioner to provisioner.
-
.vagrant_config_string(vagrant_config, variable, line_prefix) ⇒ Object
Used by vagrant_cluster and machine to get the string used to configure vagrant.
Instance Method Summary collapse
-
#acquire_machine(action_handler, node) ⇒ Object
Acquire a machine, generally by provisioning it.
-
#connect_to_machine(node) ⇒ Object
Connect to machine without acquiring it.
- #delete_machine(action_handler, node) ⇒ Object
-
#initialize(cluster_path) ⇒ VagrantProvisioner
constructor
Create a new vagrant provisioner.
- #stop_machine(action_handler, node) ⇒ Object
Methods inherited from ChefMetal::Provisioner
Constructor Details
#initialize(cluster_path) ⇒ VagrantProvisioner
Create a new vagrant provisioner.
## Parameters cluster_path - path to the directory containing the vagrant files, which
should have been created with the vagrant_cluster resource.
16 17 18 |
# File 'lib/chef_metal/provisioner/vagrant_provisioner.rb', line 16 def initialize(cluster_path) @cluster_path = cluster_path end |
Instance Attribute Details
#cluster_path ⇒ Object (readonly)
Returns the value of attribute cluster_path.
20 21 22 |
# File 'lib/chef_metal/provisioner/vagrant_provisioner.rb', line 20 def cluster_path @cluster_path end |
Class Method Details
.inflate(node) ⇒ Object
Inflate a provisioner from node information; we don’t want to force the driver to figure out what the provisioner really needs, since it varies from provisioner to provisioner.
## Parameters node - node to inflate the provisioner for
returns a VagrantProvisioner
30 31 32 33 34 |
# File 'lib/chef_metal/provisioner/vagrant_provisioner.rb', line 30 def self.inflate(node) node_url = node['normal']['provisioner_output']['provisioner_url'] cluster_path = node_url.split(':', 2)[1].sub(/^\/\//, "") self.new(cluster_path) end |
.vagrant_config_string(vagrant_config, variable, line_prefix) ⇒ Object
Used by vagrant_cluster and machine to get the string used to configure vagrant
196 197 198 199 200 201 202 203 204 |
# File 'lib/chef_metal/provisioner/vagrant_provisioner.rb', line 196 def self.vagrant_config_string(vagrant_config, variable, line_prefix) hostname = name.gsub(/[^A-Za-z0-9\-]/, '-') result = '' vagrant_config.each_pair do |key, value| result += "#{line_prefix}#{variable}.#{key} = #{value.inspect}\n" end result end |
Instance Method Details
#acquire_machine(action_handler, node) ⇒ Object
Acquire a machine, generally by provisioning it. Returns a Machine object pointing at the machine, allowing useful actions like setup, converge, execute, file and directory. The Machine object will have a “node” property which must be saved to the server (if it is any different from the original node object).
## Parameters action_handler - the action_handler object that is calling this method; this
is generally a action_handler, but could be anything that can support the
ChefMetal::ActionHandler interface (i.e., in the case of the test
kitchen driver for acquiring and VMs; see the base
class for what needs providing).
node - node object (deserialized json) representing this machine. If
the node has a hash in it, these will be used
instead of provided by the provisioner. TODO compare and
fail if different?
node will have node['normal']['provisioner_options'] in it with any .
It is a hash with this format:
-- provisioner_url: vagrant:<cluster_path>
-- vagrant_options: hash of properties of the "config"
object, i.e. "vm.box" => "ubuntu12" and "vm.box_url"
-- vagrant_config: string containing other vagrant config.
Should assume the variable "config" represents machine config.
Will be written verbatim into the vm's Vagrantfile.
-- transport_options: hash of options specifying the transport.
:type => :ssh
:type => :winrm
If not specified, ssh is used unless vm.guest is :windows. If that is
the case, the windows options are used and the port forward for 5985
is detected.
-- up_timeout: maximum time, in seconds, to wait for vagrant
to bring up the machine. Defaults to 10 minutes.
node['normal']['provisioner_output'] will be populated with information
about the created machine. For vagrant, it is a hash with this
format:
-- provisioner_url: vagrant_cluster://<current_node>/<cluster_path>
-- vm_name: name of vagrant vm created
-- vm_file_path: path to machine-specific vagrant config file
on disk
-- forwarded_ports: hash with key as guest_port => host_port
80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 |
# File 'lib/chef_metal/provisioner/vagrant_provisioner.rb', line 80 def acquire_machine(action_handler, node) # Set up the modified node data = node['normal']['provisioner_options'] vm_name = node['name'] old_provisioner_output = node['normal']['provisioner_output'] node['normal']['provisioner_output'] = provisioner_output = { 'provisioner_url' => provisioner_url(action_handler), 'vm_name' => vm_name, 'vm_file_path' => File.join(cluster_path, "#{vm_name}.vm") } # Preserve existing forwarded ports provisioner_output['forwarded_ports'] = old_provisioner_output['forwarded_ports'] if old_provisioner_output # TODO compare new options to existing and fail if we cannot change it # over (perhaps introduce a boolean that will force a delete and recreate # in such a case) # Determine contents of vm file vm_file_content = "Vagrant.configure('2') do |outer_config|\n" vm_file_content << " outer_config.vm.define #{vm_name.inspect} do |config|\n" = { 'vm.hostname' => node['name'] } .merge!(['vagrant_options']) if ['vagrant_options'] .each_pair do |key, value| vm_file_content << " config.#{key} = #{value.inspect}\n" end vm_file_content << ['vagrant_config'] if ['vagrant_config'] vm_file_content << " end\nend\n" # Set up vagrant file vm_file = ChefMetal.inline_resource(action_handler) do file provisioner_output['vm_file_path'] do content vm_file_content action :create end end # Check current status of vm current_status = vagrant_status(vm_name) up_timeout = ['up_timeout'] || 10*60 if current_status != 'running' # Run vagrant up if vm is not running action_handler.perform_action "run vagrant up #{vm_name} (status was '#{current_status}')" do result = shell_out("vagrant up #{vm_name}", :cwd => cluster_path, :timeout => up_timeout) if result.exitstatus != 0 raise "vagrant up #{vm_name} failed!\nSTDOUT:#{result.stdout}\nSTDERR:#{result.stderr}" end parse_vagrant_up(result.stdout, node) end elsif vm_file.updated_by_last_action? # Run vagrant reload if vm is running and vm file changed action_handler.perform_action "run vagrant reload #{vm_name}" do result = shell_out("vagrant reload #{vm_name}", :cwd => cluster_path, :timeout => up_timeout) if result.exitstatus != 0 raise "vagrant reload #{vm_name} failed!\nSTDOUT:#{result.stdout}\nSTDERR:#{result.stderr}" end parse_vagrant_up(result.stdout, node) end end # Create machine object for callers to use machine_for(node) end |
#connect_to_machine(node) ⇒ Object
Connect to machine without acquiring it
145 146 147 |
# File 'lib/chef_metal/provisioner/vagrant_provisioner.rb', line 145 def connect_to_machine(node) machine_for(node) end |
#delete_machine(action_handler, node) ⇒ Object
149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 |
# File 'lib/chef_metal/provisioner/vagrant_provisioner.rb', line 149 def delete_machine(action_handler, node) if node['normal'] && node['normal']['provisioner_output'] provisioner_output = node['normal']['provisioner_output'] else provisioner_output = {} end vm_name = provisioner_output['vm_name'] || node['name'] current_status = vagrant_status(vm_name) if current_status != 'not created' action_handler.perform_action "run vagrant destroy -f #{vm_name} (status was '#{current_status}')" do result = shell_out("vagrant destroy -f #{vm_name}", :cwd => cluster_path) if result.exitstatus != 0 raise "vagrant destroy failed!\nSTDOUT:#{result.stdout}\nSTDERR:#{result.stderr}" end end end convergence_strategy_for(node).cleanup_convergence(action_handler, node) vm_file_path = provisioner_output['vm_file_path'] || File.join(cluster_path, "#{vm_name}.vm") ChefMetal.inline_resource(action_handler) do file vm_file_path do action :delete end end end |
#stop_machine(action_handler, node) ⇒ Object
176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 |
# File 'lib/chef_metal/provisioner/vagrant_provisioner.rb', line 176 def stop_machine(action_handler, node) if node['normal'] && node['normal']['provisioner_output'] provisioner_output = node['normal']['provisioner_output'] else provisioner_output = {} end vm_name = provisioner_output['vm_name'] || node['name'] current_status = vagrant_status(vm_name) if current_status == 'running' action_handler.perform_action "run vagrant halt #{vm_name} (status was '#{current_status}')" do result = shell_out("vagrant halt #{vm_name}", :cwd => cluster_path) if result.exitstatus != 0 raise "vagrant halt failed!\nSTDOUT:#{result.stdout}\nSTDERR:#{result.stderr}" end end end end |