vagrant-openstack-provider 0.3.4.pre → 0.4.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.
- data/CHANGELOG.md +25 -0
- data/Gemfile +3 -0
- data/Vagrantfile +1 -1
- data/lib/vagrant-openstack-provider/action/connect_openstack.rb +1 -0
- data/lib/vagrant-openstack-provider/action/create_server.rb +135 -19
- data/lib/vagrant-openstack-provider/action/read_ssh_info.rb +16 -2
- data/lib/vagrant-openstack-provider/client/cinder.rb +40 -0
- data/lib/vagrant-openstack-provider/client/domain.rb +64 -4
- data/lib/vagrant-openstack-provider/client/nova.rb +22 -2
- data/lib/vagrant-openstack-provider/client/openstack.rb +5 -0
- data/lib/vagrant-openstack-provider/command/main.rb +2 -1
- data/lib/vagrant-openstack-provider/command/volume_list.rb +27 -0
- data/lib/vagrant-openstack-provider/config.rb +64 -1
- data/lib/vagrant-openstack-provider/errors.rb +36 -0
- data/lib/vagrant-openstack-provider/version.rb +1 -1
- data/locales/en.yml +28 -0
- data/spec/vagrant-openstack-provider/action/connect_openstack_spec.rb +1 -0
- data/spec/vagrant-openstack-provider/action/create_server_spec.rb +250 -9
- data/spec/vagrant-openstack-provider/action/read_ssh_info_spec.rb +48 -3
- data/spec/vagrant-openstack-provider/client/cinder_spec.rb +114 -0
- data/spec/vagrant-openstack-provider/client/nova_spec.rb +50 -0
- data/spec/vagrant-openstack-provider/command/floatingip_list_spec.rb +2 -11
- data/spec/vagrant-openstack-provider/command/volume_list_spec.rb +33 -0
- data/spec/vagrant-openstack-provider/config_spec.rb +20 -0
- metadata +42 -12
- checksums.yaml +0 -7
data/CHANGELOG.md
CHANGED
@@ -1,3 +1,24 @@
|
|
1
|
+
# 0.4.0 (September 23, 2014)
|
2
|
+
|
3
|
+
FEATURES:
|
4
|
+
|
5
|
+
- Enable "metadata" in config for nova create server [#25](https://github.com/ggiamarchi/vagrant-openstack-provider/issues/25)
|
6
|
+
- Enable "user_data" in config for nova create server [#78](https://github.com/ggiamarchi/vagrant-openstack-provider/issues/78)
|
7
|
+
- Enable "security_groups" in config for nova create server [#82](https://github.com/ggiamarchi/vagrant-openstack-provider/issues/82)
|
8
|
+
- Enable "scheduler_hints" in config for nova create server [#83](https://github.com/ggiamarchi/vagrant-openstack-provider/issues/83)
|
9
|
+
- Allow attaching an existing volume to the vagrant instance [#24](https://github.com/ggiamarchi/vagrant-openstack-provider/issues/24)
|
10
|
+
- Allow booting instance from volume [#44](https://github.com/ggiamarchi/vagrant-openstack-provider/issues/44)
|
11
|
+
- Add subcommand volume-list [#75](https://github.com/ggiamarchi/vagrant-openstack-provider/issues/75)
|
12
|
+
|
13
|
+
IMPROVEMENTS:
|
14
|
+
|
15
|
+
- Add config param floating_ip_pool_always_allocate [#61](https://github.com/ggiamarchi/vagrant-openstack-provider/issues/61)
|
16
|
+
|
17
|
+
BUG FIXES:
|
18
|
+
|
19
|
+
- Enable config option to override SSH port [#88](https://github.com/ggiamarchi/vagrant-openstack-provider/issues/88)
|
20
|
+
|
21
|
+
|
1
22
|
# 0.3.3 (September 19, 2014)
|
2
23
|
|
3
24
|
BUG FIXES:
|
@@ -11,6 +32,10 @@ BUG FIXES:
|
|
11
32
|
- The provider fails to load colorize gem [#76](https://github.com/ggiamarchi/vagrant-openstack-provider/issues/76)
|
12
33
|
- Sub-command arguments management have change in vagrant 1.5 [#77](https://github.com/ggiamarchi/vagrant-openstack-provider/issues/77)
|
13
34
|
|
35
|
+
IMPROVEMENTS:
|
36
|
+
|
37
|
+
- Show more informations for command flavor-list [#52](https://github.com/ggiamarchi/vagrant-openstack-provider/issues/52)
|
38
|
+
|
14
39
|
# 0.3.0 (August 29, 2014)
|
15
40
|
|
16
41
|
FEATURES:
|
data/Gemfile
CHANGED
data/Vagrantfile
CHANGED
@@ -4,6 +4,7 @@ Vagrant.configure('2') do |config|
|
|
4
4
|
|
5
5
|
config.vm.box = 'dummy-openstack'
|
6
6
|
config.vm.box_url = 'https://github.com/ggiamarchi/vagrant-openstack/raw/master/source/dummy.box'
|
7
|
+
config.ssh.username = 'stack'
|
7
8
|
|
8
9
|
config.vm.provider :openstack do |os|
|
9
10
|
os.username = ENV['OS_USERNAME']
|
@@ -13,6 +14,5 @@ Vagrant.configure('2') do |config|
|
|
13
14
|
os.image = ENV['OS_IMAGE']
|
14
15
|
os.openstack_auth_url = ENV['OS_AUTH_URL']
|
15
16
|
os.tenant_name = ENV['OS_TENANT_NAME']
|
16
|
-
os.ssh_username = 'stack'
|
17
17
|
end
|
18
18
|
end
|
@@ -67,6 +67,7 @@ module VagrantPlugins
|
|
67
67
|
config = env[:machine].provider_config
|
68
68
|
client.session.endpoints[:compute] = config.openstack_compute_url unless config.openstack_compute_url.nil?
|
69
69
|
client.session.endpoints[:network] = config.openstack_network_url unless config.openstack_network_url.nil?
|
70
|
+
client.session.endpoints[:volume] = config.openstack_volume_url unless config.openstack_volume_url.nil?
|
70
71
|
end
|
71
72
|
|
72
73
|
def log_endpoint_catalog(env)
|
@@ -19,15 +19,27 @@ module VagrantPlugins
|
|
19
19
|
def call(env)
|
20
20
|
@logger.info 'Start create server action'
|
21
21
|
|
22
|
+
config = env[:machine].provider_config
|
23
|
+
|
24
|
+
fail Errors::MissingBootOption if config.image.nil? && config.volume_boot.nil?
|
25
|
+
fail Errors::ConflictBootOption unless config.image.nil? || config.volume_boot.nil?
|
26
|
+
|
22
27
|
nova = env[:openstack_client].nova
|
23
28
|
|
24
29
|
options = {
|
25
30
|
flavor: resolve_flavor(env),
|
26
31
|
image: resolve_image(env),
|
32
|
+
volume_boot: resolve_volume_boot(env),
|
27
33
|
networks: resolve_networks(env),
|
34
|
+
volumes: resolve_volumes(env),
|
28
35
|
keypair_name: resolve_keypair(env),
|
29
|
-
availability_zone: env[:machine].provider_config.availability_zone
|
36
|
+
availability_zone: env[:machine].provider_config.availability_zone,
|
37
|
+
scheduler_hints: env[:machine].provider_config.scheduler_hints,
|
38
|
+
security_groups: env[:machine].provider_config.security_groups,
|
39
|
+
user_data: env[:machine].provider_config.user_data,
|
40
|
+
metadata: env[:machine].provider_config.metadata
|
30
41
|
}
|
42
|
+
|
31
43
|
server_id = create_server(env, options)
|
32
44
|
|
33
45
|
# Store the ID right away so we can track it
|
@@ -42,13 +54,15 @@ module VagrantPlugins
|
|
42
54
|
nova.add_floating_ip(env, server_id, floating_ip)
|
43
55
|
end
|
44
56
|
|
57
|
+
attach_volumes(env, server_id, options[:volumes]) unless options[:volumes].empty?
|
58
|
+
|
45
59
|
unless env[:interrupted]
|
46
60
|
# Clear the line one more time so the progress is removed
|
47
61
|
env[:ui].clear_line
|
48
62
|
|
49
63
|
# Wait for SSH to become available
|
50
64
|
ssh_timeout = env[:machine].provider_config.ssh_timeout
|
51
|
-
unless port_open?(env, floating_ip,
|
65
|
+
unless port_open?(env, floating_ip, resolve_ssh_port(env), ssh_timeout)
|
52
66
|
env[:ui].error(I18n.t('vagrant_openstack.timeout'))
|
53
67
|
fail Errors::SshUnavailable, host: floating_ip, timeout: ssh_timeout
|
54
68
|
end
|
@@ -62,6 +76,12 @@ module VagrantPlugins
|
|
62
76
|
|
63
77
|
private
|
64
78
|
|
79
|
+
def resolve_ssh_port(env)
|
80
|
+
machine_config = env[:machine].config
|
81
|
+
return machine_config.ssh.port if machine_config.ssh.port
|
82
|
+
22
|
83
|
+
end
|
84
|
+
|
65
85
|
# 1. if floating_ip is set, use it
|
66
86
|
# 2. if floating_ip_pool is set
|
67
87
|
# GET v2/{{tenant_id}}/os-floating-ips
|
@@ -79,7 +99,7 @@ module VagrantPlugins
|
|
79
99
|
if config.floating_ip_pool
|
80
100
|
floating_ips.each do |single|
|
81
101
|
return single.ip if single.pool == config.floating_ip_pool && single.instance_id.nil?
|
82
|
-
end
|
102
|
+
end unless config.floating_ip_pool_always_allocate
|
83
103
|
return nova.allocate_floating_ip(env, config.floating_ip_pool).ip
|
84
104
|
else
|
85
105
|
floating_ips.each do |ip|
|
@@ -101,9 +121,7 @@ module VagrantPlugins
|
|
101
121
|
key = SSHKey.generate
|
102
122
|
nova = env[:openstack_client].nova
|
103
123
|
generated_keyname = nova.import_keypair(env, key.ssh_public_key)
|
104
|
-
|
105
|
-
File.write(file_path, key.private_key)
|
106
|
-
File.chmod(0600, file_path)
|
124
|
+
File.write("#{env[:machine].data_dir}/#{generated_keyname}", key.private_key)
|
107
125
|
generated_keyname
|
108
126
|
end
|
109
127
|
|
@@ -122,6 +140,7 @@ module VagrantPlugins
|
|
122
140
|
def resolve_image(env)
|
123
141
|
@logger.info 'Resolving image'
|
124
142
|
config = env[:machine].provider_config
|
143
|
+
return nil if config.image.nil?
|
125
144
|
nova = env[:openstack_client].nova
|
126
145
|
env[:ui].info(I18n.t('vagrant_openstack.finding_image'))
|
127
146
|
images = nova.get_all_images(env)
|
@@ -158,41 +177,129 @@ module VagrantPlugins
|
|
158
177
|
networks
|
159
178
|
end
|
160
179
|
|
180
|
+
def resolve_volume_boot(env)
|
181
|
+
@logger.info 'Resolving image'
|
182
|
+
config = env[:machine].provider_config
|
183
|
+
return nil if config.volume_boot.nil?
|
184
|
+
|
185
|
+
volume_list = env[:openstack_client].cinder.get_all_volumes(env)
|
186
|
+
volume_ids = volume_list.map { |v| v.id }
|
187
|
+
|
188
|
+
@logger.debug(volume_list)
|
189
|
+
|
190
|
+
volume = resolve_volume(config.volume_boot, volume_list, volume_ids)
|
191
|
+
device = volume[:device].nil? ? 'vda' : volume[:device]
|
192
|
+
|
193
|
+
{ id: volume[:id], device: device }
|
194
|
+
end
|
195
|
+
|
196
|
+
def resolve_volumes(env)
|
197
|
+
@logger.info 'Resolving volume(s)'
|
198
|
+
config = env[:machine].provider_config
|
199
|
+
return [] if config.volumes.nil? || config.volumes.empty?
|
200
|
+
env[:ui].info(I18n.t('vagrant_openstack.finding_volumes'))
|
201
|
+
|
202
|
+
volume_list = env[:openstack_client].cinder.get_all_volumes(env)
|
203
|
+
volume_ids = volume_list.map { |v| v.id }
|
204
|
+
|
205
|
+
@logger.debug(volume_list)
|
206
|
+
|
207
|
+
volumes = []
|
208
|
+
config.volumes.each do |volume|
|
209
|
+
volumes << resolve_volume(volume, volume_list, volume_ids)
|
210
|
+
end
|
211
|
+
@logger.debug("Resolved volumes : #{volumes.to_json}")
|
212
|
+
volumes
|
213
|
+
end
|
214
|
+
|
215
|
+
def resolve_volume(volume, volume_list, volume_ids)
|
216
|
+
return resolve_volume_from_string(volume, volume_list) if volume.is_a? String
|
217
|
+
return resolve_volume_from_hash(volume, volume_list, volume_ids) if volume.is_a? Hash
|
218
|
+
fail Errors::InvalidVolumeObject, volume: volume
|
219
|
+
end
|
220
|
+
|
221
|
+
def resolve_volume_from_string(volume, volume_list)
|
222
|
+
found_volume = find_matching(volume_list, volume)
|
223
|
+
fail Errors::UnresolvedVolume, volume: volume if found_volume.nil?
|
224
|
+
{ id: found_volume.id, device: nil }
|
225
|
+
end
|
226
|
+
|
227
|
+
def resolve_volume_from_hash(volume, volume_list, volume_ids)
|
228
|
+
device = nil
|
229
|
+
device = volume[:device] if volume.key?(:device)
|
230
|
+
if volume.key?(:id)
|
231
|
+
fail Errors::ConflictVolumeNameId, volume: volume if volume.key?(:name)
|
232
|
+
volume_id = volume[:id]
|
233
|
+
fail Errors::UnresolvedVolumeId, id: volume_id unless volume_ids.include? volume_id
|
234
|
+
elsif volume.key?(:name)
|
235
|
+
volume_list.each do |v|
|
236
|
+
next unless v.name.eql? volume[:name]
|
237
|
+
fail Errors::MultipleVolumeName, name: volume[:name] unless volume_id.nil?
|
238
|
+
volume_id = v.id
|
239
|
+
end
|
240
|
+
fail Errors::UnresolvedVolumeName, name: volume[:name] unless volume_ids.include? volume_id
|
241
|
+
else
|
242
|
+
fail Errors::ConflictVolumeNameId, volume: volume
|
243
|
+
end
|
244
|
+
{ id: volume_id, device: device }
|
245
|
+
end
|
246
|
+
|
161
247
|
def create_server(env, options)
|
162
248
|
config = env[:machine].provider_config
|
163
249
|
nova = env[:openstack_client].nova
|
164
250
|
server_name = config.server_name || env[:machine].name
|
165
251
|
|
166
252
|
env[:ui].info(I18n.t('vagrant_openstack.launching_server'))
|
167
|
-
env[:ui].info(" -- Tenant
|
168
|
-
env[:ui].info(" -- Name
|
169
|
-
env[:ui].info(" -- Flavor
|
170
|
-
env[:ui].info(" -- FlavorRef
|
171
|
-
|
172
|
-
|
173
|
-
|
253
|
+
env[:ui].info(" -- Tenant : #{config.tenant_name}")
|
254
|
+
env[:ui].info(" -- Name : #{server_name}")
|
255
|
+
env[:ui].info(" -- Flavor : #{options[:flavor].name}")
|
256
|
+
env[:ui].info(" -- FlavorRef : #{options[:flavor].id}")
|
257
|
+
unless options[:image].nil?
|
258
|
+
env[:ui].info(" -- Image : #{options[:image].name}")
|
259
|
+
env[:ui].info(" -- ImageRef : #{options[:image].id}")
|
260
|
+
end
|
261
|
+
env[:ui].info(" -- Boot volume : #{options[:volume_boot][:id]} (#{options[:volume_boot][:device]})") unless options[:volume_boot].nil?
|
262
|
+
env[:ui].info(" -- KeyPair : #{options[:keypair_name]}")
|
263
|
+
|
174
264
|
unless options[:networks].empty?
|
175
265
|
if options[:networks].size == 1
|
176
|
-
env[:ui].info(" -- Network
|
266
|
+
env[:ui].info(" -- Network : #{options[:networks][0]}")
|
177
267
|
else
|
178
|
-
env[:ui].info(" -- Networks
|
268
|
+
env[:ui].info(" -- Networks : #{options[:networks]}")
|
269
|
+
end
|
270
|
+
end
|
271
|
+
|
272
|
+
unless options[:volumes].empty?
|
273
|
+
options[:volumes].each do |volume|
|
274
|
+
device = volume[:device]
|
275
|
+
device = :auto if device.nil?
|
276
|
+
env[:ui].info(" -- Volume attached : #{volume[:id]} => #{device}")
|
179
277
|
end
|
180
278
|
end
|
181
279
|
|
182
280
|
log = "Lauching server '#{server_name}' in project '#{config.tenant_name}' "
|
183
281
|
log << "with flavor '#{options[:flavor].name}' (#{options[:flavor].id}), "
|
184
|
-
|
282
|
+
unless options[:image].nil?
|
283
|
+
log << "image '#{options[:image].name}' (#{options[:image].id}) "
|
284
|
+
end
|
185
285
|
log << "and keypair '#{options[:keypair_name]}'"
|
186
286
|
|
187
287
|
@logger.info(log)
|
188
288
|
|
289
|
+
image_ref = options[:image].id unless options[:image].nil?
|
290
|
+
|
189
291
|
create_opts = {
|
190
292
|
name: server_name,
|
191
|
-
image_ref:
|
293
|
+
image_ref: image_ref,
|
294
|
+
volume_boot: options[:volume_boot],
|
192
295
|
flavor_ref: options[:flavor].id,
|
193
296
|
keypair: options[:keypair_name],
|
194
297
|
availability_zone: options[:availability_zone],
|
195
|
-
networks: options[:networks]
|
298
|
+
networks: options[:networks],
|
299
|
+
scheduler_hints: options[:scheduler_hints],
|
300
|
+
security_groups: options[:security_groups],
|
301
|
+
user_data: options[:user_data],
|
302
|
+
metadata: options[:metadata]
|
196
303
|
}
|
197
304
|
|
198
305
|
nova.create_server(env, create_opts)
|
@@ -210,6 +317,15 @@ module VagrantPlugins
|
|
210
317
|
end
|
211
318
|
end
|
212
319
|
|
320
|
+
def attach_volumes(env, server_id, volumes)
|
321
|
+
@logger.info("Attaching volumes #{volumes} to server #{server_id}")
|
322
|
+
nova = env[:openstack_client].nova
|
323
|
+
volumes.each do |volume|
|
324
|
+
@logger.debug("Attaching volumes #{volume}")
|
325
|
+
nova.attach_volume(env, server_id, volume[:id], volume[:device])
|
326
|
+
end
|
327
|
+
end
|
328
|
+
|
213
329
|
def port_open?(env, ip, port, timeout)
|
214
330
|
start_time = Time.now
|
215
331
|
current_time = start_time
|
@@ -243,7 +359,7 @@ module VagrantPlugins
|
|
243
359
|
return single if single.name == name
|
244
360
|
return single if name.is_a?(Regexp) && name =~ single.name
|
245
361
|
end
|
246
|
-
@logger.error "
|
362
|
+
@logger.error "Element '#{name}' not found in collection #{collection}"
|
247
363
|
nil
|
248
364
|
end
|
249
365
|
end
|
@@ -24,13 +24,27 @@ module VagrantPlugins
|
|
24
24
|
config = env[:machine].provider_config
|
25
25
|
hash = {
|
26
26
|
host: get_ip_address(env),
|
27
|
-
port:
|
28
|
-
username:
|
27
|
+
port: resolve_ssh_port(env),
|
28
|
+
username: resolve_ssh_username(env)
|
29
29
|
}
|
30
30
|
hash[:private_key_path] = "#{env[:machine].data_dir}/#{get_keypair_name(env)}" unless config.keypair_name || config.public_key_path
|
31
31
|
hash
|
32
32
|
end
|
33
33
|
|
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
|
38
|
+
end
|
39
|
+
|
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
|
47
|
+
|
34
48
|
def get_ip_address(env)
|
35
49
|
return env[:machine].provider_config.floating_ip unless env[:machine].provider_config.floating_ip.nil?
|
36
50
|
details = env[:openstack_client].nova.get_server_details(env, env[:machine].id)
|
@@ -0,0 +1,40 @@
|
|
1
|
+
require 'log4r'
|
2
|
+
require 'restclient'
|
3
|
+
require 'json'
|
4
|
+
|
5
|
+
require 'vagrant-openstack-provider/client/http_utils'
|
6
|
+
require 'vagrant-openstack-provider/client/domain'
|
7
|
+
|
8
|
+
module VagrantPlugins
|
9
|
+
module Openstack
|
10
|
+
class CinderClient
|
11
|
+
include Singleton
|
12
|
+
include VagrantPlugins::Openstack::HttpUtils
|
13
|
+
include VagrantPlugins::Openstack::Domain
|
14
|
+
|
15
|
+
def initialize
|
16
|
+
@logger = Log4r::Logger.new('vagrant_openstack::cinder')
|
17
|
+
@session = VagrantPlugins::Openstack.session
|
18
|
+
end
|
19
|
+
|
20
|
+
def get_all_volumes(env)
|
21
|
+
volumes_json = get(env, "#{@session.endpoints[:volume]}/volumes/detail")
|
22
|
+
JSON.parse(volumes_json)['volumes'].map do |volume|
|
23
|
+
name = volume['display_name']
|
24
|
+
name = volume['name'] if name.nil? # To be compatible with cinder api v1 and v2
|
25
|
+
case volume['attachments'].size
|
26
|
+
when 0
|
27
|
+
@logger.debug "No attachment found for volume #{volume['id']}"
|
28
|
+
else
|
29
|
+
attachment = volume['attachments'][0]
|
30
|
+
server_id = attachment['server_id']
|
31
|
+
device = attachment['device']
|
32
|
+
@logger.warn "Found #{attachment.size} attachments for volume #{volume['id']} : " if attachment.size > 1
|
33
|
+
@logger.debug "Attachment found for volume #{volume['id']} : #{attachment.to_json}"
|
34
|
+
end
|
35
|
+
Volume.new(volume['id'], name, volume['size'], volume['status'], volume['bootable'], server_id, device)
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
@@ -11,6 +11,14 @@ module VagrantPlugins
|
|
11
11
|
@id = id
|
12
12
|
@name = name
|
13
13
|
end
|
14
|
+
|
15
|
+
def ==(other)
|
16
|
+
other.class == self.class && other.state == state
|
17
|
+
end
|
18
|
+
|
19
|
+
def state
|
20
|
+
[@id, @name]
|
21
|
+
end
|
14
22
|
end
|
15
23
|
|
16
24
|
class Flavor < Item
|
@@ -36,10 +44,6 @@ module VagrantPlugins
|
|
36
44
|
super(id, name)
|
37
45
|
end
|
38
46
|
|
39
|
-
def ==(other)
|
40
|
-
other.class == self.class && other.state == state
|
41
|
-
end
|
42
|
-
|
43
47
|
protected
|
44
48
|
|
45
49
|
def state
|
@@ -55,6 +59,62 @@ module VagrantPlugins
|
|
55
59
|
@instance_id = instance_id
|
56
60
|
end
|
57
61
|
end
|
62
|
+
|
63
|
+
class Volume < Item
|
64
|
+
#
|
65
|
+
# Size in Gigaoctet
|
66
|
+
#
|
67
|
+
attr_accessor :size
|
68
|
+
|
69
|
+
#
|
70
|
+
# Status (e.g. 'Available', 'In-use')
|
71
|
+
#
|
72
|
+
attr_accessor :status
|
73
|
+
|
74
|
+
#
|
75
|
+
# Whether volume is bootable or not
|
76
|
+
#
|
77
|
+
attr_accessor :bootable
|
78
|
+
|
79
|
+
#
|
80
|
+
# instance id volume is attached to
|
81
|
+
#
|
82
|
+
attr_accessor :instance_id
|
83
|
+
|
84
|
+
#
|
85
|
+
# device (e.g. /dev/sdb) if attached
|
86
|
+
#
|
87
|
+
attr_accessor :device
|
88
|
+
|
89
|
+
# rubocop:disable Style/ParameterLists
|
90
|
+
def initialize(id, name, size, status, bootable, instance_id, device)
|
91
|
+
@size = size
|
92
|
+
@status = status
|
93
|
+
@bootable = bootable
|
94
|
+
@instance_id = instance_id
|
95
|
+
@device = device
|
96
|
+
super(id, name)
|
97
|
+
end
|
98
|
+
# rubocop:enable Style/ParameterLists
|
99
|
+
|
100
|
+
def to_s
|
101
|
+
{
|
102
|
+
id: @id,
|
103
|
+
name: @name,
|
104
|
+
size: @size,
|
105
|
+
status: @status,
|
106
|
+
bootable: @bootable,
|
107
|
+
instance_id: @instance_id,
|
108
|
+
device: @device
|
109
|
+
}.to_json
|
110
|
+
end
|
111
|
+
|
112
|
+
protected
|
113
|
+
|
114
|
+
def state
|
115
|
+
[@id, @name, @size, @status, @bootable, @instance_id, @device]
|
116
|
+
end
|
117
|
+
end
|
58
118
|
end
|
59
119
|
end
|
60
120
|
end
|