ey-backup 0.0.3 → 0.0.4
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/README +1 -1
- metadata +45 -26
- data/Rakefile +0 -59
- data/TODO +0 -4
- data/bin/eybackup +0 -60
- data/lib/ey-backup.rb +0 -0
- data/lib/ey-backup/mysql_backup.rb +0 -122
- data/spec/ey-backup_spec.rb +0 -7
- data/spec/spec_helper.rb +0 -2
data/README
CHANGED
metadata
CHANGED
|
@@ -1,63 +1,82 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: ey-backup
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
|
|
4
|
+
hash: 23
|
|
5
|
+
prerelease:
|
|
6
|
+
segments:
|
|
7
|
+
- 0
|
|
8
|
+
- 0
|
|
9
|
+
- 4
|
|
10
|
+
version: 0.0.4
|
|
5
11
|
platform: ruby
|
|
6
12
|
authors:
|
|
7
13
|
- Ezra Zygmuntowicz
|
|
8
|
-
autorequire:
|
|
14
|
+
autorequire:
|
|
9
15
|
bindir: bin
|
|
10
16
|
cert_chain: []
|
|
11
17
|
|
|
12
|
-
date:
|
|
18
|
+
date: 2012-02-22 00:00:00 -08:00
|
|
13
19
|
default_executable:
|
|
14
|
-
dependencies:
|
|
20
|
+
dependencies:
|
|
21
|
+
- !ruby/object:Gem::Dependency
|
|
22
|
+
name: ey_cloud_server
|
|
23
|
+
prerelease: false
|
|
24
|
+
requirement: &id001 !ruby/object:Gem::Requirement
|
|
25
|
+
none: false
|
|
26
|
+
requirements:
|
|
27
|
+
- - ">="
|
|
28
|
+
- !ruby/object:Gem::Version
|
|
29
|
+
hash: 3
|
|
30
|
+
segments:
|
|
31
|
+
- 0
|
|
32
|
+
version: "0"
|
|
33
|
+
type: :runtime
|
|
34
|
+
version_requirements: *id001
|
|
35
|
+
description: ey-backup functionality has been rolled into the ey_cloud_server gem
|
|
36
|
+
email:
|
|
37
|
+
- ezra@engineyard.com
|
|
38
|
+
executables: []
|
|
15
39
|
|
|
16
|
-
description: A gem that provides s3 backups for ey-solo slices...
|
|
17
|
-
email: ezra@engineyard.com
|
|
18
|
-
executables:
|
|
19
|
-
- eybackup
|
|
20
40
|
extensions: []
|
|
21
41
|
|
|
22
|
-
extra_rdoc_files:
|
|
23
|
-
|
|
24
|
-
- LICENSE
|
|
25
|
-
- TODO
|
|
42
|
+
extra_rdoc_files: []
|
|
43
|
+
|
|
26
44
|
files:
|
|
27
|
-
- LICENSE
|
|
28
45
|
- README
|
|
29
|
-
-
|
|
30
|
-
- TODO
|
|
31
|
-
- lib/ey-backup
|
|
32
|
-
- lib/ey-backup/mysql_backup.rb
|
|
33
|
-
- lib/ey-backup.rb
|
|
34
|
-
- spec/ey-backup_spec.rb
|
|
35
|
-
- spec/spec_helper.rb
|
|
46
|
+
- LICENSE
|
|
36
47
|
has_rdoc: true
|
|
37
|
-
homepage:
|
|
48
|
+
homepage: ""
|
|
49
|
+
licenses: []
|
|
50
|
+
|
|
38
51
|
post_install_message:
|
|
39
52
|
rdoc_options: []
|
|
40
53
|
|
|
41
54
|
require_paths:
|
|
42
55
|
- lib
|
|
43
56
|
required_ruby_version: !ruby/object:Gem::Requirement
|
|
57
|
+
none: false
|
|
44
58
|
requirements:
|
|
45
59
|
- - ">="
|
|
46
60
|
- !ruby/object:Gem::Version
|
|
61
|
+
hash: 3
|
|
62
|
+
segments:
|
|
63
|
+
- 0
|
|
47
64
|
version: "0"
|
|
48
|
-
version:
|
|
49
65
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
66
|
+
none: false
|
|
50
67
|
requirements:
|
|
51
68
|
- - ">="
|
|
52
69
|
- !ruby/object:Gem::Version
|
|
70
|
+
hash: 3
|
|
71
|
+
segments:
|
|
72
|
+
- 0
|
|
53
73
|
version: "0"
|
|
54
|
-
version:
|
|
55
74
|
requirements: []
|
|
56
75
|
|
|
57
76
|
rubyforge_project:
|
|
58
|
-
rubygems_version: 1.
|
|
77
|
+
rubygems_version: 1.5.2
|
|
59
78
|
signing_key:
|
|
60
|
-
specification_version:
|
|
61
|
-
summary:
|
|
79
|
+
specification_version: 3
|
|
80
|
+
summary: ey-backup has been rolled into ey_cloud_server, please use that gem instead.
|
|
62
81
|
test_files: []
|
|
63
82
|
|
data/Rakefile
DELETED
|
@@ -1,59 +0,0 @@
|
|
|
1
|
-
require 'rubygems'
|
|
2
|
-
require 'rake/gempackagetask'
|
|
3
|
-
require 'rubygems/specification'
|
|
4
|
-
require 'date'
|
|
5
|
-
require 'spec/rake/spectask'
|
|
6
|
-
|
|
7
|
-
GEM = "ey-backup"
|
|
8
|
-
GEM_VERSION = "0.0.3"
|
|
9
|
-
AUTHOR = "Ezra Zygmuntowicz"
|
|
10
|
-
EMAIL = "ezra@engineyard.com"
|
|
11
|
-
HOMEPAGE = "http://example.com"
|
|
12
|
-
SUMMARY = "A gem that provides s3 backups for ey-solo slices..."
|
|
13
|
-
|
|
14
|
-
spec = Gem::Specification.new do |s|
|
|
15
|
-
s.name = GEM
|
|
16
|
-
s.version = GEM_VERSION
|
|
17
|
-
s.platform = Gem::Platform::RUBY
|
|
18
|
-
s.has_rdoc = true
|
|
19
|
-
s.extra_rdoc_files = ["README", "LICENSE", 'TODO']
|
|
20
|
-
s.summary = SUMMARY
|
|
21
|
-
s.description = s.summary
|
|
22
|
-
s.author = AUTHOR
|
|
23
|
-
s.email = EMAIL
|
|
24
|
-
s.homepage = HOMEPAGE
|
|
25
|
-
s.bindir = "bin"
|
|
26
|
-
s.executables = %w( eybackup )
|
|
27
|
-
|
|
28
|
-
# Uncomment this to add a dependency
|
|
29
|
-
# s.add_dependency "foo"
|
|
30
|
-
|
|
31
|
-
s.require_path = 'lib'
|
|
32
|
-
s.autorequire = GEM
|
|
33
|
-
s.files = %w(LICENSE README Rakefile TODO) + Dir.glob("{lib,spec}/**/*")
|
|
34
|
-
end
|
|
35
|
-
|
|
36
|
-
task :default => :spec
|
|
37
|
-
|
|
38
|
-
desc "Run specs"
|
|
39
|
-
Spec::Rake::SpecTask.new do |t|
|
|
40
|
-
t.spec_files = FileList['spec/**/*_spec.rb']
|
|
41
|
-
t.spec_opts = %w(-fs --color)
|
|
42
|
-
end
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
Rake::GemPackageTask.new(spec) do |pkg|
|
|
46
|
-
pkg.gem_spec = spec
|
|
47
|
-
end
|
|
48
|
-
|
|
49
|
-
desc "install the gem locally"
|
|
50
|
-
task :install => [:package] do
|
|
51
|
-
sh %{sudo gem install pkg/#{GEM}-#{GEM_VERSION}}
|
|
52
|
-
end
|
|
53
|
-
|
|
54
|
-
desc "create a gemspec file"
|
|
55
|
-
task :make_spec do
|
|
56
|
-
File.open("#{GEM}.gemspec", "w") do |file|
|
|
57
|
-
file.puts spec.to_ruby
|
|
58
|
-
end
|
|
59
|
-
end
|
data/TODO
DELETED
data/bin/eybackup
DELETED
|
@@ -1,60 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env ruby
|
|
2
|
-
require 'rubygems'
|
|
3
|
-
require 'yaml'
|
|
4
|
-
require "optparse"
|
|
5
|
-
require 'ey-backup/mysql_backup'
|
|
6
|
-
|
|
7
|
-
options = {:config => '/etc/.mysql.backups.yml',
|
|
8
|
-
:command => :new_backup}
|
|
9
|
-
|
|
10
|
-
# Build a parser for the command line arguments
|
|
11
|
-
opts = OptionParser.new do |opts|
|
|
12
|
-
opts.version = "0.0.1"
|
|
13
|
-
|
|
14
|
-
opts.banner = "Usage: eybackup [-flag] [argument]"
|
|
15
|
-
opts.define_head "eybackup: backing up your shit since way back when..."
|
|
16
|
-
opts.separator '*'*80
|
|
17
|
-
|
|
18
|
-
opts.on("-l", "--list-backup DATABASE", "List mysql backups for DATABASE") do |db|
|
|
19
|
-
options[:db] = (db || 'all')
|
|
20
|
-
options[:command] = :list
|
|
21
|
-
end
|
|
22
|
-
|
|
23
|
-
opts.on("-n", "--new-backup", "Create new mysql backup") do
|
|
24
|
-
options[:command] = :new_backup
|
|
25
|
-
end
|
|
26
|
-
|
|
27
|
-
opts.on("-c", "--config CONFIG", "Use config file.") do |config|
|
|
28
|
-
options[:config] = config
|
|
29
|
-
end
|
|
30
|
-
|
|
31
|
-
opts.on("-d", "--download BACKUP_INDEX", "download the backup specified by index. Run eybackup -l to get the index.") do |index|
|
|
32
|
-
options[:command] = :download
|
|
33
|
-
options[:index] = index
|
|
34
|
-
end
|
|
35
|
-
|
|
36
|
-
opts.on("-r", "--restore BACKUP_INDEX", "Download and apply the backup specified by index WARNING! will overwrite the current db with the backup. Run eybackup -l to get the index.") do |index|
|
|
37
|
-
options[:command] = :restore
|
|
38
|
-
options[:index] = index
|
|
39
|
-
end
|
|
40
|
-
|
|
41
|
-
end
|
|
42
|
-
|
|
43
|
-
opts.parse!
|
|
44
|
-
|
|
45
|
-
eyb = nil
|
|
46
|
-
if File.exist?(options[:config])
|
|
47
|
-
eyb = EyBackup::MysqlBackup.new(YAML::load(IO.read(options[:config])))
|
|
48
|
-
end
|
|
49
|
-
|
|
50
|
-
case options[:command]
|
|
51
|
-
when :list
|
|
52
|
-
eyb.list options[:db], true
|
|
53
|
-
when :new_backup
|
|
54
|
-
eyb.new_backup
|
|
55
|
-
when :download
|
|
56
|
-
eyb.download(options[:index])
|
|
57
|
-
when :restore
|
|
58
|
-
eyb.restore(options[:index])
|
|
59
|
-
end
|
|
60
|
-
eyb.cleanup
|
data/lib/ey-backup.rb
DELETED
|
File without changes
|
|
@@ -1,122 +0,0 @@
|
|
|
1
|
-
require 'aws/s3'
|
|
2
|
-
require 'date'
|
|
3
|
-
require 'digest'
|
|
4
|
-
require 'net/http'
|
|
5
|
-
require 'fileutils'
|
|
6
|
-
|
|
7
|
-
module AWS::S3
|
|
8
|
-
class S3Object
|
|
9
|
-
def <=>(other)
|
|
10
|
-
DateTime.parse(self.about['last-modified']) <=> DateTime.parse(other.about['last-modified'])
|
|
11
|
-
end
|
|
12
|
-
end
|
|
13
|
-
end
|
|
14
|
-
|
|
15
|
-
module EyBackup
|
|
16
|
-
def self.get_from_ec2(thing="/")
|
|
17
|
-
base_url = "http://169.254.169.254/latest/meta-data" + thing
|
|
18
|
-
url = URI.parse(base_url)
|
|
19
|
-
req = Net::HTTP::Get.new(url.path)
|
|
20
|
-
res = Net::HTTP.start(url.host, url.port) {|http|
|
|
21
|
-
http.request(req)
|
|
22
|
-
}
|
|
23
|
-
res.body
|
|
24
|
-
end
|
|
25
|
-
class MysqlBackup
|
|
26
|
-
def initialize(opts={})
|
|
27
|
-
AWS::S3::Base.establish_connection!(
|
|
28
|
-
:access_key_id => opts[:aws_secret_id],
|
|
29
|
-
:secret_access_key => opts[:aws_secret_key]
|
|
30
|
-
)
|
|
31
|
-
@dbuser = opts[:dbuser]
|
|
32
|
-
@dbpass = opts[:dbpass]
|
|
33
|
-
@databases = opts[:databases]
|
|
34
|
-
@keep = opts[:keep]
|
|
35
|
-
@bucket = "ey-backup-#{Digest::SHA1.hexdigest(opts[:aws_secret_id])[0..11]}"
|
|
36
|
-
@tmpname = "#{Time.now.strftime("%Y-%m-%dT%H:%M:%S").gsub(/:/, '-')}.sql.gz"
|
|
37
|
-
@id = EyBackup.get_from_ec2('/instance-id')
|
|
38
|
-
FileUtils.mkdir_p '/mnt/tmp'
|
|
39
|
-
begin
|
|
40
|
-
AWS::S3::Bucket.create @bucket
|
|
41
|
-
rescue AWS::S3::BucketAlreadyExists
|
|
42
|
-
end
|
|
43
|
-
end
|
|
44
|
-
|
|
45
|
-
def new_backup
|
|
46
|
-
@databases.each do |db|
|
|
47
|
-
backup_database(db)
|
|
48
|
-
end
|
|
49
|
-
end
|
|
50
|
-
|
|
51
|
-
def backup_database(database)
|
|
52
|
-
mysqlcmd = "mysqldump -u #{@dbuser} -p'#{@dbpass}' #{database} | gzip - > /mnt/tmp/#{database}.#{@tmpname}"
|
|
53
|
-
if system(mysqlcmd)
|
|
54
|
-
AWS::S3::S3Object.store(
|
|
55
|
-
"/#{@id}.#{database}/#{database}.#{@tmpname}",
|
|
56
|
-
open("/mnt/tmp/#{database}.#{@tmpname}"),
|
|
57
|
-
@bucket,
|
|
58
|
-
:access => :private
|
|
59
|
-
)
|
|
60
|
-
FileUtils.rm "/mnt/tmp/#{database}.#{@tmpname}"
|
|
61
|
-
puts "successful backup: #{database}.#{@tmpname}"
|
|
62
|
-
else
|
|
63
|
-
raise "Unable to dump database#{database} wtf?"
|
|
64
|
-
end
|
|
65
|
-
end
|
|
66
|
-
|
|
67
|
-
def download(index)
|
|
68
|
-
idx, db = index.split(":")
|
|
69
|
-
obj = list(db)[idx.to_i]
|
|
70
|
-
puts "downloading: #{normalize_name(obj)}"
|
|
71
|
-
File.open(normalize_name(obj), 'wb') do |f|
|
|
72
|
-
print "."
|
|
73
|
-
obj.value {|chunk| f.write chunk }
|
|
74
|
-
end
|
|
75
|
-
puts
|
|
76
|
-
puts "finished"
|
|
77
|
-
normalize_name(obj)
|
|
78
|
-
end
|
|
79
|
-
|
|
80
|
-
def restore(index)
|
|
81
|
-
name = download(index)
|
|
82
|
-
db = name.split('.').first
|
|
83
|
-
cmd = "gunzip -c #{name} | mysql -u #{@dbuser} -p'#{@dbpass}' #{db}"
|
|
84
|
-
if system(cmd)
|
|
85
|
-
puts "successfully restored backup: #{name}"
|
|
86
|
-
else
|
|
87
|
-
puts "FAIL"
|
|
88
|
-
end
|
|
89
|
-
end
|
|
90
|
-
|
|
91
|
-
def cleanup
|
|
92
|
-
list('all',false)[0...-(@keep*@databases.size)].each{|o|
|
|
93
|
-
puts "deleting: #{o.key}"
|
|
94
|
-
o.delete
|
|
95
|
-
}
|
|
96
|
-
end
|
|
97
|
-
|
|
98
|
-
def normalize_name(obj)
|
|
99
|
-
obj.key.gsub(/^.*?\//, '')
|
|
100
|
-
end
|
|
101
|
-
|
|
102
|
-
def list(database='all', printer = false)
|
|
103
|
-
puts "listing #{database} database" if printer
|
|
104
|
-
backups = []
|
|
105
|
-
if database == 'all'
|
|
106
|
-
@databases.each do |db|
|
|
107
|
-
backups << AWS::S3::Bucket.objects(@bucket, :prefix => "#{@id}.#{db}")
|
|
108
|
-
end
|
|
109
|
-
backups = backups.flatten.sort
|
|
110
|
-
else
|
|
111
|
-
backups = AWS::S3::Bucket.objects(@bucket, :prefix => "#{@id}.#{database}").sort
|
|
112
|
-
end
|
|
113
|
-
if printer
|
|
114
|
-
backups.each_with_index do |b,i|
|
|
115
|
-
puts "#{i}:#{database} #{normalize_name(b)}"
|
|
116
|
-
end
|
|
117
|
-
end
|
|
118
|
-
backups
|
|
119
|
-
end
|
|
120
|
-
|
|
121
|
-
end
|
|
122
|
-
end
|
data/spec/ey-backup_spec.rb
DELETED
data/spec/spec_helper.rb
DELETED