Class: Chef::CookbookManifest

Inherits:
Object
  • Object
show all
Extended by:
Forwardable
Defined in:
lib/chef/cookbook_manifest.rb

Overview

Handles the details of representing a cookbook in JSON form for uploading to a Chef Server.

Constant Summary collapse

COOKBOOK_SEGMENTS =

Duplicates the same constant in CookbookVersion. We cannot remove it there because it is treated by other code as part of CookbookVersion’s public API (also used in some deprecated methods).

[ :resources, :providers, :recipes, :definitions, :libraries, :attributes, :files, :templates, :root_files ].freeze

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(cookbook_version, policy_mode: false) ⇒ CookbookManifest

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Create a new CookbookManifest object for the given ‘cookbook_version`. You can subsequently call #to_hash to get a Hash representation of the cookbook_version in the “manifest” format, or #to_json to get a JSON representation of the cookbook_version.

The inferface for this behavior is expected to change as we implement new manifest formats. The entire class should be considered a private API for now.

Parameters:

  • policy_mode (Boolean) (defaults to: false)

    whether to convert cookbooks to Hash/JSON in the format used by the ‘cookbook_artifacts` endpoint (for policyfiles). Setting this option also changes the behavior of #save_url and #force_save_url such that CookbookVersions will be uploaded to the new `cookbook_artifacts` API. This endpoint is currently under active development and the format is expected to change frequently, therefore the result of #manifest, #to_hash, and #to_json will not be stable when `policy_mode` is enabled.



63
64
65
66
67
68
# File 'lib/chef/cookbook_manifest.rb', line 63

def initialize(cookbook_version, policy_mode: false)
  @cookbook_version = cookbook_version
  @policy_mode = !!policy_mode

  reset!
end

Instance Attribute Details

#cookbook_versionObject (readonly)

Returns the value of attribute cookbook_version.



34
35
36
# File 'lib/chef/cookbook_manifest.rb', line 34

def cookbook_version
  @cookbook_version
end

Instance Method Details

#checksumsObject



114
115
116
117
# File 'lib/chef/cookbook_manifest.rb', line 114

def checksums
  @manifest || generate_manifest
  @checksums
end

#force_save_urlObject

Adds the ‘force=true` parameter to the upload URL. This allows the user to overwrite a frozen cookbook (a PUT against the normal #save_url raises a 409 Conflict in this case).



159
160
161
# File 'lib/chef/cookbook_manifest.rb', line 159

def force_save_url
  "#{save_url}?force=true"
end

#manifestObject

Returns a ‘manifest’ data structure that can be uploaded to a Chef Server.

The format is as follows:

{
  :cookbook_name  => name,            # String
  :metadata       => metadata,        # Chef::Cookbook::Metadata
  :version        => version,         # Chef::Version
  :name           => full_name,       # String of "#{name}-#{version}"

  :recipes        => Array<FileSpec>,
  :definitions    => Array<FileSpec>,
  :libraries      => Array<FileSpec>,
  :attributes     => Array<FileSpec>,
  :files          => Array<FileSpec>,
  :templates      => Array<FileSpec>,
  :resources      => Array<FileSpec>,
  :providers      => Array<FileSpec>,
  :root_files     => Array<FileSpec>
}

Where a ‘FileSpec` is a Hash of the form:

{
  :name         => file_name,
  :path         => path,
  :checksum     => csum,
  :specificity  => specificity
}


109
110
111
112
# File 'lib/chef/cookbook_manifest.rb', line 109

def manifest
  @manifest || generate_manifest
  @manifest
end

#manifest_records_by_pathObject



119
120
121
122
# File 'lib/chef/cookbook_manifest.rb', line 119

def manifest_records_by_path
  @manifest || generate_manifest
  @manifest_records_by_path
end

#named_cookbook_urlObject



152
153
154
# File 'lib/chef/cookbook_manifest.rb', line 152

def named_cookbook_url
  "#{cookbook_url_path}/#{name}"
end

#policy_mode?Boolean

Returns:

  • (Boolean)


124
125
126
# File 'lib/chef/cookbook_manifest.rb', line 124

def policy_mode?
  @policy_mode
end

#reset!Object

Resets all lazily computed values.



71
72
73
74
75
76
# File 'lib/chef/cookbook_manifest.rb', line 71

def reset!
  @manifest = nil
  @checksums = nil
  @manifest_records_by_path = nil
  true
end

#save_urlObject

Return the URL to save (PUT) this object to the server via the REST api. If there is an existing document on the server and it is marked frozen, a PUT will result in a 409 Conflict.



144
145
146
147
148
149
150
# File 'lib/chef/cookbook_manifest.rb', line 144

def save_url
  if policy_mode?
    "#{named_cookbook_url}/#{identifier}"
  else
    "#{named_cookbook_url}/#{version}"
  end
end

#to_hashObject



128
129
130
131
132
133
# File 'lib/chef/cookbook_manifest.rb', line 128

def to_hash
  result = manifest.dup
  result["frozen?"] = frozen_version?
  result["chef_type"] = "cookbook_version"
  result.to_hash
end

#to_json(*a) ⇒ Object



135
136
137
138
139
# File 'lib/chef/cookbook_manifest.rb', line 135

def to_json(*a)
  result = to_hash
  result["json_class"] = "Chef::CookbookVersion"
  Chef::JSONCompat.to_json(result, *a)
end

#update_from(new_manifest) ⇒ Object

Update this CookbookManifest from the contents of another manifest, and make the corresponding changes to the cookbook_version object. Required to provide backward compatibility with CookbookVersion#manifest= method.



166
167
168
169
170
171
172
173
174
175
176
177
# File 'lib/chef/cookbook_manifest.rb', line 166

def update_from(new_manifest)
  @manifest = Mash.new new_manifest
  @checksums = extract_checksums_from_manifest(@manifest)
  @manifest_records_by_path = extract_manifest_records_by_path(@manifest)

  COOKBOOK_SEGMENTS.each do |segment|
    next unless @manifest.has_key?(segment)
    filenames = @manifest[segment].map { |manifest_record| manifest_record["name"] }

    cookbook_version.replace_segment_filenames(segment, filenames)
  end
end