vagrant_utm 0.0.1 → 0.1.1

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 (47) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +43 -3
  3. data/README.md +1 -3
  4. data/docs/_config.yml +5 -6
  5. data/docs/assets/images/screens/debian-10.4-i3-arm64.png +0 -0
  6. data/docs/boxes/creating_utm_box.md +46 -19
  7. data/docs/boxes/utm_box_gallery.md +17 -93
  8. data/docs/commands.md +12 -8
  9. data/docs/configuration.md +13 -3
  10. data/docs/features/synced_folders.md +1 -1
  11. data/docs/index.md +28 -14
  12. data/docs/internals/utm_api.md +0 -1
  13. data/docs/known_issues.md +6 -6
  14. data/lib/vagrant_utm/action/export.rb +26 -5
  15. data/lib/vagrant_utm/action/import.rb +24 -14
  16. data/lib/vagrant_utm/action/ip_address.rb +33 -0
  17. data/lib/vagrant_utm/action/match_mac_address.rb +37 -0
  18. data/lib/vagrant_utm/action/package.rb +22 -0
  19. data/lib/vagrant_utm/action/package_setup_files.rb +22 -0
  20. data/lib/vagrant_utm/action/package_setup_folders.rb +24 -0
  21. data/lib/vagrant_utm/action/package_vagrantfile.rb +39 -0
  22. data/lib/vagrant_utm/action/set_id.rb +1 -1
  23. data/lib/vagrant_utm/action.rb +45 -19
  24. data/lib/vagrant_utm/commands/disposable.rb +29 -0
  25. data/lib/vagrant_utm/commands/ip_address.rb +28 -0
  26. data/lib/vagrant_utm/config.rb +1 -10
  27. data/lib/vagrant_utm/driver/base.rb +26 -6
  28. data/lib/vagrant_utm/driver/meta.rb +5 -3
  29. data/lib/vagrant_utm/driver/version_4_5.rb +16 -4
  30. data/lib/vagrant_utm/driver/version_4_6.rb +42 -0
  31. data/lib/vagrant_utm/model/forwarded_port.rb +3 -1
  32. data/lib/vagrant_utm/plugin.rb +11 -8
  33. data/lib/vagrant_utm/provider.rb +2 -1
  34. data/lib/vagrant_utm/scripts/export_vm.applescript +13 -0
  35. data/lib/vagrant_utm/scripts/import_vm.applescript +14 -0
  36. data/lib/vagrant_utm/scripts/read_forwarded_ports.applescript +1 -1
  37. data/lib/vagrant_utm/scripts/read_network_interfaces.applescript +2 -1
  38. data/lib/vagrant_utm/scripts/set_mac_address.applescript +25 -0
  39. data/lib/vagrant_utm/version.rb +1 -1
  40. data/lib/vagrant_utm.rb +1 -0
  41. data/locales/en.yml +9 -0
  42. data/notes/README.md +30 -0
  43. data/vagrantfile_examples/Vagrantfile +3 -2
  44. metadata +16 -5
  45. data/lib/vagrant_utm/action/download_confirm.rb +0 -19
  46. data/lib/vagrant_utm/disposable.rb +0 -16
  47. data/lib/vagrant_utm/scripts/read_guest_ip.applescript +0 -9
