backups-cli 1.0.9

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.
@@ -0,0 +1,54 @@
1
+ module Backups
2
+ module System
3
+
4
+ def exec command
5
+ # $LOGGER.debug "Running #{command}" if $LOG_ACTIVE == 1
6
+ return if $DRY_RUN
7
+
8
+ output = `#{command}`
9
+ if $?.exitstatus != 0
10
+ raise RuntimeError, \
11
+ "Command '#{command}' failed with exit code #{$?.exitstatus}."
12
+ end
13
+
14
+ return output.chomp()
15
+ end
16
+
17
+ def delete file
18
+ exec "rm #{file}"
19
+ end
20
+
21
+ def delete_dir start, stop = nil
22
+ return exec "rmdir #{start}" unless stop
23
+ stop = stop.chomp("/")
24
+ loop do
25
+ exec "rmdir #{start}" if File.directory? start
26
+ break if start == stop
27
+ start = File.dirname(start)
28
+ end
29
+ end
30
+
31
+ def nuke_dir dir
32
+ exec "rm -fr #{dir}"
33
+ end
34
+
35
+ def mkdir dirname
36
+ exec "mkdir -p #{dirname}"
37
+ end
38
+
39
+ def write filename, contents
40
+ commands = []
41
+ commands << "cat << CONTENTS > #{filename}"
42
+ commands << contents
43
+ commands << "CONTENTS"
44
+
45
+ exec commands.join("\n")
46
+ end
47
+
48
+ def get_latest_s3 path
49
+ # $LOGGER.debug "aws s3 ls #{path}/|awk '{ print $4 }'|tail -n 1"
50
+ exec "aws s3 ls #{path}/|awk '{ print $4 }'|tail -n 1"
51
+ end
52
+
53
+ end
54
+ end
@@ -0,0 +1,180 @@
1
+ require "yaml"
2
+
3
+ module Backups
4
+ module Verify
5
+ class Mysql < Base
6
+
7
+ VERIFY_PREFIX = "__verify__"
8
+
9
+ include ::Backups::Stats::Mysql
10
+
11
+ def verify
12
+ setup
13
+ download
14
+ import
15
+ clean_up
16
+ report
17
+
18
+ return @details
19
+ end
20
+
21
+ private
22
+ def setup
23
+ load_configs
24
+
25
+ @compared = 0
26
+ @failures = 0
27
+ @compsize = nil
28
+ @datedir = get_date_path()
29
+ @backups = $GLOBAL.fetch("backups", {})
30
+ @name = @config["_name"]
31
+ @verify = @config.fetch("verify", {})
32
+ @connection = @verify.fetch("connection", {})
33
+ @secret = @config.fetch("encryption", {}).fetch("secret", "")
34
+ @paths = @backups.fetch("paths", {})
35
+ @verifydir = @paths.fetch("verify", "/tmp/verify")
36
+ @jobdir = "#{@verifydir}/#{@name}"
37
+ @s3bucket = "#{@config["s3"]["bucket"]}"
38
+ @s3path = "#{@config["s3"]["path"]}"
39
+ @s3fullpath = "s3://#{@s3bucket}/#{@s3path}/#{@name}/#{@datedir}"
40
+ @package = get_latest_s3(@s3fullpath)
41
+
42
+ raise RuntimeError, "Error: Could not found the latest package in #{@s3fullpath}." \
43
+ unless @package.length > 1
44
+
45
+ @s3file = "#{@s3fullpath}/#{@package}"
46
+ @basename = File.basename(@package).gsub(".zip", "")
47
+ @download = "#{@jobdir}/#{@package}"
48
+ @timedir = @download.gsub(".zip", "")
49
+
50
+ @details = {
51
+ started: Time.now,
52
+ completed: nil,
53
+ file: nil,
54
+ size: nil,
55
+ report: nil,
56
+ }
57
+
58
+ $LOGGER.info "Preparing #{@jobdir}"
59
+ # We clean up previous imports as we are less strict with them clearing
60
+ # up cleanly.
61
+ exec "rm -fr #{@jobdir}"
62
+ exec "mkdir -p #{@jobdir}"
63
+ end
64
+
65
+ def download
66
+ $LOGGER.info "Downloading #{@s3file}"
67
+ exec "aws s3 cp #{@s3file} #{@download}"
68
+ @compsize = File.size(@download) if not $DRY_RUN
69
+ exec "cd #{@jobdir} && unzip -P #{@secret} #{@download}"
70
+ $LOGGER.info "Downloaded #{@compsize} bytes"
71
+ end
72
+
73
+ def import
74
+ files = get_import_files()
75
+
76
+ if files == []
77
+ $LOGGER.fatal "Error: There were no files in #{@timedir} to import."
78
+ return
79
+ end
80
+
81
+ # Are we importing the whole server?
82
+ if File.basename(files[0], ".sql") == ALL_DATABASES
83
+ file = files[0]
84
+ import_server file
85
+ check_stats file
86
+ else
87
+ files.each do |file|
88
+ db = File.basename(file, ".sql")
89
+ dbname = "#{VERIFY_PREFIX}#{db}"
90
+ import_database dbname, file
91
+ check_database_stats dbname, file
92
+ drop_database dbname
93
+ end
94
+ end
95
+ end
96
+
97
+ def import_server file
98
+ $LOGGER.info "Importing server from #{file}"
99
+ exec "mysql < #{file}"
100
+ end
101
+
102
+ def import_database db, file
103
+ $LOGGER.info "Importing database #{db} from #{file}"
104
+ exec "mysql -e 'DROP DATABASE IF EXISTS #{db}'"
105
+ exec "mysql -e 'CREATE DATABASE #{db}'"
106
+ exec "mysql #{db} < #{file}"
107
+ end
108
+
109
+ def get_import_files
110
+ Dir["#{@timedir}/*.sql"]
111
+ end
112
+
113
+ def check_database_stats db, file
114
+ # return if db == "mysql"
115
+
116
+ file = file.gsub(".sql", "-stats.yaml")
117
+ data = YAML.load_file(file)
118
+
119
+ data.each do |table, stats|
120
+ object = "#{db}.#{table}"
121
+ check_table db, table
122
+
123
+ imported = get_table_count(db, table)
124
+ saved = stats["rows"]
125
+
126
+ @compared = @compared + 1
127
+ if saved.to_i == imported.to_i
128
+ $LOGGER.debug "Row count match for #{object} matches"
129
+ else
130
+ $LOGGER.warn "Row count failed for #{object}. Saved #{saved} vs imported #{imported}"
131
+ end
132
+ end
133
+ end
134
+
135
+ def get_table_count db, table
136
+ sql = "SELECT COUNT(1) FROM #{db}.#{table}"
137
+ exec "mysql -e \"#{sql}\"|awk 'NR>1'"
138
+ end
139
+
140
+ def drop_database db
141
+ $LOGGER.debug "Dropping database #{db}"
142
+ sql = "DROP DATABASE #{db}"
143
+ exec "mysql -e '#{sql}'"
144
+ end
145
+
146
+ def check_table database, table
147
+ @compared = @compared + 1
148
+ rs = get_result("CHECK TABLE #{database}.#{table}")
149
+ if rs["Msg_text"] != "OK"
150
+ @failures += 1
151
+ $LOGGER.warn "Check table failed for #{database}.#{table}"
152
+ else
153
+ $LOGGER.debug "Check table passed for #{database}.#{table}"
154
+ end
155
+ end
156
+
157
+ def clean_up
158
+ $LOGGER.info "Cleaning #{@jobdir}"
159
+ @compsize = File.size(@download)
160
+ exec "rm -fr #{@jobdir}"
161
+ end
162
+
163
+ def report
164
+ $LOGGER.info "Reporting that #{@compared} checks were compared"
165
+ if @failures > 0
166
+ $LOGGER.warn "#{@failures} checks failed"
167
+ else
168
+ $LOGGER.info "All checks passed"
169
+ end
170
+
171
+ @details[:file] = @download
172
+ @details[:size] = @compsize
173
+ @details[:view] = "https://console.aws.amazon.com/s3/home?region=eu-west-1#&bucket=#{@s3bucket}&prefix=#{@s3path}"
174
+ @details[:report] = "#{@compared} stats compared with #{@failures} failures"
175
+ @details[:completed] = Time.now
176
+ end
177
+
178
+ end
179
+ end
180
+ end
@@ -0,0 +1,4 @@
1
+
2
+ module Backups
3
+ VERSION = "1.0.9"
4
+ end
metadata ADDED
@@ -0,0 +1,173 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: backups-cli
3
+ version: !ruby/object:Gem::Version
4
+ version: 1.0.9
5
+ platform: ruby
6
+ authors:
7
+ - Schibsted
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2018-03-19 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: thor
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ">="
18
+ - !ruby/object:Gem::Version
19
+ version: '0'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ">="
25
+ - !ruby/object:Gem::Version
26
+ version: '0'
27
+ - !ruby/object:Gem::Dependency
28
+ name: json
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ">="
32
+ - !ruby/object:Gem::Version
33
+ version: '0'
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ">="
39
+ - !ruby/object:Gem::Version
40
+ version: '0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: mysql2
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - ">="
46
+ - !ruby/object:Gem::Version
47
+ version: '0'
48
+ type: :runtime
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - ">="
53
+ - !ruby/object:Gem::Version
54
+ version: '0'
55
+ - !ruby/object:Gem::Dependency
56
+ name: dogapi
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - ">="
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
62
+ type: :runtime
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - ">="
67
+ - !ruby/object:Gem::Version
68
+ version: '0'
69
+ - !ruby/object:Gem::Dependency
70
+ name: slack-notifier
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - ">="
74
+ - !ruby/object:Gem::Version
75
+ version: '0'
76
+ type: :runtime
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - ">="
81
+ - !ruby/object:Gem::Version
82
+ version: '0'
83
+ - !ruby/object:Gem::Dependency
84
+ name: tablelize
85
+ requirement: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - ">="
88
+ - !ruby/object:Gem::Version
89
+ version: '0'
90
+ type: :runtime
91
+ prerelease: false
92
+ version_requirements: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - ">="
95
+ - !ruby/object:Gem::Version
96
+ version: '0'
97
+ - !ruby/object:Gem::Dependency
98
+ name: rake
99
+ requirement: !ruby/object:Gem::Requirement
100
+ requirements:
101
+ - - ">="
102
+ - !ruby/object:Gem::Version
103
+ version: '0'
104
+ type: :development
105
+ prerelease: false
106
+ version_requirements: !ruby/object:Gem::Requirement
107
+ requirements:
108
+ - - ">="
109
+ - !ruby/object:Gem::Version
110
+ version: '0'
111
+ description: This tool backups different data sources to S3.
112
+ email:
113
+ - spt@schibsted.com
114
+ executables:
115
+ - backups
116
+ extensions: []
117
+ extra_rdoc_files: []
118
+ files:
119
+ - ".gitignore"
120
+ - ".travis.yml"
121
+ - Gemfile
122
+ - LICENSE
123
+ - README.md
124
+ - Rakefile
125
+ - backups-cli.gemspec
126
+ - bin/backups
127
+ - lib/backups.rb
128
+ - lib/backups/adapter/mysql.rb
129
+ - lib/backups/base.rb
130
+ - lib/backups/cli.rb
131
+ - lib/backups/crontab.rb
132
+ - lib/backups/driver/mysql.rb
133
+ - lib/backups/events.rb
134
+ - lib/backups/ext/fixnum.rb
135
+ - lib/backups/ext/hash.rb
136
+ - lib/backups/ext/nil_class.rb
137
+ - lib/backups/ext/ordered_hash.rb
138
+ - lib/backups/ext/string.rb
139
+ - lib/backups/listener.rb
140
+ - lib/backups/listeners/notify/datadog.rb
141
+ - lib/backups/listeners/notify/slack.rb
142
+ - lib/backups/loader.rb
143
+ - lib/backups/logger.rb
144
+ - lib/backups/runner.rb
145
+ - lib/backups/stats/mysql.rb
146
+ - lib/backups/system.rb
147
+ - lib/backups/verify/mysql.rb
148
+ - lib/backups/version.rb
149
+ homepage: https://github.com/schibsted/backups-cli
150
+ licenses:
151
+ - MIT
152
+ metadata: {}
153
+ post_install_message:
154
+ rdoc_options: []
155
+ require_paths:
156
+ - lib
157
+ required_ruby_version: !ruby/object:Gem::Requirement
158
+ requirements:
159
+ - - ">="
160
+ - !ruby/object:Gem::Version
161
+ version: '0'
162
+ required_rubygems_version: !ruby/object:Gem::Requirement
163
+ requirements:
164
+ - - ">="
165
+ - !ruby/object:Gem::Version
166
+ version: '0'
167
+ requirements: []
168
+ rubyforge_project:
169
+ rubygems_version: 2.5.2.1
170
+ signing_key:
171
+ specification_version: 4
172
+ summary: This tool backups different data sources to S3
173
+ test_files: []