summaryrefslogtreecommitdiff
path: root/lib/chef_zero/chef_data
diff options
context:
space:
mode:
authorThom May <thom@chef.io>2017-01-06 16:53:09 +0000
committerThom May <thom@chef.io>2017-03-29 16:27:15 +0100
commitc57862350cdd62a03e7be0b6752129b8fc533fc8 (patch)
tree370784a07e39c885437e82fe0638256991bea41d /lib/chef_zero/chef_data
parentf8fedad60de7978f008e720d4638e81f76b69085 (diff)
downloadchef-zero-c57862350cdd62a03e7be0b6752129b8fc533fc8.tar.gz
Remove cookbook segments
This implements RFC 67, Cookbook Segment Deprecation, for the default backend of Chef Zero. It also does a little bit of work to make API versions more ergonomic. Signed-off-by: Thom May <thom@may.lt>
Diffstat (limited to 'lib/chef_zero/chef_data')
-rw-r--r--lib/chef_zero/chef_data/cookbook_data.rb68
-rw-r--r--lib/chef_zero/chef_data/data_normalizer.rb50
2 files changed, 69 insertions, 49 deletions
diff --git a/lib/chef_zero/chef_data/cookbook_data.rb b/lib/chef_zero/chef_data/cookbook_data.rb
index bdad333..2766162 100644
--- a/lib/chef_zero/chef_data/cookbook_data.rb
+++ b/lib/chef_zero/chef_data/cookbook_data.rb
@@ -13,7 +13,9 @@ module ChefZero
end
result = files_from(cookbook)
- recipe_names = result[:recipes].map do |recipe|
+ recipe_names = result[:all_files].select do |file|
+ file[:name].start_with?("recipes/")
+ end.map do |recipe|
recipe_name = recipe[:name][0..-2]
recipe_name == "default" ? name : "#{name}::#{recipe_name}"
end
@@ -86,26 +88,10 @@ module ChefZero
cookbook_arg(:supports, cookbook, version_constraints)
end
- def recommends(cookbook, *version_constraints)
- cookbook_arg(:recommendations, cookbook, version_constraints)
- end
-
- def suggests(cookbook, *version_constraints)
- cookbook_arg(:suggestions, cookbook, version_constraints)
- end
-
- def conflicts(cookbook, *version_constraints)
- cookbook_arg(:conflicting, cookbook, version_constraints)
- end
-
def provides(cookbook, *version_constraints)
cookbook_arg(:providing, cookbook, version_constraints)
end
- def replaces(cookbook, *version_constraints)
- cookbook_arg(:replacing, cookbook, version_constraints)
- end
-
def gem(*opts)
self[:gems] ||= []
self[:gems] << opts
@@ -119,10 +105,6 @@ module ChefZero
self[:attributes][name] = options
end
- def grouping(name, options)
- self[:grouping][name] = options
- end
-
def cookbook_arg(key, cookbook, version_constraints)
self[key][cookbook] = version_constraints.first || ">= 0.0.0"
end
@@ -142,19 +124,14 @@ module ChefZero
def self.files_from(directory)
# TODO some support .rb only
+ result = load_files(directory)
+
+ set_specificity(result, :templates)
+ set_specificity(result, :files)
+
result = {
- :attributes => load_child_files(directory, "attributes", false),
- :definitions => load_child_files(directory, "definitions", false),
- :recipes => load_child_files(directory, "recipes", false),
- :libraries => load_child_files(directory, "libraries", true),
- :templates => load_child_files(directory, "templates", true),
- :files => load_child_files(directory, "files", true),
- :resources => load_child_files(directory, "resources", true),
- :providers => load_child_files(directory, "providers", true),
- :root_files => load_files(directory, false),
+ all_files: result,
}
- set_specificity(result[:templates])
- set_specificity(result[:files])
result
end
@@ -199,45 +176,52 @@ module ChefZero
end
end
- def self.load_child_files(parent, key, recursive)
- result = load_files(get_directory(parent, key), recursive)
+ def self.load_child_files(parent, key, recursive, part)
+ result = load_files(get_directory(parent, key), recursive, part)
result.each do |file|
file[:path] = "#{key}/#{file[:path]}"
end
result
end
- def self.load_files(directory, recursive)
+ def self.load_files(directory, recursive = true, part = nil)
result = []
if directory
list(directory).each do |child_name|
dir = get_directory(directory, child_name)
if dir
+ child_part = child_name if part.nil?
if recursive
- result += load_child_files(directory, child_name, recursive)
+ result += load_child_files(directory, child_name, recursive, child_part)
end
else
- result += load_file(read_file(directory, child_name), child_name)
+ result += load_file(read_file(directory, child_name), child_name, part)
end
end
end
result
end
- def self.load_file(value, name)
+ def self.load_file(value, name, part = nil)
+ specific_name = part ? "#{part}/#{name}" : name
[{
- :name => name,
+ :name => specific_name,
:path => name,
:checksum => Digest::MD5.hexdigest(value),
:specificity => "default",
}]
end
- def self.set_specificity(files)
+ def self.set_specificity(files, type)
files.each do |file|
+ next unless file[:name].split("/")[0] == type.to_s
+
parts = file[:path].split("/")
- raise "Only directories are allowed directly under templates or files: #{file[:path]}" if parts.size == 2
- file[:specificity] = parts[1]
+ file[:specificity] = if parts.size == 2
+ "default"
+ else
+ parts[1]
+ end
end
end
end
diff --git a/lib/chef_zero/chef_data/data_normalizer.rb b/lib/chef_zero/chef_data/data_normalizer.rb
index 939acc5..6e96f85 100644
--- a/lib/chef_zero/chef_data/data_normalizer.rb
+++ b/lib/chef_zero/chef_data/data_normalizer.rb
@@ -5,6 +5,9 @@ require "chef_zero/chef_data/default_creator"
module ChefZero
module ChefData
class DataNormalizer
+
+ COOKBOOK_SEGMENTS = %w{ resources providers recipes definitions libraries attributes files templates root_files }
+
def self.normalize_acls(acls)
ChefData::DefaultCreator::PERMISSIONS.each do |perm|
acls[perm] ||= {}
@@ -90,18 +93,51 @@ module ChefZero
end
def self.normalize_cookbook(endpoint, org_prefix, cookbook, name, version, base_uri, method,
- is_cookbook_artifact = false)
+ is_cookbook_artifact = false, api_version: 2)
# TODO I feel dirty
- if method != "PUT"
- cookbook.each_pair do |key, value|
- if value.is_a?(Array)
- value.each do |file|
- if file.is_a?(Hash) && file.has_key?("checksum")
- file["url"] ||= endpoint.build_uri(base_uri, org_prefix + ["file_store", "checksums", file["checksum"]])
+ if method == "PUT" && api_version < 2
+ cookbook["all_files"] = cookbook.delete(["root_files"]) { [] }
+ COOKBOOK_SEGMENTS.each do |segment|
+ next unless cookbook.has_key? segment
+ cookbook[segment].each do |file|
+ file["name"] = "#{segment}/#{file['name']}"
+ cookbook["all_files"] << file
+ end
+ cookbook.delete(segment)
+ end
+ elsif method != "PUT"
+ if cookbook.key? "all_files"
+ cookbook["all_files"].each do |file|
+ if file.is_a?(Hash) && file.has_key?("checksum")
+ file["url"] ||= endpoint.build_uri(base_uri, org_prefix + ["file_store", "checksums", file["checksum"]])
+ end
+ end
+
+ # down convert to old style manifest, ensuring we don't send all_files on the wire and that we correctly divine segments
+ # any file that's not in an old segment is just dropped on the floor.
+ if api_version < 2
+
+ # the spec appears to think we should send empty arrays for each segment, so let's do that
+ COOKBOOK_SEGMENTS.each { |seg| cookbook[seg] ||= [] }
+
+ cookbook["all_files"].each do |file|
+ segment, name = file["name"].split("/")
+
+ # root_files have no segment prepended
+ if name.nil?
+ name = segment
+ segment = "root_files"
end
+
+ file.delete("full_path")
+ next unless COOKBOOK_SEGMENTS.include? segment
+ file["name"] = name
+ cookbook[segment] << file
end
+ cookbook.delete("all_files")
end
end
+
cookbook["name"] ||= "#{name}-#{version}"
# TODO it feels wrong, but the real chef server doesn't expand 'version', so we don't either.