vagrant-openstack-provider 0.1.2 → 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +13 -5
- data/.rubocop.yml +28 -0
- data/Appraisals +3 -3
- data/CHANGELOG.md +4 -0
- data/Gemfile +3 -0
- data/Rakefile +6 -2
- data/Vagrantfile +4 -15
- data/gemfiles/latest_stable.gemfile +2 -0
- data/gemfiles/oldest_current.gemfile +2 -0
- data/gemfiles/previous_release.gemfile +2 -0
- data/lib/vagrant-openstack-provider.rb +18 -13
- data/lib/vagrant-openstack-provider/action.rb +112 -46
- data/lib/vagrant-openstack-provider/action/connect_openstack.rb +9 -10
- data/lib/vagrant-openstack-provider/action/create_server.rb +86 -57
- data/lib/vagrant-openstack-provider/action/delete_server.rb +5 -6
- data/lib/vagrant-openstack-provider/action/{is_created.rb → message.rb} +4 -3
- data/lib/vagrant-openstack-provider/action/read_ssh_info.rb +7 -27
- data/lib/vagrant-openstack-provider/action/read_state.rb +7 -9
- data/lib/vagrant-openstack-provider/action/resume.rb +20 -0
- data/lib/vagrant-openstack-provider/action/start_server.rb +22 -0
- data/lib/vagrant-openstack-provider/action/stop_server.rb +22 -0
- data/lib/vagrant-openstack-provider/action/suspend.rb +20 -0
- data/lib/vagrant-openstack-provider/action/sync_folders.rb +27 -38
- data/lib/vagrant-openstack-provider/action/wait_stop.rb +29 -0
- data/lib/vagrant-openstack-provider/client/keystone.rb +76 -0
- data/lib/vagrant-openstack-provider/client/neutron.rb +32 -0
- data/lib/vagrant-openstack-provider/client/nova.rb +166 -0
- data/lib/vagrant-openstack-provider/client/openstack.rb +41 -0
- data/lib/vagrant-openstack-provider/client/utils.rb +38 -0
- data/lib/vagrant-openstack-provider/config.rb +38 -110
- data/lib/vagrant-openstack-provider/errors.rb +7 -3
- data/lib/vagrant-openstack-provider/plugin.rb +8 -8
- data/lib/vagrant-openstack-provider/provider.rb +6 -6
- data/lib/vagrant-openstack-provider/version.rb +1 -1
- data/locales/en.yml +83 -5
- data/numergyrc +22 -0
- data/spec/vagrant-openstack-provider/action/create_server_spec.rb +89 -0
- data/spec/vagrant-openstack-provider/client/keystone_spec.rb +140 -0
- data/spec/vagrant-openstack-provider/client/neutron_spec.rb +53 -0
- data/spec/vagrant-openstack-provider/client/nova_spec.rb +373 -0
- data/spec/vagrant-openstack-provider/client/utils_spec.rb +125 -0
- data/spec/vagrant-openstack-provider/config_spec.rb +117 -0
- data/spec/vagrant-openstack-provider/provider_spec.rb +13 -0
- data/spec/vagrant-openstack-provider/spec_helper.rb +23 -0
- data/vagrant-openstack-provider.gemspec +13 -14
- metadata +40 -30
- data/features/provision.feature +0 -35
- data/features/steps/sdk_steps.rb +0 -13
- data/features/steps/server_steps.rb +0 -25
- data/features/support/env.rb +0 -37
- data/features/support/fog_mock.rb +0 -19
- data/features/vagrant-openstack-provider.feature +0 -70
- data/lib/vagrant-openstack-provider/action/message_already_created.rb +0 -16
- data/lib/vagrant-openstack-provider/action/message_not_created.rb +0 -16
- data/lib/vagrant-openstack-provider/openstack_client.rb +0 -98
- data/spec/vagrant-openstack/config_spec.rb +0 -184
- data/stackrc +0 -31
@@ -1,7 +1,8 @@
|
|
1
|
-
require
|
2
|
-
require
|
3
|
-
require
|
4
|
-
|
1
|
+
require 'log4r'
|
2
|
+
require 'restclient'
|
3
|
+
require 'json'
|
4
|
+
|
5
|
+
require 'vagrant-openstack-provider/client/openstack'
|
5
6
|
|
6
7
|
module VagrantPlugins
|
7
8
|
module Openstack
|
@@ -10,17 +11,15 @@ module VagrantPlugins
|
|
10
11
|
# puts the Openstack connection object into the `:openstack_compute` key
|
11
12
|
# in the environment.
|
12
13
|
class ConnectOpenstack
|
13
|
-
def initialize(app,
|
14
|
+
def initialize(app, _env)
|
14
15
|
@app = app
|
15
|
-
@logger = Log4r::Logger.new(
|
16
|
+
@logger = Log4r::Logger.new('vagrant_openstack::action::connect_openstack')
|
16
17
|
end
|
17
18
|
|
18
19
|
def call(env)
|
19
|
-
|
20
|
-
config = env[:machine].provider_config
|
21
|
-
client = OpenstackClient::new()
|
20
|
+
client = VagrantPlugins::Openstack
|
22
21
|
env[:openstack_client] = client
|
23
|
-
client.authenticate(env)
|
22
|
+
client.keystone.authenticate(env) if client.session.token.nil?
|
24
23
|
@app.call(env)
|
25
24
|
end
|
26
25
|
end
|
@@ -1,6 +1,6 @@
|
|
1
|
-
require
|
1
|
+
require 'log4r'
|
2
2
|
require 'socket'
|
3
|
-
require
|
3
|
+
require 'timeout'
|
4
4
|
|
5
5
|
require 'vagrant/util/retryable'
|
6
6
|
|
@@ -10,108 +10,137 @@ module VagrantPlugins
|
|
10
10
|
class CreateServer
|
11
11
|
include Vagrant::Util::Retryable
|
12
12
|
|
13
|
-
def initialize(app,
|
13
|
+
def initialize(app, _env)
|
14
14
|
@app = app
|
15
|
-
@logger = Log4r::Logger.new(
|
15
|
+
@logger = Log4r::Logger.new('vagrant_openstack::action::create_server')
|
16
16
|
end
|
17
17
|
|
18
18
|
def call(env)
|
19
19
|
config = env[:machine].provider_config
|
20
|
-
|
20
|
+
nova = env[:openstack_client].nova
|
21
21
|
|
22
|
-
|
23
|
-
env
|
24
|
-
|
25
|
-
flavor = find_matching(flavors, config.flavor)
|
26
|
-
raise Errors::NoMatchingFlavor if !flavor
|
27
|
-
|
28
|
-
# Find the image
|
29
|
-
env[:ui].info(I18n.t("vagrant_openstack.finding_image"))
|
30
|
-
images = client.get_all_images(env)
|
31
|
-
image = find_matching(images, config.image)
|
32
|
-
raise Errors::NoMatchingImage if !image
|
33
|
-
|
34
|
-
# Figure out the name for the server
|
22
|
+
flavor = resolve_flavor(env)
|
23
|
+
image = resolve_image(env)
|
24
|
+
networks = resolve_networks(env)
|
35
25
|
server_name = config.server_name || env[:machine].name
|
36
26
|
|
37
|
-
|
38
|
-
env[:ui].info(
|
39
|
-
env[:ui].info(" --
|
40
|
-
env[:ui].info(" --
|
41
|
-
env[:ui].info(" --
|
42
|
-
env[:ui].info(" --
|
43
|
-
env[:ui].info(" -- ImageRef
|
44
|
-
env[:ui].info(" --
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
server_id =
|
54
|
-
|
55
|
-
#TODO(julienvey) Find a network if provided
|
56
|
-
#if config.network
|
57
|
-
# network = find_matching(env[:openstack_network].networks, config.network)
|
58
|
-
# options[:nics] = [{"net_id" => network.id}] if network
|
59
|
-
#end
|
27
|
+
env[:ui].info(I18n.t('vagrant_openstack.launching_server'))
|
28
|
+
env[:ui].info(" -- Tenant : #{config.tenant_name}")
|
29
|
+
env[:ui].info(" -- Name : #{server_name}")
|
30
|
+
env[:ui].info(" -- Flavor : #{flavor.name}")
|
31
|
+
env[:ui].info(" -- FlavorRef : #{flavor.id}")
|
32
|
+
env[:ui].info(" -- Image : #{image.name}")
|
33
|
+
env[:ui].info(" -- ImageRef : #{image.id}")
|
34
|
+
env[:ui].info(" -- KeyPair : #{config.keypair_name}")
|
35
|
+
unless networks.empty?
|
36
|
+
if networks.size == 1
|
37
|
+
env[:ui].info(" -- Network : #{config.networks[0]}")
|
38
|
+
else
|
39
|
+
env[:ui].info(" -- Networks : #{config.networks}")
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
server_id = nova.create_server(env, server_name, image.id, flavor.id, networks, config.keypair_name)
|
60
44
|
|
61
45
|
# Store the ID right away so we can track it
|
62
46
|
env[:machine].id = server_id
|
63
47
|
|
64
48
|
# Wait for the server to finish building
|
65
|
-
env[:ui].info(I18n.t(
|
49
|
+
env[:ui].info(I18n.t('vagrant_openstack.waiting_for_build'))
|
66
50
|
timeout(200) do
|
67
|
-
while
|
51
|
+
while nova.get_server_details(env, server_id)['status'] != 'ACTIVE'
|
68
52
|
sleep 3
|
69
|
-
@logger.debug(
|
53
|
+
@logger.debug('Waiting for server to be ACTIVE')
|
70
54
|
end
|
71
55
|
end
|
72
56
|
|
73
57
|
if config.floating_ip
|
74
58
|
env[:ui].info("Using floating IP #{config.floating_ip}")
|
75
|
-
|
59
|
+
nova.add_floating_ip(env, server_id, config.floating_ip)
|
76
60
|
end
|
77
61
|
|
78
|
-
|
62
|
+
unless env[:interrupted]
|
79
63
|
# Clear the line one more time so the progress is removed
|
80
64
|
env[:ui].clear_line
|
81
65
|
|
82
66
|
# Wait for SSH to become available
|
83
67
|
host = env[:machine].provider_config.floating_ip
|
84
68
|
ssh_timeout = env[:machine].provider_config.ssh_timeout
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
raise Errors::SshUnavailable,
|
89
|
-
:host => host,
|
90
|
-
:timeout => ssh_timeout
|
69
|
+
unless port_open?(env, host, 22, ssh_timeout)
|
70
|
+
env[:ui].error(I18n.t('vagrant_openstack.timeout'))
|
71
|
+
fail Errors::SshUnavailable, host: host, timeout: ssh_timeout
|
91
72
|
end
|
92
73
|
|
93
|
-
env[:ui].info(I18n.t(
|
74
|
+
env[:ui].info(I18n.t('vagrant_openstack.ready'))
|
94
75
|
end
|
95
76
|
|
96
77
|
@app.call(env)
|
97
78
|
end
|
98
79
|
|
99
|
-
|
80
|
+
private
|
81
|
+
|
82
|
+
def resolve_flavor(env)
|
83
|
+
config = env[:machine].provider_config
|
84
|
+
nova = env[:openstack_client].nova
|
85
|
+
env[:ui].info(I18n.t('vagrant_openstack.finding_flavor'))
|
86
|
+
flavors = nova.get_all_flavors(env)
|
87
|
+
flavor = find_matching(flavors, config.flavor)
|
88
|
+
fail Errors::NoMatchingFlavor unless flavor
|
89
|
+
flavor
|
90
|
+
end
|
91
|
+
|
92
|
+
def resolve_image(env)
|
93
|
+
config = env[:machine].provider_config
|
94
|
+
nova = env[:openstack_client].nova
|
95
|
+
env[:ui].info(I18n.t('vagrant_openstack.finding_image'))
|
96
|
+
images = nova.get_all_images(env)
|
97
|
+
image = find_matching(images, config.image)
|
98
|
+
fail Errors::NoMatchingImage unless image
|
99
|
+
image
|
100
|
+
end
|
101
|
+
|
102
|
+
def resolve_networks(env)
|
103
|
+
config = env[:machine].provider_config
|
104
|
+
return [] if config.networks.nil? || config.networks.empty?
|
105
|
+
env[:ui].info(I18n.t('vagrant_openstack.finding_networks'))
|
106
|
+
|
107
|
+
private_networks = env[:openstack_client].neutron.get_private_networks(env)
|
108
|
+
private_network_ids = private_networks.map { |n| n[:id] }
|
109
|
+
|
110
|
+
networks = []
|
111
|
+
config.networks.each do |network|
|
112
|
+
if private_network_ids.include?(network)
|
113
|
+
networks << network
|
114
|
+
next
|
115
|
+
end
|
116
|
+
net_id = nil
|
117
|
+
private_networks.each do |n| # Bad algorithm complexity, but here we don't care...
|
118
|
+
next unless n[:name].eql? network
|
119
|
+
fail "Multiple networks with name '#{n[:name]}'" unless net_id.nil?
|
120
|
+
net_id = n[:id]
|
121
|
+
end
|
122
|
+
fail "No matching network with name '#{network}'" if net_id.nil?
|
123
|
+
networks << net_id
|
124
|
+
end
|
125
|
+
networks
|
126
|
+
end
|
100
127
|
|
101
128
|
def port_open?(env, ip, port, timeout)
|
102
129
|
start_time = Time.now
|
103
130
|
current_time = start_time
|
131
|
+
nb_retry = 0
|
104
132
|
while (current_time - start_time) <= timeout
|
105
133
|
begin
|
106
|
-
env[:ui].info(I18n.t(
|
134
|
+
env[:ui].info(I18n.t('vagrant_openstack.waiting_for_ssh')) if nb_retry % 5 == 0
|
107
135
|
TCPSocket.new(ip, port)
|
108
136
|
return true
|
109
|
-
rescue Errno::ECONNREFUSED, Errno::EHOSTUNREACH
|
137
|
+
rescue Errno::ECONNREFUSED, Errno::EHOSTUNREACH, Errno::ETIMEDOUT
|
138
|
+
nb_retry += 1
|
110
139
|
sleep 1
|
111
140
|
end
|
112
141
|
current_time = Time.now
|
113
142
|
end
|
114
|
-
|
143
|
+
false
|
115
144
|
end
|
116
145
|
|
117
146
|
# This method finds a matching _thing_ in a collection of
|
@@ -1,20 +1,19 @@
|
|
1
|
-
require
|
1
|
+
require 'log4r'
|
2
2
|
|
3
3
|
module VagrantPlugins
|
4
4
|
module Openstack
|
5
5
|
module Action
|
6
6
|
# This deletes the running server, if there is one.
|
7
7
|
class DeleteServer
|
8
|
-
def initialize(app,
|
8
|
+
def initialize(app, _env)
|
9
9
|
@app = app
|
10
|
-
@logger = Log4r::Logger.new(
|
10
|
+
@logger = Log4r::Logger.new('vagrant_openstack::action::delete_server')
|
11
11
|
end
|
12
12
|
|
13
13
|
def call(env)
|
14
14
|
if env[:machine].id
|
15
|
-
env[:ui].info(I18n.t(
|
16
|
-
|
17
|
-
client.delete_server(env, env[:machine].id)
|
15
|
+
env[:ui].info(I18n.t('vagrant_openstack.deleting_server'))
|
16
|
+
env[:openstack_client].nova.delete_server(env, env[:machine].id)
|
18
17
|
env[:machine].id = nil
|
19
18
|
end
|
20
19
|
|
@@ -1,13 +1,14 @@
|
|
1
1
|
module VagrantPlugins
|
2
2
|
module Openstack
|
3
3
|
module Action
|
4
|
-
class
|
5
|
-
def initialize(app,
|
4
|
+
class Message
|
5
|
+
def initialize(app, _env, message)
|
6
6
|
@app = app
|
7
|
+
@message = message
|
7
8
|
end
|
8
9
|
|
9
10
|
def call(env)
|
10
|
-
env[:
|
11
|
+
env[:ui].info(@message)
|
11
12
|
@app.call(env)
|
12
13
|
end
|
13
14
|
end
|
@@ -1,4 +1,4 @@
|
|
1
|
-
require
|
1
|
+
require 'log4r'
|
2
2
|
|
3
3
|
module VagrantPlugins
|
4
4
|
module Openstack
|
@@ -6,9 +6,9 @@ module VagrantPlugins
|
|
6
6
|
# This action reads the SSH info for the machine and puts it into the
|
7
7
|
# `:machine_ssh_info` key in the environment.
|
8
8
|
class ReadSSHInfo
|
9
|
-
def initialize(app,
|
9
|
+
def initialize(app, _env)
|
10
10
|
@app = app
|
11
|
-
@logger = Log4r::Logger.new(
|
11
|
+
@logger = Log4r::Logger.new('vagrant_openstack::action::read_ssh_info')
|
12
12
|
end
|
13
13
|
|
14
14
|
def call(env)
|
@@ -18,32 +18,12 @@ module VagrantPlugins
|
|
18
18
|
end
|
19
19
|
|
20
20
|
def read_ssh_info(env)
|
21
|
-
client = env[:openstack_client]
|
22
|
-
machine = env[:machine]
|
23
21
|
config = env[:machine].provider_config
|
24
|
-
|
25
|
-
return nil if machine.id.nil?
|
26
|
-
begin
|
27
|
-
details = client.get_server_details(env, machine.id)
|
28
|
-
rescue Exception => e
|
29
|
-
# The machine can't be found
|
30
|
-
@logger.error(e)
|
31
|
-
@logger.info("Machine couldn't be found, assuming it got destroyed.")
|
32
|
-
machine.id = nil
|
33
|
-
return nil
|
34
|
-
end
|
35
|
-
|
36
|
-
for addr in details['addresses']['private']
|
37
|
-
if addr['OS-EXT-IPS:type'] == 'floating'
|
38
|
-
host = addr['addr']
|
39
|
-
end
|
40
|
-
end
|
41
|
-
|
42
|
-
return {
|
22
|
+
{
|
43
23
|
# Usually there should only be one public IP
|
44
|
-
:
|
45
|
-
:
|
46
|
-
:
|
24
|
+
host: config.floating_ip,
|
25
|
+
port: 22,
|
26
|
+
username: config.ssh_username
|
47
27
|
}
|
48
28
|
end
|
49
29
|
end
|
@@ -1,4 +1,4 @@
|
|
1
|
-
require
|
1
|
+
require 'log4r'
|
2
2
|
|
3
3
|
module VagrantPlugins
|
4
4
|
module Openstack
|
@@ -6,33 +6,31 @@ module VagrantPlugins
|
|
6
6
|
# This action reads the state of the machine and puts it in the
|
7
7
|
# `:machine_state_id` key in the environment.
|
8
8
|
class ReadState
|
9
|
-
def initialize(app,
|
9
|
+
def initialize(app, _env)
|
10
10
|
@app = app
|
11
|
-
@logger = Log4r::Logger.new(
|
11
|
+
@logger = Log4r::Logger.new('vagrant_openstack::action::read_state')
|
12
12
|
end
|
13
13
|
|
14
14
|
def call(env)
|
15
15
|
env[:machine_state_id] = read_state(env)
|
16
|
-
|
17
16
|
@app.call(env)
|
18
17
|
end
|
19
18
|
|
20
19
|
def read_state(env)
|
21
20
|
machine = env[:machine]
|
22
|
-
client = env[:openstack_client]
|
23
21
|
return :not_created if machine.id.nil?
|
24
22
|
|
25
23
|
# Find the machine
|
26
|
-
server =
|
27
|
-
if server.nil? || server['status'] ==
|
24
|
+
server = env[:openstack_client].nova.get_server_details(env, machine.id)
|
25
|
+
if server.nil? || server['status'] == 'DELETED'
|
28
26
|
# The machine can't be found
|
29
|
-
@logger.info(
|
27
|
+
@logger.info('Machine not found or deleted, assuming it got destroyed.')
|
30
28
|
machine.id = nil
|
31
29
|
return :not_created
|
32
30
|
end
|
33
31
|
|
34
32
|
# Return the state
|
35
|
-
|
33
|
+
server['status'].downcase.to_sym
|
36
34
|
end
|
37
35
|
end
|
38
36
|
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
module VagrantPlugins
|
2
|
+
module Openstack
|
3
|
+
module Action
|
4
|
+
class Resume
|
5
|
+
def initialize(app, _env)
|
6
|
+
@app = app
|
7
|
+
end
|
8
|
+
|
9
|
+
def call(env)
|
10
|
+
if env[:machine].id
|
11
|
+
env[:ui].info I18n.t('vagrant.actions.vm.resume.resuming')
|
12
|
+
env[:openstack_client].nova.resume_server(env, env[:machine].id)
|
13
|
+
end
|
14
|
+
|
15
|
+
@app.call(env)
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
require 'log4r'
|
2
|
+
|
3
|
+
module VagrantPlugins
|
4
|
+
module Openstack
|
5
|
+
module Action
|
6
|
+
class StartServer
|
7
|
+
def initialize(app, _env)
|
8
|
+
@app = app
|
9
|
+
@logger = Log4r::Logger.new('vagrant_openstack::action::start_server')
|
10
|
+
end
|
11
|
+
|
12
|
+
def call(env)
|
13
|
+
if env[:machine].id
|
14
|
+
env[:ui].info(I18n.t('vagrant_openstack.starting_server'))
|
15
|
+
env[:openstack_client].nova.start_server(env, env[:machine].id)
|
16
|
+
end
|
17
|
+
@app.call(env)
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
require 'log4r'
|
2
|
+
|
3
|
+
module VagrantPlugins
|
4
|
+
module Openstack
|
5
|
+
module Action
|
6
|
+
class StopServer
|
7
|
+
def initialize(app, _env)
|
8
|
+
@app = app
|
9
|
+
@logger = Log4r::Logger.new('vagrant_openstack::action::stop_server')
|
10
|
+
end
|
11
|
+
|
12
|
+
def call(env)
|
13
|
+
if env[:machine].id
|
14
|
+
env[:ui].info(I18n.t('vagrant_openstack.stopping_server'))
|
15
|
+
env[:openstack_client].nova.stop_server(env, env[:machine].id)
|
16
|
+
end
|
17
|
+
@app.call(env)
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|