summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTim Smith <tsmith@chef.io>2019-12-09 10:17:28 -0800
committerGitHub <noreply@github.com>2019-12-09 10:17:28 -0800
commit29783478a5320df03fa4bf1a1b64319c0e7bb264 (patch)
tree227e5e8cbebaf9acea0235adee2f30f3001cb03a
parent046667bba72792ef9309eafb2957ae6c2c77f96f (diff)
parent7f4e9113a82f8ebd969fbdcfec767dfce960389e (diff)
downloadchef-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.rb54
-rw-r--r--chef-config/spec/unit/config_spec.rb32
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