From 2b7aca1d83fae939286edbc3c3629a9bd832512a Mon Sep 17 00:00:00 2001 From: Brian Johnson Date: Wed, 10 Jul 2013 18:21:06 -0700 Subject: [PATCH] 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