Class: Kitchen::Driver::Openstack::Volume

Inherits:
Object
  • Object
show all
Defined in:
lib/kitchen/driver/openstack/volume.rb

Overview

A class to allow the Kitchen Openstack driver to use Openstack volumes

Instances of this class translate a block_device_mapping config hash into the shape Nova expects, creating a Cinder volume first when the mapping asks for one.

Author:

Constant Summary collapse

DEFAULT_CREATION_TIMEOUT =

Seconds to wait for a newly created volume to become available when the block device mapping does not specify creation_timeout.

Returns:

  • (Integer)
60
VANILLA_VOLUME_OPTIONS =

Block device mapping keys forwarded verbatim to Cinder's create call.

Returns:

  • (Array<Symbol>)
%i{
  snapshot_id
  imageRef
  volume_type
  source_volid
  availability_zone
}.freeze

Instance Method Summary collapse

Constructor Details

#initialize(logger) ⇒ Volume

Returns a new instance of Volume.

Parameters:

  • logger (Kitchen::Logger)

    logger to report volume progress to



53
54
55
# File 'lib/kitchen/driver/openstack/volume.rb', line 53

def initialize(logger)
  @logger = logger
end

Instance Method Details

#create_volume(config, os) ⇒ String

Creates a Cinder volume and blocks until it is available.

Parameters:

  • config (Hash)

    the driver config, read for :server_name and :block_device_mapping

  • os (Hash)

    Fog connection settings

Returns:

  • (String)

    the id of the newly created volume

Raises:

  • (Kitchen::ActionFailed)

    if a timeout is not a number, if the volume cannot be found after creation, or if it enters an error state

  • (Fog::Errors::TimeoutError)

    if the volume is not available before :creation_timeout elapses



76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
# File 'lib/kitchen/driver/openstack/volume.rb', line 76

def create_volume(config, os)
  bdm = config[:block_device_mapping]

  # Read both timeouts before anything is created. They are pure config
  # parsing, so a bad value should cost the user an error message, not
  # an orphaned volume that `kitchen destroy` cannot see.
  creation_timeout = timeout_value(bdm, :creation_timeout, DEFAULT_CREATION_TIMEOUT)
  attach_timeout = timeout_value(bdm, :attach_timeout, 0)

  opt = VANILLA_VOLUME_OPTIONS.select { |o| bdm[o] }.to_h { |key| [key, bdm[key]] }

  # Build the Cinder connection once and reuse it for the readiness
  # lookup, rather than authenticating to Keystone a second time.
  volume_service = volume(os)

  @logger.info "Creating Volume..."
  resp = volume_service
    .create_volume(
      "#{config[:server_name]}-volume",
      "#{config[:server_name]} volume",
      bdm[:volume_size],
      opt
    )
  vol_id = resp[:body]["volume"]["id"]

  wait_for_volume(volume_service, vol_id, creation_timeout, attach_timeout)

  vol_id
end

#get_bdm(config, os) ⇒ Hash

Resolves the block device mapping to hand to Nova, creating the backing volume first if :make_volume is set.

The returned hash is a copy: the driver's own config is never mutated, so a retried create sees the same input it did the first time.

Parameters:

  • config (Hash)

    the driver config

  • os (Hash)

    Fog connection settings

Returns:

  • (Hash)

    a block device mapping suitable for Nova



116
117
118
119
120
121
122
# File 'lib/kitchen/driver/openstack/volume.rb', line 116

def get_bdm(config, os)
  bdm = config[:block_device_mapping].dup
  bdm[:volume_id] = create_volume(config, os) if bdm[:make_volume]
  bdm.delete(:make_volume)
  bdm.delete(:snapshot_id)
  bdm
end

#volume(openstack_server) ⇒ Fog::OpenStack::Volume

Builds a Cinder connection.

Parameters:

  • openstack_server (Hash)

    Fog connection settings

Returns:

  • (Fog::OpenStack::Volume)

    a Cinder service object



61
62
63
# File 'lib/kitchen/driver/openstack/volume.rb', line 61

def volume(openstack_server)
  Fog::OpenStack::Volume.new(openstack_server)
end