restic-service 0.2.2 → 0.3.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: 20d2e8bcf01431f060bd3bf7873017742400d672
4
- data.tar.gz: da02e19bdb412eb16fdd109c4af7dc2bc7ae23c6
3
+ metadata.gz: fc0cdefcecb418357241e0acc940dc84572263d8
4
+ data.tar.gz: 9b3bf2bc152405e6fd8d4ffd4e950f8176b34a7f
5
5
  SHA512:
6
- metadata.gz: f772fd3950f54eda022a99db6b46a07f8fb8ee5ffb2095b312f30a6fb85111b1bb0cef9afca36e82d7d60704f8e517cc23daf2c6e12baa340a199b8cd55e1428
7
- data.tar.gz: edb746be5a8aff2b7c18fd90b97aededccc4b82520c5cdddc8dd781ce696542c5a36c96661210131bb4934ddfaff406d9d4ba99307ec9e92c1cb3fe22876225c
6
+ metadata.gz: 58013743c7a6ebf256b6eddc6ade110c43245513fa78242cb151698538307388af6a95e3c36b46fc381d19219780cec4c1c8543d571757429a3f81671083ae00
7
+ data.tar.gz: bd65807a2ca4f8314b39cf4f4c1fd571693c9148bb6f70db19c75d2965526bc0b69a28c4449e468a77b7ddcfd733a26650275a0138553f205cc6f8776a27e69b
@@ -12,6 +12,14 @@ module Restic
12
12
  "https://github.com/restic/restic/releases/download/v#{RESTIC_RELEASE_VERSION}/restic_#{RESTIC_RELEASE_VERSION}_#{platform}.bz2"
13
13
  end
14
14
 
15
+ RCLONE_RELEASE_VERSION = "1.41"
16
+
17
+ def self.rclone_release_url(platform)
18
+ basename = "rclone-v#{RCLONE_RELEASE_VERSION}-#{platform}"
19
+ url = "https://github.com/ncw/rclone/releases/download/v#{RCLONE_RELEASE_VERSION}/#{basename}.zip"
20
+ [basename, url]
21
+ end
22
+
15
23
 
16
24
  def initialize(binary_path)
17
25
  @root = File.dirname(File.dirname(binary_path))
@@ -61,39 +69,72 @@ module Restic
61
69
  reader.close if reader && !reader.closed?
62
70
  end
63
71
 
64
- def update_restic(platform, target_path)
65
- release_url = self.class.restic_release_url(platform)
66
-
67
- release_binary = nil
68
- while !release_binary
69
- response = Net::HTTP.get_response(URI(release_url))
72
+ def download_file(temp_path, url)
73
+ binary = nil
74
+ while !binary
75
+ response = Net::HTTP.get_response(URI(url))
70
76
  case response
71
77
  when Net::HTTPSuccess
72
- release_binary = response.body
78
+ binary = response.body
73
79
  when Net::HTTPRedirection
74
- release_url = response['location']
80
+ url = response['location']
75
81
  else
76
- raise FailedUpdate, "failed to fetch restic at #{release_url}: #{response}"
82
+ raise FailedUpdate, "failed to fetch #{url}: #{response}"
77
83
  end
78
84
  end
79
85
 
86
+ File.open(temp_path, 'w') do |io|
87
+ io.write binary
88
+ end
89
+ end
90
+
91
+ def update_release_if_needed(target_path, temp_path)
92
+ if File.file?(target_path)
93
+ current = File.read(target_path)
94
+ new = File.read(temp_path)
95
+ return false if current == new
96
+ end
97
+
98
+ FileUtils.mv temp_path, target_path
99
+ FileUtils.chmod 0755, target_path
100
+ true
101
+ end
102
+
103
+ def update_restic(platform, target_path)
104
+ release_url = self.class.restic_release_url(platform)
105
+
80
106
  tmpdir = Dir.mktmpdir
81
107
  restic_path = File.join(tmpdir, "restic")
82
- File.open("#{restic_path}.bz2", 'w') do |io|
83
- io.write release_binary
84
- end
108
+ download_file("#{restic_path}.bz2", release_url)
85
109
 
86
110
  if !system("bzip2", "-d", "#{restic_path}.bz2")
87
111
  raise FailedUpdate, "failed to uncompress the restic release file"
88
112
  end
113
+ update_release_if_needed(target_path, restic_path)
114
+
115
+ ensure
116
+ FileUtils.rm_rf tmpdir if tmpdir
117
+ end
118
+
119
+ def update_rclone(platform, target_path)
120
+ basename, release_url = self.class.rclone_release_url(platform)
121
+
122
+ tmpdir = Dir.mktmpdir
123
+ tmppath = File.join(tmpdir, "rclone.zip")
124
+ download_file(tmppath, release_url)
125
+
126
+ if !system("unzip", tmppath, chdir: tmpdir, out: '/dev/null')
127
+ raise FailedUpdate, "failed to uncompress the rclone release file"
128
+ end
89
129
 
130
+ rclone_path = File.join(tmpdir, basename, 'rclone')
90
131
  if File.file?(target_path)
91
132
  current = File.read(target_path)
92
- new = File.read(restic_path)
133
+ new = File.read(rclone_path)
93
134
  return if current == new
94
135
  end
95
136
 
96
- FileUtils.mv restic_path, target_path
137
+ FileUtils.mv rclone_path, target_path
97
138
  FileUtils.chmod 0755, target_path
