vagrant-ovirt 0.0.1
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.
- 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
|