vagrant-conoha 0.1.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 (109) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +22 -0
  3. data/.rubocop.yml +35 -0
  4. data/CHANGELOG.md +3 -0
  5. data/Gemfile +19 -0
  6. data/LICENSE +23 -0
  7. data/Rakefile +25 -0
  8. data/Vagrantfile +71 -0
  9. data/dummy.box +0 -0
  10. data/example_box/README.md +13 -0
  11. data/example_box/metadata.json +3 -0
  12. data/functional_tests/Vagrantfile +58 -0
  13. data/functional_tests/keys/vagrant-openstack +27 -0
  14. data/functional_tests/keys/vagrant-openstack.pub +1 -0
  15. data/functional_tests/run_tests.sh +142 -0
  16. data/lib/vagrant-conoha.rb +29 -0
  17. data/lib/vagrant-conoha/action.rb +227 -0
  18. data/lib/vagrant-conoha/action/abstract_action.rb +22 -0
  19. data/lib/vagrant-conoha/action/connect_openstack.rb +60 -0
  20. data/lib/vagrant-conoha/action/create_server.rb +154 -0
  21. data/lib/vagrant-conoha/action/create_stack.rb +68 -0
  22. data/lib/vagrant-conoha/action/delete_server.rb +53 -0
  23. data/lib/vagrant-conoha/action/delete_stack.rb +73 -0
  24. data/lib/vagrant-conoha/action/message.rb +19 -0
  25. data/lib/vagrant-conoha/action/provision.rb +60 -0
  26. data/lib/vagrant-conoha/action/read_ssh_info.rb +72 -0
  27. data/lib/vagrant-conoha/action/read_state.rb +43 -0
  28. data/lib/vagrant-conoha/action/resume.rb +24 -0
  29. data/lib/vagrant-conoha/action/start_server.rb +24 -0
  30. data/lib/vagrant-conoha/action/stop_server.rb +25 -0
  31. data/lib/vagrant-conoha/action/suspend.rb +24 -0
  32. data/lib/vagrant-conoha/action/sync_folders.rb +129 -0
  33. data/lib/vagrant-conoha/action/wait_accessible.rb +61 -0
  34. data/lib/vagrant-conoha/action/wait_active.rb +33 -0
  35. data/lib/vagrant-conoha/action/wait_stop.rb +33 -0
  36. data/lib/vagrant-conoha/catalog/openstack_catalog.rb +67 -0
  37. data/lib/vagrant-conoha/client/cinder.rb +39 -0
  38. data/lib/vagrant-conoha/client/domain.rb +159 -0
  39. data/lib/vagrant-conoha/client/glance.rb +65 -0
  40. data/lib/vagrant-conoha/client/heat.rb +49 -0
  41. data/lib/vagrant-conoha/client/http_utils.rb +116 -0
  42. data/lib/vagrant-conoha/client/keystone.rb +77 -0
  43. data/lib/vagrant-conoha/client/neutron.rb +48 -0
  44. data/lib/vagrant-conoha/client/nova.rb +212 -0
  45. data/lib/vagrant-conoha/client/openstack.rb +59 -0
  46. data/lib/vagrant-conoha/client/request_logger.rb +23 -0
  47. data/lib/vagrant-conoha/client/rest_utils.rb +25 -0
  48. data/lib/vagrant-conoha/command/abstract_command.rb +51 -0
  49. data/lib/vagrant-conoha/command/flavor_list.rb +24 -0
  50. data/lib/vagrant-conoha/command/image_list.rb +29 -0
  51. data/lib/vagrant-conoha/command/main.rb +51 -0
  52. data/lib/vagrant-conoha/command/network_list.rb +25 -0
  53. data/lib/vagrant-conoha/command/openstack_command.rb +16 -0
  54. data/lib/vagrant-conoha/command/reset.rb +20 -0
  55. data/lib/vagrant-conoha/command/subnet_list.rb +22 -0
  56. data/lib/vagrant-conoha/command/utils.rb +22 -0
  57. data/lib/vagrant-conoha/command/volume_list.rb +25 -0
  58. data/lib/vagrant-conoha/config.rb +390 -0
  59. data/lib/vagrant-conoha/config/http.rb +39 -0
  60. data/lib/vagrant-conoha/config_resolver.rb +285 -0
  61. data/lib/vagrant-conoha/errors.rb +187 -0
  62. data/lib/vagrant-conoha/logging.rb +39 -0
  63. data/lib/vagrant-conoha/plugin.rb +48 -0
  64. data/lib/vagrant-conoha/provider.rb +50 -0
  65. data/lib/vagrant-conoha/utils.rb +26 -0
  66. data/lib/vagrant-conoha/version.rb +15 -0
  67. data/lib/vagrant-conoha/version_checker.rb +76 -0
  68. data/locales/en.yml +393 -0
  69. data/spec/vagrant-conoha/action/connect_openstack_spec.rb +695 -0
  70. data/spec/vagrant-conoha/action/create_server_spec.rb +225 -0
  71. data/spec/vagrant-conoha/action/create_stack_spec.rb +99 -0
  72. data/spec/vagrant-conoha/action/delete_server_spec.rb +89 -0
  73. data/spec/vagrant-conoha/action/delete_stack_spec.rb +63 -0
  74. data/spec/vagrant-conoha/action/message_spec.rb +33 -0
  75. data/spec/vagrant-conoha/action/provision_spec.rb +104 -0
  76. data/spec/vagrant-conoha/action/read_ssh_info_spec.rb +190 -0
  77. data/spec/vagrant-conoha/action/read_state_spec.rb +81 -0
  78. data/spec/vagrant-conoha/action/resume_server_spec.rb +49 -0
  79. data/spec/vagrant-conoha/action/start_server_spec.rb +49 -0
  80. data/spec/vagrant-conoha/action/stop_server_spec.rb +49 -0
  81. data/spec/vagrant-conoha/action/suspend_server_spec.rb +49 -0
  82. data/spec/vagrant-conoha/action/sync_folders_spec.rb +155 -0
  83. data/spec/vagrant-conoha/action/wait_accessible_spec.rb +67 -0
  84. data/spec/vagrant-conoha/action/wait_active_spec.rb +53 -0
  85. data/spec/vagrant-conoha/action/wait_stop_spec.rb +53 -0
  86. data/spec/vagrant-conoha/action_spec.rb +120 -0
  87. data/spec/vagrant-conoha/client/cinder_spec.rb +127 -0
  88. data/spec/vagrant-conoha/client/glance_spec.rb +143 -0
  89. data/spec/vagrant-conoha/client/heat_spec.rb +128 -0
  90. data/spec/vagrant-conoha/client/keystone_spec.rb +150 -0
  91. data/spec/vagrant-conoha/client/neutron_spec.rb +171 -0
  92. data/spec/vagrant-conoha/client/nova_spec.rb +757 -0
  93. data/spec/vagrant-conoha/client/utils_spec.rb +176 -0
  94. data/spec/vagrant-conoha/command/flavor_list_spec.rb +43 -0
  95. data/spec/vagrant-conoha/command/image_list_spec.rb +95 -0
  96. data/spec/vagrant-conoha/command/network_list_spec.rb +65 -0
  97. data/spec/vagrant-conoha/command/reset_spec.rb +24 -0
  98. data/spec/vagrant-conoha/command/subnet_list_spec.rb +45 -0
  99. data/spec/vagrant-conoha/command/volume_list_spec.rb +40 -0
  100. data/spec/vagrant-conoha/config_resolver_spec.rb +860 -0
  101. data/spec/vagrant-conoha/config_spec.rb +373 -0
  102. data/spec/vagrant-conoha/e2e_spec.rb.save +27 -0
  103. data/spec/vagrant-conoha/provider_spec.rb +13 -0
  104. data/spec/vagrant-conoha/spec_helper.rb +37 -0
  105. data/spec/vagrant-conoha/utils_spec.rb +129 -0
  106. data/spec/vagrant-conoha/version_checker_spec.rb +39 -0
  107. data/stackrc +25 -0
  108. data/vagrant-conoha.gemspec +32 -0
  109. metadata +343 -0
@@ -0,0 +1,29 @@
1
+ require 'pathname'
2
+
3
+ require 'vagrant-conoha/plugin'
4
+ require 'vagrant-conoha/logging'
5
+
6
+ module VagrantPlugins
7
+ module ConoHa
8
+ lib_path = Pathname.new(File.expand_path('../vagrant-conoha', __FILE__))
9
+ autoload :Errors, lib_path.join('errors')
10
+
11
+ # This initializes the i18n load path so that the plugin-specific
12
+ # translations work.
13
+ def self.init_i18n
14
+ I18n.load_path << File.expand_path('locales/en.yml', source_root)
15
+ I18n.reload!
16
+ end
17
+
18
+ def self.init_logging
19
+ Logging.init
20
+ end
21
+
22
+ # This returns the path to the source of this plugin.
23
+ #
24
+ # @return [Pathname]
25
+ def self.source_root
26
+ @source_root ||= Pathname.new(File.expand_path('../../', __FILE__))
27
+ end
28
+ end
29
+ end
@@ -0,0 +1,227 @@
1
+ require 'pathname'
2
+
3
+ require 'vagrant/action/builder'
4
+
5
+ module VagrantPlugins
6
+ module ConoHa
7
+ module Action
8
+ # Include the built-in modules so we can use them as top-level things.
9
+ include Vagrant::Action::Builtin
10
+
11
+ # This action is called to destroy the remote machine.
12
+ def self.action_destroy
13
+ new_builder.tap do |b|
14
+ b.use ConfigValidate
15
+ b.use ConnectOpenstack
16
+ b.use Call, ReadState do |env, b2|
17
+ if env[:machine_state_id] == :not_created
18
+ b2.use Message, I18n.t('vagrant_openstack.not_created')
19
+ else
20
+ b2.use DeleteServer
21
+ b2.use DeleteStack
22
+ end
23
+ end
24
+ end
25
+ end
26
+
27
+ # This action is called when `vagrant provision` is called.
28
+ def self.action_provision
29
+ new_builder.tap do |b|
30
+ b.use ConfigValidate
31
+ b.use ConnectOpenstack
32
+ b.use Call, ReadState do |env, b2|
33
+ if env[:machine_state_id] == :not_created
34
+ b2.use Message, I18n.t('vagrant_openstack.not_created')
35
+ else
36
+ b2.use ProvisionWrapper
37
+ b2.use SyncFolders
38
+ end
39
+ end
40
+ end
41
+ end
42
+
43
+ # This action is called to read the SSH info of the machine. The
44
+ # resulting state is expected to be put into the `:machine_ssh_info`
45
+ # key.
46
+ def self.action_read_ssh_info
47
+ new_builder.tap do |b|
48
+ b.use ConfigValidate
49
+ b.use ConnectOpenstack
50
+ b.use ReadSSHInfo
51
+ end
52
+ end
53
+
54
+ # This action is called to read the state of the machine. The
55
+ # resulting state is expected to be put into the `:machine_state_id`
56
+ # key.
57
+ def self.action_read_state
58
+ new_builder.tap do |b|
59
+ b.use ConfigValidate
60
+ b.use ConnectOpenstack
61
+ b.use ReadState
62
+ end
63
+ end
64
+
65
+ def self.action_ssh
66
+ new_builder.tap do |b|
67
+ b.use ConfigValidate
68
+ b.use ConnectOpenstack
69
+ b.use Call, ReadState do |env, b2|
70
+ if env[:machine_state_id] == :not_created
71
+ b2.use Message, I18n.t('vagrant_openstack.not_created')
72
+ else
73
+ b2.use SSHExec
74
+ end
75
+ end
76
+ end
77
+ end
78
+
79
+ def self.action_ssh_run
80
+ new_builder.tap do |b|
81
+ b.use ConfigValidate
82
+ b.use ConnectOpenstack
83
+ b.use Call, ReadState do |env, b2|
84
+ if env[:machine_state_id] == :not_created
85
+ b2.use Message, I18n.t('vagrant_openstack.not_created')
86
+ else
87
+ b2.use SSHRun
88
+ end
89
+ end
90
+ end
91
+ end
92
+
93
+ def self.action_up
94
+ new_builder.tap do |b|
95
+ b.use ConfigValidate
96
+ b.use ConnectOpenstack
97
+
98
+ b.use Call, ReadState do |env, b2|
99
+ case env[:machine_state_id]
100
+ when :not_created
101
+ ssh_disabled = env[:machine].provider_config.ssh_disabled
102
+ b2.use ProvisionWrapper unless ssh_disabled
103
+ b2.use SyncFolders
104
+ b2.use CreateStack
105
+ b2.use CreateServer
106
+ b2.use Message, I18n.t('vagrant_openstack.ssh_disabled_provisioning') if ssh_disabled
107
+ b2.use WaitForServerToBeAccessible unless ssh_disabled
108
+ when :shutoff
109
+ b2.use StartServer
110
+ when :suspended
111
+ b2.use Resume
112
+ else
113
+ b2.use Message, I18n.t('vagrant_openstack.already_created')
114
+ end
115
+ end
116
+ end
117
+ end
118
+
119
+ def self.action_halt
120
+ new_builder.tap do |b|
121
+ b.use ConfigValidate
122
+ b.use ConnectOpenstack
123
+ b.use Call, ReadState do |env, b2|
124
+ if env[:machine_state_id] == :not_created
125
+ b2.use Message, I18n.t('vagrant_openstack.not_created')
126
+ else
127
+ b2.use StopServer
128
+ end
129
+ end
130
+ end
131
+ end
132
+
133
+ # This is the action that is primarily responsible for suspending
134
+ # the virtual machine.
135
+ # Vm cannot be suspended when the machine_state_id is not "active" (typically a task is ongoing)
136
+ def self.action_suspend
137
+ new_builder.tap do |b|
138
+ b.use ConfigValidate
139
+ b.use ConnectOpenstack
140
+ b.use Call, ReadState do |env, b2|
141
+ case env[:machine_state_id]
142
+ when :not_created
143
+ b2.use Message, I18n.t('vagrant_openstack.not_created')
144
+ when :suspended
145
+ b2.use Message, I18n.t('vagrant_openstack.already_suspended')
146
+ when :active
147
+ b2.use Suspend
148
+ else
149
+ b2.use Message, I18n.t('vagrant_openstack.ongoing_task')
150
+ end
151
+ end
152
+ end
153
+ end
154
+
155
+ # This is the action that is primarily responsible for resuming
156
+ # suspended machines.
157
+ # Vm cannot be resumed when the machine_state_id is not suspended.
158
+ def self.action_resume
159
+ new_builder.tap do |b|
160
+ b.use ConfigValidate
161
+ b.use ConnectOpenstack
162
+ b.use Call, ReadState do |env, b2|
163
+ case env[:machine_state_id]
164
+ when :not_created
165
+ b2.use Message, I18n.t('vagrant_openstack.not_created')
166
+ when :suspended
167
+ b2.use Resume
168
+ else
169
+ b2.use Message, I18n.t('vagrant_openstack.not_suspended')
170
+ end
171
+ end
172
+ end
173
+ end
174
+
175
+ def self.action_reload
176
+ new_builder.tap do |b|
177
+ b.use ConfigValidate
178
+ b.use ConnectOpenstack
179
+ b.use Call, ReadState do |env, b2|
180
+ case env[:machine_state_id]
181
+ when :not_created
182
+ b2.use Message, I18n.t('vagrant_openstack.not_created')
183
+ when :suspended
184
+ b2.use Resume
185
+ b2.use WaitForServerToBeActive
186
+ b2.use StopServer
187
+ b2.use WaitForServerToStop
188
+ b2.use StartServer
189
+ when :shutoff
190
+ b2.use StartServer
191
+ else
192
+ b2.use StopServer
193
+ b2.use WaitForServerToStop
194
+ b2.use StartServer
195
+ end
196
+ end
197
+ end
198
+ end
199
+
200
+ # The autoload farm
201
+ action_root = Pathname.new(File.expand_path('../action', __FILE__))
202
+ autoload :Message, action_root.join('message')
203
+ autoload :ConnectOpenstack, action_root.join('connect_openstack')
204
+ autoload :CreateServer, action_root.join('create_server')
205
+ autoload :CreateStack, action_root.join('create_stack')
206
+ autoload :DeleteStack, action_root.join('delete_stack')
207
+ autoload :DeleteServer, action_root.join('delete_server')
208
+ autoload :StopServer, action_root.join('stop_server')
209
+ autoload :StartServer, action_root.join('start_server')
210
+ autoload :ReadSSHInfo, action_root.join('read_ssh_info')
211
+ autoload :ReadState, action_root.join('read_state')
212
+ autoload :SyncFolders, action_root.join('sync_folders')
213
+ autoload :Suspend, action_root.join('suspend')
214
+ autoload :Resume, action_root.join('resume')
215
+ autoload :ProvisionWrapper, action_root.join('provision')
216
+ autoload :WaitForServerToStop, action_root.join('wait_stop')
217
+ autoload :WaitForServerToBeActive, action_root.join('wait_active')
218
+ autoload :WaitForServerToBeAccessible, action_root.join('wait_accessible')
219
+
220
+ private
221
+
222
+ def self.new_builder
223
+ Vagrant::Action::Builder.new
224
+ end
225
+ end
226
+ end
227
+ end
@@ -0,0 +1,22 @@
1
+ require 'colorize'
2
+
3
+ module VagrantPlugins
4
+ module ConoHa
5
+ module Action
6
+ class AbstractAction
7
+ def call(env)
8
+ execute(env)
9
+ # rubocop:disable Style/SpecialGlobalVars
10
+ # rubocop:disable Lint/RescueException
11
+ rescue Errors::VagrantOpenstackError, SystemExit, Interrupt => e
12
+ raise e
13
+ rescue Exception => e
14
+ puts I18n.t('vagrant_openstack.global_error').red unless e.message && e.message.start_with?('Catched Error:')
15
+ raise $!, "Catched Error: #{$!}", $!.backtrace
16
+ end
17
+ # rubocop:enable Lint/RescueException
18
+ # rubocop:enable Style/SpecialGlobalVars
19
+ end
20
+ end
21
+ end
22
+ end
@@ -0,0 +1,60 @@
1
+ require 'log4r'
2
+ require 'json'
3
+
4
+ require 'vagrant-conoha/client/openstack'
5
+ require 'vagrant-conoha/client/request_logger'
6
+ require 'vagrant-conoha/action/abstract_action'
7
+ require 'vagrant-conoha/catalog/openstack_catalog'
8
+
9
+ module VagrantPlugins
10
+ module ConoHa
11
+ module Action
12
+ class ConnectOpenstack < AbstractAction
13
+ include VagrantPlugins::ConoHa::HttpUtils::RequestLogger
14
+ include VagrantPlugins::ConoHa::Catalog
15
+
16
+ def initialize(app, env, catalog_reader = OpenstackCatalog.new)
17
+ @app = app
18
+ @logger = Log4r::Logger.new('vagrant_openstack::action::connect_openstack')
19
+ @catalog_reader = catalog_reader
20
+ env[:openstack_client] = VagrantPlugins::ConoHa
21
+ end
22
+
23
+ def execute(env)
24
+ client = env[:openstack_client]
25
+ if client.session.token.nil?
26
+ catalog = client.keystone.authenticate(env)
27
+ @catalog_reader.read(env, catalog)
28
+ override_endpoint_catalog_with_user_config(env)
29
+ check_configuration(env)
30
+ log_endpoint_catalog(env)
31
+ end
32
+ @app.call(env) unless @app.nil?
33
+ end
34
+
35
+ private
36
+
37
+ def override_endpoint_catalog_with_user_config(env)
38
+ client = env[:openstack_client]
39
+ config = env[:machine].provider_config
40
+ endpoints = client.session.endpoints
41
+ endpoints[:compute] = config.openstack_compute_url unless config.openstack_compute_url.nil?
42
+ endpoints[:network] = config.openstack_network_url unless config.openstack_network_url.nil?
43
+ endpoints[:volume] = config.openstack_volume_url unless config.openstack_volume_url.nil?
44
+ endpoints[:image] = config.openstack_image_url unless config.openstack_image_url.nil?
45
+ endpoints.delete_if { |_, value| value.nil? || value.empty? }
46
+ end
47
+
48
+ def check_configuration(env)
49
+ fail Errors::MissingNovaEndpoint unless env[:openstack_client].session.endpoints.key? :compute
50
+ end
51
+
52
+ def log_endpoint_catalog(env)
53
+ env[:openstack_client].session.endpoints.each do |key, value|
54
+ @logger.info(" -- #{key.to_s.ljust 15}: #{value}")
55
+ end
56
+ end
57
+ end
58
+ end
59
+ end
60
+ end
@@ -0,0 +1,154 @@
1
+ require 'log4r'
2
+ require 'socket'
3
+ require 'timeout'
4
+ require 'sshkey'
5
+
6
+ require 'vagrant-conoha/config_resolver'
7
+ require 'vagrant-conoha/utils'
8
+ require 'vagrant-conoha/action/abstract_action'
9
+ require 'vagrant/util/retryable'
10
+
11
+ module VagrantPlugins
12
+ module ConoHa
13
+ module Action
14
+ class CreateServer < AbstractAction
15
+ include Vagrant::Util::Retryable
16
+
17
+ def initialize(app, _env, resolver = ConfigResolver.new, utils = Utils.new)
18
+ @app = app
19
+ @logger = Log4r::Logger.new('vagrant_openstack::action::create_server')
20
+ @resolver = resolver
21
+ @utils = utils
22
+ end
23
+
24
+ def execute(env)
25
+ @logger.info 'Start create server action'
26
+
27
+ config = env[:machine].provider_config
28
+
29
+ fail Errors::MissingBootOption if config.image.nil? && config.volume_boot.nil?
30
+ fail Errors::ConflictBootOption unless config.image.nil? || config.volume_boot.nil?
31
+
32
+ options = {
33
+ flavor: @resolver.resolve_flavor(env),
34
+ image: @resolver.resolve_image(env),
35
+ volume_boot: @resolver.resolve_volume_boot(env),
36
+ networks: @resolver.resolve_networks(env),
37
+ volumes: @resolver.resolve_volumes(env),
38
+ keypair_name: @resolver.resolve_keypair(env),
39
+ availability_zone: env[:machine].provider_config.availability_zone,
40
+ scheduler_hints: env[:machine].provider_config.scheduler_hints,
41
+ security_groups: @resolver.resolve_security_groups(env),
42
+ user_data: env[:machine].provider_config.user_data,
43
+ metadata: env[:machine].provider_config.metadata
44
+ }
45
+
46
+ server_id = create_server(env, options)
47
+
48
+ # Store the ID right away so we can track it
49
+ env[:machine].id = server_id
50
+
51
+ waiting_for_server_to_be_built(env, server_id)
52
+ attach_volumes(env, server_id, options[:volumes]) unless options[:volumes].empty?
53
+
54
+ @app.call(env)
55
+ end
56
+
57
+ private
58
+
59
+ def create_server(env, options)
60
+ config = env[:machine].provider_config
61
+ nova = env[:openstack_client].nova
62
+ server_name = config.server_name || env[:machine].name
63
+
64
+ env[:ui].info(I18n.t('vagrant_openstack.launching_server'))
65
+ env[:ui].info(" -- Tenant : #{config.tenant_name}")
66
+ env[:ui].info(" -- Name : #{server_name}")
67
+ env[:ui].info(" -- Flavor : #{options[:flavor].name}")
68
+ env[:ui].info(" -- FlavorRef : #{options[:flavor].id}")
69
+ unless options[:image].nil?
70
+ env[:ui].info(" -- Image : #{options[:image].name}")
71
+ env[:ui].info(" -- ImageRef : #{options[:image].id}")
72
+ end
73
+ env[:ui].info(" -- Boot volume : #{options[:volume_boot][:id]} (#{options[:volume_boot][:device]})") unless options[:volume_boot].nil?
74
+ env[:ui].info(" -- KeyPair : #{options[:keypair_name]}")
75
+
76
+ unless options[:networks].empty?
77
+ formated_networks = ' -- '
78
+ if options[:networks].size == 1
79
+ formated_networks << 'Network : '
80
+ else
81
+ formated_networks << 'Networks : '
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)
91
+ end
92
+
93
+ unless options[:volumes].empty?
94
+ options[:volumes].each do |volume|
95
+ device = volume[:device]
96
+ device = :auto if device.nil?
97
+ env[:ui].info(" -- Volume attached : #{volume[:id]} => #{device}")
98
+ end
99
+ end
100
+
101
+ log = "Lauching server '#{server_name}' in project '#{config.tenant_name}' "
102
+ log << "with flavor '#{options[:flavor].name}' (#{options[:flavor].id}), "
103
+ unless options[:image].nil?
104
+ log << "image '#{options[:image].name}' (#{options[:image].id}) "
105
+ end
106
+ log << "and keypair '#{options[:keypair_name]}'"
107
+
108
+ @logger.info(log)
109
+
110
+ image_ref = options[:image].id unless options[:image].nil?
111
+
112
+ create_opts = {
113
+ name: server_name,
114
+ image_ref: image_ref,
115
+ volume_boot: options[:volume_boot],
116
+ flavor_ref: options[:flavor].id,
117
+ keypair: options[:keypair_name],
118
+ availability_zone: options[:availability_zone],
119
+ networks: options[:networks],
120
+ scheduler_hints: options[:scheduler_hints],
121
+ security_groups: options[:security_groups],
122
+ user_data: options[:user_data],
123
+ metadata: options[:metadata]
124
+ }
125
+
126
+ nova.create_server(env, create_opts)
127
+ end
128
+
129
+ def waiting_for_server_to_be_built(env, server_id, retry_interval = 3)
130
+ @logger.info "Waiting for the server with id #{server_id} to be built..."
131
+ env[:ui].info(I18n.t('vagrant_openstack.waiting_for_build'))
132
+ config = env[:machine].provider_config
133
+ timeout(config.server_create_timeout, Errors::Timeout) do
134
+ server_status = 'WAITING'
135
+ until server_status == 'ACTIVE'
136
+ @logger.debug('Waiting for server to be ACTIVE')
137
+ server_status = env[:openstack_client].nova.get_server_details(env, server_id)['status']
138
+ fail Errors::ServerStatusError, server: server_id if server_status == 'ERROR'
139
+ sleep retry_interval
140
+ end
141
+ end
142
+ end
143
+
144
+ def attach_volumes(env, server_id, volumes)
145
+ @logger.info("Attaching volumes #{volumes} to server #{server_id}")
146
+ volumes.each do |volume|
147
+ @logger.debug("Attaching volumes #{volume}")
148
+ env[:openstack_client].nova.attach_volume(env, server_id, volume[:id], volume[:device])
149
+ end
150
+ end
151
+ end
152
+ end
153
+ end
154
+ end