s3_meta_sync 0.14.1 → 0.15.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.
- checksums.yaml +4 -4
- data/lib/s3_meta_sync/syncer.rb +80 -22
- data/lib/s3_meta_sync/version.rb +1 -1
- metadata +3 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 54ffd2915e5dfbe58348d826c002b29391c71c8719ed6f977534f36ac86364b2
|
4
|
+
data.tar.gz: b512d0459d0ad43a424dcbf5cb4d8bab09a8199a285b1d365e50f38680ab9319
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 5a5e0d249232112ba415541f8d6185739aaf6ca913fd92d3f8e5ec1fc5af5c8eedef24398446f4b9143ab0a003eaba847e3bb1150eaef45ef146523dab82bb6a
|
7
|
+
data.tar.gz: 446490567aabed72d68b5ffac4d6692c31ebf1a021cc58aecfb4608013f2a00f27c5abc246626cdc433d4e1f9b7923d466b70f843c0c9da280151adf6a0a64d8
|
data/lib/s3_meta_sync/syncer.rb
CHANGED
@@ -7,17 +7,24 @@ require "digest/md5"
|
|
7
7
|
require "fileutils"
|
8
8
|
require "tmpdir"
|
9
9
|
require "openssl"
|
10
|
+
require "mime/types"
|
10
11
|
|
11
12
|
require "aws-sdk-s3"
|
12
13
|
require "s3_meta_sync/zip"
|
13
14
|
|
14
15
|
module S3MetaSync
|
15
16
|
class Syncer
|
16
|
-
DEFAULT_REGION =
|
17
|
+
DEFAULT_REGION = "us-east-1"
|
17
18
|
STAGING_AREA_PREFIX = "s3ms_"
|
18
19
|
|
20
|
+
AWS_PUBLIC_ACCESS = "public-read"
|
21
|
+
AWS_PRIVATE_ACCESS = "private"
|
22
|
+
|
19
23
|
def initialize(config)
|
20
|
-
@config =
|
24
|
+
@config = {
|
25
|
+
acl: AWS_PUBLIC_ACCESS,
|
26
|
+
region: DEFAULT_REGION
|
27
|
+
}.merge(config)
|
21
28
|
end
|
22
29
|
|
23
30
|
def sync(source, destination)
|
@@ -95,7 +102,7 @@ module S3MetaSync
|
|
95
102
|
# Sometimes SIGTERM causes Dir.mktmpdir to not properly delete the temp folder
|
96
103
|
# Remove 1 day old folders
|
97
104
|
def delete_old_temp_folders
|
98
|
-
path = File.join(Dir.tmpdir, STAGING_AREA_PREFIX +
|
105
|
+
path = File.join(Dir.tmpdir, STAGING_AREA_PREFIX + "*")
|
99
106
|
|
100
107
|
day = 24 * 60 * 60
|
101
108
|
dirs = Dir.glob(path)
|
@@ -163,10 +170,12 @@ module S3MetaSync
|
|
163
170
|
content = Zip.zip(content) if @config[:zip] && path != META_FILE
|
164
171
|
|
165
172
|
object = {
|
173
|
+
acl: @config[:acl],
|
166
174
|
bucket: @bucket,
|
167
175
|
body: content,
|
168
|
-
|
169
|
-
|
176
|
+
content_encoding: content.encoding.to_s,
|
177
|
+
content_type: MIME::Types.of(path).first.to_s,
|
178
|
+
key: "#{destination}/#{path}"
|
170
179
|
}
|
171
180
|
|
172
181
|
object[:server_side_encryption] = @config[:server_side_encryption] if @config[:server_side_encryption]
|
@@ -197,11 +206,19 @@ module S3MetaSync
|
|
197
206
|
end
|
198
207
|
|
199
208
|
def s3
|
200
|
-
@s3 ||=
|
201
|
-
|
202
|
-
|
203
|
-
|
204
|
-
|
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
|
205
222
|
end
|
206
223
|
|
207
224
|
def generate_meta(source)
|
@@ -239,19 +256,43 @@ module S3MetaSync
|
|
239
256
|
end
|
240
257
|
|
241
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)
|
242
283
|
content = download_content("#{destination}/#{META_FILE}") { |io| io.read }
|
243
|
-
|
284
|
+
|
285
|
+
raise OpenURI::HTTPError.new("Content is empty", nil) if content.size == 0
|
244
286
|
|
245
287
|
parse_yaml_content(content)
|
246
288
|
rescue OpenURI::HTTPError
|
247
289
|
retries ||= 0
|
290
|
+
|
291
|
+
raise S3MetaSync::RemoteWithoutMeta if retries >= 1
|
292
|
+
|
248
293
|
retries += 1
|
249
|
-
|
250
|
-
|
251
|
-
retry
|
252
|
-
else
|
253
|
-
raise RemoteWithoutMeta
|
254
|
-
end
|
294
|
+
sleep 1 # maybe the remote meta was just updated ... give aws a second chance ...
|
295
|
+
retry
|
255
296
|
end
|
256
297
|
|
257
298
|
def parse_yaml_content(content)
|
@@ -260,16 +301,29 @@ module S3MetaSync
|
|
260
301
|
end
|
261
302
|
|
262
303
|
def download_file(source, path, destination, zip)
|
263
|
-
download =
|
264
|
-
|
265
|
-
|
266
|
-
|
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}"))
|
267
312
|
|
268
313
|
# consumes less ram then File.write(path, content), possibly also faster
|
269
|
-
File.open(path,
|
314
|
+
File.open("#{destination}/#{path}", "wb") { |f| IO.copy_stream(download, f) }
|
270
315
|
download.close
|
271
316
|
end
|
272
317
|
|
318
|
+
def private_content_download(source, path)
|
319
|
+
obj = s3.get_object(bucket: @bucket, key: "#{source}/#{path}")
|
320
|
+
obj.body
|
321
|
+
end
|
322
|
+
|
323
|
+
def public_content_download(source, path)
|
324
|
+
download_content("#{source}/#{path}") # warning: using block form consumes more ram
|
325
|
+
end
|
326
|
+
|
273
327
|
def download_content(path)
|
274
328
|
log "Downloading #{path}"
|
275
329
|
url =
|
@@ -346,5 +400,9 @@ module S3MetaSync
|
|
346
400
|
def log(text, important=false)
|
347
401
|
$stderr.puts text if @config[:verbose] or important
|
348
402
|
end
|
403
|
+
|
404
|
+
def private?
|
405
|
+
@config[:acl] == AWS_PRIVATE_ACCESS
|
406
|
+
end
|
349
407
|
end
|
350
408
|
end
|
data/lib/s3_meta_sync/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: s3_meta_sync
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.15.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Michael Grosser
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2020-05-07 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: aws-sdk-s3
|
@@ -55,8 +55,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
55
55
|
- !ruby/object:Gem::Version
|
56
56
|
version: '0'
|
57
57
|
requirements: []
|
58
|
-
|
59
|
-
rubygems_version: 2.7.6
|
58
|
+
rubygems_version: 3.0.3
|
60
59
|
signing_key:
|
61
60
|
specification_version: 4
|
62
61
|
summary: Sync folders with s3 using a metadata file and md5 diffs
|