vagrant-libvirt 0.0.45 → 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +253 -109
- data/lib/vagrant-libvirt/action.rb +2 -2
- data/lib/vagrant-libvirt/action/create_domain.rb +59 -29
- data/lib/vagrant-libvirt/action/create_domain_volume.rb +14 -8
- data/lib/vagrant-libvirt/action/create_network_interfaces.rb +7 -5
- data/lib/vagrant-libvirt/action/create_networks.rb +2 -2
- data/lib/vagrant-libvirt/action/destroy_domain.rb +1 -1
- data/lib/vagrant-libvirt/action/forward_ports.rb +6 -5
- data/lib/vagrant-libvirt/action/halt_domain.rb +1 -1
- data/lib/vagrant-libvirt/action/handle_box_image.rb +22 -57
- data/lib/vagrant-libvirt/action/handle_storage_pool.rb +4 -4
- data/lib/vagrant-libvirt/action/package_domain.rb +58 -12
- data/lib/vagrant-libvirt/action/prepare_nfs_settings.rb +3 -9
- data/lib/vagrant-libvirt/action/prune_nfs_exports.rb +18 -9
- data/lib/vagrant-libvirt/action/remove_libvirt_image.rb +2 -2
- data/lib/vagrant-libvirt/action/remove_stale_volume.rb +17 -11
- data/lib/vagrant-libvirt/action/set_boot_order.rb +2 -2
- data/lib/vagrant-libvirt/action/set_name_of_domain.rb +6 -9
- data/lib/vagrant-libvirt/action/start_domain.rb +2 -2
- data/lib/vagrant-libvirt/action/wait_till_up.rb +7 -9
- data/lib/vagrant-libvirt/cap/synced_folder.rb +3 -3
- data/lib/vagrant-libvirt/config.rb +62 -11
- data/lib/vagrant-libvirt/driver.rb +3 -3
- data/lib/vagrant-libvirt/errors.rb +5 -5
- data/lib/vagrant-libvirt/plugin.rb +2 -2
- data/lib/vagrant-libvirt/templates/domain.xml.erb +18 -5
- data/lib/vagrant-libvirt/util/network_util.rb +6 -1
- data/lib/vagrant-libvirt/util/nfs.rb +17 -0
- data/lib/vagrant-libvirt/version.rb +1 -1
- data/locales/en.yml +6 -6
- data/spec/unit/action/set_name_of_domain_spec.rb +1 -1
- data/spec/unit/templates/domain_all_settings.xml +12 -2
- data/spec/unit/templates/domain_spec.rb +10 -2
- metadata +21 -34
- data/.coveralls.yml +0 -1
- data/.github/issue_template.md +0 -37
- data/.gitignore +0 -21
- data/.travis.yml +0 -24
- data/Gemfile +0 -26
- data/Rakefile +0 -8
- data/example_box/README.md +0 -29
- data/example_box/Vagrantfile +0 -60
- data/example_box/metadata.json +0 -5
- data/lib/vagrant-libvirt/templates/default_storage_volume.xml.erb +0 -14
- data/tools/create_box.sh +0 -130
- data/tools/prepare_redhat_for_box.sh +0 -119
- data/vagrant-libvirt.gemspec +0 -51
@@ -8,7 +8,7 @@ module VagrantPlugins
|
|
8
8
|
include Vagrant::Action::Builtin
|
9
9
|
@logger = Log4r::Logger.new('vagrant_libvirt::action')
|
10
10
|
|
11
|
-
# remove image from
|
11
|
+
# remove image from Libvirt storage pool
|
12
12
|
def self.remove_libvirt_image
|
13
13
|
Vagrant::Action::Builder.new.tap do |b|
|
14
14
|
b.use RemoveLibvirtImage
|
@@ -187,7 +187,7 @@ module VagrantPlugins
|
|
187
187
|
b2.use Call, DestroyConfirm do |env2, b3|
|
188
188
|
if env2[:result]
|
189
189
|
b3.use ClearForwardedPorts
|
190
|
-
|
190
|
+
b3.use PruneNFSExports
|
191
191
|
b3.use DestroyDomain
|
192
192
|
b3.use DestroyNetworks
|
193
193
|
b3.use ProvisionerCleanup
|
@@ -33,10 +33,13 @@ module VagrantPlugins
|
|
33
33
|
@name = env[:domain_name]
|
34
34
|
@uuid = config.uuid
|
35
35
|
@cpus = config.cpus.to_i
|
36
|
+
@cpuset = config.cpuset
|
36
37
|
@cpu_features = config.cpu_features
|
37
38
|
@cpu_topology = config.cpu_topology
|
39
|
+
@nodeset = config.nodeset
|
38
40
|
@features = config.features
|
39
41
|
@features_hyperv = config.features_hyperv
|
42
|
+
@shares = config.shares
|
40
43
|
@cpu_mode = config.cpu_mode
|
41
44
|
@cpu_model = config.cpu_model
|
42
45
|
@cpu_fallback = config.cpu_fallback
|
@@ -81,6 +84,7 @@ module VagrantPlugins
|
|
81
84
|
|
82
85
|
# Storage
|
83
86
|
@storage_pool_name = config.storage_pool_name
|
87
|
+
@snapshot_pool_name = config.snapshot_pool_name
|
84
88
|
@disks = config.disks
|
85
89
|
@cdroms = config.cdroms
|
86
90
|
|
@@ -106,6 +110,12 @@ module VagrantPlugins
|
|
106
110
|
@redirdevs = config.redirdevs
|
107
111
|
@redirfilters = config.redirfilters
|
108
112
|
|
113
|
+
# Additional QEMU commandline arguments
|
114
|
+
@qemu_args = config.qemu_args
|
115
|
+
|
116
|
+
# Additional QEMU commandline environment variables
|
117
|
+
@qemu_env = config.qemu_env
|
118
|
+
|
109
119
|
# smartcard device
|
110
120
|
@smartcard_dev = config.smartcard_dev
|
111
121
|
|
@@ -119,13 +129,15 @@ module VagrantPlugins
|
|
119
129
|
|
120
130
|
# Get path to domain image from the storage pool selected if we have a box.
|
121
131
|
if env[:machine].config.vm.box
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
|
132
|
+
if @snapshot_pool_name != @storage_pool_name
|
133
|
+
pool_name = @snapshot_pool_name
|
134
|
+
else
|
135
|
+
pool_name = @storage_pool_name
|
136
|
+
end
|
137
|
+
@logger.debug "Search for volume in pool: #{pool_name}"
|
138
|
+
domain_volume = env[:machine].provider.driver.connection.volumes.all(
|
139
|
+
name: "#{@name}.img"
|
140
|
+
).find { |x| x.pool_name == pool_name }
|
129
141
|
raise Errors::DomainVolumeExists if domain_volume.nil?
|
130
142
|
@domain_volume_path = domain_volume.path
|
131
143
|
end
|
@@ -155,26 +167,28 @@ module VagrantPlugins
|
|
155
167
|
|
156
168
|
disk[:absolute_path] = storage_prefix + disk[:path]
|
157
169
|
|
158
|
-
|
159
|
-
|
160
|
-
|
161
|
-
|
162
|
-
|
163
|
-
|
164
|
-
|
165
|
-
|
166
|
-
|
167
|
-
|
168
|
-
|
169
|
-
|
170
|
-
|
171
|
-
|
172
|
-
|
170
|
+
# make the disk. equivalent to:
|
171
|
+
# qemu-img create -f qcow2 <path> 5g
|
172
|
+
begin
|
173
|
+
env[:machine].provider.driver.connection.volumes.create(
|
174
|
+
name: disk[:name],
|
175
|
+
format_type: disk[:type],
|
176
|
+
path: disk[:absolute_path],
|
177
|
+
capacity: disk[:size],
|
178
|
+
#:allocation => ?,
|
179
|
+
pool_name: @storage_pool_name
|
180
|
+
)
|
181
|
+
rescue Libvirt::Error => e
|
182
|
+
# It is hard to believe that e contains just a string
|
183
|
+
# and no useful error code!
|
184
|
+
msg = "Call to virStorageVolCreateXML failed: " +
|
185
|
+
"storage volume '#{disk[:path]}' exists already"
|
186
|
+
if e.message == msg and disk[:allow_existing]
|
187
|
+
disk[:preexisting] = true
|
188
|
+
else
|
173
189
|
raise Errors::FogDomainVolumeCreateError,
|
174
190
|
error_message: e.message
|
175
191
|
end
|
176
|
-
else
|
177
|
-
disk[:preexisting] = true
|
178
192
|
end
|
179
193
|
end
|
180
194
|
|
@@ -184,6 +198,9 @@ module VagrantPlugins
|
|
184
198
|
env[:ui].info(" -- Forced UUID: #{@uuid}") if @uuid != ''
|
185
199
|
env[:ui].info(" -- Domain type: #{@domain_type}")
|
186
200
|
env[:ui].info(" -- Cpus: #{@cpus}")
|
201
|
+
unless @cpuset.nil?
|
202
|
+
env[:ui].info(" -- Cpuset: #{@cpuset}")
|
203
|
+
end
|
187
204
|
if not @cpu_topology.empty?
|
188
205
|
env[:ui].info(" -- CPU topology: sockets=#{@cpu_topology[:sockets]}, cores=#{@cpu_topology[:cores]}, threads=#{@cpu_topology[:threads]}")
|
189
206
|
end
|
@@ -197,9 +214,15 @@ module VagrantPlugins
|
|
197
214
|
env[:ui].info(" -- Feature (HyperV): name=#{feature[:name]}, state=#{feature[:state]}")
|
198
215
|
end
|
199
216
|
env[:ui].info(" -- Memory: #{@memory_size / 1024}M")
|
217
|
+
unless @nodeset.nil?
|
218
|
+
env[:ui].info(" -- Nodeset: #{@nodeset}")
|
219
|
+
end
|
200
220
|
@memory_backing.each do |backing|
|
201
221
|
env[:ui].info(" -- Memory Backing: #{backing[:name]}: #{backing[:config].map { |k,v| "#{k}='#{v}'"}.join(' ')}")
|
202
222
|
end
|
223
|
+
unless @shares.nil?
|
224
|
+
env[:ui].info(" -- Shares: #{@shares}")
|
225
|
+
end
|
203
226
|
env[:ui].info(" -- Management MAC: #{@management_network_mac}")
|
204
227
|
env[:ui].info(" -- Loader: #{@loader}")
|
205
228
|
env[:ui].info(" -- Nvram: #{@nvram}")
|
@@ -255,7 +278,7 @@ module VagrantPlugins
|
|
255
278
|
end
|
256
279
|
|
257
280
|
@pcis.each do |pci|
|
258
|
-
env[:ui].info(" -- PCI passthrough: #{pci[:bus]}:#{pci[:slot]}.#{pci[:function]}")
|
281
|
+
env[:ui].info(" -- PCI passthrough: #{pci[:domain]}:#{pci[:bus]}:#{pci[:slot]}.#{pci[:function]}")
|
259
282
|
end
|
260
283
|
|
261
284
|
unless @rng[:model].nil?
|
@@ -305,18 +328,25 @@ module VagrantPlugins
|
|
305
328
|
env[:ui].info(" -- smartcard device: mode=#{@smartcard_dev[:mode]}, type=#{@smartcard_dev[:type]}")
|
306
329
|
end
|
307
330
|
|
308
|
-
@
|
309
|
-
if not @qargs.empty?
|
331
|
+
unless @qemu_args.empty?
|
310
332
|
env[:ui].info(' -- Command line args: ')
|
311
|
-
@
|
333
|
+
@qemu_args.each do |arg|
|
312
334
|
msg = " -> value=#{arg[:value]}, "
|
313
335
|
env[:ui].info(msg)
|
314
336
|
end
|
315
337
|
end
|
316
338
|
|
339
|
+
unless @qemu_env.empty?
|
340
|
+
env[:ui].info(' -- Command line environment variables: ')
|
341
|
+
@qemu_env.each do |env_var, env_value|
|
342
|
+
msg = " -> #{env_var}=#{env_value}, "
|
343
|
+
env[:ui].info(msg)
|
344
|
+
end
|
345
|
+
end
|
346
|
+
|
317
347
|
env[:ui].info(" -- Command line : #{@cmd_line}") unless @cmd_line.empty?
|
318
348
|
|
319
|
-
# Create
|
349
|
+
# Create Libvirt domain.
|
320
350
|
# Is there a way to tell fog to create new domain with already
|
321
351
|
# existing volume? Use domain creation from template..
|
322
352
|
begin
|
@@ -25,15 +25,15 @@ module VagrantPlugins
|
|
25
25
|
@name = "#{env[:domain_name]}.img"
|
26
26
|
|
27
27
|
# Verify the volume doesn't exist already.
|
28
|
-
domain_volume =
|
29
|
-
|
30
|
-
)
|
31
|
-
raise Errors::DomainVolumeExists if domain_volume
|
28
|
+
domain_volume = env[:machine].provider.driver.connection.volumes.all(
|
29
|
+
name: @name
|
30
|
+
).first
|
31
|
+
raise Errors::DomainVolumeExists if domain_volume && domain_volume.id
|
32
32
|
|
33
33
|
# Get path to backing image - box volume.
|
34
|
-
box_volume =
|
35
|
-
|
36
|
-
)
|
34
|
+
box_volume = env[:machine].provider.driver.connection.volumes.all(
|
35
|
+
name: env[:box_volume_name]
|
36
|
+
).first
|
37
37
|
@backing_file = box_volume.path
|
38
38
|
|
39
39
|
# Virtual size of image. Take value worked out by HandleBoxImage
|
@@ -71,9 +71,15 @@ module VagrantPlugins
|
|
71
71
|
Nokogiri::XML::Node::SaveOptions::NO_EMPTY_TAGS |
|
72
72
|
Nokogiri::XML::Node::SaveOptions::FORMAT
|
73
73
|
)
|
74
|
+
if config.snapshot_pool_name != config.storage_pool_name
|
75
|
+
pool_name = config.snapshot_pool_name
|
76
|
+
else
|
77
|
+
pool_name = config.storage_pool_name
|
78
|
+
end
|
79
|
+
@logger.debug "Using pool #{pool_name} for base box snapshot"
|
74
80
|
domain_volume = env[:machine].provider.driver.connection.volumes.create(
|
75
81
|
xml: xml,
|
76
|
-
pool_name:
|
82
|
+
pool_name: pool_name
|
77
83
|
)
|
78
84
|
rescue Fog::Errors::Error => e
|
79
85
|
raise Errors::FogDomainVolumeCreateError,
|
@@ -219,10 +219,12 @@ module VagrantPlugins
|
|
219
219
|
networks_to_configure << network
|
220
220
|
end
|
221
221
|
|
222
|
-
|
223
|
-
|
224
|
-
:
|
225
|
-
|
222
|
+
unless networks_to_configure.empty?
|
223
|
+
env[:ui].info I18n.t('vagrant.actions.vm.network.configuring')
|
224
|
+
env[:machine].guest.capability(
|
225
|
+
:configure_networks, networks_to_configure
|
226
|
+
)
|
227
|
+
end
|
226
228
|
|
227
229
|
end
|
228
230
|
end
|
@@ -281,7 +283,7 @@ module VagrantPlugins
|
|
281
283
|
return options[:network_name]
|
282
284
|
end
|
283
285
|
|
284
|
-
# Get list of all (active and inactive)
|
286
|
+
# Get list of all (active and inactive) Libvirt networks.
|
285
287
|
available_networks = libvirt_networks(libvirt_client)
|
286
288
|
|
287
289
|
return 'public' if options[:iface_type] == :public_network
|
@@ -47,9 +47,9 @@ module VagrantPlugins
|
|
47
47
|
# should fix other methods so this doesn't have to be instance var
|
48
48
|
@options = options
|
49
49
|
|
50
|
-
# Get a list of all (active and inactive)
|
50
|
+
# Get a list of all (active and inactive) Libvirt networks. This
|
51
51
|
# list is used throughout this class and should be easier to
|
52
|
-
# process than
|
52
|
+
# process than Libvirt API calls.
|
53
53
|
@available_networks = libvirt_networks(
|
54
54
|
env[:machine].provider.driver.connection.client
|
55
55
|
)
|
@@ -14,7 +14,7 @@ module VagrantPlugins
|
|
14
14
|
env[:ui].info(I18n.t('vagrant_libvirt.destroy_domain'))
|
15
15
|
|
16
16
|
# Must delete any snapshots before domain can be destroyed
|
17
|
-
# Fog
|
17
|
+
# Fog Libvirt currently doesn't support snapshots. Use
|
18
18
|
# ruby-libvirt client directly. Note this is racy, see
|
19
19
|
# http://www.libvirt.org/html/libvirt-libvirt.html#virDomainSnapshotListNames
|
20
20
|
libvirt_domain = env[:machine].provider.driver.connection.client.lookup_domain_by_uuid(
|
@@ -54,7 +54,7 @@ module VagrantPlugins
|
|
54
54
|
|
55
55
|
ssh_pid = redirect_port(
|
56
56
|
@env[:machine],
|
57
|
-
fp[:host_ip] || '
|
57
|
+
fp[:host_ip] || '*',
|
58
58
|
fp[:host],
|
59
59
|
fp[:guest_ip] || @env[:machine].provider.ssh_info[:host],
|
60
60
|
fp[:guest],
|
@@ -97,6 +97,7 @@ module VagrantPlugins
|
|
97
97
|
User=#{ssh_info[:username]}
|
98
98
|
Port=#{ssh_info[:port]}
|
99
99
|
UserKnownHostsFile=/dev/null
|
100
|
+
ExitOnForwardFailure=yes
|
100
101
|
StrictHostKeyChecking=no
|
101
102
|
PasswordAuthentication=no
|
102
103
|
ForwardX11=#{ssh_info[:forward_x11] ? 'yes' : 'no'}
|
@@ -120,7 +121,7 @@ module VagrantPlugins
|
|
120
121
|
end
|
121
122
|
end
|
122
123
|
|
123
|
-
ssh_cmd << "ssh #{options} #{params}"
|
124
|
+
ssh_cmd << "ssh -n #{options} #{params}"
|
124
125
|
|
125
126
|
@logger.debug "Forwarding port with `#{ssh_cmd}`"
|
126
127
|
log_file = ssh_forward_log_file(host_ip, host_port,
|
@@ -210,9 +211,9 @@ module VagrantPlugins
|
|
210
211
|
end
|
211
212
|
|
212
213
|
def ssh_pid?(pid)
|
213
|
-
@logger.debug
|
214
|
-
|
215
|
-
`ps -o
|
214
|
+
@logger.debug "Checking if #{pid} is an ssh process "\
|
215
|
+
"with `ps -o command= #{pid}`"
|
216
|
+
`ps -o command= #{pid}`.strip.chomp =~ /ssh/
|
216
217
|
end
|
217
218
|
|
218
219
|
def remove_ssh_pids
|
@@ -4,7 +4,6 @@ module VagrantPlugins
|
|
4
4
|
module ProviderLibvirt
|
5
5
|
module Action
|
6
6
|
class HandleBoxImage
|
7
|
-
include VagrantPlugins::ProviderLibvirt::Util::ErbTemplate
|
8
7
|
include VagrantPlugins::ProviderLibvirt::Util::StorageUtil
|
9
8
|
|
10
9
|
|
@@ -64,9 +63,10 @@ module VagrantPlugins
|
|
64
63
|
# locking all subsequent actions as well.
|
65
64
|
@@lock.synchronize do
|
66
65
|
# Don't continue if image already exists in storage pool.
|
67
|
-
|
68
|
-
|
69
|
-
)
|
66
|
+
box_volume = env[:machine].provider.driver.connection.volumes.all(
|
67
|
+
name: env[:box_volume_name]
|
68
|
+
).first
|
69
|
+
break if box_volume && box_volume.id
|
70
70
|
|
71
71
|
# Box is not available as a storage pool volume. Create and upload
|
72
72
|
# it as a copy of local box image.
|
@@ -81,40 +81,22 @@ module VagrantPlugins
|
|
81
81
|
message << " in storage pool #{config.storage_pool_name}."
|
82
82
|
@logger.info(message)
|
83
83
|
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
)
|
101
|
-
rescue => e
|
102
|
-
raise Errors::CreatingVolumeError,
|
103
|
-
error_message: e.message
|
104
|
-
end
|
105
|
-
else
|
106
|
-
begin
|
107
|
-
fog_volume = env[:machine].provider.driver.connection.volumes.create(
|
108
|
-
name: env[:box_volume_name],
|
109
|
-
allocation: "#{box_image_size / 1024 / 1024}M",
|
110
|
-
capacity: "#{box_virtual_size}G",
|
111
|
-
format_type: box_format,
|
112
|
-
pool_name: config.storage_pool_name
|
113
|
-
)
|
114
|
-
rescue Fog::Errors::Error => e
|
115
|
-
raise Errors::FogCreateVolumeError,
|
116
|
-
error_message: e.message
|
117
|
-
end
|
84
|
+
@storage_volume_uid = storage_uid env
|
85
|
+
@storage_volume_gid = storage_gid env
|
86
|
+
|
87
|
+
begin
|
88
|
+
fog_volume = env[:machine].provider.driver.connection.volumes.create(
|
89
|
+
name: env[:box_volume_name],
|
90
|
+
allocation: "#{box_image_size / 1024 / 1024}M",
|
91
|
+
capacity: "#{box_virtual_size}G",
|
92
|
+
format_type: box_format,
|
93
|
+
owner: @storage_volume_uid,
|
94
|
+
group: @storage_volume_gid,
|
95
|
+
pool_name: config.storage_pool_name
|
96
|
+
)
|
97
|
+
rescue Fog::Errors::Error => e
|
98
|
+
raise Errors::FogCreateVolumeError,
|
99
|
+
error_message: e.message
|
118
100
|
end
|
119
101
|
|
120
102
|
# Upload box image to storage pool
|
@@ -132,11 +114,7 @@ module VagrantPlugins
|
|
132
114
|
# storage pool.
|
133
115
|
if env[:interrupted] || !ret
|
134
116
|
begin
|
135
|
-
|
136
|
-
libvirt_volume.delete
|
137
|
-
else
|
138
|
-
fog_volume.destroy
|
139
|
-
end
|
117
|
+
fog_volume.destroy
|
140
118
|
rescue
|
141
119
|
nil
|
142
120
|
end
|
@@ -146,22 +124,9 @@ module VagrantPlugins
|
|
146
124
|
@app.call(env)
|
147
125
|
end
|
148
126
|
|
149
|
-
def split_size_unit(text)
|
150
|
-
if text.kind_of? Integer
|
151
|
-
# if text is an integer, match will fail
|
152
|
-
size = text
|
153
|
-
unit = 'G'
|
154
|
-
else
|
155
|
-
matcher = text.match(/(\d+)(.+)/)
|
156
|
-
size = matcher[1]
|
157
|
-
unit = matcher[2]
|
158
|
-
end
|
159
|
-
[size, unit]
|
160
|
-
end
|
161
|
-
|
162
127
|
protected
|
163
128
|
|
164
|
-
# Fog
|
129
|
+
# Fog Libvirt currently doesn't support uploading images to storage
|
165
130
|
# pool volumes. Use ruby-libvirt client instead.
|
166
131
|
def upload_image(image_file, pool_name, volume_name, env)
|
167
132
|
image_size = File.size(image_file) # B
|
@@ -24,9 +24,9 @@ module VagrantPlugins
|
|
24
24
|
# locking all subsequent actions as well.
|
25
25
|
@@lock.synchronize do
|
26
26
|
# Check for storage pool, where box image should be created
|
27
|
-
break
|
28
|
-
|
29
|
-
)
|
27
|
+
break unless env[:machine].provider.driver.connection.pools.all(
|
28
|
+
name: config.storage_pool_name
|
29
|
+
).empty?
|
30
30
|
|
31
31
|
@logger.info("No storage pool '#{config.storage_pool_name}' is available.")
|
32
32
|
|
@@ -36,7 +36,7 @@ module VagrantPlugins
|
|
36
36
|
|
37
37
|
@logger.info("Creating storage pool 'default'")
|
38
38
|
|
39
|
-
# Fog
|
39
|
+
# Fog Libvirt currently doesn't support creating pools. Use
|
40
40
|
# ruby-libvirt client directly.
|
41
41
|
begin
|
42
42
|
@storage_pool_path = storage_pool_path(env)
|