vagrant-openstack-provider 0.4.1 → 0.5.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (68) hide show
  1. checksums.yaml +4 -4
  2. data/.rubocop.yml +2 -2
  3. data/CHANGELOG.md +22 -0
  4. data/Gemfile +8 -15
  5. data/Vagrantfile +12 -10
  6. data/gemfiles/latest_stable.gemfile +6 -16
  7. data/gemfiles/minimal_release.gemfile +10 -0
  8. data/gemfiles/previous_release.gemfile +6 -16
  9. data/lib/vagrant-openstack-provider/action/connect_openstack.rb +2 -1
  10. data/lib/vagrant-openstack-provider/action/create_server.rb +40 -248
  11. data/lib/vagrant-openstack-provider/action/read_ssh_info.rb +30 -29
  12. data/lib/vagrant-openstack-provider/action/sync_folders.rb +19 -9
  13. data/lib/vagrant-openstack-provider/action/wait_accessible.rb +58 -0
  14. data/lib/vagrant-openstack-provider/action/wait_active.rb +5 -3
  15. data/lib/vagrant-openstack-provider/action/wait_stop.rb +5 -3
  16. data/lib/vagrant-openstack-provider/action.rb +19 -11
  17. data/lib/vagrant-openstack-provider/client/http_utils.rb +3 -2
  18. data/lib/vagrant-openstack-provider/client/neutron.rb +11 -1
  19. data/lib/vagrant-openstack-provider/client/nova.rb +49 -30
  20. data/lib/vagrant-openstack-provider/command/abstract_command.rb +10 -1
  21. data/lib/vagrant-openstack-provider/command/flavor_list.rb +1 -1
  22. data/lib/vagrant-openstack-provider/command/floatingip_list.rb +1 -1
  23. data/lib/vagrant-openstack-provider/command/image_list.rb +1 -1
  24. data/lib/vagrant-openstack-provider/command/main.rb +2 -1
  25. data/lib/vagrant-openstack-provider/command/network_list.rb +8 -2
  26. data/lib/vagrant-openstack-provider/command/reset.rb +21 -0
  27. data/lib/vagrant-openstack-provider/command/utils.rb +1 -1
  28. data/lib/vagrant-openstack-provider/command/volume_list.rb +1 -1
  29. data/lib/vagrant-openstack-provider/config.rb +16 -1
  30. data/lib/vagrant-openstack-provider/config_resolver.rb +262 -0
  31. data/lib/vagrant-openstack-provider/errors.rb +40 -0
  32. data/lib/vagrant-openstack-provider/plugin.rb +3 -3
  33. data/lib/vagrant-openstack-provider/utils.rb +21 -0
  34. data/lib/vagrant-openstack-provider/version.rb +1 -1
  35. data/locales/en.yml +35 -1
  36. data/spec/vagrant-openstack-provider/action/create_server_spec.rb +121 -368
  37. data/spec/vagrant-openstack-provider/action/delete_server_spec.rb +54 -0
  38. data/spec/vagrant-openstack-provider/action/message_spec.rb +34 -0
  39. data/spec/vagrant-openstack-provider/action/read_ssh_info_spec.rb +34 -17
  40. data/spec/vagrant-openstack-provider/action/read_state_spec.rb +70 -0
  41. data/spec/vagrant-openstack-provider/action/resume_server_spec.rb +50 -0
  42. data/spec/vagrant-openstack-provider/action/start_server_spec.rb +50 -0
  43. data/spec/vagrant-openstack-provider/action/stop_server_spec.rb +50 -0
  44. data/spec/vagrant-openstack-provider/action/suspend_server_spec.rb +50 -0
  45. data/spec/vagrant-openstack-provider/action/sync_folders_spec.rb +155 -0
  46. data/spec/vagrant-openstack-provider/action/wait_accessible_spec.rb +68 -0
  47. data/spec/vagrant-openstack-provider/action/wait_active_spec.rb +47 -0
  48. data/spec/vagrant-openstack-provider/action/wait_stop_spec.rb +47 -0
  49. data/spec/vagrant-openstack-provider/action_spec.rb +121 -0
  50. data/spec/vagrant-openstack-provider/client/cinder_spec.rb +1 -1
  51. data/spec/vagrant-openstack-provider/client/keystone_spec.rb +1 -1
  52. data/spec/vagrant-openstack-provider/client/neutron_spec.rb +37 -1
  53. data/spec/vagrant-openstack-provider/client/nova_spec.rb +60 -7
  54. data/spec/vagrant-openstack-provider/client/utils_spec.rb +1 -1
  55. data/spec/vagrant-openstack-provider/command/flavor_list_spec.rb +44 -0
  56. data/spec/vagrant-openstack-provider/command/floatingip_list_spec.rb +19 -2
  57. data/spec/vagrant-openstack-provider/command/image_list_spec.rb +48 -0
  58. data/spec/vagrant-openstack-provider/command/network_list_spec.rb +67 -0
  59. data/spec/vagrant-openstack-provider/command/reset_spec.rb +25 -0
  60. data/spec/vagrant-openstack-provider/command/volume_list_spec.rb +10 -2
  61. data/spec/vagrant-openstack-provider/config_resolver_spec.rb +680 -0
  62. data/spec/vagrant-openstack-provider/config_spec.rb +15 -1
  63. data/spec/vagrant-openstack-provider/spec_helper.rb +3 -0
  64. data/spec/vagrant-openstack-provider/utils_spec.rb +103 -0
  65. data/vagrant-openstack-provider.gemspec +4 -2
  66. metadata +78 -11
  67. data/Appraisals +0 -13
  68. data/gemfiles/oldest_current.gemfile +0 -20
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 6700023eabc299f30f0c0403dac3955bd22c8d78
4
- data.tar.gz: 5158ae5cdaeb3c306fed463f43a5adf33cff0190
3
+ metadata.gz: d9e64c02d3bf2d8b9e0bcc903a02546cc51e7bce
4
+ data.tar.gz: 8e5200339ede584e5cfbf980b49b98a41146e275
5
5
  SHA512:
