data_keeper 0.1.0 → 0.1.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 +4 -4
- data/README.md +25 -11
- data/data_keeper.gemspec +1 -2
- data/lib/data_keeper/s3_storage.rb +103 -0
- data/lib/data_keeper/version.rb +1 -1
- metadata +4 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 268e784853f728ad8c4cefd36ca8cc2f09b2892ab8751f1eb0f16dc17bc72900
|
4
|
+
data.tar.gz: 62ea9b6a3bf57ae952417db4fd149365f56f4baf63f67839bde26d3d2f352464
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 8ea7c0182fb8698c7d9c2be973cf7d3def1845222027feb90107adda8d333488ef01318268f8ae1356c2bd45d89419cb908443b5a9037df359cf5fc63376fca7
|
7
|
+
data.tar.gz: 7110186baac099fe5ce341186b25594c4ad730a811bc4270c4cd8e1d14d3cf4858bce5eb8bed0e621152da6d5729223c4d47c4f74b8e558c9539bb5bfcecd0c1
|
data/README.md
CHANGED
@@ -36,23 +36,37 @@ order to download these dumps later. Ex:
|
|
36
36
|
DataKeeper.storage = DataKeeper::LocalStorage.new(
|
37
37
|
local_store_dir: "/users/fredy/backups/...",
|
38
38
|
remote_access: {
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
user: "fredy"
|
39
|
+
host: "10.10.10.10",
|
40
|
+
port: "22",
|
41
|
+
user: "user"
|
43
42
|
}
|
44
43
|
)
|
45
44
|
```
|
46
45
|
|
47
|
-
|
48
|
-
If you want to do your own, you can assign as an storage whatever object that responds to:
|
46
|
+
There's also support for storing the dumps in s3, using `DataKeeper::S3Storage` like in this example:
|
49
47
|
|
50
|
-
|
51
|
-
|
48
|
+
```ruby
|
49
|
+
DataKeeper.storage = DataKeeper::S3Storage.new(
|
50
|
+
bucket: 'bucket-name',
|
51
|
+
store_dir: 'dumps/',
|
52
|
+
acl: "private",
|
53
|
+
remote_access: {
|
54
|
+
access_key_id: Rails.application.credentials.access_key_id,
|
55
|
+
secret_access_key: Rails.application.credentials.secret_access_key,
|
56
|
+
region: 'eu-central-1'
|
57
|
+
}
|
58
|
+
)
|
59
|
+
```
|
60
|
+
|
61
|
+
|
62
|
+
Other storages can be implemented. An storage can be any object that responds to those two methods:
|
63
|
+
|
64
|
+
- `#save(file, filename, dump_name)`, where file is a File object and filename and dump_name are strings.
|
65
|
+
This method should save the given dump file in the store.
|
52
66
|
|
53
67
|
- `#retrieve(dump_name) { |file| (...) }`, which should retrieve the latest stored dump with the given dump_name.
|
54
|
-
It should yield the given block passing the File object pointing to the retrieved dump
|
55
|
-
which is expected to be cleaned up on block termination.
|
68
|
+
It should yield the given block passing the `File` or `Tempfile` object pointing to the retrieved dump
|
69
|
+
file in the local filesystem, which is expected to be cleaned up on block termination.
|
56
70
|
|
57
71
|
|
58
72
|
Then, declare some dumps to work with:
|
@@ -101,7 +115,7 @@ To install this gem onto your local machine, run `bundle exec rake install`. To
|
|
101
115
|
|
102
116
|
## Contributing
|
103
117
|
|
104
|
-
Bug reports and pull requests are welcome on GitHub at https://github.com/
|
118
|
+
Bug reports and pull requests are welcome on GitHub at https://github.com/rogercampos/data_keeper.
|
105
119
|
|
106
120
|
|
107
121
|
## License
|
data/data_keeper.gemspec
CHANGED
@@ -10,7 +10,7 @@ Gem::Specification.new do |spec|
|
|
10
10
|
spec.description = %q{Easy management of database dumps for dev env}
|
11
11
|
spec.homepage = "https://github.com/rogercampos/data_keeper"
|
12
12
|
spec.license = "MIT"
|
13
|
-
spec.required_ruby_version = Gem::Requirement.new(">= 2.
|
13
|
+
spec.required_ruby_version = Gem::Requirement.new(">= 2.5.0")
|
14
14
|
|
15
15
|
spec.metadata["homepage_uri"] = spec.homepage
|
16
16
|
|
@@ -27,5 +27,4 @@ Gem::Specification.new do |spec|
|
|
27
27
|
spec.add_dependency "terrapin", ">= 0.5.0"
|
28
28
|
spec.add_dependency "sshkit", ">= 1.20.0"
|
29
29
|
spec.add_dependency "rails", ">= 5.0.0"
|
30
|
-
|
31
30
|
end
|
@@ -0,0 +1,103 @@
|
|
1
|
+
begin
|
2
|
+
require 'aws-sdk-s3'
|
3
|
+
rescue LoadError
|
4
|
+
raise "You must include the 'aws-sdk-s3' gem in your Gemfile in order to use this s3 storage."
|
5
|
+
end
|
6
|
+
|
7
|
+
module DataKeeper
|
8
|
+
class S3Storage
|
9
|
+
class Client
|
10
|
+
NoSuchKey = Class.new(StandardError)
|
11
|
+
|
12
|
+
def initialize(client_options:, bucket: nil)
|
13
|
+
@client_options = client_options
|
14
|
+
@client = Aws::S3::Client.new(client_options)
|
15
|
+
@bucket = bucket
|
16
|
+
end
|
17
|
+
|
18
|
+
def delete_files(file_paths)
|
19
|
+
@client.delete_objects(
|
20
|
+
bucket: @bucket,
|
21
|
+
delete: {
|
22
|
+
objects: file_paths.map { |key| { key: key } }
|
23
|
+
}
|
24
|
+
)
|
25
|
+
end
|
26
|
+
|
27
|
+
def list_contents(prefix = '')
|
28
|
+
@client.list_objects(bucket: @bucket, prefix: prefix).contents
|
29
|
+
rescue Aws::S3::Errors::NoSuchKey
|
30
|
+
raise NoSuchKey, prefix
|
31
|
+
end
|
32
|
+
|
33
|
+
# Streams all contents from `path` into the provided io object, calling #write to it.
|
34
|
+
# io can be a File, or any other IO-like object.
|
35
|
+
def stream_to_io(path, io, opts = {})
|
36
|
+
@client.get_object(opts.merge(
|
37
|
+
bucket: @bucket,
|
38
|
+
key: path
|
39
|
+
), target: io)
|
40
|
+
rescue Aws::S3::Errors::NoSuchKey
|
41
|
+
raise NoSuchKey, path
|
42
|
+
end
|
43
|
+
|
44
|
+
# Uploads the given file into the target_path in the s3 bucket.
|
45
|
+
# `file` must be a file stored locally. Can be either a raw string (path),
|
46
|
+
# or a File/Tempfile object (close is up to you).
|
47
|
+
def put_file(target_path, file, options = {})
|
48
|
+
file.rewind if file.respond_to?(:rewind)
|
49
|
+
|
50
|
+
s3 = Aws::S3::Resource.new(@client_options)
|
51
|
+
obj = s3.bucket(@bucket).object(target_path)
|
52
|
+
obj.upload_file(file, options)
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
def initialize(bucket:, store_dir:, remote_access:, acl: "public-read", keep_amount: 3)
|
57
|
+
@bucket = bucket
|
58
|
+
@store_dir = store_dir
|
59
|
+
@remote_access = remote_access
|
60
|
+
@acl = acl
|
61
|
+
@keep_amount = keep_amount
|
62
|
+
end
|
63
|
+
|
64
|
+
def save(file, filename, dump_name)
|
65
|
+
path = dump_path(dump_name, filename)
|
66
|
+
|
67
|
+
s3_client.put_file(path, file, acl: @acl)
|
68
|
+
|
69
|
+
prefix = "#{@store_dir}#{dump_name.to_s}"
|
70
|
+
|
71
|
+
keys_to_delete = s3_client.list_contents(prefix).sort_by(&:last_modified).reverse[@keep_amount..-1]
|
72
|
+
|
73
|
+
return unless keys_to_delete
|
74
|
+
|
75
|
+
s3_client.delete_files(keys_to_delete.map(&:key))
|
76
|
+
|
77
|
+
true
|
78
|
+
end
|
79
|
+
|
80
|
+
def retrieve(dump_name)
|
81
|
+
prefix = "#{@store_dir}#{dump_name.to_s}"
|
82
|
+
last_dump = s3_client.list_contents(prefix).sort_by(&:last_modified).reverse.first
|
83
|
+
|
84
|
+
Tempfile.create do |tmp_file|
|
85
|
+
tmp_file.binmode
|
86
|
+
s3_client.stream_to_io(last_dump.key, tmp_file)
|
87
|
+
tmp_file.flush
|
88
|
+
|
89
|
+
yield(tmp_file)
|
90
|
+
end
|
91
|
+
end
|
92
|
+
|
93
|
+
private
|
94
|
+
|
95
|
+
def s3_client
|
96
|
+
@s3_client ||= Client.new(bucket: @bucket, client_options: @remote_access)
|
97
|
+
end
|
98
|
+
|
99
|
+
def dump_path(dump_name, filename)
|
100
|
+
File.join(@store_dir, dump_name.to_s, "#{SecureRandom.alphanumeric(40)}-#{filename}")
|
101
|
+
end
|
102
|
+
end
|
103
|
+
end
|
data/lib/data_keeper/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: data_keeper
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.
|
4
|
+
version: 0.1.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Roger Campos
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2021-07-16 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: activerecord
|
@@ -91,6 +91,7 @@ files:
|
|
91
91
|
- lib/data_keeper/loader.rb
|
92
92
|
- lib/data_keeper/local_storage.rb
|
93
93
|
- lib/data_keeper/railtie.rb
|
94
|
+
- lib/data_keeper/s3_storage.rb
|
94
95
|
- lib/data_keeper/tasks/data_keeper.rake
|
95
96
|
- lib/data_keeper/version.rb
|
96
97
|
- todo.md
|
@@ -107,7 +108,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
107
108
|
requirements:
|
108
109
|
- - ">="
|
109
110
|
- !ruby/object:Gem::Version
|
110
|
-
version: 2.
|
111
|
+
version: 2.5.0
|
111
112
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
112
113
|
requirements:
|
113
114
|
- - ">="
|