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.

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_h 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 interface 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.



57
58
59
60
61
62
# File 'lib/chef/cookbook_manifest.rb', line 57

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.



32
33
34
# File 'lib/chef/cookbook_manifest.rb', line 32

def cookbook_version
  @cookbook_version
end

Instance Method Details

#add_files_to_manifest(files) ⇒ Object

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.

takes a list of hashes



167
168
169
170
171
# File 'lib/chef/cookbook_manifest.rb', line 167

def add_files_to_manifest(files)
  manifest[:all_files].concat(Array(files))
  @checksums = extract_checksums_from_manifest(@manifest)
  @manifest_records_by_path = extract_manifest_records_by_path(@manifest)
end

#by_parent_directoryObject



193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
# File 'lib/chef/cookbook_manifest.rb', line 193

def by_parent_directory
  @by_parent_directory ||=
    manifest[:all_files].inject({}) do |memo, file|
      parts = file[:name].split("/")
      parent = if parts.length == 1
                 "root_files"
               else
                 parts[0]
               end

      memo[parent] ||= []
      memo[parent] << file
      memo
    end
end

#checksumsObject



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

def checksums
  @manifest || generate_manifest
  @checksums
end

#each_file(excluded_parts: [], &block) ⇒ Object



182
183
184
185
186
187
188
189
190
191
# File 'lib/chef/cookbook_manifest.rb', line 182

def each_file(excluded_parts: [], &block)
  excluded_parts = Array(excluded_parts).map(&:to_s)

  manifest[:all_files].each do |file|
    seg = file[:name].split("/")[0]
    next if excluded_parts.include?(seg)

    yield file if block_given?
  end
end

#files_for(part) ⇒ Object



173
174
175
176
177
178
179
180
# File 'lib/chef/cookbook_manifest.rb', line 173

def files_for(part)
  return root_files if part.to_s == "root_files"

  part_match = "#{part}/"
  manifest[:all_files].select do |file|
    file[:name].start_with?(part_match)
  end
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).



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

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
}


103
104
105
106
# File 'lib/chef/cookbook_manifest.rb', line 103

def manifest
  @manifest || generate_manifest
  @manifest
end

#manifest_records_by_pathObject



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

def manifest_records_by_path
  @manifest || generate_manifest
  @manifest_records_by_path
end

#named_cookbook_urlObject



145
146
147
# File 'lib/chef/cookbook_manifest.rb', line 145

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

#policy_mode?Boolean

Returns:

  • (Boolean)


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

def policy_mode?
  @policy_mode
end

#reset!Object

Resets all lazily computed values.



65
66
67
68
69
70
# File 'lib/chef/cookbook_manifest.rb', line 65

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

#root_filesObject



209
210
211
212
213
214
# File 'lib/chef/cookbook_manifest.rb', line 209

def root_files
  manifest[:all_files].select do |file|
    segment, name = file[:name].split("/")
    name.nil? || segment == "root_files"
  end
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.



137
138
139
140
141
142
143
# File 'lib/chef/cookbook_manifest.rb', line 137

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

#to_hObject Also known as: to_hash



122
123
124
# File 'lib/chef/cookbook_manifest.rb', line 122

def to_h
  CookbookManifestVersions.to_h(self)
end

#to_json(*a) ⇒ Object



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

def to_json(*a)
  result = to_h
  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.



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

def update_from(new_manifest)
  @manifest = Chef::CookbookManifestVersions.from_hash(new_manifest)
  @checksums = extract_checksums_from_manifest(@manifest)
  @manifest_records_by_path = extract_manifest_records_by_path(@manifest)
end