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.
- checksums.yaml +7 -0
- data/.gitignore +20 -0
- data/Gemfile +4 -0
- data/LICENSE +22 -0
- data/README.md +211 -0
- data/Rakefile +7 -0
- data/example_box/README.md +13 -0
- data/example_box/Vagrantfile +18 -0
- data/example_box/dummy.box +0 -0
- data/example_box/metadata.json +4 -0
- data/lib/vagrant-ovirt3.rb +42 -0
- data/lib/vagrant-ovirt3/action.rb +131 -0
- data/lib/vagrant-ovirt3/action/connect_ovirt.rb +84 -0
- data/lib/vagrant-ovirt3/action/create_network_interfaces.rb +137 -0
- data/lib/vagrant-ovirt3/action/create_vm.rb +113 -0
- data/lib/vagrant-ovirt3/action/destroy_vm.rb +25 -0
- data/lib/vagrant-ovirt3/action/is_created.rb +18 -0
- data/lib/vagrant-ovirt3/action/message_already_created.rb +16 -0
- data/lib/vagrant-ovirt3/action/message_not_created.rb +16 -0
- data/lib/vagrant-ovirt3/action/read_ssh_info.rb +56 -0
- data/lib/vagrant-ovirt3/action/read_state.rb +37 -0
- data/lib/vagrant-ovirt3/action/resize_disk.rb +71 -0
- data/lib/vagrant-ovirt3/action/set_name_of_domain.rb +31 -0
- data/lib/vagrant-ovirt3/action/start_vm.rb +37 -0
- data/lib/vagrant-ovirt3/action/sync_folders.rb +65 -0
- data/lib/vagrant-ovirt3/action/wait_till_up.rb +94 -0
- data/lib/vagrant-ovirt3/config.rb +58 -0
- data/lib/vagrant-ovirt3/errors.rb +76 -0
- data/lib/vagrant-ovirt3/plugin.rb +74 -0
- data/lib/vagrant-ovirt3/provider.rb +76 -0
- data/lib/vagrant-ovirt3/util.rb +9 -0
- data/lib/vagrant-ovirt3/util/collection.rb +21 -0
- data/lib/vagrant-ovirt3/util/timer.rb +17 -0
- data/lib/vagrant-ovirt3/version.rb +6 -0
- data/locales/en.yml +90 -0
- data/tools/prepare_redhat_for_box.sh +132 -0
- data/vagrant-ovirt3.gemspec +25 -0
- 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
|