heirloom 0.1.3 → 0.1.4

Sign up to get free protection for your applications and to get access to all the features.
Files changed (46) hide show
  1. data/CHANGELOG +6 -0
  2. data/README.md +0 -1
  3. data/lib/heirloom/acl/s3.rb +10 -8
  4. data/lib/heirloom/artifact.rb +44 -43
  5. data/lib/heirloom/artifact/artifact_authorizer.rb +20 -22
  6. data/lib/heirloom/artifact/artifact_builder.rb +41 -37
  7. data/lib/heirloom/artifact/artifact_destroyer.rb +16 -14
  8. data/lib/heirloom/artifact/artifact_downloader.rb +22 -40
  9. data/lib/heirloom/artifact/artifact_lister.rb +10 -7
  10. data/lib/heirloom/artifact/artifact_reader.rb +17 -20
  11. data/lib/heirloom/artifact/artifact_updater.rb +6 -5
  12. data/lib/heirloom/artifact/artifact_uploader.rb +8 -8
  13. data/lib/heirloom/aws/s3.rb +1 -1
  14. data/lib/heirloom/cli.rb +37 -30
  15. data/lib/heirloom/cli/build.rb +40 -0
  16. data/lib/heirloom/cli/destroy.rb +20 -0
  17. data/lib/heirloom/cli/download.rb +23 -0
  18. data/lib/heirloom/cli/list.rb +17 -0
  19. data/lib/heirloom/cli/show.rb +27 -0
  20. data/lib/heirloom/cli/update.rb +23 -0
  21. data/lib/heirloom/config.rb +11 -6
  22. data/lib/heirloom/destroyer/s3.rb +6 -4
  23. data/lib/heirloom/directory/directory.rb +15 -11
  24. data/lib/heirloom/directory/git_directory.rb +4 -3
  25. data/lib/heirloom/downloader/s3.rb +1 -1
  26. data/lib/heirloom/logger.rb +6 -4
  27. data/lib/heirloom/version.rb +1 -1
  28. data/spec/acl/s3_spec.rb +51 -0
  29. data/spec/artifact/artifact_authorizer_spec.rb +34 -0
  30. data/spec/artifact/artifact_builder_spec.rb +41 -0
  31. data/spec/artifact/artifact_destroyer_spec.rb +45 -0
  32. data/spec/artifact/artifact_downloader_spec.rb +93 -0
  33. data/spec/artifact/artifact_lister_spec.rb +21 -0
  34. data/spec/artifact/artifact_reader_spec.rb +55 -0
  35. data/spec/artifact/artifact_updater_spec.rb +16 -0
  36. data/spec/artifact/artifact_uploader_spec.rb +16 -0
  37. data/spec/artifact_spec.rb +69 -19
  38. data/spec/aws/s3_spec.rb +55 -0
  39. data/spec/aws/simpledb_spec.rb +50 -0
  40. data/spec/config_spec.rb +32 -3
  41. data/spec/destroyer/s3_spec.rb +21 -0
  42. data/spec/directory/directory_spec.rb +26 -0
  43. data/spec/directory/git_directory_spec.rb +28 -0
  44. data/spec/downloader/s3_spec.rb +23 -0
  45. data/spec/logger_spec.rb +20 -0
  46. metadata +55 -16
@@ -2,9 +2,11 @@ module Heirloom
2
2
  module Destroyer
3
3
  class S3
4
4
 
5
+ attr_accessor :config, :region
6
+
5
7
  def initialize(args)
6
- @config = args[:config]
7
- @region = args[:region]
8
+ self.config = args[:config]
9
+ self.region = args[:region]
8
10
  end
9
11
 
10
12
  def destroy_file(args)
@@ -18,8 +20,8 @@ module Heirloom
18
20
  private
19
21
 
20
22
  def s3
21
- @s3 ||= AWS::S3.new :config => @config,
22
- :region => @region
23
+ @s3 ||= AWS::S3.new :config => config,
24
+ :region => region
23
25
  end
24
26
 
25
27
  end
@@ -8,32 +8,36 @@ module Heirloom
8
8
 
9
9
  class Directory
10
10
 
11
+ attr_accessor :config, :exclude, :local_build, :path, :logger
12
+
11
13
  def initialize(args)
12
- @directory = args[:directory]
13
- @exclude = args[:exclude]
14
- @logger = args[:logger]
14
+ self.config = args[:config]
15
+ self.exclude = args[:exclude]
16
+ self.path = args[:path]
17
+ self.logger = config.logger
15
18
  end
