Class: Visor::Image::Store::HTTP

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

Overview

The HTTP backend store.

This class handles the management of image files located in a remote HTTP location, based on a URI like *‘www.domain.com/path-to-image-file’*.

Useful for point an image to the last release of some distro, like:

'http://www.ubuntu.com/start-download?distro=server&bits=64&release=latest'

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(uri, config = nil) ⇒ Object

Initializes a new HTTP store client object.

Parameters:

  • uri (String)

    The URI of the file location.

  • config (Hash) (defaults to: nil)

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



29
30
31
32
# File 'lib/image/store/http.rb', line 29

def initialize(uri, config=nil)
  @uri    = uri
  @config = config
end

Instance Attribute Details

#configObject

Returns the value of attribute config.



19
20
21
# File 'lib/image/store/http.rb', line 19

def config
  @config
end

#uriObject

Returns the value of attribute uri.



19
20
21
# File 'lib/image/store/http.rb', line 19

def uri
  @uri
end

Instance Method Details

#file_exists?(raise_exc = true) ⇒ String

Check if the image file exists. This will follow redirection to a nested deepness of 5 levels. It will also try to follow the location header if any.

Also, after finding the real location of the HTTP file, it will parse the file metadata, most properly the size and checksum, based on URL headers.

Returns:

  • (String)

    The discovered file checksum and size.

Raises:

  • (NotFound)

    If the image file was not found.



58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
# File 'lib/image/store/http.rb', line 58

def file_exists?(raise_exc=true)
  http = EventMachine::HttpRequest.new(uri, connect_timeout: 2, redirects: 5).head

  if location = http.response_header['LOCATION']
    http = EventMachine::HttpRequest.new(location, connect_timeout: 2).head
  end

  exist    = (http.response_header.status == 200)
  length   = http.response_header['CONTENT_LENGTH']
  size     = length.nil? ? nil : length.to_i
  etag     = http.response_header['ETAG']
  checksum = etag.nil? ? '' : etag.gsub('"', '')

  raise NotFound, "No image file found at #{uri}" if raise_exc && !exist
  [exist, size, checksum]
end

#getObject

Returns the image file to clients, streamed in chunks.

Returns:

  • (Object)

    Yields the file, a chunk at time.



38
39
40
41
42
43
44
45
# File 'lib/image/store/http.rb', line 38

def get
  http   = EventMachine::HttpRequest.new(uri).aget
  finish = proc { yield nil }

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