Skip to content

Instantly share code, notes, and snippets.

@rchampourlier
Created August 9, 2012 10:20
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save rchampourlier/3303042 to your computer and use it in GitHub Desktop.
Save rchampourlier/3303042 to your computer and use it in GitHub Desktop.
A Ruby script to download cookbooks from Opscode Community repo or Git using a YAML file to describe required cookbooks
# Script to ease downloading of cookbooks from Opscode repo and Github
# by using a YAML file to describe the necessary cookbooks.
require 'yaml'
require 'fileutils'
script_dir = File.expand_path('.')
cookbooks_dir = File.join(script_dir, 'cookbooks')
archives_dir = File.join(script_dir, 'cookbooks_archives')
# Constants
config_file_name = 'ingredients.yml'
config_file_path = config_file_name
# Code
if File.exists?(config_file_path)
begin
config = YAML.load(File.open(config_file_path).read)
rescue Psych::SyntaxError => e
raise "#{config_file_name} has incorrect syntax >> #{e}"
end
else
raise "#{config_file_name} is not present"
end
cookbooks = config['cookbooks']
# Downloading the changed cookbooks
pending_archives = []
FileUtils::makedirs(archives_dir)
Dir.chdir(archives_dir)
# From Opscode community repo
cookbooks['opscode'].each do |name, version|
archive_name = "#{name}-#{version}.tar.gz"
unless File.exists?(archive_name)
response = %x{knife cookbook site download #{name} #{version} 2>&1}
case response
when %r{ERROR: The object you are looking for could not be found}
raise "Cookbook #{name} #{version} could not be found in Opscode Community repository (using knife)"
when %r{ERROR}
raise "Error: an error append when trying to download cookbook #{name} #{version} (using knife)"
else
puts "Downloaded: #{archive_name}"
end
else
puts "Ignored: #{archive_name} (already downloaded)"
end
pending_archives << archive_name
end
# From git
cookbooks['git'].each do |name, hash|
# hash => { :repo => '...', :ref => '...' }
archive_name = "#{hash['repo'][%r{https://github.com/([^/]*)}, 1]}_#{name}-#{hash['ref']}.tar.gz"
tarball_url = "#{hash['repo']}/tarball/#{hash['ref']}"
unless File.exists?(archive_name)
response = %x{curl -L #{tarball_url} -o #{archive_name} 2>&1}
case response
when %r{Could not resolve host}
raise "Invalid repo URL: #{hash['repo']}"
else
begin
if File.open(archive_name).read =~ %r{Not found}
raise "Repo not found for this URL: #{tarball_url}"
end
rescue ArgumentError
# This is OK, we're trying to read as UTF a compressed tarball
end
puts "Downloaded: #{archive_name}"
end
else
puts "Ignored: #{archive_name} (already downloaded)"
end
pending_archives << archive_name
end
Dir.chdir(script_dir)
# Clear current cookbooks
%x[rm -Rf cookbooks]
FileUtils::makedirs('cookbooks')
Dir.chdir(cookbooks_dir)
pending_archives.each do |archive_name|
%x{tar zxf #{File.join(archives_dir, archive_name)}}
puts "Extracted: #{archive_name}"
end
# Renaming cookbooks from git
cookbooks['git'].each do |name, hash|
%x{mv *#{name}* #{name}}
end
cookbooks:
opscode:
apt: '1.4.4'
build-essential: '1.1.0'
database: '1.2.0'
dmg: '1.0.0'
git: '1.0.0'
mongodb: '0.11.0'
openssl: '1.0.0'
runit: '0.15.0'
yum: '0.8.0'
git:
ruby_build:
repo: 'https://github.com/fnichol/chef-ruby_build'
ref: 'v0.6.2'
rbenv:
repo: 'https://github.com/fnichol/chef-rbenv'
ref: 'v0.6.8'
ruby_stack:
repo: 'https://github.com/rchampourlier/chef_ruby_stack'
ref: 'master'
postgresql:
repo: 'https://github.com/opscode-cookbooks/postgresql'
ref: 'master'
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment