snapsync 0.3.5 → 0.3.6

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: c809fd16c3f578d58d3af399333f68781bf53ae4
4
- data.tar.gz: 4822cfbeb7c7dc00cff374a07dbf55d17a328719
3
+ metadata.gz: 95ec11fc2543f694b0067aec51d92e8a377db86c
4
+ data.tar.gz: 68c883971fa9a51ada600b7bf5d581ac7989374a
5
5
  SHA512:
6
- metadata.gz: 84c69e553af59dadd780a38905d36751a90854f865026426e0f433aeddd5adca40dfa66851f988a7b3a3c1ae2eede39404242a66d7c3b399ec3a1065aa2f098c
7
- data.tar.gz: 7e8c97f3edaa6c0162e6db011a17f0b866c94a2e55b0b06fadbf5ac75bef1aa5a16df39fb6a6a222f590797f72863c3dbdc46d6040d0d83e73fb2e04066ad1ca
6
+ metadata.gz: 42b5c23eea493a255c85571dbb6427ddc2e4f6cfb24c6c3c1549bb7d2bd2dcf5a8b9a6a65d01f73aae48e5a6fdb62ffb300d5e3e9f6a0848ebe82596b83a9983
7
+ data.tar.gz: 233573b3be382d2d9ab5cc5e6e467bbe45cf54e6930c3fffcef438fdbe24808b4bb87a9a46a631a35b8c169d24e99c3d50132ee8578c5750bea4eafb6046ca0e
@@ -17,20 +17,24 @@ module Snapsync
17
17
  end
18
18
  end
19
19
 
20
+ class UnexpectedBtrfsOutput < Error
21
+ end
22
+
23
+ # @api private
24
+ #
25
+ # A IO.popen-like API to btrfs subcommands
20
26
  def self.popen(*args, mode: 'r', raise_on_error: true, **options)
21
27
  err_r, err_w = IO.pipe
22
28
 
23
29
  block_error, block_result = nil
24
30
  IO.popen(['btrfs', *args, err: err_w, **options], mode) do |io|
25
31
  err_w.close
26
- if block_given?
27
- begin
28
- block_result = yield(io)
29
- rescue Error
30
- raise
31
- rescue Exception => block_error
32
- end
33
- else io.read
32
+
33
+ begin
34
+ block_result = yield(io)
35
+ rescue Error
36
+ raise
37
+ rescue Exception => block_error
34
38
  end
35
39
  end
36
40
 
@@ -56,8 +60,39 @@ module Snapsync
56
60
 
57
61
  def self.run(*args, **options)
58
62
  popen(*args, **options) do |io|
59
- io.read
63
+ io.read.encode('utf-8', undef: :replace, invalid: :replace)
60
64
  end
61
65
  end
66
+
67
+ # Facade for finding the generation of a subvolume using 'btrfs show'
68
+ #
69
+ # @param [Pathname] path the subvolume path
70
+ # @return [Integer] the subvolume's generation
71
+ def self.generation_of(path)
72
+ info = Btrfs.run('subvolume', 'show', path.to_s)
73
+ if info =~ /Generation[^:]*:\s+(\d+)/
74
+ Integer($1)
75
+ else
76
+ raise UnexpectedBtrfsOutput, "unexpected output for 'btrfs subvolume show', expected #{info} to contain a Generation: line"
77
+ end
78
+ end
79
+
80
+ # Facade for 'btrfs subvolume find-new'
81
+ #
82
+ # It computes what changed between a reference generation of a
83
+ # subvolume, and that subvolume's current state
84
+ #
85
+ # @param [String] subvolume_dir the subvolume target of find-new
86
+ # @param [Integer] last_gen the reference generation
87
+ #
88
+ # @overload find_new(subvolume_dir, last_gen)
89
+ # @yieldparam [String] a line of the find-new output
90
+ #
91
+ # @overload find_new(subvolume_dir, last_gen)
92
+ # @return [#each] an enumeration of the lines of the find-new output
93
+ def self.find_new(subvolume_dir, last_gen, &block)
94
+ run('subvolume', 'find-new', subvolume_dir.to_s, last_gen.to_s).
95
+ each_line(&block)
96
+ end
62
97
  end
63
98
  end
@@ -84,7 +84,7 @@ module Snapsync
84
84
 
85
85
  if copy_snapshot(target_snapshot_dir, src, parent: parent)
86
86
  partial_marker_path.unlink
87
- Btrfs.popen("filesystem", "sync", target_snapshot_dir.to_s)
87
+ Btrfs.run("filesystem", "sync", target_snapshot_dir.to_s)
88
88
  Snapsync.info "Successfully synchronized #{src.snapshot_dir}"
89
89
  true
90
90
  end
@@ -172,7 +172,7 @@ module Snapsync
172
172
  return if dry_run
173
173
 
174
174
  begin
175
- Btrfs.popen("subvolume", "delete", '--commit-each', s.subvolume_dir.to_s)
175
+ Btrfs.run("subvolume", "delete", '--commit-each', s.subvolume_dir.to_s)
176
176
  rescue Btrfs::Error
