manifest-builder 0.5.8 → 0.5.10

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: d9a09d37c265bbc389e8d5d8a0b4c7ee3a495a42
4
- data.tar.gz: 838a631b3faff67079fba98b268a1f7951547d3c
3
+ metadata.gz: e60728ab2daaf198e0540b734c90ef98133e6e76
4
+ data.tar.gz: b1a51a36abf4c4dee729cf74f50f6f4b93d43bd3
5
5
  SHA512:
6
- metadata.gz: 0ae28e498ac10100dbde4fe533ef17049bfe36233242fd4ee6d024ce1a5ef7615e1a5bd5775e22de13b00eb97a795e8aabf18c059e18e86d82b2a6ba2494f4ac
7
- data.tar.gz: 20a3d1960607a42ecc2053ddf32ec8da18eb78d6b359a0cad2271c52da033d75a354fdd4001b2ca1cd241191fea16d4beedbff559c28c1253bec3a0743da6216
6
+ metadata.gz: 5189f9610b02429a865ed37e417f5d332e228d7eec4e0856347871a9eeb4bfc2dc3566d9302d0c79eb31fa21b8a3c3fea003a641d48b5076fbd068b98bff383a
7
+ data.tar.gz: 49749634786c6eeb406a3a3c98cc6b85c7fc1288a02cec37b51b6674a60d2b2bae2bb56ffb78a3cf837e6430917aafb4cb2e9dc75da7d39219e76b0fff445ff9
data/Gemfile.lock CHANGED
@@ -1,10 +1,10 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- manifest-builder (0.5.8)
4
+ manifest-builder (0.5.10)
5
5
  archive-tar-minitar (= 0.5.2)
6
6
  chefrepo-builder (>= 0.9.27, < 1.1)
7
- cicd-builder (>= 0.9.38, < 1.1)
7
+ cicd-builder (>= 0.9.40, < 1.1)
8
8
  json (>= 1.8.1, < 1.9)
9
9
  s3etag (>= 0.0.1, < 0.1.0)
10
10
 
@@ -18,7 +18,7 @@ PATH
18
18
  PATH
19
19
  remote: ../cicd-builder
20
20
  specs:
21
- cicd-builder (0.9.38)
21
+ cicd-builder (0.9.40)
22
22
  artifactory (>= 2.2.1, < 2.3)
23
23
  awesome_print (>= 1.6, < 2.0)
24
24
  aws-sdk (>= 2.0, < 2.1)
@@ -2,7 +2,7 @@ module CiCd
2
2
  module Builder
3
3
  module Manifest
4
4
  # manifest-builder version
5
- VERSION = '0.5.8'
5
+ VERSION = '0.5.10'
6
6
  MAJOR, MINOR, TINY = VERSION.split('.')
7
7
  PATCH = TINY
8
8
  end
@@ -17,7 +17,7 @@ Gem::Specification.new do |gem|
17
17
  gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
18
18
  gem.require_paths = ['lib']
19
19
 
20
- gem.add_dependency 'cicd-builder', '>= 0.9.38', '< 1.1'
20
+ gem.add_dependency 'cicd-builder', '>= 0.9.40', '< 1.1'
21
21
  gem.add_dependency 'chefrepo-builder', '>= 0.9.27', '< 1.1'
22
22
  # gem.add_dependency 'ansiblerepo-builder', '>= 0.3.7', '< 0.5'
23
23
  gem.add_dependency 'json', '>= 1.8.1', '< 1.9'
