Created
October 21, 2014 22:38
-
-
Save dgoodlad/34f429d1b84a471933d3 to your computer and use it in GitHub Desktop.
Boxen script/sync
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
group :development do | |
# Replace the old aws gem with this one (or newer): | |
gem "aws-sdk-core", "2.0.0.rc15" | |
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/ruby | |
# Sync binary snapshots to S3. | |
require "pathname" | |
require "tempfile" | |
require "json" | |
# Put us where we belong, in the root dir of our boxen repo. | |
Dir.chdir Pathname.new(__FILE__).realpath + "../.." | |
# Make sure our local dependencies are up to date. | |
abort "Sorry, can't bootstrap." unless system "script/bootstrap" | |
# Set up our local configuration, deps, and load path. | |
load "config/basic.rb" | |
require "aws-sdk-core" | |
require "boxen/config" | |
@access_key = ENV["BOXEN_S3_ACCESS_KEY"] | |
@secret_key = ENV["BOXEN_S3_SECRET_KEY"] | |
@bucket_name = ENV["BOXEN_S3_BUCKET"] | |
@region = ENV["BOXEN_S3_REGION"] || "us-east-1" | |
unless @access_key && @secret_key && @bucket_name | |
abort "Please set the BOXEN_S3_{ACCESS_KEY,SECRET_KEY,BUCKET} env vars." | |
end | |
def os | |
@os ||= `sw_vers -productVersion`.strip.split(".")[0..1].join(".") | |
end | |
def s3 | |
@s3 ||= Aws::S3::Client.new( | |
access_key_id: @access_key, | |
secret_access_key: @secret_key, | |
region: @region | |
) | |
end | |
def config | |
@config ||= Boxen::Config.load | |
end | |
def object_exists?(key) | |
puts "Testing for #{key}" | |
begin | |
s3.head_object(bucket: @bucket_name, key: key) | |
rescue Aws::S3::Errors::NoSuchKey, Aws::S3::Errors::NotFound | |
# aws-sdk-core documentation claims that head_object will raise | |
# NoSuchKey, but it seems to raise NotFound. We'll catch both for | |
# now, as I suspect later versions will fix this | |
false | |
end | |
end | |
def sync_brew(name, version) | |
cellar = "#{config.homedir}/homebrew/Cellar" | |
dir = "#{name}/#{version}" | |
receipt = IO.read "#{cellar}/#{dir}/INSTALL_RECEIPT.json" | |
json = JSON.parse receipt | |
unless json["built_as_bottle"] | |
puts "Skipping #{name} #{version}: not built as a bottle" | |
puts "Please set the HOMEBREW_BUILD_BOTTLE env var and reinstall." | |
return | |
end | |
path = "homebrew/#{os}/#{name}-#{version}.tar.bz2" | |
return if object_exists?(path) | |
tempfile = Tempfile.new "homebrew" | |
begin | |
printf "Snapshotting #{name} #{version}... " | |
$stdout.flush | |
Dir.chdir(cellar) do | |
system "tar", "-cjf", tempfile.path, dir | |
puts "done." | |
end | |
printf "Shipping #{name} #{version} to S3... " | |
$stdout.flush | |
File.open(tempfile, "r") do |tarball| | |
puts "s3.put_object(#{{bucket: @bucket_name, key: path, acl: "public-read", body: tarball}.inspect})" | |
s3.put_object(bucket: @bucket_name, key: path, acl: "public-read", body: tarball) | |
end | |
puts "done." | |
ensure | |
tempfile.unlink | |
end | |
end | |
def sync_ruby(version) | |
s3_key = "rubies/Darwin/#{os}/#{version}.tar.bz2" | |
tempfile = Tempfile.new "boxen-ruby" | |
return if object_exists?(s3_key) | |
printf "Snapshotting ruby #{version}... " | |
$stdout.flush | |
Dir.chdir("/opt/rubies") do | |
system "tar", "-cjf", tempfile.path, version | |
end | |
puts "done." | |
printf "Shipping ruby #{version} to S3... " | |
$stdout.flush | |
File.open(tempfile, "r") do |tarball| | |
puts "s3.put_object(#{{bucket: @bucket_name, key: s3_key, acl: "public-read", body: tarball}.inspect})" | |
s3.put_object(bucket: @bucket_name, key: s3_key, acl: "public-read", body: tarball) | |
end | |
puts "done." | |
end | |
def sync_homebrew_packages | |
Dir.chdir "#{config.homedir}/homebrew/Cellar" do | |
Dir["*/*"].each do |dir| | |
name, version = File.split dir | |
sync_brew name, version | |
end | |
end | |
end | |
def sync_rubies | |
Dir.chdir "/opt/rubies" do | |
Dir["*"].each do |dir| | |
next if File.symlink? dir | |
sync_ruby File.split(dir).last | |
end | |
end | |
end | |
if ARGV.include? "--help" or ARGV.include? "-h" | |
$stderr.puts "Usage: #{$0} [-h|--help] [1.9.3-p448] [emacs/24.3-boxen2]" | |
$stderr.puts | |
$stderr.puts "When no arguments are specified, sync everything. You can alternatively" | |
$stderr.puts "sync a single package by either specifying a ruby version (eg `1.9.3-p448`)" | |
$stderr.puts "or a specific homebrew package (eg `emacs/24.3-boxen2`)." | |
exit 1 | |
elsif ARGV[0].nil? | |
# sync everything | |
sync_homebrew_packages | |
sync_rubies | |
else | |
package, version = ARGV[0].split("/") | |
if version | |
sync_brew package, version | |
else | |
sync_ruby package | |
end | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment