Merge pull request #11101 from chrisroberts/e-checksums
Extend checksum support for box validation and remote files
This commit is contained in:
commit
0d2751686b
|
@ -527,22 +527,11 @@ module Vagrant
|
||||||
end
|
end
|
||||||
|
|
||||||
def validate_checksum(checksum_type, checksum, path)
|
def validate_checksum(checksum_type, checksum, path)
|
||||||
checksum_klass = case checksum_type.to_sym
|
@logger.info("Validating checksum with #{checksum_type}")
|
||||||
when :md5
|
|
||||||
Digest::MD5
|
|
||||||
when :sha1
|
|
||||||
Digest::SHA1
|
|
||||||
when :sha256
|
|
||||||
Digest::SHA2
|
|
||||||
else
|
|
||||||
raise Errors::BoxChecksumInvalidType,
|
|
||||||
type: checksum_type.to_s
|
|
||||||
end
|
|
||||||
|
|
||||||
@logger.info("Validating checksum with #{checksum_klass}")
|
|
||||||
@logger.info("Expected checksum: #{checksum}")
|
@logger.info("Expected checksum: #{checksum}")
|
||||||
|
|
||||||
actual = FileChecksum.new(path, checksum_klass).checksum
|
actual = FileChecksum.new(path, checksum_type).checksum
|
||||||
|
@logger.info("Actual checksum: #{actual}")
|
||||||
if actual.casecmp(checksum) != 0
|
if actual.casecmp(checksum) != 0
|
||||||
raise Errors::BoxChecksumMismatch,
|
raise Errors::BoxChecksumMismatch,
|
||||||
actual: actual,
|
actual: actual,
|
||||||
|
|
|
@ -1,12 +1,14 @@
|
||||||
require "uri"
|
require "uri"
|
||||||
|
|
||||||
require "log4r"
|
require "log4r"
|
||||||
|
require "digest"
|
||||||
require "digest/md5"
|
require "digest/md5"
|
||||||
require "digest/sha1"
|
require "digest/sha1"
|
||||||
require "vagrant/util/busy"
|
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
|
||||||
|
@ -20,12 +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
|
|
||||||
}.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,
|
||||||
|
@ -68,8 +64,11 @@ module Vagrant
|
||||||
@location_trusted = options[:location_trusted]
|
@location_trusted = options[:location_trusted]
|
||||||
@checksums = {
|
@checksums = {
|
||||||
:md5 => options[:md5],
|
:md5 => options[:md5],
|
||||||
:sha1 => options[:sha1]
|
:sha1 => options[:sha1],
|
||||||
}
|
:sha256 => options[:sha256],
|
||||||
|
:sha384 => options[:sha384],
|
||||||
|
:sha512 => options[:sha512]
|
||||||
|
}.compact
|
||||||
end
|
end
|
||||||
|
|
||||||
# This executes the actual download, downloading the source file
|
# This executes the actual download, downloading the source file
|
||||||
|
@ -165,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
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -19,6 +19,12 @@ module VagrantPlugins
|
||||||
o.on("-u", "--username USERNAME_OR_EMAIL", String, "Vagrant Cloud username or email address") do |u|
|
o.on("-u", "--username USERNAME_OR_EMAIL", String, "Vagrant Cloud username or email address") do |u|
|
||||||
options[:username] = u
|
options[:username] = u
|
||||||
end
|
end
|
||||||
|
o.on("-c", "--checksum CHECKSUM_VALUE", String, "Checksum of the box for this provider. --checksum-type option is required.") do |c|
|
||||||
|
options[:checksum] = c
|
||||||
|
end
|
||||||
|
o.on("-C", "--checksum-type TYPE", String, "Type of checksum used (md5, sha1, sha256, sha384, sha512). --checksum option is required.") do |c|
|
||||||
|
options[:checksum_type] = c
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
# Parse the options
|
# Parse the options
|
||||||
|
@ -52,16 +58,17 @@ module VagrantPlugins
|
||||||
account = VagrantPlugins::CloudCommand::Util.account(org, access_token, server_url)
|
account = VagrantPlugins::CloudCommand::Util.account(org, access_token, server_url)
|
||||||
box = VagrantCloud::Box.new(account, box_name, nil, nil, nil, access_token)
|
box = VagrantCloud::Box.new(account, box_name, nil, nil, nil, access_token)
|
||||||
cloud_version = VagrantCloud::Version.new(box, version, nil, nil, access_token)
|
cloud_version = VagrantCloud::Version.new(box, version, nil, nil, access_token)
|
||||||
provider = VagrantCloud::Provider.new(cloud_version, provider_name, nil, url, org, box_name, access_token)
|
provider = VagrantCloud::Provider.new(cloud_version, provider_name, nil, url, org, box_name,
|
||||||
|
access_token, nil, options[:checksum], options[:checksum_type])
|
||||||
|
|
||||||
begin
|
begin
|
||||||
success = provider.create_provider
|
success = provider.create_provider
|
||||||
@env.ui.success(I18n.t("cloud_command.provider.create_success", provider:provider_name, org: org, box_name: box_name, version: version))
|
@env.ui.success(I18n.t("cloud_command.provider.create_success", provider: provider_name, org: org, box_name: box_name, version: version))
|
||||||
success = success.delete_if{|_, v|v.nil?}
|
success = success.compact
|
||||||
VagrantPlugins::CloudCommand::Util.format_box_results(success, @env)
|
VagrantPlugins::CloudCommand::Util.format_box_results(success, @env)
|
||||||
return 0
|
return 0
|
||||||
rescue VagrantCloud::ClientError => e
|
rescue VagrantCloud::ClientError => e
|
||||||
@env.ui.error(I18n.t("cloud_command.errors.provider.create_fail", provider:provider_name, org: org, box_name: box_name, version: version))
|
@env.ui.error(I18n.t("cloud_command.errors.provider.create_fail", provider: provider_name, org: org, box_name: box_name, version: version))
|
||||||
@env.ui.error(e)
|
@env.ui.error(e)
|
||||||
return 1
|
return 1
|
||||||
end
|
end
|
||||||
|
|
|
@ -19,6 +19,12 @@ module VagrantPlugins
|
||||||
o.on("-u", "--username USERNAME_OR_EMAIL", String, "Vagrant Cloud username or email address") do |u|
|
o.on("-u", "--username USERNAME_OR_EMAIL", String, "Vagrant Cloud username or email address") do |u|
|
||||||
options[:username] = u
|
options[:username] = u
|
||||||
end
|
end
|
||||||
|
o.on("-c", "--checksum CHECKSUM_VALUE", String, "Checksum of the box for this provider. --checksum-type option is required.") do |c|
|
||||||
|
options[:checksum] = c
|
||||||
|
end
|
||||||
|
o.on("-C", "--checksum-type TYPE", String, "Type of checksum used (md5, sha1, sha256, sha384, sha512). --checksum option is required.") do |c|
|
||||||
|
options[:checksum_type] = c
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
# Parse the options
|
# Parse the options
|
||||||
|
@ -52,7 +58,8 @@ module VagrantPlugins
|
||||||
account = VagrantPlugins::CloudCommand::Util.account(org, access_token, server_url)
|
account = VagrantPlugins::CloudCommand::Util.account(org, access_token, server_url)
|
||||||
box = VagrantCloud::Box.new(account, box_name, nil, nil, nil, access_token)
|
box = VagrantCloud::Box.new(account, box_name, nil, nil, nil, access_token)
|
||||||
cloud_version = VagrantCloud::Version.new(box, version, nil, nil, access_token)
|
cloud_version = VagrantCloud::Version.new(box, version, nil, nil, access_token)
|
||||||
provider = VagrantCloud::Provider.new(cloud_version, provider_name, nil, url, org, box_name, access_token)
|
provider = VagrantCloud::Provider.new(cloud_version, provider_name, nil, url, org, box_name,
|
||||||
|
access_token, nil, options[:checksum], options[:checksum_type])
|
||||||
|
|
||||||
begin
|
begin
|
||||||
success = provider.update
|
success = provider.update
|
||||||
|
|
|
@ -43,6 +43,12 @@ module VagrantPlugins
|
||||||
o.on("-u", "--username USERNAME_OR_EMAIL", String, "Vagrant Cloud username or email address") do |u|
|
o.on("-u", "--username USERNAME_OR_EMAIL", String, "Vagrant Cloud username or email address") do |u|
|
||||||
options[:username] = u
|
options[:username] = u
|
||||||
end
|
end
|
||||||
|
o.on("-c", "--checksum CHECKSUM_VALUE", String, "Checksum of the box for this provider. --checksum-type option is required.") do |c|
|
||||||
|
options[:checksum] = c
|
||||||
|
end
|
||||||
|
o.on("-C", "--checksum-type TYPE", String, "Type of checksum used (md5, sha1, sha256, sha384, sha512). --checksum option is required.") do |c|
|
||||||
|
options[:checksum_type] = c
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
# Parse the options
|
# Parse the options
|
||||||
|
@ -97,7 +103,8 @@ module VagrantPlugins
|
||||||
account = VagrantPlugins::CloudCommand::Util.account(org, access_token, server_url)
|
account = VagrantPlugins::CloudCommand::Util.account(org, access_token, server_url)
|
||||||
box = VagrantCloud::Box.new(account, box_name, nil, options[:short_description], options[:description], access_token)
|
box = VagrantCloud::Box.new(account, box_name, nil, options[:short_description], options[:description], access_token)
|
||||||
cloud_version = VagrantCloud::Version.new(box, version, nil, options[:version_description], access_token)
|
cloud_version = VagrantCloud::Version.new(box, version, nil, options[:version_description], access_token)
|
||||||
provider = VagrantCloud::Provider.new(cloud_version, provider_name, nil, options[:url], org, box_name, access_token)
|
provider = VagrantCloud::Provider.new(cloud_version, provider_name, nil, options[:url], org, box_name,
|
||||||
|
access_token, nil, options[:checksum], options[:checksum_type])
|
||||||
|
|
||||||
ui = Vagrant::UI::Prefixed.new(@env.ui, "cloud")
|
ui = Vagrant::UI::Prefixed.new(@env.ui, "cloud")
|
||||||
|
|
||||||
|
|
|
@ -7,6 +7,9 @@ module VagrantPlugins
|
||||||
attr_accessor :path
|
attr_accessor :path
|
||||||
attr_accessor :md5
|
attr_accessor :md5
|
||||||
attr_accessor :sha1
|
attr_accessor :sha1
|
||||||
|
attr_accessor :sha256
|
||||||
|
attr_accessor :sha384
|
||||||
|
attr_accessor :sha512
|
||||||
attr_accessor :env
|
attr_accessor :env
|
||||||
attr_accessor :upload_path
|
attr_accessor :upload_path
|
||||||
attr_accessor :args
|
attr_accessor :args
|
||||||
|
@ -26,6 +29,9 @@ module VagrantPlugins
|
||||||
@path = UNSET_VALUE
|
@path = UNSET_VALUE
|
||||||
@md5 = UNSET_VALUE
|
@md5 = UNSET_VALUE
|
||||||
@sha1 = UNSET_VALUE
|
@sha1 = UNSET_VALUE
|
||||||
|
@sha256 = UNSET_VALUE
|
||||||
|
@sha384 = UNSET_VALUE
|
||||||
|
@sha512 = UNSET_VALUE
|
||||||
@env = UNSET_VALUE
|
@env = UNSET_VALUE
|
||||||
@upload_path = UNSET_VALUE
|
@upload_path = UNSET_VALUE
|
||||||
@privileged = UNSET_VALUE
|
@privileged = UNSET_VALUE
|
||||||
|
@ -45,6 +51,9 @@ module VagrantPlugins
|
||||||
@path = nil if @path == UNSET_VALUE
|
@path = nil if @path == UNSET_VALUE
|
||||||
@md5 = nil if @md5 == UNSET_VALUE
|
@md5 = nil if @md5 == UNSET_VALUE
|
||||||
@sha1 = nil if @sha1 == UNSET_VALUE
|
@sha1 = nil if @sha1 == UNSET_VALUE
|
||||||
|
@sha256 = nil if @sha256 == UNSET_VALUE
|
||||||
|
@sha384 = nil if @sha384 == UNSET_VALUE
|
||||||
|
@sha512 = nil if @sha512 == UNSET_VALUE
|
||||||
@env = {} if @env == UNSET_VALUE
|
@env = {} if @env == UNSET_VALUE
|
||||||
@upload_path = "/tmp/vagrant-shell" if @upload_path == UNSET_VALUE
|
@upload_path = "/tmp/vagrant-shell" if @upload_path == UNSET_VALUE
|
||||||
@privileged = true if @privileged == UNSET_VALUE
|
@privileged = true if @privileged == UNSET_VALUE
|
||||||
|
|
|
@ -253,7 +253,10 @@ module VagrantPlugins
|
||||||
config.path,
|
config.path,
|
||||||
download_path,
|
download_path,
|
||||||
md5: config.md5,
|
md5: config.md5,
|
||||||
sha1: config.sha1
|
sha1: config.sha1,
|
||||||
|
sha256: config.sha256,
|
||||||
|
sha384: config.sha384,
|
||||||
|
sha512: config.sha512
|
||||||
).download!
|
).download!
|
||||||
ext = File.extname(config.path)
|
ext = File.extname(config.path)
|
||||||
script = download_path.read
|
script = download_path.read
|
||||||
|
|
|
@ -48,7 +48,7 @@ describe VagrantPlugins::CloudCommand::ProviderCommand::Command::Create do
|
||||||
|
|
||||||
it "creates a provider" do
|
it "creates a provider" do
|
||||||
allow(VagrantCloud::Provider).to receive(:new).
|
allow(VagrantCloud::Provider).to receive(:new).
|
||||||
with(version, "virtualbox", nil, nil, "vagrant", "box-name", client.token).
|
with(version, "virtualbox", nil, nil, "vagrant", "box-name", client.token, nil, nil, nil).
|
||||||
and_return(provider)
|
and_return(provider)
|
||||||
|
|
||||||
expect(VagrantPlugins::CloudCommand::Util).to receive(:format_box_results)
|
expect(VagrantPlugins::CloudCommand::Util).to receive(:format_box_results)
|
||||||
|
@ -59,7 +59,7 @@ describe VagrantPlugins::CloudCommand::ProviderCommand::Command::Create do
|
||||||
|
|
||||||
it "displays an error if encoutering a problem with the request" do
|
it "displays an error if encoutering a problem with the request" do
|
||||||
allow(VagrantCloud::Provider).to receive(:new).
|
allow(VagrantCloud::Provider).to receive(:new).
|
||||||
with(version, "virtualbox", nil, nil, "vagrant", "box-name", client.token).
|
with(version, "virtualbox", nil, nil, "vagrant", "box-name", client.token, nil, nil, nil).
|
||||||
and_return(provider)
|
and_return(provider)
|
||||||
|
|
||||||
allow(provider).to receive(:create_provider).
|
allow(provider).to receive(:create_provider).
|
||||||
|
@ -73,7 +73,7 @@ describe VagrantPlugins::CloudCommand::ProviderCommand::Command::Create do
|
||||||
|
|
||||||
it "creates a provider" do
|
it "creates a provider" do
|
||||||
allow(VagrantCloud::Provider).to receive(:new).
|
allow(VagrantCloud::Provider).to receive(:new).
|
||||||
with(version, "virtualbox", nil, "https://box.com/box", "vagrant", "box-name", client.token).
|
with(version, "virtualbox", nil, "https://box.com/box", "vagrant", "box-name", client.token, nil, nil, nil).
|
||||||
and_return(provider)
|
and_return(provider)
|
||||||
|
|
||||||
expect(VagrantPlugins::CloudCommand::Util).to receive(:format_box_results)
|
expect(VagrantPlugins::CloudCommand::Util).to receive(:format_box_results)
|
||||||
|
|
|
@ -48,7 +48,7 @@ describe VagrantPlugins::CloudCommand::ProviderCommand::Command::Update do
|
||||||
|
|
||||||
it "updates a provider" do
|
it "updates a provider" do
|
||||||
allow(VagrantCloud::Provider).to receive(:new).
|
allow(VagrantCloud::Provider).to receive(:new).
|
||||||
with(version, "virtualbox", nil, nil, "vagrant", "box-name", client.token).
|
with(version, "virtualbox", nil, nil, "vagrant", "box-name", client.token, nil, nil, nil).
|
||||||
and_return(provider)
|
and_return(provider)
|
||||||
|
|
||||||
expect(VagrantPlugins::CloudCommand::Util).to receive(:format_box_results)
|
expect(VagrantPlugins::CloudCommand::Util).to receive(:format_box_results)
|
||||||
|
@ -59,7 +59,7 @@ describe VagrantPlugins::CloudCommand::ProviderCommand::Command::Update do
|
||||||
|
|
||||||
it "displays an error if encoutering a problem with the request" do
|
it "displays an error if encoutering a problem with the request" do
|
||||||
allow(VagrantCloud::Provider).to receive(:new).
|
allow(VagrantCloud::Provider).to receive(:new).
|
||||||
with(version, "virtualbox", nil, nil, "vagrant", "box-name", client.token).
|
with(version, "virtualbox", nil, nil, "vagrant", "box-name", client.token, nil, nil, nil).
|
||||||
and_return(provider)
|
and_return(provider)
|
||||||
|
|
||||||
allow(provider).to receive(:update).
|
allow(provider).to receive(:update).
|
||||||
|
@ -73,7 +73,7 @@ describe VagrantPlugins::CloudCommand::ProviderCommand::Command::Update do
|
||||||
|
|
||||||
it "creates a provider" do
|
it "creates a provider" do
|
||||||
allow(VagrantCloud::Provider).to receive(:new).
|
allow(VagrantCloud::Provider).to receive(:new).
|
||||||
with(version, "virtualbox", nil, "https://box.com/box", "vagrant", "box-name", client.token).
|
with(version, "virtualbox", nil, "https://box.com/box", "vagrant", "box-name", client.token, nil, nil, nil).
|
||||||
and_return(provider)
|
and_return(provider)
|
||||||
|
|
||||||
expect(VagrantPlugins::CloudCommand::Util).to receive(:format_box_results)
|
expect(VagrantPlugins::CloudCommand::Util).to receive(:format_box_results)
|
||||||
|
|
|
@ -175,8 +175,16 @@ describe "Vagrant::Shell::Provisioner" do
|
||||||
end
|
end
|
||||||
|
|
||||||
context "with remote script" do
|
context "with remote script" do
|
||||||
|
let(:filechecksum) { double("filechecksum", checksum: checksum_value) }
|
||||||
|
let(:checksum_value) { double("checksum_value") }
|
||||||
|
|
||||||
|
before do
|
||||||
|
allow(FileChecksum).to receive(:new).and_return(filechecksum)
|
||||||
|
allow_any_instance_of(Vagrant::Util::Downloader).to receive(:execute_curl).and_return(true)
|
||||||
|
end
|
||||||
|
|
||||||
context "that does not have matching sha1 checksum" do
|
context "that does not have matching sha1 checksum" do
|
||||||
|
let(:checksum_value) { "INVALID_VALUE" }
|
||||||
let(:config) {
|
let(:config) {
|
||||||
double(
|
double(
|
||||||
:config,
|
:config,
|
||||||
|
@ -188,18 +196,97 @@ describe "Vagrant::Shell::Provisioner" do
|
||||||
:binary => false,
|
:binary => false,
|
||||||
:md5 => nil,
|
:md5 => nil,
|
||||||
:sha1 => 'EXPECTED_VALUE',
|
:sha1 => 'EXPECTED_VALUE',
|
||||||
|
:sha256 => nil,
|
||||||
|
:sha384 => nil,
|
||||||
|
:sha512 => nil,
|
||||||
:reset => false,
|
:reset => false,
|
||||||
:reboot => false
|
:reboot => false
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
let(:digest){ double("digest") }
|
it "should raise an exception" do
|
||||||
before do
|
vsp = VagrantPlugins::Shell::Provisioner.new(machine, config)
|
||||||
allow_any_instance_of(Vagrant::Util::Downloader).to receive(:execute_curl).and_return(true)
|
|
||||||
allow(digest).to receive(:file).and_return(digest)
|
expect{ vsp.provision }.to raise_error(Vagrant::Errors::DownloaderChecksumError)
|
||||||
expect(Digest::SHA1).to receive(:new).and_return(digest)
|
|
||||||
expect(digest).to receive(:hexdigest).and_return('INVALID_VALUE')
|
|
||||||
end
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
context "that does not have matching sha256 checksum" do
|
||||||
|
let(:checksum_value) { "INVALID_VALUE" }
|
||||||
|
let(:config) {
|
||||||
|
double(
|
||||||
|
:config,
|
||||||
|
:args => "doesn't matter",
|
||||||
|
:env => {},
|
||||||
|
:upload_path => "arbitrary",
|
||||||
|
:remote? => true,
|
||||||
|
:path => "http://example.com/script.sh",
|
||||||
|
:binary => false,
|
||||||
|
:md5 => nil,
|
||||||
|
:sha1 => nil,
|
||||||
|
:sha256 => 'EXPECTED_VALUE',
|
||||||
|
:sha384 => nil,
|
||||||
|
:sha512 => nil,
|
||||||
|
:reset => false,
|
||||||
|
:reboot => false
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
it "should raise an exception" do
|
||||||
|
vsp = VagrantPlugins::Shell::Provisioner.new(machine, config)
|
||||||
|
|
||||||
|
expect{ vsp.provision }.to raise_error(Vagrant::Errors::DownloaderChecksumError)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
context "that does not have matching sha384 checksum" do
|
||||||
|
let(:checksum_value) { "INVALID_VALUE" }
|
||||||
|
let(:config) {
|
||||||
|
double(
|
||||||
|
:config,
|
||||||
|
:args => "doesn't matter",
|
||||||
|
:env => {},
|
||||||
|
:upload_path => "arbitrary",
|
||||||
|
:remote? => true,
|
||||||
|
:path => "http://example.com/script.sh",
|
||||||
|
:binary => false,
|
||||||
|
:md5 => nil,
|
||||||
|
:sha1 => nil,
|
||||||
|
:sha256 => nil,
|
||||||
|
:sha384 => 'EXPECTED_VALUE',
|
||||||
|
:sha512 => nil,
|
||||||
|
:reset => false,
|
||||||
|
:reboot => false
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
it "should raise an exception" do
|
||||||
|
vsp = VagrantPlugins::Shell::Provisioner.new(machine, config)
|
||||||
|
|
||||||
|
expect{ vsp.provision }.to raise_error(Vagrant::Errors::DownloaderChecksumError)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
context "that does not have matching sha512 checksum" do
|
||||||
|
let(:checksum_value) { "INVALID_VALUE" }
|
||||||
|
let(:config) {
|
||||||
|
double(
|
||||||
|
:config,
|
||||||
|
:args => "doesn't matter",
|
||||||
|
:env => {},
|
||||||
|
:upload_path => "arbitrary",
|
||||||
|
:remote? => true,
|
||||||
|
:path => "http://example.com/script.sh",
|
||||||
|
:binary => false,
|
||||||
|
:md5 => nil,
|
||||||
|
:sha1 => nil,
|
||||||
|
:sha256 => nil,
|
||||||
|
:sha384 => nil,
|
||||||
|
:sha512 => 'EXPECTED_VALUE',
|
||||||
|
:reset => false,
|
||||||
|
:reboot => false
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
it "should raise an exception" do
|
it "should raise an exception" do
|
||||||
vsp = VagrantPlugins::Shell::Provisioner.new(machine, config)
|
vsp = VagrantPlugins::Shell::Provisioner.new(machine, config)
|
||||||
|
@ -209,6 +296,7 @@ describe "Vagrant::Shell::Provisioner" do
|
||||||
end
|
end
|
||||||
|
|
||||||
context "that does not have matching md5 checksum" do
|
context "that does not have matching md5 checksum" do
|
||||||
|
let(:checksum_value) { "INVALID_VALUE" }
|
||||||
let(:config) {
|
let(:config) {
|
||||||
double(
|
double(
|
||||||
:config,
|
:config,
|
||||||
|
@ -220,19 +308,14 @@ describe "Vagrant::Shell::Provisioner" do
|
||||||
:binary => false,
|
:binary => false,
|
||||||
:md5 => 'EXPECTED_VALUE',
|
:md5 => 'EXPECTED_VALUE',
|
||||||
:sha1 => nil,
|
:sha1 => nil,
|
||||||
|
:sha256 => nil,
|
||||||
|
:sha384 => nil,
|
||||||
|
:sha512 => nil,
|
||||||
:reset => false,
|
:reset => false,
|
||||||
:reboot => false
|
:reboot => false
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
let(:digest){ double("digest") }
|
|
||||||
before do
|
|
||||||
allow_any_instance_of(Vagrant::Util::Downloader).to receive(:execute_curl).and_return(true)
|
|
||||||
allow(digest).to receive(:file).and_return(digest)
|
|
||||||
expect(Digest::MD5).to receive(:new).and_return(digest)
|
|
||||||
expect(digest).to receive(:hexdigest).and_return('INVALID_VALUE')
|
|
||||||
end
|
|
||||||
|
|
||||||
it "should raise an exception" do
|
it "should raise an exception" do
|
||||||
vsp = VagrantPlugins::Shell::Provisioner.new(machine, config)
|
vsp = VagrantPlugins::Shell::Provisioner.new(machine, config)
|
||||||
|
|
||||||
|
|
|
@ -175,23 +175,19 @@ describe Vagrant::Util::Downloader do
|
||||||
context "with checksum" do
|
context "with checksum" do
|
||||||
let(:checksum_expected_value){ 'MD5_CHECKSUM_VALUE' }
|
let(:checksum_expected_value){ 'MD5_CHECKSUM_VALUE' }
|
||||||
let(:checksum_invalid_value){ 'INVALID_VALUE' }
|
let(:checksum_invalid_value){ 'INVALID_VALUE' }
|
||||||
let(:digest){ double("digest") }
|
let(:filechecksum) { double("filechecksum", checksum: checksum_value) }
|
||||||
|
let(:checksum_value) { double("checksum_value") }
|
||||||
|
|
||||||
before do
|
before { allow(FileChecksum).to receive(:new).with(any_args).and_return(filechecksum) }
|
||||||
allow(digest).to receive(:file).and_return(digest)
|
|
||||||
end
|
|
||||||
|
|
||||||
[Digest::MD5, Digest::SHA1].each do |klass|
|
[Digest::MD5, Digest::SHA1, Digest::SHA256, Digest::SHA384, Digest::SHA512].each do |klass|
|
||||||
short_name = klass.to_s.split("::").last.downcase
|
short_name = klass.to_s.split("::").last.downcase
|
||||||
|
|
||||||
context "using #{short_name} digest" do
|
context "using #{short_name} digest" do
|
||||||
subject { described_class.new(source, destination, short_name.to_sym => checksum_expected_value) }
|
subject { described_class.new(source, destination, short_name.to_sym => checksum_expected_value) }
|
||||||
|
|
||||||
context "that matches expected value" do
|
context "that matches expected value" do
|
||||||
before do
|
let(:checksum_value) { checksum_expected_value }
|
||||||
expect(klass).to receive(:new).and_return(digest)
|
|
||||||
expect(digest).to receive(:hexdigest).and_return(checksum_expected_value)
|
|
||||||
end
|
|
||||||
|
|
||||||
it "should not raise an exception" do
|
it "should not raise an exception" do
|
||||||
expect(subject.download!).to be(true)
|
expect(subject.download!).to be(true)
|
||||||
|
@ -199,10 +195,7 @@ describe Vagrant::Util::Downloader do
|
||||||
end
|
end
|
||||||
|
|
||||||
context "that does not match expected value" do
|
context "that does not match expected value" do
|
||||||
before do
|
let(:checksum_value) { checksum_invalid_value }
|
||||||
expect(klass).to receive(:new).and_return(digest)
|
|
||||||
expect(digest).to receive(:hexdigest).and_return(checksum_invalid_value)
|
|
||||||
end
|
|
||||||
|
|
||||||
it "should raise an exception" do
|
it "should raise an exception" do
|
||||||
expect{ subject.download! }.to raise_error(Vagrant::Errors::DownloaderChecksumError)
|
expect{ subject.download! }.to raise_error(Vagrant::Errors::DownloaderChecksumError)
|
||||||
|
@ -213,13 +206,9 @@ describe Vagrant::Util::Downloader do
|
||||||
|
|
||||||
context "using both md5 and sha1 digests" do
|
context "using both md5 and sha1 digests" do
|
||||||
context "that both match expected values" do
|
context "that both match expected values" do
|
||||||
subject { described_class.new(source, destination, md5: checksum_expected_value, sha1: checksum_expected_value) }
|
let(:checksum_value) { checksum_expected_value }
|
||||||
|
|
||||||
before do
|
subject { described_class.new(source, destination, md5: checksum_expected_value, sha1: checksum_expected_value) }
|
||||||
expect(Digest::MD5).to receive(:new).and_return(digest)
|
|
||||||
expect(Digest::SHA1).to receive(:new).and_return(digest)
|
|
||||||
expect(digest).to receive(:hexdigest).and_return(checksum_expected_value).exactly(2).times
|
|
||||||
end
|
|
||||||
|
|
||||||
it "should not raise an exception" do
|
it "should not raise an exception" do
|
||||||
expect(subject.download!).to be(true)
|
expect(subject.download!).to be(true)
|
||||||
|
@ -227,12 +216,14 @@ describe Vagrant::Util::Downloader do
|
||||||
end
|
end
|
||||||
|
|
||||||
context "that only sha1 matches expected value" do
|
context "that only sha1 matches expected value" do
|
||||||
subject { described_class.new(source, destination, md5: checksum_invalid_value, sha1: checksum_expected_value) }
|
subject { described_class.new(source, destination, md5: checksum_expected_value, sha1: checksum_expected_value) }
|
||||||
|
|
||||||
|
let(:valid_checksum) { double("valid_checksum", checksum: checksum_expected_value) }
|
||||||
|
let(:invalid_checksum) { double("invalid_checksum", checksum: checksum_invalid_value) }
|
||||||
|
|
||||||
before do
|
before do
|
||||||
allow(Digest::MD5).to receive(:new).and_return(digest)
|
allow(FileChecksum).to receive(:new).with(anything, :sha1).and_return(valid_checksum)
|
||||||
allow(Digest::SHA1).to receive(:new).and_return(digest)
|
allow(FileChecksum).to receive(:new).with(anything, :md5).and_return(invalid_checksum)
|
||||||
expect(digest).to receive(:hexdigest).and_return(checksum_expected_value).at_least(:once)
|
|
||||||
end
|
end
|
||||||
|
|
||||||
it "should raise an exception" do
|
it "should raise an exception" do
|
||||||
|
@ -241,12 +232,14 @@ describe Vagrant::Util::Downloader do
|
||||||
end
|
end
|
||||||
|
|
||||||
context "that only md5 matches expected value" do
|
context "that only md5 matches expected value" do
|
||||||
subject { described_class.new(source, destination, md5: checksum_expected_value, sha1: checksum_invalid_value) }
|
subject { described_class.new(source, destination, md5: checksum_expected_value, sha1: checksum_expected_value) }
|
||||||
|
|
||||||
|
let(:valid_checksum) { double("valid_checksum", checksum: checksum_expected_value) }
|
||||||
|
let(:invalid_checksum) { double("invalid_checksum", checksum: checksum_invalid_value) }
|
||||||
|
|
||||||
before do
|
before do
|
||||||
allow(Digest::MD5).to receive(:new).and_return(digest)
|
allow(FileChecksum).to receive(:new).with(anything, :md5).and_return(valid_checksum)
|
||||||
allow(Digest::SHA1).to receive(:new).and_return(digest)
|
allow(FileChecksum).to receive(:new).with(anything, :sha1).and_return(invalid_checksum)
|
||||||
expect(digest).to receive(:hexdigest).and_return(checksum_expected_value).at_least(:once)
|
|
||||||
end
|
end
|
||||||
|
|
||||||
it "should raise an exception" do
|
it "should raise an exception" do
|
||||||
|
@ -255,14 +248,9 @@ describe Vagrant::Util::Downloader do
|
||||||
end
|
end
|
||||||
|
|
||||||
context "that none match expected value" do
|
context "that none match expected value" do
|
||||||
|
let(:checksum_value) { checksum_expected_value }
|
||||||
subject { described_class.new(source, destination, md5: checksum_invalid_value, sha1: checksum_invalid_value) }
|
subject { described_class.new(source, destination, md5: checksum_invalid_value, sha1: checksum_invalid_value) }
|
||||||
|
|
||||||
before do
|
|
||||||
allow(Digest::MD5).to receive(:new).and_return(digest)
|
|
||||||
allow(Digest::SHA1).to receive(:new).and_return(digest)
|
|
||||||
expect(digest).to receive(:hexdigest).and_return(checksum_expected_value).at_least(:once)
|
|
||||||
end
|
|
||||||
|
|
||||||
it "should raise an exception" do
|
it "should raise an exception" do
|
||||||
expect{ subject.download! }.to raise_error(Vagrant::Errors::DownloaderChecksumError)
|
expect{ subject.download! }.to raise_error(Vagrant::Errors::DownloaderChecksumError)
|
||||||
end
|
end
|
||||||
|
|
|
@ -20,4 +20,16 @@ describe FileChecksum do
|
||||||
instance = described_class.new(file, Digest::SHA1)
|
instance = described_class.new(file, Digest::SHA1)
|
||||||
expect(instance.checksum).to eq("264b207c7913e461c43d0f63d2512f4017af4755")
|
expect(instance.checksum).to eq("264b207c7913e461c43d0f63d2512f4017af4755")
|
||||||
end
|
end
|
||||||
|
|
||||||
|
it "should support initialize with class or string" do
|
||||||
|
file = environment.workdir.join("file")
|
||||||
|
file.open("w+") { |f| f.write("HELLO!") }
|
||||||
|
|
||||||
|
%w(md5 sha1 sha256 sha384 sha512).each do |type|
|
||||||
|
klass = Digest.const_get(type.upcase)
|
||||||
|
t_i = described_class.new(file, type)
|
||||||
|
k_i = described_class.new(file, klass)
|
||||||
|
expect(t_i.checksum).to eq(k_i.checksum)
|
||||||
|
end
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -34,7 +34,7 @@ Gem::Specification.new do |s|
|
||||||
s.add_dependency "winrm", "~> 2.1"
|
s.add_dependency "winrm", "~> 2.1"
|
||||||
s.add_dependency "winrm-fs", "~> 1.0"
|
s.add_dependency "winrm-fs", "~> 1.0"
|
||||||
s.add_dependency "winrm-elevated", "~> 1.1"
|
s.add_dependency "winrm-elevated", "~> 1.1"
|
||||||
s.add_dependency "vagrant_cloud", "~> 2.0.2"
|
s.add_dependency "vagrant_cloud", "~> 2.0.3"
|
||||||
|
|
||||||
# NOTE: The ruby_dep gem is an implicit dependency from the listen gem. Later versions
|
# NOTE: The ruby_dep gem is an implicit dependency from the listen gem. Later versions
|
||||||
# of the ruby_dep gem impose an aggressive constraint on the required ruby version (>= 2.2.5).
|
# of the ruby_dep gem impose an aggressive constraint on the required ruby version (>= 2.2.5).
|
||||||
|
|
|
@ -91,7 +91,8 @@ you are not using a catalog).
|
||||||
included within the catalog entry.
|
included within the catalog entry.
|
||||||
|
|
||||||
* `--checksum-type TYPE` - The type of checksum that `--checksum` is if it
|
* `--checksum-type TYPE` - The type of checksum that `--checksum` is if it
|
||||||
is specified. Supported values are currently "md5", "sha1", and "sha256".
|
is specified. Supported values are currently "md5", "sha1", "sha256",
|
||||||
|
"sha384", and "sha512".
|
||||||
|
|
||||||
* `--name VALUE` - Logical name for the box. This is the value that you
|
* `--name VALUE` - Logical name for the box. This is the value that you
|
||||||
would put into `config.vm.box` in your Vagrantfile. When adding a box from
|
would put into `config.vm.box` in your Vagrantfile. When adding a box from
|
||||||
|
|
|
@ -83,6 +83,12 @@ The remainder of the available options are optional:
|
||||||
|
|
||||||
* `sha1` (string) - SHA1 checksum used to validate remotely downloaded shell files.
|
* `sha1` (string) - SHA1 checksum used to validate remotely downloaded shell files.
|
||||||
|
|
||||||
|
* `sha256` (string) - SHA256 checksum used to validate remotely downloaded shell files.
|
||||||
|
|
||||||
|
* `sha384` (string) - SHA384 checksum used to validate remotely downloaded shell files.
|
||||||
|
|
||||||
|
* `sha512` (string) - SHA512 checksum used to validate remotely downloaded shell files.
|
||||||
|
|
||||||
* `sensitive` (boolean) - Marks the Hash values used in the `env` option as sensitive
|
* `sensitive` (boolean) - Marks the Hash values used in the `env` option as sensitive
|
||||||
and hides them from output. By default this is "false".
|
and hides them from output. By default this is "false".
|
||||||
|
|
||||||
|
|
|
@ -46,7 +46,7 @@ when Vagrant must download the box. If this is specified, then
|
||||||
|
|
||||||
* `config.vm.box_download_checksum_type` (string) - The type of checksum specified
|
* `config.vm.box_download_checksum_type` (string) - The type of checksum specified
|
||||||
by `config.vm.box_download_checksum` (if any). Supported values are
|
by `config.vm.box_download_checksum` (if any). Supported values are
|
||||||
currently "md5", "sha1", and "sha256".
|
currently "md5", "sha1", "sha256", "sha384", and "sha512".
|
||||||
|
|
||||||
* `config.vm.box_download_client_cert` (string) - Path to a client certificate to
|
* `config.vm.box_download_client_cert` (string) - Path to a client certificate to
|
||||||
use when downloading the box, if it is necessary. By default, no client
|
use when downloading the box, if it is necessary. By default, no client
|
||||||
|
|
Loading…
Reference in New Issue