Class: Vagrant::Guest
- Inherits:
-
Object
- Object
- Vagrant::Guest
- Defined in:
- lib/vagrant/guest.rb
Overview
This class handles guest-OS specific interactions with a machine. It is primarily responsible for detecting the proper guest OS implementation and then delegating capabilities.
Vagrant has many tasks which require specific guest OS knowledge. These are implemented using a guest/capability system. Various plugins register as “guests” which determine the underlying OS of the system. Then, “guest capabilities” register themselves for a specific OS (one or more), and these capabilities are called.
Example capabilities might be “mount_virtualbox_shared_folder” or “configure_networks”.
This system allows for maximum flexibility and pluginability for doing guest OS specific operations.
Instance Attribute Summary collapse
-
#chain ⇒ Object
readonly
Returns the value of attribute chain.
-
#name ⇒ Symbol
readonly
The name of the guest OS.
Instance Method Summary collapse
-
#capability(cap_name, *args) ⇒ Object
Executes the capability with the given name, optionally passing more arguments onwards to the capability.
-
#capability?(cap_name) ⇒ Boolean
Tests whether the guest has the named capability.
-
#detect! ⇒ Object
This will detect the proper guest OS for the machine and set up the class to actually execute capabilities.
-
#initialize(machine, guests, capabilities) ⇒ Guest
constructor
A new instance of Guest.
-
#ready? ⇒ Boolean
This returns whether the guest is ready to work.
Constructor Details
#initialize(machine, guests, capabilities) ⇒ Guest
28 29 30 31 32 33 34 35 |
# File 'lib/vagrant/guest.rb', line 28 def initialize(machine, guests, capabilities) @logger = Log4r::Logger.new("vagrant::guest") @capabilities = capabilities @chain = [] @guests = guests @machine = machine @name = nil end |
Instance Attribute Details
#chain ⇒ Object (readonly)
Returns the value of attribute chain.
20 21 22 |
# File 'lib/vagrant/guest.rb', line 20 def chain @chain end |
#name ⇒ Symbol (readonly)
The name of the guest OS. This is available after #detect! is called.
26 27 28 |
# File 'lib/vagrant/guest.rb', line 26 def name @name end |
Instance Method Details
#capability(cap_name, *args) ⇒ Object
Executes the capability with the given name, optionally passing more arguments onwards to the capability.
121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 |
# File 'lib/vagrant/guest.rb', line 121 def capability(cap_name, *args) @logger.info("Execute capability: #{cap_name} (#{@chain[0][0]})") cap_mod = capability_module(cap_name.to_sym) if !cap_mod raise Errors::GuestCapabilityNotFound, :cap => cap_name.to_s, :guest => @chain[0][0].to_s end cap_method = nil begin cap_method = cap_mod.method(cap_name) rescue NameError raise Errors::GuestCapabilityInvalid, :cap => cap_name.to_s, :guest => @chain[0][0].to_s end cap_method.call(@machine, *args) end |
#capability?(cap_name) ⇒ Boolean
Tests whether the guest has the named capability.
115 116 117 |
# File 'lib/vagrant/guest.rb', line 115 def capability?(cap_name) !capability_module(cap_name.to_sym).nil? end |
#detect! ⇒ Object
This will detect the proper guest OS for the machine and set up the class to actually execute capabilities.
39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 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 100 101 102 103 104 105 106 107 108 109 110 |
# File 'lib/vagrant/guest.rb', line 39 def detect! @logger.info("Detect guest for machine: #{@machine}") # Get the mapping of guests with the most parents. We start searching # with the guests with the most parents first. parent_count = {} @guests.each do |name, parts| parent_count[name] = 0 parent = parts[1] while parent parent_count[name] += 1 parent = @guests[parent] parent = parent[1] if parent end end # Now swap around the mapping so that it is a mapping of # count to the actual list of guest names parent_count_to_guests = {} parent_count.each do |name, count| parent_count_to_guests[count] ||= [] parent_count_to_guests[count] << name end catch(:guest_os) do sorted_counts = parent_count_to_guests.keys.sort.reverse sorted_counts.each do |count| parent_count_to_guests[count].each do |name| @logger.debug("Trying: #{name}") guest_info = @guests[name] guest = guest_info[0].new # If a specific guest was specified, then attempt to use that # guest no matter what. Otherwise, only use it if it was detected. use_this_guest = false if @machine.config.vm.guest.nil? use_this_guest = guest.detect?(@machine) else use_this_guest = @machine.config.vm.guest.to_sym == name.to_sym end if use_this_guest @logger.info("Detected: #{name}!") @chain << [name, guest] @name = name # Build the proper chain of parents if there are any. # This allows us to do "inheritance" of capabilities later if guest_info[1] parent_name = guest_info[1] parent_info = @guests[parent_name] while parent_info @chain << [parent_name, parent_info[0].new] parent_name = parent_info[1] parent_info = @guests[parent_name] end end @logger.info("Full guest chain: #{@chain.inspect}") # Exit the search throw :guest_os end end end end # We shouldn't reach this point. Ideally we would detect # all operating systems. raise Errors::GuestNotDetected if @chain.empty? end |
#ready? ⇒ Boolean
This returns whether the guest is ready to work. If this returns ‘false`, then #detect! should be called in order to detect the guest OS.
147 148 149 |
# File 'lib/vagrant/guest.rb', line 147 def ready? !@chain.empty? end |