s3twin 0.0.1
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 +7 -0
- data/.env.sample +10 -0
- data/.gitignore +19 -0
- data/Gemfile +3 -0
- data/LICENSE +22 -0
- data/README.md +56 -0
- data/Rakefile +1 -0
- data/bin/s3twin +28 -0
- data/lib/s3twin.rb +7 -0
- data/lib/s3twin/helpers.rb +16 -0
- data/lib/s3twin/twin.rb +76 -0
- data/lib/s3twin/workers.rb +4 -0
- data/lib/s3twin/workers/ironworker.rb +61 -0
- data/s3twin.gemspec +29 -0
- metadata +172 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 8e79cbdb1aaaedc97087f56a0d1a8c83ea608b33
|
4
|
+
data.tar.gz: 795d2720da9737ca984aaadc034b972560d85d2d
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: fdb26f8d21a214c635bed2e2b6de2204e928d58af0df90752a62c33af55b5104f91c0753a0d71d80b9df472b15b5d01eae8a1f545925ab6a5bae84ba871e27eb
|
7
|
+
data.tar.gz: fae2ccd84a0ae1205941550841f4cebf9c63dfb4fec387bf21a39c1facf7ee519cb974ca768a6b2da2790f02f9f2539e7574ee2a69224c57f7f5740ac9a53281
|
data/.env.sample
ADDED
data/.gitignore
ADDED
data/Gemfile
ADDED
data/LICENSE
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
Copyright (c) 2013 Robert Coleman
|
2
|
+
|
3
|
+
MIT License
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
6
|
+
a copy of this software and associated documentation files (the
|
7
|
+
"Software"), to deal in the Software without restriction, including
|
8
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
9
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
10
|
+
permit persons to whom the Software is furnished to do so, subject to
|
11
|
+
the following conditions:
|
12
|
+
|
13
|
+
The above copyright notice and this permission notice shall be
|
14
|
+
included in all copies or substantial portions of the Software.
|
15
|
+
|
16
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
17
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
18
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
19
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
20
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
21
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
22
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,56 @@
|
|
1
|
+
# S3 Twin
|
2
|
+
|
3
|
+
Take a mirror of a S3 bucket. It leverages [aws-sdk's](http://docs.aws.amazon.com/AWSRubySDK/latest/AWS/S3/S3Object.html#copy_to-instance_method) `copy_to` function to do the heavy lifting at Amazon, similar to [s3cmd](http://s3tools.org/s3cmd-sync).
|
4
|
+
Supports local usage or remote workers, some of which may support scheduling - to keep a bucket's twin up to date.
|
5
|
+
|
6
|
+
One way copy only i.e. will not keep two buckets in sync.
|
7
|
+
Carries across Public ACLs only, no support for S3 features like server side encryption.
|
8
|
+
|
9
|
+
If an object exists in the source bucket and does not exist in the destiantion bucket it's copied.
|
10
|
+
If an object exists in both bucket and the [etags](http://docs.aws.amazon.com/AmazonS3/latest/dev/UsingMetadata.html) are identical the object is not copied, if the etags do not match the object is copied.
|
11
|
+
Does not remove object that have been deleted from the source bucket.
|
12
|
+
|
13
|
+
Please note; while this works it's the first release so the API may change drastically.
|
14
|
+
|
15
|
+
## Installation
|
16
|
+
|
17
|
+
`$ gem install s3twin`
|
18
|
+
|
19
|
+
## Usage
|
20
|
+
|
21
|
+
`$ s3twin help`
|
22
|
+
|
23
|
+
`$ s3twin go`
|
24
|
+
|
25
|
+
Example with payload:
|
26
|
+
`$ s3twin go --payload=source_bucket:bar source_access_key:foo source_secret_key:world destination_bucket:bar destination_access_key:foo destination_secret_key:world`
|
27
|
+
|
28
|
+
The payload can be set via an argument `--payload=key:value key2:value2` or `.env` file, if neither of those are present the user will be prompted for input.
|
29
|
+
|
30
|
+
### Remote Workers
|
31
|
+
|
32
|
+
Currently only [iron.io] IronWorker tasks (including scheduled) are supported.
|
33
|
+
|
34
|
+
#### IronWorker Usage
|
35
|
+
|
36
|
+
Create a new project at [https://hud.iron.io](https://hud.iron.io), collect your Iron Token and Project ID.
|
37
|
+
|
38
|
+
`$ s3twin ironworker upload`
|
39
|
+
`$ s3twin ironworker go`
|
40
|
+
`$ s3twin ironworker schedule --time `
|
41
|
+
|
42
|
+
Optionally create, or append, your `.env` file:
|
43
|
+
|
44
|
+
```bash
|
45
|
+
IRON_TOKEN='foo'
|
46
|
+
IRON_PROJECT_ID='bar'
|
47
|
+
```
|
48
|
+
|
49
|
+
|
50
|
+
## Contributing
|
51
|
+
|
52
|
+
1. Fork it
|
53
|
+
2. Create your feature branch (`git checkout -b my-new-feature`)
|
54
|
+
3. Commit your changes (`git commit -am 'Add some feature'`)
|
55
|
+
4. Push to the branch (`git push origin my-new-feature`)
|
56
|
+
5. Create new Pull Request
|
data/Rakefile
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
require 'bundler/gem_tasks'
|
data/bin/s3twin
ADDED
@@ -0,0 +1,28 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
require 'thor'
|
3
|
+
require 'dotenv'
|
4
|
+
Dotenv.load
|
5
|
+
|
6
|
+
$:.push File.expand_path('../../lib', __FILE__)
|
7
|
+
require 's3twin'
|
8
|
+
|
9
|
+
module S3twin
|
10
|
+
class S3twinCLI < Thor
|
11
|
+
include Thor::Actions
|
12
|
+
class_option :payload, :type => :hash, :default => {
|
13
|
+
'source_bucket' => ENV['SOURCE_S3_BUCKET'],
|
14
|
+
'source_access_key' => ENV['SOURCE_AWS_ACCESS_KEY_ID'],
|
15
|
+
'source_secret_key' => ENV['SOURCE_AWS_SECRET_ACCESS_KEY'],
|
16
|
+
'destination_bucket' => ENV['DESTINATION_S3_BUCKET'],
|
17
|
+
'destination_access_key' => ENV['DESTINATION_AWS_ACCESS_KEY_ID'],
|
18
|
+
'destination_secret_key' => ENV['DESTINATION_AWS_SECRET_ACCESS_KEY']
|
19
|
+
}
|
20
|
+
|
21
|
+
desc 'go', 'Make a twin of a S3 Bucket'
|
22
|
+
def go
|
23
|
+
Twin.go(S3twin::Helpers.prompt_payload(options['payload']))
|
24
|
+
end
|
25
|
+
# worker sub-commands live in ../lib/s3twin/workers
|
26
|
+
end
|
27
|
+
S3twinCLI.start
|
28
|
+
end
|
data/lib/s3twin.rb
ADDED
@@ -0,0 +1,16 @@
|
|
1
|
+
module S3twin::Helpers
|
2
|
+
class << self
|
3
|
+
|
4
|
+
def prompt_payload(payload)
|
5
|
+
payload['source_bucket'] ||= ask('Source Bucket:')
|
6
|
+
payload['source_access_key'] ||= ask('Source Access Key:')
|
7
|
+
payload['source_secret_key'] ||= ask('Source Secret Key:')
|
8
|
+
payload['destination_bucket'] ||= ask('Destination Bucket:')
|
9
|
+
payload['destination_access_key'] ||= ask('Destination Access Key:')
|
10
|
+
payload['destination_secret_key'] ||= ask('Destination Secret Key:')
|
11
|
+
return payload
|
12
|
+
end
|
13
|
+
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
data/lib/s3twin/twin.rb
ADDED
@@ -0,0 +1,76 @@
|
|
1
|
+
require 'aws-sdk'
|
2
|
+
|
3
|
+
class Twin
|
4
|
+
# these exist for ironworker compatibility. It should probaby be seperated out to a wrapper.
|
5
|
+
attr_accessor :source_bucket, :source_access_key, :source_secret_key, :destination_bucket, :destination_access_key, :destination_secret_key
|
6
|
+
def run
|
7
|
+
params = {
|
8
|
+
'source_bucket' => source_bucket,
|
9
|
+
'source_access_key' => source_access_key,
|
10
|
+
'source_secret_key' => source_secret_key,
|
11
|
+
'destination_bucket' => destination_bucket,
|
12
|
+
'destination_access_key' => destination_access_key,
|
13
|
+
'destination_secret_key' => destination_secret_key
|
14
|
+
}
|
15
|
+
Twin.go(params)
|
16
|
+
end
|
17
|
+
|
18
|
+
# Real stuff starts here
|
19
|
+
class << self
|
20
|
+
def go(params)
|
21
|
+
source_bucket = params['source_bucket']
|
22
|
+
source_access_key = params['source_access_key']
|
23
|
+
source_secret_key = params['source_secret_key']
|
24
|
+
destination_bucket = params['destination_bucket']
|
25
|
+
destination_access_key = params['destination_access_key']
|
26
|
+
destination_secret_key = params['destination_secret_key']
|
27
|
+
|
28
|
+
puts 'Starting S3Twin run'
|
29
|
+
@source = AWS::S3.new(
|
30
|
+
:access_key_id => source_access_key,
|
31
|
+
:secret_access_key => source_secret_key)
|
32
|
+
@source_bucket = @source.buckets[source_bucket]
|
33
|
+
|
34
|
+
@destination = AWS::S3.new(
|
35
|
+
:access_key_id => destination_access_key,
|
36
|
+
:secret_access_key => destination_secret_key)
|
37
|
+
@destination_bucket = @destination.buckets[destination_bucket]
|
38
|
+
|
39
|
+
@source_bucket.objects.each do |obj|
|
40
|
+
dest_key = @destination_bucket.objects[obj.key]
|
41
|
+
unless dest_key.exists?
|
42
|
+
puts "Creating: #{obj.key}"
|
43
|
+
obj.copy_to(dest_key, :acl => public_acl(obj))
|
44
|
+
else
|
45
|
+
unless etag_match(obj.key,obj.etag)
|
46
|
+
puts "Updating: #{obj.key}"
|
47
|
+
obj.copy_to(dest_key, :acl => public_acl(obj))
|
48
|
+
else
|
49
|
+
puts "Skipping: #{obj.key}"
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
53
|
+
puts 'Completed S3Twin run'
|
54
|
+
end
|
55
|
+
|
56
|
+
private
|
57
|
+
def public_acl(object)
|
58
|
+
object.acl.grants.each do |grant|
|
59
|
+
if grant.grantee.uri == 'http://acs.amazonaws.com/groups/global/AllUsers'
|
60
|
+
case grant.permission.name.to_s
|
61
|
+
when 'read'
|
62
|
+
return 'public_read'
|
63
|
+
when 'read_write'
|
64
|
+
return 'public_read_write'
|
65
|
+
else
|
66
|
+
return 'private'
|
67
|
+
end
|
68
|
+
end
|
69
|
+
end
|
70
|
+
end
|
71
|
+
|
72
|
+
def etag_match(key,etag)
|
73
|
+
etag == @destination_bucket.objects[key].etag
|
74
|
+
end
|
75
|
+
end
|
76
|
+
end
|
@@ -0,0 +1,61 @@
|
|
1
|
+
require 'iron_worker_ng'
|
2
|
+
|
3
|
+
module S3twin
|
4
|
+
class Ironworker < Thor
|
5
|
+
class_option :name, :type => :string, :default => 'S3Twin'
|
6
|
+
class_option :credentials, :type => :hash, :default => {
|
7
|
+
'token' => ENV['IRON_TOKEN'],
|
8
|
+
'project_id' => ENV['IRON_PROJECT_ID']
|
9
|
+
}
|
10
|
+
|
11
|
+
desc 'upload NAME', 'Upload our worker'
|
12
|
+
def upload
|
13
|
+
client = IronWorkerNG::Client.new(prompt_credentials(options['credentials']))
|
14
|
+
code = IronWorkerNG::Code::Base.new
|
15
|
+
code.runtime = 'ruby'
|
16
|
+
code.name = options['name']
|
17
|
+
code.full_remote_build = true
|
18
|
+
code.merge_exec('lib/s3twin/twin.rb','Twin')
|
19
|
+
code.merge_gem 'aws-sdk'
|
20
|
+
client.codes.create(code)
|
21
|
+
end
|
22
|
+
|
23
|
+
desc 'go WORKER', 'Queue a worker'
|
24
|
+
def go
|
25
|
+
payload = S3twin::Helpers.prompt_payload(options['payload'])
|
26
|
+
client = IronWorkerNG::Client.new(prompt_credentials(options['credentials']))
|
27
|
+
client.tasks.create(options['name'],payload)
|
28
|
+
puts "#{options['name']} queued! Details at https://hud.iron.io/"
|
29
|
+
end
|
30
|
+
|
31
|
+
method_option :time, :type => :hash, :default => {}
|
32
|
+
desc 'schedule WORKER', 'Schedule a worker'
|
33
|
+
def schedule(name='S3Twin')
|
34
|
+
payload = S3twin::Helpers.prompt_payload(options['payload'])
|
35
|
+
time = prompt_time(options['time'])
|
36
|
+
client = IronWorkerNG::Client.new(prompt_credentials(options['credentials']))
|
37
|
+
schedule = client.schedules.create(options['name'],payload,time)
|
38
|
+
puts "#{options['name']} scheduled! (id:#{schedule.id})"
|
39
|
+
end
|
40
|
+
|
41
|
+
private
|
42
|
+
def prompt_time(time)
|
43
|
+
time['run_every'] ||= ask('The amount of time, in seconds, between runs. By default, the task will only run once. Must be greater than 60:').to_i
|
44
|
+
#time['end_at'] ||= ask('The time tasks will stop being queued. Should be a time or datetime:')
|
45
|
+
#time['run_times'] ||= ask('Number of times the task will run:')
|
46
|
+
#time['priority'] ||= ask('The priority queue to run the job in. Higher values means tasks spend less time in the queue once they come off the schedule:', :limited_to => ['0','1','2'])
|
47
|
+
return time
|
48
|
+
end
|
49
|
+
|
50
|
+
def prompt_credentials(credentials)
|
51
|
+
credentials['token'] ||= ask('Iron.io Token:')
|
52
|
+
credentials['project_id'] ||= ask('Iron.io project ID:')
|
53
|
+
return credentials
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
class S3twinCLI < Thor
|
58
|
+
desc 'ironworker SUBCOMMAND ...ARGS', 'IronWorker tasks'
|
59
|
+
subcommand 'ironworker', Ironworker
|
60
|
+
end
|
61
|
+
end
|
data/s3twin.gemspec
ADDED
@@ -0,0 +1,29 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
$:.push File.expand_path('../lib', __FILE__)
|
3
|
+
require 's3twin'
|
4
|
+
|
5
|
+
Gem::Specification.new do |spec|
|
6
|
+
spec.name = 's3twin'
|
7
|
+
spec.version = S3twin::VERSION
|
8
|
+
spec.authors = ['Robert Coleman']
|
9
|
+
spec.email = ['github@robert.net.nz']
|
10
|
+
spec.description = %q{Mirror a S3 Bucket via command line, with support for remote workers (and scheduling).}
|
11
|
+
spec.summary = %q{Mirror a S3 Bucket via command line, with support for remote workers (and scheduling).}
|
12
|
+
spec.homepage = 'https://github.com/rjocoleman/s3twin'
|
13
|
+
spec.license = 'MIT'
|
14
|
+
|
15
|
+
spec.files = `git ls-files`.split($/)
|
16
|
+
spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
|
17
|
+
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
|
18
|
+
spec.require_paths = ['lib']
|
19
|
+
|
20
|
+
spec.add_dependency 'thor', '~> 0.18'
|
21
|
+
spec.add_dependency 'dotenv', '~> 0.8'
|
22
|
+
spec.add_dependency 'aws-sdk', '~> 1.11'
|
23
|
+
spec.add_dependency 'iron_worker_ng', '~> 0.16'
|
24
|
+
|
25
|
+
spec.add_development_dependency 'bundler', '~> 1.3'
|
26
|
+
spec.add_development_dependency 'rake'
|
27
|
+
spec.add_development_dependency 'pry', '~> 0.9'
|
28
|
+
spec.add_development_dependency 'pry-debugger', '~> 0.2'
|
29
|
+
end
|
metadata
ADDED
@@ -0,0 +1,172 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: s3twin
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.1
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Robert Coleman
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2013-07-07 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: thor
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - ~>
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '0.18'
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - ~>
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '0.18'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: dotenv
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - ~>
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '0.8'
|
34
|
+
type: :runtime
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - ~>
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '0.8'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: aws-sdk
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - ~>
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '1.11'
|
48
|
+
type: :runtime
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - ~>
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '1.11'
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: iron_worker_ng
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - ~>
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '0.16'
|
62
|
+
type: :runtime
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - ~>
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: '0.16'
|
69
|
+
- !ruby/object:Gem::Dependency
|
70
|
+
name: bundler
|
71
|
+
requirement: !ruby/object:Gem::Requirement
|
72
|
+
requirements:
|
73
|
+
- - ~>
|
74
|
+
- !ruby/object:Gem::Version
|
75
|
+
version: '1.3'
|
76
|
+
type: :development
|
77
|
+
prerelease: false
|
78
|
+
version_requirements: !ruby/object:Gem::Requirement
|
79
|
+
requirements:
|
80
|
+
- - ~>
|
81
|
+
- !ruby/object:Gem::Version
|
82
|
+
version: '1.3'
|
83
|
+
- !ruby/object:Gem::Dependency
|
84
|
+
name: rake
|
85
|
+
requirement: !ruby/object:Gem::Requirement
|
86
|
+
requirements:
|
87
|
+
- - '>='
|
88
|
+
- !ruby/object:Gem::Version
|
89
|
+
version: '0'
|
90
|
+
type: :development
|
91
|
+
prerelease: false
|
92
|
+
version_requirements: !ruby/object:Gem::Requirement
|
93
|
+
requirements:
|
94
|
+
- - '>='
|
95
|
+
- !ruby/object:Gem::Version
|
96
|
+
version: '0'
|
97
|
+
- !ruby/object:Gem::Dependency
|
98
|
+
name: pry
|
99
|
+
requirement: !ruby/object:Gem::Requirement
|
100
|
+
requirements:
|
101
|
+
- - ~>
|
102
|
+
- !ruby/object:Gem::Version
|
103
|
+
version: '0.9'
|
104
|
+
type: :development
|
105
|
+
prerelease: false
|
106
|
+
version_requirements: !ruby/object:Gem::Requirement
|
107
|
+
requirements:
|
108
|
+
- - ~>
|
109
|
+
- !ruby/object:Gem::Version
|
110
|
+
version: '0.9'
|
111
|
+
- !ruby/object:Gem::Dependency
|
112
|
+
name: pry-debugger
|
113
|
+
requirement: !ruby/object:Gem::Requirement
|
114
|
+
requirements:
|
115
|
+
- - ~>
|
116
|
+
- !ruby/object:Gem::Version
|
117
|
+
version: '0.2'
|
118
|
+
type: :development
|
119
|
+
prerelease: false
|
120
|
+
version_requirements: !ruby/object:Gem::Requirement
|
121
|
+
requirements:
|
122
|
+
- - ~>
|
123
|
+
- !ruby/object:Gem::Version
|
124
|
+
version: '0.2'
|
125
|
+
description: Mirror a S3 Bucket via command line, with support for remote workers
|
126
|
+
(and scheduling).
|
127
|
+
email:
|
128
|
+
- github@robert.net.nz
|
129
|
+
executables:
|
130
|
+
- s3twin
|
131
|
+
extensions: []
|
132
|
+
extra_rdoc_files: []
|
133
|
+
files:
|
134
|
+
- .env.sample
|
135
|
+
- .gitignore
|
136
|
+
- Gemfile
|
137
|
+
- LICENSE
|
138
|
+
- README.md
|
139
|
+
- Rakefile
|
140
|
+
- bin/s3twin
|
141
|
+
- lib/s3twin.rb
|
142
|
+
- lib/s3twin/helpers.rb
|
143
|
+
- lib/s3twin/twin.rb
|
144
|
+
- lib/s3twin/workers.rb
|
145
|
+
- lib/s3twin/workers/ironworker.rb
|
146
|
+
- s3twin.gemspec
|
147
|
+
homepage: https://github.com/rjocoleman/s3twin
|
148
|
+
licenses:
|
149
|
+
- MIT
|
150
|
+
metadata: {}
|
151
|
+
post_install_message:
|
152
|
+
rdoc_options: []
|
153
|
+
require_paths:
|
154
|
+
- lib
|
155
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
156
|
+
requirements:
|
157
|
+
- - '>='
|
158
|
+
- !ruby/object:Gem::Version
|
159
|
+
version: '0'
|
160
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
161
|
+
requirements:
|
162
|
+
- - '>='
|
163
|
+
- !ruby/object:Gem::Version
|
164
|
+
version: '0'
|
165
|
+
requirements: []
|
166
|
+
rubyforge_project:
|
167
|
+
rubygems_version: 2.0.3
|
168
|
+
signing_key:
|
169
|
+
specification_version: 4
|
170
|
+
summary: Mirror a S3 Bucket via command line, with support for remote workers (and
|
171
|
+
scheduling).
|
172
|
+
test_files: []
|