Class: Vagrant::Machine
- Inherits:
-
Object
- Object
- Vagrant::Machine
- Defined in:
- lib/vagrant/machine.rb
Overview
This represents a machine that Vagrant manages. This provides a singular API for querying the state and making state changes to the machine, which is backed by any sort of provider (VirtualBox, VMWare, etc.).
Instance Attribute Summary collapse
-
#box ⇒ Box
readonly
The box that is backing this machine.
-
#config ⇒ Object
readonly
Configuration for the machine.
-
#data_dir ⇒ Pathname
readonly
Directory where machine-specific data can be stored.
-
#env ⇒ Environment
readonly
The environment that this machine is a part of.
-
#id ⇒ String
ID of the machine.
-
#name ⇒ String
readonly
Name of the machine.
-
#provider ⇒ Object
readonly
The provider backing this machine.
-
#provider_config ⇒ Object
readonly
The provider-specific configuration for this machine.
-
#provider_name ⇒ Symbol
readonly
The name of the provider.
Instance Method Summary collapse
-
#action(name, extra_env = nil) ⇒ Object
This calls an action on the provider.
-
#communicate ⇒ Object
Returns a communication object for executing commands on the remote machine.
-
#guest ⇒ Object
Returns a guest implementation for this machine.
-
#initialize(name, provider_name, provider_cls, provider_config, config, data_dir, box, env, base = false) ⇒ Machine
constructor
Initialize a new machine.
-
#inspect ⇒ String
This returns a clean inspect value so that printing the value via a pretty print (‘p`) results in a readable value.
-
#ssh_info ⇒ Hash
This returns the SSH info for accessing this machine.
-
#state ⇒ Symbol
Returns the state of this machine.
Constructor Details
#initialize(name, provider_name, provider_cls, provider_config, config, data_dir, box, env, base = false) ⇒ Machine
Initialize a new machine.
68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 |
# File 'lib/vagrant/machine.rb', line 68 def initialize(name, provider_name, provider_cls, provider_config, config, data_dir, box, env, base=false) @logger = Log4r::Logger.new("vagrant::machine") @logger.info("Initializing machine: #{name}") @logger.info(" - Provider: #{provider_cls}") @logger.info(" - Box: #{box}") @logger.info(" - Data dir: #{data_dir}") @box = box @config = config @data_dir = data_dir @env = env @name = name @provider_config = provider_config @provider_name = provider_name # Read the ID, which is usually in local storage @id = nil # XXX: This is temporary. This will be removed very soon. if base @id = name else # Read the id file from the data directory if it exists as the # ID for the pre-existing physical representation of this machine. id_file = @data_dir.join("id") @id = id_file.read if id_file.file? end # Initializes the provider last so that it has access to all the # state we setup on this machine. @provider = provider_cls.new(self) end |
Instance Attribute Details
#box ⇒ Box (readonly)
The box that is backing this machine.
11 12 13 |
# File 'lib/vagrant/machine.rb', line 11 def box @box end |
#config ⇒ Object (readonly)
Configuration for the machine.
16 17 18 |
# File 'lib/vagrant/machine.rb', line 16 def config @config end |
#data_dir ⇒ Pathname (readonly)
Directory where machine-specific data can be stored.
21 22 23 |
# File 'lib/vagrant/machine.rb', line 21 def data_dir @data_dir end |
#env ⇒ Environment (readonly)
The environment that this machine is a part of.
26 27 28 |
# File 'lib/vagrant/machine.rb', line 26 def env @env end |
#id ⇒ String
ID of the machine. This ID comes from the provider and is not guaranteed to be of any particular format except that it is a string.
33 34 35 |
# File 'lib/vagrant/machine.rb', line 33 def id @id end |
#name ⇒ String (readonly)
Name of the machine. This is assigned by the Vagrantfile.
38 39 40 |
# File 'lib/vagrant/machine.rb', line 38 def name @name end |
#provider ⇒ Object (readonly)
The provider backing this machine.
43 44 45 |
# File 'lib/vagrant/machine.rb', line 43 def provider @provider end |
#provider_config ⇒ Object (readonly)
The provider-specific configuration for this machine.
48 49 50 |
# File 'lib/vagrant/machine.rb', line 48 def provider_config @provider_config end |
#provider_name ⇒ Symbol (readonly)
The name of the provider.
53 54 55 |
# File 'lib/vagrant/machine.rb', line 53 def provider_name @provider_name end |
Instance Method Details
#action(name, extra_env = nil) ⇒ Object
This calls an action on the provider. The provider may or may not actually implement the action.
108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 |
# File 'lib/vagrant/machine.rb', line 108 def action(name, extra_env=nil) @logger.info("Calling action: #{name} on provider #{@provider}") # Get the callable from the provider. callable = @provider.action(name) # If this action doesn't exist on the provider, then an exception # must be raised. if callable.nil? raise Errors::UnimplementedProviderAction, :action => name, :provider => @provider.to_s end # Run the action with the action runner on the environment env = { :action_name => "machine_action_#{name}".to_sym, :machine => self, :machine_action => name, :ui => @env.ui_class.new(@name) }.merge(extra_env || {}) @env.action_runner.run(callable, env) end |
#communicate ⇒ Object
Returns a communication object for executing commands on the remote machine. Note that the exact semantics of this are up to the communication provider itself. Despite this, the semantics are expected to be consistent across operating systems. For example, all linux-based systems should have similar communication (usually a shell). All Windows systems should have similar communication as well. Therefore, prior to communicating with the machine, users of this method are expected to check the guest OS to determine their behavior.
This method will always return some valid communication object. The ‘ready?` API can be used on the object to check if communication is actually ready.
146 147 148 149 150 151 152 153 154 155 |
# File 'lib/vagrant/machine.rb', line 146 def communicate if !@communicator # For now, we always return SSH. In the future, we'll abstract # this and allow plugins to define new methods of communication. klass = Vagrant.plugin("2").manager.communicators[:ssh] @communicator = klass.new(self) end @communicator end |
#guest ⇒ Object
Returns a guest implementation for this machine. The guest implementation knows how to do guest-OS specific tasks, such as configuring networks, mounting folders, etc.
162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 |
# File 'lib/vagrant/machine.rb', line 162 def guest raise Errors::MachineGuestNotReady if !communicate.ready? # Load the initial guest. last_guest = config.vm.guest guest = load_guest(last_guest) # Loop and distro dispatch while there are distros. while true distro = guest.distro_dispatch break if !distro # This is just some really basic loop detection and avoiding for # guest classes. This is just here to help implementers a bit # avoid a situation that is fairly easy, since if you subclass # a parent which does `distro_dispatch`, you'll end up dispatching # forever. if distro == last_guest @logger.warn("Distro dispatch loop in '#{distro}'. Exiting loop.") break end last_guest = distro guest = load_guest(distro) end # Return the result guest end |
#inspect ⇒ String
This returns a clean inspect value so that printing the value via a pretty print (‘p`) results in a readable value.
228 229 230 |
# File 'lib/vagrant/machine.rb', line 228 def inspect "#<#{self.class}: #{@name} (#{@provider.class})>" end |
#ssh_info ⇒ Hash
This returns the SSH info for accessing this machine. This SSH info is queried from the underlying provider. This method returns ‘nil` if the machine is not ready for SSH communication.
The structure of the resulting hash is guaranteed to contain the following structure, although it may return other keys as well not documented here:
{
:host => "1.2.3.4",
:port => "22",
:username => "mitchellh",
:private_key_path => "/path/to/my/key"
}
Note that Vagrant makes no guarantee that this info works or is correct. This is simply the data that the provider gives us or that is configured via a Vagrantfile. It is still possible after this point when attempting to connect via SSH to get authentication errors.
254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 |
# File 'lib/vagrant/machine.rb', line 254 def ssh_info # First, ask the provider for their information. If the provider # returns nil, then the machine is simply not ready for SSH, and # we return nil as well. info = @provider.ssh_info return nil if info.nil? # Delete out the nil entries. info.dup.each do |key, value| info.delete(key) if value.nil? end # Next, we default some fields if they weren't given to us by # the provider. info[:host] ||= @config.ssh.host if @config.ssh.host info[:port] ||= @config.ssh.port if @config.ssh.port info[:username] ||= @config.ssh.username if @config.ssh.username # We also set some fields that are purely controlled by Varant info[:forward_agent] = @config.ssh.forward_agent info[:forward_x11] = @config.ssh.forward_x11 # Set the private key path. If a specific private key is given in # the Vagrantfile we set that. Otherwise, we use the default (insecure) # private key, but only if the provider didn't give us one. if !info[:private_key_path] if @config.ssh.private_key_path info[:private_key_path] = @config.ssh.private_key_path else info[:private_key_path] = @env.default_private_key_path end end # Expand the private key path relative to the root path info[:private_key_path] = File.(info[:private_key_path], @env.root_path) # Return the final compiled SSH info data info end |
#state ⇒ Symbol
Returns the state of this machine. The state is queried from the backing provider, so it can be any arbitrary symbol.
298 299 300 301 302 |
# File 'lib/vagrant/machine.rb', line 298 def state result = @provider.state raise Errors::MachineStateInvalid if !result.is_a?(MachineState) result end |