Class: RightScale::MetadataSources::ConfigDriveMetadataSource

Inherits:
FileMetadataSource show all
Defined in:
lib/clouds/metadata_sources/config_drive_metadata_source.rb

Defined Under Namespace

Classes: ConfigDriveError

Constant Summary collapse

DEFAULT_CONFIG_DRIVE_MOUNTPOINT =
"/mnt/configdrive"

Instance Attribute Summary collapse

Attributes inherited from FileMetadataSource

#cloud_metadata_source_file_path, #user_metadata_source_file_path

Attributes inherited from RightScale::MetadataSource

#logger

Instance Method Summary collapse

Methods inherited from FileMetadataSource

#finish

Methods inherited from RightScale::MetadataSource

#append_branch_name, #append_leaf_name, #finish

Constructor Details

#initialize(options) ⇒ ConfigDriveMetadataSource

Returns a new instance of ConfigDriveMetadataSource.



35
36
37
38
39
40
41
42
43
44
45
46
# File 'lib/clouds/metadata_sources/config_drive_metadata_source.rb', line 35

def initialize(options)
  super(options)

  @config_drive_mountpoint        = options[:config_drive_mountpoint] || DEFAULT_CONFIG_DRIVE_MOUNTPOINT
  @config_drive_uuid              = options[:config_drive_uuid]
  @config_drive_filesystem        = options[:config_drive_filesystem]
  @config_drive_label             = options[:config_drive_label]

  if @config_drive_uuid.nil? & @config_drive_label.nil? & @config_drive_filesystem.nil?
    raise ArgumentError, "at least one of the following is required [options[:config_drive_label], options[:config_drive_filesystem],options[:config_drive_uuid]]"
  end
end

Instance Attribute Details

#config_drive_filesystemObject

Returns the value of attribute config_drive_filesystem.



33
34
35
# File 'lib/clouds/metadata_sources/config_drive_metadata_source.rb', line 33

def config_drive_filesystem
  @config_drive_filesystem
end

#config_drive_labelObject

Returns the value of attribute config_drive_label.



33
34
35
# File 'lib/clouds/metadata_sources/config_drive_metadata_source.rb', line 33

def config_drive_label
  @config_drive_label
end

#config_drive_mountpointObject

Returns the value of attribute config_drive_mountpoint.



33
34
35
# File 'lib/clouds/metadata_sources/config_drive_metadata_source.rb', line 33

def config_drive_mountpoint
  @config_drive_mountpoint
end

#config_drive_uuidObject

Returns the value of attribute config_drive_uuid.



33
34
35
# File 'lib/clouds/metadata_sources/config_drive_metadata_source.rb', line 33

def config_drive_uuid
  @config_drive_uuid
end

Instance Method Details

#mount_config_driveObject

Mounts the configuration drive based on the provided parameters

Parameters

Return

always true

Raises

ConfigDriveError

on failure to find a config drive

SystemCallError

on failure to create the mountpoint

ArgumentError

on invalid parameters

VolumeError

on a failure to mount the device

ParserError

on failure to parse volume list

Raises:



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
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
# File 'lib/clouds/metadata_sources/config_drive_metadata_source.rb', line 77

def mount_config_drive
  # These two conditions are available on *nix and windows
  conditions = {}
  conditions[:label] = @config_drive_label if @config_drive_label
  conditions[:filesystem] = @config_drive_filesystem if @config_drive_filesystem

  if ::RightScale::Platform.linux? && @config_drive_uuid
    conditions[:uuid] = @config_drive_uuid
  end

  timeout   = 60 * 10
  starttime = Time.now.to_i
  backoff   = [2,5,10]
  idx       = -1

  begin
    device_ary = []
    if ::RightScale::Platform.windows?
      # Check once, in case the metadata drive is onlined already
      device_ary = ::RightScale::Platform.volume_manager.volumes(conditions)
      ::RightScale::Platform.volume_manager.disks({:status => "Offline"}).each do |disk|
        ::RightScale::Platform.volume_manager.online_disk(disk[:index])
        # Per the interwebs, you cannot run disk part commands back to back without a wait.
        sleep(15)
        device_ary = ::RightScale::Platform.volume_manager.volumes(conditions)
        break if device_ary.length > 0
        ::RightScale::Platform.volume_manager.offline_disk(disk[:index])
      end unless device_ary.length > 0
    else
      device_ary = ::RightScale::Platform.volume_manager.volumes(conditions)
    end
    idx = idx + 1 unless idx == 2
    break if (Time.now.to_i - starttime) > timeout || device_ary.length > 0
    @logger.warn("Configuration drive device was not found.  Trying again in #{backoff[idx % backoff.length]} seconds.")
    Kernel.sleep(backoff[idx])
  end while device_ary.length == 0

  # REVIEW: Raise or log and exit?
  raise ConfigDriveError.new("Configuration drive device found. Conditions: #{conditions.inspect}") if device_ary.length == 0

  FileUtils.mkdir_p(@config_drive_mountpoint) unless File.directory? @config_drive_mountpoint

  if ::RightScale::Platform.linux?
    ::RightScale::Platform.volume_manager.mount_volume(device_ary[0], @config_drive_mountpoint)
  elsif ::RightScale::Platform.windows?
    ::RightScale::Platform.volume_manager.assign_device(device_ary[0][:index], @config_drive_mountpoint, {:idempotent => true, :clear_readonly => false, :remove_all => true})
  end
  return true
end

#query(path) ⇒ Object

Queries for metadata using the given path.

Parameters

path(String)

metadata path

Return

metadata(String)

query result or empty

Raises

QueryFailed

on any failure to query



58
59
60
61
62
# File 'lib/clouds/metadata_sources/config_drive_metadata_source.rb', line 58

def query(path)
  mount_config_drive

  super(path)
end