vagrant-libvirt 0.0.41 → 0.0.42

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 (81) hide show
  1. checksums.yaml +4 -4
  2. data/.coveralls.yml +1 -0
  3. data/.github/issue_template.md +37 -0
  4. data/.gitignore +21 -0
  5. data/.travis.yml +24 -0
  6. data/Gemfile +26 -0
  7. data/LICENSE +22 -0
  8. data/README.md +1380 -0
  9. data/Rakefile +8 -0
  10. data/example_box/README.md +29 -0
  11. data/example_box/Vagrantfile +60 -0
  12. data/example_box/metadata.json +5 -0
  13. data/lib/vagrant-libvirt.rb +29 -0
  14. data/lib/vagrant-libvirt/action.rb +370 -0
  15. data/lib/vagrant-libvirt/action/create_domain.rb +322 -0
  16. data/lib/vagrant-libvirt/action/create_domain_volume.rb +87 -0
  17. data/lib/vagrant-libvirt/action/create_network_interfaces.rb +302 -0
  18. data/lib/vagrant-libvirt/action/create_networks.rb +361 -0
  19. data/lib/vagrant-libvirt/action/destroy_domain.rb +83 -0
  20. data/lib/vagrant-libvirt/action/destroy_networks.rb +95 -0
  21. data/lib/vagrant-libvirt/action/forward_ports.rb +227 -0
  22. data/lib/vagrant-libvirt/action/halt_domain.rb +41 -0
  23. data/lib/vagrant-libvirt/action/handle_box_image.rb +156 -0
  24. data/lib/vagrant-libvirt/action/handle_storage_pool.rb +57 -0
  25. data/lib/vagrant-libvirt/action/is_created.rb +18 -0
  26. data/lib/vagrant-libvirt/action/is_running.rb +21 -0
  27. data/lib/vagrant-libvirt/action/is_suspended.rb +42 -0
  28. data/lib/vagrant-libvirt/action/message_already_created.rb +16 -0
  29. data/lib/vagrant-libvirt/action/message_not_created.rb +16 -0
  30. data/lib/vagrant-libvirt/action/message_not_running.rb +16 -0
  31. data/lib/vagrant-libvirt/action/message_not_suspended.rb +16 -0
  32. data/lib/vagrant-libvirt/action/message_will_not_destroy.rb +17 -0
  33. data/lib/vagrant-libvirt/action/package_domain.rb +105 -0
  34. data/lib/vagrant-libvirt/action/prepare_nfs_settings.rb +94 -0
  35. data/lib/vagrant-libvirt/action/prepare_nfs_valid_ids.rb +17 -0
  36. data/lib/vagrant-libvirt/action/prune_nfs_exports.rb +27 -0
  37. data/lib/vagrant-libvirt/action/read_mac_addresses.rb +40 -0
  38. data/lib/vagrant-libvirt/action/remove_libvirt_image.rb +20 -0
  39. data/lib/vagrant-libvirt/action/remove_stale_volume.rb +50 -0
  40. data/lib/vagrant-libvirt/action/resume_domain.rb +34 -0
  41. data/lib/vagrant-libvirt/action/set_boot_order.rb +109 -0
  42. data/lib/vagrant-libvirt/action/set_name_of_domain.rb +64 -0
  43. data/lib/vagrant-libvirt/action/share_folders.rb +71 -0
  44. data/lib/vagrant-libvirt/action/start_domain.rb +307 -0
  45. data/lib/vagrant-libvirt/action/suspend_domain.rb +40 -0
  46. data/lib/vagrant-libvirt/action/wait_till_up.rb +109 -0
  47. data/lib/vagrant-libvirt/cap/mount_p9.rb +42 -0
  48. data/lib/vagrant-libvirt/cap/nic_mac_addresses.rb +17 -0
  49. data/lib/vagrant-libvirt/cap/synced_folder.rb +113 -0
  50. data/lib/vagrant-libvirt/config.rb +746 -0
  51. data/lib/vagrant-libvirt/driver.rb +118 -0
  52. data/lib/vagrant-libvirt/errors.rb +153 -0
  53. data/lib/vagrant-libvirt/plugin.rb +92 -0
  54. data/lib/vagrant-libvirt/provider.rb +130 -0
  55. data/lib/vagrant-libvirt/templates/default_storage_pool.xml.erb +13 -0
  56. data/lib/vagrant-libvirt/templates/domain.xml.erb +244 -0
  57. data/lib/vagrant-libvirt/templates/private_network.xml.erb +42 -0
  58. data/lib/vagrant-libvirt/templates/public_interface.xml.erb +26 -0
  59. data/lib/vagrant-libvirt/util.rb +11 -0
  60. data/lib/vagrant-libvirt/util/collection.rb +19 -0
  61. data/lib/vagrant-libvirt/util/erb_template.rb +22 -0
  62. data/lib/vagrant-libvirt/util/error_codes.rb +100 -0
  63. data/lib/vagrant-libvirt/util/network_util.rb +151 -0
  64. data/lib/vagrant-libvirt/util/timer.rb +17 -0
  65. data/lib/vagrant-libvirt/version.rb +5 -0
  66. data/locales/en.yml +162 -0
  67. data/spec/spec_helper.rb +9 -0
  68. data/spec/support/environment_helper.rb +46 -0
  69. data/spec/support/libvirt_context.rb +30 -0
  70. data/spec/support/sharedcontext.rb +34 -0
  71. data/spec/unit/action/destroy_domain_spec.rb +97 -0
  72. data/spec/unit/action/set_name_of_domain_spec.rb +21 -0
  73. data/spec/unit/action/wait_till_up_spec.rb +127 -0
  74. data/spec/unit/config_spec.rb +113 -0
  75. data/spec/unit/templates/domain_all_settings.xml +137 -0
  76. data/spec/unit/templates/domain_defaults.xml +46 -0
  77. data/spec/unit/templates/domain_spec.rb +84 -0
  78. data/tools/create_box.sh +130 -0
  79. data/tools/prepare_redhat_for_box.sh +119 -0
  80. data/vagrant-libvirt.gemspec +54 -0
  81. metadata +93 -3
@@ -0,0 +1,151 @@
1
+ require 'nokogiri'
2
+ require 'vagrant/util/network_ip'
3
+
4
+ module VagrantPlugins
5
+ module ProviderLibvirt
6
+ module Util
7
+ module NetworkUtil
8
+ include Vagrant::Util::NetworkIP
9
+
10
+ def configured_networks(env, logger)
11
+ management_network_name = env[:machine].provider_config.management_network_name
12
+ management_network_address = env[:machine].provider_config.management_network_address
13
+ management_network_mode = env[:machine].provider_config.management_network_mode
14
+ management_network_mac = env[:machine].provider_config.management_network_mac
15
+ management_network_guest_ipv6 = env[:machine].provider_config.management_network_guest_ipv6
16
+ management_network_autostart = env[:machine].provider_config.management_network_autostart
17
+ management_network_pci_bus = env[:machine].provider_config.management_network_pci_bus
18
+ management_network_pci_slot = env[:machine].provider_config.management_network_pci_slot
19
+ logger.info "Using #{management_network_name} at #{management_network_address} as the management network #{management_network_mode} is the mode"
20
+
21
+ begin
22
+ management_network_ip = IPAddr.new(management_network_address)
23
+ rescue ArgumentError
24
+ raise Errors::ManagementNetworkError,
25
+ error_message: "#{management_network_address} is not a valid IP address"
26
+ end
27
+
28
+ # capture address into $1 and mask into $2
29
+ management_network_ip.inspect =~ /IPv4:(.*)\/(.*)>/
30
+
31
+ if Regexp.last_match(2) == '255.255.255.255'
32
+ raise Errors::ManagementNetworkError,
33
+ error_message: "#{management_network_address} does not include both an address and subnet mask"
34
+ end
35
+
36
+ management_network_options = {
37
+ iface_type: :private_network,
38
+ network_name: management_network_name,
39
+ ip: Regexp.last_match(1),
40
+ netmask: Regexp.last_match(2),
41
+ dhcp_enabled: true,
42
+ forward_mode: management_network_mode,
43
+ guest_ipv6: management_network_guest_ipv6,
44
+ autostart: management_network_autostart,
45
+ bus: management_network_pci_bus,
46
+ slot: management_network_pci_slot
47
+ }
48
+
49
+ unless management_network_mac.nil?
50
+ management_network_options[:mac] = management_network_mac
51
+ end
52
+
53
+ unless management_network_pci_bus.nil? and management_network_pci_slot.nil?
54
+ management_network_options[:bus] = management_network_pci_bus
55
+ management_network_options[:slot] = management_network_pci_slot
56
+ end
57
+
58
+ if (env[:machine].config.vm.box &&
59
+ !env[:machine].provider_config.mgmt_attach)
60
+ raise Errors::ManagementNetworkRequired
61
+ end
62
+
63
+ # add management network to list of networks to check
64
+ # unless mgmt_attach set to false
65
+ networks = if env[:machine].provider_config.mgmt_attach
66
+ [management_network_options]
67
+ else
68
+ []
69
+ end
70
+
71
+ env[:machine].config.vm.networks.each do |type, original_options|
72
+ logger.debug "In config found network type #{type} options #{original_options}"
73
+ # Options can be specified in Vagrantfile in short format (:ip => ...),
74
+ # or provider format # (:libvirt__network_name => ...).
75
+ # https://github.com/mitchellh/vagrant/blob/master/lib/vagrant/util/scoped_hash_override.rb
76
+ options = scoped_hash_override(original_options, :libvirt)
77
+ # store type in options
78
+ # use default values if not already set
79
+ options = {
80
+ iface_type: type,
81
+ netmask: '255.255.255.0',
82
+ dhcp_enabled: true,
83
+ forward_mode: 'nat'
84
+ }.merge(options)
85
+
86
+ if options[:type].to_s == 'dhcp' && options[:ip].nil?
87
+ options[:network_name] = 'vagrant-private-dhcp'
88
+ end
89
+
90
+ # add to list of networks to check
91
+ networks.push(options)
92
+ end
93
+
94
+ networks
95
+ end
96
+
97
+ # Return a list of all (active and inactive) libvirt networks as a list
98
+ # of hashes with their name, network address and status (active or not)
99
+ def libvirt_networks(libvirt_client)
100
+ libvirt_networks = []
101
+
102
+ active = libvirt_client.list_networks
103
+ inactive = libvirt_client.list_defined_networks
104
+
105
+ # Iterate over all (active and inactive) networks.
106
+ active.concat(inactive).each do |network_name|
107
+ libvirt_network = libvirt_client.lookup_network_by_name(
108
+ network_name
109
+ )
110
+
111
+ # Parse ip address and netmask from the network xml description.
112
+ xml = Nokogiri::XML(libvirt_network.xml_desc)
113
+ ip = xml.xpath('/network/ip/@address').first
114
+ ip = ip.value if ip
115
+ netmask = xml.xpath('/network/ip/@netmask').first
116
+ netmask = netmask.value if netmask
117
+
118
+ dhcp_enabled = if xml.at_xpath('//network/ip/dhcp')
119
+ true
120
+ else
121
+ false
122
+ end
123
+
124
+ domain_name = xml.at_xpath('/network/domain/@name')
125
+ domain_name = domain_name.value if domain_name
126
+
127
+ # Calculate network address of network from ip address and
128
+ # netmask.
129
+ network_address = (network_address(ip, netmask) if ip && netmask)
130
+
131
+ libvirt_networks << {
132
+ name: network_name,
133
+ ip_address: ip,
134
+ netmask: netmask,
135
+ network_address: network_address,
136
+ dhcp_enabled: dhcp_enabled,
137
+ bridge_name: libvirt_network.bridge_name,
138
+ domain_name: domain_name,
139
+ created: true,
140
+ active: libvirt_network.active?,
141
+ autostart: libvirt_network.autostart?,
142
+ libvirt_network: libvirt_network
143
+ }
144
+ end
145
+
146
+ libvirt_networks
147
+ end
148
+ end
149
+ end
150
+ end
151
+ end
@@ -0,0 +1,17 @@
1
+ module VagrantPlugins
2
+ module ProviderLibvirt
3
+ module Util
4
+ class Timer
5
+ # A basic utility method that times the execution of the given
6
+ # block and returns it.
7
+ def self.time
8
+ start_time = Time.now.to_f
9
+ yield
10
+ end_time = Time.now.to_f
11
+
12
+ end_time - start_time
13
+ end
14
+ end
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,5 @@
1
+ module VagrantPlugins
2
+ module ProviderLibvirt
3
+ VERSION = '0.0.42'.freeze
4
+ end
5
+ end
@@ -0,0 +1,162 @@
1
+ en:
2
+ vagrant_libvirt:
3
+ already_created: |-
4
+ The domain is already created.
5
+ not_created: |-
6
+ Domain is not created. Please run `vagrant up` first.
7
+ not_running: |-
8
+ Domain is not running. Please run `vagrant up` or `vagrant resume` first.
9
+ not_suspended: |-
10
+ Domain is not suspended.
11
+ finding_volume: |-
12
+ Checking if volume is available.
13
+ creating_domain: |-
14
+ Creating domain with the following settings...
15
+ manual_resize_required: |-
16
+ Created volume larger than box defaults, will require manual resizing of
17
+ filesystems to utilize.
18
+ uploading_volume: |-
19
+ Uploading base box image as volume into libvirt storage...
20
+ creating_domain_volume: |-
21
+ Creating image (snapshot of base box volume).
22
+ removing_domain_volume: |-
23
+ Removing image (snapshot of base box volume).
24
+ starting_domain: |-
25
+ Starting domain.
26
+ terminating: |-
27
+ Removing domain...
28
+ poweroff_domain: |-
29
+ Poweroff domain.
30
+ destroy_domain: |-
31
+ Removing domain...
32
+ halt_domain: |-
33
+ Halting domain...
34
+ resuming_domain: |-
35
+ Resuming domain...
36
+ suspending_domain: |-
37
+ Suspending domain...
38
+ waiting_for_ready: |-
39
+ Waiting for domain to become "ready"...
40
+ waiting_for_ip: |-
41
+ Waiting for domain to get an IP address...
42
+ waiting_for_ssh: |-
43
+ Waiting for SSH to become available...
44
+ booted: |-
45
+ Machine is booted.
46
+ rsync_folder: |-
47
+ Rsyncing folder: %{hostpath} => %{guestpath}
48
+ ready: |-
49
+ Machine is booted and ready for use!
50
+ remove_stale_volume: |-
51
+ Remove stale volume...
52
+
53
+ warnings:
54
+ ignoring_virtual_size_too_small: |-
55
+ Ignoring requested virtual disk size of '%{requested}' as it is below
56
+ the minimum box image size of '%{minimum}'.
57
+ forwarding_udp: |-
58
+ Forwarding UDP ports is not supported. Ignoring.
59
+
60
+ errors:
61
+ package_not_supported: No support for package with libvirt. Create box manually.
62
+ fog_error: |-
63
+ There was an error talking to Libvirt. The error message is shown
64
+ below:
65
+
66
+ %{message}
67
+ no_matching_volume: |-
68
+ No matching volume was found! Please check your volume setting
69
+ to make sure you have a valid volume chosen.
70
+ no_storage_pool: |-
71
+ No usable storage pool found! Please check if storage pool is
72
+ created and available.
73
+ no_box_volume: |-
74
+ Volume for box image is missing in storage pools. Try to run vagrant
75
+ again, or check if storage volume is accessible.
76
+ domain_volume_exists: |-
77
+ Volume for domain is already created. Please run 'vagrant destroy' first.
78
+ no_domain_volume: |-
79
+ Volume for domain is missing. Try to run 'vagrant up' again.
80
+ interface_slot_not_available: |-
81
+ Interface adapter number is already in use. Please specify other adapter number.
82
+ interface_slot_exhausted: |-
83
+ Available interface adapters have been exhausted. Please increase the nic_adapter_count.
84
+ rsync_error: |-
85
+ There was an error when attempting to rsync a share folder.
86
+ Please inspect the error message below for more info.
87
+
88
+ Host path: %{hostpath}
89
+ Guest path: %{guestpath}
90
+ Error: %{stderr}
91
+ no_box_virtual_size: |-
92
+ No image virtual size specified for box.
93
+ no_box_format: |-
94
+ No image format specified for box.
95
+ wrong_box_format: |-
96
+ Wrong image format specified for box.
97
+ fog_libvirt_connection_error: |-
98
+ Error while connecting to libvirt: %{error_message}
99
+ fog_create_volume_error: |-
100
+ Error while creating a storage pool volume: %{error_message}
101
+ fog_create_domain_volume_error: |-
102
+ Error while creating volume for domain: %{error_message}
103
+ fog_create_server_error: |-
104
+ Error while creating domain: %{error_message}
105
+ domain_name_exists: |-
106
+ Name `%{domain_name}` of domain about to create is already taken. Please try to run
107
+ `vagrant up` command again.
108
+ creating_storage_pool_error: |-
109
+ There was error while creating libvirt storage pool: %{error_message}
110
+ image_upload_error: |-
111
+ Error while uploading image to storage pool: %{error_message}
112
+ no_domain_error: |-
113
+ No domain found. %{error_message}
114
+ attach_device_error: |-
115
+ Error while attaching new device to domain. %{error_message}
116
+ detach_device_error: |-
117
+ Error while detaching device from domain. %{error_message}
118
+ no_ip_address_error: |-
119
+ No IP address found.
120
+ management_network_error: |-
121
+ Error in specification of management network: %{error_message}.
122
+ network_name_and_address_mismatch: |-
123
+ Address %{ip_address} does not match with network name %{network_name}.
124
+ Please fix your configuration and run vagrant again.
125
+ dhcp_mismatch: |-
126
+ Network %{network_name} exists but does not have dhcp %{requested}.
127
+ Please fix your configuration and run vagrant again.
128
+ create_network_error: |-
129
+ Error occurred while creating new network: %{error_message}.
130
+ network_not_available_error: |-
131
+ Network %{network_name} is not available. Specify available network
132
+ name, or an ip address if you want to create a new network.
133
+ activate_network_error: |-
134
+ Error while activating network: %{error_message}.
135
+ autostart_network_error: |-
136
+ Error while setting up autostart on network: %{error_message}.
137
+ destroy_network_error: |-
138
+ Error while removing network %{network_name}. %{error_message}.
139
+ delete_snapshot_error: |-
140
+ Error while deleting snapshot: %{error_message}.
141
+ tunnel_port_not_defined: |-
142
+ tunnel UDP or TCP port not defined.
143
+ management_network_required: |-
144
+ Management network can't be disabled when VM use box.
145
+ Please fix your configuration and run vagrant again.
146
+
147
+ states:
148
+ paused: |-
149
+ The Libvirt domain is suspended. Run `vagrant resume` to resume it.
150
+ shutting_down: |-
151
+ The Libvirt domain is shutting down. Wait for it to complete and
152
+ then run `vagrant up` to start it or `vagrant destroy` to remove.
153
+ shutoff: |-
154
+ The Libvirt domain is not running. Run `vagrant up` to start it.
155
+ not_created: |-
156
+ The Libvirt domain is not created. Run `vagrant up` to create it.
157
+ running: |-
158
+ The Libvirt domain is running. To stop this machine, you can run
159
+ `vagrant halt`. To destroy the machine, you can run `vagrant destroy`.
160
+ preparing: |-
161
+ The vagrant machine is being prepared for creation, please wait for
162
+ it to reach a steady state before issuing commands on it.
@@ -0,0 +1,9 @@
1
+ require 'coveralls'
2
+ Coveralls.wear!
3
+
4
+ require 'vagrant-libvirt'
5
+ require 'support/environment_helper'
6
+ require 'vagrant-spec/unit'
7
+
8
+ RSpec.configure do |spec|
9
+ end
@@ -0,0 +1,46 @@
1
+ require 'ostruct'
2
+ require 'pathname'
3
+
4
+ class EnvironmentHelper
5
+ attr_writer :domain_name
6
+
7
+ attr_accessor :random_hostname, :name, :default_prefix
8
+
9
+ def [](value)
10
+ send(value.to_sym)
11
+ end
12
+
13
+ def cpus
14
+ 4
15
+ end
16
+
17
+ def memory
18
+ 1024
19
+ end
20
+
21
+ %w(cpus cpu_mode loader boot_order machine_type disk_bus disk_device nested volume_cache kernel cmd_line initrd graphics_type graphics_autoport graphics_port graphics_ip graphics_passwd video_type video_vram keymap storage_pool_name disks cdroms driver).each do |name|
22
+ define_method(name.to_sym) do
23
+ nil
24
+ end
25
+ end
26
+
27
+ def machine
28
+ self
29
+ end
30
+
31
+ def provider_config
32
+ self
33
+ end
34
+
35
+ def root_path
36
+ Pathname.new('./spec/support/foo')
37
+ end
38
+
39
+ def domain_name
40
+ # noop
41
+ end
42
+
43
+ def libvirt_compute
44
+ OpenStruct.new(servers: [])
45
+ end
46
+ end
@@ -0,0 +1,30 @@
1
+ require 'fog/libvirt'
2
+
3
+ shared_context 'libvirt' do
4
+ include_context 'unit'
5
+
6
+ let(:libvirt_context) { true }
7
+ let(:id) { 'dummy-vagrant_dummy' }
8
+ let(:connection) { double('connection') }
9
+ let(:domain) { double('domain') }
10
+
11
+ def connection_result(options = {})
12
+ result = options.fetch(:result, nil)
13
+ double('connection_result' => result)
14
+ end
15
+
16
+ before (:each) do
17
+ # we don't want unit tests to ever run commands on the system; so we wire
18
+ # in a double to ensure any unexpected messages raise exceptions
19
+ stub_const('::Fog::Compute', connection)
20
+
21
+ # drivers also call vm_exists? during init;
22
+ allow(connection).to receive(:servers).with(kind_of(String))
23
+ .and_return(connection_result(result: nil))
24
+
25
+ # return some information for domain when needed
26
+ allow(domain).to receive(:mac).and_return('9C:D5:53:F1:5A:E7')
27
+
28
+ machine.stub(id: id)
29
+ end
30
+ end
@@ -0,0 +1,34 @@
1
+ require 'spec_helper'
2
+
3
+ shared_context 'unit' do
4
+ include_context 'vagrant-unit'
5
+
6
+ let(:vagrantfile) do
7
+ <<-EOF
8
+ Vagrant.configure('2') do |config|
9
+ config.vm.define :test
10
+ end
11
+ EOF
12
+ end
13
+ let(:test_env) do
14
+ test_env = isolated_environment
15
+ test_env.vagrantfile vagrantfile
16
+ test_env
17
+ end
18
+ let(:env) { { env: iso_env, machine: machine, ui: ui, root_path: '/rootpath' } }
19
+ let(:conf) { Vagrant::Config::V2::DummyConfig.new }
20
+ let(:ui) { Vagrant::UI::Basic.new }
21
+ let(:iso_env) { test_env.create_vagrant_env ui_class: Vagrant::UI::Basic }
22
+ let(:machine) { iso_env.machine(:test, :libvirt) }
23
+ # Mock the communicator to prevent SSH commands for being executed.
24
+ let(:communicator) { double('communicator') }
25
+ # Mock the guest operating system.
26
+ let(:guest) { double('guest') }
27
+ let(:app) { ->(env) {} }
28
+ let(:plugin) { register_plugin }
29
+
30
+ before (:each) do
31
+ machine.stub(guest: guest)
32
+ machine.stub(communicator: communicator)
33
+ end
34
+ end