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_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.


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


165
166
167
168
169
# File 'lib/chef/cookbook_manifest.rb', line 165

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


189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
# File 'lib/chef/cookbook_manifest.rb', line 189

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


179
180
181
182
183
184
185
186
187
# File 'lib/chef/cookbook_manifest.rb', line 179

def each_file(excluded_parts: [], &block)
  excluded_parts = Array(excluded_parts).map { |p| p.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


171
172
173
174
175
176
177
# File 'lib/chef/cookbook_manifest.rb', line 171

def files_for(part)
  return root_files if part.to_s == "root_files"
  manifest[:all_files].select do |file|
    seg = file[:name].split("/")[0]
    part.to_s == seg
  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).


150
151
152
# File 'lib/chef/cookbook_manifest.rb', line 150

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       => ,        # 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


143
144
145
# File 'lib/chef/cookbook_manifest.rb', line 143

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

#policy_mode?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


205
206
207
208
209
# File 'lib/chef/cookbook_manifest.rb', line 205

def root_files
  manifest[:all_files].select do |file|
    file[:name].split("/").length == 1
  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.


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

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

#to_hashObject


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

def to_hash
  CookbookManifestVersions.to_hash(self)
end

#to_json(*a) ⇒ Object


126
127
128
129
130
# File 'lib/chef/cookbook_manifest.rb', line 126

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.


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

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