16
19
 
17
20
  def build_artifact_from_directory
18
21
  random_text = (0...8).map{65.+(rand(25)).chr}.join
19
- temp_file_name = File.join(Dir.tmpdir, random_text + ".tar.gz")
20
22
 
21
- @logger.info "Building artifact '#{temp_file_name}' from '#{@directory}'."
22
- @logger.info "Excluding #{@exclude.to_s}."
23
- @logger.info "Adding #{files_to_pack.to_s}."
23
+ unless local_build
24
+ self.local_build = File.join(Dir.tmpdir, random_text + ".tar.gz")
25
+ end
26
+
27
+ logger.info "Building artifact '#{local_build}' from '#{path}'."
28
+ logger.info "Excluding #{exclude.to_s}."
29
+ logger.info "Adding #{files_to_pack.to_s}."
24
30
 
25
- tgz = Zlib::GzipWriter.new File.open(temp_file_name, 'wb')
31
+ tgz = Zlib::GzipWriter.new File.open(local_build, 'wb')
26
32
 
27
33
  Minitar.pack(files_to_pack, tgz)
28
- temp_file_name
29
34
  end
30
35
 
31
36
  private
32
37
 
33
38
  def files_to_pack
34
- Dir.entries(@directory) - ['.', '..'] - @exclude
39
+ Dir.entries(path) - ['.', '..'] - exclude
35
40
  end
36
41
 
37
-
38
42
  end
39
43
  end
@@ -6,13 +6,14 @@ module Heirloom
6
6
 
7
7
  class GitDirectory
8
8
 
9
+ attr_accessor :path
10
+
9
11
  def initialize(args)
10
- @directory = args[:directory]
11
- @logger = args[:logger]
12
+ self.path = args[:path]
12
13
  end
13
14
 
14
15
  def commit(sha = nil)
15
- r = Repo.new @directory
16
+ r = Repo.new path
16
17
  sha ? r.commits(sha).first : r.commits.first
17
18
  end
18
19
 
@@ -5,7 +5,7 @@ module Heirloom
5
5
  def initialize(args)
6
6
  @config = args[:config]
7
7
  @region = args[:region]
8
- @logger = args[:logger]
8
+ @logger = @config.logger
9
9
  end
10
10
 
11
11
  def download_file(args)
@@ -1,12 +1,14 @@
1
1
  module Heirloom
2
2
  class HeirloomLogger
3
3
 
4
- def initialize(args)
4
+ def initialize(args = {})
5
5
  @logger = args[:logger] ||= Logger.new(STDOUT)
6
6
 
7
- @logger.datetime_format = "%Y-%m-%d %H:%M:%S"
8
- @logger.formatter = proc do |severity, datetime, progname, msg|
9
- "#{datetime}: #{msg}\n"
7
+ unless args[:logger]
8
+ @logger.datetime_format = "%Y-%m-%d %H:%M:%S"
9
+ @logger.formatter = proc do |severity, datetime, progname, msg|
10
+ "#{datetime}: #{msg}\n"
11
+ end
10
12
  end
11
13
 
12
14
  @logger
@@ -1,3 +1,3 @@
1
1
  module Heirloom
2
- VERSION = "0.1.3"
2
+ VERSION = "0.1.4"
3
3
  end
