bibliotech 0.2.12 → 0.2.13

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 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