Last active
December 17, 2015 15:29
-
-
Save krames/5631808 to your computer and use it in GitHub Desktop.
This gist contains a patch to allow uploaded large segmented files in memory efficient manner in the Rackspace Cloud. It also includes an example demonstrating it's use. This should only be used with Fog 1.11.1. I am currently working on a pull request to include this in fog proper.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| #!/usr/bin/env ruby | |
| # This example demonstrates uploading large files in segments | |
| require 'rubygems' #required for Ruby 1.8.x | |
| require 'fog' | |
| # Size of segment. The Rackspace cloud currently requires files larger than 5GB to be segmented so we will choose 5GB -1 for a size | |
| # http://docs.rackspace.com/files/api/v1/cf-devguide/content/Large_Object_Creation-d1e2019.html | |
| SEGMENT_LIMIT = 5368709119.0 | |
| # Size of buffer to use for transfers. Use Excon's default chunk size and if that's not avaliable we will default to 1 MB | |
| BUFFER_SIZE = Excon.defaults[:chunk_size] || 1024 * 1024 | |
| def get_user_input(prompt) | |
| print "#{prompt}: " | |
| gets.chomp | |
| end | |
| # Use username defined in ~/.fog file, if absent prompt for username. | |
| # For more details on ~/.fog refer to http://fog.io/about/getting_started.html | |
| def rackspace_username | |
| Fog.credentials[:rackspace_username] || get_user_input("Enter Rackspace Username") | |
| end | |
| # Use api key defined in ~/.fog file, if absent prompt for api key | |
| # For more details on ~/.fog refer to http://fog.io/about/getting_started.html | |
| def rackspace_api_key | |
| Fog.credentials[:rackspace_api_key] || get_user_input("Enter Rackspace API key") | |
| end | |
| # create Cloud Files service | |
| service = Fog::Storage.new({ | |
| :provider => 'Rackspace', | |
| :rackspace_username => rackspace_username, | |
| :rackspace_api_key => rackspace_api_key, | |
| }) | |
| #Include this after the storage services is loaded to ensure that are patch takes effect | |
| require './patch_large_file_support.rb' | |
| # prompt for directory name | |
| directory_name = get_user_input "\nEnter name of directory to store file" | |
| # prompt for file name | |
| file_name = get_user_input "\nEnter full path of file to upload" | |
| File.open(file_name) do |f| | |
| num_segments = (f.size / SEGMENT_LIMIT).round + 1 | |
| puts "This upload of '#{file_name}' will require #{num_segments} segment and 1 manifest file\n" | |
| 1.upto(num_segments) do |segment| | |
| print "\nUploading segment #{segment} " | |
| offset = 0 | |
| read = 0 | |
| service.put_object(directory_name, "large_file/#{segment}", nil, options = {}) do | |
| if (offset < SEGMENT_LIMIT) && (read.zero? || read == BUFFER_SIZE) | |
| print "." | |
| buf = f.sysread(BUFFER_SIZE) | |
| read = buf.size | |
| offset += read | |
| buf | |
| else | |
| "" | |
| end | |
| end | |
| end | |
| end | |
| puts "writing manifest" | |
| service.put_object_manifest(directory_name, 'large_file') | |
| puts <<-NOTE | |
| You should now be able to download large_file from the cloud control panel or via the api using the following code: | |
| directory = service.directories.get('#{directory_name}') | |
| File.open('large_file.jpg', 'w') do | f | | |
| directory.files.get("large_file") do | data, remaining, content_length | | |
| print "." | |
| f.syswrite data | |
| end | |
| end | |
| NOTE |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| require 'rubygems' | |
| require 'fog' | |
| if Fog::VERSION == "1.11.1" | |
| Fog::Logger.warning "PATCHING Fog::Storage::Rackspace::Real to allow uploading of large objects" | |
| module Fog | |
| module Storage | |
| class Rackspace | |
| class Real | |
| def put_object(container, object, data, options = {}, &block) | |
| data = Fog::Storage.parse_data(data) | |
| headers = data[:headers].merge!(options) | |
| params = block_given? ? { :request_block => block } : { :body => data[:body] } | |
| params.merge!( | |
| :expects => 201, | |
| :idempotent => true, | |
| :headers => headers, | |
| :method => 'PUT', | |
| :path => "#{Fog::Rackspace.escape(container)}/#{Fog::Rackspace.escape(object)}" | |
| ) | |
| request(params) | |
| end | |
| end | |
| end | |
| end | |
| end | |
| else | |
| Fog::Logger.warning "PATCHING Fog::Storage::Rackspace::Real - does not apply for #{Fog::VERSION}. Please remove it." | |
| end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment