vagrant-windows-hyperv 1.0.2 → 1.0.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (30) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +34 -0
  3. data/README.md +22 -11
  4. data/lib/vagrant-windows-hyperv.rb +4 -1
  5. data/lib/vagrant-windows-hyperv/action.rb +0 -19
  6. data/lib/vagrant-windows-hyperv/communication/powershell.rb +7 -3
  7. data/lib/vagrant-windows-hyperv/errors.rb +20 -0
  8. data/lib/vagrant-windows-hyperv/monkey_patch/action.rb +45 -0
  9. data/lib/vagrant-windows-hyperv/monkey_patch/action/customize.rb +167 -0
  10. data/lib/vagrant-windows-hyperv/monkey_patch/action/import.rb +72 -0
  11. data/lib/vagrant-windows-hyperv/monkey_patch/action/provision.rb +5 -1
  12. data/lib/vagrant-windows-hyperv/monkey_patch/config.rb +51 -0
  13. data/lib/vagrant-windows-hyperv/monkey_patch/driver.rb +52 -0
  14. data/lib/vagrant-windows-hyperv/monkey_patch/machine.rb +3 -3
  15. data/lib/vagrant-windows-hyperv/monkey_patch/plugins/synced_folders/smb/synced_folders.rb +3 -0
  16. data/lib/vagrant-windows-hyperv/monkey_patch/scripts/add_switch_to_vm.ps1 +38 -0
  17. data/lib/vagrant-windows-hyperv/monkey_patch/scripts/create_switch.ps1 +75 -0
  18. data/lib/vagrant-windows-hyperv/monkey_patch/scripts/find_vm_switch_name.ps1 +29 -0
  19. data/lib/vagrant-windows-hyperv/monkey_patch/scripts/get_adapters.ps1 +17 -0
  20. data/lib/vagrant-windows-hyperv/monkey_patch/scripts/import_vm.ps1 +136 -0
  21. data/lib/vagrant-windows-hyperv/monkey_patch/scripts/switch_exist.ps1 +54 -0
  22. data/lib/vagrant-windows-hyperv/monkey_patch/scripts/utils/write_messages.ps1 +20 -0
  23. data/lib/vagrant-windows-hyperv/provisioner/puppet.rb +2 -2
  24. data/lib/vagrant-windows-hyperv/scripts/check_winrm.ps1 +7 -3
  25. data/lib/vagrant-windows-hyperv/scripts/upload_file.ps1 +29 -3
  26. data/lib/vagrant-windows-hyperv/scripts/utils/create_session.ps1 +19 -5
  27. data/lib/vagrant-windows-hyperv/version.rb +1 -1
  28. data/locales/en.yml +60 -3
  29. metadata +15 -3
  30. data/lib/vagrant-windows-hyperv/monkey_patch/util/powershell.rb +0 -37
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 5c543d48b0bf549e9a16af50a1220ab9772d56bc
4
- data.tar.gz: 49b974b06708790c44b75fe1ea0f4e0e17b94746
3
+ metadata.gz: 3ec3d21bd91cb656dd09945f257732260efef0eb
4
+ data.tar.gz: c82d9db8c20462cbd51aac9344c997b1dc27bd06
5
5
  SHA512:
