From 2b7aca1d83fae939286edbc3c3629a9bd832512a Mon Sep 17 00:00:00 2001 From: Brian Johnson Date: Wed, 10 Jul 2013 18:21:06 -0700 Subject: [PATCH 01/10] Highly limited osx (darwin) guest plugin. - Tested on mountainlion/virtualbox - virtualbox shared folders will not work (no vboxvsf support) - Must use at least 2GB of RAM or the os will refuse to boot(mountainlion requirement) To begin, create a mountainlion vm in virtualbox. You will need to install from scratch most likely, and assign at least 2GB of ram for it to install. Create 2 network interfaces, the first one a NAT interface, second a hostonly interface. 'vagrant package' the VM. In your vagrant file, be sure that the synced folder is disabled: config.vm.synced_folder "vagrant", "/vagrant", disabled: true --- plugins/guests/darwin/cap/change_host_name.rb | 14 ++++++ .../guests/darwin/cap/configure_networks.rb | 49 +++++++++++++++++++ plugins/guests/darwin/cap/halt.rb | 16 ++++++ plugins/guests/darwin/cap/mount_nfs_folder.rb | 14 ++++++ plugins/guests/darwin/guest.rb | 14 ++++++ plugins/guests/darwin/plugin.rb | 35 +++++++++++++ 6 files changed, 142 insertions(+) create mode 100644 plugins/guests/darwin/cap/change_host_name.rb create mode 100644 plugins/guests/darwin/cap/configure_networks.rb create mode 100644 plugins/guests/darwin/cap/halt.rb create mode 100644 plugins/guests/darwin/cap/mount_nfs_folder.rb create mode 100644 plugins/guests/darwin/guest.rb create mode 100644 plugins/guests/darwin/plugin.rb diff --git a/plugins/guests/darwin/cap/change_host_name.rb b/plugins/guests/darwin/cap/change_host_name.rb new file mode 100644 index 000000000..922bbf6da --- /dev/null +++ b/plugins/guests/darwin/cap/change_host_name.rb @@ -0,0 +1,14 @@ +module VagrantPlugins + module GuestFreeDarwin + module Cap + class ChangeHostName + def self.change_host_name(machine, name) + if !machine.communicate.test("hostname -f | grep '^#{name}$' || hostname -s | grep '^#{name}$'") + machine.communicate.sudo("scutil --set HostName #{name}") + machine.communicate.sudo("hostname #{name}") + end + end + end + end + end +end diff --git a/plugins/guests/darwin/cap/configure_networks.rb b/plugins/guests/darwin/cap/configure_networks.rb new file mode 100644 index 000000000..6cb4500ee --- /dev/null +++ b/plugins/guests/darwin/cap/configure_networks.rb @@ -0,0 +1,49 @@ +require "tempfile" + +require "vagrant/util/template_renderer" + +module VagrantPlugins + module GuestFreeDarwin + module Cap + class ConfigureNetworks + include Vagrant::Util + + def self.configure_networks(machine, networks) + # Slightly different than other plugins, using the template to build commands + # rather than templating the files. + + devmap = {} + machine.communicate.sudo("networksetup -listnetworkserviceorder > /tmp/vagrant.interfaces") + tmpints = File.join(Dir.tmpdir, "#{machine.id}.interfaces") + machine.communicate.download("/tmp/vagrant.interfaces",tmpints) + ints = IO.read(tmpints) + ints.split(/\n\n/m).each do |i| + if i.match(/Hardware/) and not i.match(/Ethernet/).nil? + # Ethernet, should be 2 lines, + # (3) Thunderbolt Ethernet + # (Hardware Port: Thunderbolt Ethernet, Device: en1) + devicearry = i.match(/Hardware Port: (.+), Device: en(.+)\)/) + devmap[devicearry[2]] = devicearry[1] + puts devmap + end + end + networks.each do |network| + + if network[:type].to_sym == :static + # network seems 1 indexed - skip NAT interface (en0) + intnum = network[:interface] + puts "Network - #{intnum}" + command = "networksetup -setmanual \"#{devmap[intnum.to_s]}\" #{network[:ip]} #{network[:netmask]} #{network[:gateway]}" + + elsif network[:type].to_sym == :dhcp + command = "networksetup -setdhcp \"#{devmap[options[:interface]]}\"" + + end + + machine.communicate.sudo("#{command}") + end + end + end + end + end +end diff --git a/plugins/guests/darwin/cap/halt.rb b/plugins/guests/darwin/cap/halt.rb new file mode 100644 index 000000000..edf332fc5 --- /dev/null +++ b/plugins/guests/darwin/cap/halt.rb @@ -0,0 +1,16 @@ +module VagrantPlugins + module GuestFreeDarwin + module Cap + class Halt + def self.halt(machine) + begin + machine.communicate.sudo("shutdown -h now") + rescue IOError + # Do nothing because SSH connection closed and it probably + # means the VM just shut down really fast. + end + end + end + end + end +end diff --git a/plugins/guests/darwin/cap/mount_nfs_folder.rb b/plugins/guests/darwin/cap/mount_nfs_folder.rb new file mode 100644 index 000000000..ff3dd4b3b --- /dev/null +++ b/plugins/guests/darwin/cap/mount_nfs_folder.rb @@ -0,0 +1,14 @@ +module VagrantPlugins + module GuestFreeDarwin + module Cap + class MountNFSFolder + def self.mount_nfs_folder(machine, ip, folders) + folders.each do |name, opts| + machine.communicate.sudo("mkdir -p #{opts[:guestpath]}") + machine.communicate.sudo("mount '#{ip}:#{opts[:hostpath]}' '#{opts[:guestpath]}'") + end + end + end + end + end +end diff --git a/plugins/guests/darwin/guest.rb b/plugins/guests/darwin/guest.rb new file mode 100644 index 000000000..faea6cd77 --- /dev/null +++ b/plugins/guests/darwin/guest.rb @@ -0,0 +1,14 @@ +require 'vagrant/util/template_renderer' + +module VagrantPlugins + module GuestFreeDarwin + # A general Vagrant system implementation for "freebsd". + # + # Contributed by Kenneth Vestergaard + class Guest < Vagrant.plugin("2", :guest) + def detect?(machine) + machine.communicate.test("uname -s | grep 'Darwin'") + end + end + end +end diff --git a/plugins/guests/darwin/plugin.rb b/plugins/guests/darwin/plugin.rb new file mode 100644 index 000000000..733d3318f --- /dev/null +++ b/plugins/guests/darwin/plugin.rb @@ -0,0 +1,35 @@ +require "vagrant" + +module VagrantPlugins + module GuestFreeDarwin + class Plugin < Vagrant.plugin("2") + name "Darwin guest" + description "Darwin guest support." + + guest("darwin") do + require File.expand_path("../guest", __FILE__) + Guest + end + + guest_capability("darwin", "change_host_name") do + require_relative "cap/change_host_name" + Cap::ChangeHostName + end + + guest_capability("darwin", "configure_networks") do + require_relative "cap/configure_networks" + Cap::ConfigureNetworks + end + + guest_capability("darwin", "halt") do + require_relative "cap/halt" + Cap::Halt + end + + guest_capability("darwin", "mount_nfs_folder") do + require_relative "cap/mount_nfs_folder" + Cap::MountNFSFolder + end + end + end +end From 5606aa8b1e9d66c4080641d3c7fa70805f253d5a Mon Sep 17 00:00:00 2001 From: Brian Johnson Date: Wed, 31 Jul 2013 18:07:04 -0700 Subject: [PATCH 02/10] Working implementation with NFS, still some caveats: - There's a lengthy sleep in there, probably could use a back-off loop - en1 seems totally worthless on vbox, I skip it and just use the en2 it creates. --- plugins/guests/darwin/cap/change_host_name.rb | 2 +- .../guests/darwin/cap/configure_networks.rb | 9 ++++---- plugins/guests/darwin/cap/halt.rb | 2 +- plugins/guests/darwin/cap/mount_nfs_folder.rb | 22 ++++++++++--------- plugins/guests/darwin/guest.rb | 2 +- plugins/guests/darwin/plugin.rb | 2 +- 6 files changed, 21 insertions(+), 18 deletions(-) diff --git a/plugins/guests/darwin/cap/change_host_name.rb b/plugins/guests/darwin/cap/change_host_name.rb index 922bbf6da..80df9870d 100644 --- a/plugins/guests/darwin/cap/change_host_name.rb +++ b/plugins/guests/darwin/cap/change_host_name.rb @@ -1,5 +1,5 @@ module VagrantPlugins - module GuestFreeDarwin + module GuestDarwin module Cap class ChangeHostName def self.change_host_name(machine, name) diff --git a/plugins/guests/darwin/cap/configure_networks.rb b/plugins/guests/darwin/cap/configure_networks.rb index 6cb4500ee..5b37dc1b9 100644 --- a/plugins/guests/darwin/cap/configure_networks.rb +++ b/plugins/guests/darwin/cap/configure_networks.rb @@ -3,7 +3,7 @@ require "tempfile" require "vagrant/util/template_renderer" module VagrantPlugins - module GuestFreeDarwin + module GuestDarwin module Cap class ConfigureNetworks include Vagrant::Util @@ -12,6 +12,7 @@ module VagrantPlugins # Slightly different than other plugins, using the template to build commands # rather than templating the files. + machine.communicate.sudo("networksetup -detectnewhardware") devmap = {} machine.communicate.sudo("networksetup -listnetworkserviceorder > /tmp/vagrant.interfaces") tmpints = File.join(Dir.tmpdir, "#{machine.id}.interfaces") @@ -24,14 +25,14 @@ module VagrantPlugins # (Hardware Port: Thunderbolt Ethernet, Device: en1) devicearry = i.match(/Hardware Port: (.+), Device: en(.+)\)/) devmap[devicearry[2]] = devicearry[1] - puts devmap end end networks.each do |network| + if network[:type].to_sym == :static - # network seems 1 indexed - skip NAT interface (en0) - intnum = network[:interface] + # network seems 1 indexed - skip NAT interface (en0) also en1 because it seems to not *really* exist on virtualbox? + intnum = network[:interface] + 1 puts "Network - #{intnum}" command = "networksetup -setmanual \"#{devmap[intnum.to_s]}\" #{network[:ip]} #{network[:netmask]} #{network[:gateway]}" diff --git a/plugins/guests/darwin/cap/halt.rb b/plugins/guests/darwin/cap/halt.rb index edf332fc5..6575f1c93 100644 --- a/plugins/guests/darwin/cap/halt.rb +++ b/plugins/guests/darwin/cap/halt.rb @@ -1,5 +1,5 @@ module VagrantPlugins - module GuestFreeDarwin + module GuestDarwin module Cap class Halt def self.halt(machine) diff --git a/plugins/guests/darwin/cap/mount_nfs_folder.rb b/plugins/guests/darwin/cap/mount_nfs_folder.rb index ff3dd4b3b..c4be11a05 100644 --- a/plugins/guests/darwin/cap/mount_nfs_folder.rb +++ b/plugins/guests/darwin/cap/mount_nfs_folder.rb @@ -1,14 +1,16 @@ module VagrantPlugins - module GuestFreeDarwin - module Cap - class MountNFSFolder - def self.mount_nfs_folder(machine, ip, folders) - folders.each do |name, opts| - machine.communicate.sudo("mkdir -p #{opts[:guestpath]}") - machine.communicate.sudo("mount '#{ip}:#{opts[:hostpath]}' '#{opts[:guestpath]}'") - end + module GuestDarwin + module Cap + class MountNFSFolder + def self.mount_nfs_folder(machine, ip, folders) + puts "30 second nap...." + sleep(30) + folders.each do |name, opts| + machine.communicate.sudo("if [ ! -d #{opts[:guestpath]} ]; then mkdir -p #{opts[:guestpath]};fi") + machine.communicate.sudo("mount -t nfs '#{ip}:#{opts[:hostpath]}' '#{opts[:guestpath]}'") + end + end + end end - end end - end end diff --git a/plugins/guests/darwin/guest.rb b/plugins/guests/darwin/guest.rb index faea6cd77..f3bdb35b5 100644 --- a/plugins/guests/darwin/guest.rb +++ b/plugins/guests/darwin/guest.rb @@ -1,7 +1,7 @@ require 'vagrant/util/template_renderer' module VagrantPlugins - module GuestFreeDarwin + module GuestDarwin # A general Vagrant system implementation for "freebsd". # # Contributed by Kenneth Vestergaard diff --git a/plugins/guests/darwin/plugin.rb b/plugins/guests/darwin/plugin.rb index 733d3318f..5d104ed78 100644 --- a/plugins/guests/darwin/plugin.rb +++ b/plugins/guests/darwin/plugin.rb @@ -1,7 +1,7 @@ require "vagrant" module VagrantPlugins - module GuestFreeDarwin + module GuestDarwin class Plugin < Vagrant.plugin("2") name "Darwin guest" description "Darwin guest support." From 3611ff39f4871386a42bbc69be4ba4dc6270c363 Mon Sep 17 00:00:00 2001 From: Brian Johnson Date: Mon, 5 Aug 2013 17:39:44 -0700 Subject: [PATCH 03/10] Change mount_nfs_folder cap to be more like the linux version, adding a bunch of retires rather than a long sleep. Add DarwinNFSMountFailed error. This might move be more appropriate at the plugin level. Integrate some of tvsutton's work in configure_networks to get the implementation closer to working in both fusion and virtualbox. Add shell_expand_guest_path capability (also copied from linux) --- lib/vagrant/errors.rb | 4 + .../guests/darwin/cap/configure_networks.rb | 81 ++++++++++--------- plugins/guests/darwin/cap/mount_nfs_folder.rb | 37 +++++---- .../darwin/cap/shell_expand_guest_path.rb | 26 ++++++ plugins/guests/darwin/plugin.rb | 57 +++++++------ 5 files changed, 128 insertions(+), 77 deletions(-) create mode 100644 plugins/guests/darwin/cap/shell_expand_guest_path.rb diff --git a/lib/vagrant/errors.rb b/lib/vagrant/errors.rb index 7f1ce463c..a2c34aa35 100644 --- a/lib/vagrant/errors.rb +++ b/lib/vagrant/errors.rb @@ -183,6 +183,10 @@ module Vagrant error_key(:copy_private_key_failed) end + class DarwinNFSMountFailed < VagrantError + error_key(:darwin_nfs_mount_failed) + end + class DestroyRequiresForce < VagrantError error_key(:destroy_requires_force) end diff --git a/plugins/guests/darwin/cap/configure_networks.rb b/plugins/guests/darwin/cap/configure_networks.rb index 5b37dc1b9..9836893d0 100644 --- a/plugins/guests/darwin/cap/configure_networks.rb +++ b/plugins/guests/darwin/cap/configure_networks.rb @@ -3,48 +3,55 @@ require "tempfile" require "vagrant/util/template_renderer" module VagrantPlugins - module GuestDarwin - module Cap - class ConfigureNetworks - include Vagrant::Util + module GuestDarwin + module Cap + class ConfigureNetworks + include Vagrant::Util - def self.configure_networks(machine, networks) - # Slightly different than other plugins, using the template to build commands - # rather than templating the files. + def self.configure_networks(machine, networks) + # Slightly different than other plugins, using the template to build commands + # rather than templating the files. - machine.communicate.sudo("networksetup -detectnewhardware") - devmap = {} - machine.communicate.sudo("networksetup -listnetworkserviceorder > /tmp/vagrant.interfaces") - tmpints = File.join(Dir.tmpdir, "#{machine.id}.interfaces") - machine.communicate.download("/tmp/vagrant.interfaces",tmpints) - ints = IO.read(tmpints) - ints.split(/\n\n/m).each do |i| - if i.match(/Hardware/) and not i.match(/Ethernet/).nil? - # Ethernet, should be 2 lines, - # (3) Thunderbolt Ethernet - # (Hardware Port: Thunderbolt Ethernet, Device: en1) - devicearry = i.match(/Hardware Port: (.+), Device: en(.+)\)/) - devmap[devicearry[2]] = devicearry[1] - end - end - networks.each do |network| + machine.communicate.sudo("networksetup -detectnewhardware") + machine.communicate.sudo("networksetup -listnetworkserviceorder > /tmp/vagrant.interfaces") + tmpints = File.join(Dir.tmpdir, File.basename("#{machine.id}.interfaces")) + machine.communicate.download("/tmp/vagrant.interfaces",tmpints) + devlist = [] + ints = IO.read(tmpints) + ints.split(/\n\n/m).each do |i| + if i.match(/Hardware/) and not i.match(/Ethernet/).nil? + devmap = {} + # Ethernet, should be 2 lines, + # (3) Thunderbolt Ethernet + # (Hardware Port: Thunderbolt Ethernet, Device: en1) - if network[:type].to_sym == :static - # network seems 1 indexed - skip NAT interface (en0) also en1 because it seems to not *really* exist on virtualbox? - intnum = network[:interface] + 1 - puts "Network - #{intnum}" - command = "networksetup -setmanual \"#{devmap[intnum.to_s]}\" #{network[:ip]} #{network[:netmask]} #{network[:gateway]}" + # multiline, should match "Thunderbolt Ethernet", "en1" + devicearry = i.match(/\([0-9]+\) (.+)\n.*Device: (.+)\)/m) + devmap[:interface] = devicearry[2] + devmap[:service] = devicearry[1] + devlist << devmap + end + end + puts devlist - elsif network[:type].to_sym == :dhcp - command = "networksetup -setdhcp \"#{devmap[options[:interface]]}\"" + networks.each do |network| + intnum = network[:interface] + puts network[:interface] + puts network[:type] + if network[:type].to_sym == :static + # network seems 1 indexed - skip NAT interface (en0) also en1 because it seems to not *really* exist on virtualbox? + command = "networksetup -setmanual \"#{devlist[intnum+1][:service]}\" #{network[:ip]} #{network[:netmask]}" - end + elsif network[:type].to_sym == :dhcp + command = "networksetup -setdhcp \"#{devlist[intnum+1][:service]}\"" - machine.communicate.sudo("#{command}") - end - end - end - end - end + end + + machine.communicate.sudo(command) + end + end + end + end + end end diff --git a/plugins/guests/darwin/cap/mount_nfs_folder.rb b/plugins/guests/darwin/cap/mount_nfs_folder.rb index c4be11a05..52030a2ae 100644 --- a/plugins/guests/darwin/cap/mount_nfs_folder.rb +++ b/plugins/guests/darwin/cap/mount_nfs_folder.rb @@ -1,16 +1,25 @@ +require "vagrant/util/retryable" + module VagrantPlugins - module GuestDarwin - module Cap - class MountNFSFolder - def self.mount_nfs_folder(machine, ip, folders) - puts "30 second nap...." - sleep(30) - folders.each do |name, opts| - machine.communicate.sudo("if [ ! -d #{opts[:guestpath]} ]; then mkdir -p #{opts[:guestpath]};fi") - machine.communicate.sudo("mount -t nfs '#{ip}:#{opts[:hostpath]}' '#{opts[:guestpath]}'") - end - end - end - end - end + module GuestDarwin + module Cap + class MountNFSFolder + extend Vagrant::Util::Retryable + def self.mount_nfs_folder(machine, ip, folders) + folders.each do |name, opts| + # Expand the guest path so we can handle things like "~/vagrant" + expanded_guest_path = machine.guest.capability( + :shell_expand_guest_path, opts[:guestpath]) + + machine.communicate.sudo("if [ ! -d #{expanded_guest_path} ]; then mkdir -p #{expanded_guest_path};fi") + + mount_command = "mount -t nfs '#{ip}:#{opts[:hostpath]}' '#{expanded_guest_path}'" + retryable(:on => Vagrant::Errors::DarwinNFSMountFailed, :tries => 10, :sleep => 5) do + machine.communicate.sudo(mount_command, :error_class => Vagrant::Errors::DarwinNFSMountFailed) + end + end + end + end + end + end end diff --git a/plugins/guests/darwin/cap/shell_expand_guest_path.rb b/plugins/guests/darwin/cap/shell_expand_guest_path.rb new file mode 100644 index 000000000..13a82979b --- /dev/null +++ b/plugins/guests/darwin/cap/shell_expand_guest_path.rb @@ -0,0 +1,26 @@ +module VagrantPlugins + module GuestDarwin + module Cap + class ShellExpandGuestPath + def self.shell_expand_guest_path(machine, path) + real_path = nil + machine.communicate.execute("printf #{path}") do |type, data| + if type == :stdout + real_path ||= "" + real_path += data + end + end + + if !real_path + # If no real guest path was detected, this is really strange + # and we raise an exception because this is a bug. + raise DarwinShellExpandFailed + end + + # Chomp the string so that any trailing newlines are killed + return real_path.chomp + end + end + end + end +end diff --git a/plugins/guests/darwin/plugin.rb b/plugins/guests/darwin/plugin.rb index 5d104ed78..a7b481b24 100644 --- a/plugins/guests/darwin/plugin.rb +++ b/plugins/guests/darwin/plugin.rb @@ -1,35 +1,40 @@ require "vagrant" module VagrantPlugins - module GuestDarwin - class Plugin < Vagrant.plugin("2") - name "Darwin guest" - description "Darwin guest support." + module GuestDarwin + class Plugin < Vagrant.plugin("2") + name "Darwin guest" + description "Darwin guest support." - guest("darwin") do - require File.expand_path("../guest", __FILE__) - Guest - end + guest("darwin") do + require File.expand_path("../guest", __FILE__) + Guest + end - guest_capability("darwin", "change_host_name") do - require_relative "cap/change_host_name" - Cap::ChangeHostName - end + guest_capability("darwin", "change_host_name") do + require_relative "cap/change_host_name" + Cap::ChangeHostName + end - guest_capability("darwin", "configure_networks") do - require_relative "cap/configure_networks" - Cap::ConfigureNetworks - end + guest_capability("darwin", "configure_networks") do + require_relative "cap/configure_networks" + Cap::ConfigureNetworks + end - guest_capability("darwin", "halt") do - require_relative "cap/halt" - Cap::Halt - end + guest_capability("darwin", "halt") do + require_relative "cap/halt" + Cap::Halt + end - guest_capability("darwin", "mount_nfs_folder") do - require_relative "cap/mount_nfs_folder" - Cap::MountNFSFolder - end - end - end + guest_capability("darwin", "mount_nfs_folder") do + require_relative "cap/mount_nfs_folder" + Cap::MountNFSFolder + end + + guest_capability("darwin", "shell_expand_guest_path") do + require_relative "cap/shell_expand_guest_path" + Cap::ShellExpandGuestPath + end + end + end end From e5ce19ff11e7073cf019f63565b5e4c149f83cf9 Mon Sep 17 00:00:00 2001 From: Brian Johnson Date: Mon, 5 Aug 2013 18:07:45 -0700 Subject: [PATCH 04/10] Tabs must die. --- .../guests/darwin/cap/configure_networks.rb | 86 +++++++++---------- plugins/guests/darwin/cap/mount_nfs_folder.rb | 38 ++++---- plugins/guests/darwin/plugin.rb | 60 ++++++------- 3 files changed, 92 insertions(+), 92 deletions(-) diff --git a/plugins/guests/darwin/cap/configure_networks.rb b/plugins/guests/darwin/cap/configure_networks.rb index 9836893d0..6befa80f0 100644 --- a/plugins/guests/darwin/cap/configure_networks.rb +++ b/plugins/guests/darwin/cap/configure_networks.rb @@ -3,55 +3,55 @@ require "tempfile" require "vagrant/util/template_renderer" module VagrantPlugins - module GuestDarwin - module Cap - class ConfigureNetworks - include Vagrant::Util + module GuestDarwin + module Cap + class ConfigureNetworks + include Vagrant::Util - def self.configure_networks(machine, networks) - # Slightly different than other plugins, using the template to build commands - # rather than templating the files. + def self.configure_networks(machine, networks) + # Slightly different than other plugins, using the template to build commands + # rather than templating the files. - machine.communicate.sudo("networksetup -detectnewhardware") - machine.communicate.sudo("networksetup -listnetworkserviceorder > /tmp/vagrant.interfaces") - tmpints = File.join(Dir.tmpdir, File.basename("#{machine.id}.interfaces")) - machine.communicate.download("/tmp/vagrant.interfaces",tmpints) + machine.communicate.sudo("networksetup -detectnewhardware") + machine.communicate.sudo("networksetup -listnetworkserviceorder > /tmp/vagrant.interfaces") + tmpints = File.join(Dir.tmpdir, File.basename("#{machine.id}.interfaces")) + machine.communicate.download("/tmp/vagrant.interfaces",tmpints) - devlist = [] - ints = IO.read(tmpints) - ints.split(/\n\n/m).each do |i| - if i.match(/Hardware/) and not i.match(/Ethernet/).nil? - devmap = {} - # Ethernet, should be 2 lines, - # (3) Thunderbolt Ethernet - # (Hardware Port: Thunderbolt Ethernet, Device: en1) + devlist = [] + ints = IO.read(tmpints) + ints.split(/\n\n/m).each do |i| + if i.match(/Hardware/) and not i.match(/Ethernet/).nil? + devmap = {} + # Ethernet, should be 2 lines, + # (3) Thunderbolt Ethernet + # (Hardware Port: Thunderbolt Ethernet, Device: en1) - # multiline, should match "Thunderbolt Ethernet", "en1" - devicearry = i.match(/\([0-9]+\) (.+)\n.*Device: (.+)\)/m) - devmap[:interface] = devicearry[2] - devmap[:service] = devicearry[1] - devlist << devmap - end - end - puts devlist + # multiline, should match "Thunderbolt Ethernet", "en1" + devicearry = i.match(/\([0-9]+\) (.+)\n.*Device: (.+)\)/m) + devmap[:interface] = devicearry[2] + devmap[:service] = devicearry[1] + devlist << devmap + end + end + puts devlist - networks.each do |network| - intnum = network[:interface] - puts network[:interface] - puts network[:type] - if network[:type].to_sym == :static - # network seems 1 indexed - skip NAT interface (en0) also en1 because it seems to not *really* exist on virtualbox? - command = "networksetup -setmanual \"#{devlist[intnum+1][:service]}\" #{network[:ip]} #{network[:netmask]}" + networks.each do |network| + intnum = network[:interface] + puts network[:interface] + puts network[:type] + if network[:type].to_sym == :static + # network seems 1 indexed - skip NAT interface (en0) also en1 because it seems to not *really* exist on virtualbox? + command = "networksetup -setmanual \"#{devlist[intnum+1][:service]}\" #{network[:ip]} #{network[:netmask]}" - elsif network[:type].to_sym == :dhcp - command = "networksetup -setdhcp \"#{devlist[intnum+1][:service]}\"" + elsif network[:type].to_sym == :dhcp + command = "networksetup -setdhcp \"#{devlist[intnum+1][:service]}\"" - end + end - machine.communicate.sudo(command) - end - end - end - end - end + machine.communicate.sudo(command) + end + end + end + end + end end diff --git a/plugins/guests/darwin/cap/mount_nfs_folder.rb b/plugins/guests/darwin/cap/mount_nfs_folder.rb index 52030a2ae..180d4b0d1 100644 --- a/plugins/guests/darwin/cap/mount_nfs_folder.rb +++ b/plugins/guests/darwin/cap/mount_nfs_folder.rb @@ -1,25 +1,25 @@ require "vagrant/util/retryable" module VagrantPlugins - module GuestDarwin - module Cap - class MountNFSFolder - extend Vagrant::Util::Retryable - def self.mount_nfs_folder(machine, ip, folders) - folders.each do |name, opts| - # Expand the guest path so we can handle things like "~/vagrant" - expanded_guest_path = machine.guest.capability( - :shell_expand_guest_path, opts[:guestpath]) + module GuestDarwin + module Cap + class MountNFSFolder + extend Vagrant::Util::Retryable + def self.mount_nfs_folder(machine, ip, folders) + folders.each do |name, opts| + # Expand the guest path so we can handle things like "~/vagrant" + expanded_guest_path = machine.guest.capability( + :shell_expand_guest_path, opts[:guestpath]) - machine.communicate.sudo("if [ ! -d #{expanded_guest_path} ]; then mkdir -p #{expanded_guest_path};fi") + machine.communicate.sudo("if [ ! -d #{expanded_guest_path} ]; then mkdir -p #{expanded_guest_path};fi") - mount_command = "mount -t nfs '#{ip}:#{opts[:hostpath]}' '#{expanded_guest_path}'" - retryable(:on => Vagrant::Errors::DarwinNFSMountFailed, :tries => 10, :sleep => 5) do - machine.communicate.sudo(mount_command, :error_class => Vagrant::Errors::DarwinNFSMountFailed) - end - end - end - end - end - end + mount_command = "mount -t nfs '#{ip}:#{opts[:hostpath]}' '#{expanded_guest_path}'" + retryable(:on => Vagrant::Errors::DarwinNFSMountFailed, :tries => 10, :sleep => 5) do + machine.communicate.sudo(mount_command, :error_class => Vagrant::Errors::DarwinNFSMountFailed) + end + end + end + end + end + end end diff --git a/plugins/guests/darwin/plugin.rb b/plugins/guests/darwin/plugin.rb index a7b481b24..ff437f866 100644 --- a/plugins/guests/darwin/plugin.rb +++ b/plugins/guests/darwin/plugin.rb @@ -1,40 +1,40 @@ require "vagrant" module VagrantPlugins - module GuestDarwin - class Plugin < Vagrant.plugin("2") - name "Darwin guest" - description "Darwin guest support." + module GuestDarwin + class Plugin < Vagrant.plugin("2") + name "Darwin guest" + description "Darwin guest support." - guest("darwin") do - require File.expand_path("../guest", __FILE__) - Guest - end + guest("darwin") do + require File.expand_path("../guest", __FILE__) + Guest + end - guest_capability("darwin", "change_host_name") do - require_relative "cap/change_host_name" - Cap::ChangeHostName - end + guest_capability("darwin", "change_host_name") do + require_relative "cap/change_host_name" + Cap::ChangeHostName + end - guest_capability("darwin", "configure_networks") do - require_relative "cap/configure_networks" - Cap::ConfigureNetworks - end + guest_capability("darwin", "configure_networks") do + require_relative "cap/configure_networks" + Cap::ConfigureNetworks + end - guest_capability("darwin", "halt") do - require_relative "cap/halt" - Cap::Halt - end + guest_capability("darwin", "halt") do + require_relative "cap/halt" + Cap::Halt + end - guest_capability("darwin", "mount_nfs_folder") do - require_relative "cap/mount_nfs_folder" - Cap::MountNFSFolder - end + guest_capability("darwin", "mount_nfs_folder") do + require_relative "cap/mount_nfs_folder" + Cap::MountNFSFolder + end - guest_capability("darwin", "shell_expand_guest_path") do - require_relative "cap/shell_expand_guest_path" - Cap::ShellExpandGuestPath - end - end - end + guest_capability("darwin", "shell_expand_guest_path") do + require_relative "cap/shell_expand_guest_path" + Cap::ShellExpandGuestPath + end + end + end end From 7d0a92c5b4335d24361e252458d0e27f59372f1b Mon Sep 17 00:00:00 2001 From: Brian Johnson Date: Mon, 5 Aug 2013 18:45:42 -0700 Subject: [PATCH 05/10] Remove the +1 offset, I resolved the issue with the 'phantom' en1 interface. For some reason interfaces still skip en1, but provided we enumerate based on order and not name, things should work smoothly. --- plugins/guests/darwin/cap/configure_networks.rb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/plugins/guests/darwin/cap/configure_networks.rb b/plugins/guests/darwin/cap/configure_networks.rb index 6befa80f0..da1f8c1d9 100644 --- a/plugins/guests/darwin/cap/configure_networks.rb +++ b/plugins/guests/darwin/cap/configure_networks.rb @@ -41,10 +41,10 @@ module VagrantPlugins puts network[:type] if network[:type].to_sym == :static # network seems 1 indexed - skip NAT interface (en0) also en1 because it seems to not *really* exist on virtualbox? - command = "networksetup -setmanual \"#{devlist[intnum+1][:service]}\" #{network[:ip]} #{network[:netmask]}" + command = "networksetup -setmanual \"#{devlist[intnum][:service]}\" #{network[:ip]} #{network[:netmask]}" elsif network[:type].to_sym == :dhcp - command = "networksetup -setdhcp \"#{devlist[intnum+1][:service]}\"" + command = "networksetup -setdhcp \"#{devlist[intnum][:service]}\"" end From 300d151608c188972fde9d832f97d368fbd174f9 Mon Sep 17 00:00:00 2001 From: Timothy Sutton Date: Tue, 6 Aug 2013 10:17:12 -0400 Subject: [PATCH 06/10] Darwin guest: mount_vmware_shared_folder cap for use with vmware_fusion provider - It's not clear whether it's possible to mount individual shares using 'mount -t vmhgfs', as the vagrant-vmware-fusion provider now does for Linux guests. Any mount from '.host', even if not a valid share name, succeeds and mounts _all_ shares in their respective directories at the root of the mountpoint. Instead, we symlink each directory from its place in '/Volumes/VMware Shared Folders' --- .../darwin/cap/mount_vmware_shared_folder.rb | 36 +++++++++++++++++++ plugins/guests/darwin/plugin.rb | 5 +++ 2 files changed, 41 insertions(+) create mode 100644 plugins/guests/darwin/cap/mount_vmware_shared_folder.rb diff --git a/plugins/guests/darwin/cap/mount_vmware_shared_folder.rb b/plugins/guests/darwin/cap/mount_vmware_shared_folder.rb new file mode 100644 index 000000000..7b932cd43 --- /dev/null +++ b/plugins/guests/darwin/cap/mount_vmware_shared_folder.rb @@ -0,0 +1,36 @@ +module VagrantPlugins + module GuestDarwin + module Cap + class MountVmwareSharedFolder + + # we seem to be unable to ask 'mount -t vmhgfs' to mount the roots + # of specific shares, so instead we symlink from what is already + # mounted by the guest tools + # (ie. the behaviour of the VMware_fusion provider prior to 0.8.x) + + def self.mount_vmware_shared_folder(machine, name, guestpath, options) + machine.communicate.tap do |comm| + # clear prior symlink + if comm.test("sudo test -L \"#{guestpath}\"") + comm.sudo("rm \"#{guestpath}\"") + end + + # clear prior directory if exists + if comm.test("sudo test -d \"#{guestpath}\"") + comm.sudo("rm -Rf \"#{guestpath}\"") + end + + # create intermediate directories if needed + intermediate_dir = File.dirname(guestpath) + if !comm.test("sudo test -d \"#{intermediate_dir}\"") + comm.sudo("mkdir -p \"#{intermediate_dir}\"") + end + + # finally make the symlink + comm.sudo("ln -s \"/Volumes/VMware Shared Folders/#{name}\" \"#{guestpath}\"") + end + end + end + end + end +end diff --git a/plugins/guests/darwin/plugin.rb b/plugins/guests/darwin/plugin.rb index ff437f866..a8884f6f0 100644 --- a/plugins/guests/darwin/plugin.rb +++ b/plugins/guests/darwin/plugin.rb @@ -31,6 +31,11 @@ module VagrantPlugins Cap::MountNFSFolder end + guest_capability("darwin", "mount_vmware_shared_folder") do + require_relative "cap/mount_vmware_shared_folder" + Cap::MountVmwareSharedFolder + end + guest_capability("darwin", "shell_expand_guest_path") do require_relative "cap/shell_expand_guest_path" Cap::ShellExpandGuestPath From 78ec8b580904c6d24865edd7f1a32b99c1558687 Mon Sep 17 00:00:00 2001 From: Timothy Sutton Date: Tue, 6 Aug 2013 10:17:52 -0400 Subject: [PATCH 07/10] Darwin: clean up temporary network interface file downloaded from guest --- plugins/guests/darwin/cap/configure_networks.rb | 1 + 1 file changed, 1 insertion(+) diff --git a/plugins/guests/darwin/cap/configure_networks.rb b/plugins/guests/darwin/cap/configure_networks.rb index da1f8c1d9..a858b7b84 100644 --- a/plugins/guests/darwin/cap/configure_networks.rb +++ b/plugins/guests/darwin/cap/configure_networks.rb @@ -34,6 +34,7 @@ module VagrantPlugins end end puts devlist + File.delete(tmpints) networks.each do |network| intnum = network[:interface] From 8b925e6c154ea1e3228662d8987173fc38fbc651 Mon Sep 17 00:00:00 2001 From: Timothy Sutton Date: Tue, 6 Aug 2013 10:18:12 -0400 Subject: [PATCH 08/10] Update Darwin guest description --- plugins/guests/darwin/guest.rb | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/plugins/guests/darwin/guest.rb b/plugins/guests/darwin/guest.rb index f3bdb35b5..0e8113e0a 100644 --- a/plugins/guests/darwin/guest.rb +++ b/plugins/guests/darwin/guest.rb @@ -2,9 +2,10 @@ require 'vagrant/util/template_renderer' module VagrantPlugins module GuestDarwin - # A general Vagrant system implementation for "freebsd". + # A general Vagrant system implementation for OS X (ie. "Darwin"). # - # Contributed by Kenneth Vestergaard + # Contributed by: - Brian Johnson + # - Tim Sutton class Guest < Vagrant.plugin("2", :guest) def detect?(machine) machine.communicate.test("uname -s | grep 'Darwin'") From a3b9428f6747dd0ef33d58a796c4019244dc67c7 Mon Sep 17 00:00:00 2001 From: Timothy Sutton Date: Tue, 6 Aug 2013 10:18:38 -0400 Subject: [PATCH 09/10] Darwin: code debug cleanup --- plugins/guests/darwin/cap/configure_networks.rb | 12 +++--------- 1 file changed, 3 insertions(+), 9 deletions(-) diff --git a/plugins/guests/darwin/cap/configure_networks.rb b/plugins/guests/darwin/cap/configure_networks.rb index a858b7b84..6f1d4d46b 100644 --- a/plugins/guests/darwin/cap/configure_networks.rb +++ b/plugins/guests/darwin/cap/configure_networks.rb @@ -33,20 +33,14 @@ module VagrantPlugins devlist << devmap end end - puts devlist File.delete(tmpints) networks.each do |network| - intnum = network[:interface] - puts network[:interface] - puts network[:type] + service_name = devlist[network[:interface]][:service] if network[:type].to_sym == :static - # network seems 1 indexed - skip NAT interface (en0) also en1 because it seems to not *really* exist on virtualbox? - command = "networksetup -setmanual \"#{devlist[intnum][:service]}\" #{network[:ip]} #{network[:netmask]}" - + command = "networksetup -setmanual \"#{service_name}\" #{network[:ip]} #{network[:netmask]}" elsif network[:type].to_sym == :dhcp - command = "networksetup -setdhcp \"#{devlist[intnum][:service]}\"" - + command = "networksetup -setdhcp \"#{service_name}\"" end machine.communicate.sudo(command) From 23962baac97c3e1cdc6a755419d61c48255205ea Mon Sep 17 00:00:00 2001 From: Timothy Sutton Date: Wed, 7 Aug 2013 17:10:32 -0400 Subject: [PATCH 10/10] Darwin: use :sudo for communicate.test --- plugins/guests/darwin/cap/mount_vmware_shared_folder.rb | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/plugins/guests/darwin/cap/mount_vmware_shared_folder.rb b/plugins/guests/darwin/cap/mount_vmware_shared_folder.rb index 7b932cd43..5b1cce976 100644 --- a/plugins/guests/darwin/cap/mount_vmware_shared_folder.rb +++ b/plugins/guests/darwin/cap/mount_vmware_shared_folder.rb @@ -11,18 +11,18 @@ module VagrantPlugins def self.mount_vmware_shared_folder(machine, name, guestpath, options) machine.communicate.tap do |comm| # clear prior symlink - if comm.test("sudo test -L \"#{guestpath}\"") + if comm.test("test -L \"#{guestpath}\"", :sudo => true) comm.sudo("rm \"#{guestpath}\"") end # clear prior directory if exists - if comm.test("sudo test -d \"#{guestpath}\"") + if comm.test("test -d \"#{guestpath}\"", :sudo => true) comm.sudo("rm -Rf \"#{guestpath}\"") end # create intermediate directories if needed intermediate_dir = File.dirname(guestpath) - if !comm.test("sudo test -d \"#{intermediate_dir}\"") + if !comm.test("test -d \"#{intermediate_dir}\"", :sudo => true) comm.sudo("mkdir -p \"#{intermediate_dir}\"") end