98
139
  true
99
140
 
@@ -67,6 +67,22 @@ module Restic
67
67
  target.forget
68
68
  end
69
69
  end
70
+
71
+ def auto_update_tool(conf, updater, name, version)
72
+ begin
73
+ path = conf.tool_path(name, only_if_present: false)
74
+ rescue ArgumentError
75
+ puts "cannot auto-update #{name}, provide an explicit path in the 'tools' section of the configuration first"
76
+ return
77
+ end
78
+
79
+ puts "attempting to auto-update #{name}"
80
+ if updater.send("update_#{name}", conf.send("#{name}_platform"), path)
81
+ puts "updated #{name} to version #{version}"
82
+ else
83
+ puts "restic was already up-to-date"
84
+ end
85
+ end
70
86
  end
71
87
 
72
88
  desc 'whereami', 'finds the available backup targets'
@@ -104,25 +120,16 @@ module Restic
104
120
  puts "updating restic-service disabled in configuration"
105
121
  end
106
122
 
107
- update_restic = conf.auto_update_restic?
108
- if update_restic
109
- begin
110
- restic_path = conf.tool_path('restic')
111
- rescue ArgumentError
112
- puts "cannot auto-update restic, provide an explicit path in the 'tools' section of the configuration first"
113
- update_restic = false
114
- end
123
+ if conf.auto_update_restic?
124
+ auto_update_tool(conf, updater, 'restic', AutoUpdate::RESTIC_RELEASE_VERSION)
115
125
  else
116
126
  puts "updating restic disabled in configuration"
117
127
  end
118
128
 
119
- if update_restic
120
- puts "attempting to auto-update restic"
121
- if updater.update_restic(conf.restic_platform, restic_path)
122
- puts "updated restic to version #{AutoUpdate::RESTIC_RELEASE_VERSION}"
123
- else
124
- puts "restic was already up-to-date"
125
- end
129
+ if conf.auto_update_rclone?
130
+ auto_update_tool(conf, updater, 'rclone', AutoUpdate::RCLONE_RELEASE_VERSION)
131
+ else
132
+ puts "updating rclone disabled in configuration"
126
133
  end
127
134
  end
128
135
 
@@ -202,16 +202,17 @@ module Restic
202
202
  # @param [String]
203
203
  # @return [Boolean]
204
204
  def tool_available?(tool_name)
205
- @tools.has_key?(tool_name)
205
+ _, available = @tools[tool_name]
206
+ available
206
207
  end
207
208
 
208
209
  # The full path of a given tool
209
210
  #
210
211
  # @param [String]
211
212
  # @return [Pathname]
212
- def tool_path(tool_name)
213
+ def tool_path(tool_name, only_if_present: true)
213
214
  if tool = @tools[tool_name]
214
- tool
215
+ tool[0] if tool[1] || !only_if_present
215
216
  else
216
217
  raise ArgumentError, "cound not find '#{tool_name}'"
217
218
  end
@@ -229,6 +230,14 @@ module Restic
229
230
  @auto_update_restic
230
231
  end
231
232
 
233
+ def auto_update_rclone?
234
+ @auto_update_rclone
235
+ end
236
+
237
+ def rclone_platform
238
+ @auto_update_rclone
239
+ end
240
+
232
241
  # Add the information stored in a YAML-like hash into this
233
242
  # configuration
234
243
  #
@@ -247,6 +256,8 @@ module Restic
247
256
  @auto_update_restic_service = do_update
248
257
  elsif update_target == 'restic'
249
258
  @auto_update_restic = do_update
259
+ elsif update_target == 'rclone'
260
+ @auto_update_rclone = do_update
250
261
  end
251
262
  end
252
263
 
@@ -268,12 +279,10 @@ module Restic
268
279
  if tool_path.relative?
269
280
  tool_path = find_in_path(tool_path)
270
281
  end
271
- if tool_path && tool_path.file?
272
- @tools[tool_name] = tool_path
273
- else
274
- STDERR.puts "cannot find path to #{tool_name}"
275
- @tools.delete(tool_name)
276
- end
282
+
283
+ exists = tool_path.file?
284
+ STDERR.puts "#{tool_path} does not exist" unless exists
285
+ @tools[tool_name] = [tool_path, exists]
277
286
  end
278
287
  end
279
288
  end
@@ -18,6 +18,7 @@ module Restic
18
18
  super
19
19
  @rclone_path = conf.tool_path('rclone')
20
20
  @src = yaml['src']
21
+ @filter = yaml['filter'] || []
21
22
  @conf_path = conf.conf_path
22
23
  end
23
24
 
@@ -39,6 +40,8 @@ EOCONF
39
40
  system(@rclone_path.to_path,
40
41
  '--transfers', '16',
41
42
  '--config', io.path,
43
+ '--delete-during',
44
+ *@filter.flat_map { |p| ['--filter', p] },
42
45
  *extra_args,
43
46
  'sync', @src, "restic-service:#{@bucket}/#{@path}", in: :close)
44
47
  end
@@ -1,5 +1,5 @@
1
1
  module Restic
2
2
  module Service
3
- VERSION = "0.2.2"
3
+ VERSION = "0.3.0"
4
4
  end
5
5
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: restic-service
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.2
4
+ version: 0.3.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Sylvain Joyeux
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2018-03-16 00:00:00.000000000 Z
11
+ date: 2018-05-10 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: thor