Class: VagrantLXD::Driver
- Inherits:
-
Object
- Object
- VagrantLXD::Driver
show all
- Extended by:
- MonitorMixin
- Includes:
- Vagrant::Util
- Defined in:
- lib/vagrant-lxd/driver.rb,
lib/vagrant-lxd/driver/certificate.rb
Defined Under Namespace
Classes: AuthenticationFailure, Certificate, CertificateGenerationFailure, ConnectionFailure, ContainerAlreadyExists, ContainerConfigurationFailure, ContainerCreationFailure, ContainerDeletionFailure, ContainerNotFound, DiskMountFailure, DiskUnmountFailure, DuplicateAttachmentFailure, ImageCreationFailure, ImageExportFailure, NetworkAddressAcquisitionTimeout, OperationTimeout, ProjectMiddleware, SnapshotNotFound
Constant Summary
collapse
- USER_AGENT =
"#{Version::DESCRIPTION} #{Version::VERSION} (#{Hyperkit::Default.user_agent})"
- IMAGE_PROPERTIES =
{ description: "#{Version::DESCRIPTION} #{Version::VERSION}" }
- NOT_CREATED =
Vagrant::MachineState::NOT_CREATED_ID
Instance Attribute Summary collapse
Instance Method Summary
collapse
Constructor Details
#initialize(machine) ⇒ Driver
Returns a new instance of Driver.
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
|
# File 'lib/vagrant-lxd/driver.rb', line 165
def initialize(machine)
@machine = machine
@image = machine.provider_config.image
@timeout = machine.provider_config.timeout
@api_endpoint = machine.provider_config.api_endpoint
@config = machine.provider_config.config
@devices = machine.provider_config.devices
@environment = machine.provider_config.environment
@nesting = machine.provider_config.nesting
@privileged = machine.provider_config.privileged
@ephemeral = machine.provider_config.ephemeral
@profiles = machine.provider_config.profiles
@project = machine.provider_config.project
@name = machine.provider_config.name
@client_certificate = machine.provider_config.client_certificate
@client_key = machine.provider_config.client_key
@vagrant_uid = machine.provider_config.vagrant_uid
@vagrant_gid = machine.provider_config.vagrant_gid
@logger = Log4r::Logger.new('vagrant::lxd::driver')
end
|
Instance Attribute Details
#api_endpoint ⇒ Object
Returns the value of attribute api_endpoint.
150
151
152
|
# File 'lib/vagrant-lxd/driver.rb', line 150
def api_endpoint
@api_endpoint
end
|
#client_certificate ⇒ Object
Returns the value of attribute client_certificate.
160
161
162
|
# File 'lib/vagrant-lxd/driver.rb', line 160
def client_certificate
@client_certificate
end
|
#client_key ⇒ Object
Returns the value of attribute client_key.
161
162
163
|
# File 'lib/vagrant-lxd/driver.rb', line 161
def client_key
@client_key
end
|
#devices ⇒ Object
Returns the value of attribute devices.
153
154
155
|
# File 'lib/vagrant-lxd/driver.rb', line 153
def devices
@devices
end
|
#environment ⇒ Object
Returns the value of attribute environment.
154
155
156
|
# File 'lib/vagrant-lxd/driver.rb', line 154
def environment
@environment
end
|
#ephemeral ⇒ Object
Returns the value of attribute ephemeral.
155
156
157
|
# File 'lib/vagrant-lxd/driver.rb', line 155
def ephemeral
@ephemeral
end
|
#name ⇒ Object
Returns the value of attribute name.
151
152
153
|
# File 'lib/vagrant-lxd/driver.rb', line 151
def name
@name
end
|
#nesting ⇒ Object
Returns the value of attribute nesting.
156
157
158
|
# File 'lib/vagrant-lxd/driver.rb', line 156
def nesting
@nesting
end
|
#privileged ⇒ Object
Returns the value of attribute privileged.
157
158
159
|
# File 'lib/vagrant-lxd/driver.rb', line 157
def privileged
@privileged
end
|
#profiles ⇒ Object
Returns the value of attribute profiles.
158
159
160
|
# File 'lib/vagrant-lxd/driver.rb', line 158
def profiles
@profiles
end
|
#project ⇒ Object
Returns the value of attribute project.
159
160
161
|
# File 'lib/vagrant-lxd/driver.rb', line 159
def project
@project
end
|
#timeout ⇒ Object
Returns the value of attribute timeout.
152
153
154
|
# File 'lib/vagrant-lxd/driver.rb', line 152
def timeout
@timeout
end
|
#vagrant_gid ⇒ Object
Returns the value of attribute vagrant_gid.
163
164
165
|
# File 'lib/vagrant-lxd/driver.rb', line 163
def vagrant_gid
@vagrant_gid
end
|
#vagrant_uid ⇒ Object
Returns the value of attribute vagrant_uid.
162
163
164
|
# File 'lib/vagrant-lxd/driver.rb', line 162
def vagrant_uid
@vagrant_uid
end
|
Instance Method Details
#attach(container) ⇒ Object
235
236
237
238
239
240
241
242
243
244
245
246
|
# File 'lib/vagrant-lxd/driver.rb', line 235
def attach(container)
lxd.container(container)
if in_state? NOT_CREATED
@machine.id = container
else
fail DuplicateAttachmentFailure, machine_name: @machine.name, container: container
end
rescue Hyperkit::NotFound
@machine.ui.error "Container doesn't exist: #{container}"
fail ContainerNotFound, machine_name: @machine.name, container: container
end
|
359
360
361
362
363
364
365
366
367
|
# File 'lib/vagrant-lxd/driver.rb', line 359
def configure
container = lxd.container(machine_id)
container[:config] = container[:config].to_hash.merge(config)
container[:devices] = container[:devices].to_hash.merge(devices)
lxd.update_container(machine_id, container)
rescue Hyperkit::Error => e
@machine.ui.error 'Failed to configure container'
fail ContainerConfigurationFailure, machine_name: @machine.name, reason: e.reason
end
|
#create ⇒ Object
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
|
# File 'lib/vagrant-lxd/driver.rb', line 288
def create
if in_state? NOT_CREATED
fingerprint = image_from_box
machine_id = generate_machine_id
container = lxd.create_container(machine_id, devices: devices, ephemeral: ephemeral, fingerprint: fingerprint, config: config, profiles: profiles)
@logger.debug 'Created container: ' << container.inspect
@machine.id = machine_id
end
rescue Hyperkit::Error => e
lxd.delete_container(machine_id) rescue nil unless container.nil?
lxd.delete_image(fingerprint) rescue nil unless fingerprint.nil?
if e.reason =~ /Container '([^']+)' already exists/
@machine.ui.error e.reason
fail ContainerAlreadyExists, machine_name: @machine.name, container: $1
else
@machine.ui.error 'Failed to create container'
fail ContainerCreationFailure, machine_name: @machine.name, reason: e.reason
end
end
|
#destroy ⇒ Object
342
343
344
345
346
347
348
349
|
# File 'lib/vagrant-lxd/driver.rb', line 342
def destroy
if in_state? :stopped
delete_image
delete_container
else
@logger.debug "Skipped container destroy (#{machine_id} is not stopped)"
end
end
|
#detach ⇒ Object
248
249
250
|
# File 'lib/vagrant-lxd/driver.rb', line 248
def detach
@machine.id = nil
end
|
#exec(command) ⇒ Object
398
399
400
401
402
403
404
|
# File 'lib/vagrant-lxd/driver.rb', line 398
def exec(command)
operation = lxd.execute_command(machine_id, command, sync: false, record_output: true)
wait_for_operation(operation).metadata.tap do |result|
result.output[:'1'] = lxd.get(result.output[:'1'])
result.output[:'2'] = lxd.get(result.output[:'2'])
end
end
|
#halt(force = false) ⇒ Object
320
321
322
323
324
325
326
327
328
329
330
331
|
# File 'lib/vagrant-lxd/driver.rb', line 320
def halt(force = false)
if in_state? :running, :frozen
lxd.stop_container(machine_id, timeout: timeout, force: force)
end
rescue Hyperkit::BadRequest
if force
fail OperationTimeout, time_limit: timeout, operation: 'stop', machine_id: machine_id
else
@machine.ui.warn "Container failed to stop within #{timeout} seconds, forcing shutdown..."
halt(true)
end
end
|
#info ⇒ Object
406
407
408
409
410
411
412
413
|
# File 'lib/vagrant-lxd/driver.rb', line 406
def info
if in_state? :running, :frozen
{
host: ipv4_address,
port: ipv4_port,
}
end
end
|
#mount(name, options) ⇒ Object
203
204
205
206
207
208
209
210
211
212
|
# File 'lib/vagrant-lxd/driver.rb', line 203
def mount(name, options)
container = lxd.container(machine_id)
devices = container[:devices].to_hash
devices[name] = { type: 'disk', path: options[:guestpath], source: options[:hostpath] }.merge(options[:config])
container[:devices] = devices
lxd.update_container(machine_id, container)
rescue Hyperkit::BadRequest => e
@machine.ui.error 'Failed to mount synced folder'
fail DiskMountFailure, machine_name: @machine.name, guestpath: options[:guestpath], reason: e.reason
end
|
#mounted?(name, options) ⇒ Boolean
214
215
216
217
218
219
220
221
222
223
224
|
# File 'lib/vagrant-lxd/driver.rb', line 214
def mounted?(name, options)
container = lxd.container(machine_id)
devices = container[:devices].to_hash
name = name.to_sym
begin
devices[name] and
devices[name][:type] == 'disk' and
devices[name][:path] == options[:guestpath] and
devices[name][:source] == options[:hostpath]
end
end
|
#package ⇒ Object
351
352
353
354
355
356
357
|
# File 'lib/vagrant-lxd/driver.rb', line 351
def package
if in_state? :stopped
create_package_directory
else
@logger.debug "Skipped packaging (#{machine_id} is not stopped)"
end
end
|
#reconnect ⇒ Object
When a container is restarted, the ‘forkproxy` processes that manage its proxy devices will persist but will not reliably recreate container-side listeners for devices that are configured with “bind=container”. Removing and re-creating the devices forces the proxy processes to be recreated, ensuring the listeners are as well.
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
|
# File 'lib/vagrant-lxd/driver.rb', line 374
def reconnect
container = lxd.container(machine_id)
devices = container[:devices].to_hash
proxies = devices.select { |_, d| d[:type] == 'proxy' }
return if proxies.empty?
@machine.ui.info 'Reconnecting proxy devices...'
container[:devices] = devices.except(*proxies.keys)
lxd.update_container(machine_id, container)
container[:devices] = devices.merge(proxies)
lxd.update_container(machine_id, container)
rescue Hyperkit::Error => e
@machine.ui.error 'Failed to connect proxy devices'
fail ContainerConfigurationFailure, machine_name: @machine.name, reason: e.reason
end
|
#resume ⇒ Object
308
309
310
311
312
313
314
315
316
317
318
|
# File 'lib/vagrant-lxd/driver.rb', line 308
def resume
case state
when :stopped
lxd.start_container(machine_id)
when :frozen
lxd.unfreeze_container(machine_id, timeout: timeout)
end
rescue Hyperkit::BadRequest
@machine.ui.warn "Container failed to start within #{timeout} seconds"
fail OperationTimeout, time_limit: timeout, operation: 'start', machine_id: machine_id
end
|
#snapshot_delete(name) ⇒ Object
274
275
276
277
278
|
# File 'lib/vagrant-lxd/driver.rb', line 274
def snapshot_delete(name)
lxd.delete_snapshot(machine_id, name)
rescue Hyperkit::NotFound
@logger.warn 'No such snapshot: ' << name
end
|
#snapshot_list ⇒ Object
The following methods correspond directly to middleware actions.
256
257
258
|
# File 'lib/vagrant-lxd/driver.rb', line 256
def snapshot_list
lxd.snapshots(machine_id)
end
|
#snapshot_restore(name) ⇒ Object
266
267
268
269
270
271
272
|
# File 'lib/vagrant-lxd/driver.rb', line 266
def snapshot_restore(name)
operation = lxd.restore_snapshot(machine_id, name, sync: false)
wait_for_operation(operation)
rescue Hyperkit::BadRequest
@logger.warn 'Snapshot restoration failed: ' << name
fail SnapshotNotFound, machine: @machine.name, snapshot_name: name
end
|
#snapshot_save(name) ⇒ Object
260
261
262
263
264
|
# File 'lib/vagrant-lxd/driver.rb', line 260
def snapshot_save(name)
snapshot_delete(name)
operation = lxd.create_snapshot(machine_id, name, sync: false)
wait_for_operation(operation)
end
|
#state ⇒ Object
280
281
282
283
284
285
286
|
# File 'lib/vagrant-lxd/driver.rb', line 280
def state
return NOT_CREATED if machine_id.nil?
container_state = lxd.container_state(machine_id)
container_state[:status].downcase.to_sym
rescue Hyperkit::NotFound
NOT_CREATED
end
|
#suspend ⇒ Object
333
334
335
336
337
338
339
340
|
# File 'lib/vagrant-lxd/driver.rb', line 333
def suspend
if in_state? :running
lxd.freeze_container(machine_id, timeout: timeout)
end
rescue Hyperkit::BadRequest
@machine.ui.warn "Container failed to suspend within #{timeout} seconds"
fail OperationTimeout, time_limit: timeout, operation: 'info', machine_id: machine_id
end
|
#synced_folders_usable? ⇒ Boolean
191
192
193
194
195
196
197
198
199
200
201
|
# File 'lib/vagrant-lxd/driver.rb', line 191
def synced_folders_usable?
raw_idmap = config[:'raw.idmap']
begin
raw_idmap and
id_in_map?(Process.uid, 'uid', raw_idmap) and
id_in_map?(Process.gid, 'gid', raw_idmap)
end
rescue Vagrant::Errors::ProviderNotUsable
false
end
|
#unmount(name, options) ⇒ Object
226
227
228
229
230
231
232
233
|
# File 'lib/vagrant-lxd/driver.rb', line 226
def unmount(name, options)
container = lxd.container(machine_id)
container[:devices] = container[:devices].to_hash.except(name.to_sym)
lxd.update_container(machine_id, container)
rescue Hyperkit::BadRequest => e
@machine.ui.error 'Failed to unmount synced folder'
fail DiskUnmountFailure, machine_name: @machine.name, guestpath: options[:guestpath], reason: e.reason
end
|
#validate! ⇒ Object
186
187
188
189
|
# File 'lib/vagrant-lxd/driver.rb', line 186
def validate!
raise error(ConnectionFailure) unless connection_usable?
raise error(AuthenticationFailure) unless authentication_usable?
end
|