Class: Chef::CookbookLoader

Inherits:
Object
  • Object
show all
Includes:
Enumerable
Defined in:
lib/chef/cookbook_loader.rb

Overview

This class is used by knife, cheffs and legacy chef-solo modes. It is not used by the server mode of chef-client or zolo/zero modes.

This class implements orchestration around producing a single cookbook_version for a cookbook or loading a Mash of all cookbook_versions, using the cookbook_version_loader class, and doing lazy-access and memoization to only load each cookbook once on demand.

This implements a key-value style each which makes it appear to be a Hash of String => CookbookVersion pairs where the String is the cookbook name. The use of Enumerable combined with the Hash-style each is likely not entirely sane.

This object is also passed and injected into the CookbookCollection object where it is converted to a Mash that looks almost exactly like the cookbook_by_name Mash in this object.

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(*repo_paths) ⇒ CookbookLoader

Returns a new instance of CookbookLoader.

Parameters:

  • repo_paths (Array<String>)

    the array of repo paths containing cookbook dirs

Raises:

  • (ArgumentError)

51
52
53
54
# File 'lib/chef/cookbook_loader.rb', line 51

def initialize(*repo_paths)
  @repo_paths = repo_paths.flatten.compact.map { |p| File.expand_path(p) }
  raise ArgumentError, "You must specify at least one cookbook repo path" if @repo_paths.empty?
end

Instance Attribute Details

#repo_pathsArray<String> (readonly)

Returns the array of repo paths containing cookbook dirs.

Returns:

  • (Array<String>)

    the array of repo paths containing cookbook dirs


45
46
47
# File 'lib/chef/cookbook_loader.rb', line 45

def repo_paths
  @repo_paths
end

Class Method Details

.copy_to_tmp_dir_from_array(cookbooks) ⇒ Object

This method creates tmp directory and copies all cookbooks into it and creates cookbook loader object which points to tmp directory


139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
# File 'lib/chef/cookbook_loader.rb', line 139

def self.copy_to_tmp_dir_from_array(cookbooks)
  Dir.mktmpdir do |tmp_dir|
    cookbooks.each do |cookbook|
      checksums_to_on_disk_paths = cookbook.checksums
      cookbook.each_file do |manifest_record|
        path_in_cookbook = manifest_record[:path]
        on_disk_path = checksums_to_on_disk_paths[manifest_record[:checksum]]
        dest = File.join(tmp_dir, cookbook.name.to_s, path_in_cookbook)
        FileUtils.mkdir_p(File.dirname(dest))
        FileUtils.cp_r(on_disk_path, dest)
      end
    end
    tmp_cookbook_loader ||= begin
      Chef::Cookbook::FileVendor.fetch_from_disk(tmp_dir)
      CookbookLoader.new(tmp_dir)
    end
    yield tmp_cookbook_loader
  end
end

Instance Method Details

#[](cookbook) ⇒ Object Also known as: fetch


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

def [](cookbook)
  load_cookbook(cookbook)
end

#compile_metadataObject

generates metadata.json adds it in the manifest


160
161
162
163
164
165
166
167
168
# File 'lib/chef/cookbook_loader.rb', line 160

def 
  each do |cookbook_name, cookbook|
     = cookbook.
    if 
      cookbook.all_files << 
      cookbook.cookbook_manifest.send(:generate_manifest)
    end
  end
end

#cookbook_namesObject


130
131
132
# File 'lib/chef/cookbook_loader.rb', line 130

def cookbook_names
  cookbooks_by_name.keys.sort
end

#cookbooks_by_nameMash<String, Chef::CookbookVersion>

The primary function of this class is to build this Mash mapping cookbook names as a string to the CookbookVersion objects for them. Callers must call "load_cookbooks" first.


60
61
62
# File 'lib/chef/cookbook_loader.rb', line 60

def cookbooks_by_name
  @cookbooks_by_name ||= Mash.new
end

#eachObject


116
117
118
119
120
# File 'lib/chef/cookbook_loader.rb', line 116

def each
  cookbooks_by_name.keys.sort_by(&:to_s).each do |cname|
    yield(cname, cookbooks_by_name[cname])
  end
end

#each_key(&block) ⇒ Object


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

def each_key(&block)
  cookbook_names.each(&block)
end

#each_value(&block) ⇒ Object


126
127
128
# File 'lib/chef/cookbook_loader.rb', line 126

def each_value(&block)
  values.each(&block)
end

#freeze_versionsObject

freeze versions of all the cookbooks


171
172
173
174
175
# File 'lib/chef/cookbook_loader.rb', line 171

def freeze_versions
  each do |cookbook_name, cookbook|
    cookbook.freeze_version
  end
end

#has_key?(cookbook_name) ⇒ Boolean Also known as: cookbook_exists?, key?

Returns:

  • (Boolean)

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

def has_key?(cookbook_name)
  not self[cookbook_name.to_sym].nil?
end

#load_cookbook(cookbook_name) ⇒ Chef::CookbookVersion

Loads a single cookbook by its name.

Parameters:

Returns:


86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
# File 'lib/chef/cookbook_loader.rb', line 86

def load_cookbook(cookbook_name)
  unless cookbook_version_loaders.key?(cookbook_name)
    raise Exceptions::CookbookNotFoundInRepo, "Cannot find a cookbook named #{cookbook_name}; did you forget to add metadata to a cookbook? (https://docs.chef.io/config_rb_metadata/)"
  end

  return cookbooks_by_name[cookbook_name] if cookbooks_by_name.key?(cookbook_name)

  loader = cookbook_version_loaders[cookbook_name]

  loader.load!

  cookbook_version = loader.cookbook_version
  cookbooks_by_name[cookbook_name] = cookbook_version
  [cookbook_name] = cookbook_version. unless cookbook_version.nil?
  cookbook_version
end

#load_cookbooksMash<String, Chef::CookbookVersion>

Loads all cookbooks across all repo_paths

Returns:


75
76
77
78
79
80
# File 'lib/chef/cookbook_loader.rb', line 75

def load_cookbooks
  cookbook_version_loaders.each_key do |cookbook_name|
    load_cookbook(cookbook_name)
  end
  cookbooks_by_name
end

#metadataMash<String, Chef::Cookbook::Metadata>

This class also builds a mapping of cookbook names to their Metadata objects. Callers must call "load_cookbooks" first.


68
69
70
# File 'lib/chef/cookbook_loader.rb', line 68

def 
  @metadata ||= Mash.new
end

#valuesObject Also known as: cookbooks


134
135
136
# File 'lib/chef/cookbook_loader.rb', line 134

def values
  cookbooks_by_name.values
end