Skip to content

Instantly share code, notes, and snippets.

@apsoto
Forked from mdkent/update_cache.rake
Created August 4, 2010 20:53
Show Gist options
  • Save apsoto/508778 to your computer and use it in GitHub Desktop.
Save apsoto/508778 to your computer and use it in GitHub Desktop.
Sync Chef Cookbooks and Roles with Server
#
# Tasks to keep your repository in sync with your Chef Server
#
# Author:: Matthew Kent (<[email protected]>)
# Copyright:: Copyright (c) 2010 Matthew Kent
# License:: Apache License, Version 2.0
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
require 'moneta'
require 'moneta/basic_file'
REPO_ROOT = File.expand_path(File.join(File.dirname(__FILE__), '..'))
COOKBOOK_CACHE = File.join(REPO_ROOT, ".rake_update_cache/cookbooks")
COOKBOOK_SEARCH = File.join(REPO_ROOT, "{cookbooks,site-cookbooks}/**/*")
ROLES_CACHE = File.join(REPO_ROOT, ".rake_update_cache/roles")
ROLES_SEARCH = File.join(REPO_ROOT, "roles/*.rb")
desc "Upload cookbooks altered since last sync_cookbooks"
task :sync_cookbooks do
ran_once = false
# gather cookbooks => files associations
cookbooks = {}
Dir.glob(COOKBOOK_SEARCH).each do |file|
if File.file?(file)
if file =~ %r{#{REPO_ROOT}/(.*?/(.*?)/.*)}
relative = $1
cookbook = $2
if cookbooks[cookbook]
cookbooks[cookbook] << relative
else
cookbooks[cookbook] = [ relative ]
end
end
end
end
cache = Moneta::BasicFile.new(:path => COOKBOOK_CACHE)
cookbooks.each do |cookbook, files|
update = false
knife_has_run = false
files.each do |file|
mtime = File.stat(File.expand_path(File.join(REPO_ROOT, file))).mtime
key = "cookbook-#{file.gsub(/(#{File::SEPARATOR}|\.)/, '-')}"
if cache[key]
if mtime > cache[key]
puts "cookbook[#{cookbook}] #{file} has been updated"
update = true
end
else
puts "cookbook[#{cookbook}] #{file} is new"
update = true
end
if update
# We only run the upload once as it's per cookbook but prior to setting
# the cache key, so if it bails out we run correctly next time
unless knife_has_run
sh "knife cookbook upload #{cookbook}"
knife_has_run = true
ran_once = true
end
cache[key] = mtime
end
end
end
unless ran_once
puts "No new or updated cookbooks"
end
end
desc "Update roles altered since last sync_roles"
task :sync_roles do
ran_once = false
current_files = []
Dir.glob(ROLES_SEARCH).each do |file|
if File.file?(file)
if file =~ %r{#{REPO_ROOT}/(.*)}
current_files << $1
end
end
end
cache = Moneta::BasicFile.new(:path => ROLES_CACHE)
current_files.each do |file|
mtime = File.stat(File.expand_path(File.join(REPO_ROOT, file))).mtime
key = "role-#{file.gsub(/(#{File::SEPARATOR}|\.)/, '-')}"
if cache[key]
if mtime > cache[key]
puts "role[#{file}] has been updated"
update = true
end
else
puts "role[#{file}] is new"
update = true
end
if update
sh "knife role from file #{file}"
cache[key] = mtime
ran_once = true
end
end
unless ran_once
puts "No new or updated roles"
end
end
desc "Sync updated cookbooks and roles"
task :sync => [ :sync_cookbooks, :sync_roles ]
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment