Class: Chef::Provider::Package::Cab
- Inherits:
-
Chef::Provider::Package
- Object
- Chef::Provider
- Chef::Provider::Package
- Chef::Provider::Package::Cab
- Includes:
- Mixin::ShellOut
- Defined in:
- lib/chef/provider/package/cab.rb
Constant Summary
Constants included from Mixin::ShellOut
Mixin::ShellOut::DEPRECATED_OPTIONS
Instance Attribute Summary
Attributes inherited from Chef::Provider::Package
Attributes inherited from Chef::Provider
#action, #cookbook_name, #current_resource, #new_resource, #recipe_name, #run_context
Instance Method Summary collapse
- #dism_command(command) ⇒ Object
- #find_version(stdout) ⇒ Object
- #install_package(name, version) ⇒ Object
- #installed_packages ⇒ Object
- #installed_version ⇒ Object
- #load_current_resource ⇒ Object
- #package_version ⇒ Object
-
#parse_dism_get_package_info(text) ⇒ Object
returns a hash of package information given the output of dism /get-packageinfo.
-
#parse_dism_get_packages(text) ⇒ Object
returns a hash of package state information given the output of dism /get-packages expected keys: package_identity.
- #remove_package(name, version) ⇒ Object
- #split_package_identity(identity) ⇒ Object
Methods included from Mixin::ShellOut
#a_to_s, #clean_array, #run_command_compatible_options, #shell_out, #shell_out!, #shell_out_compact, #shell_out_compact!, #shell_out_with_systems_locale, #shell_out_with_systems_locale!
Methods inherited from Chef::Provider::Package
#action_lock, #action_unlock, #as_array, #check_resource_semantics!, #define_resource_requirements, #expand_options, #get_preseed_file, #have_any_matching_version?, #initialize, #lock_package, #multipackage_api_adapter, #preseed_package, #preseed_resource, #purge_package, #reconfig_package, #removing_package?, #target_version_already_installed?, #unlock_package, #upgrade_package, #version_requirement_satisfied?, #whyrun_supported?
Methods included from Mixin::SubclassDirective
Methods included from Mixin::Command
#chdir_or_tmpdir, #handle_command_failures, #output_of_command, #run_command, #run_command_and_return_stdout_stderr, #run_command_with_systems_locale
Methods included from Mixin::Command::Windows
Methods included from Mixin::Command::Unix
Methods inherited from Chef::Provider
#action_nothing, #check_resource_semantics!, #cleanup_after_converge, #converge_by, #converge_if_changed, #define_resource_requirements, #events, include_resource_dsl, include_resource_dsl_module, #initialize, #node, #process_resource_requirements, provides, provides?, #requirements, #resource_collection, #resource_updated?, #run_action, #set_updated_status, supports?, use_inline_resources, #whyrun_mode?, #whyrun_supported?
Methods included from Mixin::Provides
#provided_as, #provides, #provides?
Methods included from Mixin::DescendantsTracker
#descendants, descendants, direct_descendants, #direct_descendants, find_descendants_by_name, #find_descendants_by_name, #inherited, store_inherited
Methods included from DeprecatedLWRPClass
#const_missing, #deprecated_constants, #register_deprecated_lwrp_class
Methods included from Mixin::LazyModuleInclude
#descendants, #include, #included
Methods included from Mixin::NotifyingBlock
#notifying_block, #subcontext_block
Methods included from DSL::DeclareResource
#build_resource, #declare_resource, #delete_resource, #delete_resource!, #edit_resource, #edit_resource!, #find_resource, #find_resource!, #with_run_context
Methods included from Mixin::PowershellOut
#powershell_out, #powershell_out!
Methods included from Mixin::WindowsArchitectureHelper
#assert_valid_windows_architecture!, #disable_wow64_file_redirection, #forced_32bit_override_required?, #is_i386_process_on_x86_64_windows?, #node_supports_windows_architecture?, #node_windows_architecture, #restore_wow64_file_redirection, #valid_windows_architecture?, #with_os_architecture, #wow64_architecture_override_required?, #wow64_directory
Methods included from DSL::PlatformIntrospection
#docker?, #platform?, #platform_family?, #value_for_platform, #value_for_platform_family
Constructor Details
This class inherits a constructor from Chef::Provider::Package
Instance Method Details
#dism_command(command) ⇒ Object
47 48 49 50 51 52 |
# File 'lib/chef/provider/package/cab.rb', line 47 def dism_command(command) shellout = Mixlib::ShellOut.new("dism.exe /Online /English #{command} /NoRestart", { :timeout => @new_resource.timeout }) with_os_architecture(nil) do shellout.run_command end end |
#find_version(stdout) ⇒ Object
79 80 81 82 83 |
# File 'lib/chef/provider/package/cab.rb', line 79 def find_version(stdout) package_info = parse_dism_get_package_info(stdout) package = split_package_identity(package_info["package_information"]["package_identity"]) package["version"] end |
#install_package(name, version) ⇒ Object
39 40 41 |
# File 'lib/chef/provider/package/cab.rb', line 39 def install_package(name, version) dism_command("/Add-Package /PackagePath:\"#{@new_resource.source}\"") end |
#installed_packages ⇒ Object
140 141 142 143 144 145 146 |
# File 'lib/chef/provider/package/cab.rb', line 140 def installed_packages @packages ||= begin output = dism_command("/Get-Packages").stdout packages = parse_dism_get_packages(output) packages end end |
#installed_version ⇒ Object
54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 |
# File 'lib/chef/provider/package/cab.rb', line 54 def installed_version stdout = dism_command("/Get-PackageInfo /PackagePath:\"#{@new_resource.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"]) # Search for just the package name to catch a different version being installed Chef::Log.debug("#{@new_resource} searching for installed package #{package['name']}") found_packages = installed_packages.select { |p| p["package_identity"] =~ /^#{package['name']}~/ } if found_packages.length == 0 nil elsif found_packages.length == 1 stdout = dism_command("/Get-PackageInfo /PackageName:\"#{found_packages.first["package_identity"]}\"").stdout find_version(stdout) else # Presuming this won't happen, otherwise we need to handle it raise Chef::Exceptions::Package, "Found multiple packages installed matching name #{package['name']}, found: #{found_packages.length} matches" end end |
#load_current_resource ⇒ Object
31 32 33 34 35 36 37 |
# File 'lib/chef/provider/package/cab.rb', line 31 def load_current_resource @current_resource = Chef::Resource::CabPackage.new(new_resource.name) current_resource.source(new_resource.source) new_resource.version(package_version) current_resource.version(installed_version) current_resource end |
#package_version ⇒ Object
73 74 75 76 77 |
# File 'lib/chef/provider/package/cab.rb', line 73 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 find_version(stdout) end |
#parse_dism_get_package_info(text) ⇒ Object
returns a hash of package information given the output of dism /get-packageinfo
101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 |
# File 'lib/chef/provider/package/cab.rb', line 101 def parse_dism_get_package_info(text) package_data = Hash.new errors = Array.new in_section = false section_headers = [ "Package information", "Custom Properties", "Features" ] text.each_line do |line| if line =~ /Error: (.*)/ errors << $1.strip elsif section_headers.any? { |header| line =~ /^(#{header})/ } in_section = $1.downcase.tr(" ", "_") elsif line =~ /(.*) ?: (.*)/ v = $2 # has to be first or the gsub below replaces this variable k = $1.downcase.strip.tr(" ", "_") if in_section package_data[in_section] = Hash.new unless package_data[in_section] package_data[in_section][k] = v else package_data[k] = v end end end unless errors.empty? if errors.include?("0x80070003") || errors.include?("0x80070002") raise Chef::Exceptions::Package, "DISM: The system cannot find the path or file specified." elsif errors.include?("740") raise Chef::Exceptions::Package, "DISM: Error 740: Elevated permissions are required to run DISM." else raise Chef::Exceptions::Package, "Unknown errors encountered parsing DISM output: #{errors}" end end package_data end |
#parse_dism_get_packages(text) ⇒ Object
returns a hash of package state information given the output of dism /get-packages expected keys: package_identity
87 88 89 90 91 92 93 94 95 96 97 98 |
# File 'lib/chef/provider/package/cab.rb', line 87 def parse_dism_get_packages(text) packages = Array.new text.each_line do |line| key, value = line.split(":") if line.start_with?("Package Identity") unless key.nil? || value.nil? package = Hash.new package[key.downcase.strip.tr(" ", "_")] = value.strip.chomp packages << package end end packages end |
#remove_package(name, version) ⇒ Object
43 44 45 |
# File 'lib/chef/provider/package/cab.rb', line 43 def remove_package(name, version) dism_command("/Remove-Package /PackagePath:\"#{@new_resource.source}\"") end |
#split_package_identity(identity) ⇒ Object
134 135 136 137 138 |
# File 'lib/chef/provider/package/cab.rb', line 134 def split_package_identity(identity) data = Hash.new data["name"], data["publisher"], data["arch"], data["resource_id"], data["version"] = identity.split("~") data end |