heirloom 0.8.3 → 0.9.0

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.
data/CHANGELOG CHANGED
@@ -1,3 +1,13 @@
1
+ ## 0.9.0:
2
+
3
+ * Updated tempfile logic to fix GC issues.
4
+ * Removed git support.
5
+ * Only setup existing buckets if forced.
6
+ * Ensure valid bucket name and heirloom name on setup.
7
+ * Return friendly error when bucket or heirloom does not exist.
8
+ * Updating to fog 1.6.0
9
+ * Removing grit gem
10
+
1
11
  ## 0.8.3:
2
12
 
3
13
  * Teardown does not try to delete buckets if they are not empty.
data/heirloom.gemspec CHANGED
@@ -22,7 +22,7 @@ Gem::Specification.new do |s|
22
22
  s.add_development_dependency "rspec", '~> 2.11.0'
23
23
  s.add_development_dependency "rake"
24
24
 
25
- s.add_runtime_dependency 'fog', '~> 1.5.0'
26
- s.add_runtime_dependency 'grit', '~> 2.5.0'
25
+ s.add_runtime_dependency 'fog', '~> 1.6.0'
27
26
  s.add_runtime_dependency 'trollop', '= 2.0'
27
+ s.add_runtime_dependency 'xml-simple', '~> 1.1.2'
28
28
  end
@@ -10,8 +10,8 @@ module Heirloom
10
10
  def initialize(args)
11
11
  @config = args[:config]
12
12
  @name = args[:name]
13
- @domain = "heirloom_#{@name}"
14
13
  @id = args[:id]
14
+ @domain = "heirloom_#{@name}"
15
15
  @logger = @config.logger
16
16
  end
17
17
 
@@ -19,49 +19,23 @@ module Heirloom
19
19
  @source = args[:directory] ||= '.'
20
20
  @secret = args[:secret]
21
21
  @bucket_prefix = args[:bucket_prefix]
22
+ @file = args[:file]
23
+ @exclude = args[:exclude]
22
24
 
23
25
  directory = Directory.new :path => @source,
24
- :exclude => args[:exclude],
26
+ :file => @file,
27
+ :exclude => @exclude,
25
28
  :config => @config
26
29
 
27
30
  unless directory.build_artifact_from_directory :secret => @secret
28
31
  return false
29
32
  end
30
33
 
31
- @local_build = directory.local_build
32
-
33
34
  create_artifact_record
34
-
35
- add_git_commit if args[:git]
36
-
37
- @local_build
38
35
  end
39
36
 
40
37
  private
41
38
 
42
- def add_git_commit
43
- git = GitDirectory.new(:path => @source)
44
- commit = git.commit @id
45
- if commit
46
- add_git_commit_to_artifact_record commit
47
- else
48
- @logger.warn "Could not load Git sha '#{@id}' in '#{@source}'."
49
- end
50
- end
51
-
52
- def add_git_commit_to_artifact_record(commit)
53
- attributes = { 'sha' => @id,
54
- 'abbreviated_sha' => commit.id_abbrev,
55
- 'message' => commit.message.gsub("\n"," ")[0..1023],
56
- 'author' => commit.author.name }
57
-
58
- attributes.each_pair do |k, v|
59
- @logger.info "Git #{k}: #{v}"
60
- end
61
-
62
- sdb.put_attributes @domain, @id, attributes
63
- end
64
-
65
39
  def create_artifact_record
66
40
  attributes = { 'built_by' => "#{user}@#{hostname}",
67
41
  'built_at' => Time.now.utc.iso8601,
@@ -24,6 +24,8 @@ module Heirloom
24
24
 
25
25
  raw_archive = s3_downloader.download_file :bucket => bucket,
26
26
  :key => key
27
+
28
+ return false unless raw_archive
27
29
 
28
30
  archive = cipher_data.decrypt_data :data => raw_archive,
29
31
  :secret => secret
@@ -1,5 +1,6 @@
1
1
  require 'openssl'
2
2
  require 'tempfile'
3
+ require 'fileutils'
3
4
 
4
5
  module Heirloom
5
6
  module Cipher
@@ -11,10 +12,10 @@ module Heirloom
11
12
  end
12
13
 
13
14
  def encrypt_file(args)
14
- file = args[:file]
15
- secret = args[:secret]
16
- output = Tempfile.new('archive.tar.gz.enc')
17
- iv = @aes.random_iv
15
+ @file = args[:file]
16
+ @encrypted_file = Tempfile.new('archive.tar.gz.enc')
17
+ secret = args[:secret]
18
+ iv = @aes.random_iv
18
19
 
19
20
  @aes.encrypt
20
21
  @aes.iv = iv
@@ -22,9 +23,9 @@ module Heirloom
22
23
 
23
24
  # Need to refactor to be less complex
24
25
  # Additionally tests to do fully cover logic
25
- ::File.open(output,'w') do |enc|
26
+ ::File.open(@encrypted_file,'w') do |enc|
26
27
  enc << iv
27
- ::File.open(file) do |f|
28
+ ::File.open(@file) do |f|
28
29
  loop do
29
30
  r = f.read(4096)
30
31
  break unless r
@@ -33,7 +34,15 @@ module Heirloom
33
34
  end
34
35
  enc << @aes.final
35
36
  end
36
- output.path
37
+
38
+ replace_file
39
+ end
40
+
41
+ private
42
+
43
+ def replace_file
44
+ FileUtils.mv @encrypted_file.path, @file
45
+ @encrypted_file.close!
37
46
  end
38
47
 
39
48
  end
@@ -22,8 +22,13 @@ module Heirloom
22
22
  :config => @config)
23
23
 
24
24
  @archive = Archive.new :name => @opts[:name],
25
- :id => id,
26
- :config => @config
25
+ :config => @config,
26
+ :id => id
27
+
28
+ unless @opts[:bucket_prefix]
29
+ ensure_archive_exists :archive => @archive,
30
+ :config => @config
31
+ end
27
32
 
28
33
  # Lookup region & bucket_prefix from simpledb unless specified
29
34
  # To Do, valid validation message that simpledb exists
@@ -35,8 +40,6 @@ module Heirloom
35
40
  ensure_directory :path => @opts[:output], :config => @config
36
41
  secret = read_secret :opts => @opts,
37
42
  :config => @config
38
- ensure_valid_secret :secret => secret,
39
- :config => @config
40
43
  archive = @archive.download :output => @opts[:output],
41
44
  :extract => @opts[:extract],
42
45
  :region => @region,
@@ -74,7 +77,7 @@ EOS
74
77
  opt :name, "Name of Heirloom.", :type => :string
75
78
  opt :output, "Path to output downloaded Heirloom. Must be existing directory.", :type => :string
76
79
  opt :region, "Region to download Heirloom.", :type => :string,
77
- :default => 'us-west-1'
80
+ :default => 'us-west-1'
78
81
  opt :secret, "Secret for ecrypted Heirloom.", :type => :string
79
82
  opt :secret_file, "Read secret from file.", :type => :string,
80
83
  :short => :none
@@ -25,16 +25,30 @@ module Heirloom
25
25
  def setup
26
26
  ensure_valid_region :region => @opts[:metadata_region],
27
27
  :config => @config
28
+
28
29
  ensure_valid_regions :regions => @opts[:region],
29
30
  :config => @config
31
+
30
32
  ensure_metadata_in_upload_region :config => @config,
31
33
  :regions => @opts[:region]
34
+
35
+ ensure_valid_name :config => @config,
36
+ :name => @opts[:name]
37
+
38
+ ensure_valid_bucket_prefix :config => @config,
39
+ :bucket_prefix => @opts[:bucket_prefix]
40
+
41
+ @catalog.create_catalog_domain
42
+
43
+ ensure_entry_does_not_exist_in_catalog :config => @config,
44
+ :catalog => @catalog,
45
+ :entry => @opts[:name],
46
+ :force => @opts[:force]
47
+
32
48
  ensure_buckets_available :config => @config,
33
49
  :bucket_prefix => @opts[:bucket_prefix],
34
50
  :regions => @opts[:region]
35
51
 
36
- @catalog.create_catalog_domain
37
-
38
52
  @catalog.add_to_catalog :regions => @opts[:region],
39
53
  :bucket_prefix => @opts[:bucket_prefix]
40
54
 
@@ -59,6 +73,7 @@ EOS
59
73
  opt :bucket_prefix, "The bucket prefix will be combined with specified \
60
74
  regions to create the required buckets. For example: '-b test -r us-west-1 -r \
61
75
  us-east-1' will create bucket test-us-west-1 in us-west-1 and test-us-east-1 in us-east-1.", :type => :string
76
+ opt :force, "Overwrite existing catalog entries."
62
77
  opt :help, "Display Help"
63
78
  opt :level, "Log level [debug|info|warn|error].", :type => :string,
64
79
  :default => 'info'
@@ -124,8 +124,8 @@ module Heirloom
124
124
  end
125
125
 
126
126
  def ensure_archive_exists(args)
127
- config = args[:config]
128
127
  archive = args[:archive]
128
+ config = args[:config]
129
129
  logger = config.logger
130
130
 
131
131
  unless archive.exists?
@@ -189,6 +189,41 @@ module Heirloom
189
189
  end
190
190
  end
191
191
 
192
+ def ensure_entry_does_not_exist_in_catalog(args)
193
+ config = args[:config]
194
+ catalog = args[:catalog]
195
+ entry = args[:entry]
196
+ force = args[:force]
197
+ logger = config.logger
198
+ region = config.metadata_region
199
+
200
+ if catalog.entry_exists_in_catalog?(entry) && !force
201
+ logger.error "Entry #{entry} exists in catalog. Use --force to overwrite."
202
+ exit 1
203
+ end
204
+ end
205
+
206
+ def ensure_valid_name(args)
207
+ config = args[:config]
208
+ name = args[:name]
209
+ logger = config.logger
210
+ unless name =~ /^[0-9a-z\-\_]+$/
211
+ logger.error "Invalid name '#{name}'. Can only contain lower case letters, numbers, dashes and underscores."
212
+ exit 1
213
+ end
214
+ end
215
+
216
+ def ensure_valid_bucket_prefix(args)
217
+ config = args[:config]
218
+ bucket_prefix = args[:bucket_prefix]
219
+ logger = config.logger
220
+
221
+ unless bucket_prefix =~ /^[0-9a-z\-]+$/
222
+ logger.error "Invalid bucket prefix '#{bucket_prefix}'. Can only contain lower case letters, numbers and dashes."
223
+ exit 1
224
+ end
225
+ end
226
+
192
227
  def latest_id(args)
193
228
  archive = Archive.new :name => args[:name],
194
229
  :config => args[:config]
@@ -1,3 +1,5 @@
1
+ require 'tempfile'
2
+
1
3
  module Heirloom
2
4
  module CLI
3
5
  class Upload
@@ -45,13 +47,14 @@ module Heirloom
45
47
 
46
48
  @archive.destroy if @archive.exists?
47
49
 