@@ -0,0 +1,51 @@
1
+ require 'spec_helper'
2
+
3
+ describe Heirloom do
4
+ before do
5
+ @config_mock = double 'config'
6
+ @logger_mock = double 'logger'
7
+ @config_mock.should_receive(:logger).and_return(@logger_mock)
8
+ @config_mock.should_receive(:authorized_aws_accounts).
9
+ and_return ['acct1@test.com', 'acct2@test.com']
10
+
11
+ @s3 = Heirloom::ACL::S3.new :config => @config_mock,
12
+ :region => 'us-west-1'
13
+ end
14
+
15
+ it "should allow read access for the specified accounts" do
16
+ acls = {
17
+ 'Owner' => {
18
+ 'Name' => 'Brett',
19
+ 'ID' => '123'
20
+ }
21
+ }
22
+ s3_mock = mock 's3'
23
+
24
+ @s3.should_receive(:s3).exactly(2).times.
25
+ and_return(s3_mock)
26
+
27
+ s3_mock.should_receive(:get_bucket_acl).with('bucket').
28
+ and_return acls
29
+
30
+ grants_mock = mock 'grants'
31
+ @s3.should_receive(:build_bucket_grants).
32
+ with(:id => '123',
33
+ :name => 'Brett',
34
+ :accounts => ['acct1@test.com', 'acct2@test.com']).
35
+ and_return grants_mock
36
+
37
+ @logger_mock.should_receive(:info).
38
+ with 'Authorizing acct1@test.com to s3://bucket/key-folder/key.tar.gz.'
39
+ @logger_mock.should_receive(:info).
40
+ with 'Authorizing acct2@test.com to s3://bucket/key-folder/key.tar.gz.'
41
+
42
+ s3_mock.should_receive(:put_object_acl).with('bucket', 'key-folder/key.tar.gz', grants_mock)
43
+
44
+ @s3.allow_read_access_from_accounts :bucket => 'bucket',
45
+ :key_name => 'key',
46
+ :key_folder => 'key-folder'
47
+ end
48
+
49
+ it "should test build_bucket_grants private method"
50
+
51
+ end
@@ -0,0 +1,34 @@
1
+ require 'spec_helper'
2
+
3
+ describe Heirloom do
4
+
5
+ before do
6
+ @config_mock = double('config')
7
+ @logger_mock = double('logger')
8
+ @config_mock.should_receive(:logger).and_return(@logger_mock)
9
+ @authorizer = Heirloom::ArtifactAuthorizer.new :config => @config_mock,
10
+ :name => 'tim',
11
+ :id => '123'
12
+ end
13
+
14
+ it "should authorize access to an acl across all regions" do
15
+ artifact_reader = double
16
+ s3_acl = double
17
+ @logger_mock.should_receive(:info).exactly(2).times
18
+ @config_mock.should_receive(:regions).
19
+ and_return(['us-west-1', 'us-west-2'])
20
+ @authorizer.should_receive(:artifact_reader).exactly(2).times.
21
+ and_return(artifact_reader)
22
+ artifact_reader.should_receive(:get_bucket).exactly(2).times.
23
+ and_return('the-bucket')
24
+ Heirloom::ACL::S3.should_receive(:new).exactly(2).
25
+ times.and_return(s3_acl)
26
+ s3_acl.should_receive(:allow_read_access_from_accounts).
27
+ exactly(2).times.
28
+ with(:key_name => '123',
29
+ :key_folder => 'tim',
30
+ :bucket => 'the-bucket')
31
+ @authorizer.authorize
32
+ end
33
+
34
+ end
@@ -0,0 +1,41 @@
1
+ require 'spec_helper'
2
+
3
+ describe Heirloom do
4
+
5
+ before do
6
+ @config_mock = double 'config'
7
+ @logger_mock = double 'logger'
8
+ @simpledb_mock = double 'simple db'
9
+ @config_mock.should_receive(:logger).and_return(@logger_mock)
10
+ Heirloom::AWS::SimpleDB.should_receive(:new).with(:config => @config_mock).
11
+ and_return(@simpledb_mock)
12
+ @simpledb_mock.should_receive(:create_domain).with 'tim'
13
+ @builder = Heirloom::ArtifactBuilder.new :config => @config_mock,
14
+ :name => 'tim',
15
+ :id => '123'
16
+ end
17
+
18
+ it "should build an artifact" do
19
+ directory_mock = double "directory"
20
+ Heirloom::Directory.should_receive(:new).with(:path => 'path_to_build',
21
+ :exclude => ['.dir_to_exclude'],
22
+ :config => @config_mock).
23
+ and_return(directory_mock)
24
+ directory_mock.should_receive :build_artifact_from_directory
25
+ directory_mock.should_receive(:local_build).and_return('/tmp/file')
26
+ @builder.should_receive(:create_artifact_record)
27
+ @builder.should_receive(:add_git_commit)
28
+ @logger_mock.should_receive(:info).with("Build complete.")
29
+ @builder.build(:exclude => ['.dir_to_exclude'],
30
+ :directory => 'path_to_build',
31
+ :git => 'true').should == '/tmp/file'
32
+ end
33
+
34
+ it "should cleanup the local artifact" do
35
+ @builder.local_build = '/tmp/file'
36
+ @logger_mock.should_receive(:info).with("Cleaning up local build /tmp/file.")
37
+ File.should_receive(:delete).with('/tmp/file')
38
+ @builder.cleanup
39
+ end
40
+
41
+ end
@@ -0,0 +1,45 @@
1
+ require 'spec_helper'
2
+
3
+ describe Heirloom do
4
+
5
+ before do
6
+ @config_mock = double 'config'
7
+ @logger_mock = double 'logger'
8
+ @config_mock.should_receive(:logger).and_return(@logger_mock)
9
+ @destroyer = Heirloom::ArtifactDestroyer.new :config => @config_mock,
10
+ :name => 'tim',
11
+ :id => '123'
12
+ end
13
+
14
+ it "should destroy the given artifact" do
15
+ @logger_mock.should_receive(:info).
16
+ with "Destroying tim - 123"
17
+ @config_mock.should_receive(:regions).and_return ['us-west-1']
18
+ artifact_reader_mock = mock 'artifact reader'
19
+ @destroyer.should_receive(:artifact_reader).and_return artifact_reader_mock
20
+ bucket_mock = mock 'bucket'
21
+ artifact_reader_mock.should_receive(:get_bucket).
22
+ with(:region => 'us-west-1').
23
+ and_return 'bucket-us-west-1'
24
+
25
+ @logger_mock.should_receive(:info).
26
+ with "Destroying 's3://bucket-us-west-1/tim/123.tar.gz'."
27
+
28
+ s3_destroyer_mock = mock 's3 destroyer'
29
+ Heirloom::Destroyer::S3.should_receive(:new).
30
+ with(:config => @config_mock,
31
+ :region => 'us-west-1').
32
+ and_return s3_destroyer_mock
33
+ s3_destroyer_mock.should_receive(:destroy_file).
34
+ with :key_name => '123.tar.gz',
35
+ :key_folder => 'tim',
36
+ :bucket => 'bucket-us-west-1'
37
+ sdb_mock = mock 'sdb'
38
+ @destroyer.should_receive(:sdb).and_return sdb_mock
39
+ sdb_mock.should_receive(:delete).with 'tim', '123'
40
+ @logger_mock.should_receive(:info).
41
+ with "Destroy complete."
42
+ @destroyer.destroy
43
+ end
44
+
45
+ end
@@ -0,0 +1,93 @@
1
+ require 'spec_helper'
2
+
3
+ describe Heirloom do
4
+
5
+ before do
6
+ @config_mock = double 'config'
7
+ @logger_mock = double 'logger'
8
+ @config_mock.should_receive(:logger).and_return(@logger_mock)
9
+ @downloader = Heirloom::ArtifactDownloader.new :config => @config_mock,
10
+ :name => 'tim',
11
+ :id => '123'
12
+ end
13
+
14
+ it "should download an artifact" do
15
+ s3_downloader_mock = mock 's3 downloader'
16
+ Heirloom::Downloader::S3.should_receive(:new).
17
+ with(:config => @config_mock,
18
+ :logger => @logger_mock,
19
+ :region => 'us-west-1').
20
+ and_return s3_downloader_mock
21
+ artifact_reader_mock = mock 'artifact_reader'
22
+ @downloader.should_receive(:artifact_reader).
23
+ exactly(2).times.
24
+ and_return artifact_reader_mock
25
+ artifact_reader_mock.should_receive(:get_bucket).
26
+ with(:region => 'us-west-1').
27
+ and_return 'bucket-us-west-1'
28
+ artifact_reader_mock.should_receive(:get_key).
29
+ with(:region => 'us-west-1').
30
+ and_return 'key'
31
+
32
+ @logger_mock.should_receive(:info).
33
+ with "Downloading s3://bucket-us-west-1/key from us-west-1."
34
+
35
+ s3_downloader_mock.should_receive(:download_file).
36
+ with(:bucket => 'bucket-us-west-1',
37
+ :key => 'key').
38
+ and_return 'filename'
39
+
40
+ @logger_mock.should_receive(:info).
41
+ with "Writing file to /tmp/file."
42
+
43
+ file_mock = mock 'file'
44
+
45
+ File.should_receive(:open).with('/tmp/file', 'w').
46
+ and_return file_mock
47
+
48
+ @logger_mock.should_receive(:info).with "Download complete."
49
+
50
+ @downloader.download(:output => '/tmp/file',
51
+ :region => 'us-west-1')
52
+ end
53
+
54
+ it "should download the artifact to the current path if output is unspecficief" do
55
+ s3_downloader_mock = mock 's3 downloader'
56
+ Heirloom::Downloader::S3.should_receive(:new).
57
+ with(:config => @config_mock,
58
+ :logger => @logger_mock,
59
+ :region => 'us-west-1').
60
+ and_return s3_downloader_mock
61
+ artifact_reader_mock = mock 'artifact_reader'
62
+ @downloader.should_receive(:artifact_reader).
63
+ exactly(2).times.
64
+ and_return artifact_reader_mock
65
+ artifact_reader_mock.should_receive(:get_bucket).
66
+ with(:region => 'us-west-1').
67
+ and_return 'bucket-us-west-1'
68
+ artifact_reader_mock.should_receive(:get_key).
69
+ with(:region => 'us-west-1').
70
+ and_return 'key'
71
+
72
+ @logger_mock.should_receive(:info).
73
+ with "Downloading s3://bucket-us-west-1/key from us-west-1."
74
+
75
+ s3_downloader_mock.should_receive(:download_file).
76
+ with(:bucket => 'bucket-us-west-1',
77
+ :key => 'key').
78
+ and_return 'filename'
79
+
80
+ @logger_mock.should_receive(:info).
81
+ with "Writing file to ./key."
82
+
83
+ file_mock = mock 'file'
84
+
85
+ File.should_receive(:open).with('./key', 'w').
86
+ and_return file_mock
87
+
88
+ @logger_mock.should_receive(:info).with "Download complete."
89
+
90
+ @downloader.download(:region => 'us-west-1')
91
+ end
92
+
93
+ end
@@ -0,0 +1,21 @@
1
+ require 'spec_helper'
2
+
3
+ describe Heirloom do
4
+
5
+ before do
6
+ @config_mock = double 'config'
7
+ @lister = Heirloom::ArtifactLister.new :config => @config_mock,
8
+ :name => 'test123'
9
+ end
10
+
11
+ it "should list the known artifacts" do
12
+ sdb_mock = mock 'sdb'
13
+ @lister.should_receive(:sdb).and_return sdb_mock
14
+ sdb_mock.should_receive(:select).
15
+ with("select * from test123 where built_at > '2000-01-01T00:00:00.000Z' \
16
+ order by built_at desc limit 10").
17
+ and_return( {'1' => 'one', '2' => 'two', '3' => 'three'} )
18
+ @lister.list.should == ['1', '2', '3']
19
+ end
20
+
21
+ end
@@ -0,0 +1,55 @@
1
+ require 'spec_helper'
2
+
3
+ describe Heirloom do
4
+
5
+ before do
6
+ @config_mock = double 'config'
7
+ @reader = Heirloom::ArtifactReader.new :config => @config_mock,
8
+ :name => 'tim',
9
+ :id => '123'
10
+ end
11
+
12
+ it "should show the item record" do
13
+ sdb_mock = mock 'sdb'
14
+ @reader.should_receive(:sdb).and_return sdb_mock
15
+ sdb_mock.should_receive(:select).
16
+ with("select * from tim where itemName() = '123'").
17
+ and_return( { '123' => 'details' } )
18
+ @reader.show.should == 'details'
19
+ end
20
+
21
+ it "should return true if the record exists" do
22
+ @reader.should_receive(:show).and_return 'a record'
23
+ @reader.exists?.should == true
24
+ end
25
+
26
+ it "should return false if the recrod does not exist" do
27
+ @reader.should_receive(:show).and_return nil
28
+ @reader.exists?.should == false
29
+ end
30
+
31
+ it "should return the bucket for the specified region" do
32
+ @reader.should_receive(:get_url).
33
+ with(:region => 'us-west-1').
34
+ and_return 's3://bucket-us-west-1/tim/123.tar.gz'
35
+ @reader.get_bucket(:region => 'us-west-1').should == 'bucket-us-west-1'
36
+ end
37
+
38
+ it "should return the key" do
39
+ @reader.should_receive(:show).
40
+ and_return( { 'us-west-1-s3-url' =>
41
+ [ 's3://bucket-us-west-1/tim/123.tar.gz' ] } )
42
+ @reader.should_receive(:get_bucket).
43
+ with(:region => 'us-west-1').
44
+ and_return 'bucket-us-west-1'
45
+ @reader.get_key(:region => 'us-west-1').should == 'tim/123.tar.gz'
46
+ end
47
+
48
+ it "shoudl return the s3 url for the given region" do
49
+ @reader.should_receive(:show).
50
+ and_return( { 'us-west-1-s3-url' =>
51
+ [ 's3://bucket-us-west-1/tim/123.tar.gz' ] } )
52
+ @reader.get_url(:region => 'us-west-1').should == 's3://bucket-us-west-1/tim/123.tar.gz'
53
+ end
54
+
55
+ end