@@ -0,0 +1,33 @@
1
+ # frozen_string_literal: true
2
+
3
+ module VagrantPlugins
4
+ module Utm
5
+ module Action
6
+ # Action to get IP address of machine.
7
+ class IpAddress
8
+ def initialize(app, _env)
9
+ @app = app
10
+ end
11
+
12
+ def call(env) # rubocop:disable Metrics/AbcSize
13
+ # Get IP address of the machine.
14
+ env[:ui].warn I18n.t("vagrant_utm.actions.vm.ip_address.reading")
15
+ guest_ips = env[:machine].provider.driver.read_guest_ip
16
+
17
+ if guest_ips.empty?
18
+ # Inform user that no IP address was found.
19
+ env[:ui].warn I18n.t("vagrant_utm.actions.vm.ip_address.not_found")
20
+ else
21
+ # Show IP address of the machine.
22
+ env[:ui].info I18n.t("vagrant_utm.actions.vm.ip_address.show")
23
+ guest_ips.each do |ip|
24
+ env[:ui].info " #{ip}"
25
+ end
26
+ end
27
+
28
+ @app.call(env)
29
+ end
30
+ end
31
+ end
32
+ end
33
+ end
@@ -0,0 +1,37 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Copyright (c) HashiCorp, Inc.
4
+ # SPDX-License-Identifier: BUSL-1.1
5
+
6
+ module VagrantPlugins
7
+ module Utm
8
+ module Action
9
+ # This action matches the MAC address of the virtual machine to the
10
+ # configured MAC address in the Vagrantfile.
11
+ # OR generates a new MAC address if none is set.
12
+ # This is useful to make sure that different virtual machines
13
+ # have different MAC addresses.
14
+ class MatchMACAddress
15
+ def initialize(app, _env)
16
+ @app = app
17
+ end
18
+
19
+ def call(env) # rubocop:disable Metrics/AbcSize
20
+ base_mac = env[:machine].config.vm.base_mac
21
+ # If we have a base MAC address and not is empty (empty in some default Vagranfile)
22
+ # then we use that to match
23
+ if base_mac && !base_mac.empty?
24
+ # Create the proc which we want to use to modify the virtual machine
25
+ env[:ui].info I18n.t("vagrant.actions.vm.match_mac.matching")
26
+ env[:machine].provider.driver.set_mac_address(env[:machine].config.vm.base_mac)
27
+ else
28
+ env[:ui].info I18n.t("vagrant.actions.vm.match_mac.generating")
29
+ env[:machine].provider.driver.set_mac_address(nil)
30
+ end
31
+
32
+ @app.call(env)
33
+ end
34
+ end
35
+ end
36
+ end
37
+ end
@@ -0,0 +1,22 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Copyright (c) HashiCorp, Inc.
4
+ # SPDX-License-Identifier: BUSL-1.1
5
+
6
+ require "vagrant/action/general/package"
7
+
8
+ module VagrantPlugins
9
+ module Utm
10
+ module Action
11
+ # This action packages the virtual machine into a box
12
+ class Package < Vagrant::Action::General::Package
13
+ # Doing this so that we can test that the parent is properly
14
+ # called in the unit tests.
15
+ alias general_call call
16
+ def call(env)
17
+ general_call(env)
18
+ end
19
+ end
20
+ end
21
+ end
22
+ end
@@ -0,0 +1,22 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Copyright (c) HashiCorp, Inc.
4
+ # SPDX-License-Identifier: BUSL-1.1
5
+
6
+ require "vagrant/action/general/package_setup_files"
7
+
8
+ module VagrantPlugins
9
+ module Utm
10
+ module Action
11
+ # This action sets up the files that are used in the package process.
12
+ class PackageSetupFiles < Vagrant::Action::General::PackageSetupFiles
13
+ # Doing this so that we can test that the parent is properly
14
+ # called in the unit tests.
15
+ alias general_call call
16
+ def call(env)
17
+ general_call(env)
18
+ end
19
+ end
20
+ end
21
+ end
22
+ end
@@ -0,0 +1,24 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Copyright (c) HashiCorp, Inc.
4
+ # SPDX-License-Identifier: BUSL-1.1
5
+
6
+ require "fileutils"
7
+
8
+ require "vagrant/action/general/package_setup_folders"
9
+
10
+ module VagrantPlugins
11
+ module Utm
12
+ module Action
13
+ # This action sets up the folders that are used in the package process.
14
+ class PackageSetupFolders < Vagrant::Action::General::PackageSetupFolders
15
+ # Doing this so that we can test that the parent is properly
16
+ # called in the unit tests.
17
+ alias general_call call
18
+ def call(env)
19
+ general_call(env)
20
+ end
21
+ end
22
+ end
23
+ end
24
+ end
@@ -0,0 +1,39 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Copyright (c) HashiCorp, Inc.
4
+ # SPDX-License-Identifier: BUSL-1.1
5
+
6
+ require "vagrant/util/template_renderer"
7
+
8
+ module VagrantPlugins
9
+ module Utm
10
+ module Action
11
+ # This middleware class sets up the Vagrantfile that will be placed
12
+ # into the root of the exported box.
13
+ class PackageVagrantfile
14
+ # For TemplateRenderer
15
+ include Vagrant::Util
16
+
17
+ def initialize(app, _env)
18
+ @app = app
19
+ end
20
+
21
+ def call(env)
22
+ @env = env
23
+ create_vagrantfile
24
+ @app.call(env)
25
+ end
26
+
27
+ # This method creates the auto-generated Vagrantfile at the root of the
28
+ # box. This Vagrantfile can contain anything that might be essential for user.
29
+ # Ex: Mac Address (for VirtualBox), etc.
30
+ # Currently nothing is added to the Vagrantfile.
31
+ def create_vagrantfile
32
+ File.open(File.join(@env["export.temp_dir"], "Vagrantfile"), "w") do |f|
33
+ f.write(TemplateRenderer.render("package_Vagrantfile"))
34
+ end
35
+ end
36
+ end
37
+ end
38
+ end
39
+ end
@@ -3,7 +3,7 @@
3
3
  module VagrantPlugins
