diff options
42 files changed, 340 insertions, 114 deletions
diff --git a/CHANGELOG.md b/CHANGELOG.md index efc57a4188..be1c2c0e85 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,15 +1,19 @@ <!-- usage documentation: http://expeditor-docs.es.chef.io/configuration/changelog/ --> -<!-- latest_release 16.0.179 --> -## [v16.0.179](https://github.com/chef/chef/tree/v16.0.179) (2020-04-02) +<!-- latest_release 16.0.183 --> +## [v16.0.183](https://github.com/chef/chef/tree/v16.0.183) (2020-04-04) #### Merged Pull Requests -- Add Ubuntu 20.04 x86_64 and Ubuntu 18.04 aarch64 testers [#9584](https://github.com/chef/chef/pull/9584) ([tas50](https://github.com/tas50)) +- Use $env:temp instead of c:/ for functional tests [#9591](https://github.com/chef/chef/pull/9591) ([btm](https://github.com/btm)) <!-- latest_release --> <!-- release_rollup since=15.6.10 --> ### Changes not yet released to stable #### Merged Pull Requests +- Use $env:temp instead of c:/ for functional tests [#9591](https://github.com/chef/chef/pull/9591) ([btm](https://github.com/btm)) <!-- 16.0.183 --> +- Implement eager_load_libraries metadata option [#9593](https://github.com/chef/chef/pull/9593) ([lamont-granquist](https://github.com/lamont-granquist)) <!-- 16.0.182 --> +- Dist windows bootstrap template - fix msi_url [#9596](https://github.com/chef/chef/pull/9596) ([bobchaos](https://github.com/bobchaos)) <!-- 16.0.181 --> +- Change the name_property to be the identity property by default, and to have desired_state: false by default [#9581](https://github.com/chef/chef/pull/9581) ([lamont-granquist](https://github.com/lamont-granquist)) <!-- 16.0.180 --> - Add Ubuntu 20.04 x86_64 and Ubuntu 18.04 aarch64 testers [#9584](https://github.com/chef/chef/pull/9584) ([tas50](https://github.com/tas50)) <!-- 16.0.179 --> - fix chef_vault_secret after_resource breakage [#9574](https://github.com/chef/chef/pull/9574) ([lamont-granquist](https://github.com/lamont-granquist)) <!-- 16.0.178 --> - Add after_resource to pair with current_resource [#9562](https://github.com/chef/chef/pull/9562) ([lamont-granquist](https://github.com/lamont-granquist)) <!-- 16.0.177 --> diff --git a/Gemfile.lock b/Gemfile.lock index 50f585a214..7f85722bb3 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -27,12 +27,12 @@ GIT PATH remote: . specs: - chef (16.0.179) + chef (16.0.183) addressable bcrypt_pbkdf (~> 1.0) bundler (>= 1.10) - chef-config (= 16.0.179) - chef-utils (= 16.0.179) + chef-config (= 16.0.183) + chef-utils (= 16.0.183) chef-vault chef-zero (>= 14.0.11) diff-lcs (~> 1.2, >= 1.2.4) @@ -61,12 +61,12 @@ PATH train-winrm (>= 0.2.5) tty-screen (~> 0.6) uuidtools (~> 2.1.5) - chef (16.0.179-universal-mingw32) + chef (16.0.183-universal-mingw32) addressable bcrypt_pbkdf (~> 1.0) bundler (>= 1.10) - chef-config (= 16.0.179) - chef-utils (= 16.0.179) + chef-config (= 16.0.183) + chef-utils (= 16.0.183) chef-vault chef-zero (>= 14.0.11) diff-lcs (~> 1.2, >= 1.2.4) @@ -111,15 +111,15 @@ PATH PATH remote: chef-bin specs: - chef-bin (16.0.179) - chef (= 16.0.179) + chef-bin (16.0.183) + chef (= 16.0.183) PATH remote: chef-config specs: - chef-config (16.0.179) + chef-config (16.0.183) addressable - chef-utils (= 16.0.179) + chef-utils (= 16.0.183) fuzzyurl mixlib-config (>= 2.2.12, < 4.0) mixlib-shellout (>= 2.0, < 4.0) @@ -128,7 +128,7 @@ PATH PATH remote: chef-utils specs: - chef-utils (16.0.179) + chef-utils (16.0.183) GEM remote: https://rubygems.org/ @@ -1 +1 @@ -16.0.179
\ No newline at end of file +16.0.183
\ No newline at end of file diff --git a/chef-bin/lib/chef-bin/version.rb b/chef-bin/lib/chef-bin/version.rb index fd7d6c122e..5554aeeba3 100644 --- a/chef-bin/lib/chef-bin/version.rb +++ b/chef-bin/lib/chef-bin/version.rb @@ -21,7 +21,7 @@ module ChefBin CHEFBIN_ROOT = File.expand_path("../..", __FILE__) - VERSION = "16.0.179".freeze + VERSION = "16.0.183".freeze end # diff --git a/chef-config/lib/chef-config/version.rb b/chef-config/lib/chef-config/version.rb index c761c8c135..50775cde88 100644 --- a/chef-config/lib/chef-config/version.rb +++ b/chef-config/lib/chef-config/version.rb @@ -15,5 +15,5 @@ module ChefConfig CHEFCONFIG_ROOT = File.expand_path("../..", __FILE__) - VERSION = "16.0.179".freeze + VERSION = "16.0.183".freeze end diff --git a/chef-utils/lib/chef-utils/version.rb b/chef-utils/lib/chef-utils/version.rb index 3180cf1f3c..2c5a945c97 100644 --- a/chef-utils/lib/chef-utils/version.rb +++ b/chef-utils/lib/chef-utils/version.rb @@ -15,5 +15,5 @@ module ChefUtils CHEFUTILS_ROOT = File.expand_path("../..", __FILE__) - VERSION = "16.0.179".freeze + VERSION = "16.0.183".freeze end diff --git a/lib/chef/cookbook/metadata.rb b/lib/chef/cookbook/metadata.rb index ad7acb0e7b..d924be0c85 100644 --- a/lib/chef/cookbook/metadata.rb +++ b/lib/chef/cookbook/metadata.rb @@ -1,7 +1,7 @@ # Author:: Adam Jacob (<adam@chef.io>) # Author:: AJ Christensen (<aj@chef.io>) # Author:: Seth Falcon (<seth@chef.io>) -# Copyright:: Copyright 2008-2018, Chef Software Inc. +# Copyright:: Copyright 2008-2020, Chef Software Inc. # License:: Apache License, Version 2.0 # # Licensed under the Apache License, Version 2.0 (the "License"); @@ -52,11 +52,13 @@ class Chef CHEF_VERSIONS = "chef_versions".freeze OHAI_VERSIONS = "ohai_versions".freeze GEMS = "gems".freeze + EAGER_LOAD_LIBRARIES = "eager_load_libraries".freeze COMPARISON_FIELDS = %i{name description long_description maintainer maintainer_email license platforms dependencies providing recipes version source_url issues_url - privacy chef_versions ohai_versions gems}.freeze + privacy chef_versions ohai_versions gems + eager_load_libraries}.freeze VERSION_CONSTRAINTS = { depends: DEPENDENCIES, provides: PROVIDING, @@ -109,6 +111,7 @@ class Chef @chef_versions = [] @ohai_versions = [] @gems = [] + @eager_load_libraries = true @errors = [] end @@ -344,6 +347,25 @@ class Chef @gems end + # Metadata DSL to control the behavior of library loading. + # + # Can be set to: + # + # true - libraries are eagerly loaded in alphabetical order (backcompat) + # false - libraries are not eagerly loaded, the libraries dir is added to the LOAD_PATH + # String - a file or glob pattern to eagerly load, otherwise it is treated like `false` + # Array<String> - array of files or globs to eagerly load, otherwise it is treated like `false` + # + # @params arg [Array,String,TrueClass,FalseClass] + # @params [Array,TrueClass,FalseCalss] + def eager_load_libraries(arg = nil) + set_or_return( + :eager_load_libraries, + arg, + kind_of: [ Array, String, TrueClass, FalseClass ] + ) + end + # Adds a description for a recipe. # # === Parameters @@ -435,6 +457,7 @@ class Chef CHEF_VERSIONS => gem_requirements_to_array(*chef_versions), OHAI_VERSIONS => gem_requirements_to_array(*ohai_versions), GEMS => gems, + EAGER_LOAD_LIBRARIES => eager_load_libraries, } end @@ -468,6 +491,7 @@ class Chef @chef_versions = gem_requirements_from_array("chef", o[CHEF_VERSIONS]) if o.key?(CHEF_VERSIONS) @ohai_versions = gem_requirements_from_array("ohai", o[OHAI_VERSIONS]) if o.key?(OHAI_VERSIONS) @gems = o[GEMS] if o.key?(GEMS) + @eager_load_libraries = o[EAGER_LOAD_LIBRARIES] if o.key?(EAGER_LOAD_LIBRARIES) self end diff --git a/lib/chef/knife/bootstrap.rb b/lib/chef/knife/bootstrap.rb index 3279f7970a..3fe2ec5d71 100644 --- a/lib/chef/knife/bootstrap.rb +++ b/lib/chef/knife/bootstrap.rb @@ -467,7 +467,7 @@ class Chef # @return [String] Default bootstrap template def default_bootstrap_template if connection.windows? - "windows-#{Chef::Dist::CLIENT}-msi" + "windows-chef-client-msi" else "chef-full" end diff --git a/lib/chef/knife/bootstrap/templates/windows-chef-client-msi.erb b/lib/chef/knife/bootstrap/templates/windows-chef-client-msi.erb index 3fe397ed9e..b4da79e453 100644 --- a/lib/chef/knife/bootstrap/templates/windows-chef-client-msi.erb +++ b/lib/chef/knife/bootstrap/templates/windows-chef-client-msi.erb @@ -109,13 +109,13 @@ goto Version10.0 goto chef_installed :chef_installed -@echo Checking for existing chef installation +@echo Checking for existing <%= Chef::Dist::PRODUCT %> installation WHERE <%= Chef::Dist::CLIENT %> >nul 2>nul If !ERRORLEVEL!==0 ( - @echo Existing Chef installation detected, skipping download + @echo Existing <%= Chef::Dist::PRODUCT %> installation detected, skipping download goto key_create ) else ( - @echo No existing installation of chef detected + @echo No existing installation of <%= Chef::Dist::PRODUCT %> detected goto install ) @@ -272,5 +272,5 @@ echo Validation key written. <%= client_d %> <% end -%> -@echo Starting chef to bootstrap the node... +@echo Starting <%= Chef::Dist::CLIENT %> to bootstrap the node... <%= start_chef %> diff --git a/lib/chef/knife/core/windows_bootstrap_context.rb b/lib/chef/knife/core/windows_bootstrap_context.rb index d3f55ce94c..ff67ee3689 100644 --- a/lib/chef/knife/core/windows_bootstrap_context.rb +++ b/lib/chef/knife/core/windows_bootstrap_context.rb @@ -159,7 +159,7 @@ class Chef def start_chef bootstrap_environment_option = bootstrap_environment.nil? ? "" : " -E #{bootstrap_environment}" start_chef = "SET \"PATH=%SystemRoot%\\system32;%SystemRoot%;%SystemRoot%\\System32\\Wbem;%SYSTEMROOT%\\System32\\WindowsPowerShell\\v1.0\\;C:\\ruby\\bin;#{ChefConfig::Config.c_opscode_dir}\\#{ChefConfig::Dist::DIR_SUFFIX}\\bin;#{ChefConfig::Config.c_opscode_dir}\\#{ChefConfig::Dist::DIR_SUFFIX}\\embedded\\bin\;%PATH%\"\n" - start_chef << "chef-client -c #{ChefConfig::Config.etc_chef_dir(true)}/client.rb -j #{ChefConfig::Config.etc_chef_dir(true)}/first-boot.json#{bootstrap_environment_option}\n" + start_chef << "#{Chef::Dist::CLIENT} -c #{ChefConfig::Config.etc_chef_dir(true)}/client.rb -j #{ChefConfig::Config.etc_chef_dir(true)}/first-boot.json#{bootstrap_environment_option}\n" end def win_wget diff --git a/lib/chef/mixin/properties.rb b/lib/chef/mixin/properties.rb index ecb589e015..94afa4640b 100644 --- a/lib/chef/mixin/properties.rb +++ b/lib/chef/mixin/properties.rb @@ -264,10 +264,22 @@ class Chef end result = properties.values.select(&:identity?) - result = [ properties[:name] ] if result.empty? + # if there are no other identity properites set, then the name_property becomes the identity, or + # failing that we use the actual name. + if result.empty? + result = name_property ? [ properties[name_property] ] : [ properties[:name] ] + end result end + # Returns the name of the name property. Returns nil if there is no name property. + # + # @return [Symbol] the name property for this resource + def name_property + p = properties.find { |n, p| p.name_property? } + p ? p.first : nil + end + def included(other) other.extend ClassMethods end diff --git a/lib/chef/property.rb b/lib/chef/property.rb index 336331b59f..a29286c21b 100644 --- a/lib/chef/property.rb +++ b/lib/chef/property.rb @@ -1,7 +1,7 @@ # # Author:: John Keiser <jkeiser@chef.io> # Copyright:: Copyright 2015-2016, John Keiser -# Copyright:: Copyright 2015-2020, Chef Software, Inc. +# Copyright:: Copyright 2015-2020, Chef Software Inc. # License:: Apache License, Version 2.0 # # Licensed under the Apache License, Version 2.0 (the "License"); @@ -141,6 +141,10 @@ class Chef raise ArgumentError, "A property cannot be both a name_property/name_attribute and have a default value. Use one or the other on property #{self}" end + if options[:name_property] + options[:desired_state] = false unless options.key?(:desired_state) + end + # Recursively freeze the default if it isn't a lazy value. unless default.is_a?(DelayedEvaluator) visitor = lambda do |obj| diff --git a/lib/chef/resource.rb b/lib/chef/resource.rb index 5153dd4910..9cdf28dd9a 100644 --- a/lib/chef/resource.rb +++ b/lib/chef/resource.rb @@ -498,7 +498,7 @@ class Chef state = {} state_properties = self.class.state_properties state_properties.each do |property| - if property.identity? || property.is_set?(self) + if property.is_set?(self) state[property.name] = property.sensitive? ? "*sensitive value suppressed*" : send(property.name) end end diff --git a/lib/chef/resource/directory.rb b/lib/chef/resource/directory.rb index c8356f64ac..36cbe076f6 100644 --- a/lib/chef/resource/directory.rb +++ b/lib/chef/resource/directory.rb @@ -42,7 +42,7 @@ class Chef default_action :create allowed_actions :create, :delete - property :path, String, name_property: true, identity: true, + property :path, String, name_property: true, description: "The path to the directory. Using a fully qualified path is recommended, but is not always required." property :recursive, [ TrueClass, FalseClass ], diff --git a/lib/chef/resource/execute.rb b/lib/chef/resource/execute.rb index 7073ddc604..646e798bc7 100644 --- a/lib/chef/resource/execute.rb +++ b/lib/chef/resource/execute.rb @@ -49,7 +49,7 @@ class Chef end property :command, [ String, Array ], - name_property: true, identity: true, + name_property: true, description: "An optional property to set the command to be executed if it differs from the resource block's name." property :umask, [ String, Integer ], diff --git a/lib/chef/resource/file.rb b/lib/chef/resource/file.rb index 73d6f2de27..c3100d1160 100644 --- a/lib/chef/resource/file.rb +++ b/lib/chef/resource/file.rb @@ -55,7 +55,7 @@ class Chef default_action :create allowed_actions :create, :delete, :touch, :create_if_missing - property :path, String, name_property: true, identity: true, + property :path, String, name_property: true, description: "The full path to the file, including the file name and its extension. For example: /files/file.txt. Default value: the name of the resource block. Microsoft Windows: A path that begins with a forward slash (/) will point to the root of the current working directory of the #{Chef::Dist::CLIENT} process. This path can vary from system to system. Therefore, using a path that begins with a forward slash (/) is not recommended." property :atomic_update, [ TrueClass, FalseClass ], desired_state: false, default: lazy { docker? && special_docker_files?(path) ? false : Chef::Config[:file_atomic_update] }, diff --git a/lib/chef/resource/group.rb b/lib/chef/resource/group.rb index 058a5a63d4..7ba1eead9a 100644 --- a/lib/chef/resource/group.rb +++ b/lib/chef/resource/group.rb @@ -31,7 +31,7 @@ class Chef default_action :create property :group_name, String, - name_property: true, identity: true, + name_property: true, description: "The name of the group." property :gid, [ String, Integer ], diff --git a/lib/chef/resource/kernel_module.rb b/lib/chef/resource/kernel_module.rb index be8b007035..0d08ae8147 100644 --- a/lib/chef/resource/kernel_module.rb +++ b/lib/chef/resource/kernel_module.rb @@ -66,7 +66,7 @@ class Chef property :modname, String, description: "An optional property to set the kernel module name if it differs from the resource block's name.", - name_property: true, identity: true + name_property: true property :options, Array, description: "An optional property to set options for the kernel module.", diff --git a/lib/chef/resource/launchd.rb b/lib/chef/resource/launchd.rb index d939559b02..613ea415d2 100644 --- a/lib/chef/resource/launchd.rb +++ b/lib/chef/resource/launchd.rb @@ -31,7 +31,7 @@ class Chef allowed_actions :create, :create_if_missing, :delete, :enable, :disable, :restart property :label, String, - identity: true, name_property: true, + name_property: true, description: "The unique identifier for the job." property :backup, [Integer, FalseClass], diff --git a/lib/chef/resource/link.rb b/lib/chef/resource/link.rb index 7758e27433..636b748eb3 100644 --- a/lib/chef/resource/link.rb +++ b/lib/chef/resource/link.rb @@ -45,7 +45,7 @@ class Chef property :target_file, String, description: "An optional property to set the target file if it differs from the resource block's name.", - name_property: true, identity: true + name_property: true property :to, String, description: "The actual file to which the link is to be created." diff --git a/lib/chef/resource/mdadm.rb b/lib/chef/resource/mdadm.rb index 6ec547d133..ab5e074c04 100644 --- a/lib/chef/resource/mdadm.rb +++ b/lib/chef/resource/mdadm.rb @@ -59,7 +59,7 @@ class Chef description: "The path to a file in which a write-intent bitmap is stored." property :raid_device, String, - identity: true, name_property: true, + name_property: true, description: "An optional property to specify the name of the RAID device if it differs from the resource block's name." property :layout, String, diff --git a/lib/chef/resource/osx_profile.rb b/lib/chef/resource/osx_profile.rb index 5389696b72..8060db5076 100644 --- a/lib/chef/resource/osx_profile.rb +++ b/lib/chef/resource/osx_profile.rb @@ -34,7 +34,7 @@ class Chef property :profile_name, String, description: "Use to specify the name of the profile, if different from the name of the resource block.", - name_property: true, identity: true + name_property: true property :profile, [ String, Hash ], description: "Use to specify a profile. This may be the name of a profile contained in a cookbook or a Hash that contains the contents of the profile." diff --git a/lib/chef/resource/registry_key.rb b/lib/chef/resource/registry_key.rb index 1ecd631096..39246b1b50 100644 --- a/lib/chef/resource/registry_key.rb +++ b/lib/chef/resource/registry_key.rb @@ -70,7 +70,7 @@ class Chef @values, @unscrubbed_values = [], [] end - property :key, String, name_property: true, identity: true + property :key, String, name_property: true def values(arg = nil) if not arg.nil? diff --git a/lib/chef/resource/route.rb b/lib/chef/resource/route.rb index 979dc12342..0d9d9d431c 100644 --- a/lib/chef/resource/route.rb +++ b/lib/chef/resource/route.rb @@ -33,7 +33,7 @@ class Chef property :target, String, description: "The IP address of the target route.", - identity: true, name_property: true + name_property: true property :comment, [String, nil], description: "Add a comment for the route.", diff --git a/lib/chef/resource/ruby_block.rb b/lib/chef/resource/ruby_block.rb index 5ecf1582d4..d4a3c47ec5 100644 --- a/lib/chef/resource/ruby_block.rb +++ b/lib/chef/resource/ruby_block.rb @@ -1,7 +1,7 @@ # # Author:: Adam Jacob (<adam@chef.io>) # Author:: AJ Christensen (<aj@chef.io>) -# Copyright:: Copyright 2008-2016, Chef Software Inc. +# Copyright:: Copyright 2008-2020, Chef Software Inc. # License:: Apache License, Version 2.0 # # Licensed under the Apache License, Version 2.0 (the "License"); @@ -44,7 +44,7 @@ class Chef end end - property :block_name, String, name_property: true, identity: true + property :block_name, String, name_property: true end end end diff --git a/lib/chef/resource/scm.rb b/lib/chef/resource/scm.rb index 40b4f8e77c..eb2bdca8b8 100644 --- a/lib/chef/resource/scm.rb +++ b/lib/chef/resource/scm.rb @@ -1,6 +1,6 @@ # # Author:: Daniel DeLeo (<dan@kallistec.com>) -# Copyright:: Copyright 2008-2016, Chef Software Inc. +# Copyright:: Copyright 2008-2020, Chef Software Inc. # License:: Apache License, Version 2.0 # # Licensed under the Apache License, Version 2.0 (the "License"); @@ -28,7 +28,7 @@ class Chef property :destination, String, description: "The location path to which the source is to be cloned, checked out, or exported. Default value: the name of the resource block.", - name_property: true, identity: true + name_property: true property :repository, String diff --git a/lib/chef/resource/service.rb b/lib/chef/resource/service.rb index 71eb344483..4c57cd07b0 100644 --- a/lib/chef/resource/service.rb +++ b/lib/chef/resource/service.rb @@ -31,8 +31,6 @@ class Chef provides :service, target_mode: true - identity_attr :service_name - description "Use the service resource to manage a service." default_action :nothing @@ -46,7 +44,7 @@ class Chef property :service_name, String, description: "An optional property to set the service name if it differs from the resource block's name.", - name_property: true, identity: true + name_property: true # regex for match against ps -ef when !supports[:has_status] && status == nil property :pattern, String, diff --git a/lib/chef/resource/systemd_unit.rb b/lib/chef/resource/systemd_unit.rb index 0d477323f9..9e7067bd70 100644 --- a/lib/chef/resource/systemd_unit.rb +++ b/lib/chef/resource/systemd_unit.rb @@ -63,7 +63,7 @@ class Chef description: "Specifies if the unit will be verified before installation. Systemd can be overly strict when verifying units, so in certain cases it is preferable not to verify the unit." property :unit_name, String, desired_state: false, - identity: true, name_property: true, + name_property: true, description: "The name of the unit file if it differs from the resource block's name.", introduced: "13.7" diff --git a/lib/chef/resource/user.rb b/lib/chef/resource/user.rb index b72cc22b2d..035ec53875 100644 --- a/lib/chef/resource/user.rb +++ b/lib/chef/resource/user.rb @@ -30,7 +30,7 @@ class Chef property :username, String, description: "An optional property to set the username value if it differs from the resource block's name.", - name_property: true, identity: true + name_property: true property :comment, String, description: "The contents of the user comments field." diff --git a/lib/chef/resource/windows_env.rb b/lib/chef/resource/windows_env.rb index 4eda6e22b9..b7f347b80b 100644 --- a/lib/chef/resource/windows_env.rb +++ b/lib/chef/resource/windows_env.rb @@ -32,7 +32,7 @@ class Chef property :key_name, String, description: "An optional property to set the name of the key that is to be created, deleted, or modified if it differs from the resource block's name.", - identity: true, name_property: true + name_property: true property :value, String, description: "The value of the environmental variable to set.", diff --git a/lib/chef/resource_reporter.rb b/lib/chef/resource_reporter.rb index 246b2d5500..c8517dfc83 100644 --- a/lib/chef/resource_reporter.rb +++ b/lib/chef/resource_reporter.rb @@ -3,7 +3,7 @@ # Author:: Prajakta Purohit (prajakta@chef.io>) # Auther:: Tyler Cloke (<tyler@opscode.com>) # -# Copyright:: Copyright 2012-2019, Chef Software Inc. +# Copyright:: Copyright 2012-2020, Chef Software Inc. # License:: Apache License, Version 2.0 # # Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/lib/chef/run_context/cookbook_compiler.rb b/lib/chef/run_context/cookbook_compiler.rb index 116020de19..4dda6aeb2e 100644 --- a/lib/chef/run_context/cookbook_compiler.rb +++ b/lib/chef/run_context/cookbook_compiler.rb @@ -1,6 +1,6 @@ # # Author:: Daniel DeLeo (<dan@chef.io>) -# Copyright:: Copyright 2012-2019, Chef Software Inc. +# Copyright:: Copyright 2012-2020, Chef Software Inc. # License:: Apache License, Version 2.0 # # Licensed under the Apache License, Version 2.0 (the "License"); @@ -100,7 +100,15 @@ class Chef def compile_libraries @events.library_load_start(count_files_by_segment(:libraries)) cookbook_order.each do |cookbook| - load_libraries_from_cookbook(cookbook) + eager_load_libraries = cookbook_collection[cookbook].metadata.eager_load_libraries + if eager_load_libraries == true # actully true, not truthy + load_libraries_from_cookbook(cookbook) + else + $LOAD_PATH.unshift File.expand_path("libraries", cookbook_collection[cookbook].root_dir) + if eager_load_libraries # we have a String or Array<String> and not false + load_libraries_from_cookbook(cookbook, eager_load_libraries) + end + end end @events.library_load_complete end @@ -221,10 +229,8 @@ class Chef raise end - def load_libraries_from_cookbook(cookbook_name) - files_in_cookbook_by_segment(cookbook_name, :libraries).each do |filename| - next unless File.extname(filename) == ".rb" - + def load_libraries_from_cookbook(cookbook_name, globs = "**/*.rb") + each_file_in_cookbook_by_segment(cookbook_name, :libraries, globs) do |filename| begin logger.trace("Loading cookbook #{cookbook_name}'s library file: #{filename}") Kernel.require(filename) @@ -327,6 +333,22 @@ class Chef cookbook_collection[cookbook].files_for(segment).map { |record| record[:full_path] }.sort end + # Iterates through all files in given cookbook segment, yielding the full path to the file + # if it matches one of the given globs. Returns matching files in lexical sort order. Supports + # extended globbing. The segment should not be included in the glob. + # + def each_file_in_cookbook_by_segment(cookbook, segment, globs) + cookbook_collection[cookbook].files_for(segment).sort_by { |record| record[:path] }.each do |record| + Array(globs).each do |glob| + target = record[:path].delete_prefix("#{segment}/") + if File.fnmatch(glob, target, File::FNM_PATHNAME | File::FNM_EXTGLOB | File::FNM_DOTMATCH) + yield record[:full_path] + break + end + end + end + end + # Yields the name, as a symbol, of each cookbook depended on by # +cookbook_name+ in lexical sort order. def each_cookbook_dep(cookbook_name, &block) diff --git a/lib/chef/version.rb b/lib/chef/version.rb index c801fd7248..dec71ae8ca 100644 --- a/lib/chef/version.rb +++ b/lib/chef/version.rb @@ -23,7 +23,7 @@ require_relative "version_string" class Chef CHEF_ROOT = File.expand_path("../..", __FILE__) - VERSION = Chef::VersionString.new("16.0.179") + VERSION = Chef::VersionString.new("16.0.183") end # diff --git a/scripts/bk_tests/bk_win_functional.ps1 b/scripts/bk_tests/bk_win_functional.ps1 index bcb6b116c8..6033812388 100644 --- a/scripts/bk_tests/bk_win_functional.ps1 +++ b/scripts/bk_tests/bk_win_functional.ps1 @@ -9,13 +9,13 @@ echo "--- install ruby + devkit" $ErrorActionPreference = 'Stop' echo "Downloading Ruby + DevKit" -aws s3 cp s3://public-cd-buildkite-cache/rubyinstaller-devkit-2.6.5-1-x64.exe c:/rubyinstaller-devkit-2.6.5-1-x64.exe +aws s3 cp s3://public-cd-buildkite-cache/rubyinstaller-devkit-2.6.5-1-x64.exe $env:temp/rubyinstaller-devkit-2.6.5-1-x64.exe echo "Installing Ruby + DevKit" -Start-Process c:\rubyinstaller-devkit-2.6.5-1-x64.exe -ArgumentList '/verysilent /dir=C:\\ruby26' -Wait +Start-Process $env:temp\rubyinstaller-devkit-2.6.5-1-x64.exe -ArgumentList '/verysilent /dir=C:\\ruby26' -Wait echo "Cleaning up installation" -Remove-Item c:\rubyinstaller-devkit-2.6.5-1-x64.exe -Force -ErrorAction SilentlyContinue +Remove-Item $env:temp\rubyinstaller-devkit-2.6.5-1-x64.exe -Force -ErrorAction SilentlyContinue echo "Closing out the layer (this can take awhile)" # Set-Item -Path Env:Path -Value to include ruby26 diff --git a/spec/integration/client/client_spec.rb b/spec/integration/client/client_spec.rb index 24ec35d5e0..0b206623b1 100644 --- a/spec/integration/client/client_spec.rb +++ b/spec/integration/client/client_spec.rb @@ -11,8 +11,8 @@ describe "chef-client" do File.join(CHEF_SPEC_DATA, "recipes.tgz") end - def start_tiny_server(server_opts = {}) - @server = TinyServer::Manager.new(server_opts) + def start_tiny_server(**server_opts) + @server = TinyServer::Manager.new(**server_opts) @server.start @api = TinyServer::API.instance @api.clear @@ -739,4 +739,125 @@ EOM expect(command.stdout).to include("NOFORK") end end + + when_the_repository "has an eager_load_libraries false cookbook" do + before do + file "cookbooks/x/libraries/require_me.rb", <<~'EOM' + class RequireMe + end + EOM + file "cookbooks/x/recipes/default.rb", <<~'EOM' + # shouldn't be required by default + raise "boom" if defined?(RequireMe) + require "require_me" + # should be in the LOAD_PATH + raise "boom" unless defined?(RequireMe) + EOM + file "cookbooks/x/metadata.rb", <<~EOM + name 'x' + version '0.0.1' + eager_load_libraries false + EOM + file "config/client.rb", <<~EOM + local_mode true + cookbook_path "#{path_to("cookbooks")}" + EOM + end + + it "should not eagerly load the library" do + result = shell_out("#{chef_client} -c \"#{path_to("config/client.rb")}\" -o 'x::default'", cwd: chef_dir) + result.error! + end + end + + when_the_repository "has an eager_load_libraries cookbook with a default hook" do + before do + file "cookbooks/x/libraries/aa_require_me.rb", <<~'EOM' + class RequireMe + end + EOM + file "cookbooks/x/libraries/default.rb", <<~'EOM' + raise "boom" if defined?(RequireMe) + require "aa_require_me" + EOM + file "cookbooks/x/libraries/nope/default.rb", <<~'EOM' + raise "boom" # this should never be required + EOM + file "cookbooks/x/recipes/default.rb", <<~'EOM' + raise "boom" unless defined?(RequireMe) + EOM + file "cookbooks/x/metadata.rb", <<~EOM + name 'x' + version '0.0.1' + eager_load_libraries "default.rb" + EOM + file "config/client.rb", <<~EOM + local_mode true + cookbook_path "#{path_to("cookbooks")}" + always_dump_stacktrace true + EOM + end + + it "should properly load the library via the hook" do + result = shell_out("#{chef_client} -c \"#{path_to("config/client.rb")}\" -o 'x::default'", cwd: chef_dir) + result.error! + end + end + + when_the_repository "has an eager_load_libraries false cookbook" do + before do + # this is loaded by default.rb + file "cookbooks/x/libraries/aa_require_me.rb", <<~'EOM' + class RequireMe + end + EOM + # this is loaded by eager_load_libraries + file "cookbooks/x/libraries/default.rb", <<~'EOM' + raise "boom" if defined?(RequireMe) + require "aa_require_me" + EOM + # this is loaded by the recipe using the LOAD_PATH + file "cookbooks/x/libraries/require_me.rb", <<~'EOM' + class RequireMe4 + end + EOM + # these two are loaded by eager_load_libraries glob + file "cookbooks/x/libraries/loadme/foo/require_me.rb", <<~'EOM' + class RequireMe2 + end + EOM + file "cookbooks/x/libraries/loadme/require_me.rb", <<~'EOM' + class RequireMe3 + end + EOM + # this should nevrer be loaded + file "cookbooks/x/libraries/nope/require_me.rb", <<~'EOM' + raise "boom" # this should never be required + EOM + file "cookbooks/x/recipes/default.rb", <<~'EOM' + # all these are loaded by the eager_load_libraries + raise "boom" unless defined?(RequireMe) + raise "boom" unless defined?(RequireMe2) + raise "boom" unless defined?(RequireMe3) + raise "boom" if defined?(RequireMe4) + require "require_me" + raise "boom" unless defined?(RequireMe4) + EOM + file "cookbooks/x/metadata.rb", <<~EOM + name 'x' + version '0.0.1' + eager_load_libraries [ "default.rb", "loadme/**/*.rb" ] + EOM + file "config/client.rb", <<~EOM + local_mode true + cookbook_path "#{path_to("cookbooks")}" + always_dump_stacktrace true + EOM + end + + it "should not eagerly load the library" do + result = shell_out("#{chef_client} -c \"#{path_to("config/client.rb")}\" -o 'x::default'", cwd: chef_dir) + result.error! + end + end end diff --git a/spec/integration/knife/cookbook_show_spec.rb b/spec/integration/knife/cookbook_show_spec.rb index 32b1324a0a..8d4b4b660f 100644 --- a/spec/integration/knife/cookbook_show_spec.rb +++ b/spec/integration/knife/cookbook_show_spec.rb @@ -1,5 +1,5 @@ # -# Copyright:: Copyright 2013-2016, Chef Software Inc. +# Copyright:: Copyright 2013-2020, Chef Software Inc. # License:: Apache License, Version 2.0 # # Licensed under the Apache License, Version 2.0 (the "License"); @@ -43,25 +43,26 @@ describe "knife cookbook show", :workstation do metadata: chef_versions: dependencies: - description: + description: + eager_load_libraries: true gems: - issues_url: - license: All rights reserved - long_description: - maintainer: - maintainer_email: - name: x + issues_url: + license: All rights reserved + long_description: + maintainer: + maintainer_email: + name: x ohai_versions: platforms: - privacy: false + privacy: false providing: x: >= 0.0.0 x::x: >= 0.0.0 recipes: - x: - x::x: - source_url: - version: 1.0.0 + x: + x::x: + source_url: + version: 1.0.0 name: x-1.0.0 recipes: checksum: 4631b34cf58de10c5ef1304889941b2e @@ -69,7 +70,7 @@ describe "knife cookbook show", :workstation do path: recipes/default.rb specificity: default url: http://127.0.0.1:8900/file_store/checksums/4631b34cf58de10c5ef1304889941b2e - + checksum: d41d8cd98f00b204e9800998ecf8427e name: recipes/x.rb path: recipes/x.rb @@ -89,25 +90,26 @@ describe "knife cookbook show", :workstation do knife("cookbook show x 1.0.0 metadata").should_succeed <<~EOM chef_versions: dependencies: - description: + description: + eager_load_libraries: true gems: - issues_url: - license: All rights reserved - long_description: - maintainer: - maintainer_email: - name: x + issues_url: + license: All rights reserved + long_description: + maintainer: + maintainer_email: + name: x ohai_versions: platforms: - privacy: false + privacy: false providing: x: >= 0.0.0 x::x: >= 0.0.0 recipes: - x: - x::x: - source_url: - version: 1.0.0 + x: + x::x: + source_url: + version: 1.0.0 EOM end @@ -118,7 +120,7 @@ describe "knife cookbook show", :workstation do path: recipes/default.rb specificity: default url: http://127.0.0.1:8900/file_store/checksums/4631b34cf58de10c5ef1304889941b2e - + checksum: d41d8cd98f00b204e9800998ecf8427e name: recipes/x.rb path: recipes/x.rb diff --git a/spec/support/shared/integration/knife_support.rb b/spec/support/shared/integration/knife_support.rb index 8de665c370..b1e01e97f2 100644 --- a/spec/support/shared/integration/knife_support.rb +++ b/spec/support/shared/integration/knife_support.rb @@ -1,6 +1,6 @@ # # Author:: John Keiser (<jkeiser@chef.io>) -# Copyright:: Copyright 2013-2017, Chef Software Inc. +# Copyright:: Copyright 2013-2020, Chef Software Inc. # License:: Apache License, Version 2.0 # # Licensed under the Apache License, Version 2.0 (the "License"); @@ -170,21 +170,24 @@ module KnifeSupport def should_result_in(expected) expected[:stdout] = "" unless expected[:stdout] + expected[:stdout] = expected[:stdout].is_a?(String) ? expected[:stdout].gsub(/[ \t\f\v]+$/, "") : expected[:stdout] expected[:stderr] = "" unless expected[:stderr] + expected[:stderr] = expected[:stderr].is_a?(String) ? expected[:stderr].gsub(/[ \t\f\v]+$/, "") : expected[:stderr] expected[:exit_code] = 0 unless expected[:exit_code] # TODO make this go away stderr_actual = @stderr.sub(/^WARNING: No knife configuration file found\n/, "") - - if expected[:stderr].is_a?(Regexp) - expect(stderr_actual).to match(expected[:stderr]) - else - expect(stderr_actual).to eq(expected[:stderr]) - end + stderr_actual = stderr_actual.gsub(/[ \t\f\v]+$/, "") stdout_actual = @stdout + stdout_actual = stdout_actual.gsub(/[ \t\f\v]+$/, "") if ChefUtils.windows? stderr_actual = stderr_actual.gsub("\r\n", "\n") stdout_actual = stdout_actual.gsub("\r\n", "\n") end + if expected[:stderr].is_a?(Regexp) + expect(stderr_actual).to match(expected[:stderr]) + else + expect(stderr_actual).to eq(expected[:stderr]) + end expect(@exit_code).to eq(expected[:exit_code]) if expected[:stdout].is_a?(Regexp) expect(stdout_actual).to match(expected[:stdout]) diff --git a/spec/unit/cookbook/metadata_spec.rb b/spec/unit/cookbook/metadata_spec.rb index 3c52198310..afb293cd37 100644 --- a/spec/unit/cookbook/metadata_spec.rb +++ b/spec/unit/cookbook/metadata_spec.rb @@ -29,7 +29,7 @@ describe Chef::Cookbook::Metadata do @fields = %i{name description long_description maintainer maintainer_email license platforms dependencies providing recipes version source_url issues_url - privacy ohai_versions chef_versions gems} + privacy ohai_versions chef_versions gems eager_load_libraries} end it "does not depend on object identity for equality" do @@ -127,6 +127,10 @@ describe Chef::Cookbook::Metadata do it "is not private" do expect(metadata.privacy).to eq(false) end + + it "has eager_load_libraries set to true" do + expect(metadata.eager_load_libraries).to eq(true) + end end describe "validation" do @@ -179,6 +183,7 @@ describe Chef::Cookbook::Metadata do source_url: "http://example.com", issues_url: "http://example.com/issues", privacy: true, + eager_load_libraries: false, } params.sort_by(&:to_s).each do |field, field_value| describe field do @@ -269,8 +274,33 @@ describe Chef::Cookbook::Metadata do it "errors on self-dependencies" do metadata.name("foo") - expect { metadata.depends("foo") }.to raise_error - # FIXME: add the error type + expect { metadata.depends("foo") }.to raise_error(RuntimeError, /Cookbook depends on itself/) + end + end + + describe "eager_load_libraries" do + it "can be set to true" do + metadata.send(:eager_load_libraries, true) + expect(metadata.send(:eager_load_libraries)).to eql(true) + end + + it "can be set to false" do + metadata.send(:eager_load_libraries, false) + expect(metadata.send(:eager_load_libraries)).to eql(false) + end + + it "can be set to a string" do + metadata.send(:eager_load_libraries, "default.rb") + expect(metadata.send(:eager_load_libraries)).to eql("default.rb") + end + + it "can be set to an array" do + metadata.send(:eager_load_libraries, [ "default.rb", "foo/*/**.rb" ]) + expect(metadata.send(:eager_load_libraries)).to eql([ "default.rb", "foo/*/**.rb" ]) + end + + it "cannot be set to a number" do + expect { metadata.send(:eager_load_libraries, 1) }.to raise_error(Chef::Exceptions::ValidationFailed) end end @@ -452,6 +482,7 @@ describe Chef::Cookbook::Metadata do metadata.chef_version "< 12.5.1", ">= 12.2.1" metadata.ohai_version "< 7.5.0", ">= 7.1.0" metadata.ohai_version "< 8.6.0", ">= 8.0.1" + metadata.eager_load_libraries [ "default.rb", "foo/*/**.rb" ] end it "should produce the same output from to_json and Chef::JSONCompat" do diff --git a/spec/unit/knife/cookbook_show_spec.rb b/spec/unit/knife/cookbook_show_spec.rb index b1e7d60e5b..9fe2e9ff90 100644 --- a/spec/unit/knife/cookbook_show_spec.rb +++ b/spec/unit/knife/cookbook_show_spec.rb @@ -1,6 +1,6 @@ # # Author:: Adam Jacob (<adam@chef.io>) -# Copyright:: Copyright 2008-2017, Chef Software Inc. +# Copyright:: Copyright 2008-2020, Chef Software Inc. # License:: Apache License, version 2.0 # # Licensed under the Apache License, Version 2.0 (the "License"); @@ -109,6 +109,7 @@ describe Chef::Knife::CookbookShow do "metadata" => { "name" => nil, "description" => "", + "eager_load_libraries" => true, "long_description" => "", "maintainer" => "", "maintainer_email" => "", diff --git a/spec/unit/property/state_spec.rb b/spec/unit/property/state_spec.rb index a6428e8617..f120039f8b 100644 --- a/spec/unit/property/state_spec.rb +++ b/spec/unit/property/state_spec.rb @@ -285,8 +285,8 @@ describe "Chef::Resource#identity and #state" do it "identity when x is not defined returns the value of x" do expect(resource.identity).to eq "blah" end - it "state when x is not defined returns the value of x" do - expect(resource.state_for_resource_reporter).to eq(x: "blah") + it "the name property is not included in the desired state" do + expect(resource.state_for_resource_reporter).to eq({}) end end end @@ -332,12 +332,17 @@ describe "Chef::Resource#identity and #state" do end with_property ":x, name_property: true" do - # it "Unset values with name_property are included in state" do - # expect(resource.state_for_resource_reporter).to eq({ x: 'blah' }) - # end - it "Set values with name_property are included in state" do + it "Is by default the identity property if no other identity property is included" do + expect(resource.identity).to eq("blah") + end + + it "Unset values with name_property are not included in state" do + expect(resource.state_for_resource_reporter).to eq({}) + end + + it "Set values with name_property are not included in state" do resource.x 1 - expect(resource.state_for_resource_reporter).to eq(x: 1) + expect(resource.state_for_resource_reporter).to eq({}) end end diff --git a/spec/unit/property_spec.rb b/spec/unit/property_spec.rb index 965da7313e..177314d8bc 100644 --- a/spec/unit/property_spec.rb +++ b/spec/unit/property_spec.rb @@ -1022,6 +1022,9 @@ describe "Chef::Resource.property" do it "defaults x to resource.name" do expect(resource.x).to eq "blah" end + it "defaults to being part of the identity if there is no other identity" do + expect(resource.identity).to eq "blah" + end it "does not pick up resource.name if set" do expect(resource.x 10).to eq 10 expect(resource.x).to eq 10 diff --git a/spec/unit/resource_reporter_spec.rb b/spec/unit/resource_reporter_spec.rb index 775b14ef19..22bba578eb 100644 --- a/spec/unit/resource_reporter_spec.rb +++ b/spec/unit/resource_reporter_spec.rb @@ -3,7 +3,7 @@ # Author:: Prajakta Purohit (<prajakta@chef.io>) # Author:: Tyler Cloke (<tyler@chef.io>) # -# Copyright:: Copyright 2012-2019, Chef Software Inc. +# Copyright:: Copyright 2012-2020, Chef Software Inc. # License:: Apache License, Version 2.0 # # Licensed under the Apache License, Version 2.0 (the "License"); @@ -294,7 +294,7 @@ describe Chef::ResourceReporter do resource_reporter.run_started(run_status) end - context "when the new_resource is sensitive" do + context "when the new_resource is a sensitive execute resource" do before do @execute_resource = Chef::Resource::Execute.new("sensitive-resource") @execute_resource.name("sensitive-resource") @@ -312,10 +312,6 @@ describe Chef::ResourceReporter do it "resource_name in prepared_run_data should be the same" do expect(@first_update_report["name"]).to eq("sensitive-resource") end - - it "resource_command in prepared_run_data should be blank" do - expect(@first_update_report["after"]).to eq({ command: "sensitive-resource" }) - end end context "when the new_resource does not have a string for name and identity" do |