cknife 0.1.6 → 0.1.7
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.
- checksums.yaml +4 -4
- data/README.md +81 -4
- data/VERSION +1 -1
- data/bin/cknifemysql +5 -0
- data/cknife.gemspec +7 -4
- data/lib/cknife/cknife_mysql.rb +83 -0
- data/lib/cknife/command_line.rb +62 -0
- metadata +6 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 10d313111e83364d913d12d981ccbca713a6d36e
|
4
|
+
data.tar.gz: def05bdb2b133e4d94660097a0b7a9661be2102c
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 01a7497e314bcefcdd892afa20fefcf320f48713b561c9ff856e52d983b00c109fe8a40eff9e72d2a3bcc3e625dd10bab95ed9dd6cf91cf059b583a23b2c19d7
|
7
|
+
data.tar.gz: ba94d943c666da16b953e8f2db2614d7f9670fcdb40166d314e127761f17d018b65d10707a696f73ea6c0c1bc26cf1547ec6d3ca9c9b8507e9ce3d11af592ad5
|
data/README.md
CHANGED
@@ -194,9 +194,13 @@ switched to DNS Simple and don't use this much anymore.
|
|
194
194
|
cknifezerigo help [TASK] # Describe available tasks or one specific task
|
195
195
|
cknifezerigo list # List available host names.
|
196
196
|
|
197
|
-
#
|
197
|
+
# PostgreSQL Backups
|
198
198
|
|
199
|
-
This
|
199
|
+
This is a wrapper around the PostgreSQL backup and restore command
|
200
|
+
line utilities.
|
201
|
+
|
202
|
+
It requires the following Rails-style configuration in the
|
203
|
+
configuration file:
|
200
204
|
|
201
205
|
pg:
|
202
206
|
host: localhost
|
@@ -204,8 +208,8 @@ This requires the following setup in the configuration:
|
|
204
208
|
username: dbuser
|
205
209
|
password: dbpassword
|
206
210
|
|
207
|
-
|
208
|
-
|
211
|
+
Then you can capture a snapshot of your database. You can also restore
|
212
|
+
it using this tool.
|
209
213
|
|
210
214
|
> bundle exec cknifepg help
|
211
215
|
Tasks:
|
@@ -215,6 +219,51 @@ cknife config file) and you can capture a snapshot of your database.
|
|
215
219
|
cknifepg restore # Restore a file. Use the one with the most recent mtime by default. Searches for db*.dump files in the CWD.
|
216
220
|
cknifepg sessions # List active sessions in this database and provide a string suitable for giving to kill for stopping those sessions.
|
217
221
|
|
222
|
+
This generates and deletes a `.pgpass` file before and after the
|
223
|
+
command line session. Be aware that if this process is interrupted,
|
224
|
+
the `.pgpass` file may be left on disk in the CWD.
|
225
|
+
|
226
|
+
# MySQL Backups
|
227
|
+
|
228
|
+
Like pg, this requires a similar setup in the configuration:
|
229
|
+
|
230
|
+
mysql:
|
231
|
+
host: localhost
|
232
|
+
database: dbname
|
233
|
+
username: dbuser
|
234
|
+
password: dbpassword
|
235
|
+
|
236
|
+
Then you can capture a snapshot of your database.
|
237
|
+
|
238
|
+
> bundle exec cknifemysql help
|
239
|
+
Tasks:
|
240
|
+
cknifemysql capture # Capture a dump of the database to db(current timestamp).sql.
|
241
|
+
cknifemysql help [TASK] # Describe available tasks or one specific task
|
242
|
+
cknifemysql restore # Restore a file. Use the one with the most recent mtime by default. Searches for db*.sql files in the CWD.
|
243
|
+
|
244
|
+
Sample output:
|
245
|
+
|
246
|
+
> bundle exec cknifemysql capture
|
247
|
+
mysqldump --defaults-file=my.cnf -h localhost -P 3306 -u dbuser dbname --add-drop-database --result-file=db20150617125335.sql
|
248
|
+
Captured db20150617125335.sql.
|
249
|
+
|
250
|
+
And the accompanying restore, were you to run it immediately afterwards:
|
251
|
+
|
252
|
+
> bundle exec cknifemysql restore
|
253
|
+
Restore db20150617125335.sql? y
|
254
|
+
Doing restore...
|
255
|
+
mysql --defaults-file=my.cnf -h localhost -P 3306 -u dbuser dbname
|
256
|
+
source db20150617125335.sql;
|
257
|
+
Restored db20150617125335.sql
|
258
|
+
|
259
|
+
**Important:** As you can see, a my.cnf is generated and your password
|
260
|
+
stored in there. That file is removed when the command is done
|
261
|
+
executing. This keeps your password off of the command line and
|
262
|
+
hidden from certain `top` or `ps` invocations by other users who may
|
263
|
+
be on the same machine. This rational is taken from the PostgreSQL
|
264
|
+
PGPASSFILE documentation. If this command error's-out, you'll be
|
265
|
+
warned to remove this file yourself for security purposes.
|
266
|
+
|
218
267
|
# Dub
|
219
268
|
|
220
269
|
Like du, but sorts your output by size. This helps you determine
|
@@ -231,6 +280,34 @@ Options:
|
|
231
280
|
|
232
281
|
-c Enable colorized output.
|
233
282
|
|
283
|
+
# A typical cron script for capturing PostgreSQL backups and uploading them to S3
|
284
|
+
|
285
|
+
#!/bin/bash
|
286
|
+
|
287
|
+
source "$HOME/.rvm/scripts/rvm";
|
288
|
+
|
289
|
+
rvm use 2.0.0;
|
290
|
+
|
291
|
+
cd path/to/backups/dir/with/cknife/config;
|
292
|
+
|
293
|
+
cknifepg capture;
|
294
|
+
|
295
|
+
cknifeaws upsync backups-bucket . --noprompt --backups-retain --glob="db*.dump";
|
296
|
+
|
297
|
+
Which can be used with the following sample [crontab](http://en.wikipedia.org/wiki/Cron#Examples),
|
298
|
+
executing once a day at 2am:
|
299
|
+
|
300
|
+
# * * * * * command to execute
|
301
|
+
# │ │ │ │ │
|
302
|
+
# │ │ │ │ │
|
303
|
+
# │ │ │ │ └───── day of week (0 - 6) (0 to 6 are Sunday to Saturday, or use names; 7 is Sunday, the same as 0)
|
304
|
+
# │ │ │ └────────── month (1 - 12)
|
305
|
+
# │ │ └─────────────── day of month (1 - 31)
|
306
|
+
# │ └──────────────────── hour (0 - 23)
|
307
|
+
# └───────────────────────── min (0 - 59)
|
308
|
+
|
309
|
+
0 2 * * * path/to/script > /dev/null
|
310
|
+
|
234
311
|
|
235
312
|
# Contributing
|
236
313
|
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.1.
|
1
|
+
0.1.7
|
data/bin/cknifemysql
ADDED
data/cknife.gemspec
CHANGED
@@ -2,19 +2,19 @@
|
|
2
2
|
# DO NOT EDIT THIS FILE DIRECTLY
|
3
3
|
# Instead, edit Jeweler::Tasks in Rakefile, and run 'rake gemspec'
|
4
4
|
# -*- encoding: utf-8 -*-
|
5
|
-
# stub: cknife 0.1.
|
5
|
+
# stub: cknife 0.1.7 ruby lib
|
6
6
|
|
7
7
|
Gem::Specification.new do |s|
|
8
8
|
s.name = "cknife"
|
9
|
-
s.version = "0.1.
|
9
|
+
s.version = "0.1.7"
|
10
10
|
|
11
11
|
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
12
12
|
s.require_paths = ["lib"]
|
13
13
|
s.authors = ["Mike De La Loza"]
|
14
|
-
s.date = "2015-06-
|
14
|
+
s.date = "2015-06-17"
|
15
15
|
s.description = "Cali Army Knife, a collection of command line tools, especially for popular API services."
|
16
16
|
s.email = "mikedll@mikedll.com"
|
17
|
-
s.executables = ["cknifeaws", "cknifedub", "cknifemail", "cknifenowtimestamp", "cknifepg", "cknifewcdir", "cknifezerigo"]
|
17
|
+
s.executables = ["cknifeaws", "cknifedub", "cknifemail", "cknifemysql", "cknifenowtimestamp", "cknifepg", "cknifewcdir", "cknifezerigo"]
|
18
18
|
s.extra_rdoc_files = [
|
19
19
|
"LICENSE",
|
20
20
|
"README.md"
|
@@ -31,13 +31,16 @@ Gem::Specification.new do |s|
|
|
31
31
|
"bin/cknifeaws",
|
32
32
|
"bin/cknifedub",
|
33
33
|
"bin/cknifemail",
|
34
|
+
"bin/cknifemysql",
|
34
35
|
"bin/cknifenowtimestamp",
|
35
36
|
"bin/cknifepg",
|
36
37
|
"bin/cknifewcdir",
|
37
38
|
"bin/cknifezerigo",
|
38
39
|
"cknife.gemspec",
|
39
40
|
"cknife.yml.sample",
|
41
|
+
"lib/cknife/cknife_mysql.rb",
|
40
42
|
"lib/cknife/cknife_pg.rb",
|
43
|
+
"lib/cknife/command_line.rb",
|
41
44
|
"lib/cknife/config.rb"
|
42
45
|
]
|
43
46
|
s.homepage = "http://github.com/mikedll/cali-army-knife"
|
@@ -0,0 +1,83 @@
|
|
1
|
+
require 'open3'
|
2
|
+
require 'thor'
|
3
|
+
require 'cknife/config'
|
4
|
+
require 'cknife/command_line'
|
5
|
+
|
6
|
+
module CKnife
|
7
|
+
class CKnifeMysql < Thor
|
8
|
+
|
9
|
+
no_tasks do
|
10
|
+
def config
|
11
|
+
@config ||= Config
|
12
|
+
end
|
13
|
+
|
14
|
+
def conf
|
15
|
+
@conf ||= {
|
16
|
+
:host => config['mysql.host'] || "localhost",
|
17
|
+
:port => config['mysql.port'] || 3306,
|
18
|
+
:database => config['mysql.database'],
|
19
|
+
:username => config['mysql.username'],
|
20
|
+
:password => config['mysql.password']
|
21
|
+
}
|
22
|
+
end
|
23
|
+
|
24
|
+
def connection_options
|
25
|
+
"--defaults-file=#{option_file} -h #{conf[:host]} -P #{conf[:port]} -u #{conf[:username]}"
|
26
|
+
end
|
27
|
+
|
28
|
+
def option_file
|
29
|
+
@option_file ||= "my.cnf"
|
30
|
+
end
|
31
|
+
|
32
|
+
def command_line
|
33
|
+
@command_line ||= CommandLine.new(option_file, "[client]\npassword=\"#{conf[:password]}\"", self)
|
34
|
+
end
|
35
|
+
|
36
|
+
end
|
37
|
+
|
38
|
+
desc "capture", "Capture a dump of the database to db(current timestamp).sql."
|
39
|
+
def capture
|
40
|
+
file_name = "db" + Time.now.strftime("%Y%m%d%H%M%S") + ".sql"
|
41
|
+
|
42
|
+
if File.exists?(file_name)
|
43
|
+
say("File already exists: #{file_name}.", :red)
|
44
|
+
end
|
45
|
+
|
46
|
+
command_line.with_option_file do |c|
|
47
|
+
c.execute "mysqldump #{connection_options} #{conf[:database]} --add-drop-database --result-file=#{file_name}" do
|
48
|
+
say("Captured #{file_name}.")
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
desc "restore", "Restore a file. Use the one with the most recent mtime by default. Searches for db*.sql files in the CWD."
|
54
|
+
method_options :filename => nil
|
55
|
+
def restore
|
56
|
+
to_restore = options[:filename] if options[:filename]
|
57
|
+
if to_restore.nil?
|
58
|
+
files = Dir["db*.sql"]
|
59
|
+
with_mtime = files.map { |f| [f, File.mtime(f)] }
|
60
|
+
with_mtime.sort! { |a,b| a.last <=> b.last }
|
61
|
+
files = with_mtime.map(&:first)
|
62
|
+
to_restore = files.last
|
63
|
+
end
|
64
|
+
|
65
|
+
if to_restore.nil?
|
66
|
+
say("No backups file to restore. None given on the command line and none could be found in the CWD.", :red)
|
67
|
+
return
|
68
|
+
else
|
69
|
+
if !yes?("Restore #{to_restore}?", :green)
|
70
|
+
return
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
74
|
+
command_line.with_option_file do |c|
|
75
|
+
say("Doing restore...")
|
76
|
+
|
77
|
+
c.execute("mysql #{connection_options} #{conf[:database]}", "source #{to_restore};") do
|
78
|
+
say("Restored #{to_restore}")
|
79
|
+
end
|
80
|
+
end
|
81
|
+
end
|
82
|
+
end
|
83
|
+
end
|
@@ -0,0 +1,62 @@
|
|
1
|
+
module CKnife
|
2
|
+
class CommandLine
|
3
|
+
|
4
|
+
attr_accessor :option_file, :option_file_contents, :thor_output
|
5
|
+
|
6
|
+
def initialize(f, s, o)
|
7
|
+
self.option_file = f
|
8
|
+
self.option_file_contents = s
|
9
|
+
self.thor_output = o
|
10
|
+
end
|
11
|
+
|
12
|
+
def execute(cmd, input = nil)
|
13
|
+
return if !@session_ok
|
14
|
+
puts cmd
|
15
|
+
stdin, stdout, stderr, wait_thread = Open3.popen3(cmd)
|
16
|
+
if input
|
17
|
+
puts input
|
18
|
+
stdin.write input
|
19
|
+
stdin.close
|
20
|
+
end
|
21
|
+
output = stdout.read
|
22
|
+
output += stderr.read
|
23
|
+
$stdout.write output
|
24
|
+
stdout.close
|
25
|
+
stderr.close
|
26
|
+
result = wait_thread.value.to_i
|
27
|
+
@session_ok = @session_ok && (result == 0)
|
28
|
+
yield if @session_ok && block_given?
|
29
|
+
output
|
30
|
+
end
|
31
|
+
|
32
|
+
def with_option_file
|
33
|
+
if @session_live
|
34
|
+
return yield
|
35
|
+
end
|
36
|
+
|
37
|
+
@session_live = true
|
38
|
+
@session_ok = true
|
39
|
+
|
40
|
+
if File.exists?(option_file)
|
41
|
+
thor_output.say("This generates a file named #{option_file}, but one is already on disk. Exiting.")
|
42
|
+
return
|
43
|
+
end
|
44
|
+
|
45
|
+
File.open(option_file, "w", 0600) { |f| f.write option_file_contents }
|
46
|
+
|
47
|
+
result = yield self
|
48
|
+
|
49
|
+
FileUtils.rm(option_file)
|
50
|
+
if File.exists?(option_file)
|
51
|
+
thor_output.say("Failed to remove #{option_file} file. Please remove it for security purposes.")
|
52
|
+
end
|
53
|
+
|
54
|
+
thor_output.say
|
55
|
+
thor_output.say("Command failed.", :red) if !@session_ok
|
56
|
+
@session_live = false
|
57
|
+
|
58
|
+
result
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: cknife
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.
|
4
|
+
version: 0.1.7
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Mike De La Loza
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2015-06-
|
11
|
+
date: 2015-06-17 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rest-client
|
@@ -215,6 +215,7 @@ executables:
|
|
215
215
|
- cknifeaws
|
216
216
|
- cknifedub
|
217
217
|
- cknifemail
|
218
|
+
- cknifemysql
|
218
219
|
- cknifenowtimestamp
|
219
220
|
- cknifepg
|
220
221
|
- cknifewcdir
|
@@ -235,13 +236,16 @@ files:
|
|
235
236
|
- bin/cknifeaws
|
236
237
|
- bin/cknifedub
|
237
238
|
- bin/cknifemail
|
239
|
+
- bin/cknifemysql
|
238
240
|
- bin/cknifenowtimestamp
|
239
241
|
- bin/cknifepg
|
240
242
|
- bin/cknifewcdir
|
241
243
|
- bin/cknifezerigo
|
242
244
|
- cknife.gemspec
|
243
245
|
- cknife.yml.sample
|
246
|
+
- lib/cknife/cknife_mysql.rb
|
244
247
|
- lib/cknife/cknife_pg.rb
|
248
|
+
- lib/cknife/command_line.rb
|
245
249
|
- lib/cknife/config.rb
|
246
250
|
homepage: http://github.com/mikedll/cali-army-knife
|
247
251
|
licenses:
|