48
- build = @archive.build :bucket_prefix => @bucket_prefix,
49
- :directory => @opts[:directory],
50
- :exclude => @opts[:exclude],
51
- :git => @opts[:git],
52
- :secret => secret
50
+ @file = Tempfile.new('archive.tar.gz')
51
+
52
+ unless @archive.build :bucket_prefix => @bucket_prefix,
53
+ :directory => @opts[:directory],
54
+ :exclude => @opts[:exclude],
55
+ :file => @file.path,
56
+ :secret => secret
53
57
 
54
- unless build
55
58
  @logger.error "Build failed."
56
59
  exit 1
57
60
  end
@@ -59,7 +62,9 @@ module Heirloom
59
62
  @archive.upload :bucket_prefix => @bucket_prefix,
60
63
  :regions => @regions,
61
64
  :public_readable => @opts[:public],
62
- :file => build
65
+ :file => @file.path
66
+
67
+ @file.close!
63
68
  end
64
69
 
65
70
  private
@@ -76,12 +81,11 @@ Usage:
76
81
  heirloom upload -n NAME -i ID -d DIRECTORY_TO_UPLOAD
77
82
 
78
83
  EOS
79
- opt :directory, "Source directory of build.", :type => :string
84
+ opt :directory, "Source directory to upload.", :type => :string
80
85
  opt :exclude, "File(s) or directorie(s) to exclude. \
81
86
  Can be specified multiple times.", :type => :string, :multi => true
82
- opt :git, "Read git commit information from directory and set as Heirloom attributes."
83
87
  opt :help, "Display Help"
84
- opt :id, "ID for Heirloom (when -g specified, assumed to be GIT sha).", :type => :string
88
+ opt :id, "ID for Heirloom.", :type => :string
85
89
  opt :level, "Log level [debug|info|warn|error].", :type => :string,
86
90
  :default => 'info'
87
91
  opt :metadata_region, "AWS region to store Heirloom metadata.", :type => :string,
@@ -1,24 +1,19 @@
1
- require 'tempfile'
2
-
3
1
  module Heirloom
4
2
 
5
3
  class Directory
6
4
 
7
- attr_reader :local_build
8
-
9
5
  def initialize(args)
10
- @config = args[:config]
6
+ @config = args[:config]
11
7
  @exclude = args[:exclude]
12
- @path = args[:path]
13
- @logger = @config.logger
8
+ @path = args[:path]
9
+ @file = args[:file]
10
+ @logger = @config.logger
14
11
  end
15
12
 
16
13
  def build_artifact_from_directory(args)
17
14
  @secret = args[:secret]
18
15
 
19
- @local_build = Tempfile.new('archive.tar.gz').path
20
-
21
- @logger.debug "Building Heirloom '#{@local_build}' from '#{@path}'."
16
+ @logger.debug "Building Heirloom '#{@file}' from '#{@path}'."
22
17
  @logger.debug "Excluding #{@exclude.to_s}."
23
18
  @logger.debug "Adding #{files_to_pack}."
24
19
 
@@ -30,7 +25,7 @@ module Heirloom
30
25
  private
31
26
 
32
27
  def build_archive
33
- command = "cd #{@path} && tar czf #{@local_build} #{files_to_pack}"
28
+ command = "cd #{@path} && tar czf #{@file} #{files_to_pack}"
34
29
  @logger.info "Archiving with: `#{command}`"
35
30
  output = `#{command}`
36
31
  @logger.debug "Exited with status: '#{$?.exitstatus}' ouput: '#{output}'"
@@ -40,8 +35,8 @@ module Heirloom
40
35
  def build_encrypted_archive
41
36
  return false unless build_archive
42
37
  @logger.info "Secret provided. Encrypting."
43
- @local_build = cipher_file.encrypt_file :file => @local_build,
44
- :secret => @secret
38
+ cipher_file.encrypt_file :file => @file,
39
+ :secret => @secret
45
40
  end
46
41
 
47
42
  def files_to_pack
@@ -1,2 +1 @@
1
1
  require 'heirloom/directory/directory'
2
- require 'heirloom/directory/git_directory'
@@ -1,3 +1,5 @@
1
+ require 'xmlsimple'
2
+
1
3
  module Heirloom
2
4
  class Downloader
3
5
  class S3
@@ -10,8 +12,16 @@ module Heirloom
10
12
 
11
13
  def download_file(args)
12
14
  s3.get_object args[:bucket], args[:key]
15
+ rescue Excon::Errors::Forbidden, Excon::Errors::NotFound => e
16
+ error = XmlSimple.xml_in e.response.body
17
+ error['Message'].each do |msg|
18
+ @logger.error msg
19
+ end
20
+ false
13
21
  end
14
22
 
23
+ private
24
+
15
25
  def s3
16
26
  @s3 ||= AWS::S3.new :config => @config,
17
27
  :region => @region
@@ -1,3 +1,5 @@
1
+ require 'logger'
2
+
1
3
  module Heirloom
2
4
  class HeirloomLogger
3
5
 
@@ -1,3 +1,3 @@
1
1
  module Heirloom
2
- VERSION = "0.8.3"
2
+ VERSION = "0.9.0"
3
3
  end
@@ -17,99 +17,28 @@ describe Heirloom::Builder do
17
17
  @author_stub = stub :name => 'weaver'
18
18
  @directory_stub = stub :build_artifact_from_directory => '/tmp/build_dir',
19
19
  :local_build => '/var/tmp/file.tar.gz'
20
- @git_dir_mock = double "git directory mock"
21
20
 
22
21
  Heirloom::Directory.should_receive(:new).
23
22
  with(:path => 'path_to_build',
24
23
  :exclude => ['.dir_to_exclude'],
24
+ :file => '/tmp/file.tar.gz',
25
25
  :config => @config_mock).
26
26
  and_return @directory_stub
27
- Heirloom::GitDirectory.should_receive(:new).
28
- with(:path => 'path_to_build').
29
- and_return @git_dir_mock
30
27
  @builder.should_receive(:create_artifact_record)
31
28
  end
32
29
 
33
- context 'with a git directory' do
34
-
35
- before do
36
- Heirloom::AWS::SimpleDB.should_receive(:new).
37
- with(:config => @config_mock).
38
- and_return(@simpledb_mock)
39
- end
40
-
41
- it "should build an archive" do
42
- commit_attributes = { 'sha' => '123',
43
- 'abbreviated_sha' => 'abc123',
44
- 'message' => 'yoyo',
45
- 'author' => 'weaver' }
46
- @simpledb_mock.should_receive(:put_attributes).
47
- with('heirloom_tim', '123', commit_attributes)
48
- @git_commit_stub = stub :id_abbrev => "abc123",
49
- :message => "yoyo",
50
- :author => @author_stub
51
- @git_dir_mock.stub :commit => @git_commit_stub
52
- @builder.build(:exclude => ['.dir_to_exclude'],
53
- :directory => 'path_to_build',
54
- :git => 'true').should == '/var/tmp/file.tar.gz'
55
- end
56
-
57
- it "should remove new lines from the commit message" do
58
- commit_attributes = { 'sha' => '123',
59
- 'abbreviated_sha' => 'abc123',
60
- 'message' => 'yo yo yo',
61
- 'author' => 'weaver' }
62
- @simpledb_mock.should_receive(:put_attributes).
63
- with('heirloom_tim', '123', commit_attributes)
64
- @git_commit_stub = stub :id_abbrev => "abc123",
65
- :message => "yo\nyo\n\nyo",
66
- :author => @author_stub
67
- @git_dir_mock.stub :commit => @git_commit_stub
68
- @builder.build(:exclude => ['.dir_to_exclude'],
69
- :directory => 'path_to_build',
70
- :git => 'true').should == '/var/tmp/file.tar.gz'
71
- end
72
-
73
- it "should truncate commit message to 1024 chars" do
74
- long_commit_message = 'long commit message' * 100
75
- truncated_commit_attributes = { 'sha' => '123',
76
- 'abbreviated_sha' => 'abc123',
77
- 'message' => long_commit_message[0..1023],
78
- 'author' => 'weaver' }
79
- @simpledb_mock.should_receive(:put_attributes).
80
- with('heirloom_tim', '123', truncated_commit_attributes)
81
- @git_commit_stub = stub :id_abbrev => "abc123",
82
- :message => long_commit_message,
83
- :author => @author_stub
84
- @git_dir_mock.stub :commit => @git_commit_stub
85
- @builder.build(:exclude => ['.dir_to_exclude'],
86
- :directory => 'path_to_build',
87
- :git => 'true').should == '/var/tmp/file.tar.gz'
88
- end
89
-
90
- end
91
-
92
- context "without git dir" do
93
- it "should build an archive and log a warning if the git sha is not found" do
94
- @logger_stub.should_receive(:warn).with "Could not load Git sha '123' in 'path_to_build'."
95
- @git_dir_mock.should_receive(:commit).
96
- with('123').and_return false
97
- @builder.build(:exclude => ['.dir_to_exclude'],
98
- :directory => 'path_to_build',
99
- :git => 'true').should == '/var/tmp/file.tar.gz'
100
- end
101
- end
102
30
  end
103
31
 
104
32
  it "should return false if the build fails" do
105
33
  directory_stub = stub :build_artifact_from_directory => false
106
34
  Heirloom::Directory.should_receive(:new).with(:path => 'path_to_build',
107
35
  :exclude => ['.dir_to_exclude'],
36
+ :file => '/tmp/file.tar.gz',
108
37
  :config => @config_mock).
109
38
  and_return directory_stub
110
39
  @builder.build(:exclude => ['.dir_to_exclude'],
111
40
  :directory => 'path_to_build',
112
- :git => 'true').should be_false
41
+ :file => '/tmp/file.tar.gz').should be_false
113
42
  end
114
43
 
115
44
  end
@@ -16,49 +16,68 @@ describe Heirloom do
16
16
  :region => 'us-west-1').
17
17
  and_return @s3_downloader_mock
18
18
  @cipher_mock = mock 'cipher'
19
- Heirloom::Cipher::Data.should_receive(:new).
20
- with(:config => @config_mock).
21
- and_return @cipher_mock
22
19
  end
23
20
 
24
21
  context "no secret given" do
25
- before do
26
- @writer_mock = mock 'writer'
27
- Heirloom::Writer.should_receive(:new).
28
- with(:config => @config_mock).
29
- and_return @writer_mock
30
- @s3_downloader_mock.should_receive(:download_file).
31
- with(:bucket => 'bucket-us-west-1',
32
- :key => 'tim/123.tar.gz').
33
- and_return 'plaintext'
34
- @cipher_mock.should_receive(:decrypt_data).
35
- with(:secret => nil,
36
- :data => 'plaintext').and_return 'plaintext'
37
- end
22
+ context "when succesful" do
23
+ before do
24
+ @writer_mock = mock 'writer'
25
+ Heirloom::Writer.should_receive(:new).
26
+ with(:config => @config_mock).
27
+ and_return @writer_mock
28
+ @s3_downloader_mock.should_receive(:download_file).
29
+ with(:bucket => 'bucket-us-west-1',
30
+ :key => 'tim/123.tar.gz').
31
+ and_return 'plaintext'
32
+ @cipher_mock.should_receive(:decrypt_data).
33
+ with(:secret => nil,
34
+ :data => 'plaintext').and_return 'plaintext'
35
+ Heirloom::Cipher::Data.should_receive(:new).
36
+ with(:config => @config_mock).
37
+ and_return @cipher_mock
38
+ end
39
+
40
+ it "should download to the current path if output is not specified" do
41
+ @writer_mock.should_receive(:save_archive).
42
+ with(:archive => 'plaintext',
43
+ :file => "123.tar.gz",
44
+ :output => './',
45
+ :extract => false).and_return true
46
+ @downloader.download(:region => 'us-west-1',
47
+ :bucket_prefix => 'bucket',
48
+ :extract => false,
49
+ :secret => nil).should == './'
50
+ end
38
51
 
