vagrant-openstack-provider 0.9.0 → 0.10.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.
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