db_backups 0.0.3
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +1 -0
- data/Gemfile +7 -0
- data/README.md +30 -0
- data/Rakefile +3 -0
- data/bin/db_backups +103 -0
- data/db_backups.gemspec +27 -0
- data/lib/db_backups/container.rb +46 -0
- data/lib/db_backups/db_backup.rb +27 -0
- data/lib/db_backups/db_config.rb +9 -0
- data/lib/db_backups/version.rb +3 -0
- data/lib/db_backups/view.rb +31 -0
- metadata +127 -0
data/.gitignore
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
Gemfile.lock
|
data/Gemfile
ADDED
data/README.md
ADDED
@@ -0,0 +1,30 @@
|
|
1
|
+
db_backups
|
2
|
+
===
|
3
|
+
|
4
|
+
A Command Line Interface to DB backups (using [backup](https://github.com/meskyanichi/backup) gem)
|
5
|
+
stored in Rackspace CloudFiles
|
6
|
+
|
7
|
+
Designed for internal usage for *our* rails apps and their mysql backups,
|
8
|
+
but *could* be driven in a more generic direction if anyone external was interested.
|
9
|
+
|
10
|
+
Setup:
|
11
|
+
|
12
|
+
Locomote only:
|
13
|
+
```bash
|
14
|
+
git clone git@github.com:locomote/config.git ~/.loco_config && ln -s ~/.loco_config/fogrc ~/.fog
|
15
|
+
```
|
16
|
+
|
17
|
+
or for everyone else:
|
18
|
+
|
19
|
+
```bash
|
20
|
+
echo "default:\n rackspace_username: ${RACKSPACE_USERNAME}\n rackspace_api_key: ${RACKSPACE_API_KEY}" > ~/.fog
|
21
|
+
```
|
22
|
+
|
23
|
+
Usage:
|
24
|
+
```bash
|
25
|
+
db_backups index
|
26
|
+
db_backups show
|
27
|
+
db_backups get
|
28
|
+
db_backups load
|
29
|
+
db_backups -euat index # NB. defaults to production environment, but can be set to any in the config/database.yml
|
30
|
+
```
|
data/Rakefile
ADDED
data/bin/db_backups
ADDED
@@ -0,0 +1,103 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
require 'rubygems'
|
3
|
+
|
4
|
+
require 'open3'
|
5
|
+
|
6
|
+
require 'optitron'
|
7
|
+
require 'db_backups/container'
|
8
|
+
require 'db_backups/db_config'
|
9
|
+
|
10
|
+
class DbBackups::CLI < Optitron::CLI
|
11
|
+
|
12
|
+
class_opt :environment, 'Source Environment', :in => %w{staging uat production} , :default => :production
|
13
|
+
|
14
|
+
desc 'Index backups'
|
15
|
+
def index
|
16
|
+
puts container
|
17
|
+
end
|
18
|
+
|
19
|
+
desc 'Show backup (defaults to last)'
|
20
|
+
arg_types :numeric
|
21
|
+
def show(index=-1)
|
22
|
+
p container[index]
|
23
|
+
end
|
24
|
+
|
25
|
+
desc 'Get backup (defaults to last)'
|
26
|
+
arg_types :numeric
|
27
|
+
def get(index=-1)
|
28
|
+
puts cat(container[index])
|
29
|
+
end
|
30
|
+
|
31
|
+
desc 'Load backup'
|
32
|
+
arg_types :numeric
|
33
|
+
def load(index=-1)
|
34
|
+
backup = container[index]
|
35
|
+
print "Loading backup #{backup.inspect} into database #{database} ... "
|
36
|
+
p cmd = "mysql -u#{username} -p#{password} #{database}"
|
37
|
+
Open3.popen3(cmd) do |stdin, stdout, stderr|
|
38
|
+
stdin.write(cat(backup))
|
39
|
+
end
|
40
|
+
puts "DONE"
|
41
|
+
end
|
42
|
+
|
43
|
+
desc 'Retrieve backup (defaults to last)'
|
44
|
+
arg_types :numeric
|
45
|
+
def retrieve(index=-1)
|
46
|
+
backup = container[index]
|
47
|
+
f_name = backup.to_s
|
48
|
+
print "Retrieving backup #{backup} ... "
|
49
|
+
File.open(f_name, 'w') do |f|
|
50
|
+
f.write(cat(backup))
|
51
|
+
end
|
52
|
+
puts "DONE"
|
53
|
+
end
|
54
|
+
|
55
|
+
private
|
56
|
+
|
57
|
+
def db_config
|
58
|
+
@db_config ||= DbBackups::DbConfig.new.yaml
|
59
|
+
end
|
60
|
+
|
61
|
+
def username
|
62
|
+
db_config[current_environment]["username"]
|
63
|
+
end
|
64
|
+
|
65
|
+
def password
|
66
|
+
db_config[current_environment]["password"]
|
67
|
+
end
|
68
|
+
|
69
|
+
def database
|
70
|
+
db_config[current_environment]["database"]
|
71
|
+
end
|
72
|
+
|
73
|
+
def current_environment
|
74
|
+
ENV['APP_ENV'] || ENV['RAILS_ENV'] || "development"
|
75
|
+
end
|
76
|
+
|
77
|
+
def cat(backup)
|
78
|
+
StringIO.open(backup.read) do |cf|
|
79
|
+
Gem::Package::TarReader.new(cf).each do |entry|
|
80
|
+
return Zlib::GzipReader.new(entry).read if entry.file?
|
81
|
+
end
|
82
|
+
end
|
83
|
+
end
|
84
|
+
|
85
|
+
def pwd
|
86
|
+
@pwd ||= `basename $(pwd)`.strip
|
87
|
+
end
|
88
|
+
|
89
|
+
def app
|
90
|
+
# TODO - fix the yuk :(
|
91
|
+
@app ||= pwd == 'travel_management_platform' ? 'tmp' : pwd
|
92
|
+
end
|
93
|
+
|
94
|
+
def environment
|
95
|
+
@environment ||= params[:environment]
|
96
|
+
end
|
97
|
+
|
98
|
+
def container
|
99
|
+
@container ||= DbBackups::Container.new(app, environment)
|
100
|
+
end
|
101
|
+
end
|
102
|
+
|
103
|
+
DbBackups::CLI.dispatch
|
data/db_backups.gemspec
ADDED
@@ -0,0 +1,27 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
lib = File.expand_path('../lib', __FILE__)
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
+
|
5
|
+
gem_name='db_backups'
|
6
|
+
|
7
|
+
require "#{gem_name}/version"
|
8
|
+
|
9
|
+
Gem::Specification.new do |gem|
|
10
|
+
gem.name = gem_name
|
11
|
+
gem.version = DbBackups::VERSION
|
12
|
+
gem.authors = ["Chris"]
|
13
|
+
gem.email = ["chris@locomote.com"]
|
14
|
+
gem.description = %q{Access Rackspace Cloud File MySQL backups}
|
15
|
+
gem.summary = gem.description
|
16
|
+
|
17
|
+
gem.files = `git ls-files | grep -vE '(jenkins|.gitmodules|.ruby-version)'`.split("\n")
|
18
|
+
gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
|
19
|
+
gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
|
20
|
+
gem.require_paths = ["lib"]
|
21
|
+
|
22
|
+
gem.add_dependency 'optitron'
|
23
|
+
gem.add_dependency 'fog'
|
24
|
+
gem.add_dependency 'terminal-table'
|
25
|
+
|
26
|
+
gem.add_dependency 'pry'
|
27
|
+
end
|
@@ -0,0 +1,46 @@
|
|
1
|
+
require 'fog'
|
2
|
+
require 'db_backups/view'
|
3
|
+
require 'db_backups/db_backup'
|
4
|
+
|
5
|
+
module DbBackups
|
6
|
+
class Container
|
7
|
+
include View
|
8
|
+
|
9
|
+
attr_reader :app, :environment
|
10
|
+
|
11
|
+
def initialize(app, environment)
|
12
|
+
@app = app
|
13
|
+
@environment = environment
|
14
|
+
end
|
15
|
+
|
16
|
+
def [](index)
|
17
|
+
files[index]
|
18
|
+
end
|
19
|
+
|
20
|
+
private
|
21
|
+
|
22
|
+
def files
|
23
|
+
@files ||= container.files.map { |f|
|
24
|
+
DbBackup.new(f, :app => app, :environment => environment)
|
25
|
+
}.select { |f|
|
26
|
+
f.environment == environment
|
27
|
+
}
|
28
|
+
end
|
29
|
+
|
30
|
+
def container_name
|
31
|
+
"#{app}_db_backup"
|
32
|
+
end
|
33
|
+
|
34
|
+
def container
|
35
|
+
@container ||= storage.directories.get(container_name)
|
36
|
+
end
|
37
|
+
|
38
|
+
def provider
|
39
|
+
@provider ||= 'Rackspace'
|
40
|
+
end
|
41
|
+
|
42
|
+
def storage
|
43
|
+
@storage ||= Fog::Storage.new(:provider => provider)
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
require 'forwardable'
|
2
|
+
|
3
|
+
class DbBackup
|
4
|
+
extend Forwardable
|
5
|
+
|
6
|
+
attr_reader :app, :environment
|
7
|
+
def_delegators :@cloud_file, :last_modified, :content_length
|
8
|
+
def_delegator :@cloud_file, :body, :read
|
9
|
+
|
10
|
+
def initialize(cloud_file, opts={})
|
11
|
+
@cloud_file = cloud_file
|
12
|
+
@app = opts[:app]
|
13
|
+
@environment = opts[:environment]
|
14
|
+
end
|
15
|
+
|
16
|
+
def environment
|
17
|
+
@environment ||= @cloud_file.key.split("/")[1]
|
18
|
+
end
|
19
|
+
|
20
|
+
def to_s
|
21
|
+
"#{app}.#{environment}.#{last_modified.strftime('%Y%m%d%H%M%S')}.sql"
|
22
|
+
end
|
23
|
+
|
24
|
+
def inspect
|
25
|
+
"<##{self.class.name} #{to_s.inspect} size=#{content_length}>"
|
26
|
+
end
|
27
|
+
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
require 'terminal-table'
|
2
|
+
|
3
|
+
module DbBackups
|
4
|
+
module View
|
5
|
+
def to_s
|
6
|
+
table.to_s
|
7
|
+
end
|
8
|
+
|
9
|
+
private
|
10
|
+
|
11
|
+
def file_attrs
|
12
|
+
@file_attrs ||= [:last_modified, :content_length]
|
13
|
+
end
|
14
|
+
|
15
|
+
def headings
|
16
|
+
@headings ||= [nil] + file_attrs
|
17
|
+
end
|
18
|
+
|
19
|
+
def rows
|
20
|
+
@rows ||= files.each_with_index.map { |f, i| file_attrs.inject([i]) { |a, attr| a << f.send(attr) } }
|
21
|
+
end
|
22
|
+
|
23
|
+
def title
|
24
|
+
"Db Backups (#{app} - #{environment})"
|
25
|
+
end
|
26
|
+
|
27
|
+
def table
|
28
|
+
@table ||= Terminal::Table.new :title => title, :headings => headings, :rows => rows
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
metadata
ADDED
@@ -0,0 +1,127 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: db_backups
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.3
|
5
|
+
prerelease:
|
6
|
+
platform: ruby
|
7
|
+
authors:
|
8
|
+
- Chris
|
9
|
+
autorequire:
|
10
|
+
bindir: bin
|
11
|
+
cert_chain: []
|
12
|
+
date: 2013-03-27 00:00:00.000000000 Z
|
13
|
+
dependencies:
|
14
|
+
- !ruby/object:Gem::Dependency
|
15
|
+
name: optitron
|
16
|
+
requirement: !ruby/object:Gem::Requirement
|
17
|
+
none: false
|
18
|
+
requirements:
|
19
|
+
- - ! '>='
|
20
|
+
- !ruby/object:Gem::Version
|
21
|
+
version: '0'
|
22
|
+
type: :runtime
|
23
|
+
prerelease: false
|
24
|
+
version_requirements: !ruby/object:Gem::Requirement
|
25
|
+
none: false
|
26
|
+
requirements:
|
27
|
+
- - ! '>='
|
28
|
+
- !ruby/object:Gem::Version
|
29
|
+
version: '0'
|
30
|
+
- !ruby/object:Gem::Dependency
|
31
|
+
name: fog
|
32
|
+
requirement: !ruby/object:Gem::Requirement
|
33
|
+
none: false
|
34
|
+
requirements:
|
35
|
+
- - ! '>='
|
36
|
+
- !ruby/object:Gem::Version
|
37
|
+
version: '0'
|
38
|
+
type: :runtime
|
39
|
+
prerelease: false
|
40
|
+
version_requirements: !ruby/object:Gem::Requirement
|
41
|
+
none: false
|
42
|
+
requirements:
|
43
|
+
- - ! '>='
|
44
|
+
- !ruby/object:Gem::Version
|
45
|
+
version: '0'
|
46
|
+
- !ruby/object:Gem::Dependency
|
47
|
+
name: terminal-table
|
48
|
+
requirement: !ruby/object:Gem::Requirement
|
49
|
+
none: false
|
50
|
+
requirements:
|
51
|
+
- - ! '>='
|
52
|
+
- !ruby/object:Gem::Version
|
53
|
+
version: '0'
|
54
|
+
type: :runtime
|
55
|
+
prerelease: false
|
56
|
+
version_requirements: !ruby/object:Gem::Requirement
|
57
|
+
none: false
|
58
|
+
requirements:
|
59
|
+
- - ! '>='
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '0'
|
62
|
+
- !ruby/object:Gem::Dependency
|
63
|
+
name: pry
|
64
|
+
requirement: !ruby/object:Gem::Requirement
|
65
|
+
none: false
|
66
|
+
requirements:
|
67
|
+
- - ! '>='
|
68
|
+
- !ruby/object:Gem::Version
|
69
|
+
version: '0'
|
70
|
+
type: :runtime
|
71
|
+
prerelease: false
|
72
|
+
version_requirements: !ruby/object:Gem::Requirement
|
73
|
+
none: false
|
74
|
+
requirements:
|
75
|
+
- - ! '>='
|
76
|
+
- !ruby/object:Gem::Version
|
77
|
+
version: '0'
|
78
|
+
description: Access Rackspace Cloud File MySQL backups
|
79
|
+
email:
|
80
|
+
- chris@locomote.com
|
81
|
+
executables:
|
82
|
+
- db_backups
|
83
|
+
extensions: []
|
84
|
+
extra_rdoc_files: []
|
85
|
+
files:
|
86
|
+
- .gitignore
|
87
|
+
- Gemfile
|
88
|
+
- README.md
|
89
|
+
- Rakefile
|
90
|
+
- bin/db_backups
|
91
|
+
- db_backups.gemspec
|
92
|
+
- lib/db_backups/container.rb
|
93
|
+
- lib/db_backups/db_backup.rb
|
94
|
+
- lib/db_backups/db_config.rb
|
95
|
+
- lib/db_backups/version.rb
|
96
|
+
- lib/db_backups/view.rb
|
97
|
+
homepage:
|
98
|
+
licenses: []
|
99
|
+
post_install_message:
|
100
|
+
rdoc_options: []
|
101
|
+
require_paths:
|
102
|
+
- lib
|
103
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
104
|
+
none: false
|
105
|
+
requirements:
|
106
|
+
- - ! '>='
|
107
|
+
- !ruby/object:Gem::Version
|
108
|
+
version: '0'
|
109
|
+
segments:
|
110
|
+
- 0
|
111
|
+
hash: 753128801201890002
|
112
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
113
|
+
none: false
|
114
|
+
requirements:
|
115
|
+
- - ! '>='
|
116
|
+
- !ruby/object:Gem::Version
|
117
|
+
version: '0'
|
118
|
+
segments:
|
119
|
+
- 0
|
120
|
+
hash: 753128801201890002
|
121
|
+
requirements: []
|
122
|
+
rubyforge_project:
|
123
|
+
rubygems_version: 1.8.24
|
124
|
+
signing_key:
|
125
|
+
specification_version: 3
|
126
|
+
summary: Access Rackspace Cloud File MySQL backups
|
127
|
+
test_files: []
|