db_backups 0.0.3
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.
- 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: []
|