4
4
  module Utm
5
5
  module Action
6
- # This action destroys the running machine.
6
+ # This action sets the machine id to the UUID of the VM in UTM.
7
7
  class SetId
8
8
  def initialize(app, _env)
9
9
  @app = app
@@ -21,20 +21,25 @@ module VagrantPlugins
21
21
  autoload :Created, action_root.join("created")
22
22
  autoload :Customize, action_root.join("customize")
23
23
  autoload :Destroy, action_root.join("destroy")
24
- autoload :DownloadConfirm, action_root.join("download_confirm")
25
24
  autoload :Export, action_root.join("export")
26
25
  autoload :ForcedHalt, action_root.join("forced_halt")
27
26
  autoload :ForwardPorts, action_root.join("forward_ports")
28
27
  autoload :Import, action_root.join("import")
28
+ autoload :IpAddress, action_root.join("ip_address")
29
29
  autoload :IsPaused, action_root.join("is_paused")
30
30
  autoload :IsRunning, action_root.join("is_running")
31
31
  autoload :IsStopped, action_root.join("is_stopped")
32
+ autoload :MatchMACAddress, action_root.join("match_mac_address")
32
33
  autoload :MessageAlreadyRunning, action_root.join("message_already_running")
33
34
  autoload :MessageNotCreated, action_root.join("message_not_created")
34
35
  autoload :MessageNotRunning, action_root.join("message_not_running")
35
36
  autoload :MessageNotStopped, action_root.join("message_not_stopped")
36
37
  autoload :MessageWillNotCreate, action_root.join("message_will_not_create")
37
38
  autoload :MessageWillNotDestroy, action_root.join("message_will_not_destroy")
39
+ autoload :Package, action_root.join("package")
40
+ autoload :PackageSetupFiles, action_root.join("package_setup_files")
41
+ autoload :PackageSetupFolders, action_root.join("package_setup_folders")
42
+ autoload :PackageVagrantfile, action_root.join("package_vagrantfile")
38
43
  autoload :PrepareForwardedPortCollisionParams, action_root.join("prepare_forwarded_port_collision_params")
39
44
  autoload :Resume, action_root.join("resume")
40
45
  autoload :SetId, action_root.join("set_id")
@@ -137,6 +142,23 @@ module VagrantPlugins
137
142
  end
138
143
  end
139
144
 
145
+ # This action returns ip address of the machine.
146
+ # UTM equivalent of `utmctl ip-address <uuid>`
147
+ def self.action_ip_address
148
+ Vagrant::Action::Builder.new.tap do |b|
149
+ b.use CheckUtm
150
+ b.use ConfigValidate
151
+ b.use Call, IsRunning do |env1, b2|
152
+ unless env1[:result]
153
+ b2.use MessageNotRunning
154
+ next
155
+ end
156
+ # If the VM is running, then get the IP address.
157
+ b2.use IpAddress
158
+ end
159
+ end
160
+ end
161
+
140
162
  # This action packages the virtual machine into a single box file.
141
163
  def self.action_package
142
164
  Vagrant::Action::Builder.new.tap do |b|
@@ -146,10 +168,15 @@ module VagrantPlugins
146
168
  b2.use MessageNotCreated
147
169
  next
148
170
  end
171
+
172
+ b2.use PackageSetupFolders
173
+ b2.use PackageSetupFiles
149
174
  b2.use CheckAccessible
