heirloom 0.8.3 → 0.9.0

Sign up to get free protection for your applications and to get access to all the features.
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