bibliotech 0.2.12 → 0.2.13

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 49e433e80626f0ee2eba944de215c187cb975ace
4
- data.tar.gz: 88b3fea79e358263eb44f0c595df403664cad512
3
+ metadata.gz: a22ff69ff51f9da65c676de7b84084129f2a9499
4
+ data.tar.gz: 414d7b654e61ab08ac35e26c3ecebb161761c4dd
5
5
  SHA512:
6
- metadata.gz: bf161c4d8a01523f787d325decbe783aec812b8c8c8d71d198074e386aecabc566c7835f54c22084fe35f3ece849f7f108fe0282a1cae35a9033565693ae6f04
7
- data.tar.gz: b92108171ef774da7c5679e72c48e00692e0a56d40020c28a38aeeafa4931c3fb7b103deb9a5b367a5aef6e7f913aab3a3106118c551b56c709808f2a28953b7
6
+ metadata.gz: ee5d38a9f9a2a393e9b44d07f15dba07e8285cad1b5a931ad5de2b3ca955e13b15962aec59cc76c699fd1aa494c10460e5ce1a9d26e4ac3e6085fdc6d4cfe8d7
7
+ data.tar.gz: 490311e700290021309b7991116fb11bc79db31be92b53c87144a355c7527ad3139ff41994f3c72a872bec96c7060998d1cb47c91668531795fdfc661564512b
@@ -67,13 +67,13 @@ module BiblioTech
67
67
  end
68
68
 
69
69
  #pull a dump from a remote
70
- def get(options)
71
- @shell.run(commands.fetch(options))
70
+ def get(remote, options)
71
+ @shell.run(commands.fetch(remote, options))
72
72
  end
73
73
 
74
74
  #push a dump to a remote
75
- def send(options)
76
- @shell.run(commands.push(options))
75
+ def send(remote, options)
76
+ @shell.run(commands.push(remote, options))
77
77
  end
78
78
 
79
79
  #clean up the DB dumps
@@ -86,8 +86,8 @@ module BiblioTech
86
86
  pruner(options || {}).most_recent.path
87
87
  end
88
88
 
89
- def remote_cli(remote, command, options)
90
- @shell.run(commands.ssh_cli(remote, command, options))
89
+ def remote_cli(remote, command, *options)
90
+ @shell.run(commands.remote_cli(remote, command, *options))
91
91
  end
92
92
  end
93
93
 
@@ -10,41 +10,52 @@ module BiblioTech
10
10
  @limit = nil if limit == "all"
11
11
  end
12
12
 
13
- def end_time(file_list)
14
- return Time.at(0) if file_list.empty?
15
- file_list.map{|record| record.timestamp}.max
13
+ def freq_seconds
14
+ frequency * 60
15
+ end
16
+
17
+ def range
18
+ freq_seconds / 2
16
19
  end
17
20
 
18
- def compute_start_time(file_list)
21
+ # The earliest possible time to keep a file in.
22
+ def compute_earliest_time(file_list)
19
23
  limit_time = Time.at(0)
20
24
  return limit_time if file_list.empty?
21
25
  unless limit.nil?
22
- limit_time = end_time(file_list) - limit * freq_seconds
26
+ limit_time = latest_time(file_list) - limit * freq_seconds
23
27
  end
24
- [limit_time, file_list.map{|record| record.timestamp}.min - range].max
28
+ [limit_time, file_list.last.timestamp - range].max
25
29
  end
26
30
 
27
- def freq_seconds
28
- frequency * 60
31
+ # The latest possible time to keep a file in.
32
+ def latest_time(file_list)
33
+ return Time.at(0) if file_list.empty?
34
+ file_list.first.timestamp
29
35
  end
30
36
 
31
- def range
32
- freq_seconds / 2
33
- end
37
+ # Working from the latest time backwards, mark the closest file to the
38
+ # appropriate frequencies as keepable
39
+ def mark(original_file_list)
40
+ file_list = original_file_list.sort_by{|record| -record.timestamp.to_i} #sort from newest to oldest
34
41
 
