vagrant-libvirt 0.0.41 → 0.0.42

Sign up to get free protection for your applications and to get access to all the features.
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