vagrant-ovirt4 1.1.0 → 2.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.
- checksums.yaml +5 -5
- data/.github/FUNDING.yml +3 -0
- data/.github/workflows/release.yml +20 -0
- data/.gitignore +2 -0
- data/Dockerfile +11 -0
- data/Gemfile +5 -11
- data/Gemfile.lock +31 -37
- data/README.md +26 -12
- data/Rakefile +1 -7
- data/lib/vagrant-ovirt4/action.rb +29 -9
- data/lib/vagrant-ovirt4/action/connect_ovirt.rb +1 -0
- data/lib/vagrant-ovirt4/action/create_network_interfaces.rb +62 -26
- data/lib/vagrant-ovirt4/action/create_vm.rb +98 -14
- data/lib/vagrant-ovirt4/action/destroy_vm.rb +14 -1
- data/lib/vagrant-ovirt4/action/disconnect_ovirt.rb +25 -0
- data/lib/vagrant-ovirt4/action/halt_vm.rb +11 -0
- data/lib/vagrant-ovirt4/action/read_ssh_info.rb +6 -1
- data/lib/vagrant-ovirt4/action/read_state.rb +7 -1
- data/lib/vagrant-ovirt4/action/resize_disk.rb +18 -17
- data/lib/vagrant-ovirt4/action/start_vm.rb +76 -34
- data/lib/vagrant-ovirt4/action/wait_til_suspended.rb +1 -1
- data/lib/vagrant-ovirt4/action/wait_till_down.rb +13 -2
- data/lib/vagrant-ovirt4/action/wait_till_up.rb +35 -6
- data/lib/vagrant-ovirt4/config.rb +81 -1
- data/lib/vagrant-ovirt4/errors.rb +20 -0
- data/lib/vagrant-ovirt4/plugin.rb +3 -3
- data/lib/vagrant-ovirt4/version.rb +1 -1
- data/locales/en.yml +17 -1
- data/spec/vagrant-ovirt4/config_spec.rb +53 -3
- data/templates/Vagrantfile.erb +199 -0
- data/tools/prepare_redhat_for_box.sh +18 -2
- data/vagrant-ovirt4.gemspec +3 -1
- metadata +35 -13
- data/docker-compose.yml +0 -9
- data/lib/vagrant-ovirt4/action/sync_folders.rb +0 -69
- data/lib/vagrant-ovirt4/cap/nic_mac_addresses.rb +0 -15
- data/test.rb +0 -3
@@ -20,16 +20,24 @@ module VagrantPlugins
|
|
20
20
|
hostname = 'vagrant' if hostname.nil?
|
21
21
|
|
22
22
|
# Output the settings we're going to use to the user
|
23
|
-
memory_size = config.memory_size*1024*1024
|
24
|
-
memory_guaranteed = config.memory_guaranteed*1024*1024
|
25
23
|
env[:ui].info(I18n.t("vagrant_ovirt4.creating_vm"))
|
26
24
|
env[:ui].info(" -- Name: #{hostname}")
|
27
25
|
env[:ui].info(" -- Cluster: #{config.cluster}")
|
28
26
|
env[:ui].info(" -- Template: #{config.template}")
|
29
27
|
env[:ui].info(" -- Console Type: #{config.console}")
|
28
|
+
env[:ui].info(" -- BIOS Serial: #{config.bios_serial}")
|
29
|
+
env[:ui].info(" -- Optimized For: #{config.optimized_for}")
|
30
|
+
env[:ui].info(" -- Description: #{config.description}")
|
31
|
+
env[:ui].info(" -- Comment: #{config.comment}")
|
32
|
+
env[:ui].info(" -- Disk: #{Filesize.from("#{config.disk_size} B").to_f('GiB').to_i} GiB") unless config.disk_size.nil?
|
33
|
+
env[:ui].info(" -- Additional Disks:") unless config.disks.empty?
|
34
|
+
config.disks.each do |disk|
|
35
|
+
env[:ui].info(" ---- name=#{disk[:name]} size=#{Filesize.from("#{disk[:size]} B").to_f('GiB').to_i} GiB")
|
36
|
+
end
|
30
37
|
env[:ui].info(" -- Memory: ")
|
31
|
-
env[:ui].info(" ---- Memory: #{config.memory_size}")
|
32
|
-
env[:ui].info(" ----
|
38
|
+
env[:ui].info(" ---- Memory: #{Filesize.from("#{config.memory_size} B").to_f('MiB').to_i} MiB")
|
39
|
+
env[:ui].info(" ---- Maximum: #{Filesize.from("#{config.memory_maximum} B").to_f('MiB').to_i} MiB")
|
40
|
+
env[:ui].info(" ---- Guaranteed: #{Filesize.from("#{config.memory_guaranteed} B").to_f('MiB').to_i} MiB")
|
33
41
|
env[:ui].info(" -- Cpu: ")
|
34
42
|
env[:ui].info(" ---- Cores: #{config.cpu_cores}")
|
35
43
|
env[:ui].info(" ---- Sockets: #{config.cpu_sockets}")
|
@@ -39,6 +47,8 @@ module VagrantPlugins
|
|
39
47
|
# Create oVirt VM.
|
40
48
|
attr = {
|
41
49
|
:name => hostname,
|
50
|
+
:description => config.description,
|
51
|
+
:comment => config.comment,
|
42
52
|
:cpu => {
|
43
53
|
:architecture => 'x86_64',
|
44
54
|
:topology => {
|
@@ -47,11 +57,12 @@ module VagrantPlugins
|
|
47
57
|
:threads => config.cpu_threads,
|
48
58
|
},
|
49
59
|
},
|
50
|
-
:
|
51
|
-
|
52
|
-
:
|
53
|
-
:
|
54
|
-
|
60
|
+
:memory_policy => OvirtSDK4::MemoryPolicy.new(
|
61
|
+
ballooning: true,
|
62
|
+
guaranteed: config.memory_guaranteed,
|
63
|
+
max: config.memory_maximum,
|
64
|
+
),
|
65
|
+
:memory => config.memory_size,
|
55
66
|
:cluster => {
|
56
67
|
:name => config.cluster,
|
57
68
|
},
|
@@ -61,14 +72,21 @@ module VagrantPlugins
|
|
61
72
|
:display => {
|
62
73
|
:type => config.console,
|
63
74
|
},
|
75
|
+
:type => config.optimized_for,
|
64
76
|
}
|
65
77
|
|
66
78
|
begin
|
67
|
-
server = env[:vms_service].add(attr)
|
79
|
+
server = env[:vms_service].add(attr)
|
68
80
|
rescue OvirtSDK4::Error => e
|
69
81
|
fault_message = /Fault detail is \"\[?(.+?)\]?\".*/.match(e.message)[1] rescue e.message
|
70
|
-
|
71
|
-
|
82
|
+
retry if e.message =~ /Related operation is currently in progress/
|
83
|
+
|
84
|
+
if config.debug
|
85
|
+
raise e
|
86
|
+
else
|
87
|
+
raise Errors::CreateVMError,
|
88
|
+
:error_message => fault_message
|
89
|
+
end
|
72
90
|
end
|
73
91
|
|
74
92
|
# Immediately save the ID since it is created at this point.
|
@@ -77,17 +95,21 @@ module VagrantPlugins
|
|
77
95
|
# Wait till all volumes are ready.
|
78
96
|
env[:ui].info(I18n.t("vagrant_ovirt4.wait_for_ready_vm"))
|
79
97
|
for i in 0..300
|
80
|
-
|
98
|
+
disk_ready = true
|
81
99
|
vm_service = env[:vms_service].vm_service(env[:machine].id)
|
82
100
|
disk_attachments_service = vm_service.disk_attachments_service
|
83
101
|
disk_attachments = disk_attachments_service.list
|
84
102
|
disk_attachments.each do |disk_attachment|
|
85
103
|
disk = env[:connection].follow_link(disk_attachment.disk)
|
104
|
+
if config.debug
|
105
|
+
env[:ui].info("Checking disk status id=#{disk.id} name=#{disk.name} status=#{disk.status}")
|
106
|
+
end
|
86
107
|
if disk.status != 'ok'
|
87
|
-
|
108
|
+
disk_ready = false
|
88
109
|
break
|
89
110
|
end
|
90
111
|
end
|
112
|
+
ready = (disk_ready and env[:vms_service].vm_service(server.id).get.status.to_sym == :down)
|
91
113
|
break if ready
|
92
114
|
sleep 2
|
93
115
|
end
|
@@ -96,6 +118,67 @@ module VagrantPlugins
|
|
96
118
|
raise Errors::WaitForReadyVmTimeout
|
97
119
|
end
|
98
120
|
|
121
|
+
# add storage disks
|
122
|
+
vm_service = env[:vms_service].vm_service(env[:machine].id)
|
123
|
+
disk_attachments_service = vm_service.disk_attachments_service
|
124
|
+
storage_disks = []
|
125
|
+
config.disks.each do |disk|
|
126
|
+
disk_attachment = disk_attachments_service.add(
|
127
|
+
OvirtSDK4::DiskAttachment.new(
|
128
|
+
disk: {
|
129
|
+
name: disk[:name],
|
130
|
+
description: '#{hostname} storage disk',
|
131
|
+
format: disk[:type] == 'qcow2' ? OvirtSDK4::DiskFormat::COW : OvirtSDK4::DiskFormat::RAW,
|
132
|
+
provisioned_size: disk[:size],
|
133
|
+
storage_domains: [{
|
134
|
+
name: disk[:storage_domain]
|
135
|
+
}]
|
136
|
+
},
|
137
|
+
interface: disk[:bus] == 'virtio' ? OvirtSDK4::DiskInterface::VIRTIO : OvirtSDK4::DiskInterface::IDE,
|
138
|
+
bootable: false,
|
139
|
+
active: true
|
140
|
+
)
|
141
|
+
)
|
142
|
+
storage_disks << disk_attachment
|
143
|
+
env[:ui].info("Added storage disk id=#{disk_attachment.disk.id} name=#{disk[:name]} size=#{disk[:size]}")
|
144
|
+
end
|
145
|
+
|
146
|
+
disks_service = env[:connection].system_service.disks_service
|
147
|
+
storage_disks.each do |s_disk|
|
148
|
+
disk_service = disks_service.disk_service(s_disk.disk.id)
|
149
|
+
loop do
|
150
|
+
sleep(5)
|
151
|
+
disk = disk_service.get
|
152
|
+
if config.debug
|
153
|
+
env[:ui].info("Checking disk status id=#{disk.id} name=#{disk.name} status=#{disk.status}")
|
154
|
+
end
|
155
|
+
break if disk.status == OvirtSDK4::DiskStatus::OK
|
156
|
+
end
|
157
|
+
end
|
158
|
+
|
159
|
+
begin
|
160
|
+
if config.bios_serial
|
161
|
+
vm_service = env[:vms_service].vm_service(env[:machine].id)
|
162
|
+
vm_service.update(
|
163
|
+
serial_number: {
|
164
|
+
policy: OvirtSDK4::SerialNumberPolicy::CUSTOM,
|
165
|
+
value: config.bios_serial,
|
166
|
+
}
|
167
|
+
)
|
168
|
+
end
|
169
|
+
rescue OvirtSDK4::Error => e
|
170
|
+
fault_message = /Fault detail is \"\[?(.+?)\]?\".*/.match(e.message)[1] rescue e.message
|
171
|
+
retry if e.message =~ /Related operation is currently in progress/
|
172
|
+
|
173
|
+
if config.debug
|
174
|
+
raise e
|
175
|
+
else
|
176
|
+
raise Errors::UpdateBiosError,
|
177
|
+
:error_message => fault_message
|
178
|
+
end
|
179
|
+
end
|
180
|
+
|
181
|
+
|
99
182
|
@app.call(env)
|
100
183
|
end
|
101
184
|
|
@@ -109,6 +192,7 @@ module VagrantPlugins
|
|
109
192
|
destroy_env[:config_validate] = false
|
110
193
|
destroy_env[:force_confirm_destroy] = true
|
111
194
|
env[:action_runner].run(Action.action_destroy, destroy_env)
|
195
|
+
env[:connection].close()
|
112
196
|
end
|
113
197
|
end
|
114
198
|
end
|
@@ -14,7 +14,20 @@ module VagrantPlugins
|
|
14
14
|
env[:ui].info(I18n.t("vagrant_ovirt4.destroy_vm"))
|
15
15
|
|
16
16
|
vm_service = env[:vms_service].vm_service(env[:machine].id)
|
17
|
-
|
17
|
+
begin
|
18
|
+
vm_service.remove
|
19
|
+
rescue OvirtSDK4::Error => e
|
20
|
+
fault_message = /Fault detail is \"\[?(.+?)\]?\".*/.match(e.message)[1] rescue e.message
|
21
|
+
retry if e.message =~ /Please try again/
|
22
|
+
|
23
|
+
if config.debug
|
24
|
+
raise e
|
25
|
+
else
|
26
|
+
raise Errors::RemoveVMError,
|
27
|
+
:error_message => fault_message
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
18
31
|
env[:machine].id = nil
|
19
32
|
|
20
33
|
@app.call(env)
|
@@ -0,0 +1,25 @@
|
|
1
|
+
require 'log4r'
|
2
|
+
require 'ovirtsdk4'
|
3
|
+
|
4
|
+
module VagrantPlugins
|
5
|
+
module OVirtProvider
|
6
|
+
module Action
|
7
|
+
class DisconnectOVirt
|
8
|
+
def initialize(app, env)
|
9
|
+
@logger = Log4r::Logger.new("vagrant_ovirt4::action::disconnect_ovirt")
|
10
|
+
@app = app
|
11
|
+
end
|
12
|
+
|
13
|
+
def call(env)
|
14
|
+
|
15
|
+
# Get config options for ovirt provider.
|
16
|
+
@logger.info("Disconnecting oVirt connection")
|
17
|
+
env[:connection].close()
|
18
|
+
|
19
|
+
@app.call(env)
|
20
|
+
end
|
21
|
+
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
@@ -12,6 +12,17 @@ module VagrantPlugins
|
|
12
12
|
def call(env)
|
13
13
|
env[:ui].info(I18n.t("vagrant_ovirt4.halt_vm"))
|
14
14
|
|
15
|
+
# Halt via OS capability
|
16
|
+
begin
|
17
|
+
if env[:machine].guest.capability?(:halt)
|
18
|
+
env[:machine].guest.capability(:halt)
|
19
|
+
# Give the VM a chance to shutdown gracefully..."
|
20
|
+
sleep 10
|
21
|
+
end
|
22
|
+
rescue
|
23
|
+
env[:ui].info("Failed to shutdown guest gracefully.")
|
24
|
+
end
|
25
|
+
|
15
26
|
machine = env[:vms_service].vm_service(env[:machine].id)
|
16
27
|
machine.stop rescue nil #todo dont rescue
|
17
28
|
|
@@ -36,7 +36,12 @@ module VagrantPlugins
|
|
36
36
|
|
37
37
|
nics_service = server.nics_service
|
38
38
|
nics = nics_service.list
|
39
|
-
|
39
|
+
begin
|
40
|
+
ip_addr = nics.collect { |nic_attachment| env[:connection].follow_link(nic_attachment.reported_devices).collect { |dev| dev.ips.collect { |ip| ip.address if ip.version == 'v4' } unless dev.ips.nil? } }.flatten.reject { |ip| ip.nil? }.first
|
41
|
+
rescue
|
42
|
+
# for backwards compatibility with ovirt 4.3
|
43
|
+
ip_addr = nics.collect { |nic_attachment| env[:connection].follow_link(nic_attachment).reported_devices.collect { |dev| dev.ips.collect { |ip| ip.address if ip.version == 'v4' } unless dev.ips.nil? } }.flatten.reject { |ip| ip.nil? }.first rescue nil
|
44
|
+
end
|
40
45
|
|
41
46
|
# Return the info
|
42
47
|
# TODO: Some info should be configurable in Vagrantfile
|
@@ -33,7 +33,13 @@ module VagrantPlugins
|
|
33
33
|
end
|
34
34
|
nics_service = server.nics_service
|
35
35
|
nics = nics_service.list
|
36
|
-
|
36
|
+
begin
|
37
|
+
ip_addr = nics.collect { |nic_attachment| env[:connection].follow_link(nic_attachment.reported_devices).collect { |dev| dev.ips.collect { |ip| ip.address if ip.version == 'v4' } unless dev.ips.nil? } }.flatten.reject { |ip| ip.nil? }.first
|
38
|
+
rescue
|
39
|
+
# for backwards compatibility with ovirt 4.3
|
40
|
+
ip_addr = nics.collect { |nic_attachment| env[:connection].follow_link(nic_attachment).reported_devices.collect { |dev| dev.ips.collect { |ip| ip.address if ip.version == 'v4' } unless dev.ips.nil? } }.flatten.reject { |ip| ip.nil? }.first rescue nil
|
41
|
+
end
|
42
|
+
|
37
43
|
unless ip_addr.nil?
|
38
44
|
env[:ip_address] = ip_addr
|
39
45
|
@logger.debug("Got output #{env[:ip_address]}")
|
@@ -24,36 +24,37 @@ module VagrantPlugins
|
|
24
24
|
|
25
25
|
# Get machine first.
|
26
26
|
begin
|
27
|
-
|
28
|
-
env[:ovirt_compute].servers.all, env[:machine].id.to_s)
|
27
|
+
vm_service = env[:vms_service].vm_service(env[:machine].id.to_s)
|
29
28
|
rescue => e
|
30
|
-
raise Errors::NoVMError,
|
31
|
-
:vm_name => env[:machine].id.to_s
|
29
|
+
raise Errors::NoVMError, :vm_id => env[:machine].id
|
32
30
|
end
|
33
31
|
|
32
|
+
disk_attachments_service = vm_service.disk_attachments_service
|
33
|
+
disk_attachments = disk_attachments_service.list
|
34
|
+
disk = disk_attachments.first.disk
|
35
|
+
|
34
36
|
# Extend disk size if necessary
|
35
37
|
begin
|
36
|
-
|
37
|
-
|
38
|
-
:
|
38
|
+
disk_attachment_service = disk_attachments_service.attachment_service(disk.id)
|
39
|
+
disk_attachment = disk_attachment_service.update(
|
40
|
+
OvirtSDK4::DiskAttachment.new(disk: {provisioned_size: config.disk_size})
|
39
41
|
)
|
40
42
|
rescue => e
|
41
43
|
raise Errors::UpdateVolumeError,
|
42
44
|
:error_message => e.message
|
43
45
|
end
|
44
46
|
|
45
|
-
# Wait
|
47
|
+
# Wait until resize operation has finished.
|
48
|
+
disks_service = env[:connection].system_service.disks_service
|
49
|
+
disk_service = disks_service.disk_service(disk.id)
|
46
50
|
env[:ui].info(I18n.t("vagrant_ovirt4.wait_for_ready_volume"))
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
break
|
54
|
-
end
|
51
|
+
ready = false
|
52
|
+
for i in 0..120
|
53
|
+
disk = disk_service.get
|
54
|
+
if disk.status == OvirtSDK4::DiskStatus::OK
|
55
|
+
ready = true
|
56
|
+
break
|
55
57
|
end
|
56
|
-
break if ready
|
57
58
|
sleep 2
|
58
59
|
end
|
59
60
|
|
@@ -15,6 +15,8 @@ module VagrantPlugins
|
|
15
15
|
end
|
16
16
|
|
17
17
|
def call(env)
|
18
|
+
config = env[:machine].provider_config
|
19
|
+
|
18
20
|
env[:ui].info(I18n.t("vagrant_ovirt4.starting_vm"))
|
19
21
|
|
20
22
|
machine = env[:vms_service].vm_service(env[:machine].id)
|
@@ -23,49 +25,89 @@ module VagrantPlugins
|
|
23
25
|
:vm_name => env[:machine].id.to_s
|
24
26
|
end
|
25
27
|
|
26
|
-
|
27
|
-
env[:machine].config.vm.
|
28
|
-
|
29
|
-
|
28
|
+
# FIX MULTIPLE NETWORK INTERFACES
|
29
|
+
hostname = env[:machine].config.vm.hostname
|
30
|
+
hostname = 'vagrant' if hostname.nil?
|
31
|
+
|
32
|
+
initialization = {
|
33
|
+
host_name: hostname,
|
34
|
+
nic_configurations: [],
|
35
|
+
custom_script: config.cloud_init,
|
36
|
+
}
|
30
37
|
|
31
|
-
|
38
|
+
configured_ifaces_options = []
|
39
|
+
env[:machine].config.vm.networks.each do |network|
|
40
|
+
type, options = network
|
41
|
+
next unless type == :private_network
|
42
|
+
|
43
|
+
configured_ifaces_options << scoped_hash_override(options, :ovirt)
|
32
44
|
end
|
33
45
|
|
34
|
-
|
35
|
-
|
46
|
+
(0...configured_ifaces_options.length()).each do |iface_index|
|
47
|
+
iface_options = configured_ifaces_options[iface_index]
|
48
|
+
|
49
|
+
if iface_options[:interface_name] != nil then
|
50
|
+
iface_name = iface_options[:interface_name]
|
51
|
+
else
|
52
|
+
iface_name = "eth#{iface_index}"
|
53
|
+
end
|
36
54
|
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
55
|
+
if iface_options[:ip] then
|
56
|
+
nic_configuration = {
|
57
|
+
name: iface_name,
|
58
|
+
on_boot: true,
|
59
|
+
boot_protocol: OvirtSDK4::BootProtocol::STATIC,
|
60
|
+
ip: {
|
61
|
+
version: OvirtSDK4::IpVersion::V4,
|
62
|
+
address: iface_options[:ip],
|
63
|
+
gateway: iface_options[:gateway],
|
64
|
+
netmask: iface_options[:netmask],
|
65
|
+
}
|
47
66
|
}
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
67
|
+
else
|
68
|
+
nic_configuration = {
|
69
|
+
name: iface_name,
|
70
|
+
on_boot: true,
|
71
|
+
boot_protocol: OvirtSDK4::BootProtocol::DHCP,
|
72
|
+
}
|
73
|
+
end
|
74
|
+
|
75
|
+
initialization[:nic_configurations] << nic_configuration
|
76
|
+
initialization[:dns_servers] = iface_options[:dns_servers] unless iface_options[:dns_servers].nil?
|
77
|
+
initialization[:dns_search] = iface_options[:dns_search] unless iface_options[:dns_search].nil?
|
55
78
|
end
|
79
|
+
# END FIX MULTIPLE NETWORK INTERFACES
|
56
80
|
|
57
81
|
vm_configuration = {
|
58
|
-
initialization:
|
59
|
-
|
60
|
-
nic_configurations: [nic_configuration],
|
61
|
-
custom_script: env[:machine].provider_config.cloud_init,
|
62
|
-
}
|
82
|
+
initialization: initialization,
|
83
|
+
placement_policy: {},
|
63
84
|
}
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
)
|
85
|
+
|
86
|
+
vm_configuration[:placement_policy][:hosts] = [{ :name => config.placement_host }] unless config.placement_host.nil?
|
87
|
+
vm_configuration[:placement_policy][:affinity] = config.affinity unless config.affinity.nil?
|
88
|
+
|
89
|
+
vm_configuration.delete(:placement_policy) if vm_configuration[:placement_policy].empty?
|
90
|
+
vm_configuration.delete(:nic_configurations) if vm_configuration[:nic_configurations].nil? or vm_configuration[:nic_configurations].empty?
|
91
|
+
|
92
|
+
begin
|
93
|
+
machine.start(
|
94
|
+
use_cloud_init: true,
|
95
|
+
vm: vm_configuration
|
96
|
+
)
|
97
|
+
rescue OvirtSDK4::Error => e
|
98
|
+
fault_message = /Fault detail is \"\[?(.+?)\]?\".*/.match(e.message)[1] rescue e.message
|
99
|
+
retry if e.message =~ /Please try again/
|
100
|
+
|
101
|
+
if e.message !~ /VM is running/
|
102
|
+
if config.debug
|
103
|
+
raise e
|
104
|
+
else
|
105
|
+
raise Errors::StartVMError,
|
106
|
+
:error_message => fault_message
|
107
|
+
end
|
108
|
+
end
|
109
|
+
|
110
|
+
end
|
69
111
|
|
70
112
|
@app.call(env)
|
71
113
|
end
|