vagrant-openstack-provider 0.4.1 → 0.5.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.
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
@@ -1,20 +1,30 @@
1
1
  require 'log4r'
2
2
 
3
+ require 'vagrant-openstack-provider/config_resolver'
4
+ require 'vagrant-openstack-provider/utils'
5
+
3
6
  module VagrantPlugins
4
7
  module Openstack
5
8
  module Action
6
9
  # This action reads the SSH info for the machine and puts it into the
7
10
  # `:machine_ssh_info` key in the environment.
8
11
  class ReadSSHInfo
9
- def initialize(app, _env)
12
+ def initialize(app, _env, resolver = ConfigResolver.new, utils = Utils.new)
10
13
  @app = app
11
14
  @logger = Log4r::Logger.new('vagrant_openstack::action::read_ssh_info')
15
+ @resolver = resolver
16
+ @utils = utils
12
17
  end
13
18
 
14
19
  def call(env)
15
20
  @logger.info 'Reading SSH info'
16
- env[:machine_ssh_info] = read_ssh_info(env)
17
-
21
+ server_id = env[:machine].id.to_sym
22
+ SSHInfoHolder.instance.tap do |holder|
23
+ holder.synchronize do
24
+ holder.ssh_info[server_id] = read_ssh_info(env) if holder.ssh_info[server_id].nil?
25
+ env[:machine_ssh_info] = holder.ssh_info[server_id]
26
+ end
27
+ end
18
28
  @app.call(env)
19
29
  end
20
30
 
@@ -22,42 +32,33 @@ module VagrantPlugins
22
32
 
23
33
  def read_ssh_info(env)
24
34
  config = env[:machine].provider_config
35
+ env[:ui].warn('SSH is disabled in the provider config. The action you are attempting is likely to fail') if config.ssh_disabled
25
36
  hash = {
26
- host: get_ip_address(env),
27
- port: resolve_ssh_port(env),
28
- username: resolve_ssh_username(env)
37
+ host: @utils.get_ip_address(env),
38
+ port: @resolver.resolve_ssh_port(env),
39
+ username: @resolver.resolve_ssh_username(env)
29
40
  }
30
41
  hash[:private_key_path] = "#{env[:machine].data_dir}/#{get_keypair_name(env)}" unless config.keypair_name || config.public_key_path
42
+ # Should work silently when https://github.com/mitchellh/vagrant/issues/4637 is fixed
43
+ hash[:log_level] = 'ERROR'
31
44
  hash
32
45
  end
33
46
 
34
- def resolve_ssh_port(env)
35
- machine_config = env[:machine].config
36
- return machine_config.ssh.port if machine_config.ssh.port
37
- 22
47
+ def get_keypair_name(env)
48
+ env[:openstack_client].nova.get_server_details(env, env[:machine].id)['key_name']
38
49
  end
50
+ end
39
51
 
40
- def resolve_ssh_username(env)
41
- config = env[:machine].provider_config
42
- machine_config = env[:machine].config
43
- return machine_config.ssh.username if machine_config.ssh.username
44
- return config.ssh_username if config.ssh_username
45
- fail Errors::NoMatchingSshUsername
46
- end
52
+ class SSHInfoHolder < Mutex
53
+ include Singleton
47
54
 
48
- def get_ip_address(env)
49
- return env[:machine].provider_config.floating_ip unless env[:machine].provider_config.floating_ip.nil?
50
- details = env[:openstack_client].nova.get_server_details(env, env[:machine].id)
51
- details['addresses'].each do |network|
52
- network[1].each do |network_detail|
53
- return network_detail['addr'] if network_detail['OS-EXT-IPS:type'] == 'floating'
54
- end
55
- end
56
- fail Errors::UnableToResolveIP
57
- end
55
+ #
56
+ # Keys are machine ids
57
+ #
58
+ attr_accessor :ssh_info
58
59
 
59
- def get_keypair_name(env)
60
- env[:openstack_client].nova.get_server_details(env, env[:machine].id)['key_name']
60
+ def initialize
61
+ @ssh_info = {}
61
62
  end
62
63
  end
63
64
  end
@@ -12,10 +12,11 @@ module VagrantPlugins
12
12
 
13
13
  def call(env)
14
14
  sync_method = env[:machine].provider_config.sync_method
15
- if sync_method == 'rsync'
15
+ ssh_disabled = env[:machine].provider_config.ssh_disabled
16
+ if sync_method == 'none' || ssh_disabled
17
+ NoSyncFolders.new(@app, env, ssh_disabled).call(env)
18
+ elsif sync_method == 'rsync'
16
19
  RsyncFolders.new(@app, env).call(env)
17
- elsif sync_method == 'none'
18
- NoSyncFolders.new(@app, env).call(env)
19
20
  else
20
21
  fail Errors::SyncMethodError, sync_method_value: sync_method
21
22
  end
@@ -23,13 +24,15 @@ module VagrantPlugins
23
24
  end
24
25
 
25
26
  class NoSyncFolders
26
- def initialize(app, _env)
27
+ def initialize(app, _env, ssh_disabled)
27
28
  @app = app
29
+ @ssh_disabled = ssh_disabled
28
30
  end
29
31
 
30
32
  def call(env)
31
33
  @app.call(env)
32
- env[:ui].info('Sync folders are disabled')
34
+ env[:ui].info('Folders will not be synced because provider config ssh_disabled is set to true') if @ssh_disabled
35
+ env[:ui].info('Sync folders are disabled in the provider configuration') unless @ssh_disabled
33
36
  end
34
37
  end
35
38
 
@@ -60,15 +63,14 @@ module VagrantPlugins
60
63
 
61
64
  # If on Windows, modify the path to work with cygwin rsync
62
65
  if @host_os =~ /mswin|mingw|cygwin/
63
- hostpath = hostpath.sub(/^([A-Za-z]):\//, "/cygdrive/#{Regexp.last_match[1].downcase}/")
66
+ hostpath = add_cygdrive_prefix_to_path(hostpath)
64
67
  end
65
68
 
66
69
  env[:ui].info(I18n.t('vagrant_openstack.rsync_folder', hostpath: hostpath, guestpath: guestpath))
67
70
 
68
71
  # Create the guest path
69
72
  env[:machine].communicate.sudo("mkdir -p '#{guestpath}'")
70
- env[:machine].communicate.sudo(
71
- "chown -R #{ssh_info[:username]} '#{guestpath}'")
73
+ env[:machine].communicate.sudo("chown -R #{ssh_info[:username]} '#{guestpath}'")
72
74
 
73
75
  # Generate rsync include commands
74
76
  includes = rsync_includes.each_with_object([]) do |incl, incls|
@@ -77,12 +79,14 @@ module VagrantPlugins
77
79
  end
78
80
 
79
81
  # Rsync over to the guest path using the SSH info. add
80
- # .hg/ to exclude list as that isn't covered in
82
+ # .hg/ and .git/ to exclude list as that isn't covered in
81
83
  # --cvs-exclude
82
84
  command = [
83
85
  'rsync', '--verbose', '--archive', '-z',
84
86
  '--cvs-exclude',
85
87
  '--exclude', '.hg/',
88
+ '--exclude', '.git/',
89
+ '--chmod', 'ugo=rwX',
86
90
  *includes,
87
91
  '-e', "ssh -p #{ssh_info[:port]} -o StrictHostKeyChecking=no #{ssh_key_options(ssh_info)}",
88
92
  hostpath,
@@ -109,6 +113,12 @@ module VagrantPlugins
109
113
  # Ensure that `private_key_path` is an Array (for Vagrant < 1.4)
110
114
  Array(ssh_info[:private_key_path]).map { |path| "-i '#{path}' " }.join
111
115
  end
116
+
117
+ def add_cygdrive_prefix_to_path(hostpath)
118
+ hostpath.downcase.sub(/^([a-z]):\//) do
119
+ "/cygdrive/#{Regexp.last_match[1]}/"
120
+ end
121
+ end
112
122
  end
113
123
  end
114
124
  end
@@ -0,0 +1,58 @@
1
+ require 'log4r'
2
+
3
+ module VagrantPlugins
4
+ module Openstack
5
+ module Action
6
+ class WaitForServerToBeAccessible
7
+ def initialize(app, env, resolver = nil, ssh = nil)
8
+ @logger = Log4r::Logger.new('vagrant_openstack::action::wait_accessible')
9
+ @app = app
10
+ @ssh = ssh || Vagrant::Action::Builtin::SSHRun.new(app, env)
11
+ @resolver = resolver || VagrantPlugins::Openstack::ConfigResolver.new
12
+ end
13
+
14
+ def call(env)
15
+ waiting_for_server_to_be_reachable(env)
16
+ @logger.info 'The server is ready'
17
+ env[:ui].info(I18n.t('vagrant_openstack.ready'))
18
+ @app.call(env)
19
+ end
20
+
21
+ private
22
+
23
+ def waiting_for_server_to_be_reachable(env)
24
+ return if env[:interrupted]
25
+ ssh_timeout = env[:machine].provider_config.ssh_timeout
26
+ return if server_is_reachable?(env, ssh_timeout)
27
+ env[:ui].error(I18n.t('vagrant_openstack.timeout'))
28
+ fail Errors::SshUnavailable, host: @resolver.resolve_floating_ip(env), timeout: ssh_timeout
29
+ end
30
+
31
+ def server_is_reachable?(env, timeout)
32
+ start_time = Time.now
33
+ current_time = start_time
34
+ nb_retry = 0
35
+
36
+ while (current_time - start_time) <= timeout
37
+ @logger.debug "Checking if SSH port is open... Attempt number #{nb_retry}"
38
+ if nb_retry % 5 == 0
39
+ @logger.info 'Waiting for SSH to become available...'
40
+ env[:ui].info(I18n.t('vagrant_openstack.waiting_for_ssh'))
41
+ end
42
+
43
+ env[:ssh_run_command] = 'exit 0'
44
+ @ssh.call(env)
45
+ return true if env[:ssh_run_exit_status] == 0
46
+
47
+ @logger.debug 'SSH not yet available... new retry in in 1 second'
48
+ nb_retry += 1
49
+ sleep 1
50
+ current_time = Time.now
51
+ end
52
+
53
+ false
54
+ end
55
+ end
56
+ end
57
+ end
58
+ end
@@ -5,18 +5,20 @@ module VagrantPlugins
5
5
  module Openstack
6
6
  module Action
7
7
  class WaitForServerToBeActive
8
- def initialize(app, _env)
8
+ def initialize(app, _env, retry_interval = 3, timeout = 200)
9
9
  @app = app
10
10
  @logger = Log4r::Logger.new('vagrant_openstack::action::start_server')
11
+ @retry_interval = retry_interval
12
+ @timeout = timeout
11
13
  end
12
14
 
13
15
  def call(env)
14
16
  if env[:machine].id
15
17
  env[:ui].info(I18n.t('vagrant_openstack.waiting_start'))
16
18
  client = env[:openstack_client].nova
17
- timeout(200) do
19
+ timeout(@timeout) do
18
20
  while client.get_server_details(env, env[:machine].id)['status'] != 'ACTIVE'
19
- sleep 3
21
+ sleep @retry_interval
20
22
  @logger.info('Waiting for server to be active')
21
23
  end
22
24
  end
@@ -5,18 +5,20 @@ module VagrantPlugins
5
5
  module Openstack
6
6
  module Action
7
7
  class WaitForServerToStop
8
- def initialize(app, _env)
8
+ def initialize(app, _env, retry_interval = 3, timeout = 200)
9
9
  @app = app
10
10
  @logger = Log4r::Logger.new('vagrant_openstack::action::stop_server')
11
+ @retry_interval = retry_interval
12
+ @timeout = timeout
11
13
  end
12
14
 
13
15
  def call(env)
14
16
  if env[:machine].id
15
17
  env[:ui].info(I18n.t('vagrant_openstack.waiting_stop'))
16
18
  client = env[:openstack_client].nova
17
- timeout(200) do
19
+ timeout(@timeout) do
18
20
  while client.get_server_details(env, env[:machine].id)['status'] != 'SHUTOFF'
19
- sleep 3
21
+ sleep @retry_interval
20
22
  @logger.info('Waiting for server to stop')
21
23
  end
22
24
  end
@@ -10,7 +10,7 @@ module VagrantPlugins
10
10
 
11
11
  # This action is called to destroy the remote machine.
12
12
  def self.action_destroy
13
- Vagrant::Action::Builder.new.tap do |b|
13
+ new_builder.tap do |b|
14
14
  b.use ConfigValidate
15
15
  b.use ConnectOpenstack
16
16
  b.use Call, ReadState do |env, b2|
@@ -25,7 +25,7 @@ module VagrantPlugins
25
25
 
26
26
  # This action is called when `vagrant provision` is called.
27
27
  def self.action_provision
28
- Vagrant::Action::Builder.new.tap do |b|
28
+ new_builder.tap do |b|
29
29
  b.use ConfigValidate
30
30
  b.use ConnectOpenstack
31
31
  b.use Call, ReadState do |env, b2|
@@ -43,7 +43,7 @@ module VagrantPlugins
43
43
  # resulting state is expected to be put into the `:machine_ssh_info`
44
44
  # key.
45
45
  def self.action_read_ssh_info
46
- Vagrant::Action::Builder.new.tap do |b|
46
+ new_builder.tap do |b|
47
47
  b.use ConfigValidate
48
48
  b.use ConnectOpenstack
49
49
  b.use ReadSSHInfo
@@ -54,7 +54,7 @@ module VagrantPlugins
54
54
  # resulting state is expected to be put into the `:machine_state_id`
55
55
  # key.
56
56
  def self.action_read_state
57
- Vagrant::Action::Builder.new.tap do |b|
57
+ new_builder.tap do |b|
58
58
  b.use ConfigValidate
59
59
  b.use ConnectOpenstack
60
60
  b.use ReadState
@@ -62,7 +62,7 @@ module VagrantPlugins
62
62
  end
63
63
 
64
64
  def self.action_ssh
65
- Vagrant::Action::Builder.new.tap do |b|
65
+ new_builder.tap do |b|
66
66
  b.use ConfigValidate
67
67
  b.use ConnectOpenstack
68
68
  b.use Call, ReadState do |env, b2|
@@ -76,7 +76,7 @@ module VagrantPlugins
76
76
  end
77
77
 
78
78
  def self.action_ssh_run
79
- Vagrant::Action::Builder.new.tap do |b|
79
+ new_builder.tap do |b|
80
80
  b.use ConfigValidate
81
81
  b.use ConnectOpenstack
82
82
  b.use Call, ReadState do |env, b2|
@@ -90,7 +90,7 @@ module VagrantPlugins
90
90
  end
91
91
 
92
92
  def self.action_up
93
- Vagrant::Action::Builder.new.tap do |b|
93
+ new_builder.tap do |b|
94
94
  b.use ConfigValidate
95
95
  b.use ConnectOpenstack
96
96
 
@@ -100,6 +100,7 @@ module VagrantPlugins
100
100
  b2.use Provision
101
101
  b2.use SyncFolders
102
102
  b2.use CreateServer
103
+ b2.use WaitForServerToBeAccessible
103
104
  when :shutoff
104
105
  b2.use StartServer
105
106
  when :suspended
@@ -112,7 +113,7 @@ module VagrantPlugins
112
113
  end
113
114
 
114
115
  def self.action_halt
115
- Vagrant::Action::Builder.new.tap do |b|
116
+ new_builder.tap do |b|
116
117
  b.use ConfigValidate
117
118
  b.use ConnectOpenstack
118
119
  b.use Call, ReadState do |env, b2|
@@ -128,7 +129,7 @@ module VagrantPlugins
128
129
  # This is the action that is primarily responsible for suspending
129
130
  # the virtual machine.
130
131
  def self.action_suspend
131
- Vagrant::Action::Builder.new.tap do |b|
132
+ new_builder.tap do |b|
132
133
  b.use ConfigValidate
133
134
  b.use ConnectOpenstack
134
135
  b.use Call, ReadState do |env, b2|
@@ -146,7 +147,7 @@ module VagrantPlugins
146
147
  # This is the action that is primarily responsible for resuming
147
148
  # suspended machines.
148
149
  def self.action_resume
149
- Vagrant::Action::Builder.new.tap do |b|
150
+ new_builder.tap do |b|
150
151
  b.use ConfigValidate
151
152
  b.use ConnectOpenstack
152
153
  b.use Call, ReadState do |env, b2|
@@ -160,7 +161,7 @@ module VagrantPlugins
160
161
  end
161
162
 
162
163
  def self.action_reload
163
- Vagrant::Action::Builder.new.tap do |b|
164
+ new_builder.tap do |b|
164
165
  b.use ConfigValidate
165
166
  b.use ConnectOpenstack
166
167
  b.use Call, ReadState do |env, b2|
@@ -199,6 +200,13 @@ module VagrantPlugins
199
200
  autoload :Resume, action_root.join('resume')
200
201
  autoload :WaitForServerToStop, action_root.join('wait_stop')
201
202
  autoload :WaitForServerToBeActive, action_root.join('wait_active')
203
+ autoload :WaitForServerToBeAccessible, action_root.join('wait_accessible')
204
+
205
+ private
206
+
207
+ def self.new_builder
208
+ Vagrant::Action::Builder.new
209
+ end
202
210
  end
203
211
  end
204
212
  end
@@ -72,9 +72,10 @@ module VagrantPlugins
72
72
  when 401
73
73
  fail Errors::AuthenticationRequired
74
74
  when 400, 404, 409
75
- fail Errors::VagrantOpenstackError, message: JSON.parse(response.to_s)[ERRORS[response.code.to_s]]['message']
75
+ message = JSON.parse(response.to_s)[ERRORS[response.code.to_s]]['message']
76
+ fail Errors::VagrantOpenstackError, message: message, code: response.code
76
77
  else
77
- fail Errors::VagrantOpenstackError, message: response.to_s
78
+ fail Errors::VagrantOpenstackError, message: response.to_s, code: response.code
78
79
  end
79
80
  end
80
81
 
@@ -33,10 +33,20 @@ module VagrantPlugins
33
33
  end
34
34
 
35
35
  def get_private_networks(env)
36
+ get_networks(env, false)
37
+ end
38
+
39
+ def get_all_networks(env)
40
+ get_networks(env, true)
41
+ end
42
+
43
+ private
44
+
45
+ def get_networks(env, all)
36
46
  networks_json = get(env, "#{@session.endpoints[:network]}/networks")
37
47
  networks = []
38
48
  JSON.parse(networks_json)['networks'].each do |n|
39
- networks << Item.new(n['id'], n['name']) if n['tenant_id'].eql? @session.project_id
49
+ networks << Item.new(n['id'], n['name']) if all || n['tenant_id'].eql?(@session.project_id)
40
50
  end
41
51
  networks
42
52
  end
@@ -27,7 +27,7 @@ module VagrantPlugins
27
27
  def get_all_floating_ips(env)
28
28
  ips_json = get(env, "#{@session.endpoints[:compute]}/os-floating-ips",
29
29
  'X-Auth-Token' => @session.token,
30
- :accept => :json) { |res| handle_response(res) }
30
+ :accept => :json)
31
31
  JSON.parse(ips_json)['floating_ips'].map { |n| FloatingIP.new(n['ip'], n['pool'], n['instance_id']) }
32
32
  end
33
33
 
@@ -38,7 +38,7 @@ module VagrantPlugins
38
38
  }.to_json,
39
39
  'X-Auth-Token' => @session.token,
40
40
  :accept => :json,
41
- :content_type => :json) { |res| handle_response(res) }
41
+ :content_type => :json)
42
42
  floating_ip = JSON.parse(ips_json)['floating_ip']
43
43
  FloatingIP.new(floating_ip['ip'], floating_ip['pool'], floating_ip['instance_id'])
44
44
  end
@@ -60,14 +60,9 @@ module VagrantPlugins
60
60
  s['key_name'] = options[:keypair]
61
61
  s['availability_zone'] = options[:availability_zone] unless options[:availability_zone].nil?
62
62
  s['security_groups'] = options[:security_groups] unless options[:security_groups].nil?
63
- s['user_data'] = options[:user_data] unless options[:user_data].nil?
63
+ s['user_data'] = Base64.encode64(options[:user_data]) unless options[:user_data].nil?
64
64
  s['metadata'] = options[:metadata] unless options[:metadata].nil?
65
- unless options[:networks].nil? || options[:networks].empty?
66
- s['networks'] = []
67
- options[:networks].each do |uuid|
68
- s['networks'] << { uuid: uuid }
69
- end
70
- end
65
+ s['networks'] = options[:networks] unless options[:networks].nil? || options[:networks].empty?
71
66
  end
72
67
  object = { server: server }
73
68
  object[:scheduler_hints] = options[:scheduler_hints] unless options[:scheduler_hints].nil?
@@ -76,36 +71,49 @@ module VagrantPlugins
76
71
  end
77
72
 
78
73
  def delete_server(env, server_id)
79
- delete(env, "#{@session.endpoints[:compute]}/servers/#{server_id}")
74
+ instance_exists do
75
+ delete(env, "#{@session.endpoints[:compute]}/servers/#{server_id}")
76
+ end
80
77
  end
81
78
 
82
79
  def suspend_server(env, server_id)
83
- change_server_state(env, server_id, :suspend)
80
+ instance_exists do
81
+ change_server_state(env, server_id, :suspend)
82
+ end
84
83
  end
85
84
 
86
85
  def resume_server(env, server_id)
87
- # TODO(julienvey) check status before (if pause->unpause, if suspend->resume...)
88
- change_server_state(env, server_id, :resume)
86
+ instance_exists do
87
+ change_server_state(env, server_id, :resume)
88
+ end
89
89
  end
90
90
 
91
91
  def stop_server(env, server_id)
92
- change_server_state(env, server_id, :stop)
92
+ instance_exists do
93
+ change_server_state(env, server_id, :stop)
94
+ end
93
95
  end
94
96
 
95
97
  def start_server(env, server_id)
96
- change_server_state(env, server_id, :start)
98
+ instance_exists do
99
+ change_server_state(env, server_id, :start)
100
+ end
97
101
  end
98
102
 
99
103
  def get_server_details(env, server_id)
100
- server_details = get(env, "#{@session.endpoints[:compute]}/servers/#{server_id}")
101
- JSON.parse(server_details)['server']
104
+ instance_exists do
105
+ server_details = get(env, "#{@session.endpoints[:compute]}/servers/#{server_id}")
106
+ JSON.parse(server_details)['server']
107
+ end
102
108
  end
103
109
 
104
110
  def add_floating_ip(env, server_id, floating_ip)
105
- check_floating_ip(env, floating_ip)
111
+ instance_exists do
112
+ check_floating_ip(env, floating_ip)
106
113
 
107
- post(env, "#{@session.endpoints[:compute]}/servers/#{server_id}/action",
108
- { addFloatingIp: { address: floating_ip } }.to_json)
114
+ post(env, "#{@session.endpoints[:compute]}/servers/#{server_id}/action",
115
+ { addFloatingIp: { address: floating_ip } }.to_json)
116
+ end
109
117
  end
110
118
 
111
119
  def import_keypair(env, public_key)
@@ -128,8 +136,10 @@ module VagrantPlugins
128
136
  end
129
137
 
130
138
  def delete_keypair_if_vagrant(env, server_id)
131
- keyname = get_server_details(env, server_id)['key_name']
132
- delete(env, "#{@session.endpoints[:compute]}/os-keypairs/#{keyname}") if keyname.start_with?('vagrant-generated-')
139
+ instance_exists do
140
+ keyname = get_server_details(env, server_id)['key_name']
141
+ delete(env, "#{@session.endpoints[:compute]}/os-keypairs/#{keyname}") if keyname.start_with?('vagrant-generated-')
142
+ end
133
143
  end
134
144
 
135
145
  def get_floating_ip_pools(env)
@@ -143,14 +153,16 @@ module VagrantPlugins
143
153
  end
144
154
 
145
155
  def attach_volume(env, server_id, volume_id, device = nil)
146
- attachment = post(env, "#{@session.endpoints[:compute]}/servers/#{server_id}/os-volume_attachments",
147
- {
148
- volumeAttachment: {
149
- volumeId: volume_id,
150
- device: device
151
- }
152
- }.to_json)
153
- JSON.parse(attachment)['volumeAttachment']
156
+ instance_exists do
157
+ attachment = post(env, "#{@session.endpoints[:compute]}/servers/#{server_id}/os-volume_attachments",
158
+ {
159
+ volumeAttachment: {
160
+ volumeId: volume_id,
161
+ device: device
162
+ }
163
+ }.to_json)
164
+ JSON.parse(attachment)['volumeAttachment']
165
+ end
154
166
  end
155
167
 
156
168
  private
@@ -163,6 +175,13 @@ module VagrantPlugins
163
175
  stop: 'os-stop'
164
176
  }
165
177
 
178
+ def instance_exists
179
+ return yield
180
+ rescue Errors::VagrantOpenstackError => e
181
+ raise Errors::InstanceNotFound if e.extra_data[:code] == 404
182
+ raise e
183
+ end
184
+
166
185
  def change_server_state(env, server_id, new_state)
167
186
  post(env, "#{@session.endpoints[:compute]}/servers/#{server_id}/action",
168
187
  { :"#{VM_STATES[new_state.to_sym]}" => nil }.to_json)