heirloom 0.1.3 → 0.1.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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