vagrant-openstack-provider 0.6.1 → 0.7.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (63) hide show
  1. checksums.yaml +4 -4
  2. data/.rubocop.yml +12 -5
  3. data/CHANGELOG.md +18 -0
  4. data/Gemfile +3 -2
  5. data/{LICENSE.txt → LICENSE} +2 -1
  6. data/lib/vagrant-openstack-provider/action.rb +3 -2
  7. data/lib/vagrant-openstack-provider/action/provision.rb +60 -0
  8. data/lib/vagrant-openstack-provider/action/read_ssh_info.rb +4 -0
  9. data/lib/vagrant-openstack-provider/client/domain.rb +2 -2
  10. data/lib/vagrant-openstack-provider/client/keystone.rb +17 -6
  11. data/lib/vagrant-openstack-provider/client/nova.rb +14 -3
  12. data/lib/vagrant-openstack-provider/command/abstract_command.rb +1 -0
  13. data/lib/vagrant-openstack-provider/command/main.rb +1 -3
  14. data/lib/vagrant-openstack-provider/config.rb +3 -3
  15. data/lib/vagrant-openstack-provider/config_resolver.rb +46 -16
  16. data/lib/vagrant-openstack-provider/errors.rb +15 -0
  17. data/lib/vagrant-openstack-provider/plugin.rb +7 -1
  18. data/lib/vagrant-openstack-provider/version.rb +11 -1
  19. data/lib/vagrant-openstack-provider/version_checker.rb +76 -0
  20. data/locales/en.yml +21 -4
  21. data/spec/vagrant-openstack-provider/action/connect_openstack_spec.rb +17 -19
  22. data/spec/vagrant-openstack-provider/action/create_server_spec.rb +19 -18
  23. data/spec/vagrant-openstack-provider/action/create_stack_spec.rb +4 -6
  24. data/spec/vagrant-openstack-provider/action/delete_server_spec.rb +4 -6
  25. data/spec/vagrant-openstack-provider/action/delete_stack_spec.rb +1 -2
  26. data/spec/vagrant-openstack-provider/action/message_spec.rb +1 -2
  27. data/spec/vagrant-openstack-provider/action/provision_spec.rb +104 -0
  28. data/spec/vagrant-openstack-provider/action/read_ssh_info_spec.rb +1 -3
  29. data/spec/vagrant-openstack-provider/action/read_state_spec.rb +1 -2
  30. data/spec/vagrant-openstack-provider/action/resume_server_spec.rb +1 -2
  31. data/spec/vagrant-openstack-provider/action/start_server_spec.rb +1 -2
  32. data/spec/vagrant-openstack-provider/action/stop_server_spec.rb +1 -2
  33. data/spec/vagrant-openstack-provider/action/suspend_server_spec.rb +1 -2
  34. data/spec/vagrant-openstack-provider/action/sync_folders_spec.rb +1 -2
  35. data/spec/vagrant-openstack-provider/action/wait_accessible_spec.rb +1 -2
  36. data/spec/vagrant-openstack-provider/action/wait_active_spec.rb +3 -4
  37. data/spec/vagrant-openstack-provider/action/wait_stop_spec.rb +3 -4
  38. data/spec/vagrant-openstack-provider/action_spec.rb +0 -1
  39. data/spec/vagrant-openstack-provider/client/cinder_spec.rb +5 -8
  40. data/spec/vagrant-openstack-provider/client/glance_spec.rb +69 -70
  41. data/spec/vagrant-openstack-provider/client/heat_spec.rb +24 -28
  42. data/spec/vagrant-openstack-provider/client/keystone_spec.rb +34 -16
  43. data/spec/vagrant-openstack-provider/client/neutron_spec.rb +76 -80
  44. data/spec/vagrant-openstack-provider/client/nova_spec.rb +198 -168
  45. data/spec/vagrant-openstack-provider/client/utils_spec.rb +1 -3
  46. data/spec/vagrant-openstack-provider/command/flavor_list_spec.rb +1 -2
  47. data/spec/vagrant-openstack-provider/command/floatingip_list_spec.rb +1 -2
  48. data/spec/vagrant-openstack-provider/command/image_list_spec.rb +1 -6
  49. data/spec/vagrant-openstack-provider/command/network_list_spec.rb +1 -3
  50. data/spec/vagrant-openstack-provider/command/reset_spec.rb +1 -2
  51. data/spec/vagrant-openstack-provider/command/subnet_list_spec.rb +1 -2
  52. data/spec/vagrant-openstack-provider/command/volume_list_spec.rb +1 -2
  53. data/spec/vagrant-openstack-provider/config_resolver_spec.rb +100 -6
  54. data/spec/vagrant-openstack-provider/config_spec.rb +2 -6
  55. data/spec/vagrant-openstack-provider/e2e_spec.rb.save +27 -0
  56. data/spec/vagrant-openstack-provider/spec_helper.rb +1 -0
  57. data/spec/vagrant-openstack-provider/utils_spec.rb +1 -2
  58. data/spec/vagrant-openstack-provider/version_checker_spec.rb +39 -0
  59. data/vagrant-openstack-provider.gemspec +4 -2
  60. metadata +29 -9
  61. data/gemfiles/latest_stable.gemfile +0 -10
  62. data/gemfiles/minimal_release.gemfile +0 -10
  63. data/gemfiles/previous_release.gemfile +0 -10
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 79d085018733ba06b31b2f7fb8f904a29db8040b
4
- data.tar.gz: 263505f7c34eb0c3456f00794fe5158076cc6654
3
+ metadata.gz: 36585a8dacc29b73947055b81be3b41c1c7fd9ef
4
+ data.tar.gz: 74481f1a768d1438f31d2ef73a76fc2e2d06961b
5
5
  SHA512:
6
- metadata.gz: c544a9afd69438fe6a0d4b63e3d283c241c890fab6a334ba0ef4d95bb9411516f715af9494313bc3b811e32371e8624b378ec0dece4060448fd8d2c90b759837
7
- data.tar.gz: 670e6af16eeb1b62312518ef589bf12eb6b38ee8d4f44147a47b3c4eecdfd997f76e813459b39c5f1be722286c495cdb61ab516b18ae3ef682230faa0b82cb0a
6
+ metadata.gz: a1483cf07c6d36599a99b441b20bc1f5db2f74df01723e88b6a766b89fd8a5353b3725f9b0427dd93b04d2dcb6b9775e7363e89e781fca8fbd3fb3fdf9ae21ff
7
+ data.tar.gz: 751776de2b6099cc462e7db5980f1f6aea185e7b361549cc07c7f0eab1ae4729cfbd6938ca8d5ca47d690334bc0794be1ecdeb31c9ae984ac31c73b964bbf5e9
@@ -1,6 +1,7 @@
1
1
  AllCops:
2
2
  Exclude:
3
3
  - 'out/**/*'
4
+ - '**/Vagrantfile'
4
5
 
5
6
  Style/FileName:
6
7
  Enabled: false
@@ -11,18 +12,24 @@ Style/Encoding:
11
12
  Style/Documentation:
12
13
  Enabled: false
13
14
 
14
- Style/ClassLength:
15
+ Metrics/ClassLength:
15
16
  Max: 300
16
17
 
17
- Style/CyclomaticComplexity:
18
+ Metrics/CyclomaticComplexity:
18
19
  Severity: warning
19
20
  Max: 15
20
21
 
21
- Style/MethodLength:
22
+ Metrics/MethodLength:
22
23
  Max: 60
23
24
 
24
- Style/LineLength:
25
+ Metrics/LineLength:
25
26
  Max: 150
26
27
 
27
- Style/ParameterLists:
28
+ Metrics/ParameterLists:
28
29
  Max: 6
