Class: Visor::Image::Store::Walrus

Inherits:
Object
  • Object
show all
Includes:
Common::Exception
Defined in:
lib/image/store/walrus.rb

Overview

The Eucalyptus Walrus (Walrus) backend store.

This class handles the management of image files located in the Walrus storage system, based on a URI like *walrus://<access_key>:<secret_key>@<host>:<port>/<bucket>/<image>*.

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(uri, config) ⇒ Object

Initializes a new Walrus store client object. Walrus credentials are loaded from the URI, on GET and DELETE operations, or from the configuration file for POST and PUT operation.

Parameters:

  • uri (String)

    The URI of the file location.

  • config (Hash)

    A set of configurations for the wanted store, loaded from VISoR configuration file.



29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
# File 'lib/image/store/walrus.rb', line 29

def initialize(uri, config)
  @uri    = URI(uri)
  @config = config[:walrus]

  if @uri.scheme
    @access_key = @uri.user
    @secret_key = @uri.password
    # Trick:
    # To build a successful Walrus connection we need happening to sign the
    # '/services/Walrus' in path too. If we append it to server's address it wont get
    # signed in the authorization string, we need to prepend it to the bucket name
    @bucket     = File.join('services/Walrus', @uri.path.split('/')[3])
    @file       = @uri.path.split('/').last
    @host       = @uri.host
    @port       = @uri.port
  else
    @access_key = @config[:access_key]
    @secret_key = @config[:secret_key]
    @bucket     = File.join('services/Walrus', @config[:bucket])
    @host       = @config[:host]
    @port       = @config[:port]
  end
end

Instance Attribute Details

#access_keyObject

Returns the value of attribute access_key.



18
19
20
# File 'lib/image/store/walrus.rb', line 18

def access_key
  @access_key
end

#bucketObject

Returns the value of attribute bucket.



18
19
20
# File 'lib/image/store/walrus.rb', line 18

def bucket
  @bucket
end

#configObject

Returns the value of attribute config.



18
19
20
# File 'lib/image/store/walrus.rb', line 18

def config
  @config
end

#fileObject

Returns the value of attribute file.



18
19
20
# File 'lib/image/store/walrus.rb', line 18

def file
  @file
end

#hostObject

Returns the value of attribute host.



18
19
20
# File 'lib/image/store/walrus.rb', line 18

def host
  @host
end

#portObject

Returns the value of attribute port.



18
19
20
# File 'lib/image/store/walrus.rb', line 18

def port
  @port
end

#secret_keyObject

Returns the value of attribute secret_key.



18
19
20
# File 'lib/image/store/walrus.rb', line 18

def secret_key
  @secret_key
end

#uriObject

Returns the value of attribute uri.



18
19
20
# File 'lib/image/store/walrus.rb', line 18

def uri
  @uri
end

Instance Method Details

#connectionS3restful::S3::Item

Returns a Walrus connection object.

Returns:

  • (S3restful::S3::Item)

    A new Walrus connection object.



57
58
59
60
# File 'lib/image/store/walrus.rb', line 57

def connection
  S3restful::S3::Item.new(bucket, file, server: host, port: port, protocol: 'http',
                          aws_access_key_id: access_key, aws_secret_access_key: secret_key)
end

#deleteObject

Deletes the image file from its location.

Raises:

  • (NotFound)

    If the image file was not found.



103
104
105
# File 'lib/image/store/walrus.rb', line 103

def delete
  connection.delete
end

#file_exists?(raise_exc = true) ⇒ True, False

Check if the image file exists.

Parameters:

  • raise_exc (True, False) (defaults to: true)

    (true) If it should raise exception or return true/false whether the file exists or not.

Returns:

  • (True, False)

    If raise_exc is false, return true/false whether the file exists or not.

Raises:

  • (NotFound)

    If the image file was not found.



117
118
119
120
121
122
123
124
125
# File 'lib/image/store/walrus.rb', line 117

def file_exists?(raise_exc=true)
  exist   = nil
  error   = proc { exist = false }
  success = proc { |res| exist = true if res.response_header.status == 200 }

  connection.head(on_error: error, on_success: success)
  raise NotFound, "No image file found at #{uri}" if raise_exc && !exist
  exist
end

#getObject

Returns the image file to clients, streamed in chunks.

Returns:

  • (Object)

    Yields the file, a chunk at time.



66
67
68
69
70
71
72
73
# File 'lib/image/store/walrus.rb', line 66

def get
  s3     = connection.aget
  finish = proc { yield nil }

  s3.stream { |chunk| yield chunk }
  s3.callback &finish
  s3.errback &finish
end

#save(id, tmp_file, format) ⇒ String, Integer

Saves the image file to the its final destination, based on the temporary file created by the server at data reception time.

Parameters:

  • id (String)

    The image id.

  • tmp_file (File)

    The temporary file descriptor.

  • format (String)

    The image file format.

Returns:

  • (String, Integer)

    The generated file location URI and image file size.

Raises:

  • (Duplicated)

    If the image file already exists.



86
87
88
89
90
91
92
93
94
95
96
97
# File 'lib/image/store/walrus.rb', line 86

def save(id, tmp_file, format)
  @file = "#{id}.#{format}"
  uri   = "walrus://#{access_key}:#{secret_key}@#{host}:#{port}/#{bucket}/#{file}"
  size  = tmp_file.size

  raise Duplicated, "The image file #{fp} already exists" if file_exists?(false)
  STDERR.puts "COPYING!!"

  connection.store tmp_file.path

  [uri, size]
end