35
- def mark(file_list)
36
- time = end_time(file_list)
37
- start_time = compute_start_time(file_list)
38
- while time > start_time do
39
- closest = file_list.min_by do |record|
40
- (record.timestamp - time).abs
42
+ time = latest_time(file_list)
43
+ earliest_time = compute_earliest_time(file_list)
44
+ while time > earliest_time do
45
+ file_list.delete_if do |record|
46
+ record.timestamp > time
41
47
  end
42
- if (closest.timestamp - time).abs < range
48
+
49
+ break if file_list.empty?
50
+
51
+ closest = file_list.first
52
+
53
+ if (time - closest.timestamp) < freq_seconds
43
54
  closest.keep = true
44
55
  end
45
56
  time -= freq_seconds
46
57
  end
47
- return file_list
58
+ return original_file_list
48
59
  end
49
60
  end
50
61
  end
@@ -3,11 +3,13 @@ require 'bibliotech/builders/file'
3
3
  module BiblioTech
4
4
  module Builders
5
5
  class GzipExpander < FileInput
6
- register(/.*\.gz\z/)
7
- register(/.*\.gzip\z/)
6
+ PATTERNS = [ /.*\.gz\z/, /.*\.gzip\z/ ]
7
+ PATTERNS.each do |pattern|
8
+ register pattern
9
+ end
8
10
 
9
11
  def go(command)
10
- command = cmd("gunzip", file) | command
12
+ command = cmd("gunzip", "-c", file) | command
11
13
  end
12
14
  end
13
15
 
@@ -31,10 +31,14 @@ module BiblioTech
31
31
 
32
32
  def fetch(remote, filename, options = nil)
33
33
  options = config.merge(options || {})
34
- cmd("scp") do |cmd|
34
+ local_path = options.local_file(filename)
35
+ cmd("mkdir") do |cmd|
36
+ cmd.options << "--parents"
37
+ cmd.options << File::dirname(local_path)
38
+ end & cmd("scp") do |cmd|
35
39
  options.optionally{ cmd.options << "-i #{options.id_file(remote)}" }
36
40
  cmd.options << options.remote_file(remote, filename)
37
- cmd.options << options.local_file(filename)
41
+ cmd.options << local_path
38
42
  end
39
43
  end
40
44
 
