Remove checksum from downloader and replace with FileChecksum

Remove checksum implementation within the Util::Downloader and
relocate it into the FileChecksum helper class. Update Downloader
to use FileChecksum.
This commit is contained in:
Chris Roberts 2019-10-04 14:12:56 -07:00
parent 7fb81bcea1
commit 9ee5ce4817
2 changed files with 42 additions and 38 deletions

View File

@ -8,6 +8,7 @@ require "vagrant/util/busy"
require "vagrant/util/platform" require "vagrant/util/platform"
require "vagrant/util/subprocess" require "vagrant/util/subprocess"
require "vagrant/util/curl_helper" require "vagrant/util/curl_helper"
require "vagrant/util/file_checksum"
module Vagrant module Vagrant
module Util module Util
@ -21,15 +22,6 @@ module Vagrant
# Vagrant/1.7.4 (+https://www.vagrantup.com; ruby2.1.0) # Vagrant/1.7.4 (+https://www.vagrantup.com; ruby2.1.0)
USER_AGENT = "Vagrant/#{VERSION} (+https://www.vagrantup.com; #{RUBY_ENGINE}#{RUBY_VERSION}) #{ENV['VAGRANT_USER_AGENT_PROVISIONAL_STRING']}".freeze USER_AGENT = "Vagrant/#{VERSION} (+https://www.vagrantup.com; #{RUBY_ENGINE}#{RUBY_VERSION}) #{ENV['VAGRANT_USER_AGENT_PROVISIONAL_STRING']}".freeze
# Supported file checksum
CHECKSUM_MAP = {
:md5 => Digest::MD5,
:sha1 => Digest::SHA1,
:sha256 => Digest::SHA256,
:sha384 => Digest::SHA384,
:sha512 => Digest::SHA512
}.freeze
# Hosts that do not require notification on redirect # Hosts that do not require notification on redirect
SILENCED_HOSTS = [ SILENCED_HOSTS = [
"vagrantcloud.com".freeze, "vagrantcloud.com".freeze,
@ -76,7 +68,7 @@ module Vagrant
:sha256 => options[:sha256], :sha256 => options[:sha256],
:sha384 => options[:sha384], :sha384 => options[:sha384],
:sha512 => options[:sha512] :sha512 => options[:sha512]
} }.compact
end end
# This executes the actual download, downloading the source file # This executes the actual download, downloading the source file
@ -172,36 +164,23 @@ module Vagrant
# @option checksums [String] :sha1 Compare SHA1 checksum # @option checksums [String] :sha1 Compare SHA1 checksum
# @return [Boolean] # @return [Boolean]
def validate_download!(source, path, checksums) def validate_download!(source, path, checksums)
CHECKSUM_MAP.each do |type, klass| checksums.each do |type, expected|
if checksums[type] actual = FileChecksum.new(path, type).checksum
result = checksum_file(klass, path) @logger.debug("Validating checksum (#{type}) for #{source}. " \
@logger.debug("Validating checksum (#{type}) for #{source}. " \ "expected: #{expected} actual: #{actual}")
"expected: #{checksums[type]} actual: #{result}") if actual.casecmp(expected) != 0
if checksums[type] != result raise Errors::DownloaderChecksumError.new(
raise Errors::DownloaderChecksumError.new( source: source,
source: source, path: path,
path: path, type: type,
type: type, expected_checksum: expected,
expected_checksum: checksums[type], actual_checksum: actual
actual_checksum: result )
)
end
end end
end end
true true
end end
# Generate checksum on given file
#
# @param digest_class [Class] Digest class to use for generating checksum
# @param path [String, Pathname] Path to file
# @return [String] hexdigest result
def checksum_file(digest_class, path)
digester = digest_class.new
digester.file(path)
digester.hexdigest
end
def execute_curl(options, subprocess_options, &data_proc) def execute_curl(options, subprocess_options, &data_proc)
options = options.dup options = options.dup
options << subprocess_options options << subprocess_options

View File

@ -10,13 +10,27 @@ end
class FileChecksum class FileChecksum
BUFFER_SIZE = 1024 * 8 BUFFER_SIZE = 1024 * 8
# Supported file checksum
CHECKSUM_MAP = {
:md5 => Digest::MD5,
:sha1 => Digest::SHA1,
:sha256 => Digest::SHA256,
:sha384 => Digest::SHA384,
:sha512 => Digest::SHA512
}.freeze
# Initializes an object to calculate the checksum of a file. The given # Initializes an object to calculate the checksum of a file. The given
# ``digest_klass`` should implement the ``DigestClass`` interface. Note # ``digest_klass`` should implement the ``DigestClass`` interface. Note
# that the built-in Ruby digest classes duck type this properly: # that the built-in Ruby digest classes duck type this properly:
# Digest::MD5, Digest::SHA1, etc. # Digest::MD5, Digest::SHA1, etc.
def initialize(path, digest_klass) def initialize(path, digest_klass)
@digest_klass = digest_klass if digest_klass.is_a?(Class)
@path = path @digest_klass = digest_klass
else
@digest_klass = load_digest(digest_klass)
end
@path = path
end end
# This calculates the checksum of the file and returns it as a # This calculates the checksum of the file and returns it as a
@ -40,6 +54,17 @@ class FileChecksum
end end
end end
return digest.hexdigest digest.hexdigest
end
private
def load_digest(type)
digest = CHECKSUM_MAP[type.to_s.to_sym]
if digest.nil?
raise Errors::BoxChecksumInvalidType,
type: type.to_s
end
digest
end end
end end