@@ -0,0 +1,166 @@
1
+ require 'aws-sdk-core'
2
+ require 'aws-sdk-resources'
3
+ require 'uri'
4
+
5
+ # ---------------------------------------------------------------------------------------------------------------
6
+ def getS3()
7
+ region = ENV['AWS_REGION'] || ::Aws.config[:region] || 'us-east-1'
8
+ unless @s3
9
+ # noinspection RubyArgCount
10
+ @s3 = ::Aws::S3::Client.new(region: region)
11
+ end
12
+ unless @s3 and ((@s3.config.access_key_id and @s3.config.secret_access_key) or @s3.config.credentials)
13
+ @logger.warn "Unable to find AWS credentials in standard locations:
14
+ ENV['AWS_ACCESS_KEY'] and ENV['AWS_SECRET_ACCESS_KEY']
15
+ Aws.config[:credentials]
16
+ Shared credentials file, ~/.aws/credentials
17
+ EC2 Instance profile
18
+ "
19
+ if ENV['AWS_PROFILE']
20
+ @logger.info "Trying profile '#{ENV['AWS_PROFILE']}' explicitly"
21
+ creds = Aws::SharedCredentials.new( path: File.expand_path('~/.aws/credentials'), profile: ENV['AWS_PROFILE'] )
22
+ if creds.loadable?
23
+ # noinspection RubyArgCount
24
+ @s3 = ::Aws::S3::Client.new(region: region, credentials: creds)
25
+ end
26
+ else
27
+ @logger.warn 'No AWS_PROFILE defined'
28
+ end
29
+ end
30
+ unless @s3 and ((@s3.config.access_key_id and @s3.config.secret_access_key) or @s3.config.credentials)
31
+ raise 'Unable to find AWS credentials!'
32
+ end
33
+ @s3
34
+ end
35
+
36
+ # ---------------------------------------------------------------------------------------------------------------
37
+ def getBucket(name = nil)
38
+ @s3 = getS3()
39
+ begin
40
+ ::Aws::S3::Bucket.new(name: name || ENV['AWS_S3_BUCKET'], client: @s3)
41
+ rescue Aws::S3::Errors::NotFound
42
+ @vars[:return_code] = Errors::BUCKET
43
+ nil
44
+ rescue Exception => e
45
+ @logger.error "S3 Bucket resource API error: #{e.class.name} #{e.message}"
46
+ raise e
47
+ end
48
+ end
49
+
50
+ # ---------------------------------------------------------------------------------------------------------------
51
+ def getObjects(artifact, path)
52
+ parts = URI(path).path.gsub(%r'^#{File::SEPARATOR}', '').split(File::SEPARATOR)
53
+ name = parts.shift
54
+ bucket = getBucket(name)
55
+ key = File.join(parts, '')
56
+ @logger.info "S3://#{name}:#{key} URL: #{path} #{artifact}"
57
+ objects = []
58
+ bucket.objects(prefix: key).each do |object|
59
+ if artifact.empty? or (not artifact.empty? and object.key =~ %r'#{key}#{artifact}')
60
+ objects << object
61
+ end
62
+ end
63
+ @logger.debug "S3://#{name}:#{key} has #{objects.size} objects"
64
+ return key, name, objects
65
+ end
66
+
67
+ # ---------------------------------------------------------------------------------------------------------------
68
+ def calcLocalETag(etag, local, size = nil)
69
+ if size == nil
70
+ stat = File.stat(local)
71
+ size = stat.size
72
+ end
73
+ @logger.debug "Calculate etag to match #{etag}"
74
+ match = etag.match(%r'-(\d+)$')
75
+ check = if match
76
+ require 's3etag'
77
+ parts = match[1].to_i
78
+ chunk = size.to_f / parts.to_f
79
+ mbs = (chunk.to_f / 1024 /1024 + 0.5).to_i
80
+ part_size = mbs * 1024 * 1024
81
+ chkit = S3Etag.calc(file: local, threshold: part_size, min_part_size: part_size, max_parts: parts)
82
+ @logger.debug "S3Etag Calculated #{chkit} : (#{size} / #{part_size}) <= #{parts}"
83
+ chunks = size / part_size
84
+ while chkit != etag and chunks <= parts and chunks > 0 and (size > part_size)
85
+ # Go one larger if a modulus remains and we have the right number of parts
86
+ mbs += 1
87
+ part_size = mbs * 1024 * 1024
88
+ chunks = size.to_f / part_size
89
+ chkit = S3Etag.calc(file: local, threshold: part_size, min_part_size: part_size, max_parts: parts)
90
+ @logger.debug "S3Etag Calculated #{chkit} : (#{size} / #{part_size}) <= #{parts}"
91
+ end
92
+ raise "Unable to match etag #{etag}!" if chkit != etag
93
+ chkit
94
+ else
95
+ Digest::MD5.file(local).hexdigest
96
+ end
97
+ end
98
+
99
+ # ---------------------------------------------------------------------------------------------------------------
100
+ def shouldDownload?(etag, local, object)
101
+ if File.exists?(local)
102
+ @logger.debug "\t\tchecking etag on #{local}"
103
+ stat = File.stat(local)
104
+ check = calcLocalETag(etag, local, stat.size)
105
+ if etag != check or object.size != stat.size or object.last_modified > stat.mtime
106
+ @logger.debug "\t\t#{etag} != \"#{check}\" #{object.size} != #{stat.size} #{object.last_modified} > #{stat.mtime}"
107
+ true
108
+ else
109
+ @logger.debug "\t\tmatched #{etag}"
110
+ false
111
+ end
112
+ else
113
+ true
114
+ end
115
+ end
116
+
117
+ # ---------------------------------------------------------------------------------------------------------------
118
+ def doDownload(etag, local, object)
119
+ @logger.info "\t\tdownload #{object.size} bytes"
120
+ response = object.get(:response_target => local)
121
+ File.utime(response.last_modified, response.last_modified, local)
122
+ @logger.info "\t\tdone"
123
+ check = calcLocalETag(etag, local)
124
+ if check.eql?(etag)
125
+ false
126
+ else
127
+ @logger.info "\tETag different: #{etag} != #{check}"
128
+ true
129
+ end
130
+ end
131
+
132
+
133
+ class FakeLogger
134
+ def initialize
135
+
136
+ end
137
+
138
+ def method_missing(*args)
139
+ puts "#{args[0]}: #{args[1..-1].join(' ')}"
140
+ end
141
+ end
142
+
143
+ @logger = FakeLogger.new()
144
+ artifact, path = ['', 'https://s3.amazonaws.com/wgen-sto-artifacts/release/com/amplify/learning/enrollment/1.3.0-265']
145
+ local_dir = File.join('/tmp', 'enrollment', '')
146
+ Dir.mkdir(local_dir, 0700) unless File.directory?(local_dir)
147
+ artifacts = []
148
+
149
+ key, name, objects = getObjects(artifact, path)
150
+ # 1 or more objects on the key/ path
151
+ if objects.size > 0
152
+ objects.each do |object|
153
+ @logger.info "\tchecking #{object.key}"
154
+ local = File.join(local_dir, File.basename(object.key))
155
+ etag = object.etag.gsub(%r/['"]/, '')
156
+ download = shouldDownload?(etag, local, object)
157
+ if download
158
+ changed = doDownload(etag, local, object)
159
+ else
160
+ @logger.info "\t\tunchanged"
161
+ end
162
+ artifacts << local
163
+ end
164
+ else
165
+ @logger.fatal "Artifact not found: s3://#{name}/#{key}#{artifact}"
166
+ end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: manifest-builder
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.5.8
4
+ version: 0.5.10
5
5
  platform: ruby
6
6
  authors:
7
7
  - Christo De Lange
@@ -16,7 +16,7 @@ dependencies:
16
16
  requirements:
17
17
  - - ">="
18
18
  - !ruby/object:Gem::Version
19
- version: 0.9.38
19
+ version: 0.9.40
20
20
  - - "<"
21
21
  - !ruby/object:Gem::Version
22
22
  version: '1.1'
@@ -26,7 +26,7 @@ dependencies:
26
26
  requirements:
27
27
  - - ">="
28
28
  - !ruby/object:Gem::Version
29
- version: 0.9.38
29
+ version: 0.9.40
30
30
  - - "<"
31
31
  - !ruby/object:Gem::Version
32
32
  version: '1.1'
@@ -235,6 +235,7 @@ files:
235
235
  - manifest-builder.gemspec
236
236
  - spec/builder_spec.rb
237
237
  - spec/spec_helper.rb
238
+ - tests/infinite-etag.rb
238
239
  homepage: https://rubygems.org/gems/manifest-builder
239
240
  licenses:
240
241
  - Apachev2