redis-backup 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +17 -0
- data/Gemfile +6 -0
- data/LICENSE +7 -0
- data/README.md +4 -0
- data/Rakefile +2 -0
- data/bin/redis-backup +164 -0
- data/lib/redis-backup.rb +4 -0
- data/lib/redis-backup/version.rb +3 -0
- data/redis-backup.gemspec +17 -0
- metadata +57 -0
data/.gitignore
ADDED
data/Gemfile
ADDED
data/LICENSE
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
Copyright (c) 2013 Jose Diaz-Gonzalez
|
2
|
+
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
4
|
+
|
5
|
+
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
|
6
|
+
|
7
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
data/Rakefile
ADDED
data/bin/redis-backup
ADDED
@@ -0,0 +1,164 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
# -*- encoding : utf-8 -*-
|
3
|
+
|
4
|
+
#
|
5
|
+
# redis-backup
|
6
|
+
#
|
7
|
+
# Uses environment variables for running:
|
8
|
+
#
|
9
|
+
# - BACKUP_DIR: Directory to write backups to
|
10
|
+
# - REDIS_SAVE: 0 or 1. If "1", then perform, and wait for, a bgsave before copying backup
|
11
|
+
# - REDIS_SAVE_METHOD: If calling a save, the method to call on redis for saving (save or bgsave)
|
12
|
+
# - REDIS_HOST: Host for local redis
|
13
|
+
# - REDIS_PORT: Port to local redis
|
14
|
+
# - REDIS_SOURCE: Full path to redis dump.rdb file
|
15
|
+
# - S3_SAVE: 0 or 1. If "1", then use S3 to backup the file
|
16
|
+
# - S3_BUCKET: Name of bucket to use on S3
|
17
|
+
# - S3_ACCESS_KEY_ID: Your access_key_id for AWS S3
|
18
|
+
# - S3_SECRET_ACCESS_KEY: Your secret_access_key for AWS S3
|
19
|
+
#
|
20
|
+
|
21
|
+
require 'aws-sdk'
|
22
|
+
require 'date'
|
23
|
+
require 'fileutils'
|
24
|
+
require 'optparse'
|
25
|
+
require 'redis'
|
26
|
+
|
27
|
+
require File.expand_path('../../lib/redis-backup/version', __FILE__)
|
28
|
+
version = RedisBackup::VERSION
|
29
|
+
|
30
|
+
backup_dir = "/data/backup/redis"
|
31
|
+
redis_host = "localhost"
|
32
|
+
redis_port = 6379
|
33
|
+
redis_save_method = false
|
34
|
+
redis_source = "/var/lib/redis/dump.rdb"
|
35
|
+
s3_save = !!ENV.fetch("S3_SAVE", false)
|
36
|
+
s3_bucket = false
|
37
|
+
s3_access_key_id = false
|
38
|
+
s3_secret_access_key = false
|
39
|
+
|
40
|
+
optparse = OptionParser.new do |opts|
|
41
|
+
opts.version = version
|
42
|
+
opts.banner = "Usage: redis-backup [options]"
|
43
|
+
opts.on('-h', '--help', 'Usage information') do
|
44
|
+
puts opts
|
45
|
+
exit
|
46
|
+
end
|
47
|
+
opts.on('-b', '--backup-dir BACKUP_DIR', 'Directory to write backups to') { |dir| backup_dir = dir }
|
48
|
+
opts.on('-s', '--redis-source REDIS_SOURCE', 'Full path to redis dump.rdb file') { |source| redis_source = source }
|
49
|
+
opts.on('-m', '--redis-save-method REDIS_SAVE_METHOD', 'The method to call on redis for saving (save or bgsave or none)') { |method| redis_save_method = method }
|
50
|
+
opts.on('-H', '--redis-host REDIS_HOST', 'Host for local redis') { |host| redis_host = host }
|
51
|
+
opts.on('-p', '--redis-port REDIS_PORT', 'Port for local redis') { |port| redis_port = port.to_i }
|
52
|
+
opts.on('-B', '--s3-bucket S3_BUCKET', 'Name of bucket to use on S3') { |bucket| s3_bucket = bucket }
|
53
|
+
opts.on('-A', '--s3-access-key-id S3_ACCESS_KEY_ID', 'Your access_key_id for AWS S3') { |key| s3_access_key_id = key }
|
54
|
+
opts.on('-S', '--s3-secret-access-key S3_SECRET_ACCESS_KEY', 'Your secret_access_key for AWS S3') { |secret| s3_secret_access_key = secret }
|
55
|
+
end
|
56
|
+
optparse.parse!
|
57
|
+
|
58
|
+
BACKUP_DIR = backup_dir
|
59
|
+
REDIS_SAVE_METHOD = redis_save_method
|
60
|
+
REDIS_HOST = redis_host
|
61
|
+
REDIS_SOURCE = redis_source
|
62
|
+
REDIS_PORT = redis_port
|
63
|
+
S3_SAVE = !!s3_bucket && !!s3_access_key_id && !!s3_secret_access_key
|
64
|
+
S3_BUCKET = s3_bucket
|
65
|
+
S3_ACCESS_KEY_ID = s3_access_key_id
|
66
|
+
S3_SECRET_ACCESS_KEY = s3_secret_access_key
|
67
|
+
|
68
|
+
|
69
|
+
def colorize(text, color_code); RUBY_PLATFORM =~ /win32/ ? text : "#{color_code}#{text}\e[0m"; end
|
70
|
+
def red(text); colorize(text, "\e[31m"); end
|
71
|
+
def green(text); colorize(text, "\e[32m"); end
|
72
|
+
def yellow(text); colorize(text, "\e[33m"); end
|
73
|
+
def blue(text); colorize(text, "\e[34m"); end
|
74
|
+
def magenta(text); colorize(text, "\e[35m"); end
|
75
|
+
def cyan(text); colorize(text, "\e[36m"); end
|
76
|
+
def white(text); colorize(text, "\e[37m"); end
|
77
|
+
def bold(text); colorize(text, "\e[1m"); end
|
78
|
+
def grey(text); colorize(text, "\e[90m"); end
|
79
|
+
|
80
|
+
abort("Redis .rdb file does not exist: " + REDIS_SOURCE) unless File.exists? REDIS_SOURCE
|
81
|
+
|
82
|
+
FileUtils.mkdir_p BACKUP_DIR unless File.directory? BACKUP_DIR
|
83
|
+
|
84
|
+
abort("Backup directory does not exist: " + BACKUP_DIR) unless File.directory? BACKUP_DIR
|
85
|
+
abort("Backup directory is not writable: " + BACKUP_DIR) unless File.writable? BACKUP_DIR
|
86
|
+
|
87
|
+
if S3_SAVE
|
88
|
+
abort("No bucket specified") unless S3_BUCKET
|
89
|
+
abort("No access key specified in S3_ACCESS_KEY_ID environment variable") unless S3_ACCESS_KEY_ID
|
90
|
+
abort("No secret access key specified in S3_SECRET_ACCESS_KEY environment variable") unless S3_SECRET_ACCESS_KEY
|
91
|
+
AWS.config({
|
92
|
+
access_key_id: S3_ACCESS_KEY_ID,
|
93
|
+
secret_access_key: S3_SECRET_ACCESS_KEY
|
94
|
+
})
|
95
|
+
s3 = AWS::S3.new
|
96
|
+
bucket = s3.buckets[S3_BUCKET]
|
97
|
+
abort("Bucket does not exist: " + S3_BUCKET) unless bucket.exists?
|
98
|
+
begin
|
99
|
+
owner = bucket.owner
|
100
|
+
rescue AWS::S3::Errors::AccessDenied => e
|
101
|
+
abort("Access to the bucket is denied: " + S3_BUCKET)
|
102
|
+
end
|
103
|
+
end
|
104
|
+
|
105
|
+
|
106
|
+
puts blue(cyan('Starting save'))
|
107
|
+
backup_start = Time.now
|
108
|
+
|
109
|
+
puts "--> Saving from %s to %s" % [ REDIS_SOURCE, BACKUP_DIR ]
|
110
|
+
|
111
|
+
if REDIS_SAVE_METHOD
|
112
|
+
puts "--> Performing background save " + bold(cyan('↴'))
|
113
|
+
bgsave_start = Time.now
|
114
|
+
|
115
|
+
mtime = File.mtime(REDIS_SOURCE).strftime("%Y-%m-%d-%H-%M-%S")
|
116
|
+
puts " - Current backup.rdb mtime: " + mtime
|
117
|
+
|
118
|
+
puts " - Sending '%s' command" % (REDIS_SAVE_METHOD)
|
119
|
+
redis = Redis.new(
|
120
|
+
:host => REDIS_HOST,
|
121
|
+
:port => REDIS_PORT
|
122
|
+
)
|
123
|
+
|
124
|
+
if REDIS_SAVE_METHOD == "bgsave"
|
125
|
+
redis.bgsave
|
126
|
+
else
|
127
|
+
redis.save
|
128
|
+
end
|
129
|
+
|
130
|
+
puts " - Command sent, waiting"
|
131
|
+
|
132
|
+
while File.mtime(REDIS_SOURCE).strftime("%Y-%m-%d-%H-%M-%S") == mtime
|
133
|
+
sleep 0.0001
|
134
|
+
end
|
135
|
+
|
136
|
+
puts " - Save performed successfully, took %.2f seconds" % (Time.now - backup_start)
|
137
|
+
end
|
138
|
+
|
139
|
+
DATETIME = DateTime.parse(`date`).strftime("%Y-%m-%d-%H-%M-%S")
|
140
|
+
REDIS_DEST = "%s/%s-dump.rdb" % [ BACKUP_DIR, DATETIME ]
|
141
|
+
|
142
|
+
puts "--> Copying backup from %s to %s" % [ REDIS_SOURCE, REDIS_DEST ]
|
143
|
+
FileUtils.cp(REDIS_SOURCE, REDIS_DEST)
|
144
|
+
|
145
|
+
if S3_SAVE
|
146
|
+
puts "--> Pushing file to S3 " + bold(cyan('↴'))
|
147
|
+
s3_start = Time.now
|
148
|
+
|
149
|
+
puts " - Connecting to S3"
|
150
|
+
s3 = AWS::S3.new
|
151
|
+
bucket = s3.buckets[S3_BUCKET]
|
152
|
+
|
153
|
+
puts " - Uploading the file, please wait..."
|
154
|
+
basename = File.basename(REDIS_DEST)
|
155
|
+
object = bucket.objects[basename]
|
156
|
+
object.write(:file => REDIS_DEST)
|
157
|
+
request_uri = object.url_for(:read).request_uri.gsub(S3_ACCESS_KEY_ID, "YOUR_S3_ACCESS_KEY_ID")
|
158
|
+
|
159
|
+
puts " - Uploaded to: " + object.public_url.request_uri
|
160
|
+
puts " - Use this URL to download the file: https://s3.amazonaws.com/" + S3_BUCKET + request_uri
|
161
|
+
puts " - S3 sync performed successfully, took %.2f seconds" % (Time.now - s3_start)
|
162
|
+
end
|
163
|
+
|
164
|
+
puts '🚀 ' + green('Backup took %.2f seconds' % (Time.now - backup_start))
|
data/lib/redis-backup.rb
ADDED
@@ -0,0 +1,17 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
require File.expand_path('../lib/redis-backup/version', __FILE__)
|
3
|
+
|
4
|
+
Gem::Specification.new do |gem|
|
5
|
+
gem.authors = ["Jose Diaz-Gonzalez"]
|
6
|
+
gem.email = ["email@josediazgonzalez.com"]
|
7
|
+
gem.description = %q{redis-backup is a simple backup script to automate the creation and storage or redis dump.rdb files.}
|
8
|
+
gem.summary = %q{a small ruby gem that allows automated redis-backups}
|
9
|
+
gem.homepage = "https://github.com/josegonzalez/redis-backup"
|
10
|
+
|
11
|
+
gem.files = `git ls-files`.split($\)
|
12
|
+
gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
|
13
|
+
gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
|
14
|
+
gem.name = "redis-backup"
|
15
|
+
gem.require_paths = ["lib"]
|
16
|
+
gem.version = RedisBackup::VERSION
|
17
|
+
end
|
metadata
ADDED
@@ -0,0 +1,57 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: redis-backup
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.1
|
5
|
+
prerelease:
|
6
|
+
platform: ruby
|
7
|
+
authors:
|
8
|
+
- Jose Diaz-Gonzalez
|
9
|
+
autorequire:
|
10
|
+
bindir: bin
|
11
|
+
cert_chain: []
|
12
|
+
date: 2013-02-19 00:00:00.000000000 Z
|
13
|
+
dependencies: []
|
14
|
+
description: redis-backup is a simple backup script to automate the creation and storage
|
15
|
+
or redis dump.rdb files.
|
16
|
+
email:
|
17
|
+
- email@josediazgonzalez.com
|
18
|
+
executables:
|
19
|
+
- redis-backup
|
20
|
+
extensions: []
|
21
|
+
extra_rdoc_files: []
|
22
|
+
files:
|
23
|
+
- .gitignore
|
24
|
+
- Gemfile
|
25
|
+
- LICENSE
|
26
|
+
- README.md
|
27
|
+
- Rakefile
|
28
|
+
- bin/redis-backup
|
29
|
+
- lib/redis-backup.rb
|
30
|
+
- lib/redis-backup/version.rb
|
31
|
+
- redis-backup.gemspec
|
32
|
+
homepage: https://github.com/josegonzalez/redis-backup
|
33
|
+
licenses: []
|
34
|
+
post_install_message:
|
35
|
+
rdoc_options: []
|
36
|
+
require_paths:
|
37
|
+
- lib
|
38
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
39
|
+
none: false
|
40
|
+
requirements:
|
41
|
+
- - ! '>='
|
42
|
+
- !ruby/object:Gem::Version
|
43
|
+
version: '0'
|
44
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
45
|
+
none: false
|
46
|
+
requirements:
|
47
|
+
- - ! '>='
|
48
|
+
- !ruby/object:Gem::Version
|
49
|
+
version: '0'
|
50
|
+
requirements: []
|
51
|
+
rubyforge_project:
|
52
|
+
rubygems_version: 1.8.23
|
53
|
+
signing_key:
|
54
|
+
specification_version: 3
|
55
|
+
summary: a small ruby gem that allows automated redis-backups
|
56
|
+
test_files: []
|
57
|
+
has_rdoc:
|