vagrant-ovirt3 1.0.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 (38) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +20 -0
  3. data/Gemfile +4 -0
  4. data/LICENSE +22 -0
  5. data/README.md +211 -0
  6. data/Rakefile +7 -0
  7. data/example_box/README.md +13 -0
  8. data/example_box/Vagrantfile +18 -0
  9. data/example_box/dummy.box +0 -0
  10. data/example_box/metadata.json +4 -0
  11. data/lib/vagrant-ovirt3.rb +42 -0
  12. data/lib/vagrant-ovirt3/action.rb +131 -0
  13. data/lib/vagrant-ovirt3/action/connect_ovirt.rb +84 -0
  14. data/lib/vagrant-ovirt3/action/create_network_interfaces.rb +137 -0
  15. data/lib/vagrant-ovirt3/action/create_vm.rb +113 -0
  16. data/lib/vagrant-ovirt3/action/destroy_vm.rb +25 -0
  17. data/lib/vagrant-ovirt3/action/is_created.rb +18 -0
  18. data/lib/vagrant-ovirt3/action/message_already_created.rb +16 -0
  19. data/lib/vagrant-ovirt3/action/message_not_created.rb +16 -0
  20. data/lib/vagrant-ovirt3/action/read_ssh_info.rb +56 -0
  21. data/lib/vagrant-ovirt3/action/read_state.rb +37 -0
  22. data/lib/vagrant-ovirt3/action/resize_disk.rb +71 -0
  23. data/lib/vagrant-ovirt3/action/set_name_of_domain.rb +31 -0
  24. data/lib/vagrant-ovirt3/action/start_vm.rb +37 -0
  25. data/lib/vagrant-ovirt3/action/sync_folders.rb +65 -0
  26. data/lib/vagrant-ovirt3/action/wait_till_up.rb +94 -0
  27. data/lib/vagrant-ovirt3/config.rb +58 -0
  28. data/lib/vagrant-ovirt3/errors.rb +76 -0
  29. data/lib/vagrant-ovirt3/plugin.rb +74 -0
  30. data/lib/vagrant-ovirt3/provider.rb +76 -0
  31. data/lib/vagrant-ovirt3/util.rb +9 -0
  32. data/lib/vagrant-ovirt3/util/collection.rb +21 -0
  33. data/lib/vagrant-ovirt3/util/timer.rb +17 -0
  34. data/lib/vagrant-ovirt3/version.rb +6 -0
  35. data/locales/en.yml +90 -0
  36. data/tools/prepare_redhat_for_box.sh +132 -0
  37. data/vagrant-ovirt3.gemspec +25 -0
  38. metadata +129 -0
