vagrant-vmware-desktop 0.0.1 → 3.0.0

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 (62) hide show
  1. checksums.yaml +4 -4
  2. data/lib/vagrant-vmware-desktop.rb +190 -0
  3. data/lib/vagrant-vmware-desktop/action.rb +442 -0
  4. data/lib/vagrant-vmware-desktop/action/base_mac_to_ip.rb +55 -0
  5. data/lib/vagrant-vmware-desktop/action/boot.rb +26 -0
  6. data/lib/vagrant-vmware-desktop/action/check_existing_network.rb +35 -0
  7. data/lib/vagrant-vmware-desktop/action/check_vmware.rb +28 -0
  8. data/lib/vagrant-vmware-desktop/action/checkpoint.rb +86 -0
  9. data/lib/vagrant-vmware-desktop/action/clear_shared_folders.rb +25 -0
  10. data/lib/vagrant-vmware-desktop/action/common.rb +16 -0
  11. data/lib/vagrant-vmware-desktop/action/compatibility.rb +36 -0
  12. data/lib/vagrant-vmware-desktop/action/created.rb +20 -0
  13. data/lib/vagrant-vmware-desktop/action/destroy.rb +32 -0
  14. data/lib/vagrant-vmware-desktop/action/discard_suspended_state.rb +32 -0
  15. data/lib/vagrant-vmware-desktop/action/export.rb +29 -0
  16. data/lib/vagrant-vmware-desktop/action/fix_old_machine_id.rb +29 -0
  17. data/lib/vagrant-vmware-desktop/action/forward_ports.rb +110 -0
  18. data/lib/vagrant-vmware-desktop/action/halt.rb +27 -0
  19. data/lib/vagrant-vmware-desktop/action/import.rb +138 -0
  20. data/lib/vagrant-vmware-desktop/action/machine_lock.rb +26 -0
  21. data/lib/vagrant-vmware-desktop/action/message_already_running.rb +18 -0
  22. data/lib/vagrant-vmware-desktop/action/message_not_created.rb +18 -0
  23. data/lib/vagrant-vmware-desktop/action/message_not_running.rb +18 -0
  24. data/lib/vagrant-vmware-desktop/action/network.rb +339 -0
  25. data/lib/vagrant-vmware-desktop/action/package_vagrantfile.rb +46 -0
  26. data/lib/vagrant-vmware-desktop/action/prepare_forwarded_port_collision_params.rb +28 -0
  27. data/lib/vagrant-vmware-desktop/action/prepare_nfs_settings.rb +43 -0
  28. data/lib/vagrant-vmware-desktop/action/prepare_synced_folder_cleanup.rb +19 -0
  29. data/lib/vagrant-vmware-desktop/action/prune_forwarded_ports.rb +30 -0
  30. data/lib/vagrant-vmware-desktop/action/prune_nfs_exports.rb +22 -0
  31. data/lib/vagrant-vmware-desktop/action/running.rb +20 -0
  32. data/lib/vagrant-vmware-desktop/action/set_display_name.rb +37 -0
  33. data/lib/vagrant-vmware-desktop/action/share_folders.rb +97 -0
  34. data/lib/vagrant-vmware-desktop/action/snapshot_delete.rb +26 -0
  35. data/lib/vagrant-vmware-desktop/action/snapshot_restore.rb +26 -0
  36. data/lib/vagrant-vmware-desktop/action/snapshot_save.rb +26 -0
  37. data/lib/vagrant-vmware-desktop/action/suspend.rb +26 -0
  38. data/lib/vagrant-vmware-desktop/action/suspended.rb +24 -0
  39. data/lib/vagrant-vmware-desktop/action/vmx_modify.rb +39 -0
  40. data/lib/vagrant-vmware-desktop/action/wait_for_address.rb +31 -0
  41. data/lib/vagrant-vmware-desktop/action/wait_for_communicator_compat.rb +32 -0
  42. data/lib/vagrant-vmware-desktop/action/wait_for_vmx_halt.rb +35 -0
  43. data/lib/vagrant-vmware-desktop/cap/disk.rb +287 -0
  44. data/lib/vagrant-vmware-desktop/cap/provider.rb +37 -0
  45. data/lib/vagrant-vmware-desktop/cap/snapshot.rb +41 -0
  46. data/lib/vagrant-vmware-desktop/checkpoint_client.rb +203 -0
  47. data/lib/vagrant-vmware-desktop/config.rb +377 -0
  48. data/lib/vagrant-vmware-desktop/constants.rb +16 -0
  49. data/lib/vagrant-vmware-desktop/driver.rb +15 -0
  50. data/lib/vagrant-vmware-desktop/driver/base.rb +1356 -0
  51. data/lib/vagrant-vmware-desktop/errors.rb +342 -0
  52. data/lib/vagrant-vmware-desktop/guest_cap/linux/mount_vmware_shared_folder.rb +158 -0
  53. data/lib/vagrant-vmware-desktop/guest_cap/linux/verify_vmware_hgfs.rb +27 -0
  54. data/lib/vagrant-vmware-desktop/helper/lock.rb +26 -0
  55. data/lib/vagrant-vmware-desktop/helper/routing_table.rb +182 -0
  56. data/lib/vagrant-vmware-desktop/helper/vagrant_utility.rb +185 -0
  57. data/lib/vagrant-vmware-desktop/plugin.rb +148 -0
  58. data/lib/vagrant-vmware-desktop/provider.rb +96 -0
  59. data/lib/vagrant-vmware-desktop/setup_plugin.rb +24 -0
  60. data/lib/vagrant-vmware-desktop/synced_folder.rb +93 -0
  61. data/locales/en.yml +634 -0
  62. metadata +71 -17