150
175
  b2.use action_halt
151
176
  b2.use ClearForwardedPorts
177
+ b2.use Package
152
178
  b2.use Export
179
+ b2.use PackageVagrantfile
153
180
  end
154
181
  end
155
182
  end
@@ -321,6 +348,7 @@ module VagrantPlugins
321
348
  Vagrant::Action::Builder.new.tap do |b|
322
349
  b.use CheckUtm
323
350
  b.use ConfigValidate
351
+ b.use BoxCheckOutdated
324
352
  b.use Call, IsRunning do |env, b2|
325
353
  # If the VM is running, run the necessary provisioners
326
354
  if env[:result]
@@ -342,12 +370,14 @@ module VagrantPlugins
342
370
  end
343
371
  end
344
372
 
345
- # This action start VM in disposable mode.
373
+ # This action starts VM in disposable mode.
346
374
  # UTM equivalent of `utmctl start <uuid> --disposable`
347
375
  def self.action_start_disposable
348
376
  Vagrant::Action::Builder.new.tap do |b|
349
377
  b.use CheckUtm
350
378
  b.use ConfigValidate
379
+ b.use CheckCreated
380
+
351
381
  b.use Call, IsRunning do |env1, b2|
352
382
  if env1[:result]
353
383
  b2.use MessageAlreadyRunning
@@ -376,35 +406,31 @@ module VagrantPlugins
376
406
  end
377
407
 
378
408
  # This action brings the machine up from nothing, including importing
379
- # the UTM file, configuring metadata, and booting.
380
- def self.action_up # rubocop:disable Metrics/AbcSize
409
+ # the box, configuring metadata, and booting.
410
+ def self.action_up
381
411
  Vagrant::Action::Builder.new.tap do |b|
382
412
  b.use CheckUtm
413
+
414
+ # Handle box_url downloading early so that if the Vagrantfile
415
+ # references any files in the box or something it all just
416
+ # works fine.
417
+ b.use Call, Created do |env, b2|
418
+ b2.use HandleBox unless env[:result]
419
+ end
420
+
383
421
  b.use ConfigValidate
384
422
  b.use Call, Created do |env, b2|
385
423
  # If the VM is NOT created yet, then do the setup steps
386
424
  unless env[:result]
387
425
  b2.use CheckAccessible
388
426
  b2.use Customize, "pre-import"
389
- # load UTM file to UTM app, through 'utm://downloadVM?url='
390
- b2.use Import
391
427
 
392
- b2.use Call, DownloadConfirm do |env1, b3|
393
- if env1[:result]
394
- # SetID
395
- b3.use SetId
396
- b3.use SetName
397
- # Customize
398
- b3.use Customize, "pre-boot"
399
- else
400
- b3.use MessageWillNotCreate
401
- raise Errors::UtmImportFailed
402
- end
403
- end
428
+ b2.use Import
429
+ b2.use MatchMACAddress
404
430
  end
405
431
  end
406
432
 
407
- # Start the VM
433
+ b.use EnvSet, cloud_init: true
408
434
  b.use action_start
409
435
  end
410
436
  end
@@ -0,0 +1,29 @@
1
+ # frozen_string_literal: true
2
+
3
+ module VagrantPlugins
4
+ module Utm
5
+ # Run VM as a snapshot and do not save changes to disk.
6
+ class CommandDisposable < Vagrant.plugin(2, :command)
7
+ def self.synopsis
8
+ "UTM: boots machine in UTM disposable mode"
9
+ end
10
+
11
+ def execute
12
+ opts = OptionParser.new do |o|
13
+ o.banner = "Usage: vagrant disposable [name|id]"
14
+ end
15
+
16
+ # Parse the options
17
+ argv = parse_options(opts)
18
+ return unless argv
19
+
20
+ with_target_vms do |machine|
21
+ machine.action(:start_disposable)
22
+ end
23
+
24
+ # Success, exit status 0
25
+ 0
26
+ end
27
+ end
28
+ end
29
+ end
@@ -0,0 +1,28 @@
1
+ # frozen_string_literal: true
2
+
3
+ module VagrantPlugins
4
+ module Utm
5
+ # Get All IP Adress of a machine.
6
+ class CommandIpAddress < Vagrant.plugin(2, :command)
7
+ def self.synopsis
8
+ "UTM: outputs ip address of the vagrant machine"
9
+ end
10
+
11
+ def execute
12
+ opts = OptionParser.new do |o|
13
+ o.banner = "Usage: vagrant ip-address [name|id]"
14
+ end
15
+
16
+ # Parse the options
17
+ argv = parse_options(opts)
18
+ return unless argv
19
+
20
+ with_target_vms do |machine|
21
+ machine.action(:ip_address)
22
+ end
23
+
24
+ 0
25
+ end
26
+ end
27
+ end
28
+ end
@@ -12,11 +12,6 @@ module VagrantPlugins
12
12
  # @return [String]
13
13
  attr_accessor :name
14
14
 
15
- # The path to the UTM VM file.
16
- #
17
- # @return [String]
18
- attr_accessor :utm_file_url
19
-
20
15
  # If true, will check if guest additions are installed and up to
21
16
  # date. By default, this is true.
22
17
  #
@@ -39,7 +34,6 @@ module VagrantPlugins
39
34
  @check_guest_additions = UNSET_VALUE
40
35
  @customizations = []
41
36
  @name = UNSET_VALUE
42
- @utm_file_url = UNSET_VALUE
43
37
  @wait_time = UNSET_VALUE
44
38
  end
45
39
 
@@ -112,16 +106,13 @@ module VagrantPlugins
112
106
  # The default name is just nothing, and we default it
113
107
  @name = nil if @name == UNSET_VALUE
114
108
 
115
- @utm_file_url = nil if @utm_file_url == UNSET_VALUE
116
-
117
109
  @wait_time = 20 if @wait_time == UNSET_VALUE
118
110
  end
119
111
 
120
112
  def validate(_machine)
121
113
  errors = _detected_errors
122
114
 
123
- # Checks for the UTM file URL
124
- errors << I18n.t("vagrant_utm.config.utm_file_url_required") if @utm_file_url.nil? || @utm_file_url.empty?
115
+ # Add errors if config is invalid Ex: required fields are not set
125
116
 
126
117
  valid_events = %w[pre-import pre-boot post-boot post-comm]
127
118
  @customizations.each do |event, _| # rubocop:disable Style/HashEachMethods
@@ -86,9 +86,10 @@ module VagrantPlugins
86
86
  # @return [Array]
87
87
  def read_used_ports(active_only: true); end
88
88
 
89
- # Returns the IP address of the guest machine.
89
+ # Returns the IP addresses of the guest machine.
90
+ # Only supported for VMs with qemu-guest-agent installed.
90
91
  #
91
- # @return [String] The IP address of the guest machine.
92
+ # @return [Array<String>] The IP addresses of the guest machine.
92
93
  def read_guest_ip; end
93
94
 
94
95
  # Returns a list of network interfaces of the VM.
@@ -96,15 +97,19 @@ module VagrantPlugins
96
97
  # @return [Hash]
97
98
  def read_network_interfaces; end
98
99
 
100
+ # Sets the MAC address of the first network adapter.
101
+ #
102
+ # @param [String] mac MAC address without any spaces/hyphens.
103
+ def set_mac_address(mac); end # rubocop:disable Naming/AccessorMethodName
104
+
99
105
  # Execute the 'list' command and returns the list of machines.
100
106
  # @return [ListResult] The list of machines.
101
107
  def list; end
102
108
 
103
- # Execute the 'utm://downloadVM?url='
104
- # See https://docs.getutm.app/advanced/remote-control/
105
- # @param utm_file_url [String] The url to the UTM file.
109
+ # Import a virtual machine from a UTM file.
110
+ # @param utm_file [String] The url to the UTM file.
106
111
  # @return [uuid] The UUID of the imported machine.
107
- def import(utm_file_url); end
112
+ def import(utm_file); end
108
113
 
109
114
  # Sets the name of the virtual machine.
110
115
  # @param name [String] The new name of the machine.
@@ -143,6 +148,21 @@ module VagrantPlugins
143
148
  # This should raise a VagrantError if things are not ready.
144
149
  def verify!; end
145
150
 
