guests/windows: initial vagrant-windows extraction
This commit is contained in:
parent
7223e29330
commit
b81f430f31
|
@ -0,0 +1,14 @@
|
||||||
|
module VagrantPlugins
|
||||||
|
module GuestWindows
|
||||||
|
module Cap
|
||||||
|
module ChangeHostName
|
||||||
|
def self.change_host_name(machine, name)
|
||||||
|
# On windows, renaming a computer seems to require a reboot
|
||||||
|
machine.communicate.execute(
|
||||||
|
"wmic computersystem where name=\"%COMPUTERNAME%\" call rename name=\"#{name}\"",
|
||||||
|
:shell => :cmd)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
|
@ -0,0 +1,72 @@
|
||||||
|
require "log4r"
|
||||||
|
|
||||||
|
require_relative '../../communication/guestnetwork'
|
||||||
|
require_relative '../../communication/winrmshell'
|
||||||
|
require_relative '../../errors'
|
||||||
|
require_relative '../../helper'
|
||||||
|
require_relative '../../windows_machine'
|
||||||
|
|
||||||
|
module VagrantPlugins
|
||||||
|
module GuestWindows
|
||||||
|
module Cap
|
||||||
|
module ConfigureNetworks
|
||||||
|
@@logger = Log4r::Logger.new("vagrant::guest::windows::configure_networks")
|
||||||
|
|
||||||
|
def self.configure_networks(machine, networks)
|
||||||
|
@@logger.debug("Networks: #{networks.inspect}")
|
||||||
|
|
||||||
|
windows_machine = VagrantWindows::WindowsMachine.new(machine)
|
||||||
|
guest_network = VagrantWindows::Communication::GuestNetwork.new(windows_machine.winrmshell)
|
||||||
|
if windows_machine.is_vmware?()
|
||||||
|
@@logger.warn('Configuring secondary network adapters through VMware is not yet supported.')
|
||||||
|
@@logger.warn('You will need to manually configure the network adapter.')
|
||||||
|
else
|
||||||
|
vm_interface_map = create_vm_interface_map(windows_machine, guest_network)
|
||||||
|
networks.each do |network|
|
||||||
|
interface = vm_interface_map[network[:interface]+1]
|
||||||
|
if interface.nil?
|
||||||
|
@@logger.warn("Could not find interface for network #{network.inspect}")
|
||||||
|
next
|
||||||
|
end
|
||||||
|
network_type = network[:type].to_sym
|
||||||
|
if network_type == :static
|
||||||
|
guest_network.configure_static_interface(
|
||||||
|
interface[:index],
|
||||||
|
interface[:net_connection_id],
|
||||||
|
network[:ip],
|
||||||
|
network[:netmask])
|
||||||
|
elsif network_type == :dhcp
|
||||||
|
guest_network.configure_dhcp_interface(
|
||||||
|
interface[:index],
|
||||||
|
interface[:net_connection_id])
|
||||||
|
else
|
||||||
|
raise WindowsError, "#{network_type} network type is not supported, try static or dhcp"
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
guest_network.set_all_networks_to_work() if windows_machine.windows_config.set_work_network
|
||||||
|
end
|
||||||
|
|
||||||
|
#{1=>{:name=>"Local Area Connection", :mac_address=>"0800275FAC5B", :interface_index=>"11", :index=>"7"}}
|
||||||
|
def self.create_vm_interface_map(windows_machine, guest_network)
|
||||||
|
vm_interface_map = {}
|
||||||
|
driver_mac_address = windows_machine.read_mac_addresses.invert
|
||||||
|
@@logger.debug("mac addresses: #{driver_mac_address.inspect}")
|
||||||
|
guest_network.network_adapters().each do |nic|
|
||||||
|
@@logger.debug("nic: #{nic.inspect}")
|
||||||
|
naked_mac = nic[:mac_address].gsub(':','')
|
||||||
|
if driver_mac_address[naked_mac]
|
||||||
|
vm_interface_map[driver_mac_address[naked_mac]] = {
|
||||||
|
:net_connection_id => nic[:net_connection_id],
|
||||||
|
:mac_address => naked_mac,
|
||||||
|
:interface_index => nic[:interface_index],
|
||||||
|
:index => nic[:index] }
|
||||||
|
end
|
||||||
|
end
|
||||||
|
@@logger.debug("vm_interface_map: #{vm_interface_map.inspect}")
|
||||||
|
vm_interface_map
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
|
@ -0,0 +1,16 @@
|
||||||
|
module VagrantPlugins
|
||||||
|
module GuestWindows
|
||||||
|
module Cap
|
||||||
|
module Halt
|
||||||
|
def self.halt(machine)
|
||||||
|
# Fix vagrant-windows GH-129, if there's an existing scheduled
|
||||||
|
# reboot cancel it so shutdown succeeds
|
||||||
|
machine.communicate.execute("shutdown -a", error_check: false)
|
||||||
|
|
||||||
|
# Force shutdown the machine now
|
||||||
|
machine.communicate.execute("shutdown /s /t 1 /c \"Vagrant Halt\" /f /d p:4:1")
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
|
@ -0,0 +1,36 @@
|
||||||
|
require "vagrant/util/template_renderer"
|
||||||
|
|
||||||
|
module VagrantPlugins
|
||||||
|
module GuestWindows
|
||||||
|
module Cap
|
||||||
|
class MountSharedFolder
|
||||||
|
def self.mount_virtualbox_shared_folder(machine, name, guestpath, options)
|
||||||
|
mount_shared_folder(machine, name, guestpath, "\\\\vboxsrv\\")
|
||||||
|
end
|
||||||
|
|
||||||
|
def self.mount_vmware_shared_folder(machine, name, guestpath, options)
|
||||||
|
mount_shared_folder(machine, name, guestpath, "\\\\vmware-host\\Shared Folders\\")
|
||||||
|
end
|
||||||
|
|
||||||
|
def self.mount_parallels_shared_folder(machine, name, guestpath, options)
|
||||||
|
mount_shared_folder(machine, name, guestpath, "\\\\psf\\")
|
||||||
|
end
|
||||||
|
|
||||||
|
protected
|
||||||
|
|
||||||
|
def self.mount_shared_folder(machine, name, guestpath, vm_provider_unc_base)
|
||||||
|
name = name.gsub(/[\/\/]/,'_').sub(/^_/, '')
|
||||||
|
|
||||||
|
path = File.expand_path("../../scripts/mount_volume.ps1.erb", __FILE__)
|
||||||
|
script = Vagrant::Util::TemplateRenderer.render(path, options: {
|
||||||
|
mount_point: guestpath,
|
||||||
|
share_name: name,
|
||||||
|
vm_provider_unc_path: vm_provider_unc_base + name,
|
||||||
|
})
|
||||||
|
|
||||||
|
machine.communicate.execute(script, shell: :powershell)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
|
@ -0,0 +1,32 @@
|
||||||
|
module VagrantPlugins
|
||||||
|
module GuestWindows
|
||||||
|
class Config < Vagrant.plugin("2", :config)
|
||||||
|
attr_accessor :halt_timeout
|
||||||
|
attr_accessor :halt_check_interval
|
||||||
|
attr_accessor :set_work_network
|
||||||
|
|
||||||
|
def initialize
|
||||||
|
@halt_timeout = UNSET_VALUE
|
||||||
|
@halt_check_interval = UNSET_VALUE
|
||||||
|
@set_work_network = UNSET_VALUE
|
||||||
|
end
|
||||||
|
|
||||||
|
def validate(machine)
|
||||||
|
errors = []
|
||||||
|
|
||||||
|
errors << "windows.halt_timeout cannot be nil." if machine.config.windows.halt_timeout.nil?
|
||||||
|
errors << "windows.halt_check_interval cannot be nil." if machine.config.windows.halt_check_interval.nil?
|
||||||
|
|
||||||
|
errors << "windows.set_work_network cannot be nil." if machine.config.windows.set_work_network.nil?
|
||||||
|
|
||||||
|
{ "Windows Guest" => errors }
|
||||||
|
end
|
||||||
|
|
||||||
|
def finalize!
|
||||||
|
@halt_timeout = 30 if @halt_timeout == UNSET_VALUE
|
||||||
|
@halt_check_interval = 1 if @halt_check_interval == UNSET_VALUE
|
||||||
|
@set_work_network = false if @set_work_network == UNSET_VALUE
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
|
@ -0,0 +1,10 @@
|
||||||
|
module VagrantPlugins
|
||||||
|
module GuestWindows
|
||||||
|
class Guest < Vagrant.plugin("2", :guest)
|
||||||
|
def detect?(machine)
|
||||||
|
# See if the Windows directory is present.
|
||||||
|
machine.communicate.test("test -d $Env:SystemRoot")
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
|
@ -0,0 +1,50 @@
|
||||||
|
require "vagrant"
|
||||||
|
|
||||||
|
module VagrantPlugins
|
||||||
|
module GuestWindows
|
||||||
|
class Plugin < Vagrant.plugin("2")
|
||||||
|
name "Windows guest."
|
||||||
|
description "Windows guest support."
|
||||||
|
|
||||||
|
config("windows") do
|
||||||
|
require_relative "config"
|
||||||
|
Config
|
||||||
|
end
|
||||||
|
|
||||||
|
guest("windows") do
|
||||||
|
require_relative "guest"
|
||||||
|
Guest
|
||||||
|
end
|
||||||
|
|
||||||
|
guest_capability(:windows, :change_host_name) do
|
||||||
|
require_relative "cap/change_host_name"
|
||||||
|
Cap::ChangeHostName
|
||||||
|
end
|
||||||
|
|
||||||
|
guest_capability(:windows, :configure_networks) do
|
||||||
|
require_relative "cap/configure_networks"
|
||||||
|
Cap::ConfigureNetworks
|
||||||
|
end
|
||||||
|
|
||||||
|
guest_capability(:windows, :halt) do
|
||||||
|
require_relative "cap/halt"
|
||||||
|
Cap::Halt
|
||||||
|
end
|
||||||
|
|
||||||
|
guest_capability(:windows, :mount_virtualbox_shared_folder) do
|
||||||
|
require_relative "cap/mount_shared_folder"
|
||||||
|
Cap::MountSharedFolder
|
||||||
|
end
|
||||||
|
|
||||||
|
guest_capability(:windows, :mount_vmware_shared_folder) do
|
||||||
|
require_relative "cap/mount_shared_folder"
|
||||||
|
Cap::MountSharedFolder
|
||||||
|
end
|
||||||
|
|
||||||
|
guest_capability(:windows, :mount_parallels_shared_folder) do
|
||||||
|
require_relative "cap/mount_shared_folder"
|
||||||
|
Cap::MountSharedFolder
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
|
@ -0,0 +1,48 @@
|
||||||
|
function Test-ReparsePoint([string]$path) {
|
||||||
|
$file = Get-Item $path -Force -ea 0
|
||||||
|
return [bool]($file.Attributes -band [IO.FileAttributes]::ReparsePoint)
|
||||||
|
}
|
||||||
|
|
||||||
|
$MountPoint = [System.IO.Path]::GetFullPath("<%= options[:mount_point] %>")
|
||||||
|
$ShareName = "<%= options[:share_name] %>"
|
||||||
|
$VmProviderUncPath = "<%= options[:vm_provider_unc_path] %>"
|
||||||
|
|
||||||
|
# https://github.com/BIAINC/vagrant-windows/issues/4
|
||||||
|
# Not sure why this works, but it does.
|
||||||
|
|
||||||
|
& net use $ShareName 2>&1 | Out-Null
|
||||||
|
|
||||||
|
Write-Debug "Attempting to mount $ShareName to $MountPoint"
|
||||||
|
if( (Test-Path "$MountPoint") -and (Test-ReparsePoint "$MountPoint") )
|
||||||
|
{
|
||||||
|
Write-Debug "Junction already exists, so I will delete it"
|
||||||
|
# Powershell refuses to delete junctions, oh well use cmd
|
||||||
|
cmd /c rd "$MountPoint"
|
||||||
|
|
||||||
|
if ( $LASTEXITCODE -ne 0 )
|
||||||
|
{
|
||||||
|
Write-Error "Failed to delete symbolic link at $MountPoint"
|
||||||
|
exit 1
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
elseif(Test-Path $MountPoint)
|
||||||
|
{
|
||||||
|
Write-Debug "Mount point already exists and is not a symbolic link"
|
||||||
|
exit 1
|
||||||
|
}
|
||||||
|
|
||||||
|
$BaseDirectory = [System.IO.Path]::GetDirectoryName($MountPoint)
|
||||||
|
|
||||||
|
if (-not (Test-Path $BaseDirectory))
|
||||||
|
{
|
||||||
|
Write-Debug "Creating parent directory for mount point $BaseDirectory"
|
||||||
|
New-Item $BaseDirectory -Type Directory -Force | Out-Null
|
||||||
|
}
|
||||||
|
|
||||||
|
cmd /c mklink /D "$MountPoint" "$VmProviderUncPath" | out-null
|
||||||
|
|
||||||
|
if ( $LASTEXITCODE -ne 0 )
|
||||||
|
{
|
||||||
|
exit 1
|
||||||
|
}
|
Loading…
Reference in New Issue