@@ -0,0 +1,24 @@
1
+ require "log4r"
2
+
3
+ module HashiCorp
4
+ module VagrantVMwareDesktop
5
+ module Action
6
+ # This can be used with "Call" built-in to check if the machine
7
+ # is suspended.
8
+ class Suspended
9
+ include Common
10
+
11
+ def initialize(app, env)
12
+ @app = app
13
+ @logger = Log4r::Logger.new("hashicorp::provider::vmware::suspended")
14
+ end
15
+
16
+ def call(env)
17
+ env[:result] = env[:machine].state.id == :suspended
18
+ @logger.debug("result: #{env[:result].inspect}")
19
+ @app.call(env)
20
+ end
21
+ end
22
+ end
23
+ end
24
+ end
@@ -0,0 +1,39 @@
1
+ require "log4r"
2
+
3
+ module HashiCorp
4
+ module VagrantVMwareDesktop
5
+ module Action
6
+ # This class modifies the VMX file according to the advanced
7
+ # provider configuration.
8
+ class VMXModify
9
+ include Common
10
+
11
+ def initialize(app, env)
12
+ @app = app
13
+ @logger = Log4r::Logger.new("hashicorp::provider::vmware::vmx_modify")
14
+ end
15
+
16
+ def call(env)
17
+ vmx_changes = env[:machine].provider_config.vmx
18
+ if vmx_changes.length > 0
19
+ @logger.info("Modifying VMX file according to user config...")
20
+ env[:machine].provider.driver.vmx_modify do |vmx|
21
+ vmx_changes.each do |key, value|
22
+ if value.nil?
23
+ @logger.info(" - Delete: #{key}")
24
+ vmx.delete(key)
25
+ else
26
+ @logger.info(" - Set: #{key} = '#{value}'")
27
+ vmx[key.to_s.downcase] = value
28
+ end
29
+ end
30
+ end
31
+ end
32
+
33
+ # Carry on
34
+ @app.call(env)
35
+ end
36
+ end
37
+ end
38
+ end
39
+ end
@@ -0,0 +1,31 @@
1
+ module HashiCorp
2
+ module VagrantVMwareDesktop
3
+ module Action
4
+ class WaitForAddress
5
+ include Common
6
+
7
+ def initialize(app, env)
8
+ @app = app
9
+ end
10
+
11
+ def call(env)
12
+ env[:ui].info(
13
+ I18n.t("hashicorp.vagrant_vmware_desktop.waiting_for_address"))
14
+ while true
15
+ # If we're interrupted then just back out
16
+ return if env[:interrupted]
17
+
18
+ # If we have an IP we are don
19
+ break if env[:machine].provider.driver.read_ip(
20
+ env[:machine].provider_config.enable_vmrun_ip_lookup
21
+ )
22
+
23
+ sleep 1
24
+ end
25
+
26
+ @app.call(env)
27
+ end
28
+ end
29
+ end
30
+ end
31
+ end
@@ -0,0 +1,32 @@
1
+ module HashiCorp
2
+ module VagrantVMwareDesktop
3
+ module Action
4
+ class WaitForCommunicatorCompat
5
+ include Common
6
+
7
+ def initialize(app, env)
8
+ @app = app
9
+ end
10
+
11
+ def call(env)
12
+ env[:ui].info(
13
+ I18n.t("hashicorp.vagrant_vmware_desktop.waiting_for_boot"))
14
+ while true
15
+ # If we're interrupted then just back out
16
+ return if env[:interrupted]
17
+
18
+ if env[:machine].communicate.ready?
19
+ env[:ui].info(I18n.t(
20
+ "hashicorp.vagrant_vmware_desktop.booted_and_ready"))
21
+ break
22
+ end
23
+
24
+ sleep 2
25
+ end
26
+
27
+ @app.call(env)
28
+ end
29
+ end
30
+ end
31
+ end
32
+ end
@@ -0,0 +1,35 @@
1
+ require "log4r"
2
+
3
+ module HashiCorp
4
+ module VagrantVMwareDesktop
5
+ module Action
6
+ # This waits for the actual "vmx" process to finish running.
7
+ class WaitForVMXHalt
8
+ include Common
9
+
10
+ def initialize(app, env)
11
+ @app = app
12
+ @logger = Log4r::Logger.new("hashicorp::provider::vmware::wait_for_vmx_halt")
13
+ end
14
+
15
+ def call(env)
16
+ @logger.info("Waiting for VMX process to go away...")
17
+ if env[:machine].provider.driver.vmx_alive?
18
+ env[:ui].info(I18n.t("hashicorp.vagrant_vmware_desktop.waiting_for_vmx_halt"))
19
+
20
+ 60.times do |i|
21
+ if !env[:machine].provider.driver.vmx_alive?
22
+ @logger.info("VMX process went away!")
23
+ break
24
+ end
25
+
26
+ sleep 1
27
+ end
28
+ end
29
+
30
+ @app.call(env)
31
+ end
32
+ end
33
+ end
34
+ end
35
+ end
@@ -0,0 +1,287 @@
1
+ require "vagrant/util/experimental"
2
+ require "vagrant/util/numeric"
3
+
4
+ module HashiCorp
5
+ module VagrantVMwareDesktop
6
+ module Cap
7
+ module Disk
8
+
9
+ @@logger = Log4r::Logger.new("hashicorp::provider::vmware::cap::disk")
10
+
11
+ DEFAULT_DISK_EXT = "vmdk".freeze
12
+ BUS_TYPES = ["sata", "ide", "scsi"].map(&:freeze).freeze
13
+ DEFAULT_BUS = "scsi".freeze
14
+ DEFAULT_DVD_BUS = "ide".freeze
15
+ DEFAULT_DVD_DEVICE_TYPE = "cdrom-image"
16
+ # Adapter types (from vmware-vdiskmanager -h)
17
+ DISK_ADAPTER_TYPES = ["ide", "buslogic", "lsilogic"].map(&:freeze).freeze
18
+ DEFAULT_ADAPTER_TYPE = "lsilogic".freeze
19
+ # Disk types (from vmware-vdiskmanager -h)
20
+ # 0 : single growable virtual disk
21
+ # 1 : growable virtual disk split into multiple files
22
+ # 2 : preallocated virtual disk
23
+ # 3 : preallocated virtual disk split into multiple files
24
+ # 4 : preallocated ESX-type virtual disk
25
+ # 5 : compressed disk optimized for streaming
26
+ # 6 : thin provisioned virtual disk - ESX 3.x and above
27
+ DEFAULT_DISK_TYPE = 0.freeze
28
+ PRIMARY_DISK_SLOT = "scsi0:0".freeze
29
+
30
+ def self.set_default_disk_ext(machine)
31
+ DEFAULT_DISK_EXT
32
+ end
33
+
34
+ def self.default_disk_exts(machine)
35
+ [DEFAULT_DISK_EXT].freeze
36
+ end
37
+
38
+ # @param [Vagrant::Machine] machine
39
+ # @param [VagrantPlugins::Kernel_V2::VagrantConfigDisk] defined_disks
40
+ # @return [Hash] configured_disks - A hash of all the current configured disks
41
+ def self.configure_disks(machine, defined_disks)
42
+ return {} if defined_disks.empty?
43
+
44
+ attached_disks = machine.provider.driver.get_disks(BUS_TYPES)
45
+ configured_disks = {disk: [], floppy: [], dvd: []}
46
+
47
+ defined_disks.each do |disk|
48
+ case disk.type
49
+ when :disk
50
+ disk_data = setup_disk(machine, disk, attached_disks)
51
+ if !disk_data.empty?
52
+ configured_disks[:disk] << disk_data
53
+ end
54
+ when :floppy
55
+ # TODO: Write me
56
+ machine.ui.info(I18n.t("hashicorp.vagrant_vmware_desktop.cap.disks.floppy_not_supported", name: disk.name))
57
+ when :dvd
58
+ disk_data = setup_dvd(machine, disk, attached_disks)
59
+ if !disk_data.empty?
60
+ configured_disks[:dvd] << disk_data
61
+ end
62
+ else
63
+ @@logger.info("Invalid disk type #{disk.type}, carrying on.")
64
+ end
65
+ end
66
+
67
+ configured_disks
68
+ end
69
+
70
+ # @param [Vagrant::Machine] machine
71
+ # @param [VagrantPlugins::Kernel_V2::VagrantConfigDisk] defined_disks
72
+ # @param [Hash] disk_meta - A hash of all the previously defined disks
73
+ # from the last configure_disk action
74
+ # @return [nil]
75
+ def self.cleanup_disks(machine, defined_disks, disk_meta)
76
+ return if disk_meta.values.flatten.empty?
77
+
78
+ ["disk", "dvd"].each do |k|
79
+ if !disk_meta[k].is_a?(Array)
80
+ raise TypeError, "Expected `Array` but received `#{disk_meta[k].class}`"
81
+ end
82
+ end
83
+
84
+ # TODO: floppy
85
+ disk_meta["disk"].each do |d|
86
+ # If disk is defined or the primary disk, don't remove
87
+ if d["primary"]
88
+ @@logger.warn("Vagrant will not clean up the primary disk! Primary disk no longer tracked in Vagrantfile")
89
+ next
90
+ end
91
+ next if defined_disks.any? { |dsk| dsk.name == d["Name"]}
92
+ machine.provider.driver.remove_disk(File.basename(d["Path"]))
93
+ end
94
+
95
+ disk_meta["dvd"].each do |d|
96
+ # If disk is defined, don't remove
97
+ next if defined_disks.any? { |dsk| dsk.name == d["Name"]}
98
+ machine.provider.driver.remove_disk_from_vmx(d["Path"], ["deviceType"])
99
+ end
100
+ nil
101
+ end
102
+
103
+ protected
104
+
105
+ # Retrieves a disk from a Hash of all the disks
106
+ #
107
+ # @param [Config::Disk] disk - the current disk to configure
108
+ # @param [Hash] all_disks - A hash of all currently defined disks
109
+ # @return [Hash, nil] - A hash of the current disk, nil if not found
110
+ def self.get_disk(disk, all_disks)
111
+ if disk.primary
112
+ return all_disks[PRIMARY_DISK_SLOT]
113
+ else
114
+ if disk.type == :dvd
115
+ all_disks.values.detect { |v| v["filename"] == disk.file }
116
+ else
117
+ all_disks.values.detect do |v|
118
+ m_ext = File.extname(v["filename"])
119
+ m_fil = v["filename"].sub(/#{Regexp.escape(m_ext)}$/, "")
120
+ m_ext.sub!(".", "")
121
+ m_ext == disk.disk_ext &&
122
+ (m_fil == disk.name || m_fil =~ /^#{Regexp.escape(disk.name)}-\d+$/)
123
+ end
124
+ end
125
+ end
126
+ end
127
+
128
+ # Sets up all disk configs of type `:disk`
129
+ #
130
+ # @param [Vagrant::Machine] machine - the current machine
131
+ # @param [Config::Disk] disk - the current disk to configure
132
+ # @param [Array] all_disks - A list of all currently defined disks in VirtualBox
133
+ # @return [Hash] - disk_metadata
134
+ def self.setup_disk(machine, disk, attached_disks)
135
+ current_disk = get_disk(disk, attached_disks)
136
+
137
+ if current_disk.nil?
138
+ disk_path = create_disk(machine, disk, attached_disks)
139
+ else
140
+ # If the path matches the disk name + some extra characters then
141
+ # make sure to remove the extra characters. They may take the form
142
+ # <name>-f.vmdk, <name>-f<num>.vmdk, <name>-s<num>.vmdk, <name>-s.vmdk, <name>-flat.vmdk, <name>-delta.vmdk
143
+ # ref: https://github.com/libyal/libvmdk/blob/master/documentation/VMWare%20Virtual%20Disk%20Format%20(VMDK).asciidoc
144
+ if current_disk["filename"].match(/\w+-(f\d*|s\d*|flat|delta).vmdk/)
145
+ file_name = current_disk["filename"].gsub(/-(f\d*|s\d*|flat|delta)/, "")
146
+ disk_path = File.join(File.dirname(machine.provider.driver.vmx_path), file_name)
147
+ else
148
+ disk_path = File.join(File.dirname(machine.provider.driver.vmx_path), current_disk["filename"])
149
+ end
150
+
151
+ # disk.size is in bytes
152
+ if disk.size > machine.provider.driver.get_disk_size(disk_path)
153
+ grow_disk(machine, disk_path, disk)
154
+ elsif disk.size < machine.provider.driver.get_disk_size(disk_path)
155
+ machine.env.ui.warn(I18n.t("hashicorp.vagrant_vmware_desktop.disk_not_shrinking", path: disk.name))
156
+ @@logger.warn("Not shrinking disk #{disk.name}")
157
+ else
158
+ @@logger.info("Not changing #{disk.name}")
159
+ end
160
+ end
161
+ {UUID: disk.id, Name: disk.name, Path: disk_path, primary: !!disk.primary}
162
+ end
163
+
164
+ # Sets up all disk configs of type `:dvd`
165
+ #
166
+ # @param [Vagrant::Machine] machine - the current machine
167
+ # @param [Config::Disk] disk - the current disk to configure
168
+ # @param [Array] all_disks - A list of all currently defined disks in VirtualBox
169
+ # @return [Hash] - disk_metadata
170
+ def self.setup_dvd(machine, disk, attached_disks)
171
+ disk_provider_config = {}
172
+ if disk.provider_config && disk.provider_config.key?(:vmware_desktop)
173
+ disk_provider_config = disk.provider_config[:vmware_desktop]
174
+ if !BUS_TYPES.include?(disk_provider_config[:bus_type])
175
+ disk_provider_config[:bus_type] = DEFAULT_DVD_BUS
176
+ @@logger.warn("#{disk_provider_config[:bus_type]} is not a valid. Should be one of " \
177
+ "#{BUS_TYPES.join(', ')}! Setting adapter type to #{DEFAULT_DVD_BUS}")
178
+ end
179
+ end
180
+
181
+ current_disk = get_disk(disk, attached_disks)
182
+ bus = disk_provider_config.fetch(:bus_type, DEFAULT_DVD_BUS)
183
+ if current_disk.nil?
184
+ # Attach dvd if not already attached
185
+ slot = get_slot(bus, attached_disks)
186
+ dvd_opts = {"deviceType" => disk_provider_config.fetch(:device_type, DEFAULT_DVD_DEVICE_TYPE)}
187
+ machine.provider.driver.add_disk_to_vmx(disk.file, slot, dvd_opts)
188
+ # Add newly attached disk
189
+ attached_disks[slot] = {"filename" => disk.file}
190
+ end
191
+ {UUID: disk.id, Name: disk.name, Path: disk.file, primary: !!disk.primary}
192
+ end
193
+
194
+ # Creates a disk and attaches disk by editing the machine's vmx data
195
+ #
196
+ # @param [Vagrant::Machine] machine
197
+ # @param [Kernel_V2::VagrantConfigDisk] disk_config
198
+ # @return [String] full path to disk file
199
+ def self.create_disk(machine, disk_config, attached_disks)
200
+ if disk_config.file.nil? || !File.exist?(disk_config.file)
201
+ # Create a new disk if a file is not provided, or that path does not exist
202
+ disk_filename = "#{disk_config.name}.#{disk_config.disk_ext}"
203
+ disk_provider_config = {}
204
+
205
+ if disk_config.provider_config && disk_config.provider_config.key?(:vmware_desktop)
206
+ disk_provider_config = disk_config.provider_config[:vmware_desktop]
207
+ if !DISK_ADAPTER_TYPES.include?(disk_provider_config[:adapter_type])
208
+ disk_provider_config[:adapter_type] = DEFAULT_ADAPTER_TYPE
209
+ @@logger.warn("#{disk_provider_config[:adapter_type]} is not a valid. Should be one " \
210
+ "of #{DISK_ADAPTER_TYPES.join(', ')}! Setting adapter type to #{DEFAULT_ADAPTER_TYPE}")
211
+ end
212
+ if !BUS_TYPES.include?(disk_provider_config[:bus_type])
213
+ disk_provider_config[:bus_type] = DEFAULT_BUS
214
+ @@logger.warn("#{disk_provider_config[:bus_type]} is not a valid. Should be one of " \
215
+ "#{BUS_TYPES.join(', ')}! Setting adapter type to #{DEFAULT_BUS}")
216
+ end
217
+ end
218
+ disk_type = DEFAULT_DISK_TYPE
219
+ disk_adapter = disk_provider_config.fetch(:adapter_type, DEFAULT_ADAPTER_TYPE)
220
+ bus = disk_provider_config.fetch(:bus_type, DEFAULT_BUS)
221
+ disk_path = machine.provider.driver.create_disk(disk_filename, disk_config.size, disk_type, disk_adapter)
222
+ else
223
+ # Don't create a new disk if one is provided by `file` config argument
224
+ disk_path = disk_config.file
225
+ end
226
+
227
+ slot = get_slot(bus, attached_disks)
228
+ machine.provider.driver.add_disk_to_vmx(File.basename(disk_path), slot)
229
+ # Add newly attached disk
230
+ attached_disks[slot] = { "filename" => disk_filename }
231
+ disk_path
232
+ end
233
+
234
+ # Expand an existing disk
235
+ #
236
+ # @param [Vagrant::Machine] machine
237
+ # @param [String] disk_path Path to disk for expansion
238
+ # @param [VagrantPlugins::Kernel_V2::VagrantConfigDisk] disk_config
239
+ # @return [nil]
240
+ def self.grow_disk(machine, disk_path, disk_config)
241
+ if machine.provider.driver.snapshot_list.empty?
242
+ machine.provider.driver.grow_disk(disk_path, disk_config.size)
243
+ else
244
+ raise Errors::DiskNotResizedSnapshot, path: disk_path
245
+ end
246
+ nil
247
+ end
248
+
249
+ # Gets the next slot available
250
+ #
251
+ # @param [String] bus name, one of BUS_TYPES
252
+ # @param [Hash] attached disks
253
+ def self.get_slot(bus, attached_disks)
254
+ bus_num = 0
255
+ slot_num = 0
256
+ attached_disks.keys.each do |k|
257
+ s = k.match(/(?<=#{bus})(\d+:\d+)/)
258
+ if !s.nil?
259
+ bus_and_slot = s[0].split(":")
260
+ if bus_and_slot[0].to_i > bus_num
261
+ bus_num = bus_and_slot[0].to_i
262
+ # reset slot num
263
+ slot_num = 0
264
+ end
265
+ if bus_and_slot[1].to_i > slot_num
266
+ slot_num = bus_and_slot[1].to_i
267
+ end
268
+ end
269
+ end
270
+
271
+ # For ide bus the slot number must be 0 or 1
272
+ if bus.to_s == "ide"
273
+ bus_num = bus_num + (slot_num%2)
274
+ slot_num = (slot_num+1)%2
275
+ if bus_num > 1
276
+ @@logger.warn("attaching disk to #{bus}#{bus_num}:#{slot_num}, this will " \
277
+ "likely cause the disk to be unavailable, consider attaching the disk to a different bus")
278
+ end
279
+ else
280
+ slot_num = slot_num + 1
281
+ end
282
+ "#{bus}#{bus_num}:#{slot_num}"
283
+ end
284
+ end
285
+ end
286
+ end
287
+ end