vagrant-libvirt 0.0.45 → 0.1.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 (48) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +253 -109
  3. data/lib/vagrant-libvirt/action.rb +2 -2
  4. data/lib/vagrant-libvirt/action/create_domain.rb +59 -29
  5. data/lib/vagrant-libvirt/action/create_domain_volume.rb +14 -8
  6. data/lib/vagrant-libvirt/action/create_network_interfaces.rb +7 -5
  7. data/lib/vagrant-libvirt/action/create_networks.rb +2 -2
  8. data/lib/vagrant-libvirt/action/destroy_domain.rb +1 -1
  9. data/lib/vagrant-libvirt/action/forward_ports.rb +6 -5
  10. data/lib/vagrant-libvirt/action/halt_domain.rb +1 -1
  11. data/lib/vagrant-libvirt/action/handle_box_image.rb +22 -57
  12. data/lib/vagrant-libvirt/action/handle_storage_pool.rb +4 -4
  13. data/lib/vagrant-libvirt/action/package_domain.rb +58 -12
  14. data/lib/vagrant-libvirt/action/prepare_nfs_settings.rb +3 -9
  15. data/lib/vagrant-libvirt/action/prune_nfs_exports.rb +18 -9
  16. data/lib/vagrant-libvirt/action/remove_libvirt_image.rb +2 -2
  17. data/lib/vagrant-libvirt/action/remove_stale_volume.rb +17 -11
  18. data/lib/vagrant-libvirt/action/set_boot_order.rb +2 -2
  19. data/lib/vagrant-libvirt/action/set_name_of_domain.rb +6 -9
  20. data/lib/vagrant-libvirt/action/start_domain.rb +2 -2
  21. data/lib/vagrant-libvirt/action/wait_till_up.rb +7 -9
  22. data/lib/vagrant-libvirt/cap/synced_folder.rb +3 -3
  23. data/lib/vagrant-libvirt/config.rb +62 -11
  24. data/lib/vagrant-libvirt/driver.rb +3 -3
  25. data/lib/vagrant-libvirt/errors.rb +5 -5
  26. data/lib/vagrant-libvirt/plugin.rb +2 -2
  27. data/lib/vagrant-libvirt/templates/domain.xml.erb +18 -5
  28. data/lib/vagrant-libvirt/util/network_util.rb +6 -1
  29. data/lib/vagrant-libvirt/util/nfs.rb +17 -0
  30. data/lib/vagrant-libvirt/version.rb +1 -1
  31. data/locales/en.yml +6 -6
  32. data/spec/unit/action/set_name_of_domain_spec.rb +1 -1
  33. data/spec/unit/templates/domain_all_settings.xml +12 -2
  34. data/spec/unit/templates/domain_spec.rb +10 -2
  35. metadata +21 -34
  36. data/.coveralls.yml +0 -1
  37. data/.github/issue_template.md +0 -37
  38. data/.gitignore +0 -21
  39. data/.travis.yml +0 -24
  40. data/Gemfile +0 -26
  41. data/Rakefile +0 -8
  42. data/example_box/README.md +0 -29
  43. data/example_box/Vagrantfile +0 -60
  44. data/example_box/metadata.json +0 -5
  45. data/lib/vagrant-libvirt/templates/default_storage_volume.xml.erb +0 -14
  46. data/tools/create_box.sh +0 -130
  47. data/tools/prepare_redhat_for_box.sh +0 -119
  48. 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 libvirt storage pool
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
- # b3.use PruneNFSExports
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
- actual_volumes =
123
- env[:machine].provider.driver.connection.volumes.all.select do |x|
124
- x.pool_name == @storage_pool_name
125
- end
126
- domain_volume = ProviderLibvirt::Util::Collection.find_matching(
127
- actual_volumes, "#{@name}.img"
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
- if env[:machine].provider.driver.connection.volumes.select do |x|
159
- x.name == disk[:name] && x.pool_name == @storage_pool_name
160
- end.empty?
161
- # make the disk. equivalent to:
162
- # qemu-img create -f qcow2 <path> 5g
163
- begin
164
- env[:machine].provider.driver.connection.volumes.create(
165
- name: disk[:name],
166
- format_type: disk[:type],
167
- path: disk[:absolute_path],
168
- capacity: disk[:size],
169
- #:allocation => ?,
170
- pool_name: @storage_pool_name
171
- )
172
- rescue Fog::Errors::Error => e
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
- @qargs = config.qemu_args
309
- if not @qargs.empty?
331
+ unless @qemu_args.empty?
310
332
  env[:ui].info(' -- Command line args: ')
311
- @qargs.each do |arg|
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 libvirt domain.
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 = ProviderLibvirt::Util::Collection.find_matching(
29
- env[:machine].provider.driver.connection.volumes.all, @name
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 = ProviderLibvirt::Util::Collection.find_matching(
35
- env[:machine].provider.driver.connection.volumes.all, env[:box_volume_name]
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: config.storage_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
- env[:ui].info I18n.t('vagrant.actions.vm.network.configuring')
223
- env[:machine].guest.capability(
224
- :configure_networks, networks_to_configure
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) libvirt networks.
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) libvirt networks. This
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 libvirt API calls.
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 libvirt currently doesn't support snapshots. Use
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] || 'localhost',
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 'Checking if #{pid} is an ssh process '\
214
- 'with `ps -o cmd= #{pid}`'
215
- `ps -o cmd= #{pid}`.strip.chomp =~ /ssh/
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
@@ -19,7 +19,7 @@ module VagrantPlugins
19
19
  begin
20
20
  env[:machine].guest.capability(:halt)
21
21
  rescue
22
- @logger.info('Trying libvirt graceful shutdown.')
22
+ @logger.info('Trying Libvirt graceful shutdown.')
23
23
  domain.shutdown
24
24
  end
25
25
 
@@ -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
- break if ProviderLibvirt::Util::Collection.find_matching(
68
- env[:machine].provider.driver.connection.volumes.all, env[:box_volume_name]
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
- if config.qemu_use_session
85
- begin
86
- @name = env[:box_volume_name]
87
- @allocation = "#{box_image_size / 1024 / 1024}M"
88
- @capacity = "#{box_virtual_size}G"
89
- @format_type = box_format ? box_format : 'raw'
90
-
91
- @storage_volume_uid = storage_uid env
92
- @storage_volume_gid = storage_gid env
93
-
94
- libvirt_client = env[:machine].provider.driver.connection.client
95
- libvirt_pool = libvirt_client.lookup_storage_pool_by_name(
96
- config.storage_pool_name
97
- )
98
- libvirt_volume = libvirt_pool.create_volume_xml(
99
- to_xml('default_storage_volume')
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
- if config.qemu_use_session
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 libvirt currently doesn't support uploading images to storage
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 if ProviderLibvirt::Util::Collection.find_matching(
28
- env[:machine].provider.driver.connection.pools.all, config.storage_pool_name
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 libvirt currently doesn't support creating pools. Use
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)