Cory O'Daniel – These are just words Software development, thoughts, and randomness

30Dec/090

Deploying apps stored in Git to Rightscale – easy peasy (Git archive to S3, nothing but net)

Since I started using Rightscale for all my application needs I've found that I don't need things like Capistrano, Chef, or WarningShot. Rightscale has a really cool feature called "Rightscripts" that let you apply little snippets to a server at boot time, any time or decommission time.

Using Rightscripts (which I'm going to start sharing on my blog soon) I can apply a bunch of snippets to a server instance, and it essentially does all the 'dependency' resolution that people put together with things like those mentioned above.

I have a script called "deploy_vokle" which gets a tarball, unpacks it, does testing on it then boots up the server if the test pass. The one thing I was missing was how to get my code from git to my servers without my servers having a github account. Solution - Git archive the revision I want to release, send it to S3 and let my new servers pick it up at boot-time. First install the AWS gem.

1
2
3
4
# First you need aws rubygem.
gem install aws-s3
export AS3_ACCESS_KEY=YOUR_KEY_HERE
export AS3_SECRET_KEY=YOUR_SECRET_HERE

Then, put this script in a file called s3packager.rb and make it executable:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
require 'rubygems'
require 'aws/s3'
 
AWS::S3::Base.establish_connection!(
  :access_key_id     => ENV['AS3_ACCESS_KEY'],
  :secret_access_key => ENV['AS3_SECRET_KEY']
)
 
def git_archive(revision='HEAD', filename = nil, format='tar')
  filename ||= revision
 
  if format == 'tar'
    filename = "#{filename}.tar.gz"
  else
    filename = "#{filename}.zip"
  end
 
  `git archive --format=#{format} #{revision} | gzip > #{filename}`
  if $? == 0
    filename 
  else
    return false
  end
end
 
def s3put(filename, opts={})
  deploy_label = filename
  backup_label = "#{$REVISION}-#{filename}"
 
  file_ref = File.read File.expand_path(filename)
 
  # Push the package twice, once with the revision in the name, and once as the intended package
  #   acts as a sort of back up of what has been pushed...
  [deploy_label, backup_label].each do |file_label|
    begin
      puts "Putting to S3: #{file_label}"
 
      AWS::S3::S3Object.store(
        file_label,
        file_ref,
        $BUCKET_NAME,
        :content_type => (file_label =~ /\.tar\.gz$/i ? 'application/x-gzip' : 'application/x-zip'),
        :access       => :private
      )
    rescue Exception => ex
      puts ex.message
      return false
    end
  end
 
  return true
end
 
 
def s3get(filename)
  local_filename = File.expand_path(filename)
 
  File.open(local_filename, 'w') do |new_file|
    AWS::S3::S3Object.stream(filename,$BUCKET_NAME) do |chunk|
      new_file.write chunk
    end
  end
 
  return File.exist?(filename)
end
 
if ARGV.index('-h') || ARGV.empty?
  puts "============================================================================"
  puts "Packages a git revision w/o git data to Amazon S3"
  puts "package.rb --bucket [BUCKET_NAME] --revision [REVISION|HEAD] --FILENAME [production|experimental|USER_DEF]"
  puts "To see revisions do 'git log'"
  puts "============================================================================"
  exit(0)
end
 
$REVISION = ARGV[ARGV.index('--revision') + 1] rescue nil
$OUT_NAME = ARGV[ARGV.index('--filename') + 1] rescue nil
$BUCKET_NAME   = ARGV[ARGV.index('--bucket') + 1] rescue nil
 
begin
  AWS::S3::Bucket.find $BUCKET_NAME
rescue Exception => ex
  puts "Could not fetch bucket #{$BUCKET_NAME}, did you set $AS3_ACCESS_KEY & $AS3_SECRET_KEY?"
  exit(1)  
end
 
if $REVISION.nil?
  puts "--revision is required"
  exit 3
end
 
arch_file = git_archive($REVISION, $OUT_NAME)
 
if arch_file && s3put(arch_file)
  puts "SUCCESS"
else
  puts "FAILED"
end
# First

Make it executable!

1
chmod +x s3packager.rb

Wanna use it? When ever you want to release something from git:

1
s3packager.rb --revision YOUR_GIT_LOG_REVISION_ID --bucket YOUR_AMAZON_BUCKET --filename THE_NAME_OF_THE_FILE_YOUR_SERVER_IS_LOOKING_FOR

If you need help:

1
s3packager.rb -h

Yay, your up in the clouds. Congrats.

Post to Twitter Post to Digg Post to Facebook Post to Reddit Post to StumbleUpon

Comments (0) Trackbacks (0)

No comments yet.


Leave a comment


No trackbacks yet.