@@ -0,0 +1,84 @@
1
+ require 'fog'
2
+ require 'log4r'
3
+ require 'pp'
4
+ require 'rbovirt'
5
+
6
+ module VagrantPlugins
7
+ module OVirtProvider
8
+ module Action
9
+ class ConnectOVirt
10
+ def initialize(app, env)
11
+ @logger = Log4r::Logger.new("vagrant_ovirt3::action::connect_ovirt")
12
+ @app = app
13
+ end
14
+
15
+ def call(env)
16
+
17
+ # We need both, fog and rbovirt client. Sometimes fog doesn't
18
+ # support some operations like managing quotas, or working with
19
+ # networks. For this rbovirt client is used.
20
+ env[:ovirt_client] = OVirtProvider.ovirt_client if \
21
+ OVirtProvider.ovirt_client != nil
22
+
23
+ if OVirtProvider.ovirt_connection != nil
24
+ env[:ovirt_compute] = OVirtProvider.ovirt_connection
25
+ return @app.call(env)
26
+ end
27
+
28
+ # Get config options for ovirt provider.
29
+ config = env[:machine].provider_config
30
+
31
+ conn_attr = {}
32
+ conn_attr[:provider] = 'ovirt'
33
+ conn_attr[:ovirt_url] = "#{config.url}/api"
34
+ conn_attr[:ovirt_username] = config.username if config.username
35
+ conn_attr[:ovirt_password] = config.password if config.password
36
+
37
+ # We need datacenter id in fog connection initialization. But it's
38
+ # much simpler to use datacenter name in Vagrantfile. So get
39
+ # datacenter id here from rbovirt client before connecting to fog.
40
+ env[:ovirt_client] = ovirt_connect(conn_attr)
41
+ begin
42
+ datacenter = OVirtProvider::Util::Collection.find_matching(
43
+ env[:ovirt_client].datacenters, config.datacenter)
44
+ rescue OVIRT::OvirtException => e
45
+ raise Errors::FogOVirtConnectionError,
46
+ :error_message => e.message
47
+ end
48
+
49
+ raise Errors::NoDatacenterError if datacenter == nil
50
+ conn_attr[:ovirt_datacenter] = datacenter.id
51
+
52
+ # Reconnect and prepar rbovirt client with datacenter set from
53
+ # configuration.
54
+ env[:ovirt_client] = ovirt_connect(conn_attr)
55
+ OVirtProvider.ovirt_client = env[:ovirt_client]
56
+
57
+ # Establish fog connection now.
58
+ @logger.info("Connecting to oVirt (#{config.url}) ...")
59
+ begin
60
+ env[:ovirt_compute] = Fog::Compute.new(conn_attr)
61
+ rescue OVIRT::OvirtException => e
62
+ raise Errors::FogOVirtConnectionError,
63
+ :error_message => e.message
64
+ end
65
+ OVirtProvider.ovirt_connection = env[:ovirt_compute]
66
+
67
+ @app.call(env)
68
+ end
69
+
70
+ private
71
+
72
+ def ovirt_connect(credentials)
73
+ OVIRT::Client.new(
74
+ credentials[:ovirt_username],
75
+ credentials[:ovirt_password],
76
+ credentials[:ovirt_url],
77
+ credentials[:ovirt_datacenter],
78
+ )
79
+ end
80
+ end
81
+ end
82
+ end
83
+ end
84
+
@@ -0,0 +1,137 @@
1
+ require 'log4r'
2
+ require 'vagrant/util/scoped_hash_override'
3
+
4
+ module VagrantPlugins
5
+ module OVirtProvider
6
+ module Action
7
+ # Create network interfaces for machine, before VM is running.
8
+ class CreateNetworkInterfaces
9
+ include Vagrant::Util::ScopedHashOverride
10
+
11
+ def initialize(app, env)
12
+ @logger = Log4r::Logger.new("vagrant_ovirt3::action::create_network_interfaces")
13
+ @app = app
14
+ end
15
+
16
+ def call(env)
17
+ # Get machine first.
18
+ begin
19
+ machine = OVirtProvider::Util::Collection.find_matching(
20
+ env[:ovirt_compute].servers.all, env[:machine].id.to_s)
21
+ rescue => e
22
+ raise Errors::NoVMError,
23
+ :vm_name => env[:machine].id.to_s
24
+ end
25
+
26
+ # Setup list of interfaces before creating them
27
+ adapters = []
28
+
29
+ # First interface is for provisioning, so this slot is not usable.
30
+ # This interface should be available already from template.
31
+
32
+ env[:machine].config.vm.networks.each do |type, options|
33
+ # We support private and public networks only. They mean both the
34
+ # same right now.
35
+ next if type != :private_network and type != :public_network
36
+
37
+ # Get options for this interface. Options can be specified in
38
+ # Vagrantfile in short format (:ip => ...), or provider format
39
+ # (:ovirt__network_name => ...).
40
+ options = scoped_hash_override(options, :ovirt)
41
+ options = {
42
+ :netmask => '255.255.255.0',
43
+ :network_name => 'rhevm',
44
+ :interface_type => 'virtio'
45
+ }.merge(options)
46
+
47
+ if options[:adapter]
48
+ if adapters[options[:adapter]]
49
+ raise Errors::InterfaceSlotNotAvailable
50
+ end
51
+
52
+ free_slot = options[:adapter].to_i
53
+ else
54
+ free_slot = find_empty(adapters, start=1)
55
+ raise Errors::InterfaceSlotNotAvailable if free_slot == nil
56
+ end
57
+
58
+ adapters[free_slot] = options
59
+ end
60
+
61
+ # Create each interface as new domain device
62
+ adapters.each_with_index do |opts, slot_number|
63
+ next if slot_number == 0 or opts.nil?
64
+ iface_number = slot_number + 1
65
+
66
+ # Get network id
67
+ network = OVirtProvider::Util::Collection.find_matching(
68
+ env[:ovirt_client].networks(:cluster_id => env[:ovirt_cluster].id),
69
+ opts[:network_name])
70
+ if network == nil
71
+ raise Errors::NoNetworkError,
72
+ :network_name => opts[:network_name]
73
+ end
74
+
75
+ @logger.info("Creating network interface nic#{iface_number}")
76
+ begin
77
+ machine.add_interface(
78
+ :name => "nic#{iface_number}",
79
+ :network => network.id,
80
+ :interface => opts[:interface_type],
81
+ )
82
+ rescue => e
83
+ raise Errors::AddInterfaceError,
84
+ :error_message => e.message
85
+ end
86
+ end
87
+
88
+ # Continue the middleware chain.
89
+ @app.call(env)
90
+
91
+ # Configure interfaces that user requested. Machine should be up and
92
+ # running now.
93
+ networks_to_configure = []
94
+
95
+ adapters.each_with_index do |opts, slot_number|
96
+ # Skip configuring first interface. It's used for provisioning and
97
+ # it has to be available during provisioning - ifdown command is
98
+ # not acceptable here.
99
+ next if slot_number == 0
100
+
101
+ network = {
102
+ :interface => slot_number,
103
+ #:mac => ...,
104
+ }
105
+
106
+ if opts[:ip]
107
+ network = {
108
+ :type => :static,
109
+ :ip => opts[:ip],
110
+ :netmask => opts[:netmask],
111
+ :gateway => opts[:gateway],
112
+ }.merge(network)
113
+ else
114
+ network[:type] = :dhcp
115
+ end
116
+
117
+ networks_to_configure << network
118
+ end
119
+
120
+ env[:ui].info I18n.t("vagrant.actions.vm.network.configuring")
121
+ env[:machine].guest.capability(
122
+ :configure_networks, networks_to_configure)
123
+ end
124
+
125
+ private
126
+
127
+ def find_empty(array, start=0, stop=8)
128
+ for i in start..stop
129
+ return i if !array[i]
130
+ end
131
+ return nil
132
+ end
133
+ end
134
+ end
135
+ end
136
+ end
137
+
@@ -0,0 +1,113 @@
1
+ require 'log4r'
2
+ require 'vagrant/util/retryable'
3
+
4
+ module VagrantPlugins
5
+ module OVirtProvider
6
+ module Action
7
+ class CreateVM
8
+ include Vagrant::Util::Retryable
9
+
10
+ def initialize(app, env)
11
+ @logger = Log4r::Logger.new("vagrant_ovirt3::action::create_vm")
12
+ @app = app
13
+ end
14
+
15
+ def call(env)
16
+ # Get config.
17
+ config = env[:machine].provider_config
18
+
19
+ # Gather some info about domain
20
+ name = env[:domain_name]
21
+ console = config.console
22
+ cpus = config.cpus
23
+ memory_size = config.memory*1024
24
+
25
+ # Get cluster
26
+ if config.cluster == nil
27
+ cluster = env[:ovirt_compute].clusters.first
28
+ else
29
+ cluster = OVirtProvider::Util::Collection.find_matching(
30
+ env[:ovirt_compute].clusters.all, config.cluster)
31
+ end
32
+ raise Error::NoClusterError if cluster == nil
33
+ # TODO fill env also with other ovirtoptions.
34
+ env[:ovirt_cluster] = cluster
35
+
36
+ # Get template
37
+ template = OVirtProvider::Util::Collection.find_matching(
38
+ env[:ovirt_compute].templates.all, config.template)
39
+ if template == nil
40
+ raise Error::NoTemplateError,
41
+ :template_name => config.template
42
+ end
43
+
44
+ # Output the settings we're going to use to the user
45
+ env[:ui].info(I18n.t("vagrant_ovirt3.creating_vm"))
46
+ env[:ui].info(" -- Name: #{name}")
47
+ env[:ui].info(" -- Cpus: #{cpus}")
48
+ env[:ui].info(" -- Memory: #{memory_size/1024}M")
49
+ env[:ui].info(" -- Template: #{template.name}")
50
+ env[:ui].info(" -- Datacenter: #{config.datacenter}")
51
+ env[:ui].info(" -- Cluster: #{cluster.name}")
52
+ env[:ui].info(" -- Console: #{console}")
53
+ if config.disk_size
54
+ env[:ui].info(" -- Disk size: #{config.disk_size}G")
55
+ end
56
+
57
+ # Create oVirt VM.
58
+ attr = {
59
+ :name => name,
60
+ :cores => cpus,
61
+ :memory => memory_size*1024,
62
+ :cluster => cluster.id,
63
+ :template => template.id,
64
+ :display => {:type => console },
65
+ }
66
+
67
+ begin
68
+ server = env[:ovirt_compute].servers.create(attr)
69
+ rescue OVIRT::OvirtException => e
70
+ raise Errors::FogCreateServerError,
71
+ :error_message => e.message
72
+ end
73
+
74
+ # Immediately save the ID since it is created at this point.
75
+ env[:machine].id = server.id
76
+
77
+ # Wait till all volumes are ready.
78
+ env[:ui].info(I18n.t("vagrant_ovirt3.wait_for_ready_vm"))
79
+ for i in 0..10
80
+ ready = true
81
+ server = env[:ovirt_compute].servers.get(env[:machine].id.to_s)
82
+ server.volumes.each do |volume|
83
+ if volume.status != 'ok'
84
+ ready = false
85
+ break
86
+ end
87
+ end
88
+ break if ready
89
+ sleep 2
90
+ end
91
+
92
+ if not ready
93
+ raise Errors::WaitForReadyVmTimeout
94
+ end
95
+
96
+ @app.call(env)
97
+ end
98
+
99
+ def recover(env)
100
+ return if env["vagrant.error"].is_a?(Vagrant::Errors::VagrantError)
101
+
102
+ # Undo the import
103
+ env[:ui].info(I18n.t("vagrant_ovirt3.error_recovering"))
104
+ destroy_env = env.dup
105
+ destroy_env.delete(:interrupted)
106
+ destroy_env[:config_validate] = false
107
+ destroy_env[:force_confirm_destroy] = true
108
+ env[:action_runner].run(Action.action_destroy, destroy_env)
109
+ end
110
+ end
111
+ end
112
+ end
113
+ end
@@ -0,0 +1,25 @@
1
+ require 'log4r'
2
+
3
+ module VagrantPlugins
4
+ module OVirtProvider
5
+ module Action
6
+ class DestroyVM
7
+ def initialize(app, env)
8
+ @logger = Log4r::Logger.new("vagrant_ovirt3::action::destroy_vm")
9
+ @app = app
10
+ end
11
+
12
+ def call(env)
13
+ # Destroy the server, remove the tracking ID
14
+ env[:ui].info(I18n.t("vagrant_ovirt3.destroy_vm"))
15
+
16
+ machine = env[:ovirt_compute].servers.get(env[:machine].id.to_s)
17
+ machine.destroy
18
+ env[:machine].id = nil
19
+
20
+ @app.call(env)
21
+ end
22
+ end
23
+ end
24
+ end
25
+ end
@@ -0,0 +1,18 @@
1
+ module VagrantPlugins
2
+ module OVirtProvider
3
+ module Action
4
+ # This can be used with "Call" built-in to check if the machine
5
+ # is created and branch in the middleware.
6
+ class IsCreated
7
+ def initialize(app, env)
8
+ @app = app
9
+ end
10
+
11
+ def call(env)
12
+ env[:result] = env[:machine].state.id != :not_created
13
+ @app.call(env)
14
+ end
15
+ end
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,16 @@
1
+ module VagrantPlugins
2
+ module OVirtProvider
3
+ module Action
4
+ class MessageAlreadyCreated
5
+ def initialize(app, env)
6
+ @app = app
7
+ end
8
+
9
+ def call(env)
10
+ env[:ui].info(I18n.t("vagrant_ovirt3.already_created"))
11
+ @app.call(env)
12
+ end
13
+ end
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,16 @@
1
+ module VagrantPlugins
2
+ module OVirtProvider
3
+ module Action
4
+ class MessageNotCreated
5
+ def initialize(app, env)
6
+ @app = app
7
+ end
8
+
9
+ def call(env)
10
+ env[:ui].info(I18n.t("vagrant_ovirt3.not_created"))
11
+ @app.call(env)
12
+ end
13
+ end
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,56 @@
1
+ require "log4r"
2
+
3
+ module VagrantPlugins
4
+ module OVirtProvider
5
+ module Action
6
+ # This action reads the SSH info for the machine and puts it into the
7
+ # `:machine_ssh_info` key in the environment.
8
+ class ReadSSHInfo
9
+ def initialize(app, env)
10
+ @app = app
11
+ @logger = Log4r::Logger.new("vagrant_ovirt3::action::read_ssh_info")
12
+ end
13
+
14
+ def call(env)
15
+ env[:machine_ssh_info] = read_ssh_info(
16
+ env[:ovirt_compute], env[:machine])
17
+
18
+ @app.call(env)
19
+ end
20
+
21
+ def read_ssh_info(ovirt, machine)
22
+ return nil if machine.id.nil?
23
+
24
+ # Get config.
25
+ config = machine.provider_config
26
+
27
+ # Find the machine
28
+ server = ovirt.servers.get(machine.id.to_s)
29
+
30
+ if server.nil?
31
+ # The machine can't be found
32
+ @logger.info("Machine couldn't be found, assuming it got destroyed.")
33
+ machine.id = nil
34
+ return nil
35
+ end
36
+
37
+ ip_address = server.ips.first
38
+ if ip_address == nil or ip_address == ''
39
+ raise Errors::NoIpAddressError
40
+ end
41
+
42
+ # Return the info
43
+ # TODO: Some info should be configurable in Vagrantfile
44
+ return {
45
+ :host => ip_address,
46
+ :port => machine.config.ssh.guest_port,
47
+ :username => machine.config.ssh.username,
48
+ :private_key_path => machine.config.ssh.private_key_path,
49
+ :forward_agent => machine.config.ssh.forward_agent,
50
+ :forward_x11 => machine.config.ssh.forward_x11,
51
+ }
52
+ end
53
+ end
54
+ end
55
+ end
56
+ end