6
- metadata.gz: 7dc2347aa090830468f2c728cb6eb829d92082bdcde0e3b988905234b2fbf0ed1b41c051e14c3dbe35be7c87278d113f3f5338500cdcd332f7eb2916bc72493e
7
- data.tar.gz: 6fea9e4d12c07edf17c55b759481f4d62dbb1960973b2872000ac18184da0278bdb8750c9368b01b63ecc3bed737524c316ffe913e20a48873fe13caf0221aaf
6
+ metadata.gz: 8a7437d5ef7f8d44cb1dbf11e0cb761936cc663379e3dc17b0e5753e2eaacad80a29c89aaf0e6c123d779236faf33fc0ef073c81d254267dd38cd94bf229f3a3
7
+ data.tar.gz: 24e275ff6272b99b6f34f27b88277230963e9f40a8c6e76591e269423d389f7f079ba679228531c1c1713e41d0130258bc5082e748d5515380a15ffcbdfc3e02
@@ -0,0 +1,34 @@
1
+ ## 1.0.3 (13 May 2014)
2
+
3
+ FEATURES
4
+
5
+ #### Customization for Virtual Switch
6
+ - Add customization for adding virtual switch. User can choose either External or
7
+ Internal switch which will be attached to the VM on `vagrant up` or `vagrant reload`
8
+ - **NOTE:** Vagrant works best with External switch, if you are using an Internal switch
9
+ make sure the switch is properly configured for vagrant to communicate with the VM and
10
+ the VM back to the host.
11
+ - Example for configuration
12
+ NOTE:
13
+ If the adapter part if left blank, a list of available adapters will be displayed
14
+ and the desired adapter can be selected.
15
+
16
+ ```ruby
17
+ config.vm.provider "hyperv" do |hv|
18
+ hv.customize ["virtual_switch", { type: "External", name: "External Switch", :adapter => "Ethernet" }]
19
+ end
20
+ ```
21
+
22
+ IMPROVEMENTS
23
+
24
+ - Better error messages for PowerShell communication fails.
25
+ - Better exception handling for PowerShell sessions.
26
+
27
+ BUGFIXES
28
+
29
+ - Fix module path for Puppet manifests.
30
+ - Fix race condition while enabling Guest Services [GH-61]
31
+
32
+ ## Previous
33
+
34
+ See git commit
data/README.md CHANGED
@@ -6,15 +6,15 @@ Hyper-V provider is available by default in Vagrant with version 1.5 and up. Thi
6
6
 
7
7
 
8
8
  ## Installation
9
- Install Vagrant 1.5 (or higher)
9
+ Install Vagrant 1.5.4
10
10
  http://www.vagrantup.com/downloads.html
11
11
 
12
12
 
13
- Install plugin like so:
13
+ Install plugin like so:
14
14
  vagrant plugin install vagrant-windows-hyperv
15
15
 
16
16
 
17
- ## Configuration settings
17
+ ## Configuration settings
18
18
  For more information on general configuration settings please visit the Vagrant Documentation.
19
19
  http://docs.vagrantup.com/v2/
20
20
 
@@ -29,17 +29,17 @@ implementation for the providers.
29
29
  You can even specify the following options
30
30
 
31
31
  :smb_id Specify a unique share name, with which the network share will be available. By default vagrant will generate a smb_id if not specified.
32
-
32
+
33
33
 
34
34
 
35
35
 
36
36
  ```ruby
37
37
  # Mounts the host/path to guest/path and will have realtime sync
38
- config.vm.synced_folder 'C:/test_sync_2', "C:/Users/vagrant/test_sync_2"
38
+ config.vm.synced_folder 'C:/test_sync_2', "C:/Users/vagrant/test_sync_2"
39
39
 
40
40
  ```
41
41
  ### VM Type
42
- * Set the VM guest type
42
+ * Set the VM guest type
43
43
 