151
+ # Generate a random MAC address.
152
+ #
153
+ # This method generates a random MAC address because it is difficult
154
+ # to get UTM to generate one through scripting.
155
+ #
156
+ # @return [String] The MAC address.
157
+ def random_mac_address
158
+ # Generate 6 random bytes
159
+ bytes = Array.new(6) { rand(256) }
160
+ # Ensure the first byte is local
161
+ bytes[0] = (bytes[0] & 0xFC) | 0x02
162
+ # Convert bytes to MAC address string
163
+ bytes.map { |byte| format("%02X", byte) }.join(":")
164
+ end
165
+
146
166
  # Execute a script using the OSA interface.
147
167
  def execute_osa_script(command); end
148
168
 
@@ -55,12 +55,12 @@ module VagrantPlugins
55
55
  # Instantiate the proper version driver for UTM
56
56
  @logger.debug("Finding driver for UTM version: #{@version}")
57
57
  driver_map = {
58
- "4.5" => Version_4_5
58
+ "4.6" => Version_4_6
59
59
  }
60
60
 
61
- # UTM 4.5.0 just doesn't work with Vagrant (https://github.com/utmapp/UTM/issues/5963),
61
+ # UTM 4.6.0 doesn't have import support to work with Vagrant box,
62
62
  # so show error
63
- raise Errors::UtmInvalidVersion if @version.start_with?("4.5.0")
63
+ raise Errors::UtmInvalidVersion if @version.start_with?("4.6.0")
64
64
 
65
65
  driver_klass = nil
66
66
  driver_map.each do |key, klass|
@@ -92,6 +92,7 @@ module VagrantPlugins
92
92
  :delete,
93
93
  :delete_snapshot,
94
94
  :execute_osa_script,
95
+ :export,
95
96
  :forward_ports,
96
97
  :halt,
97
98
  :import,
@@ -104,6 +105,7 @@ module VagrantPlugins
104
105
  :read_state,
105
106
  :read_used_ports,
106
107
  :restore_snapshot,
108
+ :set_mac_address,
107
109
  :set_name,
108
110
  :ssh_port,
109
111
  :start,
@@ -14,7 +14,7 @@ module VagrantPlugins
14
14
  def initialize(uuid)
15
15
  super()
16
16
 
17
- @logger = Log4r::Logger.new("vagrant::provider::utm_4_5")
17
+ @logger = Log4r::Logger.new("vagrant::provider::utm::version_4_5")
18
18
  @uuid = uuid
19
19
  end
20
20
 
@@ -52,6 +52,11 @@ module VagrantPlugins
52
52
  execute_shell("qemu-img", "snapshot", "-d", snapshot_name, machine_file)
53
53
  end
54
54
 
