opennebula-provider 0.3.0 → 1.0.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/Gemfile +2 -2
- data/README.md +11 -11
- data/lib/opennebula-provider/action.rb +59 -5
- data/lib/opennebula-provider/action/check_state.rb +1 -2
- data/lib/opennebula-provider/action/messages.rb +33 -0
- data/lib/opennebula-provider/action/resume.rb +19 -0
- data/lib/opennebula-provider/action/suspend.rb +19 -0
- data/lib/opennebula-provider/action/wait_for_state.rb +4 -1
- data/lib/opennebula-provider/config.rb +29 -3
- data/lib/opennebula-provider/driver.rb +31 -15
- data/lib/opennebula-provider/helpers/fog.rb +149 -0
- data/lib/opennebula-provider/provider.rb +3 -1
- data/lib/opennebula-provider/version.rb +1 -1
- data/locales/en.yml +31 -9
- data/opennebula-provider.gemspec +2 -1
- metadata +29 -7
- data/lib/opennebula-provider/helpers/rocci.rb +0 -136
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: d54ad5437c3357301e0f52b252dc1eee03103c3d
|
4
|
+
data.tar.gz: f5c1b7451fb8ff82fa58745272f68fc715f94776
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 87d820a1495222852e53775ce75d96828447f3669b749ffdc0d7aadd0388b167af527cdbc215eb0027abdbce1083edabdc20a58de2eabd7b247e751194066c83
|
7
|
+
data.tar.gz: fed987dd54af464b87d82c073955aaacea94f2387cdf8dc1b8eac64b1e261364d37d94ae4473e2146351e89d503c784311ba29f4121c9a24aaf18e00dcd151c7
|
data/Gemfile
CHANGED
data/README.md
CHANGED
@@ -1,11 +1,9 @@
|
|
1
1
|
# OpenNebula::Provider
|
2
2
|
|
3
|
-
[![Gem Version](https://badge.fury.io/rb/opennebula-provider.svg)](https://rubygems.org/gems/opennebula-provider)
|
3
|
+
[![Gem Version](https://badge.fury.io/rb/opennebula-provider.svg)](https://rubygems.org/gems/opennebula-provider)
|
4
4
|
|
5
5
|
This is a Vagrant 1.5+ plugin that add an OpenNebula provider to Vagrant.
|
6
6
|
|
7
|
-
**NOTE:** This plugin requires occi-api gem and works with [rOCCI-server](https://github.com/gwdg/rOCCI-server/).
|
8
|
-
|
9
7
|
## Features
|
10
8
|
|
11
9
|
* Boot OpenNebula instances
|
@@ -33,31 +31,33 @@ Vagrant.configure("2") do |config|
|
|
33
31
|
config.vm.box = "dummy"
|
34
32
|
|
35
33
|
config.vm.provider :opennebula do |one, override|
|
36
|
-
one.endpoint = 'http://
|
34
|
+
one.endpoint = 'http://opennebula.server:2633/RPC2'
|
37
35
|
one.username = 'YOUR NAME'
|
38
36
|
one.password = 'YOUR PASSWORD'
|
39
|
-
one.
|
37
|
+
one.template_id = 123
|
38
|
+
one.title = 'my vm'
|
40
39
|
end
|
41
40
|
end
|
42
41
|
```
|
43
42
|
|
44
43
|
## Configuration
|
45
44
|
|
46
|
-
* `endpoint` -
|
45
|
+
* `endpoint` - OpenNebula RPC endpoint (like 'http://127.0.0.1:2633/RPC2')
|
47
46
|
* `username` - OpenNebula username
|
48
47
|
* `password` - OpenNebula password
|
49
|
-
* `
|
50
|
-
* `os_tpl` - OpenNebula os template
|
51
|
-
* `resource_tpl` - OpenNebula resource template, default: small
|
48
|
+
* `template_id` - OpenNebula template id
|
52
49
|
* `title` - OpenNebula instance name
|
50
|
+
* `memory` - An instance memory in MB
|
51
|
+
* `cpu` - An instance cpus
|
52
|
+
* `vcpu` - An instance virtual cpus
|
53
53
|
|
54
|
-
You can use ONE_USER, ONE_PASSWORD, ONE_ENDPOINT environment variables
|
54
|
+
You can use ONE_USER, ONE_PASSWORD, ONE_XMLRPC (or ONE_ENDPOINT) environment variables
|
55
55
|
instead of defining it in Vagrantfile.
|
56
56
|
However, Vagrantfile's provider config has more priority.
|
57
57
|
|
58
58
|
## Contributing
|
59
59
|
|
60
|
-
1. Fork it
|
60
|
+
1. Fork it
|
61
61
|
2. Create your feature branch (`git checkout -b my-new-feature`)
|
62
62
|
3. Commit your changes (`git commit -am 'Add some feature'`)
|
63
63
|
4. Push to the branch (`git push origin my-new-feature`)
|
@@ -3,9 +3,11 @@ require_relative 'action/create'
|
|
3
3
|
require_relative 'action/destroy'
|
4
4
|
require_relative 'action/messages'
|
5
5
|
require_relative 'action/read_ssh_info'
|
6
|
+
require_relative 'action/resume'
|
6
7
|
require_relative 'action/sync_folders'
|
7
8
|
require_relative 'action/start'
|
8
9
|
require_relative 'action/stop'
|
10
|
+
require_relative 'action/suspend'
|
9
11
|
require_relative 'action/wait_for_state'
|
10
12
|
require_relative 'action/wait_for_ssh'
|
11
13
|
|
@@ -19,7 +21,7 @@ module VagrantPlugins
|
|
19
21
|
b.use ConfigValidate
|
20
22
|
b.use Call, CheckState do |env, b1|
|
21
23
|
case env[:machine_state]
|
22
|
-
when :active, :error, :suspended, :inactive
|
24
|
+
when :active, :error, :suspended, :inactive, :stopped
|
23
25
|
b1.use Call, DestroyConfirm do |env1, b2|
|
24
26
|
if env1[:result]
|
25
27
|
b2.use Destroy
|
@@ -44,11 +46,22 @@ module VagrantPlugins
|
|
44
46
|
when :active
|
45
47
|
b1.use MessageAlreadyCreated
|
46
48
|
when :suspended
|
49
|
+
# TODO: uncomment this with patching fog
|
50
|
+
# b1.use Resume
|
51
|
+
when :stopped
|
47
52
|
b1.use Start
|
48
53
|
when :not_created, :inactive
|
49
54
|
b1.use Create
|
55
|
+
when :error # in state FAILED
|
56
|
+
b1.use MessageInErrorState
|
57
|
+
next
|
58
|
+
end
|
59
|
+
b1.use Call, WaitForState, :active do |env1, b2|
|
60
|
+
if env1[:machine_state] == :error
|
61
|
+
b2.use MessageInErrorState
|
62
|
+
next
|
63
|
+
end
|
50
64
|
end
|
51
|
-
b1.use WaitForState, 'active'
|
52
65
|
end
|
53
66
|
end
|
54
67
|
end
|
@@ -60,8 +73,10 @@ module VagrantPlugins
|
|
60
73
|
case env1[:machine_state]
|
61
74
|
when :active
|
62
75
|
b1.use Stop
|
63
|
-
b1.use WaitForState,
|
76
|
+
b1.use WaitForState, :stopped
|
64
77
|
when :suspended
|
78
|
+
b1.use MessageSuspended
|
79
|
+
when :stopped
|
65
80
|
b1.use MessageAlreadyHalted
|
66
81
|
when :not_created, :inactive
|
67
82
|
b1.use MessageNotCreated
|
@@ -70,6 +85,42 @@ module VagrantPlugins
|
|
70
85
|
end
|
71
86
|
end
|
72
87
|
|
88
|
+
def self.suspend
|
89
|
+
Vagrant::Action::Builder.new.tap do |b|
|
90
|
+
b.use ConfigValidate
|
91
|
+
b.use Call, CheckState do |env1, b1|
|
92
|
+
case env1[:machine_state]
|
93
|
+
when :active
|
94
|
+
# TODO: uncomment this with patching fog
|
95
|
+
# b1.use Suspend
|
96
|
+
# b1.use WaitForState, :suspended
|
97
|
+
when :suspended
|
98
|
+
b1.use MessageAlreadySuspended
|
99
|
+
when :not_created, :inactive
|
100
|
+
b1.use MessageNotCreated
|
101
|
+
end
|
102
|
+
end
|
103
|
+
end
|
104
|
+
end
|
105
|
+
|
106
|
+
def self.resume
|
107
|
+
Vagrant::Action::Builder.new.tap do |b|
|
108
|
+
b.use ConfigValidate
|
109
|
+
b.use Call, CheckState do |env1, b1|
|
110
|
+
case env1[:machine_state]
|
111
|
+
when :suspended
|
112
|
+
# TODO: uncomment this with patching fog
|
113
|
+
# b1.use Resume
|
114
|
+
# b1.use WaitForState, :active
|
115
|
+
when :stopped
|
116
|
+
b1.use MessageHalted
|
117
|
+
when :not_created, :inactive
|
118
|
+
b1.use MessageNotCreated
|
119
|
+
end
|
120
|
+
end
|
121
|
+
end
|
122
|
+
end
|
123
|
+
|
73
124
|
def self.reload
|
74
125
|
Vagrant::Action::Builder.new.tap do |b|
|
75
126
|
b.use ConfigValidate
|
@@ -101,6 +152,8 @@ module VagrantPlugins
|
|
101
152
|
when :not_created, :inactive
|
102
153
|
b1.use MessageNotCreated
|
103
154
|
when :suspended
|
155
|
+
b1.use MessageSuspended
|
156
|
+
when :stopped
|
104
157
|
b1.use MessageHalted
|
105
158
|
else
|
106
159
|
b1.use Provision
|
@@ -112,7 +165,6 @@ module VagrantPlugins
|
|
112
165
|
|
113
166
|
def self.read_ssh_info
|
114
167
|
Vagrant::Action::Builder.new.tap do |b|
|
115
|
-
b.use ConfigValidate
|
116
168
|
b.use ReadSSHInfo
|
117
169
|
end
|
118
170
|
end
|
@@ -125,7 +177,9 @@ module VagrantPlugins
|
|
125
177
|
when :not_created, :inactive
|
126
178
|
b1.use MessageNotCreated
|
127
179
|
when :suspended
|
128
|
-
b1.use
|
180
|
+
b1.use MessageSuspended
|
181
|
+
when :stopped
|
182
|
+
b1.use MessageStopped
|
129
183
|
else
|
130
184
|
b1.use SSHExec
|
131
185
|
end
|
@@ -34,6 +34,17 @@ module VagrantPlugins
|
|
34
34
|
end
|
35
35
|
end
|
36
36
|
|
37
|
+
class MessageAlreadySuspended
|
38
|
+
def initialize(app, env)
|
39
|
+
@app = app
|
40
|
+
end
|
41
|
+
|
42
|
+
def call(env)
|
43
|
+
env[:ui].info I18n.t('opennebula_provider.info.already_suspended')
|
44
|
+
@app.call(env)
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
37
48
|
class MessageNotCreated
|
38
49
|
def initialize(app, env)
|
39
50
|
@app = app
|
@@ -56,6 +67,17 @@ module VagrantPlugins
|
|
56
67
|
end
|
57
68
|
end
|
58
69
|
|
70
|
+
class MessageSuspended
|
71
|
+
def initialize(app, env)
|
72
|
+
@app = app
|
73
|
+
end
|
74
|
+
|
75
|
+
def call(env)
|
76
|
+
env[:ui].info I18n.t('opennebula_provider.info.suspended')
|
77
|
+
@app.call(env)
|
78
|
+
end
|
79
|
+
end
|
80
|
+
|
59
81
|
class MessageHalted
|
60
82
|
def initialize(app, env)
|
61
83
|
@app = app
|
@@ -66,6 +88,17 @@ module VagrantPlugins
|
|
66
88
|
@app.call(env)
|
67
89
|
end
|
68
90
|
end
|
91
|
+
|
92
|
+
class MessageInErrorState
|
93
|
+
def initialize(app, env)
|
94
|
+
@app = app
|
95
|
+
end
|
96
|
+
|
97
|
+
def call(env)
|
98
|
+
env[:ui].info I18n.t('opennebula_provider.info.error')
|
99
|
+
@app.call(env)
|
100
|
+
end
|
101
|
+
end
|
69
102
|
end
|
70
103
|
end
|
71
104
|
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
module VagrantPlugins
|
2
|
+
module OpenNebulaProvider
|
3
|
+
module Action
|
4
|
+
class Resume
|
5
|
+
def initialize(app, env)
|
6
|
+
@app = app
|
7
|
+
@logger = Log4r::Logger.new('vagrant::provider::opennebula::resume')
|
8
|
+
end
|
9
|
+
|
10
|
+
def call(env)
|
11
|
+
env[:ui].info I18n.t('opennebula_provider.info.resume', machine: env[:machine].id)
|
12
|
+
driver = env[:machine].provider.driver
|
13
|
+
driver.resume(env[:machine].id)
|
14
|
+
@app.call(env)
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
module VagrantPlugins
|
2
|
+
module OpenNebulaProvider
|
3
|
+
module Action
|
4
|
+
class Suspend
|
5
|
+
def initialize(app, env)
|
6
|
+
@app = app
|
7
|
+
@logger = Log4r::Logger.new('vagrant::provider::opennebula::suspend')
|
8
|
+
end
|
9
|
+
|
10
|
+
def call(env)
|
11
|
+
env[:ui].info I18n.t('opennebula_provider.info.suspend', machine: env[:machine].id)
|
12
|
+
driver = env[:machine].provider.driver
|
13
|
+
driver.suspend(env[:machine].id)
|
14
|
+
@app.call(env)
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
@@ -10,7 +10,10 @@ module VagrantPlugins
|
|
10
10
|
|
11
11
|
def call(env)
|
12
12
|
driver = env[:machine].provider.driver
|
13
|
-
driver.wait_for_state(env, @state)
|
13
|
+
driver.wait_for_state(env, @state) do |last_state|
|
14
|
+
# env[:machine_state] = last_state.to_sym
|
15
|
+
break if last_state == :error
|
16
|
+
end
|
14
17
|
@app.call(env)
|
15
18
|
end
|
16
19
|
end
|
@@ -5,18 +5,29 @@ module VagrantPlugins
|
|
5
5
|
attr_accessor :auth
|
6
6
|
attr_accessor :username
|
7
7
|
attr_accessor :password
|
8
|
+
attr_accessor :template
|
9
|
+
attr_accessor :template_id
|
10
|
+
attr_accessor :template_name
|
8
11
|
attr_accessor :os_tpl
|
9
12
|
attr_accessor :resource_tpl
|
10
13
|
attr_accessor :title
|
14
|
+
attr_accessor :memory
|
15
|
+
attr_accessor :cpu
|
16
|
+
attr_accessor :vcpu
|
11
17
|
|
12
18
|
def initialize
|
13
|
-
@endpoint = ENV['ONE_ENDPOINT'] || UNSET_VALUE
|
19
|
+
@endpoint = ENV['ONE_XMLRPC'] || ENV['ONE_ENDPOINT'] || UNSET_VALUE
|
14
20
|
@auth = UNSET_VALUE
|
15
21
|
@username = ENV['ONE_USER'] || UNSET_VALUE
|
16
22
|
@password = ENV['ONE_PASSWORD'] || UNSET_VALUE
|
23
|
+
@template_id = UNSET_VALUE
|
24
|
+
@template_name = UNSET_VALUE
|
17
25
|
@os_tpl = UNSET_VALUE
|
18
26
|
@resource_tpl = UNSET_VALUE
|
19
27
|
@title = UNSET_VALUE
|
28
|
+
@memory = UNSET_VALUE
|
29
|
+
@cpu = UNSET_VALUE
|
30
|
+
@vcpu = UNSET_VALUE
|
20
31
|
end
|
21
32
|
|
22
33
|
def finalize!
|
@@ -24,9 +35,23 @@ module VagrantPlugins
|
|
24
35
|
@auth = 'basic' if @auth == UNSET_VALUE
|
25
36
|
@username = nil if @username == UNSET_VALUE
|
26
37
|
@password = nil if @password == UNSET_VALUE
|
27
|
-
@
|
38
|
+
@template_id = nil if @template_id == UNSET_VALUE
|
39
|
+
@template_name = nil if @template_name == UNSET_VALUE
|
40
|
+
if @template_id
|
41
|
+
@template = @template_id
|
42
|
+
elsif @template_name
|
43
|
+
@template = @template_name
|
44
|
+
elsif @template == UNSET_VALUE
|
45
|
+
@template = nil
|
46
|
+
end
|
28
47
|
@resource_tpl = 'small' if @resource_tpl == UNSET_VALUE
|
29
48
|
@title = nil if @title == UNSET_VALUE
|
49
|
+
@memory = nil if @memory == UNSET_VALUE
|
50
|
+
@vcpu = nil if @vcpu == UNSET_VALUE
|
51
|
+
@cpu = nil if @cpu == UNSET_VALUE
|
52
|
+
if @cpu && ! @vcpu
|
53
|
+
@vcpu = @cpu
|
54
|
+
end
|
30
55
|
end
|
31
56
|
|
32
57
|
def validate(machine)
|
@@ -34,7 +59,8 @@ module VagrantPlugins
|
|
34
59
|
errors << I18n.t('opennebula_provider.config.endpoint') unless @endpoint
|
35
60
|
errors << I18n.t('opennebula_provider.config.username') unless @username
|
36
61
|
errors << I18n.t('opennebula_provider.config.password') unless @password
|
37
|
-
errors << I18n.t('opennebula_provider.config.
|
62
|
+
errors << I18n.t('opennebula_provider.config.template') unless @template
|
63
|
+
errors << I18n.t('opennebula_provider.config.title') unless @title
|
38
64
|
|
39
65
|
{ 'OpenNebula provider' => errors }
|
40
66
|
end
|
@@ -1,4 +1,4 @@
|
|
1
|
-
require 'opennebula-provider/helpers/
|
1
|
+
require 'opennebula-provider/helpers/fog'
|
2
2
|
|
3
3
|
module VagrantPlugins
|
4
4
|
module OpenNebulaProvider
|
@@ -6,48 +6,64 @@ module VagrantPlugins
|
|
6
6
|
include Vagrant::Util::Retryable
|
7
7
|
|
8
8
|
def initialize
|
9
|
-
@
|
9
|
+
@fog_driver ||= VagrantPlugins::OpenNebulaProvider::Helpers::FogApi.new
|
10
10
|
end
|
11
11
|
|
12
|
-
def config=(
|
13
|
-
@
|
14
|
-
|
12
|
+
def config=(config)
|
13
|
+
@fog_driver.config = config
|
14
|
+
end
|
15
|
+
|
16
|
+
def provider_config=(provider_config)
|
17
|
+
@fog_driver.provider_config = provider_config
|
18
|
+
end
|
19
|
+
|
20
|
+
def connect
|
21
|
+
@fog_driver.connect
|
15
22
|
end
|
16
23
|
|
17
24
|
def state(cid)
|
18
|
-
@
|
25
|
+
@fog_driver.machine_state(cid)
|
19
26
|
end
|
20
27
|
|
21
28
|
def create
|
22
|
-
@
|
29
|
+
@fog_driver.compute
|
23
30
|
end
|
24
31
|
|
25
32
|
def delete(cid)
|
26
|
-
@
|
33
|
+
@fog_driver.delete(cid)
|
27
34
|
end
|
28
35
|
|
29
36
|
def start(cid)
|
30
|
-
@
|
37
|
+
@fog_driver.start(cid)
|
31
38
|
end
|
32
39
|
|
33
40
|
def stop(cid)
|
34
|
-
@
|
41
|
+
@fog_driver.stop(cid)
|
42
|
+
end
|
43
|
+
|
44
|
+
def suspend(cid)
|
45
|
+
@fog_driver.suspend(cid)
|
46
|
+
end
|
47
|
+
|
48
|
+
def resume(cid)
|
49
|
+
@fog_driver.resume(cid)
|
35
50
|
end
|
36
51
|
|
37
52
|
def ssh_info(cid)
|
38
|
-
@
|
53
|
+
@fog_driver.ssh_info(cid)
|
39
54
|
end
|
40
55
|
|
41
56
|
def wait_for_state(env, state)
|
42
57
|
retryable(tries: 60, sleep: 2) do
|
43
58
|
next if env[:interrupted]
|
44
|
-
|
59
|
+
env[:machine_state] = @fog_driver.machine_state(env[:machine].id)
|
60
|
+
|
61
|
+
yield env[:machine_state] if block_given?
|
45
62
|
|
46
|
-
|
47
|
-
if result != state
|
63
|
+
if env[:machine_state] != state
|
48
64
|
fail Errors::ComputeError,
|
49
65
|
error: "Can not wait when instance will be in '#{state}' status, " \
|
50
|
-
"last status is '#{
|
66
|
+
"last status is '#{env[:machine_state]}'"
|
51
67
|
end
|
52
68
|
end
|
53
69
|
end
|
@@ -0,0 +1,149 @@
|
|
1
|
+
require 'fog'
|
2
|
+
|
3
|
+
module VagrantPlugins
|
4
|
+
module OpenNebulaProvider
|
5
|
+
module Helpers
|
6
|
+
class FogApi
|
7
|
+
attr_accessor :config
|
8
|
+
|
9
|
+
def initialize
|
10
|
+
@logger = Log4r::Logger.new('vagrant::provider::opennebula::helpers::fog')
|
11
|
+
end
|
12
|
+
|
13
|
+
def provider_config=(provider_config)
|
14
|
+
@provider_config = provider_config
|
15
|
+
@options = {
|
16
|
+
provider: 'OpenNebula',
|
17
|
+
opennebula_endpoint: provider_config.endpoint,
|
18
|
+
opennebula_username: provider_config.username,
|
19
|
+
opennebula_password: provider_config.password
|
20
|
+
}
|
21
|
+
end
|
22
|
+
|
23
|
+
def connect
|
24
|
+
@logger = Log4r::Logger.new('vagrant::provider::opennebula::helpers::fog')
|
25
|
+
@logger.info 'Connect to OpenNebula RPC'
|
26
|
+
@fog_client = Fog::Compute.new(@options)
|
27
|
+
rc = @fog_client.client.get_version
|
28
|
+
if rc.is_a?(OpenNebula::Error)
|
29
|
+
case rc.errno
|
30
|
+
when 256
|
31
|
+
raise Errors::AuthError, error: rc.message
|
32
|
+
when 4369
|
33
|
+
raise Errors::ConnectError, error: rc.message
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
def compute
|
39
|
+
@logger.info 'compute!'
|
40
|
+
newvm = @fog_client.servers.new
|
41
|
+
if @provider_config.template_id
|
42
|
+
newvm.flavor = @fog_client.flavors.get @provider_config.template_id
|
43
|
+
elsif @provider_config.template_name
|
44
|
+
newvm.flavor = @fog_client.flavors.get_by_filter({name: @provider_config.template_name})
|
45
|
+
end
|
46
|
+
if newvm.flavor.nil?
|
47
|
+
fail Errors::ComputeError, error: I18n.t('opennebula_provider.compute.template_missing', template: @provider_config.template)
|
48
|
+
end
|
49
|
+
|
50
|
+
newvm.name = @provider_config.title if @provider_config.title
|
51
|
+
if @config.vm.hostname != nil
|
52
|
+
newvm.flavor.context = (newvm.flavor.context).merge({ 'SET_HOSTNAME' => @config.vm.hostname })
|
53
|
+
end
|
54
|
+
newvm.flavor.memory = @provider_config.memory unless @provider_config.memory.nil?
|
55
|
+
newvm.flavor.cpu = @provider_config.cpu unless @provider_config.cpu.nil?
|
56
|
+
newvm.flavor.vcpu = @provider_config.vcpu unless @provider_config.vcpu.nil?
|
57
|
+
vm = newvm.save
|
58
|
+
vm.id
|
59
|
+
rescue RuntimeError => e
|
60
|
+
raise Errors::ComputeError, error: e
|
61
|
+
end
|
62
|
+
|
63
|
+
def stop(id)
|
64
|
+
@logger.info 'stop!'
|
65
|
+
@fog_client.servers.get(id).stop
|
66
|
+
end
|
67
|
+
|
68
|
+
def start(id)
|
69
|
+
@logger.info 'start!'
|
70
|
+
@fog_client.servers.get(id).start
|
71
|
+
end
|
72
|
+
|
73
|
+
def delete(id)
|
74
|
+
@logger.info 'delete!'
|
75
|
+
@fog_client.servers.get(id).destroy
|
76
|
+
end
|
77
|
+
|
78
|
+
def suspend(id)
|
79
|
+
@logger.info 'suspend!'
|
80
|
+
@fog_client.servers.get(id).suspend
|
81
|
+
end
|
82
|
+
|
83
|
+
def resume(id)
|
84
|
+
@logger.info 'resume!'
|
85
|
+
@fog_client.servers.get(id).resume
|
86
|
+
end
|
87
|
+
|
88
|
+
def machine_state(id)
|
89
|
+
if id
|
90
|
+
begin
|
91
|
+
desc = @fog_client.servers.get(id) #state LCM_INIT & RUNNING status 7 && UNDEPLOYED
|
92
|
+
rescue ArgumentError => e
|
93
|
+
raise Errors::ResourceError, error: e
|
94
|
+
end
|
95
|
+
return :not_created if desc.nil?
|
96
|
+
|
97
|
+
return get_pretty_status(desc.state, desc.status)
|
98
|
+
else
|
99
|
+
return :not_created
|
100
|
+
end
|
101
|
+
end
|
102
|
+
|
103
|
+
def ssh_info(id)
|
104
|
+
desc = @fog_client.servers.get(id)
|
105
|
+
desc.ip
|
106
|
+
end
|
107
|
+
|
108
|
+
private
|
109
|
+
def get_pretty_status(state, status)
|
110
|
+
pretty = "#{state}_#{status}"
|
111
|
+
case state
|
112
|
+
when 'LCM_INIT'
|
113
|
+
case status
|
114
|
+
when 1
|
115
|
+
pretty = 'pending'
|
116
|
+
when 4
|
117
|
+
pretty = 'stopped'
|
118
|
+
when 5
|
119
|
+
pretty = 'suspended'
|
120
|
+
when 7
|
121
|
+
pretty = 'error'
|
122
|
+
end
|
123
|
+
when 'PROLOG'
|
124
|
+
case status
|
125
|
+
when 3
|
126
|
+
pretty = 'prolog'
|
127
|
+
end
|
128
|
+
when 'BOOT'
|
129
|
+
case status
|
130
|
+
when 3
|
131
|
+
pretty = 'boot'
|
132
|
+
end
|
133
|
+
when 'RUNNING'
|
134
|
+
case status
|
135
|
+
when 3
|
136
|
+
pretty = 'active'
|
137
|
+
end
|
138
|
+
when 'BOOT_STOPPED_FAILURE'
|
139
|
+
case status
|
140
|
+
when 3
|
141
|
+
pretty = 'error'
|
142
|
+
end
|
143
|
+
end
|
144
|
+
pretty.to_sym
|
145
|
+
end
|
146
|
+
end
|
147
|
+
end
|
148
|
+
end
|
149
|
+
end
|
@@ -16,7 +16,9 @@ module VagrantPlugins
|
|
16
16
|
def driver
|
17
17
|
return @driver if @driver
|
18
18
|
@driver = Driver.new
|
19
|
-
@driver.config = @machine.
|
19
|
+
@driver.config = @machine.config
|
20
|
+
@driver.provider_config = @machine.provider_config
|
21
|
+
@driver.connect
|
20
22
|
|
21
23
|
@driver
|
22
24
|
end
|
data/locales/en.yml
CHANGED
@@ -8,11 +8,13 @@ en:
|
|
8
8
|
not_created: |-
|
9
9
|
Instance is not created
|
10
10
|
already_created: |-
|
11
|
-
Instance already created
|
11
|
+
Instance is already created
|
12
12
|
already_destroyed: |-
|
13
|
-
Instance already destroyed
|
13
|
+
Instance is already destroyed
|
14
14
|
already_halted: |-
|
15
|
-
Instance already halted
|
15
|
+
Instance is already halted
|
16
|
+
already_suspended: |-
|
17
|
+
Instance is already suspended
|
16
18
|
destroying: |-
|
17
19
|
Instance %{machine} is destroying...
|
18
20
|
will_not_destroy: |-
|
@@ -25,6 +27,12 @@ en:
|
|
25
27
|
Instance is halted
|
26
28
|
start: |-
|
27
29
|
Starting the instance...
|
30
|
+
suspend: |-
|
31
|
+
Instance is suspending...
|
32
|
+
suspended: |-
|
33
|
+
Instance is suspended
|
34
|
+
resume: |-
|
35
|
+
Resuming instance...
|
28
36
|
waiting_for_sshd: |-
|
29
37
|
Instance is active, waiting for sshd daemon startup...
|
30
38
|
rsyncing: |-
|
@@ -32,6 +40,8 @@ en:
|
|
32
40
|
rsync_not_found_warning: |-
|
33
41
|
Warning! Folder sync disabled because the rsync binary is missing in the %{side}.
|
34
42
|
Make sure rsync is installed and the binary can be found in the PATH.
|
43
|
+
error: |-
|
44
|
+
The instance is in error state
|
35
45
|
|
36
46
|
states:
|
37
47
|
short_not_created: |-
|
@@ -62,12 +72,22 @@ en:
|
|
62
72
|
short_error: |-
|
63
73
|
error
|
64
74
|
long_error: |-
|
65
|
-
The OpenNebula instance
|
75
|
+
The OpenNebula instance is can not start
|
76
|
+
|
77
|
+
short_stopped: |-
|
78
|
+
stopped
|
79
|
+
long_stopped: |-
|
80
|
+
The OpenNebula instance is in stopped state (halted)
|
66
81
|
|
67
82
|
short_suspended: |-
|
68
83
|
suspended
|
69
84
|
long_suspended: |-
|
70
|
-
The OpenNebula instance is suspended
|
85
|
+
The OpenNebula instance is suspended
|
86
|
+
|
87
|
+
short_LCM_INIT_7: |-
|
88
|
+
FAILED
|
89
|
+
long_LCM_INIT_7: |-
|
90
|
+
The OpenNebula instance is in FAILED state
|
71
91
|
|
72
92
|
config:
|
73
93
|
endpoint: |-
|
@@ -76,12 +96,14 @@ en:
|
|
76
96
|
Username is not set
|
77
97
|
password: |-
|
78
98
|
Password is not set
|
79
|
-
|
80
|
-
An
|
99
|
+
template: |-
|
100
|
+
An template must defined via "template_id" or "template_name"
|
101
|
+
title: |-
|
102
|
+
VM title is not set
|
81
103
|
|
82
104
|
compute:
|
83
|
-
|
84
|
-
|
105
|
+
template_missing: |-
|
106
|
+
Template "%{template}" is not defined in OpenNebula
|
85
107
|
resource_size_missing: |-
|
86
108
|
Resource size "%{template}" is not defined in rOCCI-server
|
87
109
|
|
data/opennebula-provider.gemspec
CHANGED
@@ -44,7 +44,8 @@ Gem::Specification.new do |spec|
|
|
44
44
|
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
|
45
45
|
spec.require_paths = ["lib"]
|
46
46
|
|
47
|
-
spec.add_runtime_dependency '
|
47
|
+
spec.add_runtime_dependency 'opennebula', '~> 4.14'
|
48
|
+
spec.add_runtime_dependency 'fog', '~> 1.38', '>= 1.38.0'
|
48
49
|
|
49
50
|
spec.add_development_dependency 'bundler', '~> 1.3'
|
50
51
|
spec.add_development_dependency 'rake', '~> 0'
|
metadata
CHANGED
@@ -1,29 +1,49 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: opennebula-provider
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 1.0.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Cherdancev Evgeni
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2016-06-20 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
|
-
name:
|
14
|
+
name: opennebula
|
15
15
|
requirement: !ruby/object:Gem::Requirement
|
16
16
|
requirements:
|
17
17
|
- - "~>"
|
18
18
|
- !ruby/object:Gem::Version
|
19
|
-
version: '4.
|
19
|
+
version: '4.14'
|
20
20
|
type: :runtime
|
21
21
|
prerelease: false
|
22
22
|
version_requirements: !ruby/object:Gem::Requirement
|
23
23
|
requirements:
|
24
24
|
- - "~>"
|
25
25
|
- !ruby/object:Gem::Version
|
26
|
-
version: '4.
|
26
|
+
version: '4.14'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: fog
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - "~>"
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '1.38'
|
34
|
+
- - ">="
|
35
|
+
- !ruby/object:Gem::Version
|
36
|
+
version: 1.38.0
|
37
|
+
type: :runtime
|
38
|
+
prerelease: false
|
39
|
+
version_requirements: !ruby/object:Gem::Requirement
|
40
|
+
requirements:
|
41
|
+
- - "~>"
|
42
|
+
- !ruby/object:Gem::Version
|
43
|
+
version: '1.38'
|
44
|
+
- - ">="
|
45
|
+
- !ruby/object:Gem::Version
|
46
|
+
version: 1.38.0
|
27
47
|
- !ruby/object:Gem::Dependency
|
28
48
|
name: bundler
|
29
49
|
requirement: !ruby/object:Gem::Requirement
|
@@ -88,15 +108,17 @@ files:
|
|
88
108
|
- lib/opennebula-provider/action/destroy.rb
|
89
109
|
- lib/opennebula-provider/action/messages.rb
|
90
110
|
- lib/opennebula-provider/action/read_ssh_info.rb
|
111
|
+
- lib/opennebula-provider/action/resume.rb
|
91
112
|
- lib/opennebula-provider/action/start.rb
|
92
113
|
- lib/opennebula-provider/action/stop.rb
|
114
|
+
- lib/opennebula-provider/action/suspend.rb
|
93
115
|
- lib/opennebula-provider/action/sync_folders.rb
|
94
116
|
- lib/opennebula-provider/action/wait_for_ssh.rb
|
95
117
|
- lib/opennebula-provider/action/wait_for_state.rb
|
96
118
|
- lib/opennebula-provider/config.rb
|
97
119
|
- lib/opennebula-provider/driver.rb
|
98
120
|
- lib/opennebula-provider/errors.rb
|
99
|
-
- lib/opennebula-provider/helpers/
|
121
|
+
- lib/opennebula-provider/helpers/fog.rb
|
100
122
|
- lib/opennebula-provider/plugin.rb
|
101
123
|
- lib/opennebula-provider/provider.rb
|
102
124
|
- lib/opennebula-provider/version.rb
|
@@ -122,7 +144,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
122
144
|
version: '0'
|
123
145
|
requirements: []
|
124
146
|
rubyforge_project:
|
125
|
-
rubygems_version: 2.
|
147
|
+
rubygems_version: 2.4.8
|
126
148
|
signing_key:
|
127
149
|
specification_version: 4
|
128
150
|
summary: OpenNebula provider for Vagrant
|
@@ -1,136 +0,0 @@
|
|
1
|
-
require 'occi-api'
|
2
|
-
|
3
|
-
module VagrantPlugins
|
4
|
-
module OpenNebulaProvider
|
5
|
-
module Helpers
|
6
|
-
class RocciApi
|
7
|
-
def initialize
|
8
|
-
@logger = Log4r::Logger.new('vagrant::provider::opennebula::helpers::rocciapi')
|
9
|
-
end
|
10
|
-
|
11
|
-
def fill_config(provider_config)
|
12
|
-
@logger = Log4r::Logger.new('vagrant::provider::opennebula::helpers::rocciapi')
|
13
|
-
@config = provider_config
|
14
|
-
@options = {
|
15
|
-
endpoint: provider_config.endpoint,
|
16
|
-
auth: {
|
17
|
-
type: provider_config.auth,
|
18
|
-
username: provider_config.username,
|
19
|
-
password: provider_config.password
|
20
|
-
}
|
21
|
-
# :log => {
|
22
|
-
# :out => STDERR,
|
23
|
-
# :level => Occi::Api::Log::DEBUG
|
24
|
-
# }
|
25
|
-
}
|
26
|
-
end
|
27
|
-
|
28
|
-
def connect
|
29
|
-
@logger = Log4r::Logger.new('vagrant::provider::opennebula::helpers::rocciapi')
|
30
|
-
@logger.info 'Connect to RocciServer'
|
31
|
-
begin
|
32
|
-
@rocci = Occi::Api::Client::ClientHttp.new(@options)
|
33
|
-
rescue Errno::ECONNREFUSED => e
|
34
|
-
raise Errors::ConnectError, error: e
|
35
|
-
rescue Occi::Api::Client::Errors::AuthnError => e
|
36
|
-
raise Errors::AuthError, error: e
|
37
|
-
end
|
38
|
-
end
|
39
|
-
|
40
|
-
def compute
|
41
|
-
@logger.info 'compute!'
|
42
|
-
cmpt = @rocci.get_resource 'compute'
|
43
|
-
|
44
|
-
os = @rocci.get_mixin @config.os_tpl, 'os_tpl'
|
45
|
-
unless os
|
46
|
-
mixins = @rocci.get_mixins 'os_tpl'
|
47
|
-
mixins.each do |mixin|
|
48
|
-
if mixin.title == @config.os_tpl
|
49
|
-
os = @rocci.get_mixin mixin.term, 'os_tpl'
|
50
|
-
end
|
51
|
-
end
|
52
|
-
fail Errors::ComputeError, error: I18n.t('opennebula_provider.compute.os_missing', template: @config.os_tpl) unless os
|
53
|
-
end
|
54
|
-
|
55
|
-
size = @rocci.get_mixin @config.resource_tpl, 'resource_tpl'
|
56
|
-
unless size
|
57
|
-
fail Errors::ComputeError, error: I18n.t('opennebula_provider.compute.resource_size_missing', template: @config.resource_tpl)
|
58
|
-
end
|
59
|
-
|
60
|
-
cmpt.mixins << os << size
|
61
|
-
cmpt.title = @config.title if @config.title
|
62
|
-
cmpt_loc = @rocci.create cmpt
|
63
|
-
@logger.info "Location of new compute resource: #{cmpt_loc}"
|
64
|
-
cmpt_loc
|
65
|
-
rescue RuntimeError => e
|
66
|
-
case e.message
|
67
|
-
when /(?<ms>\[VirtualMachineAllocate\])/
|
68
|
-
message_scope = $LAST_MATCH_INFO[:ms]
|
69
|
-
case e.message
|
70
|
-
when /quota/
|
71
|
-
raise Errors::QuotaError, error: e.message.split(message_scope)[1].to_s
|
72
|
-
else
|
73
|
-
raise Errors::AllocateError, error: e
|
74
|
-
end
|
75
|
-
end
|
76
|
-
raise Errors::ComputeError, error: e
|
77
|
-
end
|
78
|
-
|
79
|
-
def stop(id)
|
80
|
-
@logger.info 'stop!'
|
81
|
-
@rocci.trigger id, action_instance(id, 'stop')
|
82
|
-
end
|
83
|
-
|
84
|
-
def start(id)
|
85
|
-
@logger.info 'start!'
|
86
|
-
@rocci.trigger id, action_instance(id, 'start')
|
87
|
-
end
|
88
|
-
|
89
|
-
def delete(id)
|
90
|
-
@logger.info 'delete!'
|
91
|
-
@rocci.delete id
|
92
|
-
end
|
93
|
-
|
94
|
-
def machine_state(id)
|
95
|
-
if id
|
96
|
-
begin
|
97
|
-
desc = @rocci.describe id
|
98
|
-
rescue ArgumentError => e
|
99
|
-
raise Errors::ResourceError, error: e
|
100
|
-
end
|
101
|
-
return :not_created if desc.empty?
|
102
|
-
return desc.first.attributes.occi.compute.state
|
103
|
-
else
|
104
|
-
return :not_created
|
105
|
-
end
|
106
|
-
end
|
107
|
-
|
108
|
-
def ssh_info(id)
|
109
|
-
desc = describe_resource(id)
|
110
|
-
networkinterface = desc.first.links.map do |link|
|
111
|
-
if link.attributes.occi.key?(:networkinterface)
|
112
|
-
link.attributes.occi.networkinterface
|
113
|
-
else
|
114
|
-
nil
|
115
|
-
end
|
116
|
-
end.reject! { |n| n.nil? }.first
|
117
|
-
networkinterface[:address]
|
118
|
-
end
|
119
|
-
|
120
|
-
private
|
121
|
-
|
122
|
-
def action_instance(id, action)
|
123
|
-
desc = describe_resource(id)
|
124
|
-
action_ = desc.first.actions.map do |ai|
|
125
|
-
ai.term == action ? ai : nil
|
126
|
-
end.compact.first
|
127
|
-
Occi::Core::ActionInstance.new action_, nil
|
128
|
-
end
|
129
|
-
|
130
|
-
def describe_resource(resource)
|
131
|
-
@rocci.describe resource
|
132
|
-
end
|
133
|
-
end
|
134
|
-
end
|
135
|
-
end
|
136
|
-
end
|