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,37 @@
|
|
1
|
+
require "log4r"
|
2
|
+
|
3
|
+
module VagrantPlugins
|
4
|
+
module OVirtProvider
|
5
|
+
module Action
|
6
|
+
# This action reads the state of the machine and puts it in the
|
7
|
+
# `:machine_state_id` key in the environment.
|
8
|
+
class ReadState
|
9
|
+
def initialize(app, env)
|
10
|
+
@app = app
|
11
|
+
@logger = Log4r::Logger.new("vagrant_ovirt3::action::read_state")
|
12
|
+
end
|
13
|
+
|
14
|
+
def call(env)
|
15
|
+
env[:machine_state_id] = read_state(env[:ovirt_compute], env[:machine])
|
16
|
+
@app.call(env)
|
17
|
+
end
|
18
|
+
|
19
|
+
def read_state(ovirt, machine)
|
20
|
+
return :not_created if machine.id.nil?
|
21
|
+
|
22
|
+
# Find the machine
|
23
|
+
server = ovirt.servers.get(machine.id)
|
24
|
+
if server.nil? || [:"shutting-down", :terminated].include?(server.status.to_sym)
|
25
|
+
# The machine can't be found
|
26
|
+
@logger.info("Machine not found or terminated, assuming it got destroyed.")
|
27
|
+
machine.id = nil
|
28
|
+
return :not_created
|
29
|
+
end
|
30
|
+
|
31
|
+
# Return the state
|
32
|
+
return server.status
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
@@ -0,0 +1,71 @@
|
|
1
|
+
require 'log4r'
|
2
|
+
require 'vagrant/util/scoped_hash_override'
|
3
|
+
|
4
|
+
module VagrantPlugins
|
5
|
+
module OVirtProvider
|
6
|
+
module Action
|
7
|
+
# Resize the disk if necessary, before VM is running.
|
8
|
+
class ResizeDisk
|
9
|
+
include Vagrant::Util::ScopedHashOverride
|
10
|
+
|
11
|
+
def initialize(app, env)
|
12
|
+
@logger = Log4r::Logger.new("vagrant_ovirt::action::resize_disk")
|
13
|
+
@app = app
|
14
|
+
end
|
15
|
+
|
16
|
+
def call(env)
|
17
|
+
# Is it necessary to resize the disk?
|
18
|
+
config = env[:machine].provider_config
|
19
|
+
if config.disk_size.nil?
|
20
|
+
# Nothing to do
|
21
|
+
@app.call(env)
|
22
|
+
return
|
23
|
+
end
|
24
|
+
|
25
|
+
# Get machine first.
|
26
|
+
begin
|
27
|
+
machine = OVirtProvider::Util::Collection.find_matching(
|
28
|
+
env[:ovirt_compute].servers.all, env[:machine].id.to_s)
|
29
|
+
rescue => e
|
30
|
+
raise Errors::NoVMError,
|
31
|
+
:vm_name => env[:machine].id.to_s
|
32
|
+
end
|
33
|
+
|
34
|
+
# Extend disk size if necessary
|
35
|
+
begin
|
36
|
+
machine.update_volume(
|
37
|
+
:id => machine.volumes.first.id,
|
38
|
+
:size => config.disk_size*1024*1024*1024,
|
39
|
+
)
|
40
|
+
rescue => e
|
41
|
+
raise Errors::UpdateVolumeError,
|
42
|
+
:error_message => e.message
|
43
|
+
end
|
44
|
+
|
45
|
+
# Wait till all volumes are ready.
|
46
|
+
env[:ui].info(I18n.t("vagrant_ovirt3.wait_for_ready_volume"))
|
47
|
+
for i in 0..10
|
48
|
+
ready = true
|
49
|
+
machine = env[:ovirt_compute].servers.get(env[:machine].id.to_s)
|
50
|
+
machine.volumes.each do |volume|
|
51
|
+
if volume.status != 'ok'
|
52
|
+
ready = false
|
53
|
+
break
|
54
|
+
end
|
55
|
+
end
|
56
|
+
break if ready
|
57
|
+
sleep 2
|
58
|
+
end
|
59
|
+
|
60
|
+
if not ready
|
61
|
+
raise Errors::WaitForReadyResizedVolumeTimeout
|
62
|
+
end
|
63
|
+
|
64
|
+
@app.call(env)
|
65
|
+
end
|
66
|
+
|
67
|
+
end
|
68
|
+
end
|
69
|
+
end
|
70
|
+
end
|
71
|
+
|
@@ -0,0 +1,31 @@
|
|
1
|
+
module VagrantPlugins
|
2
|
+
module OVirtProvider
|
3
|
+
module Action
|
4
|
+
|
5
|
+
# Setup name for domain and domain volumes.
|
6
|
+
class SetNameOfDomain
|
7
|
+
def initialize(app, env)
|
8
|
+
@app = app
|
9
|
+
end
|
10
|
+
|
11
|
+
def call(env)
|
12
|
+
env[:domain_name] = env[:root_path].basename.to_s.dup
|
13
|
+
env[:domain_name].gsub!(/[^-a-z0-9_]/i, "")
|
14
|
+
env[:domain_name] << "_#{Time.now.to_i}"
|
15
|
+
|
16
|
+
# Check if the domain name is not already taken
|
17
|
+
domain = OVirtProvider::Util::Collection.find_matching(
|
18
|
+
env[:ovirt_compute].servers.all, env[:domain_name])
|
19
|
+
if domain != nil
|
20
|
+
raise Vagrant::Errors::DomainNameExists,
|
21
|
+
:domain_name => env[:domain_name]
|
22
|
+
end
|
23
|
+
|
24
|
+
@app.call(env)
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
@@ -0,0 +1,37 @@
|
|
1
|
+
require 'log4r'
|
2
|
+
|
3
|
+
module VagrantPlugins
|
4
|
+
module OVirtProvider
|
5
|
+
module Action
|
6
|
+
|
7
|
+
# Just start the VM.
|
8
|
+
class StartVM
|
9
|
+
|
10
|
+
def initialize(app, env)
|
11
|
+
@logger = Log4r::Logger.new("vagrant_ovirt::action::start_vm")
|
12
|
+
@app = app
|
13
|
+
end
|
14
|
+
|
15
|
+
def call(env)
|
16
|
+
env[:ui].info(I18n.t("vagrant_ovirt3.starting_vm"))
|
17
|
+
|
18
|
+
machine = env[:ovirt_compute].servers.get(env[:machine].id.to_s)
|
19
|
+
if machine == nil
|
20
|
+
raise Errors::NoVMError,
|
21
|
+
:vm_name => env[:machine].id.to_s
|
22
|
+
end
|
23
|
+
|
24
|
+
# Start VM.
|
25
|
+
begin
|
26
|
+
machine.start
|
27
|
+
rescue OVIRT::OvirtException => e
|
28
|
+
raise Errors::StartVMError,
|
29
|
+
:error_message => e.message
|
30
|
+
end
|
31
|
+
|
32
|
+
@app.call(env)
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
@@ -0,0 +1,65 @@
|
|
1
|
+
require "log4r"
|
2
|
+
require "vagrant/util/subprocess"
|
3
|
+
|
4
|
+
module VagrantPlugins
|
5
|
+
module OVirtProvider
|
6
|
+
module Action
|
7
|
+
# This middleware uses `rsync` to sync the folders over to the
|
8
|
+
# oVirt VM.
|
9
|
+
class SyncFolders
|
10
|
+
def initialize(app, env)
|
11
|
+
@app = app
|
12
|
+
@logger = Log4r::Logger.new("vagrant_ovirt::action::sync_folders")
|
13
|
+
end
|
14
|
+
|
15
|
+
def call(env)
|
16
|
+
@app.call(env)
|
17
|
+
|
18
|
+
ssh_info = env[:machine].ssh_info
|
19
|
+
|
20
|
+
env[:machine].config.vm.synced_folders.each do |id, data|
|
21
|
+
hostpath = File.expand_path(data[:hostpath], env[:root_path])
|
22
|
+
guestpath = data[:guestpath]
|
23
|
+
|
24
|
+
# Make sure there is a trailing slash on the host path to
|
25
|
+
# avoid creating an additional directory with rsync
|
26
|
+
hostpath = "#{hostpath}/" if hostpath !~ /\/$/
|
27
|
+
|
28
|
+
# on windows rsync.exe requires cygdrive-style paths.
|
29
|
+
# assumes: /c/...
|
30
|
+
# Should be msysgit and cygwin compatible if /etc/fstab in cygwin contains:
|
31
|
+
# none / cygdrive binary,posix=0,user 0 0
|
32
|
+
if Vagrant::Util::Platform.windows?
|
33
|
+
hostpath = hostpath.gsub(/^(\w):/) { "/#{$1}" }
|
34
|
+
end
|
35
|
+
|
36
|
+
env[:ui].info(I18n.t("vagrant_ovirt3.rsync_folder",
|
37
|
+
:hostpath => hostpath,
|
38
|
+
:guestpath => guestpath))
|
39
|
+
|
40
|
+
# Create the guest path
|
41
|
+
env[:machine].communicate.sudo("mkdir -p '#{guestpath}'")
|
42
|
+
env[:machine].communicate.sudo("chown #{ssh_info[:username]} '#{guestpath}'")
|
43
|
+
|
44
|
+
# Rsync over to the guest path using the SSH info
|
45
|
+
command = [
|
46
|
+
"rsync", "--verbose", "--archive", "-z", "--owner", "--perms",
|
47
|
+
"--exclude", ".vagrant/",
|
48
|
+
"-e", "ssh -p #{ssh_info[:port]} -o StrictHostKeyChecking=no -i '#{ssh_info[:private_key_path][0]}'",
|
49
|
+
hostpath,
|
50
|
+
"#{ssh_info[:username]}@#{ssh_info[:host]}:#{guestpath}"]
|
51
|
+
|
52
|
+
r = Vagrant::Util::Subprocess.execute(*command)
|
53
|
+
if r.exit_code != 0
|
54
|
+
raise Errors::RsyncError,
|
55
|
+
:guestpath => guestpath,
|
56
|
+
:hostpath => hostpath,
|
57
|
+
:stderr => r.stderr
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
@@ -0,0 +1,94 @@
|
|
1
|
+
require 'log4r'
|
2
|
+
require 'vagrant-ovirt3/util/timer'
|
3
|
+
require 'vagrant/util/retryable'
|
4
|
+
|
5
|
+
module VagrantPlugins
|
6
|
+
module OVirtProvider
|
7
|
+
module Action
|
8
|
+
|
9
|
+
# Wait till VM is started, till it obtains an IP address and is
|
10
|
+
# accessible via ssh.
|
11
|
+
class WaitTillUp
|
12
|
+
include Vagrant::Util::Retryable
|
13
|
+
|
14
|
+
def initialize(app, env)
|
15
|
+
@logger = Log4r::Logger.new("vagrant_ovirt3::action::wait_till_up")
|
16
|
+
@app = app
|
17
|
+
end
|
18
|
+
|
19
|
+
def call(env)
|
20
|
+
# Initialize metrics if they haven't been
|
21
|
+
env[:metrics] ||= {}
|
22
|
+
|
23
|
+
# Get config.
|
24
|
+
config = env[:machine].provider_config
|
25
|
+
|
26
|
+
# Wait for VM to obtain an ip address.
|
27
|
+
env[:ip_address] = nil
|
28
|
+
env[:metrics]["instance_ip_time"] = Util::Timer.time do
|
29
|
+
env[:ui].info(I18n.t("vagrant_ovirt3.waiting_for_ip"))
|
30
|
+
#retryable(:on => Fog::Errors::TimeoutError, :tries => 300) do
|
31
|
+
for i in 1..300
|
32
|
+
# If we're interrupted don't worry about waiting
|
33
|
+
next if env[:interrupted]
|
34
|
+
|
35
|
+
# Get VM.
|
36
|
+
server = env[:ovirt_compute].servers.get(env[:machine].id.to_s)
|
37
|
+
if server == nil
|
38
|
+
raise NoVMError, :vm_name => ''
|
39
|
+
end
|
40
|
+
|
41
|
+
env[:ip_address] = server.ips.first
|
42
|
+
@logger.debug("Got output #{env[:ip_address]}")
|
43
|
+
break if env[:ip_address] =~ /[0-9\.]+/
|
44
|
+
sleep 2
|
45
|
+
end
|
46
|
+
#end
|
47
|
+
end
|
48
|
+
terminate(env) if env[:interrupted]
|
49
|
+
@logger.info("Got IP address #{env[:ip_address]}")
|
50
|
+
@logger.info("Time for getting IP: #{env[:metrics]["instance_ip_time"]}")
|
51
|
+
|
52
|
+
# Machine has ip address assigned, now wait till we are able to
|
53
|
+
# connect via ssh.
|
54
|
+
env[:metrics]["instance_ssh_time"] = Util::Timer.time do
|
55
|
+
env[:ui].info(I18n.t("vagrant_ovirt3.waiting_for_ssh"))
|
56
|
+
retryable(:on => Fog::Errors::TimeoutError, :tries => 60) do
|
57
|
+
# If we're interrupted don't worry about waiting
|
58
|
+
next if env[:interrupted]
|
59
|
+
|
60
|
+
# Wait till we are able to connect via ssh.
|
61
|
+
next if env[:machine].communicate.ready?
|
62
|
+
sleep 2
|
63
|
+
end
|
64
|
+
end
|
65
|
+
terminate(env) if env[:interrupted]
|
66
|
+
@logger.info("Time for SSH ready: #{env[:metrics]["instance_ssh_time"]}")
|
67
|
+
|
68
|
+
# Booted and ready for use.
|
69
|
+
env[:ui].info(I18n.t("vagrant_ovirt3.ready"))
|
70
|
+
|
71
|
+
@app.call(env)
|
72
|
+
end
|
73
|
+
|
74
|
+
def recover(env)
|
75
|
+
return if env["vagrant.error"].is_a?(Vagrant::Errors::VagrantError)
|
76
|
+
|
77
|
+
if env[:machine].provider.state.id != :not_created
|
78
|
+
# Undo the import
|
79
|
+
terminate(env)
|
80
|
+
end
|
81
|
+
end
|
82
|
+
|
83
|
+
def terminate(env)
|
84
|
+
destroy_env = env.dup
|
85
|
+
destroy_env.delete(:interrupted)
|
86
|
+
destroy_env[:config_validate] = false
|
87
|
+
destroy_env[:force_confirm_destroy] = true
|
88
|
+
env[:action_runner].run(Action.action_destroy, destroy_env)
|
89
|
+
end
|
90
|
+
end
|
91
|
+
end
|
92
|
+
end
|
93
|
+
end
|
94
|
+
|
@@ -0,0 +1,58 @@
|
|
1
|
+
require 'vagrant'
|
2
|
+
|
3
|
+
module VagrantPlugins
|
4
|
+
module OVirtProvider
|
5
|
+
class Config < Vagrant.plugin('2', :config)
|
6
|
+
|
7
|
+
attr_accessor :url
|
8
|
+
attr_accessor :username
|
9
|
+
attr_accessor :password
|
10
|
+
attr_accessor :datacenter
|
11
|
+
attr_accessor :cluster
|
12
|
+
|
13
|
+
# Domain specific settings used while creating new machine.
|
14
|
+
attr_accessor :memory
|
15
|
+
attr_accessor :cpus
|
16
|
+
attr_accessor :template
|
17
|
+
attr_accessor :console
|
18
|
+
attr_accessor :disk_size
|
19
|
+
|
20
|
+
def initialize
|
21
|
+
@url = UNSET_VALUE
|
22
|
+
@username = UNSET_VALUE
|
23
|
+
@password = UNSET_VALUE
|
24
|
+
@datacenter = UNSET_VALUE
|
25
|
+
@cluster = UNSET_VALUE
|
26
|
+
|
27
|
+
# Domain specific settings.
|
28
|
+
@memory = UNSET_VALUE
|
29
|
+
@cpus = UNSET_VALUE
|
30
|
+
@template = UNSET_VALUE
|
31
|
+
@console = UNSET_VALUE
|
32
|
+
@disk_size = UNSET_VALUE
|
33
|
+
end
|
34
|
+
|
35
|
+
def finalize!
|
36
|
+
@url = nil if @url == UNSET_VALUE
|
37
|
+
@username = nil if @username == UNSET_VALUE
|
38
|
+
@password = nil if @password == UNSET_VALUE
|
39
|
+
@datacenter = nil if @datacenter == UNSET_VALUE
|
40
|
+
@cluster = nil if @cluster == UNSET_VALUE
|
41
|
+
|
42
|
+
# Domain specific settings.
|
43
|
+
@memory = 512 if @memory == UNSET_VALUE
|
44
|
+
@cpus = 1 if @cpus == UNSET_VALUE
|
45
|
+
@template = 'Blank' if @template == UNSET_VALUE
|
46
|
+
@console = 'spice' if @console == UNSET_VALUE
|
47
|
+
@disk_size = nil if @disk_size == UNSET_VALUE
|
48
|
+
end
|
49
|
+
|
50
|
+
def validate(machine)
|
51
|
+
valid_console_types = ['vnc', 'spice']
|
52
|
+
raise Error::InvalidConsoleType,
|
53
|
+
:console => @console unless valid_console_types.include? @console
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
@@ -0,0 +1,76 @@
|
|
1
|
+
require 'vagrant'
|
2
|
+
|
3
|
+
module VagrantPlugins
|
4
|
+
module OVirtProvider
|
5
|
+
module Errors
|
6
|
+
class VagrantOVirtError < Vagrant::Errors::VagrantError
|
7
|
+
error_namespace("vagrant_ovirt3.errors")
|
8
|
+
end
|
9
|
+
|
10
|
+
class RsyncError < VagrantOVirtError
|
11
|
+
error_key(:rsync_error)
|
12
|
+
end
|
13
|
+
|
14
|
+
class FogOVirtConnectionError < VagrantOVirtError
|
15
|
+
error_key(:fog_ovirt_connection_error)
|
16
|
+
end
|
17
|
+
|
18
|
+
class NoDatacenterError < VagrantOVirtError
|
19
|
+
error_key(:no_datacenter_error)
|
20
|
+
end
|
21
|
+
|
22
|
+
class NoClusterError < VagrantOVirtError
|
23
|
+
error_key(:no_cluster_error)
|
24
|
+
end
|
25
|
+
|
26
|
+
class NoTemplateError < VagrantOVirtError
|
27
|
+
error_key(:no_template_error)
|
28
|
+
end
|
29
|
+
|
30
|
+
class NoQuotaError < VagrantOVirtError
|
31
|
+
error_key(:no_template_error)
|
32
|
+
end
|
33
|
+
|
34
|
+
class FogCreateServerError < VagrantOVirtError
|
35
|
+
error_key(:fog_create_server_error)
|
36
|
+
end
|
37
|
+
|
38
|
+
class InterfaceSlotNotAvailable < VagrantOVirtError
|
39
|
+
error_key(:interface_slot_not_available)
|
40
|
+
end
|
41
|
+
|
42
|
+
class AddInterfaceError < VagrantOVirtError
|
43
|
+
error_key(:add_interface_error)
|
44
|
+
end
|
45
|
+
|
46
|
+
class NoVMError < VagrantOVirtError
|
47
|
+
error_key(:no_vm_error)
|
48
|
+
end
|
49
|
+
|
50
|
+
class StartVMError < VagrantOVirtError
|
51
|
+
error_key(:start_vm_error)
|
52
|
+
end
|
53
|
+
|
54
|
+
class WaitForReadyVmTimeout < VagrantOVirtError
|
55
|
+
error_key(:wait_for_ready_vm_timeout)
|
56
|
+
end
|
57
|
+
|
58
|
+
class NoIpAddressError < VagrantOVirtError
|
59
|
+
error_key(:no_ip_address_error)
|
60
|
+
end
|
61
|
+
|
62
|
+
class NoNetworkError < VagrantOVirtError
|
63
|
+
error_key(:no_network_error)
|
64
|
+
end
|
65
|
+
|
66
|
+
class UpdateVolumeError < VagrantOVirtError
|
67
|
+
error_key(:update_volume_error)
|
68
|
+
end
|
69
|
+
|
70
|
+
class WaitForReadyResizedVolumeTimeout < VagrantOVirtError
|
71
|
+
error_key(:wait_for_ready_resized_volume_timeout)
|
72
|
+
end
|
73
|
+
end
|
74
|
+
end
|
75
|
+
end
|
76
|
+
|