diff options
-rw-r--r-- | lib/chef/provider/package/cab.rb | 42 | ||||
-rw-r--r-- | spec/unit/provider/package/cab_spec.rb | 64 |
2 files changed, 95 insertions, 11 deletions
diff --git a/lib/chef/provider/package/cab.rb b/lib/chef/provider/package/cab.rb index 8e1709f618..a281100f8b 100644 --- a/lib/chef/provider/package/cab.rb +++ b/lib/chef/provider/package/cab.rb @@ -19,29 +19,59 @@ require "chef/provider/package" require "chef/resource/cab_package" require "chef/mixin/shell_out" +require "chef/mixin/uris" +require "chef/mixin/checksum" class Chef class Provider class Package class Cab < Chef::Provider::Package + use_inline_resources include Chef::Mixin::ShellOut + include Chef::Mixin::Uris + include Chef::Mixin::Checksum provides :cab_package, os: "windows" def load_current_resource @current_resource = Chef::Resource::CabPackage.new(new_resource.name) - current_resource.source(new_resource.source) + current_resource.source(cab_file_source) new_resource.version(package_version) current_resource.version(installed_version) current_resource end + def cab_file_source + @cab_file_source ||= uri_scheme?(new_resource.source) ? download_source_file : new_resource.source + end + + def download_source_file + source_resource.run_action(:create) + Chef::Log.debug("#{new_resource} fetched source file to #{source_resource.path}") + source_resource.path + end + + def source_resource + @source_resource ||= declare_resource(:remote_file, new_resource.name) do + path default_download_cache_path + source new_resource.source + backup false + end + end + + def default_download_cache_path + uri = ::URI.parse(new_resource.source) + filename = ::File.basename(::URI.unescape(uri.path)) + file_cache_dir = Chef::FileCache.create_cache_path("package/") + Chef::Util::PathHelper.cleanpath("#{file_cache_dir}/#{filename}") + end + def install_package(name, version) - dism_command("/Add-Package /PackagePath:\"#{@new_resource.source}\"") + dism_command("/Add-Package /PackagePath:\"#{cab_file_source}\"") end def remove_package(name, version) - dism_command("/Remove-Package /PackagePath:\"#{@new_resource.source}\"") + dism_command("/Remove-Package /PackagePath:\"#{cab_file_source}\"") end def dism_command(command) @@ -52,7 +82,7 @@ class Chef end def installed_version - stdout = dism_command("/Get-PackageInfo /PackagePath:\"#{@new_resource.source}\"").stdout + stdout = dism_command("/Get-PackageInfo /PackagePath:\"#{cab_file_source}\"").stdout package_info = parse_dism_get_package_info(stdout) # e.g. Package_for_KB2975719~31bf3856ad364e35~amd64~~6.3.1.8 package = split_package_identity(package_info["package_information"]["package_identity"]) @@ -71,8 +101,8 @@ class Chef end def package_version - Chef::Log.debug("#{@new_resource} getting product version for package at #{@new_resource.source}") - stdout = dism_command("/Get-PackageInfo /PackagePath:\"#{@new_resource.source}\"").stdout + Chef::Log.debug("#{@new_resource} getting product version for package at #{cab_file_source}") + stdout = dism_command("/Get-PackageInfo /PackagePath:\"#{cab_file_source}\"").stdout find_version(stdout) end diff --git a/spec/unit/provider/package/cab_spec.rb b/spec/unit/provider/package/cab_spec.rb index 5e16795aa8..5c86f781f3 100644 --- a/spec/unit/provider/package/cab_spec.rb +++ b/spec/unit/provider/package/cab_spec.rb @@ -49,7 +49,7 @@ The operation completed successfully end before do - new_resource.source = "C:\\Temp\\Test6.1-KB2664825-v3-x64.cab" + new_resource.source = File.join("#{ENV['TEMP']}", "test6.1-kb2664825-v3-x64.cab") installed_package_list_obj = double(stdout: installed_package_list_stdout) allow(provider).to receive(:dism_command).with("/Get-Packages").and_return(installed_package_list_obj) package_version_obj = double(stdout: package_version_stdout) @@ -126,6 +126,63 @@ The operation completed successfully. end end + describe "#source_resource" do + before do + new_resource.source = "https://www.something.com/Test6.1-KB2664825-v3-x64.cab" + new_resource.cookbook_name = "cab_package" + end + + it "sets the desired parameters of downloades cab file" do + allow(provider).to receive(:default_download_cache_path).and_return("C:\\chef\\cache\\package") + source_resource = provider.source_resource + expect(source_resource.path).to be == "C:\\chef\\cache\\package" + expect(source_resource.name).to be == "windows_test_pkg" + expect(source_resource.source).to be == [new_resource.source] + expect(source_resource.cookbook_name).to be == "cab_package" + end + end + + describe "#default_download_cache_path" do + before do + new_resource.source = "https://www.something.com/Test6.1-KB2664825-v3-x64.cab" + end + + it "returns a clean cache path where the cab file is downloaded" do + allow(Chef::FileCache).to receive(:create_cache_path).and_return(ENV["TEMP"]) + path = provider.default_download_cache_path + if windows? + expect(path).to be == File.join("#{ENV['TEMP']}", "\\", "Test6.1-KB2664825-v3-x64.cab") + else + expect(path).to be == File.join("#{ENV['TEMP']}", "Test6.1-KB2664825-v3-x64.cab") + end + end + end + + describe "#cab_file_source" do + context "when local file path is set" do + it "returns local cab file source path" do + new_resource.source = File.join("#{ENV['TEMP']}", "test6.1-kb2664825-v3-x64.cab") + path = provider.cab_file_source + if windows? + expect(path).to be == File.join("#{ENV['TEMP'].downcase}", "\\", "test6.1-kb2664825-v3-x64.cab") + else + expect(path).to be == File.join("#{ENV['TEMP']}", "test6.1-kb2664825-v3-x64.cab") + end + end + end + context "when url is set" do + it "calls download_source_file method" do + new_resource.source = "https://www.something.com/test6.1-kb2664825-v3-x64.cab" + if windows? + expect(provider).to receive(:download_source_file).and_return(File.join("#{ENV['TEMP'].downcase}", "\\", "test6.1-kb2664825-v3-x64.cab")) + else + expect(provider).to receive(:download_source_file).and_return(File.join("#{ENV['TEMP']}", "test6.1-kb2664825-v3-x64.cab")) + end + provider.cab_file_source + end + end + end + describe "#initialize" do it "returns the correct class" do expect(provider).to be_kind_of(Chef::Provider::Package::Cab) @@ -192,12 +249,9 @@ The operation completed successfully. context "Invalid package source" do def package_version_stdout package_version_stdout = <<-EOF - Deployment Image Servicing and Management tool Version: 6.1.7600.16385 - Image Version: 6.1.7600.16385 - An error occurred trying to open - c:\\temp\\test6.1-KB2664825-v3-x64.cab Error: 0x80070003 Error: 3 The system cannot find the path specified. @@ -206,7 +260,7 @@ The DISM log file can be found at C:\\Windows\\Logs\\DISM\\dism.log. end before do - new_resource.source = "C:\\Temp\\Test6.1-KB2664825-v3-x64.cab" + new_resource.source = "#{ENV['TEMP']}/test6.1-kb2664825-v3-x64.cab" installed_package_list_obj = double(stdout: installed_package_list_stdout) allow(provider).to receive(:dism_command).with("/Get-Packages").and_return(installed_package_list_obj) end |