177
177
  Snapsync.warn "failed to remove snapshot at #{s.subvolume_dir}, keeping the rest of the snapshot"
178
178
  return
@@ -180,7 +180,7 @@ module Snapsync
180
180
 
181
181
  Snapsync.info "Flushing data to disk"
182
182
  begin
183
- Btrfs.popen("subvolume", "sync", self.dir.to_s)
183
+ Btrfs.run("subvolume", "sync", self.dir.to_s)
184
184
  rescue Btrfs::Error
185
185
  end
186
186
 
@@ -77,21 +77,34 @@ module Snapsync
77
77
  #
78
78
  # This is an estimate of the size required to send this snapshot using
79
79
  # the given snapshot as parent
80
+ #
81
+ # @param [Snapshot] a reference snapshot, which would be used as parent
82
+ # in the 'send' operation
83
+ # @return [Integer] the size in bytes of the difference between the
84
+ # given snapshot and the current subvolume's state
80
85
  def size_diff_from(snapshot)
81
- info = Btrfs.run('subvolume', 'show', snapshot.subvolume_dir.to_s)
82
- info =~ /Generation[^:]*:\s+(\d+)/
83
- size_diff_from_gen(Integer($1))
86
+ snapshot_gen = Btrfs.generation_of(snapshot.subvolume_dir)
87
+ size_diff_from_gen(snapshot_gen)
84
88
  end
85
89
 
86
- # Compute the size of the snapshot
90
+ # Compute an estimate of the size of sending the whole subvolume
91
+ #
92
+ # @return [Integer] size in bytes
87
93
  def size
88
94
  size_diff_from_gen(0)
89
95
  end
90
96
 
97
+ # @api private
98
+ #
99
+ # Compute the size of the 'diff' between a generation and the
100
+ # subvolume's current state
101
+ #
102
+ # @param [Integer] gen the reference generation (the 'from' in the diff)
103
+ # @return [Integer] size in bytes
104
+ # @see size_diff_from size
91
105
  def size_diff_from_gen(gen)
92
- new = Btrfs.run('subvolume', 'find-new', subvolume_dir.to_s, gen.to_s)
93
- new.split("\n").inject(0) do |size, line|
94
- if line.strip =~ /len (\d+)/
106
+ Btrfs.find_new(subvolume_dir, gen).inject(0) do |size, line|
107
+ if line =~ /len (\d+)/
95
108
  size + Integer($1)
96
109
  else size
97
110
  end
@@ -38,9 +38,9 @@ module Snapsync
38
38
  Snapsync.info "Removing partial snapshot at #{path}"
39
39
  begin
40
40
  if (path + "snapshot").exist?
41
- Btrfs.popen("subvolume", "delete", (path + "snapshot").to_s)
41
+ Btrfs.run("subvolume", "delete", (path + "snapshot").to_s)
42
42
  elsif (path + "snapshot.partial").exist?
43
- Btrfs.popen("subvolume", "delete", (path + "snapshot.partial").to_s)
43
+ Btrfs.run("subvolume", "delete", (path + "snapshot.partial").to_s)
44
44
  end
45
45
  rescue Btrfs::Error => e
46
46
  Snapsync.warn "failed to remove snapshot at #{path}, keeping the rest of the snapshot"
@@ -51,7 +51,7 @@ module Snapsync
51
51
  path.rmtree
52
52
  Snapsync.info "Flushing data to disk"
53
53
  begin
54
- Btrfs.popen("subvolume", "sync", path.to_s)
54
+ Btrfs.run("subvolume", "sync", path.to_s)
55
55
  rescue Btrfs::Error
56
56
  end
57
57
  end
@@ -38,25 +38,25 @@ module Snapsync
38
38
  # end
39
39
  #
40
40
  module SelfTest
41
- if defined? FlexMock
42
- include FlexMock::ArgumentTypes
43
- include FlexMock::MockContainer
44
- end
45
-
46
41
  def setup
42
+ @tempdirs = Array.new
43
+ super
47
44
  # Setup code for all the tests
48
45
  end
49
46
 
50
47
  def teardown
51
- if defined? FlexMock
52
- flexmock_teardown
48
+ @tempdirs.each do |dir|
49
+ FileUtils.rm_rf dir
53
50
  end
54
51
  super
55
52
  # Teardown code for all the tests
56
53
  end
54
+
55
+ def make_tmpdir
56
+ @tempdirs << Dir.mktmpdir
57
+ end
57
58
  end
58
59
  end
59
60
 
60
61
  Minitest::Test.include Snapsync::SelfTest
61
62
 
62
-
@@ -1,3 +1,3 @@
1
1
  module Snapsync
2
- VERSION = "0.3.5"
2
+ VERSION = "0.3.6"
3
3
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: snapsync
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.3.5
4
+ version: 0.3.6
5
5
  platform: ruby
6
6
  authors:
7
7
  - Sylvain Joyeux
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2016-07-04 00:00:00.000000000 Z
11
+ date: 2017-04-14 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: logging
@@ -237,3 +237,4 @@ signing_key:
237
237
  specification_version: 4
238
238
  summary: tool to automate backing up snapper snapshots to other medias
239
239
  test_files: []
240
+ has_rdoc: