Add resumable downloads
Since VM images can be fairly large and connections rather flaky, it would be nice to support resumable downloads whereby, if a download is interrupted for some reason, on the next attempt, it picks up where it left off. To implement this, the following changes were made: * The temporary download filename is now constructed from a SHA1 of the `box_url` instead of a timestamp. This allows separate invocations of Vagrant to 'share' the download-path if the URLs exactly match. * Add `--continue-at -` option to `curl` which tells it to automatically resume downloading where it left off * Modify the `recover` method in `box_add` to not remove the temporary download path if the download was interrupted Known Issue: * The progress on a resumed download will look a bit wonky in the sense that, it starts at 0% each time, instead of where it left off. Since Vagrant is pulling this directly from `curl`, this is more of an upstream issue. Fixes #57
This commit is contained in:
parent
b4aa8c0061
commit
87a47abee8
|
@ -5,6 +5,7 @@ IMPROVEMENTS:
|
||||||
- commands/provision: Add `--no-parallel` option to disable provider
|
- commands/provision: Add `--no-parallel` option to disable provider
|
||||||
parallelization if the provider supports it. [GH-2404]
|
parallelization if the provider supports it. [GH-2404]
|
||||||
- providers/virtualbox: Enable symlinks for VirtualBox 4.1. [GH-2414]
|
- providers/virtualbox: Enable symlinks for VirtualBox 4.1. [GH-2414]
|
||||||
|
- core: Support resumable downloads [GH-57]
|
||||||
|
|
||||||
BUG FIXES:
|
BUG FIXES:
|
||||||
|
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
require "digest/sha1"
|
||||||
require "log4r"
|
require "log4r"
|
||||||
|
|
||||||
require "vagrant/util/downloader"
|
require "vagrant/util/downloader"
|
||||||
|
@ -15,7 +16,8 @@ module Vagrant
|
||||||
end
|
end
|
||||||
|
|
||||||
def call(env)
|
def call(env)
|
||||||
@temp_path = env[:tmp_path].join("box" + Time.now.to_i.to_s)
|
@download_interrupted = false
|
||||||
|
@temp_path = env[:tmp_path].join("box" + Digest::SHA1.hexdigest(env[:box_url]))
|
||||||
@logger.info("Downloading box to: #{@temp_path}")
|
@logger.info("Downloading box to: #{@temp_path}")
|
||||||
|
|
||||||
url = env[:box_url]
|
url = env[:box_url]
|
||||||
|
@ -40,6 +42,7 @@ module Vagrant
|
||||||
rescue Errors::DownloaderInterrupted
|
rescue Errors::DownloaderInterrupted
|
||||||
# The downloader was interrupted, so just return, because that
|
# The downloader was interrupted, so just return, because that
|
||||||
# means we were interrupted as well.
|
# means we were interrupted as well.
|
||||||
|
@download_interrupted = true
|
||||||
env[:ui].info(I18n.t("vagrant.actions.box.download.interrupted"))
|
env[:ui].info(I18n.t("vagrant.actions.box.download.interrupted"))
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
|
@ -82,7 +85,7 @@ module Vagrant
|
||||||
end
|
end
|
||||||
|
|
||||||
def recover(env)
|
def recover(env)
|
||||||
if @temp_path && File.exist?(@temp_path)
|
if @temp_path && File.exist?(@temp_path) && !@download_interrupted
|
||||||
File.unlink(@temp_path)
|
File.unlink(@temp_path)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -37,7 +37,8 @@ module Vagrant
|
||||||
"--location",
|
"--location",
|
||||||
"--max-redirs", "10",
|
"--max-redirs", "10",
|
||||||
"--user-agent", USER_AGENT,
|
"--user-agent", USER_AGENT,
|
||||||
"--output", @destination
|
"--output", @destination,
|
||||||
|
"--continue-at", "-"
|
||||||
]
|
]
|
||||||
|
|
||||||
options << "--insecure" if @insecure
|
options << "--insecure" if @insecure
|
||||||
|
|
Loading…
Reference in New Issue