pg_s3_dumper 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.gitignore +10 -0
- data/CODE_OF_CONDUCT.md +13 -0
- data/Gemfile +4 -0
- data/LICENSE.txt +21 -0
- data/README.md +40 -0
- data/Rakefile +2 -0
- data/bin/console +14 -0
- data/bin/setup +7 -0
- data/exe/pg_s3_dumper +6 -0
- data/lib/pg_s3_dumper.rb +15 -0
- data/lib/pg_s3_dumper/backup.rb +59 -0
- data/lib/pg_s3_dumper/cli.rb +87 -0
- data/lib/pg_s3_dumper/dumper.rb +140 -0
- data/lib/pg_s3_dumper/version.rb +3 -0
- data/pg_s3_dumper.gemspec +26 -0
- metadata +116 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 8b14600ad7c17cf7a10564e4072cebeedc7c7b3a
|
4
|
+
data.tar.gz: 3043449edb6e21f11cb1b015e708e8cca7675d4b
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 85933b6c92087a99f1c491678eabebb2fbb7d50e2ccd349f9ee0a2666500d1cae553035ba34a32ce36581832afc18a83f268011bb6648e07117dfaaa5393a39c
|
7
|
+
data.tar.gz: 86f5b988f8fc4ba8d8998b0923ee8d89148496ae8dbb6c88064a38775e1aa668944c6e64ec6c56b6efa57f67749d08bed72a225cf39b58cf86858d3233c910dc
|
data/.gitignore
ADDED
data/CODE_OF_CONDUCT.md
ADDED
@@ -0,0 +1,13 @@
|
|
1
|
+
# Contributor Code of Conduct
|
2
|
+
|
3
|
+
As contributors and maintainers of this project, we pledge to respect all people who contribute through reporting issues, posting feature requests, updating documentation, submitting pull requests or patches, and other activities.
|
4
|
+
|
5
|
+
We are committed to making participation in this project a harassment-free experience for everyone, regardless of level of experience, gender, gender identity and expression, sexual orientation, disability, personal appearance, body size, race, age, or religion.
|
6
|
+
|
7
|
+
Examples of unacceptable behavior by participants include the use of sexual language or imagery, derogatory comments or personal attacks, trolling, public or private harassment, insults, or other unprofessional conduct.
|
8
|
+
|
9
|
+
Project maintainers have the right and responsibility to remove, edit, or reject comments, commits, code, wiki edits, issues, and other contributions that are not aligned to this Code of Conduct. Project maintainers who do not follow the Code of Conduct may be removed from the project team.
|
10
|
+
|
11
|
+
Instances of abusive, harassing, or otherwise unacceptable behavior may be reported by opening an issue or contacting one or more of the project maintainers.
|
12
|
+
|
13
|
+
This Code of Conduct is adapted from the [Contributor Covenant](http:contributor-covenant.org), version 1.0.0, available at [http://contributor-covenant.org/version/1/0/0/](http://contributor-covenant.org/version/1/0/0/)
|
data/Gemfile
ADDED
data/LICENSE.txt
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
The MIT License (MIT)
|
2
|
+
|
3
|
+
Copyright (c) 2015 Nicolas Goy
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
7
|
+
in the Software without restriction, including without limitation the rights
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
10
|
+
furnished to do so, subject to the following conditions:
|
11
|
+
|
12
|
+
The above copyright notice and this permission notice shall be included in
|
13
|
+
all copies or substantial portions of the Software.
|
14
|
+
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
21
|
+
THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,40 @@
|
|
1
|
+
# PG S3 Dumper
|
2
|
+
|
3
|
+
This simple tool creates and expires postgresql backups on an S3 bucket.
|
4
|
+
|
5
|
+
In this document, "PG S3 Dumper" will be refered simply as "Dumper".
|
6
|
+
|
7
|
+
NOTE: This is alpha quality software, use at your own risks.
|
8
|
+
|
9
|
+
WARNING: Ensure you create a bucket and prefix specifically for this tool, with
|
10
|
+
proper IAM permissions to avoid dataloss in case of failure.
|
11
|
+
|
12
|
+
## Installation
|
13
|
+
|
14
|
+
Just install the gem.
|
15
|
+
|
16
|
+
$ gem install pg_s3_dumper
|
17
|
+
|
18
|
+
## Usage
|
19
|
+
|
20
|
+
### Configuration
|
21
|
+
|
22
|
+
Dumper can be configured by command line arguments or environment variables.
|
23
|
+
|
24
|
+
For usage information:
|
25
|
+
|
26
|
+
$ pg_s3_dumper -h
|
27
|
+
|
28
|
+
## TODO
|
29
|
+
|
30
|
+
- Make backup keep count configurable
|
31
|
+
- Write tests
|
32
|
+
|
33
|
+
|
34
|
+
## Contributing
|
35
|
+
|
36
|
+
1. Fork it ( https://github.com/kuon/pg_s3_dumper/fork )
|
37
|
+
2. Create your feature branch (`git checkout -b my-new-feature`)
|
38
|
+
3. Commit your changes (`git commit -am 'Add some feature'`)
|
39
|
+
4. Push to the branch (`git push origin my-new-feature`)
|
40
|
+
5. Create a new Pull Request
|
data/Rakefile
ADDED
data/bin/console
ADDED
@@ -0,0 +1,14 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require "bundler/setup"
|
4
|
+
require "pg_s3_dumper"
|
5
|
+
|
6
|
+
# You can add fixtures and/or initialization code here to make experimenting
|
7
|
+
# with your gem easier. You can also use a different console, if you like.
|
8
|
+
|
9
|
+
# (If you use this, don't forget to add pry to your Gemfile!)
|
10
|
+
# require "pry"
|
11
|
+
# Pry.start
|
12
|
+
|
13
|
+
require "irb"
|
14
|
+
IRB.start
|
data/bin/setup
ADDED
data/exe/pg_s3_dumper
ADDED
data/lib/pg_s3_dumper.rb
ADDED
@@ -0,0 +1,15 @@
|
|
1
|
+
require "time"
|
2
|
+
require "tempfile"
|
3
|
+
require "aws-sdk"
|
4
|
+
require "securerandom"
|
5
|
+
require "active_support"
|
6
|
+
require "active_support/core_ext"
|
7
|
+
|
8
|
+
require "pg_s3_dumper/version"
|
9
|
+
require "pg_s3_dumper/cli"
|
10
|
+
require "pg_s3_dumper/dumper"
|
11
|
+
require "pg_s3_dumper/backup"
|
12
|
+
|
13
|
+
module PgS3Dumper
|
14
|
+
# Your code goes here...
|
15
|
+
end
|
@@ -0,0 +1,59 @@
|
|
1
|
+
class Backup
|
2
|
+
|
3
|
+
def self.generate_id
|
4
|
+
SecureRandom.hex(32)
|
5
|
+
end
|
6
|
+
|
7
|
+
include Comparable
|
8
|
+
|
9
|
+
attr_reader :s3_object, :ts, :keep
|
10
|
+
|
11
|
+
def <=>(other)
|
12
|
+
ts <=> other.ts
|
13
|
+
end
|
14
|
+
|
15
|
+
def initialize(s3_object)
|
16
|
+
@s3_object = s3_object
|
17
|
+
@ts = Time.parse(s3_object.key.split('/').last)
|
18
|
+
@keep = false
|
19
|
+
end
|
20
|
+
|
21
|
+
def to_s
|
22
|
+
"id: #{short_id}, key: #{basename}"
|
23
|
+
end
|
24
|
+
|
25
|
+
def on_day?(date)
|
26
|
+
ts.strftime('%F') == date.strftime('%F')
|
27
|
+
end
|
28
|
+
|
29
|
+
def keep_on_day(date)
|
30
|
+
@keep = true if on_day?(date)
|
31
|
+
end
|
32
|
+
|
33
|
+
def prune
|
34
|
+
if keep
|
35
|
+
puts "Keeping backup: #{self}"
|
36
|
+
else
|
37
|
+
delete
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
def delete
|
42
|
+
puts "Deleting backup: #{self}"
|
43
|
+
s3_object.delete
|
44
|
+
end
|
45
|
+
|
46
|
+
def id
|
47
|
+
@id ||= s3_object.metadata['backup_id']
|
48
|
+
end
|
49
|
+
|
50
|
+
def short_id
|
51
|
+
id[0..8]
|
52
|
+
end
|
53
|
+
|
54
|
+
def basename
|
55
|
+
File.basename(s3_object.key)
|
56
|
+
end
|
57
|
+
|
58
|
+
end
|
59
|
+
|
@@ -0,0 +1,87 @@
|
|
1
|
+
module PgS3Dumper
|
2
|
+
module CLI
|
3
|
+
module_function
|
4
|
+
|
5
|
+
def start
|
6
|
+
options = {}
|
7
|
+
|
8
|
+
OptionParser.new do |opts|
|
9
|
+
opts.banner = "Usage: pg_s3_dumper options"
|
10
|
+
|
11
|
+
|
12
|
+
opts.separator "Commands options:"
|
13
|
+
opts.on("-c", "--command=COMMAND", "Command to execute",
|
14
|
+
" - list - List all backups",
|
15
|
+
" - backup - Create a new backup",
|
16
|
+
" - cleanup - Delete all backups") do |v|
|
17
|
+
options[:command] = v.to_sym
|
18
|
+
end
|
19
|
+
|
20
|
+
opts.on("-p", "--[no-]prune", "Prune (delete) old backups.",
|
21
|
+
"When pruning is off all backups are kept.",
|
22
|
+
"When pruning is on, the following backups are kept:",
|
23
|
+
" - all backups for today",
|
24
|
+
" - 1 per day for the last week",
|
25
|
+
" - 1 per week for the last month",
|
26
|
+
" - 1 per month for the last year") do |v|
|
27
|
+
options[:prune] = v
|
28
|
+
end
|
29
|
+
|
30
|
+
opts.separator ""
|
31
|
+
opts.separator "Configuration options:"
|
32
|
+
|
33
|
+
opts.on("-d", "--database URL", "Database to use, must be an URL in the form:",
|
34
|
+
"'postgres://username:password@hostname:port/database',",
|
35
|
+
"it will be passed directly to the pg_dump command.",
|
36
|
+
"If not set, the environment variable DATABASE_URL is used.") do |v|
|
37
|
+
options[:database_url] = v
|
38
|
+
end
|
39
|
+
|
40
|
+
opts.on("-k", "--aws-key KEY", "AWS key, must have read write access to the bucket.",
|
41
|
+
"If not set, the environment variable AWS_ACCESS_KEY_ID is used.") do |v|
|
42
|
+
options[:aws_key] = v
|
43
|
+
end
|
44
|
+
|
45
|
+
opts.on("-w", "--aws-secret SECRET", "AWS secret key.",
|
46
|
+
"If not set, the environment variable AWS_SECRET_ACCESS_KEY is used.") do |v|
|
47
|
+
options[:aws_secret] = v
|
48
|
+
end
|
49
|
+
|
50
|
+
opts.on("-r", "--aws-region REGION", "AWS region your bucket resides in.",
|
51
|
+
"If not set, the environment variable AWS_REGION is used.") do |v|
|
52
|
+
options[:aws_region] = v
|
53
|
+
end
|
54
|
+
|
55
|
+
opts.on("-u", "--aws-url URL", "AWS destination, must be an URL in the form:",
|
56
|
+
"'s3://bucket/prefix'.",
|
57
|
+
"If not set, the environment variable AWS_URL is used.") do |v|
|
58
|
+
options[:aws_url] = v
|
59
|
+
end
|
60
|
+
|
61
|
+
opts.separator ""
|
62
|
+
opts.separator "General options:"
|
63
|
+
|
64
|
+
opts.on("-v", "--version", "Output version information, then exit.") do
|
65
|
+
puts PgS3Dumper::VERSION
|
66
|
+
exit
|
67
|
+
end
|
68
|
+
|
69
|
+
opts.on("-h", "--help", "Show this help, then exit.") do
|
70
|
+
puts opts.help
|
71
|
+
exit
|
72
|
+
end
|
73
|
+
|
74
|
+
|
75
|
+
end.parse!
|
76
|
+
|
77
|
+
begin
|
78
|
+
dumper = PgS3Dumper::Dumper.new(options)
|
79
|
+
dumper.run(options[:command])
|
80
|
+
rescue PgS3Dumper::Error => e
|
81
|
+
puts "ERROR: #{e.message}."
|
82
|
+
end
|
83
|
+
|
84
|
+
end
|
85
|
+
end
|
86
|
+
end
|
87
|
+
|
@@ -0,0 +1,140 @@
|
|
1
|
+
require "aws-sdk"
|
2
|
+
|
3
|
+
module PgS3Dumper
|
4
|
+
class Error < ::StandardError
|
5
|
+
end
|
6
|
+
|
7
|
+
class Dumper
|
8
|
+
|
9
|
+
attr_reader :database_url,
|
10
|
+
:database_name,
|
11
|
+
:prefix,
|
12
|
+
:bucket
|
13
|
+
|
14
|
+
def prune?
|
15
|
+
@prune
|
16
|
+
end
|
17
|
+
|
18
|
+
def initialize(options)
|
19
|
+
@database_url = options[:database_url] || ENV['DATABASE_URL']
|
20
|
+
aws_region = options[:aws_region] || ENV['AWS_REGION']
|
21
|
+
aws_key = options[:aws_key] || ENV['AWS_ACCESS_KEY_ID']
|
22
|
+
aws_secret = options[:aws_secret] || ENV['AWS_SECRET_ACCESS_KEY']
|
23
|
+
aws_url = options[:aws_url] || ENV['AWS_URL']
|
24
|
+
@prune = options.has_key?(:prune) ? options[:prune] : false
|
25
|
+
|
26
|
+
v = `pg_dump --version`
|
27
|
+
v =~ /pg_dump \(PostgreSQL\) 9\.\d\.\d/ or raise Error, "pg_dump version 9.x.x is required and must be in the PATH"
|
28
|
+
database_url or raise Error, "Database URL required."
|
29
|
+
aws_url =~ %r{^s3://([^/]+)/(\S*?)/?$} or raise Error, "Invalid AWS URL"
|
30
|
+
|
31
|
+
bucket_name = $1
|
32
|
+
@prefix = "#{$2}/"
|
33
|
+
|
34
|
+
database_url =~ %r{postgres://[^/]+/(.+)} or raise Error, "Invalid database URL"
|
35
|
+
@database_name = $1
|
36
|
+
@prefix = File.join(prefix, database_name)
|
37
|
+
|
38
|
+
aws_key && aws_secret or raise Error, "AWS key and secret required"
|
39
|
+
|
40
|
+
cred = Aws::Credentials.new(aws_key, aws_secret)
|
41
|
+
client = Aws::S3::Client.new(:credentials => cred, :region => aws_region)
|
42
|
+
s3 = Aws::S3::Resource.new(:client => client)
|
43
|
+
@bucket = s3.bucket(bucket_name)
|
44
|
+
end
|
45
|
+
|
46
|
+
def run(command)
|
47
|
+
case command
|
48
|
+
when :list
|
49
|
+
list
|
50
|
+
when :backup
|
51
|
+
backup
|
52
|
+
when :cleanup
|
53
|
+
cleanup
|
54
|
+
else
|
55
|
+
raise Error, "Invalid command '#{command}'"
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
def list
|
60
|
+
f = "% 12s% 30s"
|
61
|
+
puts f % ['id', 'date']
|
62
|
+
puts "-" * 42
|
63
|
+
find_backups.each do |b|
|
64
|
+
puts f % [b.short_id, b.ts]
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
68
|
+
def cleanup
|
69
|
+
find_backups.each do |b|
|
70
|
+
b.delete
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
74
|
+
def backup
|
75
|
+
backups = find_backups
|
76
|
+
|
77
|
+
# Keep daily backups for one week
|
78
|
+
# Keep weekly backups for one month
|
79
|
+
# Keep monthly backups for one year
|
80
|
+
days =
|
81
|
+
7.times.map{|i| i.days.ago} +
|
82
|
+
4.times.map{|i| i.weeks.ago} +
|
83
|
+
12.times.map{|i| i.months.ago}
|
84
|
+
|
85
|
+
days.each do |ts|
|
86
|
+
backups.each do |b|
|
87
|
+
b.keep_on_day(ts)
|
88
|
+
# We kept one backup on day ts, go to next day
|
89
|
+
break if b.keep
|
90
|
+
end
|
91
|
+
end
|
92
|
+
|
93
|
+
# Keep all backups for today
|
94
|
+
backups.each do |b|
|
95
|
+
b.keep_on_day(Date.today)
|
96
|
+
end
|
97
|
+
|
98
|
+
# Make new backup
|
99
|
+
key = "#{now.iso8601}-#{database_name.split('/').last}.dmp"
|
100
|
+
file = Tempfile.new(key)
|
101
|
+
|
102
|
+
puts "## Creating backup"
|
103
|
+
|
104
|
+
system "pg_dump -Fc --no-owner --no-acl -d #{database_url} > #{file.path}" or fail 'Cannot create dump'
|
105
|
+
|
106
|
+
obj = bucket.object(File.join(prefix, key))
|
107
|
+
|
108
|
+
obj.upload_file(file.path, :metadata => {:backup_id => Backup.generate_id})
|
109
|
+
file.close
|
110
|
+
file.unlink
|
111
|
+
bck = Backup.new(obj)
|
112
|
+
puts "Created backup: #{bck}"
|
113
|
+
|
114
|
+
if prune?
|
115
|
+
puts "## Pruning old backups"
|
116
|
+
backups.each do |b|
|
117
|
+
b.prune
|
118
|
+
end
|
119
|
+
end
|
120
|
+
end
|
121
|
+
|
122
|
+
def now
|
123
|
+
Time.now.utc
|
124
|
+
end
|
125
|
+
|
126
|
+
private
|
127
|
+
def find_backups
|
128
|
+
backups = []
|
129
|
+
|
130
|
+
# Collect existing backups
|
131
|
+
bucket.objects(:prefix => prefix).each do |o|
|
132
|
+
backups << Backup.new(o.object)
|
133
|
+
end
|
134
|
+
|
135
|
+
backups.sort
|
136
|
+
end
|
137
|
+
|
138
|
+
end
|
139
|
+
end
|
140
|
+
|
@@ -0,0 +1,26 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
lib = File.expand_path('../lib', __FILE__)
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
+
require 'pg_s3_dumper/version'
|
5
|
+
|
6
|
+
Gem::Specification.new do |spec|
|
7
|
+
spec.name = "pg_s3_dumper"
|
8
|
+
spec.version = PgS3Dumper::VERSION
|
9
|
+
spec.authors = ["Nicolas Goy"]
|
10
|
+
spec.email = ["kuon@goyman.com"]
|
11
|
+
|
12
|
+
|
13
|
+
spec.summary = %q{Simple tool to dump postgresql database to an S3 bucket.}
|
14
|
+
spec.homepage = "http://github.com/kuon/pg_s3_dumper"
|
15
|
+
spec.license = "MIT"
|
16
|
+
|
17
|
+
spec.files = `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
|
18
|
+
spec.bindir = "exe"
|
19
|
+
spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
|
20
|
+
spec.require_paths = ["lib"]
|
21
|
+
|
22
|
+
spec.add_dependency "aws-sdk", "~> 2.0"
|
23
|
+
spec.add_dependency "activesupport", "~> 4.0"
|
24
|
+
spec.add_development_dependency "bundler", "~> 1.8"
|
25
|
+
spec.add_development_dependency "rake", "~> 10.0"
|
26
|
+
end
|
metadata
ADDED
@@ -0,0 +1,116 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: pg_s3_dumper
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Nicolas Goy
|
8
|
+
autorequire:
|
9
|
+
bindir: exe
|
10
|
+
cert_chain: []
|
11
|
+
date: 2015-03-16 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: aws-sdk
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - "~>"
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '2.0'
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - "~>"
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '2.0'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: activesupport
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - "~>"
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '4.0'
|
34
|
+
type: :runtime
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - "~>"
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '4.0'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: bundler
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - "~>"
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '1.8'
|
48
|
+
type: :development
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - "~>"
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '1.8'
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: rake
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - "~>"
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '10.0'
|
62
|
+
type: :development
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - "~>"
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: '10.0'
|
69
|
+
description:
|
70
|
+
email:
|
71
|
+
- kuon@goyman.com
|
72
|
+
executables:
|
73
|
+
- pg_s3_dumper
|
74
|
+
extensions: []
|
75
|
+
extra_rdoc_files: []
|
76
|
+
files:
|
77
|
+
- ".gitignore"
|
78
|
+
- CODE_OF_CONDUCT.md
|
79
|
+
- Gemfile
|
80
|
+
- LICENSE.txt
|
81
|
+
- README.md
|
82
|
+
- Rakefile
|
83
|
+
- bin/console
|
84
|
+
- bin/setup
|
85
|
+
- exe/pg_s3_dumper
|
86
|
+
- lib/pg_s3_dumper.rb
|
87
|
+
- lib/pg_s3_dumper/backup.rb
|
88
|
+
- lib/pg_s3_dumper/cli.rb
|
89
|
+
- lib/pg_s3_dumper/dumper.rb
|
90
|
+
- lib/pg_s3_dumper/version.rb
|
91
|
+
- pg_s3_dumper.gemspec
|
92
|
+
homepage: http://github.com/kuon/pg_s3_dumper
|
93
|
+
licenses:
|
94
|
+
- MIT
|
95
|
+
metadata: {}
|
96
|
+
post_install_message:
|
97
|
+
rdoc_options: []
|
98
|
+
require_paths:
|
99
|
+
- lib
|
100
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
101
|
+
requirements:
|
102
|
+
- - ">="
|
103
|
+
- !ruby/object:Gem::Version
|
104
|
+
version: '0'
|
105
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
106
|
+
requirements:
|
107
|
+
- - ">="
|
108
|
+
- !ruby/object:Gem::Version
|
109
|
+
version: '0'
|
110
|
+
requirements: []
|
111
|
+
rubyforge_project:
|
112
|
+
rubygems_version: 2.4.5
|
113
|
+
signing_key:
|
114
|
+
specification_version: 4
|
115
|
+
summary: Simple tool to dump postgresql database to an S3 bucket.
|
116
|
+
test_files: []
|