vagrant-windows-hyperv 1.0.2 → 1.0.3

Sign up to get free protection for your applications and to get access to all the features.
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