39
- it "should download to the current path if output is not specified" do
40
- @writer_mock.should_receive(:save_archive).
41
- with(:archive => 'plaintext',
42
- :file => "123.tar.gz",
43
- :output => './',
44
- :extract => false).and_return true
45
- @downloader.download(:region => 'us-west-1',
46
- :bucket_prefix => 'bucket',
47
- :extract => false,
48
- :secret => nil).should == './'
52
+ it "should download arhcive to specified output" do
53
+ @writer_mock.should_receive(:save_archive).
54
+ with(:archive => 'plaintext',
55
+ :file => "123.tar.gz",
56
+ :output => '/tmp/dir',
57
+ :extract => false).and_return true
58
+ @downloader.download(:output => '/tmp/dir',
59
+ :region => 'us-west-1',
60
+ :bucket_prefix => 'bucket',
61
+ :extract => false,
62
+ :secret => nil).should == '/tmp/dir'
63
+ end
49
64
  end
50
65
 
51
- it "should download arhcive to specified output" do
52
- @writer_mock.should_receive(:save_archive).
53
- with(:archive => 'plaintext',
54
- :file => "123.tar.gz",
55
- :output => '/tmp/dir',
56
- :extract => false).and_return true
57
- @downloader.download(:output => '/tmp/dir',
58
- :region => 'us-west-1',
59
- :bucket_prefix => 'bucket',
60
- :extract => false,
61
- :secret => nil).should == '/tmp/dir'
66
+ context "when unsuccesful" do
67
+ before do
68
+ @s3_downloader_mock.should_receive(:download_file).
69
+ with(:bucket => 'bucket-us-west-1',
70
+ :key => 'tim/123.tar.gz').
71
+ and_return false
72
+ end
73
+
74
+ it "should return false if the archive is not downloaded" do
75
+ @downloader.download(:output => '/tmp/dir',
76
+ :region => 'us-west-1',
77
+ :bucket_prefix => 'bucket',
78
+ :extract => false,
79
+ :secret => nil).should be_false
80
+ end
62
81
  end
63
82
  end
64
83
 
@@ -68,6 +87,9 @@ describe Heirloom do
68
87
  with(:bucket => 'bucket-us-west-1',
69
88
  :key => 'tim/123.tar.gz').
70
89
  and_return 'encrypted_data'
90
+ Heirloom::Cipher::Data.should_receive(:new).
91
+ with(:config => @config_mock).
92
+ and_return @cipher_mock
71
93
  end
72
94
 
73
95
  context "valid secret" do
@@ -6,7 +6,8 @@ describe Heirloom do
6
6
  @logger_mock.stub :info => true
7
7
  @config_mock = mock 'config'
8
8
  @config_mock.stub :logger => @logger_mock
9
- @tempfile_stub = stub 'tempfile', :path => '/path_to_encrypted_archive'
9
+ @tempfile_stub = stub 'tempfile', :path => '/path_to_encrypted_archive',
10
+ :close! => true
10
11
  Tempfile.stub :new => @tempfile_stub
11
12
  @aes_mock = mock 'aes'
12
13
  @aes_mock.stub :random_iv => 'firstsixteenchar'
@@ -20,9 +21,10 @@ describe Heirloom do
20
21
  @aes_mock.should_receive(:iv=).with 'firstsixteenchar'
21
22
  @aes_mock.should_receive(:key=).with Digest::SHA256.hexdigest 'mysecret'
22
23
  ::File.should_receive(:open)
24
+ FileUtils.should_receive(:mv).
25
+ with('/path_to_encrypted_archive', '/file')
23
26
  @file.encrypt_file(:file => '/file',
24
- :secret => 'mysecret').
25
- should == '/path_to_encrypted_archive'
27
+ :secret => 'mysecret').should be_true
26
28
  end
27
29
 
28
30
  end
@@ -58,6 +58,7 @@ describe Heirloom do
58
58
  before do
59
59
  @catalog_stub = stub 'catalog', :regions => ['us-east-1', 'us-west-1'],
60
60
  :bucket_prefix => 'bp'