30
+
31
+ Metrics/AbcSize:
32
+ Max: 110
33
+
34
+ Metrics/PerceivedComplexity:
35
+ Max: 45
@@ -1,3 +1,21 @@
1
+ # 0.7.0 (August, 10, 2015)
2
+
3
+ FEATURES:
4
+
5
+ - Access to obtained floating IP from provisioner phase [#205](https://github.com/ggiamarchi/vagrant-openstack-provider/issues/205)
6
+
7
+ IMPROVEMENTS:
8
+
9
+ - Autodetect new version of the provider and provide info message to update [#132](https://github.com/ggiamarchi/vagrant-openstack-provider/issues/132)
10
+ - Documentation for the `ssh_timeout` option [#230](https://github.com/ggiamarchi/vagrant-openstack-provider/pull/230)
11
+
12
+ BUG FIXES:
13
+
14
+ - scheduler_hints ignored due to incorrect json tag in create request [#231](https://github.com/ggiamarchi/vagrant-openstack-provider/issues/231)
15
+ - delete_keypair_if_vagrant throws exception if key_name is missing [#238](https://github.com/ggiamarchi/vagrant-openstack-provider/issues/238)
16
+ - Fix Vagrant 1.4 bug, extra_data attr not found [#211](https://github.com/ggiamarchi/vagrant-openstack-provider/issues/211)
17
+ - Add suffix /tokens in auth url if missing [#208](https://github.com/ggiamarchi/vagrant-openstack-provider/pull/208)
18
+
1
19
  # 0.6.1 (January 30, 2015)
2
20
 
3
21
  IMPROVEMENTS:
data/Gemfile CHANGED
@@ -5,8 +5,9 @@ gemspec
5
5
  group :development do
6
6
  gem 'vagrant', git: 'https://github.com/mitchellh/vagrant.git', tag: 'v1.6.5'
7
7
  gem 'appraisal', '1.0.0'
8
- gem 'rubocop', '0.23.0', require: false
8
+ gem 'rubocop', '0.29.0', require: false
9
9
  gem 'coveralls', require: false
10
+ gem 'rspec-its'
10
11
  end
11
12
 
12
13
  group :debug do
@@ -14,5 +15,5 @@ group :debug do
14
15
  end
15
16
 
16
17
  group :plugins do
17
- gem "vagrant-openstack-provider", path: "."
18
+ gem 'vagrant-openstack-provider', path: '.'
18
19
  end
@@ -1,4 +1,5 @@
1
1
  Copyright (c) 2013 Mitchell Hashimoto
2
+ Copyright (c) 2015 Guillaume Giamarchi, Julien Vey
2
3
 
3
4
  MIT License
4
5
 
@@ -19,4 +20,4 @@ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
20
  NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
21
  LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
22
  OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
- WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
23
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -33,7 +33,7 @@ module VagrantPlugins
33
33
  if env[:machine_state_id] == :not_created
34
34
  b2.use Message, I18n.t('vagrant_openstack.not_created')
35
35
  else
36
- b2.use Provision
36
+ b2.use ProvisionWrapper
37
37
  b2.use SyncFolders
38
38
  end
39
39
  end
@@ -99,7 +99,7 @@ module VagrantPlugins
99
99
  case env[:machine_state_id]
100
100
  when :not_created
101
101
  ssh_disabled = env[:machine].provider_config.ssh_disabled
102
- b2.use Provision unless ssh_disabled
102
+ b2.use ProvisionWrapper unless ssh_disabled
103
103
  b2.use SyncFolders
104
104
  b2.use CreateStack
105
105
  b2.use CreateServer
@@ -212,6 +212,7 @@ module VagrantPlugins
212
212
  autoload :SyncFolders, action_root.join('sync_folders')
213
213
  autoload :Suspend, action_root.join('suspend')
214
214
  autoload :Resume, action_root.join('resume')
215
+ autoload :ProvisionWrapper, action_root.join('provision')
215
216
  autoload :WaitForServerToStop, action_root.join('wait_stop')
216
217
  autoload :WaitForServerToBeActive, action_root.join('wait_active')
217
218
  autoload :WaitForServerToBeAccessible, action_root.join('wait_accessible')
@@ -0,0 +1,60 @@
1
+ require 'log4r'
2
+
3
+ require 'vagrant/action/builder'
4
+
5
+ require 'vagrant-openstack-provider/action/abstract_action'
6
+ require 'vagrant-openstack-provider/action/read_ssh_info'
7
+
8
+ module VagrantPlugins
9
+ module Openstack
10
+ module Action
11
+ include Vagrant::Action::Builtin
12
+
13
+ class ProvisionWrapper < AbstractAction
14
+ def initialize(app, env)
15
+ @app = app
16
+ @env = env
17
+ @logger = Log4r::Logger.new('vagrant_openstack::action::provision_wrapper')
18
+ end
19
+
20
+ def execute(env)
21
+ @logger.info 'Run provisioning'
22
+ InternalProvisionWrapper.new(@app, @env).call(@env)
23
+ @app.call(env)
24
+ end
25
+ end
26
+
27
+ class InternalProvisionWrapper < Vagrant::Action::Builtin::Provision
28
+ def initialize(app, env)
29
+ @logger = Log4r::Logger.new('vagrant_openstack::action::internal_provision_wrapper')
30
+ super app, env
31
+ end
32
+
33
+ def run_provisioner(env)
34
+ if env[:provisioner].class == VagrantPlugins::Shell::Provisioner
35
+ handle_shell_meta_args(env)
36
+ end
37
+ env[:provisioner].provision
38
+ end
39
+
40
+ private
41
+
42
+ def handle_shell_meta_args(env)
43
+ config = env[:provisioner].config
44
+ args = config.args.nil? ? [] : [config.args].flatten
45
+ config.args = []
46
+ @logger.info "Shell provisioner args: #{args}"
47
+ args.each do |arg|
48
+ if '@@ssh_ip@@'.eql? arg
49
+ ssh_info = VagrantPlugins::Openstack::Action.get_ssh_info(env)
50
+ @logger.info "Replace meta-arg #{arg} by value #{ssh_info[:host]}"
51
+ config.args << ssh_info[:host]
52
+ else
53
+ config.args << arg
54
+ end
55
+ end
56
+ end
57
+ end
58
+ end
59
+ end
60
+ end
@@ -63,6 +63,10 @@ module VagrantPlugins
63
63
  @ssh_info = {}
64
64
  end
65
65
  end
66
+
67
+ def self.get_ssh_info(env)
68
+ SSHInfoHolder.instance.ssh_info[env[:machine].id.to_sym]
69
+ end
66
70
  end
67
71
  end
68
72
  end
@@ -106,7 +106,7 @@ module VagrantPlugins
106
106
  #
107
107
  attr_accessor :device
108
108
 
109
- # rubocop:disable Style/ParameterLists
109
+ # rubocop:disable Metrics/ParameterLists
110
110
  def initialize(id, name, size, status, bootable, instance_id, device)
111
111
  @size = size
112
112
  @status = status
@@ -115,7 +115,7 @@ module VagrantPlugins
115
115
  @device = device
116
116
  super(id, name)
117
117
  end
118
- # rubocop:enable Style/ParameterLists
118
+ # rubocop:enable Metrics/ParameterLists
119
119
 
120
120
  def to_s
121
121
  {
@@ -32,15 +32,18 @@ module VagrantPlugins
32
32
  }
33
33
  }
34
34
 
35
- log_request(:POST, config.openstack_auth_url, post_body.to_json)
35
+ auth_url = get_auth_url_v2 env
36
+
37
+ headers = {
38
+ content_type: :json,
39
+ accept: :json
40
+ }
41
+
42
+ log_request(:POST, auth_url, post_body.to_json, headers)
36
43
 
37
44
  post_body[:auth][:passwordCredentials][:password] = config.password
38
45
 
39
- authentication = RestUtils.post(env, config.openstack_auth_url, post_body.to_json,
40
- content_type: :json,
41
- accept: :json,
42
- timeout: config.http.read_timeout,
43
- open_timeout: config.http.open_timeout) do |response|
46
+ authentication = RestUtils.post(env, auth_url, post_body.to_json, headers) do |response|
44
47
  log_response(response)
45
48
  case response.code
46
49
  when 200
@@ -61,6 +64,14 @@ module VagrantPlugins
61
64
 
62
65
  access['serviceCatalog']
63
66
  end
67
+
68
+ private
69
+
70
+ def get_auth_url_v2(env)
71
+ url = env[:machine].provider_config.openstack_auth_url
72
+ return url if url.match(%r{/tokens/*$})
73
+ "#{url}/tokens"
74
+ end
64
75
  end
65
76
  end
66
77
  end
@@ -51,7 +51,16 @@ module VagrantPlugins
51
51
  server = {}.tap do |s|
52
52
  s['name'] = options[:name]
53
53
  if options[:image_ref].nil?
54
- s['block_device_mapping'] = [{ volume_id: options[:volume_boot][:id], device_name: options[:volume_boot][:device] }]
54
+ s['block_device_mapping'] = [{ volume_id: options[:volume_boot][:id],
55
+ device_name: options[:volume_boot][:device] }] if options[:volume_boot].key?(:id)
56
+ s['block_device_mapping_v2'] = [{ boot_index: '0',
57
+ volume_size: options[:volume_boot][:size],
58
+ uuid: options[:volume_boot][:image],
59
+ device_name: options[:volume_boot][:device],
60
+ source_type: 'image',
61
+ destination_type: 'volume',
62
+ delete_on_termination: options[:volume_boot][:delete_on_destroy] }]\
63
+ if options[:volume_boot].key?(:image)
55
64
  else
56
65
  s['imageRef'] = options[:image_ref]
57
66
  end
@@ -64,7 +73,7 @@ module VagrantPlugins
64
73
  s['networks'] = options[:networks] unless options[:networks].nil? || options[:networks].empty?
65
74
  end
66
75
  object = { server: server }
67
- object[:scheduler_hints] = options[:scheduler_hints] unless options[:scheduler_hints].nil?
76
+ object['os:scheduler_hints'] = options[:scheduler_hints] unless options[:scheduler_hints].nil?
68
77
  server = post(env, "#{@session.endpoints[:compute]}/servers", object.to_json)
69
78
  JSON.parse(server)['server']['id']
70
79
  end
@@ -137,7 +146,9 @@ module VagrantPlugins
137
146
  def delete_keypair_if_vagrant(env, server_id)
138
147
  instance_exists do
139
148
  keyname = get_server_details(env, server_id)['key_name']
140
- delete(env, "#{@session.endpoints[:compute]}/os-keypairs/#{keyname}") if keyname.start_with?('vagrant-generated-')
149
+ if keyname
150
+ delete(env, "#{@session.endpoints[:compute]}/os-keypairs/#{keyname}") if keyname.start_with?('vagrant-generated-')
151
+ end
141
152
  end
142
153
  end
143
154
 
@@ -1,4 +1,5 @@
1
1
  require 'vagrant-openstack-provider/client/openstack'
2
+ require 'colorize'
2
3
 
3
4
  module VagrantPlugins
4
5
  module Openstack
@@ -2,7 +2,7 @@ module VagrantPlugins
2
2
  module Openstack
3
3
  module Command
4
4
  COMMANDS = [
5
- { name: :'image-list', file: 'image_list' , clazz: 'ImageList' },
5
+ { name: :'image-list', file: 'image_list', clazz: 'ImageList' },
6
6
  { name: :'flavor-list', file: 'flavor_list', clazz: 'FlavorList' },
7
7
  { name: :'network-list', file: 'network_list', clazz: 'NetworkList' },
8
8
  { name: :'subnet-list', file: 'subnet_list', clazz: 'SubnetList' },
@@ -13,7 +13,6 @@ module VagrantPlugins
13
13
 
14
14
  class Main < Vagrant.plugin('2', :command)
15
15
  def self.synopsis
16
- Openstack.init_i18n
17
16
  I18n.t('vagrant_openstack.command.main_synopsis')
18
17
  end
19
18
 
@@ -33,7 +32,6 @@ module VagrantPlugins
33
32
  end
34
33
 
35
34
  def execute
36
- Openstack.init_i18n
37
35
  command_class = @commands.get(@sub_command.to_sym) if @sub_command
38
36
  return usage unless command_class && @sub_command
39
37
  command_class.new(@sub_args, @env).execute(@sub_command)
@@ -258,7 +258,7 @@ module VagrantPlugins
258
258
  # Don't set the value if it is the unset value, either.
259
259
  value = obj.instance_variable_get(key)
260
260
 
261
- if [:@networks, :@volumes, :@rsync_includes, :@ignore_files, :@floating_ip_pool, :@stacks].include? key
261
+ if [:@networks, :@volumes, :@rsync_includes, :@rsync_ignore_files, :@floating_ip_pool, :@stacks].include? key
262
262
  result.instance_variable_set(key, value) unless value.empty?
263
263
  elsif [:@http].include? key
264
264
  result.instance_variable_set(key, instance_variable_get(key).merge(other.instance_variable_get(key))) if value != UNSET_VALUE
@@ -276,7 +276,7 @@ module VagrantPlugins
276
276
  result
277
277
  end
278
278
 
279
- # rubocop:disable Style/CyclomaticComplexity
279
+ # rubocop:disable Metrics/CyclomaticComplexity
280
280
  def finalize!
281
281
  @password = nil if @password == UNSET_VALUE
282
282
  @openstack_compute_url = nil if @openstack_compute_url == UNSET_VALUE
@@ -323,7 +323,7 @@ module VagrantPlugins
323
323
  @stacks = nil if @stacks.empty?
324
324
  @http.finalize!
325
325
  end
326
- # rubocop:enable Style/CyclomaticComplexity
326
+ # rubocop:enable Metrics/CyclomaticComplexity
327
327
 
328
328
  def rsync_include(inc)
329
329
  @rsync_includes << inc
@@ -25,15 +25,12 @@ module VagrantPlugins
25
25
 
26
26
  def resolve_image(env)
27
27
  @logger.info 'Resolving image'
28
- config = env[:machine].provider_config
29
- return nil if config.image.nil?
30
- nova = env[:openstack_client].nova
31
- env[:ui].info(I18n.t('vagrant_openstack.finding_image'))
32
- images = nova.get_all_images(env)
33
- @logger.info "Finding image matching name '#{config.image}'"
34
- image = find_matching(images, config.image)
35
- fail Errors::NoMatchingImage unless image
36
- image
28
+ resolve_image_internal(env, env[:machine].provider_config.image)
29
+ end
30
+
31
+ def resolve_volume_boot_image(env)
32
+ @logger.info 'Resolving image to create a volume from'
33
+ resolve_image_internal(env, env[:machine].provider_config.volume_boot[:image])
37
34
  end
38
35
 
39
36
  def resolve_floating_ip(env)
@@ -65,7 +62,7 @@ module VagrantPlugins
65
62
  return resolve_networks_without_network_service(env) unless env[:openstack_client].session.endpoints.key? :network
66
63
 
67
64
  all_networks = env[:openstack_client].neutron.get_all_networks(env)
68
- all_network_ids = all_networks.map { |v| v.id }
65
+ all_network_ids = all_networks.map(&:id)
69
66
 
70
67
  networks = []
71
68
  config.networks.each do |network|
@@ -76,20 +73,28 @@ module VagrantPlugins
76
73
  end
77
74
 
78
75
  def resolve_volume_boot(env)
79
- @logger.info 'Resolving image'
80
76
  config = env[:machine].provider_config
81
77
  return nil if config.volume_boot.nil?
82
78
  return resolve_volume_without_volume_service(env, config.volume_boot, 'vda') unless env[:openstack_client].session.endpoints.key? :volume
83
79
 
84
80
  volume_list = env[:openstack_client].cinder.get_all_volumes(env)
85
- volume_ids = volume_list.map { |v| v.id }
81
+ volume_ids = volume_list.map(&:id)
86
82
 
87
83
  @logger.debug(volume_list)
88
84
 
89
85
  volume = resolve_volume(config.volume_boot, volume_list, volume_ids)
90
- device = volume[:device].nil? ? 'vda' : volume[:device]
91
86
 
92
- { id: volume[:id], device: device }
87
+ device = (volume[:device].nil?) ? 'vda' : volume[:device]
88
+ size = (volume[:size].nil?) ? nil : volume[:size]
89
+ delete_on_destroy = (volume[:delete_on_destroy].nil?) ? nil : volume[:delete_on_destroy]
90
+
91
+ image = resolve_volume_boot_image(env) unless volume[:image].nil?
92
+ image_id = (image.nil?) ? nil : image.id
93
+ if image.nil?
94
+ return { id: volume[:id], device: device }
95
+ else
96
+ { image: image_id, device: device, size: size, delete_on_destroy: delete_on_destroy }
97
+ end
93
98
  end
94
99
 
95
100
  def resolve_volumes(env)
@@ -100,7 +105,7 @@ module VagrantPlugins
100
105
  return resolve_volumes_without_volume_service(env) unless env[:openstack_client].session.endpoints.key? :volume
101
106
 
102
107
  volume_list = env[:openstack_client].cinder.get_all_volumes(env)
103
- volume_ids = volume_list.map { |v| v.id }
108
+ volume_ids = volume_list.map(&:id)
104
109
 
105
110
  @logger.debug(volume_list)
106
111
 
@@ -135,6 +140,17 @@ module VagrantPlugins
135
140
 
136
141
  private
137
142
 
143
+ def resolve_image_internal(env, image_name)
144
+ return nil if image_name.nil?
145
+
146
+ nova = env[:openstack_client].nova
147
+ env[:ui].info(I18n.t('vagrant_openstack.finding_image'))
148
+ images = nova.get_all_images(env)
149
+ image = find_matching(images, image_name)
150
+ fail Errors::NoMatchingImage unless image
151
+ image
152
+ end
153
+
138
154
  def search_free_ip(config, nova, env)
139
155
  @logger.debug 'Retrieving all allocated floating ips on tenant'
140
156
  all_floating_ips = nova.get_all_floating_ips(env)
@@ -258,23 +274,37 @@ module VagrantPlugins
258
274
  def resolve_volume_from_hash(volume, volume_list, volume_ids)
259
275
  device = nil
260
276
  device = volume[:device] if volume.key?(:device)
277
+ delete_on_destroy = (volume[:delete_on_destroy].nil?) ? 'true' : volume[:delete_on_destroy]
278
+
279
+ volume_id = nil
261
280
  if volume.key?(:id)
262
281
  fail Errors::ConflictVolumeNameId, volume: volume if volume.key?(:name)
282
+ check_boot_volume_conflict(volume)
263
283
  volume_id = volume[:id]
264
284
  fail Errors::UnresolvedVolumeId, id: volume_id unless volume_ids.include? volume_id
265
285
  elsif volume.key?(:name)
266
286
  volume_list.each do |v|
267
287
  next unless v.name.eql? volume[:name]
268
288
  fail Errors::MultipleVolumeName, name: volume[:name] unless volume_id.nil?
289
+ check_boot_volume_conflict(volume)
269
290
  volume_id = v.id
270
291
  end
271
292
  fail Errors::UnresolvedVolumeName, name: volume[:name] unless volume_ids.include? volume_id
293
+ elsif volume.key?(:image)
294
+ fail Errors::UnresolvedVolume, volume: volume unless volume.key?(:size)
295
+ fail Errors::ConflictBootVolume, volume: volume if volume.key?(:id)
296
+ fail Errors::ConflictBootVolume, volume: volume if volume.key?(:name)
297
+ return { image: volume[:image], device: device, size: volume[:size], delete_on_destroy: delete_on_destroy }
272
298
  else
273
- fail Errors::ConflictVolumeNameId, volume: volume
299
+ fail Errors::ConflictBootVolume, volume: volume
274
300
  end
275
301
  { id: volume_id, device: device }
276
302
  end
277
303
 
304
+ def check_boot_volume_conflict(volume)
305
+ fail Errors::ConflictBootVolume, volume: volume if volume.key?(:image) || volume.key?(:size) || volume.key?(:delete_on_destroy)
306
+ end
307
+
278
308
  # This method finds any matching _thing_ from a list of names
279
309
  # in a collection of _things_. The first to match is the returned
280
310
  # one. Names in list can be a regexp, a partial match is chosen