vagrant-libvirt 0.0.13 → 0.0.14

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 ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 6a7de8bcfdcab60b3237c7d64fd047fa9b43bbf8
4
+ data.tar.gz: f98b1b521b2d6665be337341791ae260244d29eb
5
+ SHA512:
6
+ metadata.gz: 6d33e5ae966f1758ec327b73a9d3527cfa0b6c3ab461630beb4e13bc391c5f291ab04b48884bc0d568e2376ee3fda1361bce6efab0d3d5513b987f08f7b75513
7
+ data.tar.gz: 83408a1dcb5c55fd745e204b7d23f78cf1ec9d6e6eb5beb8a27f31cbff4154a916bd9068b7e80dade9318f97b504a77671171486ce954e65b9af73474487e151
data/Gemfile CHANGED
@@ -4,11 +4,9 @@ source 'https://rubygems.org'
4
4
  gemspec
5
5
 
6
6
  group :development do
7
- gem 'rake'
8
- gem 'rspec', '~> 2.13.0'
9
- gem 'rspec-fire', require: 'rspec/fire'
10
- gem 'rspec-spies', require: false
11
- gem 'coveralls', require: false
12
- gem 'vagrant', :git => 'git://github.com/mitchellh/vagrant.git'
7
+ # We depend on Vagrant for development, but we don't add it as a
8
+ # gem dependency because we expect to be installed within the
9
+ # Vagrant environment itself using `vagrant plugin`.
10
+ gem "vagrant", :git => "git://github.com/mitchellh/vagrant.git"
13
11
  end
14
12
 
data/README.md CHANGED
@@ -99,14 +99,19 @@ This provider exposes quite a few provider-specific configuration options:
99
99
  * `password` - Password to access Libvirt.
100
100
  * `id_ssh_key_file` - The id ssh key file name to access Libvirt (eg: id_dsa or id_rsa or ... in the user .ssh directory)
101
101
  * `storage_pool_name` - Libvirt storage pool name, where box image and instance snapshots will be stored.
102
- * `default_network` - Libvirt default network name. If not specified default network name is 'default'.
103
102
 
104
103
  ### Domain Specific Options
105
104
 
105
+ * `disk_bus` - The type of disk device to emulate. Defaults to virtio if not set. Possible values are documented in libvirt's [description for _target_](http://libvirt.org/formatdomain.html#elementsDisks).
106
106
  * `memory` - Amount of memory in MBytes. Defaults to 512 if not set.
107
107
  * `cpus` - Number of virtual cpus. Defaults to 1 if not set.