44
44
  ```ruby
45
45
  config.vm.guest = :windows
@@ -57,11 +57,22 @@ end
57
57
  * A new command vagrant rdp is introduced to connect to the Windows VM
58
58
  ` vagrant rdp `
59
59
 
60
-
61
- ### Provision Command
62
- * Provision command works for Vagrant hyper-v with this plugin installed
63
- ` vagrant provision `
64
-
60
+ ### Customization
61
+ * Add customization for adding virtual switch. User can choose either External or
62
+ Internal switch which will be attached to the VM on `vagrant up` or `vagrant reload`
63
+ - **NOTE:** Vagrant works best with External switch, if you are using an Internal switch
64
+ make sure the switch is properly configured for vagrant to communicate with the VM and
65
+ the VM back to the host.
66
+ - Example for configuration
67
+
68
+ **NOTE:** If the adapter part if left blank, a list of available adapters will be displayed
69
+ and the desired adapter can be selected.
70
+
71
+ ```ruby
72
+ config.vm.provider "hyperv" do |hv|
73
+ hv.customize ["virtual_switch", { type: "External", name: "External Switch", :adapter => "Ethernet" }]
74
+ end
75
+ ```
65
76
 
66
77
  ## Troubleshooting
67
78
 
@@ -25,8 +25,11 @@ module VagrantPlugins
25
25
  # Monkey Patch the core Hyper-V vagrant with the following
26
26
  require monkey_patch.join("plugins/synced_folders/smb/synced_folders")
27
27
  require monkey_patch.join("action/provision")
28
+ require monkey_patch.join("action/import")
28
29
  require monkey_patch.join("machine")
29
- require monkey_patch.join("util/powershell")
30
+ require monkey_patch.join("config")
31
+ require monkey_patch.join("action")
32
+ require monkey_patch.join("driver")
30
33
 
31
34
  # This returns the path to the source of this plugin.
32
35
  #
@@ -52,25 +52,6 @@ module VagrantPlugins
52
52
  end
53
53
  end
54
54
 
55
- def self.action_provision
56
- Vagrant::Action::Builder.new.tap do |b|
57
- b.use ConfigValidate
58
- b.use Call, IsState, :not_created do |env1, b1|
59
- if env1[:result]
60
- b1.use Message, I18n.t("vagrant_hyperv.message_not_created")
61
- next
62
- end
63
- b1.use Call, IsState, :running do |env2, b2|
64
- if !env2[:result]
65
- b2.use Message, I18n.t("vagrant_hyperv.message_not_running")
66
- else
67
- b2.use Provision
68
- end
69
- end
70
- end
71
- end
72
- end
73
-
74
55
  # The autoload farm
75
56
  action_root = Pathname.new(File.expand_path("../action", __FILE__))
76
57
  autoload :Export, action_root.join("export")
@@ -20,10 +20,14 @@ module VagrantPlugins
20
20
  # In this case we can try any remote PowerShell commands to see if
21
21
  # further vagrant can be carried out using this communication
22
22
  if !@winrm_status
23
- status = false
23
+ @winrm_status = false
24
24
  response = @machine.provider.driver.check_winrm
25
- @winrm_status = response["message"] == "Running"
26
- raise Errors::WinRMNotReady if !@winrm_status
25
+ message = nil
26
+ if response && response["message"]
27
+ message = response["message"]
28
+ @winrm_status = message == "Running"
29
+ end
30
+ raise Errors::WinRMNotReady, message: message if !@winrm_status
27
31
  end
28
32
  @winrm_status
29
33
  end
@@ -26,6 +26,26 @@ module VagrantPlugins
26
26
  error_key(:win_rm_not_available)
27
27
  end
28
28
 
29
+ class NoNetworkAdapter < VagrantHyperVError
30
+ error_key(:no_network_adapter)
31
+ end
32
+
33
+ class NoSwitches < VagrantHyperVError
34
+ error_key(:no_switches)
35
+ end
36
+
37
+ class NetworkDown < VagrantHyperVError
38
+ error_key(:network_down)
39
+ end
40
+
41
+ class NoSwitchFound < VagrantHyperVError
42
+ error_key(:switch_not_found)
43
+ end
44
+
45
+ class ExternalSwitchExist < VagrantHyperVError
46
+ error_key(:external_switch_exist)
47
+ end
48
+
29
49
  end
30
50
  end
31
51
  end
@@ -0,0 +1,45 @@
1
+ #-------------------------------------------------------------------------
2
+ # Copyright (c) Microsoft Open Technologies, Inc.
3
+ # All Rights Reserved. Licensed under the Apache 2.0 License.
4
+ #--------------------------------------------------------------------------
5
+
6
+ module VagrantPlugins
7
+ module HyperV
8
+ module Action
9
+
10
+ def self.action_up
11
+ Vagrant::Action::Builder.new.tap do |b|
12
+ b.use CheckEnabled
13
+ b.use HandleBox
14
+ b.use ConfigValidate
15
+ b.use Call, IsState, :not_created do |env1, b1|
16
+ if env1[:result]
17
+ b1.use Import
18
+ end
19
+ b1.use Customize, "pre-boot"
20
+ b1.use action_start
21
+ end
22
+ end
23
+ end
24
+
25
+ def self.action_reload
26
+ Vagrant::Action::Builder.new.tap do |b|
27
+ b.use ConfigValidate
28
+ b.use Call, IsState, :not_created do |env, b2|
29
+ if env[:result]
30
+ b2.use Message, I18n.t("vagrant_hyperv.message_not_created")
31
+ next
32
+ end
33
+
34
+ b2.use action_halt
35
+ b2.use Customize, "pre-boot"
36
+ b2.use action_start
37
+ end
38
+ end
39
+ end
40
+ action_root = Pathname.new(File.expand_path("../action", __FILE__))
41
+ autoload :Customize, action_root.join("customize")
42
+
43
+ end
44
+ end
45
+ end
@@ -0,0 +1,167 @@
1
+ #-------------------------------------------------------------------------
2
+ # Copyright (c) Microsoft Open Technologies, Inc.
3
+ # All Rights Reserved. Licensed under the MIT License.
4
+ #--------------------------------------------------------------------------
5
+
6
+ require "log4r"
7
+
8
+ module VagrantPlugins
9
+ module HyperV
10
+ module Action
11
+ class Customize
12
+
13
+ def initialize(app, env, event)
14
+ @app = app
15
+ @logger = Log4r::Logger.new("vagrant::hyperv::connection")
16
+ @event = event
17
+ end
18
+
19
+ def call(env)
20
+ customizations = []
21
+ @env = env
22
+ # FIXME:
23
+ # Currently we are unable to set a default value for the customizations
24
+ # to the vagrant core Config initialization. This check should be removed
25
+ # when this code becomes a part of vagrant core.
26
+ custom_config = env[:machine].provider_config.customizations
27
+ if custom_config
28
+ custom_config.each do |event, command|
29
+ if event == @event
30
+ customizations << command
31
+ end
32
+ end
33
+ end
34
+
35
+ if !customizations.empty?
36
+ env[:ui].info I18n.t("vagrant.actions.vm.customize.running", event: @event)
37
+ customizations.each do |query|
38
+ command = query[0]
39
+ params = query[1]
40
+ if self.respond_to?("custom_action_#{command}")
41
+ self.send("custom_action_#{command}", params)
42
+ end
43
+ end
44
+ end
45
+
46
+ validate_virtual_switch
47
+ @app.call(env)
48
+ end
49
+
50
+ def custom_action_virtual_switch(params)
51
+ options = { vm_id: @env[:machine].id,
52
+ type: (params[:type] || "").downcase || "external",
53
+ name: params[:name],
54
+ adapter: (params[:bridge] || "").downcase
55
+ }
56
+
57
+ if options[:type] == "private"
58
+ @env[:ui].detail I18n.t("vagrant_win_hyperv.private_switch_not_allowed")
59
+ return
60
+ end
61
+
62
+ response = @env[:machine].provider.driver.switch_exist({ name: options[:name],
63
+ type: options[:type]})
64
+
65
+ if options[:type] == "internal"
66
+ @env[:ui].detail(" ")
67
+ @env[:ui].detail I18n.t("vagrant_win_hyperv.internal_switch_warn")
68
+ @env[:ui].detail(" ")
69
+ if response["message"] == "switch exist"
70
+ add_swith_to_vm(options)
71
+ return
72
+ else
73
+ raise VagrantPlugins::VagrantHyperV::Errors::NoSwitchFound,
74
+ type: options[:type], name: options[:name]
75
+ end
76
+ end
77
+
78
+ if options[:type] == "external"
79
+ if response["message"] == "switch exist"
80
+ if (response["switch_name"].casecmp(options[:name]) == 0)
81
+ add_swith_to_vm(options)
82
+ return
83
+ else
84
+ raise VagrantPlugins::VagrantHyperV::Errors::ExternalSwitchExist, name: response["switch_name"]
85
+ end
86
+ end
87
+
88
+ adapters = @env[:machine].provider.driver.list_net_adapters
89
+ available_adapters = adapters.map { |a| a["Name"].downcase }
90
+
91
+ unless available_adapters.include? (options[:adapter])
92
+ @env[:ui].detail I18n.t("vagrant_win_hyperv.net_adapter_warn")
93
+ selected_adapter = choose_option_from(adapters, "adapter")
94
+ options[:adapter] = selected_adapter["Name"]
95
+ end
96
+
97
+ @env[:ui].info I18n.t("vagrant_win_hyperv.creating_switch",
98
+ { type: options[:type], name: options[:name] })
99
+ response = @env[:machine].provider.driver.create_network_switch(options)
100
+ case response["message"]
101
+ when "Network down"
102
+ # TODO: Create a error class in core vagrant when merged.
103
+ raise VagrantPlugins::VagrantHyperV::Errors::NetworkDown
104
+ when "Success"
105
+ add_swith_to_vm(options)
106
+ end
107
+ end
108
+ end
109
+
110
+ def add_swith_to_vm(options)
111
+ current_vm_switch = @env[:machine].provider.driver.find_vm_switch_name
112
+ if current_vm_switch["network_adapter"].nil?
113
+ raise VagrantPlugins::VagrantHyperV::Errors::NoNetworkAdapter
114
+ end
115
+ @env[:machine].provider.driver.add_swith_to_vm(options)
116
+ end
117
+
118
+ def validate_virtual_switch
119
+ @env[:ui].info "Validating Virtual Switch"
120
+ current_vm_switch = @env[:machine].provider.driver.find_vm_switch_name
121
+
122
+ if current_vm_switch["switch_name"].nil?
123
+ switches = @env[:machine].provider.driver.execute("get_switches.ps1", {})
124
+ raise VagrantPlugins::VagrantHyperV::Errors::NoSwitches if switches.empty?
125
+
126
+ switch = choose_option_from(switches, "switch")
127
+ switch_type = nil
128
+ case switch["SwitchType"]
129
+ when 1
130
+ switch_type = "Internal"
131
+ when 2
132
+ switch_type = "External"
133
+ end
134
+
135
+ options = { vm_id: @env[:machine].id,
136
+ type: switch_type.downcase,
137
+ name: switch["Name"]
138
+ }
139
+ @env[:ui].info I18n.t("vagrant_win_hyperv.add_switch_to_vm",
140
+ { type: options[:type], name: options[:name] })
141
+
142
+ add_swith_to_vm(options)
143
+ end
144
+ end
145
+
146
+ private
147
+ def choose_option_from(options, key)
148
+ @env[:ui].detail(I18n.t("vagrant_win_hyperv.choose_#{key}") + "\n ")
149
+ options.each_index do |i|
150
+ option = options[i]
151
+ @env[:ui].detail("#{i+1}) #{option["Name"]}")
152
+ end
153
+ @env[:ui].detail(" ")
154
+
155
+ selected = nil
156
+ while !selected
157
+ selected = @env[:ui].ask("What #{key} would you like to use? ")
158
+ next if !selected
159
+ selected = selected.to_i - 1
160
+ selected = nil if selected < 0 || selected >= options.length
161
+ end
162
+ options[selected]
163
+ end
164
+ end
165
+ end
166
+ end
167
+ end
@@ -0,0 +1,72 @@
1
+ #-------------------------------------------------------------------------
2
+ # Copyright (c) Microsoft Open Technologies, Inc.
3
+ # All Rights Reserved. Licensed under the Apache 2.0 License.
4
+ #--------------------------------------------------------------------------
5
+
6
+ require "fileutils"
7
+
8
+ require "log4r"
9
+
10
+ module VagrantPlugins
11
+ module HyperV
12
+ module Action
13
+ class Import
14
+ def initialize(app, env)
15
+ @app = app
16
+ @logger = Log4r::Logger.new("vagrant::hyperv::import")
17
+ end
18
+
19
+ def call(env)
20
+ vm_dir = env[:machine].box.directory.join("Virtual Machines")
21
+ hd_dir = env[:machine].box.directory.join("Virtual Hard Disks")
22
+
23
+ if !vm_dir.directory? || !hd_dir.directory?
24
+ raise Errors::BoxInvalid
25
+ end
26
+
27
+ config_path = nil
28
+ vm_dir.each_child do |f|
29
+ if f.extname.downcase == ".xml"
30
+ config_path = f
31
+ break
32
+ end
33
+ end
34
+
35
+ vhdx_path = nil
36
+ hd_dir.each_child do |f|
37
+ if f.extname.downcase == ".vhdx"
38
+ vhdx_path = f
39
+ break
40
+ end
41
+ end
42
+
43
+ if !config_path || !vhdx_path
44
+ raise Errors::BoxInvalid
45
+ end
46
+
47
+ env[:ui].output("Importing a Hyper-V instance")
48
+
49
+ env[:ui].detail("Cloning virtual hard drive...")
50
+ source_path = vhdx_path.to_s
51
+ dest_path = env[:machine].data_dir.join("disk.vhdx").to_s
52
+ FileUtils.cp(source_path, dest_path)
53
+ vhdx_path = dest_path
54
+
55
+ # We have to normalize the paths to be Windows paths since
56
+ # we're executing PowerShell.
57
+ options = {
58
+ vm_xml_config: config_path.to_s.gsub("/", "\\"),
59
+ vhdx_path: vhdx_path.to_s.gsub("/", "\\")
60
+ }
61
+
62
+ env[:ui].detail("Creating and registering the VM...")
63
+ server = env[:machine].provider.driver.import(options)
64
+ env[:ui].detail("Successfully imported a VM with name: #{server['name']}")
65
+ env[:machine].id = server["id"]
66
+ @app.call(env)
67
+ end
68
+
69
+ end
70
+ end
71
+ end
72
+ end