Skip to content

Instantly share code, notes, and snippets.

@dgoodlad
Created October 21, 2014 22:38
Show Gist options
  • Save dgoodlad/34f429d1b84a471933d3 to your computer and use it in GitHub Desktop.
Save dgoodlad/34f429d1b84a471933d3 to your computer and use it in GitHub Desktop.
Boxen script/sync
group :development do
# Replace the old aws gem with this one (or newer):
gem "aws-sdk-core", "2.0.0.rc15"
end
#!/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