vagrant-openstack-provider 0.5.2 → 0.6.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (59) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +34 -0
  3. data/lib/vagrant-openstack-provider.rb +2 -31
  4. data/lib/vagrant-openstack-provider/action.rb +21 -7
  5. data/lib/vagrant-openstack-provider/action/abstract_action.rb +22 -0
  6. data/lib/vagrant-openstack-provider/action/connect_openstack.rb +19 -40
  7. data/lib/vagrant-openstack-provider/action/create_server.rb +10 -6
  8. data/lib/vagrant-openstack-provider/action/create_stack.rb +67 -0
  9. data/lib/vagrant-openstack-provider/action/delete_server.rb +28 -3
  10. data/lib/vagrant-openstack-provider/action/delete_stack.rb +72 -0
  11. data/lib/vagrant-openstack-provider/action/message.rb +4 -2
  12. data/lib/vagrant-openstack-provider/action/read_ssh_info.rb +4 -2
  13. data/lib/vagrant-openstack-provider/action/read_state.rb +9 -4
  14. data/lib/vagrant-openstack-provider/action/resume.rb +4 -2
  15. data/lib/vagrant-openstack-provider/action/start_server.rb +4 -2
  16. data/lib/vagrant-openstack-provider/action/stop_server.rb +4 -2
  17. data/lib/vagrant-openstack-provider/action/suspend.rb +4 -2
  18. data/lib/vagrant-openstack-provider/action/sync_folders.rb +17 -13
  19. data/lib/vagrant-openstack-provider/action/wait_accessible.rb +5 -2
  20. data/lib/vagrant-openstack-provider/action/wait_active.rb +5 -3
  21. data/lib/vagrant-openstack-provider/action/wait_stop.rb +5 -3
  22. data/lib/vagrant-openstack-provider/catalog/openstack_catalog.rb +66 -0
  23. data/lib/vagrant-openstack-provider/client/domain.rb +41 -1
  24. data/lib/vagrant-openstack-provider/client/glance.rb +63 -0
  25. data/lib/vagrant-openstack-provider/client/heat.rb +50 -0
  26. data/lib/vagrant-openstack-provider/client/http_utils.rb +18 -0
  27. data/lib/vagrant-openstack-provider/client/neutron.rb +9 -15
  28. data/lib/vagrant-openstack-provider/client/nova.rb +3 -3
  29. data/lib/vagrant-openstack-provider/client/openstack.rb +10 -0
  30. data/lib/vagrant-openstack-provider/command/abstract_command.rb +7 -0
  31. data/lib/vagrant-openstack-provider/command/image_list.rb +12 -2
  32. data/lib/vagrant-openstack-provider/command/main.rb +1 -0
  33. data/lib/vagrant-openstack-provider/command/network_list.rb +3 -3
  34. data/lib/vagrant-openstack-provider/command/subnet_list.rb +25 -0
  35. data/lib/vagrant-openstack-provider/config.rb +78 -7
  36. data/lib/vagrant-openstack-provider/config_resolver.rb +36 -5
  37. data/lib/vagrant-openstack-provider/errors.rb +30 -2
  38. data/lib/vagrant-openstack-provider/logging.rb +39 -0
  39. data/lib/vagrant-openstack-provider/version.rb +1 -1
  40. data/locales/en.yml +107 -4
  41. data/spec/vagrant-openstack-provider/action/connect_openstack_spec.rb +255 -8
  42. data/spec/vagrant-openstack-provider/action/create_server_spec.rb +6 -1
  43. data/spec/vagrant-openstack-provider/action/create_stack_spec.rb +97 -0
  44. data/spec/vagrant-openstack-provider/action/delete_server_spec.rb +34 -6
  45. data/spec/vagrant-openstack-provider/action/delete_stack_spec.rb +64 -0
  46. data/spec/vagrant-openstack-provider/action/read_state_spec.rb +13 -1
  47. data/spec/vagrant-openstack-provider/action/sync_folders_spec.rb +1 -0
  48. data/spec/vagrant-openstack-provider/action/wait_active_spec.rb +1 -1
  49. data/spec/vagrant-openstack-provider/action/wait_stop_spec.rb +1 -1
  50. data/spec/vagrant-openstack-provider/client/glance_spec.rb +128 -0
  51. data/spec/vagrant-openstack-provider/client/heat_spec.rb +124 -0
  52. data/spec/vagrant-openstack-provider/client/neutron_spec.rb +33 -1
  53. data/spec/vagrant-openstack-provider/client/nova_spec.rb +2 -2
  54. data/spec/vagrant-openstack-provider/command/image_list_spec.rb +75 -23
  55. data/spec/vagrant-openstack-provider/command/subnet_list_spec.rb +46 -0
  56. data/spec/vagrant-openstack-provider/config_resolver_spec.rb +85 -19
  57. data/spec/vagrant-openstack-provider/config_spec.rb +177 -1
  58. data/spec/vagrant-openstack-provider/spec_helper.rb +3 -0
  59. metadata +20 -2
@@ -0,0 +1,72 @@
1
+ require 'log4r'
2
+ require 'socket'
3
+ require 'timeout'
4
+ require 'sshkey'
5
+ require 'yaml'
6
+
7
+ require 'vagrant-openstack-provider/config_resolver'
8
+ require 'vagrant-openstack-provider/utils'
9
+ require 'vagrant-openstack-provider/action/abstract_action'
10
+ require 'vagrant/util/retryable'
11
+
12
+ module VagrantPlugins
13
+ module Openstack
14
+ module Action
15
+ class DeleteStack < AbstractAction
16
+ def initialize(app, _env)
17
+ @app = app
18
+ @logger = Log4r::Logger.new('vagrant_openstack::action::delete_stack')
19
+ end
20
+
21
+ def execute(env)
22
+ @logger.info 'Start delete stacks action'
23
+
24
+ heat = env[:openstack_client].heat
25
+
26
+ list_stack_files(env).each do |stack|
27
+ env[:ui].info(I18n.t('vagrant_openstack.delete_stack'))
28
+ env[:ui].info(" -- Stack Name : #{stack[:name]}")
29
+ env[:ui].info(" -- Stack Id : #{stack[:id]}")
30
+
31
+ heat.delete_stack(env, stack[:name], stack[:id])
32
+
33
+ waiting_for_stack_to_be_deleted(env, stack[:name], stack[:id])
34
+ end
35
+
36
+ # This will remove all files in the .vagrant instance directory
37
+ env[:machine].id = nil
38
+
39
+ @app.call(env)
40
+ end
41
+
42
+ private
43
+
44
+ def list_stack_files(env)
45
+ stack_files = []
46
+ Dir.glob("#{env[:machine].data_dir}/stack_*_id") do |stack_file|
47
+ file_name = stack_file.split('/')[-1]
48
+ stack_files << {
49
+ name: file_name[6, (file_name.length) - 9],
50
+ id: File.read("#{stack_file}")
51
+ }
52
+ end
53
+ stack_files
54
+ end
55
+
56
+ def waiting_for_stack_to_be_deleted(env, stack_name, stack_id, retry_interval = 3, timeout = 200)
57
+ @logger.info "Waiting for the stack with id #{stack_id} to be deleted..."
58
+ env[:ui].info(I18n.t('vagrant_openstack.waiting_for_stack_deleted'))
59
+ timeout(timeout, Errors::Timeout) do
60
+ stack_status = 'DELETE_IN_PROGRESS'
61
+ until stack_status == 'DELETE_COMPLETE'
62
+ @logger.debug('Waiting for stack to be DELETED')
63
+ stack_status = env[:openstack_client].heat.get_stack_details(env, stack_name, stack_id)['stack_status']
64
+ fail Errors::StackStatusError, stack: stack_id if stack_status == 'DELETE_FAILED'
65
+ sleep retry_interval
66
+ end
67
+ end
68
+ end
69
+ end
70
+ end
71
+ end
72
+ end
@@ -1,13 +1,15 @@
1
+ require 'vagrant-openstack-provider/action/abstract_action'
2
+
1
3
  module VagrantPlugins
2
4
  module Openstack
3
5
  module Action
4
- class Message
6
+ class Message < AbstractAction
5
7
  def initialize(app, _env, message)
6
8
  @app = app
7
9
  @message = message
8
10
  end
9
11
 
10
- def call(env)
12
+ def execute(env)
11
13
  env[:ui].info(@message)
12
14
  @app.call(env)
13
15
  end
@@ -2,13 +2,15 @@ require 'log4r'
2
2
 
3
3
  require 'vagrant-openstack-provider/config_resolver'
4
4
  require 'vagrant-openstack-provider/utils'
5
+ require 'vagrant-openstack-provider/action/abstract_action'
5
6
 
6
7
  module VagrantPlugins
7
8
  module Openstack
8
9
  module Action
9
10
  # This action reads the SSH info for the machine and puts it into the
10
11
  # `:machine_ssh_info` key in the environment.
11
- class ReadSSHInfo
12
+
13
+ class ReadSSHInfo < AbstractAction
12
14
  def initialize(app, _env, resolver = ConfigResolver.new, utils = Utils.new)
13
15
  @app = app
14
16
  @logger = Log4r::Logger.new('vagrant_openstack::action::read_ssh_info')
@@ -16,7 +18,7 @@ module VagrantPlugins
16
18
  @utils = utils
17
19
  end
18
20
 
19
- def call(env)
21
+ def execute(env)
20
22
  @logger.info 'Reading SSH info'
21
23
  server_id = env[:machine].id.to_sym
22
24
  SSHInfoHolder.instance.tap do |holder|
@@ -1,17 +1,19 @@
1
1
  require 'log4r'
2
2
 
3
+ require 'vagrant-openstack-provider/action/abstract_action'
4
+
3
5
  module VagrantPlugins
4
6
  module Openstack
5
7
  module Action
6
8
  # This action reads the state of the machine and puts it in the
7
9
  # `:machine_state_id` key in the environment.
8
- class ReadState
10
+ class ReadState < AbstractAction
9
11
  def initialize(app, _env)
10
12
  @app = app
11
13
  @logger = Log4r::Logger.new('vagrant_openstack::action::read_state')
12
14
  end
13
15
 
14
- def call(env)
16
+ def execute(env)
15
17
  env[:machine_state_id] = read_state(env)
16
18
  @app.call(env)
17
19
  end
@@ -29,8 +31,11 @@ module VagrantPlugins
29
31
  return :not_created
30
32
  end
31
33
 
32
- # Return the state
33
- server['status'].downcase.to_sym
34
+ if !server['OS-EXT-STS:task_state'].nil?
35
+ server['OS-EXT-STS:task_state'].downcase.to_sym
36
+ else
37
+ server['status'].downcase.to_sym
38
+ end
34
39
  end
35
40
  end
36
41
  end
@@ -1,13 +1,15 @@
1
+ require 'vagrant-openstack-provider/action/abstract_action'
2
+
1
3
  module VagrantPlugins
2
4
  module Openstack
3
5
  module Action
4
- class Resume
6
+ class Resume < AbstractAction
5
7
  def initialize(app, _env)
6
8
  @app = app
7
9
  @logger = Log4r::Logger.new('vagrant_openstack::action::resume_server')
8
10
  end
9
11
 
10
- def call(env)
12
+ def execute(env)
11
13
  if env[:machine].id
12
14
  @logger.info "Resuming suspended VM #{env[:machine].id}..."
13
15
  env[:ui].info I18n.t('vagrant.actions.vm.resume.resuming')
@@ -1,15 +1,17 @@
1
1
  require 'log4r'
2
2
 
3
+ require 'vagrant-openstack-provider/action/abstract_action'
4
+
3
5
  module VagrantPlugins
4
6
  module Openstack
5
7
  module Action
6
- class StartServer
8
+ class StartServer < AbstractAction
7
9
  def initialize(app, _env)
8
10
  @app = app
9
11
  @logger = Log4r::Logger.new('vagrant_openstack::action::start_server')
10
12
  end
11
13
 
12
- def call(env)
14
+ def execute(env)
13
15
  if env[:machine].id
14
16
  env[:ui].info(I18n.t('vagrant_openstack.starting_server'))
15
17
  env[:openstack_client].nova.start_server(env, env[:machine].id)
@@ -1,15 +1,17 @@
1
1
  require 'log4r'
2
2
 
3
+ require 'vagrant-openstack-provider/action/abstract_action'
4
+
3
5
  module VagrantPlugins
4
6
  module Openstack
5
7
  module Action
6
- class StopServer
8
+ class StopServer < AbstractAction
7
9
  def initialize(app, _env)
8
10
  @app = app
9
11
  @logger = Log4r::Logger.new('vagrant_openstack::action::stop_server')
10
12
  end
11
13
 
12
- def call(env)
14
+ def execute(env)
13
15
  if env[:machine].id
14
16
  @logger.info "Stopping server #{env[:machine].id}..."
15
17
  env[:ui].info(I18n.t('vagrant_openstack.stopping_server'))
@@ -1,13 +1,15 @@
1
+ require 'vagrant-openstack-provider/action/abstract_action'
2
+
1
3
  module VagrantPlugins
2
4
  module Openstack
3
5
  module Action
4
- class Suspend
6
+ class Suspend < AbstractAction
5
7
  def initialize(app, _env)
6
8
  @app = app
7
9
  @logger = Log4r::Logger.new('vagrant_openstack::action::suspend_server')
8
10
  end
9
11
 
10
- def call(env)
12
+ def execute(env)
11
13
  if env[:machine].id
12
14
  @logger.info "Saving VM #{env[:machine].id} state and suspending execution..."
13
15
  env[:ui].info I18n.t('vagrant.actions.vm.suspend.suspending')
@@ -2,19 +2,20 @@ require 'log4r'
2
2
  require 'rbconfig'
3
3
  require 'vagrant/util/subprocess'
4
4
 
5
+ require 'vagrant-openstack-provider/action/abstract_action'
6
+
5
7
  module VagrantPlugins
6
8
  module Openstack
7
9
  module Action
8
- class SyncFolders
10
+ class SyncFolders < AbstractAction
9
11
  def initialize(app, _env)
10
12
  @app = app
11
13
  end
12
14
 
13
- def call(env)
15
+ def execute(env)
14
16
  sync_method = env[:machine].provider_config.sync_method
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)
17
+ if sync_method == 'none'
18
+ NoSyncFolders.new(@app, env).call(env)
18
19
  elsif sync_method == 'rsync'
19
20
  RsyncFolders.new(@app, env).call(env)
20
21
  else
@@ -24,15 +25,13 @@ module VagrantPlugins
24
25
  end
25
26
 
26
27
  class NoSyncFolders
27
- def initialize(app, _env, ssh_disabled)
28
+ def initialize(app, _env)
28
29
  @app = app
29
- @ssh_disabled = ssh_disabled
30
30
  end
31
31
 
32
32
  def call(env)
33
33
  @app.call(env)
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
34
+ env[:ui].info(I18n.t('vagrant_openstack.disabled_sync_folders'))
36
35
  end
37
36
  end
38
37
 
@@ -48,6 +47,11 @@ module VagrantPlugins
48
47
  def call(env)
49
48
  @app.call(env)
50
49
 
50
+ if env[:machine].provider_config.ssh_disabled
51
+ env[:ui].info(I18n.t('vagrant_openstack.ssh_disabled_sync_folders'))
52
+ return
53
+ end
54
+
51
55
  ssh_info = env[:machine].ssh_info
52
56
 
53
57
  config = env[:machine].provider_config
@@ -93,14 +97,14 @@ module VagrantPlugins
93
97
  "#{ssh_info[:username]}@#{ssh_info[:host]}:#{guestpath}"]
94
98
  command.compact!
95
99
 
96
- # during rsync, ignore files specified in .hgignore and
97
- # .gitignore traditional .gitignore or .hgignore files
98
- ignore_files = ['.hgignore', '.gitignore']
100
+ # during rsync, ignore files specified in list of files containing exclude patterns
101
+ # ex: rsync_ignore_files = ['.hgignore', '.gitignore']
102
+ ignore_files = []
103
+ ignore_files = env[:machine].provider_config.rsync_ignore_files unless env[:machine].provider_config.rsync_ignore_files.nil?
99
104
  ignore_files.each do |ignore_file|
100
105
  abs_ignore_file = env[:root_path].to_s + '/' + ignore_file
101
106
  command += ['--exclude-from', abs_ignore_file] if File.exist?(abs_ignore_file)
102
107
  end
103
-
104
108
  r = Vagrant::Util::Subprocess.execute(*command)
105
109
  next if r.exit_code == 0
106
110
  fail Errors::RsyncError, guestpath: guestpath, hostpath: hostpath, stderr: r.stderr
@@ -3,7 +3,7 @@ require 'log4r'
3
3
  module VagrantPlugins
4
4
  module Openstack
5
5
  module Action
6
- class WaitForServerToBeAccessible
6
+ class WaitForServerToBeAccessible < AbstractAction
7
7
  def initialize(app, env, resolver = nil, ssh = nil)
8
8
  @logger = Log4r::Logger.new('vagrant_openstack::action::wait_accessible')
9
9
  @app = app
@@ -11,7 +11,7 @@ module VagrantPlugins
11
11
  @resolver = resolver || VagrantPlugins::Openstack::ConfigResolver.new
12
12
  end
13
13
 
14
- def call(env)
14
+ def execute(env)
15
15
  waiting_for_server_to_be_reachable(env)
16
16
  @logger.info 'The server is ready'
17
17
  env[:ui].info(I18n.t('vagrant_openstack.ready'))
@@ -41,6 +41,9 @@ module VagrantPlugins
41
41
  end
42
42
 
43
43
  env[:ssh_run_command] = 'exit 0'
44
+ env[:ssh_opts] = {
45
+ extra_args: ['-o', 'BatchMode=yes']
46
+ }
44
47
  @ssh.call(env)
45
48
  return true if env[:ssh_run_exit_status] == 0
46
49
 
@@ -1,10 +1,12 @@
1
1
  require 'log4r'
2
2
  require 'timeout'
3
3
 
4
+ require 'vagrant-openstack-provider/action/abstract_action'
5
+
4
6
  module VagrantPlugins
5
7
  module Openstack
6
8
  module Action
7
- class WaitForServerToBeActive
9
+ class WaitForServerToBeActive < AbstractAction
8
10
  def initialize(app, _env, retry_interval = 3, timeout = 200)
9
11
  @app = app
10
12
  @logger = Log4r::Logger.new('vagrant_openstack::action::start_server')
@@ -12,11 +14,11 @@ module VagrantPlugins
12
14
  @timeout = timeout
13
15
  end
14
16
 
15
- def call(env)
17
+ def execute(env)
16
18
  if env[:machine].id
17
19
  env[:ui].info(I18n.t('vagrant_openstack.waiting_start'))
18
20
  client = env[:openstack_client].nova
19
- timeout(@timeout) do
21
+ timeout(@timeout, Errors::Timeout) do
20
22
  while client.get_server_details(env, env[:machine].id)['status'] != 'ACTIVE'
21
23
  sleep @retry_interval
22
24
  @logger.info('Waiting for server to be active')
@@ -1,10 +1,12 @@
1
1
  require 'log4r'
2
2
  require 'timeout'
3
3
 
4
+ require 'vagrant-openstack-provider/action/abstract_action'
5
+
4
6
  module VagrantPlugins
5
7
  module Openstack
6
8
  module Action
7
- class WaitForServerToStop
9
+ class WaitForServerToStop < AbstractAction
8
10
  def initialize(app, _env, retry_interval = 3, timeout = 200)
9
11
  @app = app
10
12
  @logger = Log4r::Logger.new('vagrant_openstack::action::stop_server')
@@ -12,11 +14,11 @@ module VagrantPlugins
12
14
  @timeout = timeout
13
15
  end
14
16
 
15
- def call(env)
17
+ def execute(env)
16
18
  if env[:machine].id
17
19
  env[:ui].info(I18n.t('vagrant_openstack.waiting_stop'))
18
20
  client = env[:openstack_client].nova
19
- timeout(@timeout) do
21
+ timeout(@timeout, Errors::Timeout) do
20
22
  while client.get_server_details(env, env[:machine].id)['status'] != 'SHUTOFF'
21
23
  sleep @retry_interval
22
24
  @logger.info('Waiting for server to stop')
@@ -0,0 +1,66 @@
1
+ module VagrantPlugins
2
+ module Openstack
3
+ module Catalog
4
+ class OpenstackCatalog
5
+ def initialize
6
+ @logger = Log4r::Logger.new('vagrant_openstack::action::openstack_reader')
7
+ end
8
+
9
+ def read(env, catalog)
10
+ config = env[:machine].provider_config
11
+ client = env[:openstack_client]
12
+ endpoints = client.session.endpoints
13
+ @logger.info(I18n.t('vagrant_openstack.client.looking_for_available_endpoints'))
14
+ @logger.info("Selecting endpoints matching region '#{config.region}'") unless config.region.nil?
15
+
16
+ catalog.each do |service|
17
+ se = service['endpoints']
18
+ if config.region.nil?
19
+ if se.size > 1
20
+ env[:ui].warn I18n.t('vagrant_openstack.client.multiple_endpoint', size: se.size, type: service['type'])
21
+ env[:ui].warn " => #{service['endpoints'][0]['publicURL']}"
22
+ end
23
+ url = se[0]['publicURL'].strip
24
+ else
25
+ se.each do |endpoint|
26
+ url = endpoint['publicURL'].strip if endpoint['region'].eql? config.region
27
+ end
28
+ end
29
+ endpoints[service['type'].to_sym] = url unless url.nil? || url.empty?
30
+ end
31
+
32
+ endpoints[:network] = choose_api_version('Neutron', 'openstack_network_url', 'v2') do
33
+ client.neutron.get_api_version_list(:network)
34
+ end if config.openstack_network_url.nil? && !endpoints[:network].nil?
35
+
36
+ endpoints[:image] = choose_api_version('Glance', 'openstack_image_url', nil, false) do
37
+ client.glance.get_api_version_list(:image)
38
+ end if config.openstack_image_url.nil? && !endpoints[:image].nil?
39
+ end
40
+
41
+ private
42
+
43
+ def choose_api_version(service_name, url_property, version_prefix = nil, fail_if_not_found = true)
44
+ versions = yield
45
+
46
+ return versions.first['links'].first['href'] if version_prefix.nil?
47
+
48
+ if versions.size == 1
49
+ return versions.first['links'].first['href'] if versions.first['id'].start_with?(version_prefix)
50
+ fail Errors::NoMatchingApiVersion, api_name: service_name, url_property: url_property, version_list: version_list if fail_if_not_found
51
+ end
52
+
53
+ version_list = ''
54
+ versions.each do |version|
55
+ return version['links'].first['href'] if version['id'].start_with?(version_prefix)
56
+ links = version['links'].map { |l| l['href'] }
57
+ version_list << "#{version['id'].ljust(6)} #{version['status'].ljust(10)} #{links}\n"
58
+ end
59
+
60
+ fail Errors::NoMatchingApiVersion, api_name: service_name, url_property: url_property, version_list: version_list if fail_if_not_found
61
+ nil
62
+ end
63
+ end
64
+ end
65
+ end
66
+ end