s3_meta_sync 0.13.1 → 0.15.2

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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
- SHA1:
3
- metadata.gz: 216269b8e8057ed05a79cfdc52324704203c57e5
4
- data.tar.gz: 924fd0b552fbe6734acb3c89e5cb3193bff08f1d
2
+ SHA256:
3
+ metadata.gz: eb3dcbb8679154cb0863f3c13ba43d5c828220cbc2f0624346c19cf3617dd358
4
+ data.tar.gz: 6973f43e1a0bad829be2748ec65e447a2f7e96c16b2d95746d3bfad1e8daa0ea
5
5
  SHA512:
6
- metadata.gz: 8ea2a75355336b6c88d303ed183d5681819c4d560f3edcde9bdfc1aca872ec690b9032abcd97e8d7c8aba36bd76bf7d2e0924903450512eb61b7642582b23134
7
- data.tar.gz: 0c59e4cfb6a6630f932385e573209f644b39498336ab9fe379a104a579834518eaada8cba94dcccb4e77f910ebc719b3d1bc1779e18b1bd964ef6f64ec83d60f
6
+ metadata.gz: e6aca9b4086bf08b5bb18ea74622fd4ad45fa783440246499459e5d8663b331ab3b63cef7ce2c78a8eb66eb7ae6470e5fffd2beb43ab95363d38f96bf60128b5
7
+ data.tar.gz: d8c6e284debf19ac52094a3ec1e36cb158b318b3c655fbc5a63a9c65ebc236048c24af184327a8085acfe11b082395a53a3e199e654e63cb0ca6195b455e4a8c
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require "optparse"
2
4
  require "s3_meta_sync/version"
3
5
  require "s3_meta_sync/syncer"
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require "net/http"
2
4
  require "open-uri"
3
5
  require "yaml"
@@ -5,17 +7,24 @@ require "digest/md5"
5
7
  require "fileutils"
6
8
  require "tmpdir"
7
9
  require "openssl"
10
+ require "mime/types"
8
11
 
9
- require "aws-sdk-core"
12
+ require "aws-sdk-s3"
10
13
  require "s3_meta_sync/zip"
11
14
 
12
15
  module S3MetaSync
13
16
  class Syncer
14
- DEFAULT_REGION = 'us-east-1'
17
+ DEFAULT_REGION = "us-east-1"
15
18
  STAGING_AREA_PREFIX = "s3ms_"
16
19
 
20
+ AWS_PUBLIC_ACCESS = "public-read"
21
+ AWS_PRIVATE_ACCESS = "private"
22
+
17
23
  def initialize(config)
18
- @config = config
24
+ @config = {
25
+ acl: AWS_PUBLIC_ACCESS,
26
+ region: DEFAULT_REGION
27
+ }.merge(config)
19
28
  end
20
29
 
21
30
  def sync(source, destination)
@@ -93,7 +102,7 @@ module S3MetaSync
93
102
  # Sometimes SIGTERM causes Dir.mktmpdir to not properly delete the temp folder
94
103
  # Remove 1 day old folders
95
104
  def delete_old_temp_folders
96
- path = File.join(Dir.tmpdir, STAGING_AREA_PREFIX + '*')
105
+ path = File.join(Dir.tmpdir, STAGING_AREA_PREFIX + "*")
97
106
 
98
107
  day = 24 * 60 * 60
99
108
  dirs = Dir.glob(path)
@@ -161,10 +170,12 @@ module S3MetaSync
161
170
  content = Zip.zip(content) if @config[:zip] && path != META_FILE
162
171
 
163
172
  object = {
173
+ acl: @config[:acl],
164
174
  bucket: @bucket,
165
175
  body: content,
166
- key: "#{destination}/#{path}",
167
- acl: 'public-read'
176
+ content_encoding: content.encoding.to_s,
177
+ content_type: MIME::Types.of(path).first.to_s,
178
+ key: "#{destination}/#{path}"
168
179
  }
169
180
 
170
181
  object[:server_side_encryption] = @config[:server_side_encryption] if @config[:server_side_encryption]
@@ -195,11 +206,19 @@ module S3MetaSync
195
206
  end
196
207
 
197
208
  def s3
198
- @s3 ||= ::Aws::S3::Client.new(
199
- access_key_id: @config[:key],
200
- secret_access_key: @config[:secret],
201
- region: @config[:region] || 'us-west-2'
202
- )
209
+ @s3 ||= begin
210
+ config = { region: @config[:region] }
211
+
212
+ if @config[:credentials_path]
213
+ config[:credentials] = Aws::SharedCredentials.new(path: @config[:credentials_path], profile_name: "default")
214
+ else
215
+ config[:access_key_id] = @config[:key]
216
+ config[:secret_access_key] = @config[:secret]
217
+ config[:session_token] = @config[:session_token] if @config[:session_token]
218
+ end
219
+
220
+ Aws::S3::Client.new(config)
221
+ end
203
222
  end
204
223
 
205
224
  def generate_meta(source)
@@ -230,21 +249,50 @@ module S3MetaSync
230
249
 
231
250
  def read_meta(source)
232
251
  file = "#{source}/#{META_FILE}"
233
- parse_yaml_content(File.read(file)) if File.exist?(file)
252
+ if File.exist?(file)
253
+ content = File.read(file)
254
+ parse_yaml_content(content) if content.size > 0
255
+ end
234
256
  end
235
257
 
236
258
  def download_meta(destination)
259
+ if private?
260
+ private_access_download_meta(destination)
261
+ else
262
+ public_access_download_meta(destination)
263
+ end
264
+ end
265
+
266
+ def private_access_download_meta(destination)
267
+ content = private_content_download(destination, META_FILE).string
268
+
269
+ raise S3MetaSync::RemoteWithoutMeta if content.empty? # if missing, upload everything
270
+
271
+ parse_yaml_content(content)
272
+ rescue Aws::S3::Errors::NoSuchKey, Aws::S3::Errors::AccessDenied # if requesting a file that doesn't exist AccessDenied is raised
273
+ retries ||= 0
274
+
275
+ raise S3MetaSync::RemoteWithoutMeta if retries >= 1
276
+
277
+ retries += 1
278
+ sleep 1 # maybe the remote meta was just updated ... give aws a second chance ...
279
+ retry
280
+ end
281
+
282
+ def public_access_download_meta(destination)
237
283
  content = download_content("#{destination}/#{META_FILE}") { |io| io.read }
284
+
285
+ raise OpenURI::HTTPError.new("Content is empty", nil) if content.size == 0
286
+
238
287
  parse_yaml_content(content)
239
288
  rescue OpenURI::HTTPError
240
289
  retries ||= 0
290
+
291
+ raise S3MetaSync::RemoteWithoutMeta if retries >= 1
292
+
241
293
  retries += 1
242
- if retries <= 1
243
- sleep 1 # maybe the remote meta was just updated ... give aws a second chance ...
244
- retry
245
- else
246
- raise RemoteWithoutMeta
247
- end
294
+ sleep 1 # maybe the remote meta was just updated ... give aws a second chance ...
295
+ retry
248
296
  end
249
297
 
250
298
  def parse_yaml_content(content)
@@ -253,16 +301,30 @@ module S3MetaSync
253
301
  end
254
302
 
255
303
  def download_file(source, path, destination, zip)
256
- download = download_content("#{source}/#{path}") # warning: using block form consumes more ram
257
- download = Zip.unzip(download) if zip
258
- path = "#{destination}/#{path}"
259
- FileUtils.mkdir_p(File.dirname(path))
304
+ download = if private?
305
+ private_content_download(source, path)
306
+ else
307
+ public_content_download(source, path)
308
+ end
309
+
310
+ download = S3MetaSync::Zip.unzip(download) if zip
311
+ FileUtils.mkdir_p(File.dirname("#{destination}/#{path}"))
260
312
 
261
313
  # consumes less ram then File.write(path, content), possibly also faster
262
- File.open(path, 'wb') { |f| IO.copy_stream(download, f) }
314
+ File.open("#{destination}/#{path}", "wb") { |f| IO.copy_stream(download, f) }
263
315
  download.close
264
316
  end
265
317
 
318
+ def private_content_download(source, path)
319
+ log "Downloading #{path}"
320
+ obj = s3.get_object(bucket: @bucket, key: "#{source}/#{path}")
321
+ obj.body
322
+ end
323
+
324
+ def public_content_download(source, path)
325
+ download_content("#{source}/#{path}") # warning: using block form consumes more ram
326
+ end
327
+
266
328
  def download_content(path)
267
329
  log "Downloading #{path}"
268
330
  url =
@@ -287,8 +349,7 @@ module S3MetaSync
287
349
  log "#{e.class} error downloading #{url}, retrying #{http_error_retries}/#{max_retries}"
288
350
  retry
289
351
  else
290
- $!.message << " -- while trying to download #{url}"
291
- raise
352
+ raise $!, "#{$!.message} -- while trying to download #{url}", $!.backtrace
292
353
  end
293
354
  rescue OpenSSL::SSL::SSLError
294
355
  ssl_error_retries ||= 0
@@ -340,5 +401,9 @@ module S3MetaSync
340
401
  def log(text, important=false)
341
402
  $stderr.puts text if @config[:verbose] or important
342
403
  end
404
+
405
+ def private?
406
+ @config[:acl] == AWS_PRIVATE_ACCESS
407
+ end
343
408
  end
344
409
  end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module S3MetaSync
2
- VERSION = "0.13.1"
4
+ VERSION = "0.15.2"
3
5
  end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require "zlib"
2
4
  require "stringio"
3
5
 
@@ -5,7 +7,7 @@ module S3MetaSync
5
7
  module Zip
6
8
  class << self
7
9
  def zip(string)
8
- io = StringIO.new("w")
10
+ io = StringIO.new("w".dup)
9
11
  w_gz = Zlib::GzipWriter.new(io)
10
12
  w_gz.write(string)
11
13
  w_gz.close
metadata CHANGED
@@ -1,29 +1,43 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: s3_meta_sync
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.13.1
4
+ version: 0.15.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Michael Grosser
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2017-12-05 00:00:00.000000000 Z
11
+ date: 2020-09-09 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
- name: aws-sdk-core
14
+ name: aws-sdk-s3
15
15
  requirement: !ruby/object:Gem::Requirement
16
16
  requirements:
17
17
  - - "~>"
18
18
  - !ruby/object:Gem::Version
19
- version: '2.0'
19
+ version: '1.0'
20
20
  type: :runtime
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
24
  - - "~>"
25
25
  - !ruby/object:Gem::Version
26
- version: '2.0'
26
+ version: '1.0'
27
+ - !ruby/object:Gem::Dependency
28
+ name: mime-types
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ">="
32
+ - !ruby/object:Gem::Version
33
+ version: '0'
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ">="
39
+ - !ruby/object:Gem::Version
40
+ version: '0'
27
41
  description:
28
42
  email: michael@grosser.it
29
43
  executables:
@@ -55,8 +69,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
55
69
  - !ruby/object:Gem::Version
56
70
  version: '0'
57
71
  requirements: []
58
- rubyforge_project:
59
- rubygems_version: 2.4.5.1
72
+ rubygems_version: 3.1.4
60
73
  signing_key:
61
74
  specification_version: 4
62
75
  summary: Sync folders with s3 using a metadata file and md5 diffs