HTTP downloader implemented. Boxes can now be added via HTTP!
This commit is contained in:
parent
9913c07ff2
commit
3d220ef5c8
|
@ -3,7 +3,7 @@ $:.unshift(libdir)
|
|||
PROJECT_ROOT = File.join(libdir, '..') unless defined?(PROJECT_ROOT)
|
||||
|
||||
# The libs which must be loaded prior to the rest
|
||||
%w{tempfile open-uri ftools json pathname logger uri virtualbox net/ssh tarruby
|
||||
%w{tempfile open-uri ftools json pathname logger uri net/http virtualbox net/ssh tarruby
|
||||
net/scp fileutils vagrant/util vagrant/actions/base vagrant/downloaders/base}.each do |f|
|
||||
require f
|
||||
end
|
||||
|
|
|
@ -12,10 +12,13 @@ module Vagrant
|
|||
def prepare
|
||||
# Parse the URI given and prepare a downloader
|
||||
uri = URI.parse(@runner.uri)
|
||||
uri_map = [[URI::HTTP, Downloaders::HTTP], [URI::Generic, Downloaders::File]]
|
||||
|
||||
if uri.is_a?(URI::Generic)
|
||||
logger.info "Generic URI type for box download, assuming file..."
|
||||
@downloader = Downloaders::File.new
|
||||
uri_map.find do |uri_type, downloader_klass|
|
||||
if uri.is_a?(uri_type)
|
||||
logger.info "#{uri_type} for URI, downloading via #{downloader_klass}..."
|
||||
@downloader = downloader_klass.new
|
||||
end
|
||||
end
|
||||
|
||||
raise ActionException.new("Unknown URI type for box download.") unless @downloader
|
||||
|
|
|
@ -0,0 +1,40 @@
|
|||
module Vagrant
|
||||
module Downloaders
|
||||
# Downloads a file from an HTTP URL to a temporary file. This
|
||||
# downloader reports its progress to stdout while downloading.
|
||||
class HTTP < Base
|
||||
# ANSI escape code to clear lines from cursor to end of line
|
||||
CL_RESET = "\r\e[0K"
|
||||
|
||||
def download!(source_url, destination_file)
|
||||
Net::HTTP.get_response(URI.parse(source_url)) do |response|
|
||||
total = response.content_length
|
||||
progress = 0
|
||||
segment_count = 0
|
||||
|
||||
response.read_body do |segment|
|
||||
# Report the progress out
|
||||
progress += segment.length
|
||||
segment_count += 1
|
||||
|
||||
# Progress reporting is limited to every 25 segments just so
|
||||
# we're not constantly updating
|
||||
if segment_count % 25 == 0
|
||||
report_progress(progress, total)
|
||||
segment_count = 0
|
||||
end
|
||||
|
||||
# Store the segment
|
||||
destination_file.write(segment)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def report_progress(progress, total)
|
||||
percent = (progress.to_f / total.to_f) * 100
|
||||
print "#{CL_RESET}Download Progress: #{percent.to_i}% (#{progress} / #{total})"
|
||||
$stdout.flush
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
|
@ -30,6 +30,12 @@ class DownloadBoxActionTest < Test::Unit::TestCase
|
|||
@action.prepare
|
||||
assert @action.downloader.is_a?(Vagrant::Downloaders::File)
|
||||
end
|
||||
|
||||
should "set the downloader to HTTP if URI is HTTP" do
|
||||
@uri.stubs(:is_a?).with(URI::HTTP).returns(true)
|
||||
@action.prepare
|
||||
assert @action.downloader.is_a?(Vagrant::Downloaders::HTTP)
|
||||
end
|
||||
end
|
||||
|
||||
context "executing" do
|
||||
|
|
|
@ -0,0 +1,39 @@
|
|||
require File.join(File.dirname(__FILE__), '..', '..', 'test_helper')
|
||||
|
||||
class HttpDownloaderTest < Test::Unit::TestCase
|
||||
setup do
|
||||
@downloader, @tempfile = mock_downloader(Vagrant::Downloaders::HTTP)
|
||||
@downloader.stubs(:report_progress)
|
||||
@uri = "foo.box"
|
||||
end
|
||||
|
||||
context "downloading" do
|
||||
setup do
|
||||
@parsed_uri = mock("parsed")
|
||||
URI.stubs(:parse).with(@uri).returns(@parsed_uri)
|
||||
end
|
||||
|
||||
should "parse the URI and use that parsed URI for Net::HTTP" do
|
||||
URI.expects(:parse).with(@uri).returns(@parsed_uri).once
|
||||
Net::HTTP.expects(:get_response).with(@parsed_uri).once
|
||||
@downloader.download!(@uri, @tempfile)
|
||||
end
|
||||
|
||||
should "read the body of the response and place each segment into the file" do
|
||||
response = mock("response")
|
||||
response.stubs(:content_length)
|
||||
segment = mock("segment")
|
||||
segment.stubs(:length).returns(7)
|
||||
|
||||
Net::HTTP.stubs(:get_response).yields(response)
|
||||
response.expects(:read_body).once.yields(segment)
|
||||
@tempfile.expects(:write).with(segment).once
|
||||
|
||||
@downloader.download!(@uri, @tempfile)
|
||||
end
|
||||
end
|
||||
|
||||
context "reporting progress" do
|
||||
# TODO: Testing for this, probably
|
||||
end
|
||||
end
|
Loading…
Reference in New Issue