snapsync 0.1.8 → 0.2.0

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