opennebula-provider 0.3.0 → 1.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.
- 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
|
-
[](https://rubygems.org/gems/opennebula-provider)
|
3
|
+
[](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
|