Class: Chef::Provider::Package::Chocolatey
- Inherits:
-
Chef::Provider::Package
- Object
- Chef::Provider
- Chef::Provider::Package
- Chef::Provider::Package::Chocolatey
- Defined in:
- lib/chef/provider/package/chocolatey.rb
Constant Summary collapse
- PATHFINDING_POWERSHELL_COMMAND =
"[System.Environment]::GetEnvironmentVariable('ChocolateyInstall', 'MACHINE')".freeze
- CHOCO_MISSING_MSG =
<<~EOS.freeze Could not locate your Chocolatey install. To install chocolatey, we recommend the 'chocolatey_installer' resource. If Chocolatey is installed, ensure that the 'ChocolateyInstall' environment variable is correctly set. You can verify this with the PowerShell command '#{PATHFINDING_POWERSHELL_COMMAND}'. EOS
- @@choco_available_packages =
initialize our cache on load
nil
- @@choco_config =
nil
Instance Attribute Summary
Attributes inherited from Chef::Provider
#action, #after_resource, #current_resource, #logger, #new_resource, #run_context
Instance Method Summary collapse
-
#cache_is_valid? ⇒ Boolean
This checks that the repo list has not changed between now and when we last checked the cache.
-
#candidate_version ⇒ Array
Lazy initializer for candidate_version.
-
#check_resource_semantics! ⇒ Object
Override the superclass check.
-
#collect_package_requests(ignore_list: [], walk_resource_tree: false) ⇒ Array
Find the set of packages to ask the chocolatey server about.
- #define_resource_requirements ⇒ Object
- #get_choco_version ⇒ Object
-
#install_package(names, versions) ⇒ Object
Install multiple packages via choco.exe.
-
#invalidate_cache ⇒ Object
invalidate cache for testing purposes.
-
#load_current_resource ⇒ Chef::Resource::ChocolateyPackage
Responsible for building the current_resource.
-
#query_command ⇒ Object
Choco V2 uses ‘Search’ for remote repositories and ‘List’ for local packages.
-
#remove_package(names, versions) ⇒ Object
(also: #purge_package)
Remove multiple packages via choco.exe.
-
#upgrade_package(names, versions) ⇒ Object
Upgrade multiple packages via choco.exe.
Methods included from ReservedNames::Win32::API::CommandLineHelper
#command_line_to_argv_w_helper
Methods inherited from Chef::Provider::Package
#as_array, #expand_options, #have_any_matching_version?, #initialize, #lock_package, #multipackage_api_adapter, #options, #package_locked, #prepare_for_installation, #preseed_package, #reconfig_package, #removing_package?, #target_version_already_installed?, #unlock_package, #version_equals?, #version_requirement_satisfied?
Methods included from Mixin::SubclassDirective
Methods inherited from Chef::Provider
action, action_description, action_descriptions, #action_nothing, #cleanup_after_converge, #compile_and_converge_action, #converge_by, #converge_if_changed, #cookbook_name, #description, #events, include_resource_dsl?, include_resource_dsl_module, #initialize, #introduced, #load_after_resource, #node, #process_resource_requirements, provides, provides?, #recipe_name, #requirements, #resource_collection, #resource_updated?, #run_action, #set_updated_status, supports?, use, use_inline_resources, #validate_required_properties!, #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 Mixin::LazyModuleInclude
#descendants, #include, #included
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::Secret
#default_secret_config, #default_secret_service, #secret, #with_secret_config, #with_secret_service
Methods included from DSL::RenderHelpers
#render_json, #render_toml, #render_yaml
Methods included from DSL::ReaderHelpers
#parse_file, #parse_json, #parse_toml, #parse_yaml
Methods included from DSL::Powershell
Methods included from DSL::RegistryHelper
#registry_data_exists?, #registry_get_subkeys, #registry_get_values, #registry_has_subkeys?, #registry_key_exists?, #registry_value_exists?
Methods included from DSL::ChefVault
#chef_vault, #chef_vault_item, #chef_vault_item_for_environment
Methods included from DSL::DataQuery
#data_bag, #data_bag_item, #search, #tagged?
Methods included from EncryptedDataBagItem::CheckEncrypted
Methods included from DSL::PlatformIntrospection
#older_than_win_2012_or_8?, #platform?, #platform_family?, #value_for_platform, #value_for_platform_family
Methods included from DSL::Recipe
#exec, #have_resource_class_for?, #resource_class_for
Methods included from DSL::Definitions
add_definition, #evaluate_resource_definition, #has_resource_definition?
Methods included from DSL::Resources
add_resource_dsl, remove_resource_dsl
Methods included from DSL::Cheffish
Methods included from DSL::RebootPending
Methods included from DSL::IncludeRecipe
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!, #resources, #with_run_context
Methods included from DSL::Compliance
#include_input, #include_profile, #include_waiver
Constructor Details
This class inherits a constructor from Chef::Provider::Package
Instance Method Details
#cache_is_valid? ⇒ Boolean
This checks that the repo list has not changed between now and when we last checked the cache
168 169 170 171 172 |
# File 'lib/chef/provider/package/chocolatey.rb', line 168 def cache_is_valid? return false if @@choco_config.nil? || (actual_config != @@choco_config) true end |
#candidate_version ⇒ Array
Lazy initializer for candidate_version. A nil value means that there is no candidate version and the package is not installable (generally an error).
83 84 85 |
# File 'lib/chef/provider/package/chocolatey.rb', line 83 def candidate_version @candidate_version ||= build_candidate_versions end |
#check_resource_semantics! ⇒ Object
Override the superclass check. The semantics for our new_resource.source is not files to install from, but like the rubygem provider’s sources which are more like repos.
144 |
# File 'lib/chef/provider/package/chocolatey.rb', line 144 def check_resource_semantics!; end |
#collect_package_requests(ignore_list: [], walk_resource_tree: false) ⇒ Array
Find the set of packages to ask the chocolatey server about
if walk_resource_tree is true, this finds all of the packages that we have referenced anywhere in our recipes - this is so we can attempt to query them all in a single transaction. However, currently we don’t do that - see the comment on available_packages for details of the why, but the TL;DR is that the public chocolatey servers do not support ‘or` type queries properly.
If walk_resource_tree is false, we don’t do any of that - we just filter the package list based on cache data. This is the default due to reasons explained in the comment on available_packages - the goal is to eventually turn this back on, hence the default false parameter here.
189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 |
# File 'lib/chef/provider/package/chocolatey.rb', line 189 def collect_package_requests(ignore_list: [], walk_resource_tree: false) return ["*"] if new_resource.bulk_query || Chef::Config[:always_use_bulk_chocolatey_package_list] if walk_resource_tree # Get to the root of the resource collection rc = run_context.parent_run_context || run_context rc = rc.parent_run_context while rc.parent_run_context package_collection = package_name_array package_collection += nested_package_resources(rc.resource_collection) else package_collection = package_name_array end # downcase the array and uniq. sorted for easier testing... package_collection.uniq.sort.filter { |pkg| !ignore_list.include?(pkg) } end |
#define_resource_requirements ⇒ Object
64 65 66 67 68 69 70 71 72 73 74 75 76 77 |
# File 'lib/chef/provider/package/chocolatey.rb', line 64 def define_resource_requirements super # The check that Chocolatey is installed is in #choco_exe. # Chocolatey source property points to an alternate feed # and not a package specific alternate source like other providers # so we want to assert candidates exist for the alternate source requirements.assert(:upgrade, :install) do |a| a.assertion { candidates_exist_for_all_uninstalled? } a.(Chef::Exceptions::Package, "No candidate version available for #{packages_missing_candidates.join(", ")}") a.whyrun("Assuming a repository that offers #{packages_missing_candidates.join(", ")} would have been configured") end end |
#get_choco_version ⇒ Object
146 147 148 149 150 151 152 |
# File 'lib/chef/provider/package/chocolatey.rb', line 146 def get_choco_version # We need a different way to get the version than by simply calling "choco --version". # If the license file is installed (for business customers) but not the Chocolatey.Extension (because you're using the choco resource to install it) # then you get a license error. This method bypasses that by getting the version from the exe directly instead of invoking it. # deprecated: @get_choco_version ||= powershell_exec!("#{choco_exe} --version").result @get_choco_version ||= powershell_exec!("Get-ItemProperty #{choco_exe} | select-object -expandproperty versioninfo | select-object -expandproperty productversion").result end |
#install_package(names, versions) ⇒ Object
Install multiple packages via choco.exe
91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 |
# File 'lib/chef/provider/package/chocolatey.rb', line 91 def install_package(names, versions) name_versions_to_install = desired_name_versions.select { |n, v| lowercase_names(names).include?(n) } name_nil_versions = name_versions_to_install.select { |n, v| v.nil? } name_has_versions = name_versions_to_install.compact # choco does not support installing multiple packages with version pins name_has_versions.each do |name, version| choco_command("install", "-y", "--version", version, cmd_args, name) end # but we can do all the ones without version pins at once unless name_nil_versions.empty? cmd_names = name_nil_versions.keys choco_command("install", "-y", cmd_args, *cmd_names) end end |
#invalidate_cache ⇒ Object
invalidate cache for testing purposes
162 163 164 |
# File 'lib/chef/provider/package/chocolatey.rb', line 162 def invalidate_cache @@choco_config = nil end |
#load_current_resource ⇒ Chef::Resource::ChocolateyPackage
Responsible for building the current_resource.
53 54 55 56 57 58 59 60 61 62 |
# File 'lib/chef/provider/package/chocolatey.rb', line 53 def load_current_resource @current_resource = Chef::Resource::ChocolateyPackage.new(new_resource.name) current_resource.package_name(new_resource.package_name) current_resource.version(build_current_versions) # Ensure that we have a working chocolatey executable - this used to be # covered off by loading the resource, but since that's no longer required, # we're going to put a quick check here to fail early! choco_exe current_resource end |
#query_command ⇒ Object
Choco V2 uses ‘Search’ for remote repositories and ‘List’ for local packages
155 156 157 158 159 |
# File 'lib/chef/provider/package/chocolatey.rb', line 155 def query_command return "list" if Gem::Dependency.new("", "< 1.4.0").match?("", get_choco_version) "search" end |
#remove_package(names, versions) ⇒ Object Also known as: purge_package
Remove multiple packages via choco.exe
135 136 137 |
# File 'lib/chef/provider/package/chocolatey.rb', line 135 def remove_package(names, versions) choco_command("uninstall", "-y", cmd_args(include_source: false), *names) end |
#upgrade_package(names, versions) ⇒ Object
Upgrade multiple packages via choco.exe
113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 |
# File 'lib/chef/provider/package/chocolatey.rb', line 113 def upgrade_package(names, versions) name_versions_to_install = desired_name_versions.select { |n, v| lowercase_names(names).include?(n) } name_nil_versions = name_versions_to_install.select { |n, v| v.nil? } name_has_versions = name_versions_to_install.compact # choco does not support installing multiple packages with version pins name_has_versions.each do |name, version| choco_command("upgrade", "-y", "--version", version, cmd_args, name) end # but we can do all the ones without version pins at once unless name_nil_versions.empty? cmd_names = name_nil_versions.keys choco_command("upgrade", "-y", cmd_args, *cmd_names) end end |