108
108
  * `nested` - [Enable nested virtualization](https://github.com/torvalds/linux/blob/master/Documentation/virtual/kvm/nested-vmx.txt). Default is false.
109
+ * `cpu_mode` - What cpu mode to use for nested virtualization. Defaults to 'host-model' if not set.
109
110
  * `volume_cache` - Controls the cache mechanism. Possible values are "default", "none", "writethrough", "writeback", "directsync" and "unsafe". [See driver->cache in libvirt documentation](http://libvirt.org/formatdomain.html#elementsDisks).
111
+ * `kernel` - To launch the guest with a kernel residing on host filesystems (Equivalent to qemu `-kernel`)
112
+ * `initrd` - To specify the initramfs/initrd to use for the guest (Equivalent to qemu `-initrd`)
113
+ * `cmd_line` - Arguments passed on to the guest kernel initramfs or initrd to use (Equivalent to qemu `-append`)
114
+
110
115
 
111
116
  Specific domain settings can be set for each domain separately in multi-VM
112
117
  environment. Example below shows a part of Vagrantfile, where specific options
@@ -120,7 +125,7 @@ Vagrant.configure("2") do |config|
120
125
  domain.memory = 2048
121
126
  domain.cpus = 2
122
127
  domain.nested = true
123
- domain.volume_cache = 'none'
128
+ domain.volume_cache = 'none'
124
129
  end
125
130
  end
126
131
 
@@ -229,15 +234,24 @@ starts with 'libvirt__' string. Here is a list of those options:
229
234
  Default mode is 'bridge'.
230
235
  * `:mac` - MAC address for the interface.
231
236
 
232
- ## Obtaining Domain IP Address
237
+ ### Management Network
238
+
239
+ Vagrant-libvirt uses a private network to perform some management operations
240
+ on VMs. All VMs will have an interface connected to this network and
241
+ an IP address dynamically assigned by libvirt. This is in addition to any
242
+ networks you configure. The name and address used by this network are
243
+ configurable at the provider level.
244
+
245
+ * `management_network_name` - Name of libvirt network to which all VMs will be connected. If not specified the default is 'vagrant-libvirt'.
246
+ * `management_network_address` - Address of network to which all VMs will be connected. Must include the address and subnet mask. If not specified the default is '192.168.121.0/24'.
233
247
 
234
- Libvirt doesn't provide standard way how to find out an IP address of running
235
- domain. But we know, what is MAC address of virtual machine. Libvirt is closely
236
- connected with dnsmasq server, which acts also as a DHCP server. Dnsmasq server
237
- makes lease information public in `/var/lib/libvirt/dnsmasq` directory, or in
238
- `/var/lib/misc/dnsmasq.leases` file on some systems. This is the place, where
239
- information like which MAC address has which IP address resides and it's parsed
240
- by vagrant-libvirt plugin.
248
+ You may wonder how vagrant-libvirt knows the IP address a VM received.
249
+ Libvirt doesn't provide a standard way to find out the IP address of a running
250
+ domain. But we do know the MAC address of the virtual machine's interface on
251
+ the management network. Libvirt is closely connected with dnsmasq, which acts as
252
+ a DHCP server. dnsmasq writes lease information in the `/var/lib/libvirt/dnsmasq`
253
+ directory. Vagrant-libvirt looks for the MAC address in this file and extracts
254
+ the corresponding IP address.
241
255
 
242
256
  ## SSH Access To VM
243
257
 
data/Rakefile CHANGED
@@ -2,7 +2,6 @@
2
2
 
3
3
  #require 'rubygems'
4
4
  #require 'bundler/setup'
5
- Dir['./tasks/**/*.rake'].each { |f| load f }
6
5
  require 'bundler/gem_tasks'
7
6
  Bundler::GemHelper.install_tasks
8
7
  task default: [:deftask]
@@ -52,6 +52,9 @@ Vagrant.configure("2") do |config|
52
52
  # Libvirt storage pool name, where box image and instance snapshots will
53
53
  # be stored.
54
54
  libvirt.storage_pool_name = "default"
55
+
56
+ # Set a prefix for the machines that's different than the project dir name.
57
+ #libvirt.default_prefix = ''
55
58
  end
56
59
  end
57
60
 
@@ -25,7 +25,13 @@ module VagrantPlugins
25
25
  b2.use CreateNetworks
26
26
  b2.use CreateNetworkInterfaces
27
27
 
28
- b2.use NFS
28
+ if Vagrant::VERSION < "1.4.0"
29
+ b2.use NFS
30
+ else
31
+ b2.use SyncedFolderCleanup
32
+ b2.use SyncedFolders
33
+ end
34
+
29
35
  b2.use PrepareNFSSettings
30
36
  b2.use ShareFolders
31
37
  b2.use SetHostname
@@ -51,19 +57,32 @@ module VagrantPlugins
51
57
  next if env[:result]
52
58
 
53
59
  b2.use Call, IsSuspended do |env2, b3|
60
+ # if vm is suspended resume it then exit
54
61
  if env2[:result]
55
62
  b3.use ResumeDomain
56
63
  next
57
64
  end
58
65
 
59
- # VM is not running or suspended. Start it.. Machine should gain
60
- # IP address when comming up, so wait for dhcp lease and store IP
61
- # into machines data_dir.
62
- b3.use NFS
66
+ # VM is not running or suspended.
67
+
68
+ # Ensure networks are created and active
69
+ b3.use CreateNetworks
70
+
71
+ # Handle shared folders
72
+ if Vagrant::VERSION < "1.4.0"
73
+ b3.use NFS
74
+ else
75
+ b3.use SyncedFolderCleanup
76
+ b3.use SyncedFolders
77
+ end
63
78
  b3.use PrepareNFSSettings
64
79
  b3.use ShareFolders
65
80
 
81
+ # Start it..
66
82
  b3.use StartDomain
83
+
84
+ # Machine should gain IP address when comming up,
85
+ # so wait for dhcp lease and store IP into machines data_dir.
67
86
  b3.use WaitTillUp
68
87
  end
69
88
  end
@@ -302,6 +321,10 @@ module VagrantPlugins
302
321
  autoload :WaitTillUp, action_root.join('wait_till_up')
303
322
  autoload :SSHRun, 'vagrant/action/builtin/ssh_run'
304
323
  autoload :HandleBoxUrl, 'vagrant/action/builtin/handle_box_url'
324
+ unless Vagrant::VERSION < "1.4.0"
325
+ autoload :SyncedFolders, 'vagrant/action/builtin/synced_folders'
326
+ autoload :SyncedFolderCleanup, 'vagrant/action/builtin/synced_folder_cleanup'
327
+ end
305
328
  end
306
329
  end
307
330
  end
@@ -67,13 +67,9 @@ module VagrantPlugins
67
67
  conn_attr[:libvirt_password] = config.password if config.password
68
68
 
69
69
  # Setup command for retrieving IP address for newly created machine
70
- # with some MAC address. Get it from dnsmasq leases table - either
71
- # /var/lib/libvirt/dnsmasq/*.leases files, or
72
- # /var/lib/misc/dnsmasq.leases if available.
73
- ip_command = "LEASES='/var/lib/libvirt/dnsmasq/*.leases'; "
74
- ip_command << "[ -f /var/lib/misc/dnsmasq.leases ] && "
75
- ip_command << "LEASES='/var/lib/misc/dnsmasq.leases'; "
76
- ip_command << "grep $mac $LEASES | awk '{ print $3 }'"
70
+ # with some MAC address. Get it from dnsmasq leases table
71
+ ip_command = %q[ LEASES=$(find /var/lib/libvirt/dnsmasq/ /var/lib/misc/ -name '*leases'); ]
72
+ ip_command << %q[ [ -n "$LEASES" ] && grep $mac $LEASES | awk '{ print $3 }' ]
77
73
  conn_attr[:libvirt_ip_command] = ip_command
78
74
 
79
75
  @logger.info("Connecting to Libvirt (#{uri}) ...")
@@ -19,9 +19,14 @@ module VagrantPlugins
19
19
  # Gather some info about domain
20
20
  @name = env[:domain_name]
21
21
  @cpus = config.cpus
22
+ @cpu_mode = config.cpu_mode
23
+ @disk_bus = config.disk_bus
22
24
  @nested = config.nested
23
25
  @memory_size = config.memory*1024
24
26
  @domain_volume_cache = config.volume_cache
27
+ @kernel = config.kernel
28
+ @cmd_line = config.cmd_line
29
+ @initrd = config.initrd
25
30
 
26
31
  # TODO get type from driver config option
27
32
  @domain_type = 'kvm'
@@ -44,6 +49,9 @@ module VagrantPlugins
44
49
  env[:ui].info(" -- Storage pool: #{env[:machine].provider_config.storage_pool_name}")
45
50
  env[:ui].info(" -- Image: #{@domain_volume_path}")
46
51
  env[:ui].info(" -- Volume Cache: #{@domain_volume_cache}")
52
+ env[:ui].info(" -- Kernel: #{@kernel}")
53
+ env[:ui].info(" -- Initrd: #{@initrd}")
54
+ env[:ui].info(" -- Command line : #{@cmd_line}")
47
55
 
48
56
  # Create libvirt domain.
49
57
  # Is there a way to tell fog to create new domain with already
@@ -16,7 +16,7 @@ module VagrantPlugins
16
16
 
17
17
  def initialize(app, env)
18
18
  @logger = Log4r::Logger.new('vagrant_libvirt::action::create_network_interfaces')
19
- @default_network = env[:machine].provider_config.default_network;
19
+ @management_network_name = env[:machine].provider_config.management_network_name
20
20
  @app = app
21
21
  end
22
22
 
@@ -37,6 +37,7 @@ module VagrantPlugins
37
37
 
38
38
  # Assign interfaces to slots.
39
39
  env[:machine].config.vm.networks.each do |type, options|
40
+ @logger.debug "In config found network type #{type} options #{options}"
40
41
 
41
42
  # Get options for this interface. Options can be specified in
42
43
  # Vagrantfile in short format (:ip => ...), or provider format
@@ -51,8 +52,10 @@ module VagrantPlugins
51
52
  end
52
53
 
53
54
  free_slot = options[:adapter].to_i
55
+ @logger.debug "Using specified adapter slot #{free_slot}"
54
56
  else
55
57
  free_slot = find_empty(adapters)
58
+ @logger.debug "Adapter not specified so found slot #{free_slot}"
56
59
  raise Errors::InterfaceSlotNotAvailable if free_slot == nil
57
60
  end
58
61
 
@@ -104,6 +107,7 @@ module VagrantPlugins
104
107
  # it has to be available during provisioning - ifdown command is
105
108
  # not acceptable here.
106
109
  next if slot_number == 0
110
+ @logger.debug "Configuring interface slot_number #{slot_number} options #{options}"
107
111
 
108
112
  network = {
109
113
  :interface => slot_number,
@@ -139,7 +143,10 @@ module VagrantPlugins
139
143
 
140
144
  # Return network name according to interface options.
141
145
  def interface_network(libvirt_client, options)
142
- return options[:network_name] if options[:network_name]
146
+ if options[:network_name]
147
+ @logger.debug "Found network by name"
148
+ return options[:network_name]
149
+ end
143
150
 
144
151
  # Get list of all (active and inactive) libvirt networks.
145
152
  available_networks = libvirt_networks(libvirt_client)
@@ -147,12 +154,20 @@ module VagrantPlugins
147
154
  if options[:ip]
148
155
  address = network_address(options[:ip], options[:netmask])
149
156
  available_networks.each do |network|
150
- return network[:name] if address == network[:network_address]
157
+ if address == network[:network_address]
158
+ @logger.debug "Found network by ip"
159
+ return network[:name]
160
+ end
151
161
  end
152
162
  end
153
163
 
154
- # TODO Network default can be missing or named different.
155
- return @default_network;
164
+ # the management network always gets attached to slot 0
165
+ # because the first network is of type forwarded_port.
166
+ # this is confusing.
167
+ # TODO only iterate over networks of type private_network
168
+ # and prepend the management network to that list
169
+ @logger.debug "Did not find network so using default of #{@management_network_name}"
170
+ @management_network_name
156
171
  end
157
172
  end
158
173
  end
@@ -2,6 +2,7 @@ require 'log4r'
2
2
  require 'vagrant/util/network_ip'
3
3
  require 'vagrant/util/scoped_hash_override'
4
4
  require 'ipaddr'
5
+ require 'thread'
5
6
 
6
7
  module VagrantPlugins
7
8
  module ProviderLibvirt
@@ -13,6 +14,8 @@ module VagrantPlugins
13
14
  include VagrantPlugins::ProviderLibvirt::Util::ErbTemplate
14
15
  include VagrantPlugins::ProviderLibvirt::Util::LibvirtUtil
15
16
 
17
+ @@lock = Mutex.new
18
+
16
19
  def initialize(app, env)
17
20
  mess = 'vagrant_libvirt::action::create_networks'
18
21
  @logger = Log4r::Logger.new(mess)
@@ -25,60 +28,98 @@ module VagrantPlugins
25
28
 
26
29
  def call(env)
27
30
 
28
- # Iterate over networks requested from config. If some network is not
29
- # available, create it if possible. Otherwise raise an error.
30
- env[:machine].config.vm.networks.each do |type, options|
31
+ management_network_name = env[:machine].provider_config.management_network_name
32
+ management_network_address = env[:machine].provider_config.management_network_address
33
+ @logger.info "Using #{management_network_name} at #{management_network_address} as the management network"
31
34
 
32
- # Get a list of all (active and inactive) libvirt networks. This
33
- # list is used throughout this class and should be easier to
34
- # process than libvirt API calls.
35
- @available_networks = libvirt_networks(env[:libvirt_compute].client)
35
+ begin
36
+ management_network_ip = IPAddr.new(management_network_address)
37
+ rescue ArgumentError
38
+ raise Errors::ManagementNetworkError,
39
+ error_message: "#{management_network_address} is not a valid IP address"
40
+ end
36
41
 
37
- # Now, we support private networks only. There are two other types
38
- # public network and port forwarding, but there are problems with
39
- # creating them via libvirt API, so this provider doesn't implement
40
- # them.
41
- next if type != :private_network
42
+ # capture address into $1 and mask into $2
43
+ management_network_ip.inspect =~ /IPv4:(.*)\/(.*)>/
42
44
 
43
- # Get options for this interface network. Options can be specified
44
- # in Vagrantfile in short format (:ip => ...), or provider format
45
- # (:libvirt__network_name => ...).
46
- @options = scoped_hash_override(options, :libvirt)
47
- @options = {
45
+ if $2 == '255.255.255.255'
46
+ raise Errors::ManagementNetworkError,
47
+ error_message: "#{management_network_address} does not include both an address and subnet mask"
48
+ end
49
+
50
+ management_network_options = {
51
+ network_name: management_network_name,
52
+ ip: $1,
53
+ netmask: $2,
54
+ dhcp_enabled: true,
55
+ forward_mode: 'nat',
56
+ }
57
+
58
+ # add management network to list of networks to check
59
+ networks = [ management_network_options ]
60
+
61
+ env[:machine].config.vm.networks.each do |type, original_options|
62
+ # There are two other types public network and port forwarding,
63
+ # but there are problems with creating them via libvirt API,
64
+ # so this provider doesn't implement them.
65
+ next if type != :private_network
66
+ # Options can be specified in Vagrantfile in short format (:ip => ...),
67
+ # or provider format # (:libvirt__network_name => ...).
68
+ # https://github.com/mitchellh/vagrant/blob/master/lib/vagrant/util/scoped_hash_override.rb
69
+ options = scoped_hash_override(original_options, :libvirt)
70
+ # use default values if not already set
71
+ options = {
48
72
  netmask: '255.255.255.0',
49
73
  dhcp_enabled: true,
50
74
  forward_mode: 'nat',
51
- }.merge(@options)
52
-
53
- # Prepare a hash describing network for this specific interface.
54
- @interface_network = {
55
- name: nil,
56
- ip_address: nil,
57
- netmask: @options[:netmask],
58
- network_address: nil,
59
- bridge_name: nil,
60
- created: false,
61
- active: false,
62
- autostart: false,
63
- libvirt_network: nil,
64
- }
65
-
66
- if @options[:ip]
67
- handle_ip_option(env)
68
- elsif @options[:network_name]
69
- handle_network_name_option
70
- else
71
- # TODO: Should be smarter than just using fixed 'default' string.
72
- @interface_network = lookup_network_by_name('default')
73
- if !@interface_network
74
- raise Errors::NetworkNotAvailableError,
75
- network_name: 'default'
75
+ }.merge(options)
76
+ # add to list of networks to check
77
+ networks.push(options)
78
+ end
79
+
80
+ # only one vm at a time should try to set up networks
81
+ # otherwise they'll have inconsitent views of current state
82
+ # and conduct redundant operations that cause errors
83
+ @@lock.synchronize do
84
+ # Iterate over networks If some network is not
85
+ # available, create it if possible. Otherwise raise an error.
86
+ networks.each do |options|
87
+ @logger.debug "Searching for network with options #{options}"
88
+
89
+ # should fix other methods so this doesn't have to be instance var
90
+ @options = options
91
+
92
+ # Get a list of all (active and inactive) libvirt networks. This
93
+ # list is used throughout this class and should be easier to
94
+ # process than libvirt API calls.
95
+ @available_networks = libvirt_networks(env[:libvirt_compute].client)
96
+
97
+ # Prepare a hash describing network for this specific interface.
98
+ @interface_network = {
99
+ name: nil,
100
+ ip_address: nil,
101
+ netmask: @options[:netmask],
102
+ network_address: nil,
103
+ bridge_name: nil,
104
+ created: false,
105
+ active: false,
106
+ autostart: false,
107
+ libvirt_network: nil,
108
+ }
109
+
110
+ if @options[:ip]
111
+ handle_ip_option(env)
112
+ # in vagrant 1.2.3 and later it is not possible to take this branch
113
+ # because cannot have name without ip
114
+ # https://github.com/mitchellh/vagrant/commit/cf2f6da4dbcb4f57c9cdb3b94dcd0bba62c5f5fd
115
+ elsif @options[:network_name]
116
+ handle_network_name_option
76
117
  end
77
- end
78
118
 
79
- autostart_network if !@interface_network[:autostart]
80
- activate_network if !@interface_network[:active]
119
+ autostart_network if !@interface_network[:autostart]
120
+ activate_network if !@interface_network[:active]
81
121
  end
122
+ end
82
123
 
83
124
  @app.call(env)
84
125
  end
@@ -87,6 +128,7 @@ module VagrantPlugins
87
128
 
88
129
  # Return hash of network for specified name, or nil if not found.
89
130
  def lookup_network_by_name(network_name)
131
+ @logger.debug "looking up network named #{network_name}"
90
132
  @available_networks.each do |network|
91
133
  return network if network[:name] == network_name
92
134
  end
@@ -95,12 +137,25 @@ module VagrantPlugins
95
137
 
96
138
  # Return hash of network for specified bridge, or nil if not found.
97
139
  def lookup_bridge_by_name(bridge_name)
140
+ @logger.debug "looking up bridge named #{bridge_name}"
98
141
  @available_networks.each do |network|
99
142
  return network if network[:bridge_name] == bridge_name
100
143
  end
101
144
  nil
102
145
  end
103
146
 
147
+ # Throw an error if dhcp setting for an existing network does not
148
+ # match what was configured in the vagrantfile
149
+ # since we always enable dhcp for the management network
150
+ # this ensures we wont start a vm vagrant cant reach
151
+ def verify_dhcp
152
+ unless @options[:dhcp_enabled] == @interface_network[:dhcp_enabled]
153
+ raise Errors::DHCPMismatch,
154
+ network_name: @interface_network[:name],
155
+ requested: @options[:dhcp_enabled] ? 'enabled' : 'disabled'
156
+ end
157
+ end
158
+
104
159
  # Handle only situations, when ip is specified. Variables @options and
105
160
  # @available_networks should be filled before calling this function.
106
161
  def handle_ip_option(env)
@@ -120,11 +175,18 @@ module VagrantPlugins
120
175
  if available_network[:network_address] == \
121
176
  @interface_network[:network_address]
122
177
  @interface_network = available_network
178
+ @logger.debug "found existing network by ip, values are"
179
+ @logger.debug @interface_network
123
180
  break
124
181
  end
125
182
  end
126
183
 
184
+ if @interface_network[:created]
185
+ verify_dhcp
186
+ end
187
+
127
188
  if @options[:network_name]
189
+ @logger.debug "Checking that network name does not clash with ip"
128
190
  if @interface_network[:created]
129
191
  # Just check for mismatch error here - if name and ip from
130
192
  # config match together.
@@ -156,6 +218,7 @@ module VagrantPlugins
156
218
  # Is name for new network set? If not, generate a unique one.
157
219
  count = 0
158
220
  while @interface_network[:name].nil?
221
+ @logger.debug "generating name for network"
159
222
 
160
223
  # Generate a network name.
161
224
  network_name = env[:root_path].basename.to_s.dup
@@ -171,6 +234,7 @@ module VagrantPlugins
171
234
  # Generate a unique name for network bridge.
172
235
  count = 0
173
236
  while @interface_network[:bridge_name].nil?
237
+ @logger.debug "generating name for bridge"
174
238
  bridge_name = 'virbr'
175
239
  bridge_name << count.to_s
176
240
  count += 1
@@ -195,6 +259,8 @@ module VagrantPlugins
195
259
  if !@interface_network
196
260
  raise Errors::NetworkNotAvailableError,
197
261
  network_name: @options[:network_name]
262
+ else
263
+ verify_dhcp
198
264
  end
199
265
  end
200
266
 
@@ -234,6 +300,7 @@ module VagrantPlugins
234
300
  begin
235
301
  @interface_network[:libvirt_network] = \
236
302
  @libvirt_client.define_network_xml(to_xml('private_network'))
303
+ @logger.debug "created network"
237
304
  rescue => e
238
305
  raise Errors::CreateNetworkError, error_message: e.message
239
306
  end
@@ -18,7 +18,7 @@ module VagrantPlugins
18
18
  # data directory, created_networks file holds UUIDs of each network.
19
19
  created_networks_file = env[:machine].data_dir + 'created_networks'
20
20
 
21
- @logger.info 'Attepmt destroy network'
21
+ @logger.info 'Checking if any networks were created'
22
22
  # If created_networks file doesn't exist, there are no networks we
23
23
  # need to remove.
24
24
  unless File.exist?(created_networks_file)
@@ -26,39 +26,45 @@ module VagrantPlugins
26
26
  return @app.call(env)
27
27
  end
28
28
 
29
- @logger.info 'file with network exists'
29
+ @logger.info 'File with created networks exists'
30
30
 
31
31
  # Iterate over each created network UUID and try to remove it.
32
32
  created_networks = []
33
33
  file = File.open(created_networks_file, 'r')
34
34
  file.readlines.each do |network_uuid|
35
- @logger.info network_uuid
35
+ @logger.info "Checking for #{network_uuid}"
36
+ # lookup_network_by_uuid throws same exception
37
+ # if there is an error or if the network just doesn't exist
36
38
  begin
37
39
  libvirt_network = env[:libvirt_compute].client.lookup_network_by_uuid(
38
40
  network_uuid)
39
- rescue
40
- raise network_uuid
41
- next
41
+ rescue Libvirt::RetrieveError => e
42
+ # this network is already destroyed, so move on
43
+ if e.message =~ /Network not found/
44
+ @logger.info "It is already undefined"
45
+ next
46
+ # some other error occured, so raise it again
47
+ else
48
+ raise e
49
+ end
42
50
  end
43
51
 
44
- # Maybe network doesn't exist anymore.
45
- next unless libvirt_network
46
-
47
52
  # Skip removing if network has still active connections.
48
53
  xml = Nokogiri::XML(libvirt_network.xml_desc)
49
54
  connections = xml.xpath('/network/@connections').first
50
- @logger.info connections
51
55
  if connections != nil
56
+ @logger.info "Still has connections so will not undefine"
52
57
  created_networks << network_uuid
53
58
  next
54
59
  end
55
60
 
56
- # Shutdown network first.
57
- libvirt_network.destroy
58
61
 
62
+ # Shutdown network first.
59
63
  # Undefine network.
60
64
  begin
65
+ libvirt_network.destroy
61
66
  libvirt_network.undefine
67
+ @logger.info "Undefined it"
62
68
  rescue => e
63
69
  raise Error::DestroyNetworkError,
64
70
  network_name: libvirt_network.name,
@@ -68,13 +74,16 @@ module VagrantPlugins
68
74
  file.close
69
75
 
70
76
  # Update status of created networks after removing some/all of them.
77
+ # Not sure why we are doing this, something else seems to always delete the file
71
78
  if created_networks.length > 0
72
79
  File.open(created_networks_file, 'w') do |file|
80
+ @logger.info "Writing new created_networks file"
73
81
  created_networks.each do |network_uuid|
74
82
  file.puts network_uuid
75
83
  end
76
84
  end
77
85
  else
86
+ @logger.info "Deleting created_networks file"
78
87
  File.delete(created_networks_file)
79
88
  end
80
89
 
@@ -5,21 +5,31 @@ module VagrantPlugins
5
5
  # Setup name for domain and domain volumes.
6
6
  class SetNameOfDomain
7
7
  def initialize(app, env)
8
+ @logger = Log4r::Logger.new("vagrant_libvirt::action::set_name_of_domain")
8
9
  @app = app
9
10
  end
10
11
 
11
12
  def call(env)
12
13
  require 'securerandom'
13
- env[:domain_name] = env[:root_path].basename.to_s.dup
14
+ config = env[:machine].provider_config
15
+ if config.default_prefix.nil?
16
+ env[:domain_name] = env[:root_path].basename.to_s.dup
17
+ else
18
+ env[:domain_name] = config.default_prefix.to_s
19
+ end
14
20
  env[:domain_name].gsub!(/[^-a-z0-9_]/i, '')
15
21
  env[:domain_name] << '_'
16
22
  env[:domain_name] << env[:machine].name.to_s
17
-
23
+
24
+ @logger.info("Looking for domain #{env[:domain_name]} through list #{env[:libvirt_compute].servers.all}")
18
25
  # Check if the domain name is not already taken
19
26
  domain = ProviderLibvirt::Util::Collection.find_matching(
20
27
  env[:libvirt_compute].servers.all, env[:domain_name])
28
+
29
+ @logger.info("Looking for domain #{env[:domain_name]}")
30
+
21
31
  if domain != nil
22
- raise Vagrant::Errors::DomainNameExists,
32
+ raise ProviderLibvirt::Errors::DomainNameExists,
23
33
  :domain_name => env[:domain_name]
24
34
  end
25
35
 
@@ -1,4 +1,4 @@
1
- require "pathname"
1
+ require 'pathname'
2
2
 
3
3
  require "log4r"
4
4
 
@@ -27,7 +27,7 @@ module VagrantPlugins
27
27
  # avoid creating an additional directory with rsync
28
28
  hostpath = "#{hostpath}/" if hostpath !~ /\/$/
29
29
 
30
- env[:ui].info(I18n.t("vagrant_libvirt.rsync_folder",
30
+ env[:ui].info(I18n.t('vagrant_libvirt.rsync_folder',
31
31
  :hostpath => hostpath,
32
32
  :guestpath => guestpath))
33
33
 
@@ -38,9 +38,9 @@ module VagrantPlugins
38
38
 
39
39
  # Rsync over to the guest path using the SSH info
40
40
  command = [
41
- "rsync", "--del", "--verbose", "--archive", "-z",
42
- "--exclude", ".vagrant/",
43
- "-e", "ssh -p #{ssh_info[:port]} #{proxycommand} -o StrictHostKeyChecking=no -i '#{ssh_info[:private_key_path]}'",
41
+ 'rsync', '--del', '--verbose', '--archive', '-z',
42
+ '--exclude', '.vagrant/',
43
+ '-e', "ssh -p #{ssh_info[:port]} #{proxycommand} -o StrictHostKeyChecking=no #{ssh_key_options(ssh_info)}",
44
44
  hostpath,
45
45
  "#{ssh_info[:username]}@#{ssh_info[:host]}:#{guestpath}"]
46
46
 
@@ -53,6 +53,12 @@ module VagrantPlugins
53
53
  end
54
54
  end
55
55
  end
56
+ private
57
+
58
+ def ssh_key_options(ssh_info)
59
+ # Ensure that `private_key_path` is an Array (for Vagrant < 1.4)
60
+ Array(ssh_info[:private_key_path]).map { |path| "-i '#{path}' " }.join
61
+ end
56
62
  end
57
63
  end
58
64
  end
@@ -26,13 +26,22 @@ module VagrantPlugins
26
26
  attr_accessor :storage_pool_name
27
27
 
28
28
  # Libvirt default network
29
- attr_accessor :default_network
29
+ attr_accessor :management_network_name
30
+ attr_accessor :management_network_address
31
+
32
+ # Default host prefix (alternative to use project folder name)
33
+ attr_accessor :default_prefix
30
34
 
31
35
  # Domain specific settings used while creating new domain.
32
36
  attr_accessor :memory
33
37
  attr_accessor :cpus
38
+ attr_accessor :cpu_mode
39
+ attr_accessor :disk_bus
34
40
  attr_accessor :nested
35
41
  attr_accessor :volume_cache
42
+ attr_accessor :kernel
43
+ attr_accessor :cmd_line
44
+ attr_accessor :initrd
36
45
 
37
46
  def initialize
38
47
  @driver = UNSET_VALUE
@@ -42,13 +51,19 @@ module VagrantPlugins
42
51
  @password = UNSET_VALUE
43
52
  @id_ssh_key_file = UNSET_VALUE
44
53
  @storage_pool_name = UNSET_VALUE
45
- @default_network = UNSET_VALUE
54
+ @management_network_name = UNSET_VALUE
55
+ @management_network_address = UNSET_VALUE
46
56
 
47
57
  # Domain specific settings.
48
58
  @memory = UNSET_VALUE
49
59
  @cpus = UNSET_VALUE
60
+ @cpu_mode = UNSET_VALUE
61
+ @disk_bus = UNSET_VALUE
50
62
  @nested = UNSET_VALUE
51
63
  @volume_cache = UNSET_VALUE
64
+ @kernel = UNSET_VALUE
65
+ @initrd = UNSET_VALUE
66
+ @cmd_line = UNSET_VALUE
52
67
  end
53
68
 
54
69
  def finalize!
@@ -59,13 +74,19 @@ module VagrantPlugins
59
74
  @password = nil if @password == UNSET_VALUE
60
75
  @id_ssh_key_file = 'id_rsa' if @id_ssh_key_file == UNSET_VALUE
61
76
  @storage_pool_name = 'default' if @storage_pool_name == UNSET_VALUE
62
- @default_network = 'default' if @default_network == UNSET_VALUE
77
+ @management_network_name = 'vagrant-libvirt' if @management_network_name == UNSET_VALUE
78
+ @management_network_address = '192.168.121.0/24' if @management_network_address == UNSET_VALUE
63
79
 
64
80
  # Domain specific settings.
65
81
  @memory = 512 if @memory == UNSET_VALUE
66
82
  @cpus = 1 if @cpus == UNSET_VALUE
83
+ @cpu_mode = 'host-model' if @cpu_mode == UNSET_VALUE
84
+ @disk_bus = 'virtio' if @disk_bus == UNSET_VALUE
67
85
  @nested = false if @nested == UNSET_VALUE
68
86
  @volume_cache = 'default' if @volume_cache == UNSET_VALUE
87
+ @kernel = nil if @kernel == UNSET_VALUE
88
+ @cmd_line = '' if @cmd_line == UNSET_VALUE
89
+ @initrd = '' if @initrd == UNSET_VALUE
69
90
  end
70
91
 
71
92
  def validate(machine)
@@ -68,16 +68,19 @@ module VagrantPlugins
68
68
  error_key(:fog_create_server_error)
69
69
  end
70
70
 
71
-
72
- # Other exceptions
73
- class InterfaceSlotNotAvailable < VagrantLibvirtError
74
- error_key(:interface_slot_not_available)
71
+ # Network exceptions
72
+ class ManagementNetworkError < VagrantLibvirtError
73
+ error_key(:management_network_error)
75
74
  end
76
75
 
77
76
  class NetworkNameAndAddressMismatch < VagrantLibvirtError
78
77
  error_key(:network_name_and_address_mismatch)
79
78
  end
80
79
 
80
+ class DHCPMismatch < VagrantLibvirtError
81
+ error_key(:dhcp_mismatch)
82
+ end
83
+
81
84
  class CreateNetworkError < VagrantLibvirtError
82
85
  error_key(:create_network_error)
83
86
  end
@@ -98,12 +101,17 @@ module VagrantPlugins
98
101
  error_key(:activate_network_error)
99
102
  end
100
103
 
104
+ # Other exceptions
105
+ class InterfaceSlotNotAvailable < VagrantLibvirtError
106
+ error_key(:interface_slot_not_available)
107
+ end
108
+
101
109
  class RsyncError < VagrantLibvirtError
102
110
  error_key(:rsync_error)
103
111
  end
104
112
 
105
113
  class DomainNameExists < VagrantLibvirtError
106
- error_key(:domain_name_exists_error)
114
+ error_key(:domain_name_exists)
107
115
  end
108
116
 
109
117
  class NoDomainError < VagrantLibvirtError
@@ -4,7 +4,7 @@
4
4
  <vcpu><%= @cpus %></vcpu>
5
5
 
6
6
  <% if @nested %>
7
- <cpu mode='host-model'>
7
+ <cpu mode='<%= @cpu_mode %>'>
8
8
  <model fallback='allow'>qemu64</model>
9
9
  <feature policy='optional' name='vmx'/>
10
10
  <feature policy='optional' name='svm'/>
@@ -14,6 +14,9 @@
14
14
  <os>
15
15
  <type arch='x86_64'>hvm</type>
16
16
  <boot dev='hd'/>
17
+ <kernel><%= @kernel %></kernel>
18
+ <initrd><%= @initrd %></initrd>
19
+ <cmdline><%= @cmd_line %></cmdline>
17
20
  </os>
18
21
  <features>
19
22
  <acpi/>
@@ -26,7 +29,7 @@
26
29
  <driver name='qemu' type='qcow2' cache='<%= @domain_volume_cache %>'/>
27
30
  <source file='<%= @domain_volume_path %>'/>
28
31
  <%# we need to ensure a unique target dev -%>
29
- <target dev='vda' bus='virtio'/>
32
+ <target dev='vda' bus='<%= @disk_bus %>'/>
30
33
  </disk>
31
34
  <serial type='pty'>
32
35
  <target port='0'/>
@@ -27,6 +27,12 @@ module VagrantPlugins
27
27
  netmask = xml.xpath('/network/ip/@netmask').first
28
28
  netmask = netmask.value if netmask
29
29
 
30
+ if xml.at_xpath('//network/ip/dhcp')
31
+ dhcp_enabled = true
32
+ else
33
+ dhcp_enabled = false
34
+ end
35
+
30
36
  # Calculate network address of network from ip address and
31
37
  # netmask.
32
38
  if ip && netmask
@@ -40,6 +46,7 @@ module VagrantPlugins
40
46
  ip_address: ip,
41
47
  netmask: netmask,
42
48
  network_address: network_address,
49
+ dhcp_enabled: dhcp_enabled,
43
50
  bridge_name: libvirt_network.bridge_name,
44
51
  created: true,
45
52
  active: libvirt_network.active?,
@@ -1,5 +1,5 @@
1
1
  module VagrantPlugins
2
2
  module ProviderLibvirt
3
- VERSION = '0.0.13'
3
+ VERSION = '0.0.14'
4
4
  end
5
5
  end
data/locales/en.yml CHANGED
@@ -89,7 +89,7 @@ en:
89
89
  fog_create_server_error: |-
90
90
  Error while creating domain: %{error_message}
91
91
  domain_name_exists: |-
92
- Name of domain about to create is already taken. Please try to run
92
+ Name `%{domain_name}` of domain about to create is already taken. Please try to run
93
93
  `vagrant up` command again.
94
94
  creating_storage_pool_error: |-
95
95
  There was error while creating libvirt storage pool: %{error_message}
@@ -101,9 +101,14 @@ en:
101
101
  Error while attaching new device to domain. %{error_message}
102
102
  no_ip_address_error: |-
103
103
  No IP address found.
104
+ management_network_error: |-
105
+ Error in specification of management network: %{error_message}.
104
106
  network_name_and_address_mismatch: |-
105
107
  Address %{ip_address} does not match with network name %{network_name}.
106
108
  Please fix your configuration and run vagrant again.
109
+ dhcp_mismatch: |-
110
+ Network %{network_name} exists but does not have dhcp %{requested}.
111
+ Please fix your configuration and run vagrant again.
107
112
  create_network_error: |-
108
113
  Error occured while creating new network: %{error_message}.
109
114
  network_not_available_error: |-
metadata CHANGED
@@ -1,8 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: vagrant-libvirt
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.13
5
- prerelease:
4
+ version: 0.0.14
6
5
  platform: ruby
7
6
  authors:
8
7
  - Lukas Stanek
@@ -10,12 +9,11 @@ authors:
10
9
  autorequire:
11
10
  bindir: bin
12
11
  cert_chain: []
13
- date: 2013-12-12 00:00:00.000000000 Z
12
+ date: 2014-01-21 00:00:00.000000000 Z
14
13
  dependencies:
15
14
  - !ruby/object:Gem::Dependency
16
15
  name: fog
17
16
  requirement: !ruby/object:Gem::Requirement
18
- none: false
19
17
  requirements:
20
18
  - - '='
21
19
  - !ruby/object:Gem::Version
@@ -23,7 +21,6 @@ dependencies:
23
21
  type: :runtime
24
22
  prerelease: false
25
23
  version_requirements: !ruby/object:Gem::Requirement
26
- none: false
27
24
  requirements:
28
25
  - - '='
29
26
  - !ruby/object:Gem::Version
@@ -31,23 +28,20 @@ dependencies:
31
28
  - !ruby/object:Gem::Dependency
32
29
  name: ruby-libvirt
33
30
  requirement: !ruby/object:Gem::Requirement
34
- none: false
35
31
  requirements:
36
- - - ~>
32
+ - - "~>"
37
33
  - !ruby/object:Gem::Version
38
34
  version: 0.4.0
39
35
  type: :runtime
40
36
  prerelease: false
41
37
  version_requirements: !ruby/object:Gem::Requirement
42
- none: false
43
38
  requirements:
44
- - - ~>
39
+ - - "~>"
45
40
  - !ruby/object:Gem::Version
46
41
  version: 0.4.0
47
42
  - !ruby/object:Gem::Dependency
48
43
  name: nokogiri
49
44
  requirement: !ruby/object:Gem::Requirement
50
- none: false
51
45
  requirements:
52
46
  - - '='
53
47
  - !ruby/object:Gem::Version
@@ -55,7 +49,6 @@ dependencies:
55
49
  type: :runtime
56
50
  prerelease: false
57
51
  version_requirements: !ruby/object:Gem::Requirement
58
- none: false
59
52
  requirements:
60
53
  - - '='
61
54
  - !ruby/object:Gem::Version
@@ -63,17 +56,15 @@ dependencies:
63
56
  - !ruby/object:Gem::Dependency
64
57
  name: rake
65
58
  requirement: !ruby/object:Gem::Requirement
66
- none: false
67
59
  requirements:
68
- - - ! '>='
60
+ - - ">="
69
61
  - !ruby/object:Gem::Version
70
62
  version: '0'
71
63
  type: :development
72
64
  prerelease: false
73
65
  version_requirements: !ruby/object:Gem::Requirement
74
- none: false
75
66
  requirements:
76
- - - ! '>='
67
+ - - ">="
77
68
  - !ruby/object:Gem::Version
78
69
  version: '0'
79
70
  description: Vagrant provider for libvirt.
@@ -84,7 +75,7 @@ executables: []
84
75
  extensions: []
85
76
  extra_rdoc_files: []
86
77
  files:
87
- - .gitignore
78
+ - ".gitignore"
88
79
  - CHANGELOG.md
89
80
  - Gemfile
90
81
  - LICENSE
@@ -146,27 +137,25 @@ files:
146
137
  homepage: https://github.com/pradels/vagrant-libvirt
147
138
  licenses:
148
139
  - MIT
140
+ metadata: {}
149
141
  post_install_message:
150
142
  rdoc_options: []
151
143
  require_paths:
152
144
  - lib
153
145
  required_ruby_version: !ruby/object:Gem::Requirement
154
- none: false
155
146
  requirements:
156
- - - ! '>='
147
+ - - ">="
157
148
  - !ruby/object:Gem::Version
158
149
  version: '0'
159
150
  required_rubygems_version: !ruby/object:Gem::Requirement
160
- none: false
161
151
  requirements:
162
- - - ! '>='
152
+ - - ">="
163
153
  - !ruby/object:Gem::Version
164
154
  version: '0'
165
155
  requirements: []
166
156
  rubyforge_project:
167
- rubygems_version: 1.8.25
157
+ rubygems_version: 2.0.14
168
158
  signing_key:
169
- specification_version: 3
159
+ specification_version: 4
170
160
  summary: Vagrant provider for libvirt.
171
161
  test_files: []
172
- has_rdoc: