Class: Visor::Image::PostImage
- Inherits:
-
Goliath::API
- Object
- Goliath::API
- Visor::Image::PostImage
- Includes:
- Common::Exception, Common::Util
- Defined in:
- lib/image/routes/post_image.rb
Overview
Post image data and metadata and returns the registered metadata.
Instance Method Summary collapse
-
#do_upload(id, meta, body) ⇒ Array
Upload image file to wanted store.
-
#exit_error(code, message, set_status = false) ⇒ Array
Produce an HTTP response with an error code and message.
-
#insert_meta(meta) ⇒ Hash
Insert image metadata on database (which set its status to locked).
-
#on_body(env, data) ⇒ Object
Pre-process body as it arrives in streaming chunks and load them into a tempfile.
-
#on_close(env) ⇒ Object
On connection close log a message.
-
#on_headers(env, headers) ⇒ Object
Pre-process headers as they arrive and load them into a environment variable.
-
#response(env) ⇒ Array
Main response method which processes the received headers and body, managing image metadata and file data.
-
#upload_and_update(id, body) ⇒ Hash
Update image status and launch upload.
Instance Method Details
#do_upload(id, meta, body) ⇒ Array
Upload image file to wanted store.
173 174 175 176 177 178 179 180 181 182 183 184 185 |
# File 'lib/image/routes/post_image.rb', line 173 def do_upload(id, , body) content_type = env['headers']['Content-Type'] || '' store_name = [:store] || configs[:default] format = [:format] || 'none' unless content_type == 'application/octet-stream' raise ArgumentError, 'Request Content-Type must be application/octet-stream' end store = Visor::Image::Store.get_backend(store_name, configs) logger.debug "Uploading image #{id} data to #{store_name} store" store.save(id, body, format) end |
#exit_error(code, message, set_status = false) ⇒ Array
Produce an HTTP response with an error code and message.
113 114 115 116 117 118 119 120 121 |
# File 'lib/image/routes/post_image.rb', line 113 def exit_error(code, , set_status=false) logger.error begin vms.put_image(env['id'], status: 'error') if set_status rescue => e logger.error "Unable to set image #{env['id']} status to 'error': #{e.}" end [code, {}, {code: code, message: }] end |
#insert_meta(meta) ⇒ Hash
Insert image metadata on database (which set its status to locked).
129 130 131 132 133 134 135 136 137 138 139 140 |
# File 'lib/image/routes/post_image.rb', line 129 def () image = vms.post_image() env['id'] = image[:_id] if image[:location] logger.debug "Location for image #{env['id']} is #{image[:location]}" logger.debug "Setting image #{env['id']} status to 'available'" vms.put_image(env['id'], status: 'available') else image end end |
#on_body(env, data) ⇒ Object
Pre-process body as it arrives in streaming chunks and load them into a tempfile.
29 30 31 32 |
# File 'lib/image/routes/post_image.rb', line 29 def on_body(env, data) (env['body'] ||= Tempfile.open('visor-image', encoding: 'ascii-8bit')) << data (env['md5'] ||= Digest::MD5.new) << data end |
#on_close(env) ⇒ Object
On connection close log a message.
101 102 103 |
# File 'lib/image/routes/post_image.rb', line 101 def on_close(env) logger.info 'Connection closed' end |
#on_headers(env, headers) ⇒ Object
Pre-process headers as they arrive and load them into a environment variable.
19 20 21 22 |
# File 'lib/image/routes/post_image.rb', line 19 def on_headers(env, headers) logger.debug "Received headers: #{headers.inspect}" env['headers'] = headers end |
#response(env) ⇒ Array
Main response method which processes the received headers and body, managing image metadata and file data.
42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 |
# File 'lib/image/routes/post_image.rb', line 42 def response(env) begin access_key = (env, vas) rescue Forbidden => e return exit_error(403, e.) end = (env['headers']) [:owner] = access_key body = env['body'] location = [:location] if location && body msg = 'When the location header is present no file content can be provided' return exit_error(400, msg) end if [:store] == 'http' || (location && location.split(':').first == 'http') return exit_error(400, 'Cannot post an image file to a HTTP backend') if body store = Visor::Image::Store::HTTP.new(location) exist, [:size], [:checksum] = store.file_exists?(false) return exit_error(404, "No image file found at #{location}") unless exist end # first registers the image meta or raises on error begin image = () rescue ArgumentError => e body.close if body body.unlink if body return exit_error(400, e.) rescue InternalError => e body.close if body body.unlink if body return exit_error(500, e.) end # if has body(image file), upload file and update meta or raise on error begin image = upload_and_update(env['id'], body) rescue UnsupportedStore, ArgumentError => e return exit_error(400, e., true) rescue NotFound => e return exit_error(404, e., true) rescue Duplicated => e return exit_error(409, e., true) ensure body.close body.unlink end unless body.nil? [200, {}, {image: image}] end |
#upload_and_update(id, body) ⇒ Hash
Update image status and launch upload.
149 150 151 152 153 154 155 156 157 158 159 160 161 |
# File 'lib/image/routes/post_image.rb', line 149 def upload_and_update(id, body) logger.debug "Setting image #{id} status to 'uploading'" = vms.put_image(id, status: 'uploading') checksum = env['md5'] location, size = do_upload(id, , body) logger.debug "Updating image #{id} meta:" logger.debug "Setting status to 'available'" logger.debug "Setting location to '#{location}'" logger.debug "Setting size to '#{size}'" logger.debug "Setting checksum to '#{checksum}'" vms.put_image(id, status: 'available', uploaded_at: Time.now, location: location, size: size, checksum: checksum) end |