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.
- checksums.yaml +4 -4
- data/CHANGELOG.md +43 -3
- data/README.md +1 -3
- data/docs/_config.yml +5 -6
- data/docs/assets/images/screens/debian-10.4-i3-arm64.png +0 -0
- data/docs/boxes/creating_utm_box.md +46 -19
- data/docs/boxes/utm_box_gallery.md +17 -93
- data/docs/commands.md +12 -8
- data/docs/configuration.md +13 -3
- data/docs/features/synced_folders.md +1 -1
- data/docs/index.md +28 -14
- data/docs/internals/utm_api.md +0 -1
- data/docs/known_issues.md +6 -6
- data/lib/vagrant_utm/action/export.rb +26 -5
- data/lib/vagrant_utm/action/import.rb +24 -14
- data/lib/vagrant_utm/action/ip_address.rb +33 -0
- data/lib/vagrant_utm/action/match_mac_address.rb +37 -0
- data/lib/vagrant_utm/action/package.rb +22 -0
- data/lib/vagrant_utm/action/package_setup_files.rb +22 -0
- data/lib/vagrant_utm/action/package_setup_folders.rb +24 -0
- data/lib/vagrant_utm/action/package_vagrantfile.rb +39 -0
- data/lib/vagrant_utm/action/set_id.rb +1 -1
- data/lib/vagrant_utm/action.rb +45 -19
- data/lib/vagrant_utm/commands/disposable.rb +29 -0
- data/lib/vagrant_utm/commands/ip_address.rb +28 -0
- data/lib/vagrant_utm/config.rb +1 -10
- data/lib/vagrant_utm/driver/base.rb +26 -6
- data/lib/vagrant_utm/driver/meta.rb +5 -3
- data/lib/vagrant_utm/driver/version_4_5.rb +16 -4
- data/lib/vagrant_utm/driver/version_4_6.rb +42 -0
- data/lib/vagrant_utm/model/forwarded_port.rb +3 -1
- data/lib/vagrant_utm/plugin.rb +11 -8
- data/lib/vagrant_utm/provider.rb +2 -1
- data/lib/vagrant_utm/scripts/export_vm.applescript +13 -0
- data/lib/vagrant_utm/scripts/import_vm.applescript +14 -0
- data/lib/vagrant_utm/scripts/read_forwarded_ports.applescript +1 -1
- data/lib/vagrant_utm/scripts/read_network_interfaces.applescript +2 -1
- data/lib/vagrant_utm/scripts/set_mac_address.applescript +25 -0
- data/lib/vagrant_utm/version.rb +1 -1
- data/lib/vagrant_utm.rb +1 -0
- data/locales/en.yml +9 -0
- data/notes/README.md +30 -0
- data/vagrantfile_examples/Vagrantfile +3 -2
- metadata +16 -5
- data/lib/vagrant_utm/action/download_confirm.rb +0 -19
- data/lib/vagrant_utm/disposable.rb +0 -16
- 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
|
data/lib/vagrant_utm/action.rb
CHANGED
@@ -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
|
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
|
380
|
-
def self.action_up
|
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
|
393
|
-
|
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
|
-
|
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
|
data/lib/vagrant_utm/config.rb
CHANGED
@@ -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
|
-
#
|
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
|
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
|
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
|
-
#
|
104
|
-
#
|
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(
|
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.
|
58
|
+
"4.6" => Version_4_6
|
59
59
|
}
|
60
60
|
|
61
|
-
# UTM 4.
|
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.
|
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::
|
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
|
-
|
173
|
-
output
|
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
|
-
|
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
|
data/lib/vagrant_utm/plugin.rb
CHANGED
@@ -21,12 +21,7 @@ module VagrantPlugins
|
|
21
21
|
DESCRIPTION
|
22
22
|
|
23
23
|
# Register the provider
|
24
|
-
|
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
|
-
|
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
|
data/lib/vagrant_utm/provider.rb
CHANGED
@@ -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.
|