61
+ @archive_mock.stub :exists? => true
61
62
  options = { :name => 'archive_name',
62
63
  :level => 'info',
63
64
  :output => '/tmp/test123',
@@ -353,4 +353,115 @@ describe Heirloom do
353
353
  should raise_error SystemExit
354
354
  end
355
355
  end
356
+
357
+ context "testing ensure entry does not exist in catalog unless forced" do
358
+ before do
359
+ @catalog_mock = mock 'catalog'
360
+ @logger_stub = stub 'logger', :error => true
361
+ @config_stub = stub 'config', :logger => @logger_stub,
362
+ :metadata_region => 'us-west-1'
363
+ @object = Object.new
364
+ @object.extend Heirloom::CLI::Shared
365
+ end
366
+
367
+ it "should exit if the entry exists in catalog and not forced" do
368
+ options = { :config => @config_stub,
369
+ :catalog => @catalog_mock,
370
+ :entry => 'entry',
371
+ :force => false }
372
+ @catalog_mock.should_receive(:entry_exists_in_catalog?).
373
+ with('entry').
374
+ and_return true
375
+ lambda { @object.ensure_entry_does_not_exist_in_catalog options }.
376
+ should raise_error SystemExit
377
+ end
378
+
379
+ it "should not exit if the entry exists in catalog and forced" do
380
+ options = { :config => @config_stub,
381
+ :catalog => @catalog_mock,
382
+ :entry => 'entry',
383
+ :force => true }
384
+ @catalog_mock.should_receive(:entry_exists_in_catalog?).
385
+ with('entry').
386
+ and_return true
387
+ @object.ensure_entry_does_not_exist_in_catalog options
388
+ end
389
+
390
+ it "should not exit if the does not exists in catalog" do
391
+ options = { :config => @config_stub,
392
+ :catalog => @catalog_mock,
393
+ :entry => 'entry',
394
+ :force => false }
395
+ @catalog_mock.should_receive(:entry_exists_in_catalog?).
396
+ with('entry').
397
+ and_return false
398
+ @object.ensure_entry_does_not_exist_in_catalog options
399
+ end
400
+ end
401
+
402
+ context "testing ensure valid name" do
403
+ before do
404
+ @logger_stub = stub 'logger', :error => true
405
+ @config_stub = stub 'config', :logger => @logger_stub,
406
+ :metadata_region => 'us-west-1'
407
+ @object = Object.new
408
+ @object.extend Heirloom::CLI::Shared
409
+ end
410
+
411
+ it "should not exit if name is valid" do
412
+ @object.ensure_valid_name :config => @config_stub,
413
+ :name => 'test-123_test'
414
+ end
415
+
416
+ it "should exit if name contains a upper case" do
417
+ lambda { @object.ensure_valid_name :config => @config_stub,
418
+ :name => 'TEST-123' }.
419
+ should raise_error SystemExit
420
+ end
421
+
422
+ it "should exit if name contains a space" do
423
+ lambda { @object.ensure_valid_name :config => @config_stub,
424
+ :name => 'test 123' }.
425
+ should raise_error SystemExit
426
+ end
427
+
428
+ it "should exit if name contains invalid characters" do
429
+ lambda { @object.ensure_valid_name :config => @config_stub,
430
+ :name => 'test,123' }.
431
+ should raise_error SystemExit
432
+ end
433
+ end
434
+
435
+ context "testing ensure valid bucket prefix" do
436
+ before do
437
+ @logger_stub = stub 'logger', :error => true
438
+ @config_stub = stub 'config', :logger => @logger_stub,
439
+ :metadata_region => 'us-west-1'
440
+ @object = Object.new
441
+ @object.extend Heirloom::CLI::Shared
442
+ end
443
+
444
+ it "should not exit if bucket_prefix is valid" do
445
+ @object.ensure_valid_bucket_prefix :config => @config_stub,
446
+ :bucket_prefix => 'test-123'
447
+ end
448
+
449
+ it "should exit if bucket_prefix contains uppercase" do
450
+ lambda { @object.ensure_valid_bucket_prefix :config => @config_stub,
451
+ :bucket_prefix => 'TEST-123' }.
452
+ should raise_error SystemExit
453
+ end
454
+
455
+ it "should exit if bucket_prefix contains a space" do
456
+ lambda { @object.ensure_valid_bucket_prefix :config => @config_stub,
457
+ :bucket_prefix => 'test 123' }.
458
+ should raise_error SystemExit
459
+ end
460
+
461
+ it "should exit if bucket_prefix contains invalid characters" do
462
+ lambda { @object.ensure_valid_bucket_prefix :config => @config_stub,
463
+ :bucket_prefix => 'test,123' }.
464
+ should raise_error SystemExit
465
+ end
466
+ end
356
467
  end
@@ -6,7 +6,6 @@ describe Heirloom do
6
6
  before do
7
7
  @regions = ['us-west-1', 'us-west-2']
8
8
  options = { :level => 'info',
9
- :git => false,
10
9
  :exclude => ['exclude1', 'exclude2'],
11
10
  :directory => '/buildme',
12
11
  :public => false,
@@ -27,6 +26,10 @@ describe Heirloom do
27
26
  :bucket_prefix => 'bp',
28
27
  :catalog_domain_exists? => true
29
28
  Trollop.stub(:options).and_return options
29
+ tempfile_stub = stub 'tempfile', :path => '/tmp/file.tar.gz',
30
+ :close! => true
31
+ Tempfile.stub :new => tempfile_stub
32
+
30
33
  Heirloom::HeirloomLogger.should_receive(:new).with(:log_level => 'info').
31
34
  and_return @logger_stub
32
35
  Heirloom::CLI::Upload.any_instance.should_receive(:load_config).
@@ -68,14 +71,14 @@ describe Heirloom do
68
71
  with(:bucket_prefix => 'bp',
69
72
  :directory => '/buildme',
70
73
  :exclude => ["exclude1", "exclude2"],
71
- :git => false,
72
- :secret => 'secret12').
73
- and_return '/tmp/build123.tar.gz'
74
+ :secret => 'secret12',
75
+ :file => '/tmp/file.tar.gz').
76
+ and_return true
74
77
  @archive_mock.should_receive(:upload).
75
78
  with(:bucket_prefix => 'bp',
76
79
  :regions => @regions,
77
80
  :public_readable => false,
78
- :file => '/tmp/build123.tar.gz')
81
+ :file => '/tmp/file.tar.gz')
79
82
  @upload.upload
80
83
  end
81
84
 
