vagrant-ovirt 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +20 -0
- data/Gemfile +12 -0
- data/LICENSE +22 -0
- data/README.md +219 -0
- data/Rakefile +7 -0
- data/example_box/Vagrantfile +22 -0
- data/example_box/metadata.json +4 -0
- data/example_box/ovirt.box +0 -0
- data/lib/vagrant-ovirt/action/connect_ovirt.rb +84 -0
- data/lib/vagrant-ovirt/action/create_network_interfaces.rb +96 -0
- data/lib/vagrant-ovirt/action/create_vm.rb +114 -0
- data/lib/vagrant-ovirt/action/destroy_vm.rb +25 -0
- data/lib/vagrant-ovirt/action/is_created.rb +18 -0
- data/lib/vagrant-ovirt/action/message_already_created.rb +16 -0
- data/lib/vagrant-ovirt/action/message_not_created.rb +16 -0
- data/lib/vagrant-ovirt/action/read_ssh_info.rb +68 -0
- data/lib/vagrant-ovirt/action/read_state.rb +37 -0
- data/lib/vagrant-ovirt/action/set_name_of_domain.rb +31 -0
- data/lib/vagrant-ovirt/action/start_vm.rb +37 -0
- data/lib/vagrant-ovirt/action/sync_folders.rb +58 -0
- data/lib/vagrant-ovirt/action/timed_provision.rb +21 -0
- data/lib/vagrant-ovirt/action/wait_till_up.rb +108 -0
- data/lib/vagrant-ovirt/action.rb +89 -0
- data/lib/vagrant-ovirt/config.rb +57 -0
- data/lib/vagrant-ovirt/errors.rb +61 -0
- data/lib/vagrant-ovirt/plugin.rb +74 -0
- data/lib/vagrant-ovirt/provider.rb +76 -0
- data/lib/vagrant-ovirt/util/collection.rb +21 -0
- data/lib/vagrant-ovirt/util/timer.rb +17 -0
- data/lib/vagrant-ovirt/util.rb +9 -0
- data/lib/vagrant-ovirt/version.rb +6 -0
- data/lib/vagrant-ovirt.rb +47 -0
- data/locales/en.yml +82 -0
- data/tools/prepare_redhat_for_box.sh +138 -0
- data/vagrant-ovirt.gemspec +23 -0
- metadata +128 -0
data/.gitignore
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
*.gem
|
2
|
+
*.rbc
|
3
|
+
.bundle
|
4
|
+
.config
|
5
|
+
.yardoc
|
6
|
+
Gemfile.lock
|
7
|
+
InstalledFiles
|
8
|
+
_yardoc
|
9
|
+
coverage
|
10
|
+
doc/
|
11
|
+
lib/bundler/man
|
12
|
+
pkg
|
13
|
+
rdoc
|
14
|
+
spec/reports
|
15
|
+
test/tmp
|
16
|
+
test/version_tmp
|
17
|
+
tmp
|
18
|
+
Vagrantfile
|
19
|
+
!example_box/Vagrantfile
|
20
|
+
.vagrant
|
data/Gemfile
ADDED
@@ -0,0 +1,12 @@
|
|
1
|
+
source 'https://rubygems.org'
|
2
|
+
|
3
|
+
# Specify your gem's dependencies in vagrant-ovirt.gemspec
|
4
|
+
gemspec
|
5
|
+
|
6
|
+
group :development do
|
7
|
+
# We depend on Vagrant for development, but we don't add it as a
|
8
|
+
# gem dependency because we expect to be installed within the
|
9
|
+
# Vagrant environment itself using `vagrant plugin`.
|
10
|
+
gem "vagrant", :git => "git://github.com/mitchellh/vagrant.git"
|
11
|
+
end
|
12
|
+
|
data/LICENSE
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
Copyright (c) 2013 Lukas Stanek
|
2
|
+
|
3
|
+
MIT License
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
6
|
+
a copy of this software and associated documentation files (the
|
7
|
+
"Software"), to deal in the Software without restriction, including
|
8
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
9
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
10
|
+
permit persons to whom the Software is furnished to do so, subject to
|
11
|
+
the following conditions:
|
12
|
+
|
13
|
+
The above copyright notice and this permission notice shall be
|
14
|
+
included in all copies or substantial portions of the Software.
|
15
|
+
|
16
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
17
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
18
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
19
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
20
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
21
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
22
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,219 @@
|
|
1
|
+
# Vagrant oVirt/RHEV Provider
|
2
|
+
|
3
|
+
This is a [Vagrant](http://www.vagrantup.com) 1.1+ plugin that adds an
|
4
|
+
[oVirt](http://ovirt.org) and
|
5
|
+
[rhev](http://www.redhat.com/products/virtualization/) provider to Vagrant,
|
6
|
+
allowing Vagrant to control and provision machines in oVirt and RHEV.
|
7
|
+
|
8
|
+
**Note:** Actual version (0.0.1) is still a development one.
|
9
|
+
|
10
|
+
## Features (Version 0.0.1)
|
11
|
+
|
12
|
+
* Vagrant `up`, `destroy` commands.
|
13
|
+
* Create and boot oVirt machines from oVirt templates.
|
14
|
+
* SSH into domains.
|
15
|
+
* Provision domains with any built-in Vagrant provisioner.
|
16
|
+
* Minimal synced folder support via `rsync`.
|
17
|
+
|
18
|
+
## Future work
|
19
|
+
|
20
|
+
* Take a look at [open issues](https://github.com/pradels/vagrant-ovirt/issues?state=open).
|
21
|
+
|
22
|
+
## Installation
|
23
|
+
|
24
|
+
Install using standard [Vagrant 1.1+](http://downloads.vagrantup.com) plugin installation methods. After
|
25
|
+
installing, `vagrant up` and specify the `ovirt` provider. An example is shown below.
|
26
|
+
|
27
|
+
```
|
28
|
+
$ vagrant plugin install vagrant-ovirt
|
29
|
+
```
|
30
|
+
|
31
|
+
## Vagrant Project Preparation
|
32
|
+
|
33
|
+
After installing the plugin (instructions above), the quickest way to get
|
34
|
+
started is to actually use a dummy oVirt box and specify all the details
|
35
|
+
manually within a `config.vm.provider` block. So first, add the dummy box using
|
36
|
+
any name you want:
|
37
|
+
|
38
|
+
```
|
39
|
+
$ vagrant box add ovirt https://raw.github.com/pradels/vagrant-ovirt/master/example_box/ovirt.box
|
40
|
+
```
|
41
|
+
|
42
|
+
And then make a Vagrantfile that looks like the following, filling in
|
43
|
+
your information where necessary.
|
44
|
+
|
45
|
+
```ruby
|
46
|
+
Vagrant.configure("2") do |config|
|
47
|
+
config.vm.define :test_vm do |test_vm|
|
48
|
+
test_vm.vm.box = "ovirt"
|
49
|
+
test_vm.vm.provider :ovirt do |ovirt|
|
50
|
+
ovirt.template = "example-template-name"
|
51
|
+
ovirt.quota = "quota name"
|
52
|
+
ovirt.cpus = 1
|
53
|
+
ovirt.memory = 1024
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
config.vm.provider :ovirt do |ovirt|
|
58
|
+
ovirt.url = "https://rhevm.example.com:443"
|
59
|
+
ovirt.username = "example_user"
|
60
|
+
ovirt.password = "example_password"
|
61
|
+
ovirt.datacenter = "example_datacenter"
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
```
|
66
|
+
|
67
|
+
### RHEV/oVirt Configuration Options
|
68
|
+
|
69
|
+
This provider exposes quite a few provider-specific configuration options:
|
70
|
+
|
71
|
+
* `url` - URL to management interface.
|
72
|
+
* `username` - Username to access oVirt.
|
73
|
+
* `password` - Password to access oVirt.
|
74
|
+
* `datacenter` - oVirt datacenter name, where machines will be created.
|
75
|
+
* `cluster` - oVirt cluster name. Defaults to first cluster found.
|
76
|
+
* ``ip_command` - Shell command, which shoud return IP address string for
|
77
|
+
MAC address specified in MAC environment variable. By default, this command
|
78
|
+
searches in local arp table.
|
79
|
+
|
80
|
+
### Domain Specific Options
|
81
|
+
|
82
|
+
* `memory` - Amount of memory in MBytes. Defaults to 512 if not set.
|
83
|
+
* `cpus` - Number of virtual cpus. Defaults to 1 if not set.
|
84
|
+
* `template` - Name of template from which new VM should be created.
|
85
|
+
* `quota` - Name of oVirt quota for VM. Defaults to first quota found.
|
86
|
+
|
87
|
+
Specific domain settings can be set for each domain separately in multi-VM
|
88
|
+
environment. Example below shows a part of Vagrantfile, where specific options
|
89
|
+
are set for dbserver domain.
|
90
|
+
|
91
|
+
```ruby
|
92
|
+
Vagrant.configure("2") do |config|
|
93
|
+
config.vm.define :dbserver do |dbserver|
|
94
|
+
dbserver.vm.box = "ovirt"
|
95
|
+
dbserver.vm.provider :ovirt do |vm|
|
96
|
+
vm.memory = 2048
|
97
|
+
vm.cpus = 2
|
98
|
+
vm.template = "centos63-vagrant-base"
|
99
|
+
end
|
100
|
+
end
|
101
|
+
|
102
|
+
# ...
|
103
|
+
```
|
104
|
+
|
105
|
+
## Create Project - Vagrant up
|
106
|
+
|
107
|
+
In prepared project directory, run following command:
|
108
|
+
|
109
|
+
```
|
110
|
+
$ vagrant up --provider=ovirt
|
111
|
+
```
|
112
|
+
|
113
|
+
Vagrant needs to know that we want to use oVirt and not default VirtualBox.
|
114
|
+
That's why there is `--provider=ovirt` option specified. Other way to tell
|
115
|
+
Vagrant to use oVirt provider is to setup environment variable
|
116
|
+
`export VAGRANT_DEFAULT_PROVIDER=ovirt`.
|
117
|
+
|
118
|
+
### How Project Is Created
|
119
|
+
|
120
|
+
Vagrant goes through steps below when creating new project:
|
121
|
+
|
122
|
+
1. Connect to oVirt via REST API on every REST query.
|
123
|
+
2. Create new oVirt machine from template with additional network interfaces.
|
124
|
+
3. Start oVirt machine.
|
125
|
+
4. Check for IP address of VM with ip_command.
|
126
|
+
5. Wait till SSH is available.
|
127
|
+
6. Sync folders via `rsync` and run Vagrant provisioner on new domain if
|
128
|
+
setup in Vagrantfile.
|
129
|
+
|
130
|
+
## Networks
|
131
|
+
|
132
|
+
Networking features in the form of `config.vm.network` are supported only
|
133
|
+
in bridged format, no hostonly network is supported in current version of
|
134
|
+
provider.
|
135
|
+
|
136
|
+
Example of network interface definition:
|
137
|
+
|
138
|
+
```ruby
|
139
|
+
config.vm.define :test_vm do |test_vm|
|
140
|
+
test_vm.vm.network :bridged, :bridge => "rhevm", :adapter => 1
|
141
|
+
end
|
142
|
+
```
|
143
|
+
|
144
|
+
In example above, bridged network adapter connected to network `rhevm` is
|
145
|
+
defined.
|
146
|
+
|
147
|
+
## Obtaining Domain IP Address
|
148
|
+
|
149
|
+
OVirt API doesn't provide standard way how to find out an IP address of running
|
150
|
+
VM. But we know, what is MAC address of virtual machine. Problem is, where to
|
151
|
+
get mapping MAC to IP address.
|
152
|
+
|
153
|
+
There is an option named ip_command, which by default looks into local arp
|
154
|
+
table and searches there IP for MAC address specified as a MAC shell variable.
|
155
|
+
Maybe you need to customize this behaviour, so setup your own ip_commands to
|
156
|
+
your needs.
|
157
|
+
|
158
|
+
## Synced Folders
|
159
|
+
|
160
|
+
There is minimal support for synced folders. Upon `vagrant up`, the oVirt
|
161
|
+
provider will use `rsync` (if available) to uni-directionally sync the folder
|
162
|
+
to the remote machine over SSH.
|
163
|
+
|
164
|
+
This is good enough for all built-in Vagrant provisioners (shell,
|
165
|
+
chef, and puppet) to work!
|
166
|
+
|
167
|
+
## Box Format
|
168
|
+
|
169
|
+
Every provider in Vagrant must introduce a custom box format. This provider
|
170
|
+
introduces oVirt boxes. You can view an example box in the
|
171
|
+
[example_box](https://github.com/pradels/vagrant-ovirt/tree/master/example_box)
|
172
|
+
directory. That directory also contains instructions on how to build a box.
|
173
|
+
|
174
|
+
The box is a tarball containing:
|
175
|
+
|
176
|
+
* `metadata.json` file describing box image (just a provider name).
|
177
|
+
* `Vagrantfile` that does default settings for the provider-specific configuration for this provider.
|
178
|
+
|
179
|
+
## Development
|
180
|
+
|
181
|
+
To work on the `vagrant-ovirt` plugin, clone this repository out, and use
|
182
|
+
[Bundler](http://gembundler.com) to get the dependencies:
|
183
|
+
|
184
|
+
```
|
185
|
+
$ git clone https://github.com/pradels/vagrant-ovirt.git
|
186
|
+
$ cd vagrant-ovirt
|
187
|
+
$ bundle install
|
188
|
+
```
|
189
|
+
|
190
|
+
Once you have the dependencies, verify the unit tests pass with `rake`:
|
191
|
+
|
192
|
+
```
|
193
|
+
$ bundle exec rake
|
194
|
+
```
|
195
|
+
|
196
|
+
If those pass, you're ready to start developing the plugin. You can test
|
197
|
+
the plugin without installing it into your Vagrant environment by just
|
198
|
+
creating a `Vagrantfile` in the top level of this directory (it is gitignored)
|
199
|
+
that uses it. Don't forget to add following line at the beginning of your
|
200
|
+
`Vagrantfile` while in development mode:
|
201
|
+
|
202
|
+
```ruby
|
203
|
+
Vagrant.require_plugin "vagrant-ovirt"
|
204
|
+
```
|
205
|
+
|
206
|
+
Now you can use bundler to execute Vagrant:
|
207
|
+
|
208
|
+
```
|
209
|
+
$ bundle exec vagrant up --provider=ovirt
|
210
|
+
```
|
211
|
+
|
212
|
+
## Contributing
|
213
|
+
|
214
|
+
1. Fork it
|
215
|
+
2. Create your feature branch (`git checkout -b my-new-feature`)
|
216
|
+
3. Commit your changes (`git commit -am 'Add some feature'`)
|
217
|
+
4. Push to the branch (`git push origin my-new-feature`)
|
218
|
+
5. Create new Pull Request
|
219
|
+
|
data/Rakefile
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
# -*- mode: ruby -*-
|
2
|
+
# vi: set ft=ruby :
|
3
|
+
|
4
|
+
Vagrant.configure("2") do |config|
|
5
|
+
config.vm.box = 'ovirt'
|
6
|
+
|
7
|
+
#config.vm.define :test_vm do |test_vm|
|
8
|
+
# test_vm.vm.provider :ovirt do |ovirt|
|
9
|
+
# ovirt.template = "Template name"
|
10
|
+
# ovirt.quota = "Quota name"
|
11
|
+
# ovirt.cpus = 1
|
12
|
+
# ovirt.memory = 512
|
13
|
+
# end
|
14
|
+
#end
|
15
|
+
|
16
|
+
#config.vm.provider :ovirt do |ovirt|
|
17
|
+
# ovirt.url = "https://ovirt.example.com:443"
|
18
|
+
# ovirt.username = "username"
|
19
|
+
# ovirt.password = "secret"
|
20
|
+
# ovirt.datacenter = "Datacenter name"
|
21
|
+
#end
|
22
|
+
end
|
Binary file
|
@@ -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_ovirt::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,96 @@
|
|
1
|
+
require 'log4r'
|
2
|
+
|
3
|
+
module VagrantPlugins
|
4
|
+
module OVirtProvider
|
5
|
+
module Action
|
6
|
+
# Create network interfaces for machine, before VM is running.
|
7
|
+
class CreateNetworkInterfaces
|
8
|
+
|
9
|
+
def initialize(app, env)
|
10
|
+
@logger = Log4r::Logger.new("vagrant_ovirt::action::create_network_interfaces")
|
11
|
+
@app = app
|
12
|
+
end
|
13
|
+
|
14
|
+
def call(env)
|
15
|
+
# Get machine first.
|
16
|
+
begin
|
17
|
+
machine = OVirtProvider::Util::Collection.find_matching(
|
18
|
+
env[:ovirt_compute].servers.all, env[:machine].id.to_s)
|
19
|
+
rescue => e
|
20
|
+
raise Errors::NoVMError,
|
21
|
+
:vm_name => env[:machine].id.to_s
|
22
|
+
end
|
23
|
+
|
24
|
+
# Setup list of interfaces before creating them
|
25
|
+
adapters = []
|
26
|
+
|
27
|
+
# First interface is for provisioning, so this slot is not usable.
|
28
|
+
# This interface should be available already from template.
|
29
|
+
adapters[0] = :reserved
|
30
|
+
|
31
|
+
env[:machine].config.vm.networks.each do |type, options|
|
32
|
+
# Other types than bridged are not supported for now.
|
33
|
+
next if type != :bridged
|
34
|
+
|
35
|
+
network_name = 'rhevm'
|
36
|
+
network_name = options[:bridge] if options[:bridge]
|
37
|
+
|
38
|
+
if options[:adapter]
|
39
|
+
if adapters[options[:adapter]]
|
40
|
+
raise Errors::InterfaceSlotNotAvailable
|
41
|
+
end
|
42
|
+
|
43
|
+
adapters[options[:adapter].to_i] = network_name
|
44
|
+
else
|
45
|
+
empty_slot = find_empty(adapters, start=1)
|
46
|
+
raise Errors::InterfaceSlotNotAvailable if empty_slot == nil
|
47
|
+
|
48
|
+
adapters[empty_slot] = network_name
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
# Create each interface as new domain device
|
53
|
+
adapters.each_with_index do |network_name, slot_number|
|
54
|
+
next if network_name == :reserved
|
55
|
+
iface_number = slot_number + 1
|
56
|
+
|
57
|
+
# Get network id
|
58
|
+
network = OVirtProvider::Util::Collection.find_matching(
|
59
|
+
env[:ovirt_client].networks(:cluster => env[:ovirt_cluster].id),
|
60
|
+
network_name)
|
61
|
+
if network == nil
|
62
|
+
raise Errors::NoNetworkError,
|
63
|
+
:network_name => network_name
|
64
|
+
end
|
65
|
+
|
66
|
+
@logger.info("Creating network interface nic#{iface_number}")
|
67
|
+
begin
|
68
|
+
machine.add_interface(
|
69
|
+
:name => "nic#{iface_number}",
|
70
|
+
:network => network.id,
|
71
|
+
|
72
|
+
# TODO This should be configurable in Vagrantfile.
|
73
|
+
:interface => 'virtio',
|
74
|
+
)
|
75
|
+
rescue => e
|
76
|
+
raise Errors::AddInterfaceError,
|
77
|
+
:error_message => e.message
|
78
|
+
end
|
79
|
+
end
|
80
|
+
|
81
|
+
@app.call(env)
|
82
|
+
end
|
83
|
+
|
84
|
+
private
|
85
|
+
|
86
|
+
def find_empty(array, start=0, stop=8)
|
87
|
+
for i in start..stop
|
88
|
+
return i if !array[i]
|
89
|
+
end
|
90
|
+
return nil
|
91
|
+
end
|
92
|
+
end
|
93
|
+
end
|
94
|
+
end
|
95
|
+
end
|
96
|
+
|
@@ -0,0 +1,114 @@
|
|
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_ovirt::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
|
+
cpus = config.cpus
|
22
|
+
memory_size = config.memory*1024
|
23
|
+
|
24
|
+
# Get cluster
|
25
|
+
if config.cluster == nil
|
26
|
+
cluster = env[:ovirt_compute].clusters.first
|
27
|
+
else
|
28
|
+
cluster = OVirtProvider::Util::Collection.find_matching(
|
29
|
+
env[:ovirt_compute].clusters.all, config.cluster)
|
30
|
+
end
|
31
|
+
raise Error::NoClusterError if cluster == nil
|
32
|
+
# TODO fill env also with other ovirtoptions.
|
33
|
+
env[:ovirt_cluster] = cluster
|
34
|
+
|
35
|
+
# Get template
|
36
|
+
template = OVirtProvider::Util::Collection.find_matching(
|
37
|
+
env[:ovirt_compute].templates.all, config.template)
|
38
|
+
if template == nil
|
39
|
+
raise Error::NoTemplateError,
|
40
|
+
:template_name => config.template
|
41
|
+
end
|
42
|
+
|
43
|
+
# Get quota
|
44
|
+
if config.quota == nil
|
45
|
+
quota = env[:ovirt_client].quotas.first
|
46
|
+
else
|
47
|
+
quota = OVirtProvider::Util::Collection.find_matching(
|
48
|
+
env[:ovirt_client].quotas.all, config.quota)
|
49
|
+
end
|
50
|
+
raise Error::NoQuotaError if quota == nil
|
51
|
+
|
52
|
+
# Output the settings we're going to use to the user
|
53
|
+
env[:ui].info(I18n.t("vagrant_ovirt.creating_vm"))
|
54
|
+
env[:ui].info(" -- Name: #{name}")
|
55
|
+
env[:ui].info(" -- Cpus: #{cpus}")
|
56
|
+
env[:ui].info(" -- Memory: #{memory_size/1024}M")
|
57
|
+
env[:ui].info(" -- Base box: #{env[:machine].box.name}")
|
58
|
+
env[:ui].info(" -- Template: #{template.name}")
|
59
|
+
env[:ui].info(" -- Quota: #{quota.name}")
|
60
|
+
env[:ui].info(" -- Datacenter: #{config.datacenter}")
|
61
|
+
env[:ui].info(" -- Cluster: #{cluster.name}")
|
62
|
+
|
63
|
+
# Create oVirt VM.
|
64
|
+
attr = {
|
65
|
+
:name => name,
|
66
|
+
:cores => cpus,
|
67
|
+
:memory => memory_size*1024,
|
68
|
+
:cluster => cluster.id,
|
69
|
+
:template => template.id,
|
70
|
+
:quota => quota.id,
|
71
|
+
}
|
72
|
+
|
73
|
+
begin
|
74
|
+
server = env[:ovirt_compute].servers.create(attr)
|
75
|
+
rescue OVIRT::OvirtException => e
|
76
|
+
raise Errors::FogCreateServerError,
|
77
|
+
:error_message => e.message
|
78
|
+
end
|
79
|
+
|
80
|
+
# Immediately save the ID since it is created at this point.
|
81
|
+
env[:machine].id = server.id
|
82
|
+
|
83
|
+
# Wait till all volumes are ready.
|
84
|
+
env[:ui].info(I18n.t("vagrant_ovirt.wait_for_ready_vm"))
|
85
|
+
for i in 0..5
|
86
|
+
ready = true
|
87
|
+
server.volumes.each do |volume|
|
88
|
+
if volume.status != 'ok'
|
89
|
+
ready = false
|
90
|
+
break
|
91
|
+
end
|
92
|
+
end
|
93
|
+
break if ready
|
94
|
+
sleep 2
|
95
|
+
end
|
96
|
+
|
97
|
+
@app.call(env)
|
98
|
+
end
|
99
|
+
|
100
|
+
def recover(env)
|
101
|
+
return if env["vagrant.error"].is_a?(Vagrant::Errors::VagrantError)
|
102
|
+
|
103
|
+
# Undo the import
|
104
|
+
env[:ui].info(I18n.t("vagrant_ovirt.error_recovering"))
|
105
|
+
destroy_env = env.dup
|
106
|
+
destroy_env.delete(:interrupted)
|
107
|
+
destroy_env[:config_validate] = false
|
108
|
+
destroy_env[:force_confirm_destroy] = true
|
109
|
+
env[:action_runner].run(Action.action_destroy, destroy_env)
|
110
|
+
end
|
111
|
+
end
|
112
|
+
end
|
113
|
+
end
|
114
|
+
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_ovirt::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_ovirt.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_ovirt.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_ovirt.not_created"))
|
11
|
+
@app.call(env)
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|