@@ -5,16 +5,16 @@ module BiblioTech
5
5
  CONFIG_STEPS = {
6
6
  :database_config_file => [ "database_config_file" ] ,
7
7
  :database_config_env => [ "database_config_env" ] ,
8
+ :root_path => [ "path" ] ,
8
9
  :host => [ "host" ] ,
9
10
  :port => [ "port" ] ,
10
11
  :user => [ "user" ] ,
11
12
  :rsa_files => [ "rsa_files" ] ,
12
13
  :ssh_options => [ "ssh_options" ] ,
14
+ :fetch_dir => [ "fetched_dir" ] ,
13
15
  :file => [ "backups" , "file" ] ,
14
16
  :filename => [ "backups" , "filename" ] ,
15
17
  :backup_path => [ "backups" , "dir" ] ,
16
- :root_path => [ "path" ] ,
17
- :fetch_dir => [ "fetched_dir" ] ,
18
18
  :compressor => [ "backups" , "compress" ] ,
19
19
  :prune_schedule => [ "backups" , "keep" ] ,
20
20
  :backup_name => [ "backups" , "prefix" ] ,
@@ -208,6 +208,13 @@ module BiblioTech
208
208
  unless real_frequency % backup_frequency == 0
209
209
  raise "Pruning frequency #{real_frequency}:#{frequency} is not a multiple of backup frequency: #{backup_frequency}:#{local_get(:backup_frequency)}"
210
210
  end
211
+ limit =
212
+ case limit
213
+ when "all"
214
+ nil
215
+ else
216
+ Integer(limit)
217
+ end
211
218
  [real_frequency, limit]
212
219
  end.sort_by do |frequency, limit|
213
220
  frequency
@@ -244,9 +251,9 @@ module BiblioTech
244
251
 
245
252
  def expander
246
253
  if remote.nil?
247
- local_get(:expander)
254
+ local_get(:compressor)
248
255
  else
249
- remote_get(remote, :expander)
256
+ remote_get(remote, :compressor)
250
257
  end
251
258
  end
252
259
 
@@ -74,16 +74,19 @@ module BiblioTech
74
74
  namespace :remote_sync do
75
75
  desc "Pull the latest DB dump from the remote server into our local DB"
76
76
  task :down do
77
- filename = app.remote_cli(remote, "latest")
78
- app.get(remote, filename)
79
- app.import(:backups => { :filename => filename})
77
+ result = app.remote_cli(remote, "latest")
78
+ result.must_succeed!
79
+ filename = result.stdout.chomp
80
+
81
+ app.get(remote, filename).must_succeed!
82
+ app.import(:backups => { :file => app.config.local_file(filename)}).must_succeed!
80
83
  end
81
84
 
82
85
  desc "Push the latest local DB dump to the remote server's DB"
83
86
  task :up do
84
87
  filename = app.latest
85
- app.send(remote, filename)
86
- app.remote_cli(remote, "load", filename)
88
+ app.send(remote, filename).must_succeed!
89
+ app.remote_cli(remote, "load", filename).must_succeed!
87
90
  end
88
91
  end
89
92
  end
@@ -13,11 +13,15 @@ module BiblioTech
13
13
  App.new
14
14
  end
15
15
 
16
+ let :schedule do
17
+ {:daily => 100}
18
+ end
19
+
16
20
  let :pruner do
17
21
  app.pruner({:backups => {
18
22
  :frequency => "daily",
19
23
  :prefix => "testing",
20
- :keep => {:daily => 100},
24
+ :keep => schedule,
21
25
  :dir => "db_backups"
22
26
  }})
23
27
  end
@@ -5,7 +5,7 @@ module BiblioTech::Backups
5
5
  let(:test_jitter){ 0 }
6
6
 
7
7
  let :unfiltered_files do
8
- (0..interval).step(frequency).map do |seconds| #every 15 seconds for 8 hours
8
+ (0..interval).step(frequency).map do |seconds| #e.g. every 15 seconds for 8 hours
9
9
  seconds = seconds - test_jitter/2 + rand(test_jitter)
10
10
  FileRecord.new("", Time.now - seconds)
11
11
  end
@@ -27,12 +27,12 @@ module BiblioTech::Backups
27
27
  end
28
28
 
29
29
  context "when there's more than enough backups" do
30
- let(:interval){ 60*60*12 - 1}
30
+ let(:interval){ 60*60*12 - test_jitter}
31
31
  let(:frequency) { 15 }
32
32
  let(:test_jitter){ 60 }
33
33
 
34
34
  it "should mark 8 files kept" do
35
- expect(kept_files.count).to eql 13
35
+ expect(kept_files.count).to eql 12
36
36
  end
37
37
  end
38
38
  end
@@ -43,7 +43,7 @@ module BiblioTech::Backups
43
43
  end
44
44
 
45
45
  context "when there's just enough backups" do
46
- let(:interval){ 60*60*8 - 1 }
46
+ let(:interval){ 60*60*8 - test_jitter }
47
47
  let(:frequency){ 60*8 }
48
48
  let(:test_jitter){ 60 }
49
49
 
@@ -85,12 +85,12 @@ module BiblioTech::Backups
85
85
  end
86
86
 
87
87
  context "when there are too few backups" do
88
- let(:interval){ 60*60*4 - 1 }
88
+ let(:interval){ 60*60*4 - test_jitter }
89
89
  let(:frequency){ 60*8 }
90
90
  let(:test_jitter){ 60 }
91
91
 
92
- it "should mark 5 files kept" do
93
- expect(kept_files.count).to eql 5
92
+ it "should mark 4 files kept" do
93
+ expect(kept_files.count).to eql 4
94
94
  end
95
95
  end
96
96
 
@@ -18,7 +18,7 @@ module BiblioTech
18
18
  let( :filename ) { "export.sql" }
19
19
  let( :path ) { "/some/path" }
20
20
 
21
- let :base_config_hash do
21
+ let :base_config_hash do
22
22
  { "database_config" => {
23
23
  "adapter" => :mysql,
24
24
  "database" => db_name,
@@ -158,7 +158,7 @@ module BiblioTech
158
158
 
159
159
  it { expect(command).to be_a(Caliph::PipelineChain) }
160
160
  it { expect(first_cmd.executable).to eq('gunzip') }
161
- it { expect(first_cmd.options).to eq(["#{path}/#{filename}.gz"]) }
161
+ it { expect(first_cmd.options).to eq(["-c", "#{path}/#{filename}.gz"]) }
162
162
  end
163
163
  end
164
164
  end
@@ -171,7 +171,7 @@ module BiblioTech
171
171
 
172
172
  it { expect(command).to be_a(Caliph::PipelineChain) }
173
173
  it { expect(first_cmd.executable).to eq('gunzip') }
174
- it { expect(first_cmd.options).to eq(["#{path}/#{filename}.gz"]) }
174
+ it { expect(first_cmd.options).to eq(["-c", "#{path}/#{filename}.gz"]) }
175
175
  end
176
176
  end
177
177
  end
@@ -70,7 +70,7 @@ module BiblioTech
70
70
  end
71
71
 
72
72
  it "should produce a fetch command" do
73
- expect(generator.fetch("staging", "latest.sql.gz").command).to match(/\Ascp.*@.*latest\.sql\.gz.*latest\.sql\.gz\z/)
73
+ expect(generator.fetch("staging", "latest.sql.gz").command).to match(/scp.*@.*latest\.sql\.gz.*latest\.sql\.gz\z/)
74
74
  end
75
75
 
76
76
  it "should produce a push command" do
@@ -144,12 +144,13 @@ module BiblioTech
144
144
  "keep" => {
145
145
  "hourlies" => 24,
146
146
  "daily" => 7,
147
- "weeklies" => 4
147
+ "weeklies" => 4,
148
+ "monthly" => "all"
148
149
  }}}
149
150
  end
150
151
 
151
152
  it "should produce correct schedule" do
152
- expect(schedule_array).to contain_exactly([60, 24], [60*24, 7], [60*24*7, 4])
153
+ expect(schedule_array).to contain_exactly([60, 24], [60*24, 7], [60*24*7, 4], [60*24*30, nil])
153
154
  end
154
155
  end
155
156
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: bibliotech
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.12
4
+ version: 0.2.13
5
5
  platform: ruby
6
6
  authors:
7
7
  - Evan Dorn
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2014-08-21 00:00:00.000000000 Z
12
+ date: 2014-09-04 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: caliph
@@ -31,14 +31,14 @@ dependencies:
31
31
  requirements:
32
32
  - - ~>
33
33
  - !ruby/object:Gem::Version
34
- version: 0.8.0
34
+ version: 0.9.0
35
35
  type: :runtime
36
36
  prerelease: false
37
37
  version_requirements: !ruby/object:Gem::Requirement
38
38
  requirements:
39
39
  - - ~>
40
40
  - !ruby/object:Gem::Version
41
- version: 0.8.0
41
+ version: 0.9.0
42
42
  - !ruby/object:Gem::Dependency
43
43
  name: valise
44
44
  requirement: !ruby/object:Gem::Requirement
@@ -128,7 +128,7 @@ rdoc_options:
128
128
  - --main
129
129
  - doc/README
130
130
  - --title
131
- - bibliotech-0.2.12 Documentation
131
+ - bibliotech-0.2.13 Documentation
132
132
  require_paths:
133
133
  - lib/
134
134
  required_ruby_version: !ruby/object:Gem::Requirement