6
- metadata.gz: f7c0405fd3d9aecd3c2ad876018ce5bec702ad61f6cea4799a12e7288cbebd2e143a2731959c260e0f61afa0ef1fc8e3333131884b649bdb6c1cf0f18fa3211a
7
- data.tar.gz: 1e12503398d53f5ac8a4b59e47267f8a8ca64f6f5ec4de5df291cc210a4307af0c34c557ffbdc72ea59e2ae15aecfc591ff9b71d23b313c4c711a1fc2280a782
6
+ metadata.gz: 3f56b3c7bde75c3813dee4bc83de5e9d9e367e71fc4f7d61fa0a486dce0f5130d559e8b26d55e30cd44babec3dd5c0544f0f20ca60327bf812f4448a40e5931a
7
+ data.tar.gz: 95711dba6f3275a1a54dd375424d5a536225d60c1c21ddb3c2514c59a23dde977e75db68a216c0a11f38a87ee69a682c8d5411e89ce9bf000233e4f521bde843
data/.rubocop.yml CHANGED
@@ -16,10 +16,10 @@ Style/ClassLength:
16
16
 
17
17
  Style/CyclomaticComplexity:
18
18
  Severity: warning
19
- Max: 10
19
+ Max: 15
20
20
 
21
21
  Style/MethodLength:
22
- Max: 50
22
+ Max: 60
23
23
 
24
24
  Style/LineLength:
25
25
  Max: 150
data/CHANGELOG.md CHANGED
@@ -1,3 +1,25 @@
1
+ # 0.5.0 (November 4, 2014)
2
+
3
+ FEATURES:
4
+
5
+ - Add an option to disable SSH Authentication and allow private vms [#120](https://github.com/ggiamarchi/vagrant-openstack-provider/issues/120)
6
+ - Support for fixed IP address for private network [#87](https://github.com/ggiamarchi/vagrant-openstack-provider/issues/87)
7
+
8
+ IMPROVEMENTS:
9
+
10
+ - Accept a string for ssh_timeout value [#144](https://github.com/ggiamarchi/vagrant-openstack-provider/issues/144)
11
+ - Vagrant Openstack should works in degraded mode id only Keystone and Nova are availables [#142](https://github.com/ggiamarchi/vagrant-openstack-provider/issues/142)
12
+ - Add custom command `vagrant openstack reset [#107](https://github.com/ggiamarchi/vagrant-openstack-provider/issues/107)
13
+ - Make box optional [#105](https://github.com/ggiamarchi/vagrant-openstack-provider/issues/105)
14
+ - vagrant up => Instance could not be found [#98](https://github.com/ggiamarchi/vagrant-openstack-provider/issues/98)
15
+
16
+ BUG FIXES:
17
+
18
+ - security_groups should be an array of hashes [#137](https://github.com/ggiamarchi/vagrant-openstack-provider/issues/137)
19
+ - user_data needs to be Base64 encoded in Nova.createServer [#122](https://github.com/ggiamarchi/vagrant-openstack-provider/issues/122)
20
+ - SSH failures after port 22 is open because user doesn't exist yet [#106](https://github.com/ggiamarchi/vagrant-openstack-provider/issues/106)
21
+ - Floating IP should not be mandatory [#55](https://github.com/ggiamarchi/vagrant-openstack-provider/issues/55)
22
+
1
23
  # 0.4.1 (October 3, 2014)
2
24
 
3
25
  BUG FIXES:
data/Gemfile CHANGED
@@ -2,24 +2,17 @@ source 'https://rubygems.org'
2
2
 
3
3
  gemspec
4
4
 
5
- gem 'json', '1.7.7'
6
- gem 'appraisal', '1.0.0'
7
- gem 'rest-client', '~> 1.6.0'
8
- gem 'terminal-table', '1.4.5'
9
- gem 'webmock', '~> 1.18.0', group: [:test]
10
- gem 'rubocop', '0.23.0', require: false
11
- gem 'vagrant', git: 'git://github.com/mitchellh/vagrant.git', tag: 'v1.4.3'
12
- gem 'fakefs', '~> 0.5.2', group: [:test]
13
- gem 'sshkey', '~> 1.6.1'
14
- gem 'colorize', '~> 0.7.3'
15
-
16
5
  group :development do
17
- # We depend on Vagrant for development, but we don't add it as a
18
- # gem dependency because we expect to be installed within the
19
- # Vagrant environment itself using `vagrant plugin`.
6
+ gem 'vagrant', git: 'https://github.com/mitchellh/vagrant.git', tag: 'v1.6.5'
7
+ gem 'appraisal', '1.0.0'
8
+ gem 'rubocop', '0.23.0', require: false
20
9
  gem 'coveralls', require: false
21
10
  end
22
11
 
23
12
  group :debug do
24
- gem 'debugger'
13
+ gem 'byebug'
14
+ end
15
+
16
+ group :plugins do
17
+ gem "vagrant-openstack-provider", path: "."
25
18
  end
data/Vagrantfile CHANGED
@@ -2,17 +2,19 @@ require 'vagrant-openstack-provider'
2
2
 
3
3
  Vagrant.configure('2') do |config|
4
4
 
5
- config.vm.box = 'dummy-openstack'
6
- config.vm.box_url = 'https://github.com/ggiamarchi/vagrant-openstack/raw/master/source/dummy.box'
7
- config.ssh.username = 'stack'
5
+ config.vm.box = 'openstack'
6
+
7
+ config.ssh.username = ENV['OS_SSH_USERNAME']
8
8
 
9
9
  config.vm.provider :openstack do |os|
10
- os.username = ENV['OS_USERNAME']
11
- os.floating_ip_pool = ENV['OS_FLOATING_IP_POOL']
12
- os.password = ENV['OS_PASSWORD']
13
- os.flavor = ENV['OS_FLAVOR']
14
- os.image = ENV['OS_IMAGE']
15
- os.openstack_auth_url = ENV['OS_AUTH_URL']
16
- os.tenant_name = ENV['OS_TENANT_NAME']
10
+ os.openstack_auth_url = ENV['OS_AUTH_URL']
11
+ os.tenant_name = ENV['OS_TENANT_NAME']
12
+ os.username = ENV['OS_USERNAME']
13
+ os.password = ENV['OS_PASSWORD']
14
+ os.floating_ip_pool = ENV['OS_FLOATING_IP_POOL']
15
+ os.flavor = ENV['OS_FLAVOR']
16
+ os.image = ENV['OS_IMAGE']
17
17
  end
18
+
19
+ config.vm.provision "shell", inline: "echo 'ok' > ~/provision"
18
20
  end
@@ -1,20 +1,10 @@
1
- # This file was generated by Appraisal
1
+ source 'https://rubygems.org'
2
2
 
3
- source "https://rubygems.org"
4
-
5
- gem "appraisal", "1.0.0"
6
- gem "restclient", "0.10.0"
7
- gem "terminal-table", "1.4.5"
8
- gem "webmock", "~> 1.18.0", :group => [:test]
9
- gem "rubocop", "0.23.0", :require => false
10
- gem "vagrant", :git => "git://github.com/mitchellh/vagrant.git", :tag => "v1.4.3"
11
- gem "fakefs", "~> 0.5.2", :group => [:test]
12
- gem "sshkey", "~> 1.6.1"
13
- gem "colorize", "~> 0.7.3"
3
+ gemspec :path => "../"
14
4
 
15
5
  group :development do
16
- gem "coveralls", :require => false
17
- gem "debugger"
6
+ gem 'vagrant', git: 'git://github.com/mitchellh/vagrant.git', tag: 'v1.6.5'
7
+ gem 'appraisal', '1.0.0'
8
+ gem 'rubocop', '0.23.0', require: false
9
+ gem 'coveralls', require: false
18
10
  end
19
-
20
- gemspec :path => "../"
@@ -0,0 +1,10 @@
1
+ source 'https://rubygems.org'
2
+
3
+ gemspec :path => "../"
4
+
5
+ group :development do
6
+ gem 'vagrant', git: 'git://github.com/mitchellh/vagrant.git', tag: 'v1.4.0'
7
+ gem 'appraisal', '1.0.0'
8
+ gem 'rubocop', '0.23.0', require: false
9
+ gem 'coveralls', require: false
10
+ end
@@ -1,20 +1,10 @@
1
- # This file was generated by Appraisal
1
+ source 'https://rubygems.org'
2
2
 
3
- source "https://rubygems.org"
4
-
5
- gem "appraisal", "1.0.0"
6
- gem "restclient", "0.10.0"
7
- gem "terminal-table", "1.4.5"
8
- gem "webmock", "~> 1.18.0", :group => [:test]
9
- gem "rubocop", "0.23.0", :require => false
10
- gem "vagrant", :git => "git://github.com/mitchellh/vagrant.git", :tag => "v1.4.3"
11
- gem "fakefs", "~> 0.5.2", :group => [:test]
12
- gem "sshkey", "~> 1.6.1"
13
- gem "colorize", "~> 0.7.3"
3
+ gemspec :path => "../"
14
4
 
15
5
  group :development do
16
- gem "coveralls", :require => false
17
- gem "debugger"
6
+ gem 'vagrant', git: 'git://github.com/mitchellh/vagrant.git', tag: 'v1.5.4'
7
+ gem 'appraisal', '1.0.0'
8
+ gem 'rubocop', '0.23.0', require: false
9
+ gem 'coveralls', require: false
18
10
  end
19
-
20
- gemspec :path => "../"
@@ -67,7 +67,8 @@ module VagrantPlugins
67
67
  config = env[:machine].provider_config
68
68
  client.session.endpoints[:compute] = config.openstack_compute_url unless config.openstack_compute_url.nil?
69
69
  client.session.endpoints[:network] = config.openstack_network_url unless config.openstack_network_url.nil?
70
- client.session.endpoints[:volume] = config.openstack_volume_url unless config.openstack_volume_url.nil?
70
+ client.session.endpoints[:volume] = config.openstack_volume_url unless config.openstack_volume_url.nil?
71
+ client.session.endpoints.delete_if { |_, value| value.nil? || value.empty? }
71
72
  end
72
73
 
73
74
  def log_endpoint_catalog(env)
@@ -3,6 +3,8 @@ require 'socket'
3
3
  require 'timeout'
4
4
  require 'sshkey'
5
5
 
6
+ require 'vagrant-openstack-provider/config_resolver'
7
+ require 'vagrant-openstack-provider/utils'
6
8
  require 'vagrant/util/retryable'
7
9
 
8
10
  module VagrantPlugins
@@ -11,9 +13,11 @@ module VagrantPlugins
11
13
  class CreateServer
12
14
  include Vagrant::Util::Retryable
13
15
 
14
- def initialize(app, _env)
16
+ def initialize(app, _env, resolver = ConfigResolver.new, utils = Utils.new)
15
17
  @app = app
16
18
  @logger = Log4r::Logger.new('vagrant_openstack::action::create_server')
19
+ @resolver = resolver
20
+ @utils = utils
17
21
  end
18
22
 
19
23
  def call(env)
@@ -24,18 +28,16 @@ module VagrantPlugins
24
28
  fail Errors::MissingBootOption if config.image.nil? && config.volume_boot.nil?
25
29
  fail Errors::ConflictBootOption unless config.image.nil? || config.volume_boot.nil?
26
30
 
27
- nova = env[:openstack_client].nova
28
-
29
31
  options = {
30
- flavor: resolve_flavor(env),
31
- image: resolve_image(env),
32
- volume_boot: resolve_volume_boot(env),
33
- networks: resolve_networks(env),
34
- volumes: resolve_volumes(env),
35
- keypair_name: resolve_keypair(env),
32
+ flavor: @resolver.resolve_flavor(env),
33
+ image: @resolver.resolve_image(env),
34
+ volume_boot: @resolver.resolve_volume_boot(env),
35
+ networks: @resolver.resolve_networks(env),
36
+ volumes: @resolver.resolve_volumes(env),
37
+ keypair_name: @resolver.resolve_keypair(env),
36
38
  availability_zone: env[:machine].provider_config.availability_zone,
37
39
  scheduler_hints: env[:machine].provider_config.scheduler_hints,
38
- security_groups: env[:machine].provider_config.security_groups,
40
+ security_groups: @resolver.resolve_security_groups(env),
39
41
  user_data: env[:machine].provider_config.user_data,
40
42
  metadata: env[:machine].provider_config.metadata
41
43
  }
@@ -45,205 +47,15 @@ module VagrantPlugins
45
47
  # Store the ID right away so we can track it
46
48
  env[:machine].id = server_id
47
49
 
48
- waiting_for_server_to_be_build(env, server_id)
49
-
50
- floating_ip = resolve_floating_ip(env)
51
- if floating_ip && !floating_ip.empty?
52
- @logger.info "Using floating IP #{floating_ip}"
53
- env[:ui].info(I18n.t('vagrant_openstack.using_floating_ip', floating_ip: floating_ip))
54
- nova.add_floating_ip(env, server_id, floating_ip)
55
- end
56
-
50
+ waiting_for_server_to_be_built(env, server_id)
51
+ assign_floating_ip(env, server_id)
57
52
  attach_volumes(env, server_id, options[:volumes]) unless options[:volumes].empty?
58
53
 
59
- unless env[:interrupted]
60
- # Clear the line one more time so the progress is removed
61
- env[:ui].clear_line
62
-
63
- # Wait for SSH to become available
64
- ssh_timeout = env[:machine].provider_config.ssh_timeout
65
- unless port_open?(env, floating_ip, resolve_ssh_port(env), ssh_timeout)
66
- env[:ui].error(I18n.t('vagrant_openstack.timeout'))
67
- fail Errors::SshUnavailable, host: floating_ip, timeout: ssh_timeout
68
- end
69
-
70
- @logger.info 'The server is ready'
71
- env[:ui].info(I18n.t('vagrant_openstack.ready'))
72
- end
73
-
74
54
  @app.call(env)
75
55
  end
76
56
 
77
57
  private
78
58
 
79
- def resolve_ssh_port(env)
80
- machine_config = env[:machine].config
81
- return machine_config.ssh.port if machine_config.ssh.port
82
- 22
83
- end
84
-
85
- # 1. if floating_ip is set, use it
86
- # 2. if floating_ip_pool is set
87
- # GET v2/{{tenant_id}}/os-floating-ips
88
- # If any IP with the same pool is available, use it
89
- # Else Allocate a new IP from the pool
90
- # Manage error case
91
- # 3. GET v2/{{tenant_id}}/os-floating-ips
92
- # If any IP is available, use it
93
- # Else fail
94
- def resolve_floating_ip(env)
95
- config = env[:machine].provider_config
96
- nova = env[:openstack_client].nova
97
- return config.floating_ip if config.floating_ip
98
- floating_ips = nova.get_all_floating_ips(env)
99
- if config.floating_ip_pool
100
- floating_ips.each do |single|
101
- return single.ip if single.pool == config.floating_ip_pool && single.instance_id.nil?
102
- end unless config.floating_ip_pool_always_allocate
103
- return nova.allocate_floating_ip(env, config.floating_ip_pool).ip
104
- else
105
- floating_ips.each do |ip|
106
- return ip.ip if ip.instance_id.nil?
107
- end
108
- end
109
- fail Errors::UnableToResolveFloatingIP
110
- end
111
-
112
- def resolve_keypair(env)
113
- config = env[:machine].provider_config
114
- nova = env[:openstack_client].nova
115
- return config.keypair_name if config.keypair_name
116
- return nova.import_keypair_from_file(env, config.public_key_path) if config.public_key_path
117
- generate_keypair(env)
118
- end
119
-
120
- def generate_keypair(env)
121
- key = SSHKey.generate
122
- nova = env[:openstack_client].nova
123
- generated_keyname = nova.import_keypair(env, key.ssh_public_key)
124
- File.write("#{env[:machine].data_dir}/#{generated_keyname}", key.private_key)
125
- generated_keyname
126
- end
127
-
128
- def resolve_flavor(env)
129
- @logger.info 'Resolving flavor'
130
- config = env[:machine].provider_config
131
- nova = env[:openstack_client].nova
132
- env[:ui].info(I18n.t('vagrant_openstack.finding_flavor'))
133
- flavors = nova.get_all_flavors(env)
134
- @logger.info "Finding flavor matching name '#{config.flavor}'"
135
- flavor = find_matching(flavors, config.flavor)
136
- fail Errors::NoMatchingFlavor unless flavor
137
- flavor
138
- end
139
-
140
- def resolve_image(env)
141
- @logger.info 'Resolving image'
142
- config = env[:machine].provider_config
143
- return nil if config.image.nil?
144
- nova = env[:openstack_client].nova
145
- env[:ui].info(I18n.t('vagrant_openstack.finding_image'))
146
- images = nova.get_all_images(env)
147
- @logger.info "Finding image matching name '#{config.image}'"
148
- image = find_matching(images, config.image)
149
- fail Errors::NoMatchingImage unless image
150
- image
151
- end
152
-
153
- def resolve_networks(env)
154
- @logger.info 'Resolving network(s)'
155
- config = env[:machine].provider_config
156
- return [] if config.networks.nil? || config.networks.empty?
157
- env[:ui].info(I18n.t('vagrant_openstack.finding_networks'))
158
-
159
- private_networks = env[:openstack_client].neutron.get_private_networks(env)
160
- private_network_ids = private_networks.map { |n| n.id }
161
-
162
- networks = []
163
- config.networks.each do |network|
164
- if private_network_ids.include?(network)
165
- networks << network
166
- next
167
- end
168
- net_id = nil
169
- private_networks.each do |n| # Bad algorithm complexity, but here we don't care...
170
- next unless n.name.eql? network
171
- fail "Multiple networks with name '#{n.id}'" unless net_id.nil?
172
- net_id = n.id
173
- end
174
- fail "No matching network with name '#{network}'" if net_id.nil?
175
- networks << net_id
176
- end
177
- networks
178
- end
179
-
180
- def resolve_volume_boot(env)
181
- @logger.info 'Resolving image'
182
- config = env[:machine].provider_config
183
- return nil if config.volume_boot.nil?
184
-
185
- volume_list = env[:openstack_client].cinder.get_all_volumes(env)
186
- volume_ids = volume_list.map { |v| v.id }
187
-
188
- @logger.debug(volume_list)
189
-
190
- volume = resolve_volume(config.volume_boot, volume_list, volume_ids)
191
- device = volume[:device].nil? ? 'vda' : volume[:device]
192
-
193
- { id: volume[:id], device: device }
194
- end
195
-
196
- def resolve_volumes(env)
197
- @logger.info 'Resolving volume(s)'
198
- config = env[:machine].provider_config
199
- return [] if config.volumes.nil? || config.volumes.empty?
200
- env[:ui].info(I18n.t('vagrant_openstack.finding_volumes'))
201
-
202
- volume_list = env[:openstack_client].cinder.get_all_volumes(env)
203
- volume_ids = volume_list.map { |v| v.id }
204
-
205
- @logger.debug(volume_list)
206
-
207
- volumes = []
208
- config.volumes.each do |volume|
209
- volumes << resolve_volume(volume, volume_list, volume_ids)
210
- end
211
- @logger.debug("Resolved volumes : #{volumes.to_json}")
212
- volumes
213
- end
214
-
215
- def resolve_volume(volume, volume_list, volume_ids)
216
- return resolve_volume_from_string(volume, volume_list) if volume.is_a? String
217
- return resolve_volume_from_hash(volume, volume_list, volume_ids) if volume.is_a? Hash
218
- fail Errors::InvalidVolumeObject, volume: volume
219
- end
220
-
221
- def resolve_volume_from_string(volume, volume_list)
222
- found_volume = find_matching(volume_list, volume)
223
- fail Errors::UnresolvedVolume, volume: volume if found_volume.nil?
224
- { id: found_volume.id, device: nil }
225
- end
226
-
227
- def resolve_volume_from_hash(volume, volume_list, volume_ids)
228
- device = nil
229
- device = volume[:device] if volume.key?(:device)
230
- if volume.key?(:id)
231
- fail Errors::ConflictVolumeNameId, volume: volume if volume.key?(:name)
232
- volume_id = volume[:id]
233
- fail Errors::UnresolvedVolumeId, id: volume_id unless volume_ids.include? volume_id
234
- elsif volume.key?(:name)
235
- volume_list.each do |v|
236
- next unless v.name.eql? volume[:name]
237
- fail Errors::MultipleVolumeName, name: volume[:name] unless volume_id.nil?
238
- volume_id = v.id
239
- end
240
- fail Errors::UnresolvedVolumeName, name: volume[:name] unless volume_ids.include? volume_id
241
- else
242
- fail Errors::ConflictVolumeNameId, volume: volume
243
- end
244
- { id: volume_id, device: device }
245
- end
246
-
247
59
  def create_server(env, options)
248
60
  config = env[:machine].provider_config
249
61
  nova = env[:openstack_client].nova
@@ -262,11 +74,20 @@ module VagrantPlugins
262
74
  env[:ui].info(" -- KeyPair : #{options[:keypair_name]}")
263
75
 
264
76
  unless options[:networks].empty?
77
+ formated_networks = ' -- '
265
78
  if options[:networks].size == 1
266
- env[:ui].info(" -- Network : #{options[:networks][0]}")
79
+ formated_networks << 'Network : '
267
80
  else
268
- env[:ui].info(" -- Networks : #{options[:networks]}")
81
+ formated_networks << 'Networks : '
269
82
  end
83
+ formated_networks << options[:networks].map do |n|
84
+ if n.key? :fixed_ip
85
+ "#{n[:uuid]} (#{n[:fixed_ip]})"
86
+ else
87
+ n[:uuid]
88
+ end
89
+ end.join(', ')
90
+ env[:ui].info(formated_networks)
270
91
  end
271
92
 
272
93
  unless options[:volumes].empty?
@@ -305,62 +126,33 @@ module VagrantPlugins
305
126
  nova.create_server(env, create_opts)
306
127
  end
307
128
 
308
- def waiting_for_server_to_be_build(env, server_id)
129
+ def waiting_for_server_to_be_built(env, server_id, retry_interval = 3, timeout = 200)
309
130
  @logger.info 'Waiting for the server to be built...'
310
131
  env[:ui].info(I18n.t('vagrant_openstack.waiting_for_build'))
311
- nova = env[:openstack_client].nova
312
- timeout(200) do
313
- while nova.get_server_details(env, server_id)['status'] != 'ACTIVE'
314
- sleep 3
132
+ timeout(timeout) do
133
+ while env[:openstack_client].nova.get_server_details(env, server_id)['status'] != 'ACTIVE'
134
+ sleep retry_interval
315
135
  @logger.debug('Waiting for server to be ACTIVE')
316
136
  end
317
137
  end
318
138
  end
319
139
 
140
+ def assign_floating_ip(env, server_id)
141
+ floating_ip = @resolver.resolve_floating_ip(env)
142
+ return if !floating_ip || floating_ip.empty?
143
+ @logger.info "Using floating IP #{floating_ip}"
144
+ env[:ui].info(I18n.t('vagrant_openstack.using_floating_ip', floating_ip: floating_ip))
145
+ env[:openstack_client].nova.add_floating_ip(env, server_id, floating_ip)
146
+ rescue Errors::UnableToResolveFloatingIP
147
+ @logger.info 'Vagrant was unable to resolve FloatingIP, continue assuming it is not necessary'
148
+ end
149
+
320
150
  def attach_volumes(env, server_id, volumes)
321
151
  @logger.info("Attaching volumes #{volumes} to server #{server_id}")
322
- nova = env[:openstack_client].nova
323
152
  volumes.each do |volume|
324
153
  @logger.debug("Attaching volumes #{volume}")
325
- nova.attach_volume(env, server_id, volume[:id], volume[:device])
326
- end
327
- end
328
-
329
- def port_open?(env, ip, port, timeout)
330
- start_time = Time.now
331
- current_time = start_time
332
- nb_retry = 0
333
- while (current_time - start_time) <= timeout
334
- begin
335
- @logger.debug "Checking if SSH port is open... Attempt number #{nb_retry}"
336
- if nb_retry % 5 == 0
337
- @logger.info 'Waiting for SSH to become available...'
338
- env[:ui].info(I18n.t('vagrant_openstack.waiting_for_ssh'))
339
- end
340
- TCPSocket.new(ip, port)
341
- return true
342
- rescue Errno::ECONNREFUSED, Errno::EHOSTUNREACH, Errno::ETIMEDOUT
343
- @logger.debug 'SSH port is not open... new retry in in 1 second'
344
- nb_retry += 1
345
- sleep 1
346
- end
347
- current_time = Time.now
348
- end
349
- false
350
- end
351
-
352
- # This method finds a matching _thing_ in a collection of
353
- # _things_. This works matching if the ID or NAME equals to
354
- # `name`. Or, if `name` is a regexp, a partial match is chosen
355
- # as well.
356
- def find_matching(collection, name)
357
- collection.each do |single|
358
- return single if single.id == name
359
- return single if single.name == name
360
- return single if name.is_a?(Regexp) && name =~ single.name
154
+ env[:openstack_client].nova.attach_volume(env, server_id, volume[:id], volume[:device])
361
155
  end
362
- @logger.error "Element '#{name}' not found in collection #{collection}"
363
- nil
364
156
  end
365
157
  end
366
158
  end