@@ -9,9 +9,8 @@ describe Heirloom::Directory do
9
9
  @config_mock.stub(:logger).and_return(@logger_stub)
10
10
  @directory = Heirloom::Directory.new :config => @config_mock,
11
11
  :exclude => ['.', '..', 'dont_pack_me'],
12
- :path => '/dir'
13
- @tempfile_stub = stub 'tempfile', :path => '/tmp/file.tar.gz'
14
- Tempfile.stub :new => @tempfile_stub
12
+ :path => '/dir',
13
+ :file => '/tmp/file.tar.gz'
15
14
  output_mock = double 'output mock'
16
15
  Dir.should_receive(:entries).with('/dir').
17
16
  exactly(2).times.
@@ -46,7 +45,7 @@ describe Heirloom::Directory do
46
45
  @cipher_mock.should_receive(:encrypt_file).
47
46
  with(:file => '/tmp/file.tar.gz',
48
47
  :secret => 'supersecret').
49
- and_return '/tmp/encrypted_file.tar.gz'
48
+ and_return true
50
49
  @directory.build_artifact_from_directory(:secret => 'supersecret').
51
50
  should be_true
52
51
  end
@@ -2,22 +2,50 @@ require 'spec_helper'
2
2
 
3
3
  describe Heirloom do
4
4
 
5
+ before do
6
+ @s3_mock = mock 's3 mock'
7
+ Heirloom::AWS::S3.stub :new => @s3_mock
8
+
9
+ @config_mock = double 'config'
10
+ @logger_mock = double 'logger'
11
+ @config_mock.stub :logger => @logger_mock
12
+ @s3 = Heirloom::Downloader::S3.new :config => @config_mock,
13
+ :region => 'us-west-1'
14
+ end
15
+
16
+ context "when succesful" do
17
+ it "should download the specified file from s3" do
18
+ @s3_mock.should_receive(:get_object).
19
+ with('bucket', 'key_name').
20
+ and_return 'data'
21
+ @s3.download_file(:key => 'key_name',
22
+ :bucket => 'bucket').should == 'data'
23
+ end
24
+ end
25
+
26
+ context "when unsuccesful" do
5
27
  before do
6
- @config_mock = double 'config'
7
- @logger_mock = double 'logger'
8
- @config_mock.should_receive(:logger).and_return(@logger_mock)
28
+ body = '<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<Error><Code>AccessDenied</Code><Message>Access Denied</Message><RequestId>7A737B6941146062</RequestId><HostId>8DlaCTOXO2aBxLnM2cZs+C8pQ2a5IDI/NQJRlPGRbPbBU2U1jH67i0zA376utqyR</HostId></Error>'
29
+ @response_stub = stub 'response', :body => body
30
+ end
9
31
 
10
- @s3 = Heirloom::Downloader::S3.new :config => @config_mock,
11
- :region => 'us-west-1'
32
+ it "should return an error if the bucket not found" do
33
+ @logger_mock.should_receive(:error).with('Access Denied')
34
+ @s3_mock.should_receive(:get_object).
35
+ with('bucket', 'key_name').
36
+ and_raise Excon::Errors::Forbidden.new 'msg', 'req', @response_stub
37
+ @s3.download_file(:key => 'key_name',
38
+ :bucket => 'bucket').should be_false
12
39
  end
13
40
 
14
- it "should download the specified file from s3" do
15
- s3_mock = mock 's3 mock'
16
- @s3.should_receive(:s3).and_return(s3_mock)
17
- s3_mock.should_receive(:get_object).
18
- with 'bucket', 'key_name'
19
- @s3.download_file :key => 'key_name',
20
- :bucket => 'bucket'
41
+ it "should return an error if the object not found / forbidden" do
42
+ @logger_mock.should_receive(:error).with('Access Denied')
43
+ @s3_mock.should_receive(:get_object).
44
+ with('bucket', 'key_name').
45
+ and_raise Excon::Errors::NotFound.new 'msg', 'req', @response_stub
46
+ @s3.download_file(:key => 'key_name',
47
+ :bucket => 'bucket').should be_false
21
48
  end
49
+ end
22
50
 
23
51
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: heirloom
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.8.3
4
+ version: 0.9.0
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,11 +9,11 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2012-11-19 00:00:00.000000000 Z
12
+ date: 2012-12-01 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: rspec
16
- requirement: &70288889244580 !ruby/object:Gem::Requirement
16
+ requirement: &70302923492580 !ruby/object:Gem::Requirement
17
17
  none: false
18
18
  requirements:
19
19
  - - ~>
@@ -21,10 +21,10 @@ dependencies:
21
21
  version: 2.11.0
22
22
  type: :development
23
23
  prerelease: false
24
- version_requirements: *70288889244580
24
+ version_requirements: *70302923492580
25
25
  - !ruby/object:Gem::Dependency
26
26
  name: rake
27
- requirement: &70288889253380 !ruby/object:Gem::Requirement
27
+ requirement: &70302923545380 !ruby/object:Gem::Requirement
28
28
  none: false
29
29
  requirements:
30
30
  - - ! '>='
@@ -32,40 +32,40 @@ dependencies:
32
32
  version: '0'
33
33
  type: :development
34
34
  prerelease: false
35
- version_requirements: *70288889253380
35
+ version_requirements: *70302923545380
36
36
  - !ruby/object:Gem::Dependency
37
37
  name: fog
38
- requirement: &70288889249440 !ruby/object:Gem::Requirement
38
+ requirement: &70302923542440 !ruby/object:Gem::Requirement
39
39
  none: false
40
40
  requirements:
41
41
  - - ~>
42
42
  - !ruby/object:Gem::Version
