snapsync 0.1.8 → 0.2.0

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: ea592c2458f120d101b112422dbeb0dc5966dcb7
4
- data.tar.gz: d1a5181d899385dfca5174b28d8d6c67b6dd2751
3
+ metadata.gz: 75228e89d473612d045f56e995ddc5492506a119
4
+ data.tar.gz: 476af2e900213d61aa7fd9c5d606f33ca33df4d8
5
5
  SHA512:
6
- metadata.gz: da792693feec9b09f8e41105f36c2a5d3a72af5f05d63f434e0073be469c3b7852a1b836b39259eec4187529e61f9a108e155fb2c852cc2f07ace2424ef6ea24
7
- data.tar.gz: c6daee2a0394602db608b73b2b1b98dce9fcc818842fb15f657a5723676076eceeb25f2557fea14edea1cd06ba24b47cf2db71630fad01acca24486bf8c9a425
6
+ metadata.gz: 2aafcd762a596944cf0d1997b92e2e3a74ff9daa19e706529ce6f26e4d697202c7223b0e80075cc1653a8ed0322173321bee62abf29fd573bf251cf579071eca
7
+ data.tar.gz: e3e0b871f358c5a76cfcaa09a5d3d88b8614dbcb623fbc91fa04f4d8232ce4fd8bf76539153c4ce3b319d699184f690efaddfc4dfa160220615b488676601975
data/Gemfile CHANGED
@@ -2,6 +2,3 @@ source 'https://rubygems.org'
2
2
 
3
3
  # Specify your gem's dependencies in snapsync.gemspec
4
4
  gemspec
5
-
6
- gem 'pry'
7
- gem 'pry-byebug'
@@ -1,3 +1,7 @@
1
1
  #! /usr/bin/env ruby
2
2
  require 'snapsync/cli'
3
- Snapsync::CLI.start(ARGV)
3
+ begin
4
+ Snapsync::CLI.start(ARGV)
5
+ rescue Interrupt
6
+ Snapsync.info "Interrupted by user"
7
+ end
@@ -8,6 +8,7 @@ require 'concurrent'
8
8
 
9
9
  require "snapsync/version"
10
10
  require "snapsync/exceptions"
11
+ require 'snapsync/btrfs'
11
12
  require "snapsync/snapper_config"
12
13
  require "snapsync/snapshot"
13
14
  require "snapsync/local_target"
@@ -0,0 +1,49 @@
1
+ module Snapsync
2
+ module Btrfs
3
+ class Error < RuntimeError
4
+ attr_reader :error_lines
5
+ def initialize(error_lines = Array.new)
6
+ @error_lines = error_lines
7
+ end
8
+
9
+ def pretty_print(pp)
10
+ pp.text message
11
+ pp.nest(2) do
12
+ error_lines.each do |l|
13
+ pp.breakable
14
+ pp.text l.chomp
15
+ end
16
+ end
17
+ end
18
+ end
19
+
20
+ def self.popen(*args, mode: 'r', raise_on_error: true, **options)
21
+ err_r, err_w = IO.pipe
22
+ result = IO.popen(['btrfs', *args, err: err_w, **options], mode) do |io|
23
+ err_w.close
24
+ yield(io)
25
+ end
26
+
27
+ if $?.success?
28
+ result
29
+ elsif raise_on_error
30
+ raise Error.new, "btrfs failed"
31
+ end
32
+
33
+ rescue Error => e
34
+ prefix = args.join(" ")
35
+ lines = err_r.readlines.map do |line|
36
+ "#{prefix}: #{line.chomp}"
37
+ end
38
+ raise Error.new(e.error_lines + lines), e.message, e.backtrace
39
+
40
+ ensure err_r.close
41
+ end
42
+
43
+ def self.run(*args, **options)
44
+ popen(*args, **options) do |io|
45
+ io.read
46
+ end
47
+ end
48
+ end
49
+ end
@@ -111,54 +111,33 @@ module Snapsync
111
111
 
112
112
  start = Time.now
113
113
  bytes_transferred = nil
114
- receive_status, send_status = nil
115
- err_send_pipe_r, err_send_pipe_w = IO.pipe
116
- err_receive_pipe_r, err_receive_pipe_w = IO.pipe
117
- IO.popen(['btrfs', 'send', *parent_opt, src.subvolume_dir.to_s, err: err_send_pipe_w]) do |send_io|
118
- err_send_pipe_w.close
119
- IO.popen(['btrfs', 'receive', target_snapshot_dir.to_s, err: err_receive_pipe_w, out: '/dev/null'], 'w') do |receive_io|
120
- err_receive_pipe_w.close
121
- receive_io.sync = true
122
- bytes_transferred = copy_stream(send_io, receive_io, estimated_size: estimated_size)
123
- end
124
- receive_status = $?
125
- end
126
- send_status = $?
127
-
128
- success = (receive_status.success? && send_status.success?)
129
- if !send_status.success?
130
- Snapsync.warn "btrfs send reported an error"
131
- err_send_pipe_w.readlines.each do |line|
132
- Snapsync.warn " #{line.chomp}"
133
- end
134
- end
135
-
136
- if !receive_status.success?
137
- Snapsync.warn "btrfs receive reported an error"
138
- err_receive_pipe_w.readlines.each do |line|
139
- Snapsync.warn " #{line.chomp}"
114
+ bytes_transferred =
115
+ Btrfs.popen('send', *parent_opt, src.subvolume_dir.to_s) do |send_io|
116
+ Btrfs.popen('receive', target_snapshot_dir.to_s, mode: 'w', out: '/dev/null') do |receive_io|
117
+ receive_io.sync = true
118
+ copy_stream(send_io, receive_io, estimated_size: estimated_size)
119
+ end
140
120
  end
141
- end
142
121
 
143
- if success
144
- Snapsync.info "Flushing data to disk"
145
- IO.popen(["btrfs", "filesystem", "sync", target_snapshot_dir.to_s, err: '/dev/null']).read
146
- duration = Time.now - start
147
- rate = bytes_transferred / duration
148
- Snapsync.info "Transferred #{human_readable_size(bytes_transferred)} in #{human_readable_time(duration)} (#{human_readable_size(rate)}/s)"
149
- Snapsync.info "Successfully synchronized #{src.snapshot_dir}"
150
- true
151
- end
152
-
153
- ensure
154
- if !success
155
- Snapsync.warn "Failed to synchronize #{src.snapshot_dir}, deleting target directory"
156
- subvolume_dir = target_snapshot_dir + "snapshot"
157
- if subvolume_dir.directory?
158
- IO.popen(["btrfs", "subvolume", "delete", subvolume_dir.to_s, err: '/dev/null']).read
159
- end
122
+ Snapsync.info "Flushing data to disk"
123
+ Btrfs.run("filesystem", "sync", target_snapshot_dir.to_s)
124
+ duration = Time.now - start
125
+ rate = bytes_transferred / duration
126
+ Snapsync.info "Transferred #{human_readable_size(bytes_transferred)} in #{human_readable_time(duration)} (#{human_readable_size(rate)}/s)"
127
+ Snapsync.info "Successfully synchronized #{src.snapshot_dir}"
128
+ true
129
+
130
+ rescue Exception => e
131
+ Snapsync.warn "Failed to synchronize #{src.snapshot_dir}, deleting target directory"
132
+ subvolume_dir = target_snapshot_dir + "snapshot"
133
+ if subvolume_dir.directory?
134
+ Btrfs.run("subvolume", "delete", subvolume_dir.to_s)
135
+ end
136
+ if target_snapshot_dir.directory?
160
137
  target_snapshot_dir.rmtree
161
138
  end
139
+
140
+ raise
162
141
  end
163
142
 
164
143
  def sync
@@ -78,7 +78,7 @@ module Snapsync
78
78
  # This is an estimate of the size required to send this snapshot using
79
79
  # the given snapshot as parent
80
80
  def size_diff_from(snapshot)
81
- info = IO.popen(['btrfs', 'subvolume', 'show', snapshot.subvolume_dir.to_s, err: '/dev/null']).read
81
+ info = Btrfs.run('subvolume', 'show', snapshot.subvolume_dir.to_s)
82
82
  info =~ /Generation[^:]*:\s+(\d+)/
83
83
  size_diff_from_gen(Integer($1))
84
84
  end
@@ -89,7 +89,7 @@ module Snapsync
89
89
  end
90
90
 
91
91
  def size_diff_from_gen(gen)
92
- new = IO.popen(['btrfs', 'subvolume', 'find-new', subvolume_dir.to_s, gen.to_s, err: '/dev/null']).read
92
+ new = Btrfs.run('subvolume', 'find-new', subvolume_dir.to_s, gen.to_s)
93
93
  new.split("\n").inject(0) do |size, line|
94
94
  if line.strip =~ /len (\d+)/
95
95
  size + Integer($1)
@@ -53,8 +53,17 @@ module Snapsync
53
53
  end
54
54
  begin
55
55
  Sync.new(config, target, autoclean: autoclean?).run
56
+ rescue Interrupt
57
+ raise
56
58
  rescue Exception => e
57
59
  Snapsync.warn "failed to synchronization #{config.name} on #{target.dir}"
60
+ PP.pp(e, buffer = String.new)
61
+ buffer.each_line do |line|
62
+ Snapsync.warn " #{line}"
63
+ end
64
+ e.backtrace.each do |line|
65
+ Snapsync.debug " #{line}"
66
+ end
58
67
  end
59
68
  end
60
69
  end
@@ -1,3 +1,3 @@
1
1
  module Snapsync
2
- VERSION = "0.1.8"
2
+ VERSION = "0.2.0"
3
3
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: snapsync
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.8
4
+ version: 0.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Sylvain Joyeux
@@ -177,6 +177,7 @@ files:
177
177
  - install.sh
178
178
  - lib/snapsync.rb
179
179
  - lib/snapsync/auto_sync.rb
180
+ - lib/snapsync/btrfs.rb
180
181
  - lib/snapsync/cleanup.rb
181
182
  - lib/snapsync/cli.rb
182
183
  - lib/snapsync/default_sync_policy.rb