Class: Chef::CookbookSynchronizer
- Defined in:
- lib/chef/cookbook/synchronizer.rb
Overview
Synchronizes the locally cached copies of cookbooks with the files on the server.
Constant Summary collapse
- EAGER_SEGMENTS =
Chef::CookbookVersion::COOKBOOK_SEGMENTS.dup
Instance Method Summary collapse
- #cache ⇒ Object
- #cached_copy_up_to_date?(local_path, expected_checksum) ⇒ Boolean
-
#clear_obsoleted_cookbooks ⇒ Object
Iterates over cached cookbooks’ files, removing files belonging to cookbooks that don’t appear in
cookbook_hash
. - #cookbook_count ⇒ Object
- #cookbook_names ⇒ Object
- #cookbooks ⇒ Object
-
#download_file(url, destination) ⇒ Object
Unconditionally download the file from the given URL.
- #have_cookbook?(cookbook_name) ⇒ Boolean
-
#initialize(cookbooks_by_name, events) ⇒ CookbookSynchronizer
constructor
A new instance of CookbookSynchronizer.
-
#mark_cached_file_valid(cache_filename) ⇒ Object
Marks the given file as valid (non-stale).
- #server_api ⇒ Object
-
#sync_cookbook(cookbook) ⇒ Object
Sync the eagerly loaded files contained by
cookbook
. -
#sync_cookbooks ⇒ Object
Synchronizes all the cookbooks from the chef-server.
-
#sync_file_in_cookbook(cookbook, file_manifest) ⇒ Object
Sync an individual file if needed.
Constructor Details
#initialize(cookbooks_by_name, events) ⇒ CookbookSynchronizer
Returns a new instance of CookbookSynchronizer.
64 65 66 |
# File 'lib/chef/cookbook/synchronizer.rb', line 64 def initialize(cookbooks_by_name, events) @cookbooks_by_name, @events = cookbooks_by_name, events end |
Instance Method Details
#cache ⇒ Object
68 69 70 |
# File 'lib/chef/cookbook/synchronizer.rb', line 68 def cache Chef::FileCache end |
#cached_copy_up_to_date?(local_path, expected_checksum) ⇒ Boolean
187 188 189 190 191 192 193 194 |
# File 'lib/chef/cookbook/synchronizer.rb', line 187 def cached_copy_up_to_date?(local_path, expected_checksum) if cache.has_key?(local_path) current_checksum = CookbookVersion.checksum_cookbook_file(cache.load(local_path, false)) expected_checksum == current_checksum else false end end |
#clear_obsoleted_cookbooks ⇒ Object
Iterates over cached cookbooks’ files, removing files belonging to cookbooks that don’t appear in cookbook_hash
116 117 118 119 120 121 122 123 124 125 126 127 128 |
# File 'lib/chef/cookbook/synchronizer.rb', line 116 def clear_obsoleted_cookbooks @events.cookbook_clean_start # Remove all cookbooks no longer relevant to this node cache.find(File.join(%w{cookbooks ** *})).each do |cache_file| cache_file =~ /^cookbooks\/([^\/]+)\// unless have_cookbook?($1) Chef::Log.info("Removing #{cache_file} from the cache; its cookbook is no longer needed on this client.") cache.delete(cache_file) @events.removed_cookbook_file(cache_file) end end @events.cookbook_clean_complete end |
#cookbook_count ⇒ Object
80 81 82 |
# File 'lib/chef/cookbook/synchronizer.rb', line 80 def cookbook_count @cookbooks_by_name.size end |
#cookbook_names ⇒ Object
72 73 74 |
# File 'lib/chef/cookbook/synchronizer.rb', line 72 def cookbook_names @cookbooks_by_name.keys end |
#cookbooks ⇒ Object
76 77 78 |
# File 'lib/chef/cookbook/synchronizer.rb', line 76 def cookbooks @cookbooks_by_name.values end |
#download_file(url, destination) ⇒ Object
Unconditionally download the file from the given URL. File will be downloaded to the path destination
which is relative to the Chef file cache root.
199 200 201 202 203 204 |
# File 'lib/chef/cookbook/synchronizer.rb', line 199 def download_file(url, destination) raw_file = server_api.get_rest(url, true) Chef::Log.info("Storing updated #{destination} in the cache.") cache.move_to(raw_file.path, destination) end |
#have_cookbook?(cookbook_name) ⇒ Boolean
84 85 86 |
# File 'lib/chef/cookbook/synchronizer.rb', line 84 def have_cookbook?(cookbook_name) @cookbooks_by_name.key?(cookbook_name) end |
#mark_cached_file_valid(cache_filename) ⇒ Object
Marks the given file as valid (non-stale).
207 208 209 |
# File 'lib/chef/cookbook/synchronizer.rb', line 207 def mark_cached_file_valid(cache_filename) CookbookCacheCleaner.instance.mark_file_as_valid(cache_filename) end |
#server_api ⇒ Object
211 212 213 |
# File 'lib/chef/cookbook/synchronizer.rb', line 211 def server_api Chef::REST.new(Chef::Config[:chef_server_url]) end |
#sync_cookbook(cookbook) ⇒ Object
Sync the eagerly loaded files contained by cookbook
Arguments
- cookbook<Chef::Cookbook>
-
The cookbook to update
- valid_cache_entries<Hash>
-
Out-param; Added to this hash are the files that
were referred to by this cookbook
136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 |
# File 'lib/chef/cookbook/synchronizer.rb', line 136 def sync_cookbook(cookbook) Chef::Log.debug("Synchronizing cookbook #{cookbook.name}") # files and templates are lazily loaded, and will be done later. EAGER_SEGMENTS.each do |segment| segment_filenames = Array.new cookbook.manifest[segment].each do |manifest_record| cache_filename = sync_file_in_cookbook(cookbook, manifest_record) # make the segment filenames a full path. full_path_cache_filename = cache.load(cache_filename, false) segment_filenames << full_path_cache_filename end # replace segment filenames with a full-path one. if segment.to_sym == :recipes cookbook.recipe_filenames = segment_filenames elsif segment.to_sym == :attributes cookbook.attribute_filenames = segment_filenames else cookbook.segment_filenames(segment).replace(segment_filenames) end end @events.synchronized_cookbook(cookbook.name) end |
#sync_cookbooks ⇒ Object
Synchronizes all the cookbooks from the chef-server. )
Returns
- true
-
Always returns true
92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 |
# File 'lib/chef/cookbook/synchronizer.rb', line 92 def sync_cookbooks Chef::Log.info("Loading cookbooks [#{cookbook_names.sort.join(', ')}]") Chef::Log.debug("Cookbooks detail: #{cookbooks.inspect}") clear_obsoleted_cookbooks @events.cookbook_sync_start(cookbook_count) # Synchronize each of the node's cookbooks, and add to the # valid_cache_entries hash. cookbooks.each do |cookbook| sync_cookbook(cookbook) end rescue Exception => e @events.cookbook_sync_failed(cookbooks, e) raise else @events.cookbook_sync_complete true end |
#sync_file_in_cookbook(cookbook, file_manifest) ⇒ Object
Sync an individual file if needed. If there is an up to date copy locally, nothing is done.
Arguments
- file_manifest:
-
A Hash of the form => ‘relative/path’, “url” => “location to fetch the file”
Returns
Path to the cached file as a String
170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 |
# File 'lib/chef/cookbook/synchronizer.rb', line 170 def sync_file_in_cookbook(cookbook, file_manifest) cache_filename = File.join("cookbooks", cookbook.name, file_manifest['path']) mark_cached_file_valid(cache_filename) # If the checksums are different between on-disk (current) and on-server # (remote, per manifest), do the update. This will also execute if there # is no current checksum. if !cached_copy_up_to_date?(cache_filename, file_manifest['checksum']) download_file(file_manifest['url'], cache_filename) @events.updated_cookbook_file(cookbook.name, cache_filename) else Chef::Log.debug("Not storing #{cache_filename}, as the cache is up to date.") end cache_filename end |