43
- version: 1.5.0
43
+ version: 1.6.0
44
44
  type: :runtime
45
45
  prerelease: false
46
- version_requirements: *70288889249440
46
+ version_requirements: *70302923542440
47
47
  - !ruby/object:Gem::Dependency
48
- name: grit
49
- requirement: &70288889247600 !ruby/object:Gem::Requirement
48
+ name: trollop
49
+ requirement: &70302923623680 !ruby/object:Gem::Requirement
50
50
  none: false
51
51
  requirements:
52
- - - ~>
52
+ - - =
53
53
  - !ruby/object:Gem::Version
54
- version: 2.5.0
54
+ version: '2.0'
55
55
  type: :runtime
56
56
  prerelease: false
57
- version_requirements: *70288889247600
57
+ version_requirements: *70302923623680
58
58
  - !ruby/object:Gem::Dependency
59
- name: trollop
60
- requirement: &70288889097340 !ruby/object:Gem::Requirement
59
+ name: xml-simple
60
+ requirement: &70302923692740 !ruby/object:Gem::Requirement
61
61
  none: false
62
62
  requirements:
63
- - - =
63
+ - - ~>
64
64
  - !ruby/object:Gem::Version
65
- version: '2.0'
65
+ version: 1.1.2
66
66
  type: :runtime
67
67
  prerelease: false
68
- version_requirements: *70288889097340
68
+ version_requirements: *70302923692740
69
69
  description: I help build and manage building tar.gz files and deploying them into
70
70
  the cloud
71
71
  email:
@@ -135,7 +135,6 @@ files:
135
135
  - lib/heirloom/destroyer/s3.rb
136
136
  - lib/heirloom/directory.rb
137
137
  - lib/heirloom/directory/directory.rb
138
- - lib/heirloom/directory/git_directory.rb
139
138
  - lib/heirloom/downloader.rb
140
139
  - lib/heirloom/downloader/s3.rb
141
140
  - lib/heirloom/logger.rb
@@ -184,7 +183,6 @@ files:
184
183
  - spec/config_spec.rb
185
184
  - spec/destroyer/s3_spec.rb
186
185
  - spec/directory/directory_spec.rb
187
- - spec/directory/git_directory_spec.rb
188
186
  - spec/downloader/s3_spec.rb
189
187
  - spec/logger_spec.rb
190
188
  - spec/spec_helper.rb
@@ -202,7 +200,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
202
200
  version: '0'
203
201
  segments:
204
202
  - 0
205
- hash: 3211129644745839536
203
+ hash: -2336051542288959986
206
204
  required_rubygems_version: !ruby/object:Gem::Requirement
207
205
  none: false
208
206
  requirements:
@@ -211,7 +209,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
211
209
  version: '0'
212
210
  segments:
213
211
  - 0
214
- hash: 3211129644745839536
212
+ hash: -2336051542288959986
215
213
  requirements: []
216
214
  rubyforge_project: heirloom
217
215
  rubygems_version: 1.8.16
@@ -261,7 +259,6 @@ test_files:
261
259
  - spec/config_spec.rb
262
260
  - spec/destroyer/s3_spec.rb
263
261
  - spec/directory/directory_spec.rb
264
- - spec/directory/git_directory_spec.rb
265
262
  - spec/downloader/s3_spec.rb
266
263
  - spec/logger_spec.rb
267
264
  - spec/spec_helper.rb
@@ -1,33 +0,0 @@
1
- require 'grit'
2
-
3
- include Grit
4
-
5
- module Heirloom
6
-
7
- class GitDirectory
8
-
9
- def initialize(args)
10
- @path = args[:path]
11
- end
12
-
13
- def commit(sha = nil)
14
- return false unless repo
15
-
16
- if sha
17
- commit = repo.commits(sha)
18
- commit ? commit.first : false
19
- else
20
- repo.commits.first
21
- end
22
- end
23
-
24
- private
25
-
26
- def repo
27
- Repo.new @path
28
- rescue Grit::InvalidGitRepositoryError
29
- false
30
- end
31
-
32
- end
33
- end
@@ -1,47 +0,0 @@
1
- require 'spec_helper'
2
-
3
- describe Heirloom do
4
-
5
- describe 'commit' do
6
- before do
7
- @repo_mock = double 'repo mock'
8
- @git_directory = Heirloom::GitDirectory.new :path => '/target/dir'
9
- end
10
-
11
- context "when dir is git repo" do
12
- before do
13
- Repo.should_receive(:new).with('/target/dir').exactly(2).times.
14
- and_return(@repo_mock)
15
- end
16
-
17
- it "should return the first commit from the given repo" do
18
- @repo_mock.stub(:commits).and_return(['git_sha', 'other_sha'])
19
- @git_directory.commit.should == 'git_sha'
20
- end
21
-
22
- it "should read commit from the given path" do
23
- @repo_mock.should_receive(:commits).
24
- with('sha_i_want').
25
- and_return(['sha_i_want', 'other_sha'])
26
- @git_directory.commit('sha_i_want').should == 'sha_i_want'
27
- end
28
-
29
- it "should return false if the commit given does not exist" do
30
- @repo_mock.should_receive(:commits).
31
- with('sha_that_dont_exist').
32
- and_return(nil)
33
- @git_directory.commit('sha_that_dont_exist').should be_false
34
- end
35
- end
36
-
37
- context "when dir is not git repo" do
38
- it "should return false if the directory is not a git repo" do
39
- Repo.should_receive(:new).with('/target/dir').
40
- and_raise Grit::InvalidGitRepositoryError
41
- @git_directory.commit.should be_false
42
- end
43
- end
44
-
45
- end
46
-
47
- end