diff options
author | Tim Smith <tsmith@chef.io> | 2019-12-09 10:17:28 -0800 |
---|---|---|
committer | GitHub <noreply@github.com> | 2019-12-09 10:17:28 -0800 |
commit | 29783478a5320df03fa4bf1a1b64319c0e7bb264 (patch) | |
tree | 227e5e8cbebaf9acea0235adee2f30f3001cb03a | |
parent | 046667bba72792ef9309eafb2957ae6c2c77f96f (diff) | |
parent | 7f4e9113a82f8ebd969fbdcfec767dfce960389e (diff) | |
download | chef-29783478a5320df03fa4bf1a1b64319c0e7bb264.tar.gz |
Merge pull request #9042 from MsysTechnologiesllc/Kapil/MSYS-1148_ChefConfig_should_expand_relative_paths
Fix for ChefConfig should expand relative paths
-rw-r--r-- | chef-config/lib/chef-config/config.rb | 54 | ||||
-rw-r--r-- | chef-config/spec/unit/config_spec.rb | 32 |
2 files changed, 70 insertions, 16 deletions
diff --git a/chef-config/lib/chef-config/config.rb b/chef-config/lib/chef-config/config.rb index 374d548d31..d146051672 100644 --- a/chef-config/lib/chef-config/config.rb +++ b/chef-config/lib/chef-config/config.rb @@ -134,12 +134,20 @@ module ChefConfig # Split including whitespace if someone does truly odd like # --config-option "foo = bar" key, value = option.split(/\s*=\s*/, 2) + # Call to_sym because Chef::Config expects only symbol keys. Also # runs a simple parse on the string for some common types. memo[key.to_sym] = YAML.safe_load(value) memo end - merge!(extra_parsed_options) + set_extra_config_options(extra_parsed_options) + end + end + + # We use :[]= assignment here to not bypass any coercions that happen via mixlib-config writes_value callbacks + def self.set_extra_config_options(extra_parsed_options) + extra_parsed_options.each do |key, value| + self[key.to_sym] = value end end @@ -182,6 +190,20 @@ module ChefConfig # properly. configurable(:daemonize).writes_value { |v| v } + def self.expand_relative_paths(path) + unless path.nil? + if path.is_a?(String) + File.expand_path(path) + else + Array(path).map { |path| File.expand_path(path) } + end + end + end + + configurable(:cookbook_path).writes_value { |path| expand_relative_paths(path) } + + configurable(:chef_repo_path).writes_value { |path| expand_relative_paths(path) } + # The root where all local chef object data is stored. cookbooks, data bags, # environments are all assumed to be in separate directories under this. # chef-solo uses these directories for input data. knife commands @@ -230,23 +252,23 @@ module ChefConfig # Location of acls on disk. String or array of strings. # Defaults to <chef_repo_path>/acls. - default(:acl_path) { derive_path_from_chef_repo_path("acls") } + default(:acl_path) { derive_path_from_chef_repo_path("acls") }.writes_value { |path| expand_relative_paths(path) } # Location of clients on disk. String or array of strings. # Defaults to <chef_repo_path>/clients. - default(:client_path) { derive_path_from_chef_repo_path("clients") } + default(:client_path) { derive_path_from_chef_repo_path("clients") }.writes_value { |path| expand_relative_paths(path) } # Location of client keys on disk. String or array of strings. # Defaults to <chef_repo_path>/client_keys. - default(:client_key_path) { derive_path_from_chef_repo_path("client_keys") } + default(:client_key_path) { derive_path_from_chef_repo_path("client_keys") }.writes_value { |path| expand_relative_paths(path) } # Location of containers on disk. String or array of strings. # Defaults to <chef_repo_path>/containers. - default(:container_path) { derive_path_from_chef_repo_path("containers") } + default(:container_path) { derive_path_from_chef_repo_path("containers") }.writes_value { |path| expand_relative_paths(path) } # Location of cookbook_artifacts on disk. String or array of strings. # Defaults to <chef_repo_path>/cookbook_artifacts. - default(:cookbook_artifact_path) { derive_path_from_chef_repo_path("cookbook_artifacts") } + default(:cookbook_artifact_path) { derive_path_from_chef_repo_path("cookbook_artifacts") }.writes_value { |path| expand_relative_paths(path) } # Location of cookbooks on disk. String or array of strings. # Defaults to <chef_repo_path>/cookbooks. If chef_repo_path @@ -262,35 +284,35 @@ module ChefConfig # Location of data bags on disk. String or array of strings. # Defaults to <chef_repo_path>/data_bags. - default(:data_bag_path) { derive_path_from_chef_repo_path("data_bags") } + default(:data_bag_path) { derive_path_from_chef_repo_path("data_bags") }.writes_value { |path| expand_relative_paths(path) } # Location of environments on disk. String or array of strings. # Defaults to <chef_repo_path>/environments. - default(:environment_path) { derive_path_from_chef_repo_path("environments") } + default(:environment_path) { derive_path_from_chef_repo_path("environments") }.writes_value { |path| expand_relative_paths(path) } # Location of groups on disk. String or array of strings. # Defaults to <chef_repo_path>/groups. - default(:group_path) { derive_path_from_chef_repo_path("groups") } + default(:group_path) { derive_path_from_chef_repo_path("groups") }.writes_value { |path| expand_relative_paths(path) } # Location of nodes on disk. String or array of strings. # Defaults to <chef_repo_path>/nodes. - default(:node_path) { derive_path_from_chef_repo_path("nodes") } + default(:node_path) { derive_path_from_chef_repo_path("nodes") }.writes_value { |path| expand_relative_paths(path) } # Location of policies on disk. String or array of strings. # Defaults to <chef_repo_path>/policies. - default(:policy_path) { derive_path_from_chef_repo_path("policies") } + default(:policy_path) { derive_path_from_chef_repo_path("policies") }.writes_value { |path| expand_relative_paths(path) } # Location of policy_groups on disk. String or array of strings. # Defaults to <chef_repo_path>/policy_groups. - default(:policy_group_path) { derive_path_from_chef_repo_path("policy_groups") } + default(:policy_group_path) { derive_path_from_chef_repo_path("policy_groups") }.writes_value { |path| expand_relative_paths(path) } # Location of roles on disk. String or array of strings. # Defaults to <chef_repo_path>/roles. - default(:role_path) { derive_path_from_chef_repo_path("roles") } + default(:role_path) { derive_path_from_chef_repo_path("roles") }.writes_value { |path| expand_relative_paths(path) } # Location of users on disk. String or array of strings. # Defaults to <chef_repo_path>/users. - default(:user_path) { derive_path_from_chef_repo_path("users") } + default(:user_path) { derive_path_from_chef_repo_path("users") }.writes_value { |path| expand_relative_paths(path) } # Turn on "path sanity" by default. default :enforce_path_sanity, false @@ -338,7 +360,7 @@ module ChefConfig default(:checksum_path) { PathHelper.join(cache_path, "checksums") } # Where chef's cache files should be stored - default(:file_cache_path) { PathHelper.join(cache_path, "cache") } + default(:file_cache_path) { PathHelper.join(cache_path, "cache") }.writes_value { |path| expand_relative_paths(path) } # Where backups of chef-managed files should go default(:file_backup_path) { PathHelper.join(cache_path, "backup") } @@ -782,7 +804,7 @@ module ChefConfig # the new (and preferred) configuration setting. If not set, knife will # fall back to using cache_options[:path], which is deprecated but exists in # many client configs generated by pre-Chef-11 bootstrappers. - default(:syntax_check_cache_path) { cache_options[:path] } + default(:syntax_check_cache_path) { cache_options[:path] }.writes_value { |path| expand_relative_paths(path) } # Deprecated: # Move this to the default value of syntax_cache_path when this is removed. diff --git a/chef-config/spec/unit/config_spec.rb b/chef-config/spec/unit/config_spec.rb index c0cd08893d..b7f070c0fa 100644 --- a/chef-config/spec/unit/config_spec.rb +++ b/chef-config/spec/unit/config_spec.rb @@ -151,6 +151,38 @@ RSpec.describe ChefConfig::Config do end + describe "expand relative paths" do + let(:current_directory) { Dir.pwd } + + context "when given cookbook_path" do + let(:extra_config_options) { [ "cookbook_path=cookbooks/" ] } + + it "expanded cookbook_path" do + apply_config + expect(described_class[:cookbook_path]).to eq("#{current_directory}/cookbooks") + end + end + + context "when passes multiple config options" do + let(:extra_config_options) { ["data_bag_path=data_bags/", "cookbook_path=cookbooks", "chef_repo_path=."] } + + it "expanded paths" do + apply_config + expect(described_class[:data_bag_path]).to eq("#{current_directory}/data_bags") + expect(described_class[:cookbook_path]).to eq("#{current_directory}/cookbooks") + expect(described_class[:chef_repo_path]).to eq("#{current_directory}") + end + end + + context "when passes multiple cookbook_paths in config options" do + let(:extra_config_options) { ["cookbook_path=[first_cookbook, secound_cookbooks]"] } + + it "expanded paths" do + apply_config + expect(described_class[:cookbook_path]).to eq(["#{current_directory}/first_cookbook", "#{current_directory}/secound_cookbooks"]) + end + end + end end describe "when configuring formatters" do |