vagrant-openstack-provider 0.9.0 → 0.10.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: e111c9012b675ada99d43c5aa067faeb8d11270a
4
- data.tar.gz: 3bf6027578550da5dd29ef24f87a845c677da8b6
3
+ metadata.gz: 8ee292bbda02fdc4f61b3d79ef0275edf0df7735
4
+ data.tar.gz: a0299d495eb5cb64c3d7dfc47690340ad2eb4ccf
5
5
  SHA512:
6
- metadata.gz: 27ef526289abb14e29224195a7ba099de0dcd58194cae42a9bfcf42b72f38a98357372f68107da358473ac4d07e41a3c5d5d4ddc99caf76653831b1a19113f4d
7
- data.tar.gz: f2ef73aebe3096576f0a3301dca1f65985b5991b709bda72705aa2517b00ecd4dcc22a675f57deaa3f0210ba504d4c0c5e7fef1415147d276253e3996884cafb
6
+ metadata.gz: f55aa6db29a728c9f5cd0e9940ca9b1697dc900925f5a444c1eb397b4dd1bd9d734f4c6b0f32470964ac1d56dc458a445b01049b3e7c79032595e85dc42a4db3
7
+ data.tar.gz: bf8c6aceaa67d1f65c458168191e5ec26ca1e7c4f8bb4ee00acc9e4d816306746bb22ce4d032723d65289f827fea4858baf011a61da6743a728e5b93bd420ffd
@@ -3,6 +3,7 @@ AllCops:
3
3
  - '.bundle/**/*'
4
4
  - 'out/**/*'
5
5
  - '**/Vagrantfile'
6
+ DisplayCopNames: true
6
7
 
7
8
  Style/FileName:
8
9
  Enabled: false
@@ -1,3 +1,9 @@
1
+ # 0.10.0 ( April 11, 2017)
2
+
3
+ IMPROVEMENTS:
4
+
5
+ - Add snapshot support #296
6
+
1
7
  # 0.9.0 (January 30, 2016)
2
8
 
3
9
  BUG FIXES:
@@ -18,6 +18,7 @@ module VagrantPlugins
18
18
  b2.use Message, I18n.t('vagrant_openstack.not_created')
19
19
  else
20
20
  b2.use(ProvisionerCleanup, :before)
21
+ b2.use SnapshotCleanup if Gem::Version.new(Vagrant::VERSION) >= Gem::Version.new('1.8.0')
21
22
  b2.use DeleteServer
22
23
  b2.use DeleteStack
23
24
  end
@@ -233,6 +234,77 @@ module VagrantPlugins
233
234
  end
234
235
  end
235
236
 
237
+ # TODO: Remove the if guard when Vagrant 1.8.0 is the minimum version.
238
+ # rubocop:disable IndentationWidth
239
+ if Gem::Version.new(Vagrant::VERSION) >= Gem::Version.new('1.8.0')
240
+ def self.action_snapshot_delete
241
+ new_builder.tap do |b|
242
+ b.use ConfigValidate
243
+ b.use ConnectOpenstack
244
+ b.use Call, IsState, :not_created do |env, b2|
245
+ if env[:result]
246
+ b2.use Message, I18n.t('vagrant_openstack.not_created')
247
+ else
248
+ b2.use SnapshotDelete
249
+ end
250
+ end
251
+ end
252
+ end
253
+
254
+ def self.action_snapshot_list
255
+ new_builder.tap do |b|
256
+ b.use ConfigValidate
257
+ b.use ConnectOpenstack
258
+ b.use Call, IsState, :not_created do |env, b2|
259
+ if env[:result]
260
+ b2.use Message, I18n.t('vagrant_openstack.not_created')
261
+ else
262
+ b2.use SnapshotList
263
+ end
264
+ end
265
+ end
266
+ end
267
+
268
+ def self.action_snapshot_restore
269
+ new_builder.tap do |b|
270
+ b.use ConfigValidate
271
+ b.use ConnectOpenstack
272
+ b.use Call, IsState, :not_created do |env, b2|
273
+ if env[:result]
274
+ b2.use Message, I18n.t('vagrant_openstack.not_created')
275
+ next
276
+ end
277
+
278
+ b2.use SnapshotRestore
279
+ b2.use WaitForServerToBeActive
280
+ b2.use WaitForCommunicator
281
+
282
+ b2.use Call, IsEnvSet, :snapshot_delete do |env2, b3|
283
+ # Used by vagrant push/pop
284
+ b3.use action_snapshot_delete if env2[:result]
285
+ end
286
+
287
+ b2.use action_provision
288
+ end
289
+ end
290
+ end
291
+
292
+ def self.action_snapshot_save
293
+ new_builder.tap do |b|
294
+ b.use ConfigValidate
295
+ b.use ConnectOpenstack
296
+ b.use Call, IsState, :not_created do |env, b2|
297
+ if env[:result]
298
+ b2.use Message, I18n.t('vagrant_openstack.not_created')
299
+ else
300
+ b2.use SnapshotSave
301
+ end
302
+ end
303
+ end
304
+ end
305
+ end # Vagrant > 1.8.0 guard
306
+ # rubocop:enable IndentationWidth
307
+
236
308
  # The autoload farm
237
309
  action_root = Pathname.new(File.expand_path('../action', __FILE__))
238
310
  autoload :Message, action_root.join('message')
@@ -251,6 +323,16 @@ module VagrantPlugins
251
323
  autoload :ProvisionWrapper, action_root.join('provision')
252
324
  autoload :WaitForServerToStop, action_root.join('wait_stop')
253
325
  autoload :WaitForServerToBeActive, action_root.join('wait_active')
326
+ # TODO: Remove the if guard when Vagrant 1.8.0 is the minimum version.
327
+ # rubocop:disable IndentationWidth
328
+ if Gem::Version.new(Vagrant::VERSION) >= Gem::Version.new('1.8.0')
329
+ autoload :SnapshotCleanup, action_root.join('snapshot_cleanup')
330
+ autoload :SnapshotDelete, action_root.join('snapshot_delete')
331
+ autoload :SnapshotList, action_root.join('snapshot_list')
332
+ autoload :SnapshotRestore, action_root.join('snapshot_restore')
333
+ autoload :SnapshotSave, action_root.join('snapshot_save')
334
+ end
335
+ # rubocop:enable IndentationWidth
254
336
 
255
337
  private
256
338
 
@@ -0,0 +1,32 @@
1
+ require 'vagrant-openstack-provider/action/abstract_action'
2
+
3
+ module VagrantPlugins
4
+ module Openstack
5
+ module Action
6
+ class SnapshotCleanup < AbstractAction
7
+ def initialize(app, _env)
8
+ @app = app
9
+ end
10
+
11
+ def call(env)
12
+ nova = env[:openstack_client].nova
13
+ machine_snapshots = nova.list_snapshots(env, env[:machine].id)
14
+
15
+ snapshots_to_clean = machine_snapshots.select do |s|
16
+ s.metadata.key?('vagrant_snapshot')
17
+ end
18
+
19
+ @app.call env
20
+
21
+ unless snapshots_to_clean.empty?
22
+ env[:ui].info("Deleting Vagrant snapshots: #{snapshots_to_clean.map(&:name)}")
23
+ end
24
+
25
+ snapshots_to_clean.each do |s|
26
+ nova.delete_snapshot(env, s.id)
27
+ end
28
+ end
29
+ end
30
+ end
31
+ end
32
+ end
@@ -0,0 +1,32 @@
1
+ require 'vagrant-openstack-provider/action/abstract_action'
2
+
3
+ module VagrantPlugins
4
+ module Openstack
5
+ module Action
6
+ class SnapshotDelete < AbstractAction
7
+ def initialize(app, _env)
8
+ @app = app
9
+ end
10
+
11
+ def call(env)
12
+ nova = env[:openstack_client].nova
13
+ machine_snapshots = nova.list_snapshots(env, env[:machine].id)
14
+
15
+ snapshot = machine_snapshots.find { |s| s.name == env[:snapshot_name] }
16
+
17
+ unless snapshot.nil?
18
+ env[:ui].info(I18n.t('vagrant.actions.vm.snapshot.deleting',
19
+ name: snapshot.name))
20
+
21
+ nova.delete_snapshot(env, snapshot.id)
22
+
23
+ env[:ui].info(I18n.t('vagrant.actions.vm.snapshot.deleted',
24
+ name: snapshot.name))
25
+ end
26
+
27
+ @app.call env
28
+ end
29
+ end
30
+ end
31
+ end
32
+ end
@@ -0,0 +1,22 @@
1
+ require 'vagrant-openstack-provider/action/abstract_action'
2
+
3
+ module VagrantPlugins
4
+ module Openstack
5
+ module Action
6
+ class SnapshotList < AbstractAction
7
+ def initialize(app, _env)
8
+ @app = app
9
+ end
10
+
11
+ def call(env)
12
+ nova = env[:openstack_client].nova
13
+ machine_snapshots = nova.list_snapshots(env, env[:machine].id)
14
+
15
+ env[:machine_snapshot_list] = machine_snapshots.map(&:name)
16
+
17
+ @app.call env
18
+ end
19
+ end
20
+ end
21
+ end
22
+ end
@@ -0,0 +1,29 @@
1
+ require 'vagrant-openstack-provider/action/abstract_action'
2
+
3
+ module VagrantPlugins
4
+ module Openstack
5
+ module Action
6
+ class SnapshotRestore < AbstractAction
7
+ def initialize(app, _env)
8
+ @app = app
9
+ end
10
+
11
+ def call(env)
12
+ nova = env[:openstack_client].nova
13
+ machine_snapshots = nova.list_snapshots(env, env[:machine].id)
14
+
15
+ snapshot = machine_snapshots.find { |s| s.name == env[:snapshot_name] }
16
+
17
+ unless snapshot.nil?
18
+ env[:ui].info(I18n.t('vagrant.actions.vm.snapshot.restoring',
19
+ name: snapshot.name))
20
+
21
+ nova.restore_snapshot(env, env[:machine].id, snapshot.id)
22
+ end
23
+
24
+ @app.call env
25
+ end
26
+ end
27
+ end
28
+ end
29
+ end
@@ -0,0 +1,51 @@
1
+ require 'vagrant-openstack-provider/action/abstract_action'
2
+
3
+ module VagrantPlugins
4
+ module Openstack
5
+ module Action
6
+ class SnapshotSave < AbstractAction
7
+ def initialize(app, _env, retry_interval = 3)
8
+ @app = app
9
+ @retry_interval = retry_interval
10
+ end
11
+
12
+ def call(env)
13
+ nova = env[:openstack_client].nova
14
+ config = env[:machine].provider_config
15
+
16
+ env[:ui].info(I18n.t('vagrant.actions.vm.snapshot.saving',
17
+ name: env[:snapshot_name]))
18
+
19
+ nova.create_snapshot(
20
+ env,
21
+ env[:machine].id, env[:snapshot_name])
22
+
23
+ image = nova.list_snapshots(env, env[:machine].id).find { |i| i.name == env[:snapshot_name] }
24
+
25
+ timeout(config.server_create_timeout, Errors::Timeout) do
26
+ loop do
27
+ image_status = nova.get_image_details(env, image.id)
28
+
29
+ break if image_status['status'] == 'ACTIVE'
30
+
31
+ unless image_status['progress'].nil?
32
+ env[:ui].clear_line
33
+ env[:ui].report_progress(image_status['progress'], 100, false)
34
+ end
35
+
36
+ sleep @retry_interval
37
+ end
38
+ end
39
+
40
+ # Clear progress output.
41
+ env[:ui].clear_line
42
+
43
+ env[:ui].success(I18n.t('vagrant.actions.vm.snapshot.saved',
44
+ name: env[:snapshot_name]))
45
+
46
+ @app.call env
47
+ end
48
+ end
49
+ end
50
+ end
51
+ end
@@ -0,0 +1,15 @@
1
+ module VagrantPlugins
2
+ module Openstack
3
+ module Cap
4
+ module SnapshotList
5
+ # Returns a list of the snapshots that are taken on this machine.
6
+ #
7
+ # @return [Array<String>]
8
+ def self.snapshot_list(machine)
9
+ env = machine.action(:snapshot_list, lock: false)
10
+ env[:machine_snapshot_list]
11
+ end
12
+ end
13
+ end
14
+ end
15
+ end
@@ -25,19 +25,23 @@ module VagrantPlugins
25
25
  attr_accessor :size
26
26
  attr_accessor :min_ram
27
27
  attr_accessor :min_disk
28
+ attr_accessor :metadata
28
29
 
29
- def initialize(id, name, visibility = nil, size = nil, min_ram = nil, min_disk = nil)
30
+ # rubocop:disable Metrics/ParameterLists
31
+ def initialize(id, name, visibility = nil, size = nil, min_ram = nil, min_disk = nil, metadata = {})
30
32
  @visibility = visibility
31
33
  @size = size
32
34
  @min_ram = min_ram
33
35
  @min_disk = min_disk
36
+ @metadata = metadata
34
37
  super(id, name)
35
38
  end
39
+ # rubocop:enable Metrics/ParameterLists
36
40
 
37
41
  protected
38
42
 
39
43
  def state
40
- [@id, @name, @visibility, @size, @min_ram, @min_disk]
44
+ [@id, @name, @visibility, @size, @min_ram, @min_disk, @metadata]
41
45
  end
42
46
  end
43
47
 
@@ -42,9 +42,30 @@ module VagrantPlugins
42
42
  FloatingIP.new(floating_ip['ip'], floating_ip['pool'], floating_ip['instance_id'])
43
43
  end
44
44
 
45
- def get_all_images(env)
46
- images_json = get(env, "#{@session.endpoints[:compute]}/images")
47
- JSON.parse(images_json)['images'].map { |fl| Image.new(fl['id'], fl['name'], 'unknown') }
45
+ def get_all_images(env, headers = {})
46
+ images_json = get(env, "#{@session.endpoints[:compute]}/images/detail", headers)
47
+ JSON.parse(images_json)['images'].map do |fl|
48
+ Image.new(
49
+ fl['id'],
50
+ fl['name'],
51
+ 'unknown',
52
+ nil,
53
+ fl['minRam'],
54
+ fl['minDisk'],
55
+ fl['metadata']
56
+ )
57
+ end
58
+ end
59
+
60
+ # Get detailed information about an image
61
+ #
62
+ # @param env [Hash] Vagrant action environment
63
+ # @param image_id [String] Image UUID
64
+ #
65
+ # @return [Hash]
66
+ def get_image_details(env, image_id)
67
+ image_json = get(env, "#{@session.endpoints[:compute]}/images/#{image_id}")
68
+ JSON.parse(image_json)['image']
48
69
  end
49
70
 
50
71
  def create_server(env, options)
@@ -175,6 +196,63 @@ module VagrantPlugins
175
196
  end
176
197
  end
177
198
 
199
+ # List snapshot images associated with a particular server
200
+ #
201
+ # @param env [Hash] Vagrant action environment
202
+ # @param server_id [String] Server UUID
203
+ #
204
+ # @return [Array<VagrantPlugins::Openstack::Domain::Image>]
205
+ def list_snapshots(env, server_id)
206
+ get_all_images(env, params: { server: server_id })
207
+ end
208
+
209
+ # Create a named snapsot for a given VM
210
+ #
211
+ # @param env [Hash] Vagrant action environment
212
+ # @param server_id [String] Server UUID
213
+ # @param snapshot_name [String]
214
+ #
215
+ # @return [void]
216
+ def create_snapshot(env, server_id, snapshot_name)
217
+ instance_exists do
218
+ post(
219
+ env,
220
+ "#{@session.endpoints[:compute]}/servers/#{server_id}/action",
221
+ { createImage: {
222
+ name: snapshot_name,
223
+ metadata: { vagrant_snapshot: 'true' }
224
+ } }.to_json)
225
+ end
226
+ end
227
+
228
+ # Delete an identified snapshot
229
+ #
230
+ # @param env [Hash] Vagrant action environment
231
+ # @param snapshot_id [String] Snapshot UUID
232
+ #
233
+ # @return [void]
234
+ def delete_snapshot(env, snapshot_id)
235
+ delete(
236
+ env,
237
+ "#{@session.endpoints[:compute]}/images/#{snapshot_id}")
238
+ end
239
+
240
+ # Restore a VM to an identified snapshot
241
+ #
242
+ # @param env [Hash] Vagrant action environment
243
+ # @param server_id [String] Server UUID
244
+ # @param snapshot_id [String] Snapshot UUID
245
+ #
246
+ # @return [void]
247
+ def restore_snapshot(env, server_id, snapshot_id)
248
+ instance_exists do
249
+ post(
250
+ env,
251
+ "#{@session.endpoints[:compute]}/servers/#{server_id}/action",
252
+ { rebuild: { imageRef: snapshot_id } }.to_json)
253
+ end
254
+ end
255
+
178
256
  private
179
257
 
180
258
  VM_STATES =
@@ -35,6 +35,16 @@ module VagrantPlugins
35
35
  Provider
36
36
  end
37
37
 
38
+ # TODO: Remove the if guard when Vagrant 1.8.0 is the minimum version.
39
+ # rubocop:disable IndentationWidth
40
+ if Gem::Version.new(Vagrant::VERSION) >= Gem::Version.new('1.8.0')
41
+ provider_capability('openstack', 'snapshot_list') do
42
+ require_relative 'cap/snapshot_list'
43
+ Cap::SnapshotList
44
+ end
45
+ end
46
+ # rubocop:enable IndentationWidth
47
+
38
48
  command('openstack') do
39
49
  Openstack.init_i18n
40
50
  Openstack.init_logging
@@ -4,7 +4,7 @@ module VagrantPlugins
4
4
  # Stable versions must respect the pattern given
5
5
  # by VagrantPlugins::Openstack::VERSION_PATTERN
6
6
  #
7
- VERSION = '0.9.0'
7
+ VERSION = '0.10.0'
8
8
 
9
9
  #
10
10
  # Stable version must respect the naming convention 'x.y.z'
@@ -101,7 +101,7 @@ describe VagrantPlugins::Openstack::NovaClient do
101
101
  describe 'get_all_images' do
102
102
  context 'with token and project_id acquainted' do
103
103
  it 'returns all images' do
104
- stub_request(:get, 'http://nova/a1b2c3/images')
104
+ stub_request(:get, 'http://nova/a1b2c3/images/detail')
105
105
  .with(
106
106
  headers:
107
107
  {
@@ -110,13 +110,14 @@ describe VagrantPlugins::Openstack::NovaClient do
110
110
  })
111
111
  .to_return(
112
112
  status: 200,
113
- body: '{ "images": [ { "id": "i1", "name": "image1"}, { "id": "i2", "name": "image2"} ] }')
113
+ body: '{ "images": [ { "id": "i1", "name": "image1", "metadata": {"customVal1": 1}}, { "id": "i2", "name": "image2"} ] }')
114
114
 
115
115
  images = @nova_client.get_all_images(env)
116
116
 
117
117
  expect(images.length).to eq(2)
118
118
  expect(images[0].id).to eq('i1')
119
119
  expect(images[0].name).to eq('image1')
120
+ expect(images[0].metadata['customVal1']).to eq(1)
120
121
  expect(images[1].id).to eq('i2')
121
122
  expect(images[1].name).to eq('image2')
122
123
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: vagrant-openstack-provider
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.9.0
4
+ version: 0.10.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Guillaume Giamarchi
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2017-01-30 00:00:00.000000000 Z
12
+ date: 2017-04-11 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: json
@@ -213,12 +213,18 @@ files:
213
213
  - lib/vagrant-openstack-provider/action/read_ssh_info.rb
214
214
  - lib/vagrant-openstack-provider/action/read_state.rb
215
215
  - lib/vagrant-openstack-provider/action/resume.rb
216
+ - lib/vagrant-openstack-provider/action/snapshot_cleanup.rb
217
+ - lib/vagrant-openstack-provider/action/snapshot_delete.rb
218
+ - lib/vagrant-openstack-provider/action/snapshot_list.rb
219
+ - lib/vagrant-openstack-provider/action/snapshot_restore.rb
220
+ - lib/vagrant-openstack-provider/action/snapshot_save.rb
216
221
  - lib/vagrant-openstack-provider/action/start_server.rb
217
222
  - lib/vagrant-openstack-provider/action/stop_server.rb
218
223
  - lib/vagrant-openstack-provider/action/suspend.rb
219
224
  - lib/vagrant-openstack-provider/action/sync_folders.rb
220
225
  - lib/vagrant-openstack-provider/action/wait_active.rb
221
226
  - lib/vagrant-openstack-provider/action/wait_stop.rb
227
+ - lib/vagrant-openstack-provider/cap/snapshot_list.rb
222
228
  - lib/vagrant-openstack-provider/catalog/openstack_catalog.rb
223
229
  - lib/vagrant-openstack-provider/client/cinder.rb
224
230
  - lib/vagrant-openstack-provider/client/domain.rb