55
+ def export(_path)
56
+ @logger.info("This version of UTM does not support exporting VMs
57
+ Please upgrade to the latest version of UTM or UTM 'Share' feature in UI to export the virtual machine")
58
+ end
59
+
55
60
  def list_snapshots(machine_id) # rubocop:disable Metrics/AbcSize
56
61
  list_result = list
57
62
  machine_name = list_result.find(uuid: machine_id).name
@@ -169,9 +174,8 @@ module VagrantPlugins
169
174
  end
170
175
 
171
176
  def read_guest_ip
172
- command = ["read_guest_ip.applescript", @uuid]
173
- output = execute_osa_script(command)
174
- output.strip
177
+ output = execute("ip-address", @uuid)
178
+ output.strip.split("\n")
175
179
  end
176
180
 
177
181
  def read_network_interfaces
@@ -190,6 +194,14 @@ module VagrantPlugins
190
194
  nics
191
195
  end
192
196
 
197
+ def set_mac_address(mac) # rubocop:disable Naming/AccessorMethodName
198
+ # Set the MAC address of the first NIC (index 0)
199
+ # Set MAC address to given value or randomize it if nil
200
+ mac = random_mac_address if mac.nil?
201
+ command = ["set_mac_address.applescript", @uuid, "0", mac]
202
+ execute_osa_script(command)
203
+ end
204
+
193
205
  def ssh_port(expected_port)
194
206
  @logger.debug("Searching for SSH port: #{expected_port.inspect}")
195
207
 
@@ -0,0 +1,42 @@
1
+ # frozen_string_literal: true
2
+
3
+ require File.expand_path("version_4_5", __dir__)
4
+
5
+ module VagrantPlugins
6
+ module Utm
7
+ module Driver
8
+ # Driver for UTM 4.6.x
9
+ class Version_4_6 < Version_4_5 # rubocop:disable Naming/ClassAndModuleCamelCase
10
+ def initialize(uuid)
11
+ super
12
+
13
+ @logger = Log4r::Logger.new("vagrant::provider::utm::version_4_6")
14
+ end
15
+
16
+ def import(utm)
17
+ utm = Vagrant::Util::Platform.windows_path(utm)
18
+
19
+ vm_id = nil
20
+
21
+ command = ["import_vm.applescript", utm]
22
+ output = execute_osa_script(command)
23
+
24
+ @logger.debug("Import output: #{output}")
25
+
26
+ # Check if we got the VM ID
27
+ if output =~ /virtual machine id ([A-F0-9-]+)/
28
+ vm_id = ::Regexp.last_match(1) # Capture the VM ID
29
+ end
30
+
31
+ vm_id
32
+ end
33
+
34
+ def export(path)
35
+ @logger.debug("Exporting UTM file to: #{path}")
36
+ command = ["export_vm.applescript", @uuid, path]
37
+ execute_osa_script(command)
38
+ end
39
+ end
40
+ end
41
+ end
42
+ end
@@ -57,7 +57,9 @@ module VagrantPlugins
57
57
  options ||= {}
58
58
  @auto_correct = false
59
59
  @auto_correct = options[:auto_correct] if options.key?(:auto_correct)
60
- @adapter = (options[:adapter] || 1).to_i # if adapter is not set, use 1. index 0 is the default adapter
60
+ # if adapter is not set, use index 1 (Emulated VLAN).
61
+ # index 0 is the default adapter (Shared Network)
62
+ @adapter = (options[:adapter] || 1).to_i
61
63
  @guest_ip = options[:guest_ip] || nil
62
64
  @host_ip = options[:host_ip] || nil
63
65
  @protocol = options[:protocol] || "tcp" # default to TCP
@@ -21,12 +21,7 @@ module VagrantPlugins
21
21
  DESCRIPTION
22
22
 
23
23
  # Register the provider
24
- # TODO: Define box format for UTM
25
- # IDEA: UTM file comes as a zip file containing
26
- # directory with Data/qcow2, Data/efi_vars.fd and config.plist
27
- # Box format will only require additional metadata.json file
28
- # Till then use UTM file directly and so box_optional: true
29
- provider(:utm, box_optional: true, parallel: false) do
24
+ provider(:utm, box_optional: false, parallel: false) do
30
25
  setup_i18n
31
26
  require_relative "provider"
32
27
  Provider
@@ -50,9 +45,17 @@ module VagrantPlugins
50
45
  end
51
46
 
52
47
  # Register the command
48
+ ## Start machine as a snapshot and do not save changes to disk
53
49
  command "disposable" do
54
- require_relative "disposable"
55
- Disposable
50
+ require_relative "commands/disposable"
51
+ CommandDisposable
52
+ end
53
+
54
+ ## Get the IP address of the machine
55
+ ## Only supported if machine as qemu-guest-additions
56
+ command "ip-address" do
57
+ require_relative "commands/ip_address"
58
+ CommandIpAddress
56
59
  end
57
60
 
58
61
  # Load the translation files
@@ -94,6 +94,8 @@ module VagrantPlugins
94
94
  # If we have multiple network adapters, we need to pick the right one, read_guest_ip returns just first IP
95
95
  # Also, since Vagrant by default adds port forwarding for ssh port 22,
96
96
  # we might aswell use the forwarded ports to connect to the VM using the localhost.
97
+ # and the forwarded port.
98
+ # So we use 127.0.0.1 and the forwarded port to connect to the VM.
97
99
  {
98
100
  host: "127.0.0.1",
99
101
  port: @driver.ssh_port(@machine.config.ssh.guest_port)
@@ -124,7 +126,6 @@ module VagrantPlugins
124
126
  Vagrant::MachineState.new(state_id, short, long)
125
127
  end
126
128
 
127
- # TODO: Get UUID of the VM from UTM
128
129
  # Returns a human-friendly string version of this provider which
129
130
  # includes the machine's ID that this provider represents, if it
130
131
  # has one.