kamal-backup 0.3.0.beta17 → 0.3.0.beta18

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
  SHA256:
3
- metadata.gz: 88d55c67a4d6276ea516c9d3149ee486c3da3587a438856fa08ba0050f0b99d0
4
- data.tar.gz: '09290fe105b1ef100c9d59f8631426f86ee169977cb5561e4308aec05f3e3eb5'
3
+ metadata.gz: f7b7f6a104e974d738b46ed67b5ece749627d8d33737845f9e9e7ea0e921ce21
4
+ data.tar.gz: e95a651804aa74ec1146989f0db3428e4c8510dc247ef07383e8b0f3d0168f43
5
5
  SHA512:
6
- metadata.gz: 3f0de6a3b23a06e127b860b63d2227ba154272ef6da3e011943f8d82fae445b4f676ae89e8f52931aaf11ea142c73d5fb417e8e360c04912bb42604d2fcf6b76
7
- data.tar.gz: a26fb0fbc1b23f03a0e3316606e07c3df718368e42bb3ac8d082218dc9c1bf4e3ff010695812e3532b1f09bd1c878b979aaff0098b9c04389c07abd097a38354
6
+ metadata.gz: 447bbd9c378d92aef836e0f05cf751ef9b978121b9e3ff5d8675b943441f028aaa082809e9adf462d3380e6035e35dfd52cd74cac68c0ac6fef099632ff89429
7
+ data.tar.gz: 7f414a27f4c452371b9c88fb91ac7aece2bd9771d92ae835997487fa252aeb2f053955cce3a76741be12cd4f6fe31c7c206a2d2ccbdf356a595f34e5d007986b
@@ -503,6 +503,7 @@ module KamalBackup
503
503
  puts deploy_snippet
504
504
  puts
505
505
  puts "The accessory runs scheduled database and file backups with backup.schedule."
506
+ puts "kamal-backup passes RESTIC_PASSWORD to restic through a private temporary password file."
506
507
  puts "For most Rails apps, restore local and drill local can infer the development database, Active Storage path, and tmp state directory."
507
508
  puts "Local restore and drill also require the restic binary on your machine."
508
509
  puts "Create config/kamal-backup.local.yml only if you need to override those local defaults."
@@ -1,6 +1,7 @@
1
1
  require "fileutils"
2
2
  require "json"
3
3
  require "open3"
4
+ require "tempfile"
4
5
  require "time"
5
6
  require_relative "command"
6
7
 
@@ -27,43 +28,49 @@ module KamalBackup
27
28
  end
28
29
 
29
30
  def backup_stream(command, filename:, tags:)
30
- restic_command = CommandSpec.new(
31
- argv: ["restic", "backup"] + host_args + ["--stdin", "--stdin-filename", filename] + tag_args(common_tags + tags),
32
- env: restic_env
33
- )
34
- log("backing up stream as #{filename}")
35
- pipe_commands(command, restic_command, producer_label: "dump", consumer_label: "restic backup")
31
+ with_restic_env do |env|
32
+ restic_command = CommandSpec.new(
33
+ argv: ["restic", "backup"] + host_args + ["--stdin", "--stdin-filename", filename] + tag_args(common_tags + tags),
34
+ env: env
35
+ )
36
+ log("backing up stream as #{filename}")
37
+ pipe_commands(command, restic_command, producer_label: "dump", consumer_label: "restic backup")
38
+ end
36
39
  end
37
40
 
38
41
  def backup_file(path, filename:, tags:)
39
- command = CommandSpec.new(
40
- argv: ["restic", "backup"] + host_args + ["--stdin", "--stdin-filename", filename] + tag_args(common_tags + tags),
41
- env: restic_env
42
- )
43
- log("backing up file content as #{filename}")
42
+ command = nil
44
43
 
45
- File.open(path, "rb") do |file|
46
- output = Command.output
47
- context = output&.command_start(command, redactor: redactor)
48
- Open3.popen3(command.env, *command.argv) do |stdin, stdout, stderr, wait_thread|
49
- stdout_reader = Thread.new { Command.collect_stream(stdout, command_output: output, context: context, stream: :stdout, redactor: redactor) }
50
- stderr_reader = Thread.new { Command.collect_stream(stderr, command_output: output, context: context, stream: :stderr, redactor: redactor) }
51
- copy_error = nil
52
- begin
53
- IO.copy_stream(file, stdin)
54
- rescue Errno::EPIPE => e
55
- copy_error = e
56
- ensure
57
- stdin.close unless stdin.closed?
44
+ with_restic_env do |env|
45
+ command = CommandSpec.new(
46
+ argv: ["restic", "backup"] + host_args + ["--stdin", "--stdin-filename", filename] + tag_args(common_tags + tags),
47
+ env: env
48
+ )
49
+ log("backing up file content as #{filename}")
50
+
51
+ File.open(path, "rb") do |file|
52
+ output = Command.output
53
+ context = output&.command_start(command, redactor: redactor)
54
+ Open3.popen3(command.env, *command.argv) do |stdin, stdout, stderr, wait_thread|
55
+ stdout_reader = Thread.new { Command.collect_stream(stdout, command_output: output, context: context, stream: :stdout, redactor: redactor) }
56
+ stderr_reader = Thread.new { Command.collect_stream(stderr, command_output: output, context: context, stream: :stderr, redactor: redactor) }
57
+ copy_error = nil
58
+ begin
59
+ IO.copy_stream(file, stdin)
60
+ rescue Errno::EPIPE => e
61
+ copy_error = e
62
+ ensure
63
+ stdin.close unless stdin.closed?
64
+ end
65
+ out = stdout_reader.value
66
+ err = stderr_reader.value
67
+ status = wait_thread.value
68
+ output&.command_exit(context, status.exitstatus)
69
+ raise_command_error(command, status, out, err) unless status.success?
70
+ raise_stream_error(command, copy_error, out, err) if copy_error
71
+
72
+ CommandResult.new(stdout: out, stderr: err, status: status.exitstatus)
58
73
  end
59
- out = stdout_reader.value
60
- err = stderr_reader.value
61
- status = wait_thread.value
62
- output&.command_exit(context, status.exitstatus)
63
- raise_command_error(command, status, out, err) unless status.success?
64
- raise_stream_error(command, copy_error, out, err) if copy_error
65
-
66
- CommandResult.new(stdout: out, stderr: err, status: status.exitstatus)
67
74
  end
68
75
  end
69
76
  rescue Errno::ENOENT => e
@@ -153,26 +160,31 @@ module KamalBackup
153
160
  end
154
161
 
155
162
  def pipe_dump_to_command(snapshot, filename, command)
156
- restic_command = CommandSpec.new(argv: ["restic", "dump", snapshot, filename], env: restic_env)
157
- pipe_commands(restic_command, command, producer_label: "restic dump", consumer_label: command.argv.first)
163
+ with_restic_env do |env|
164
+ restic_command = CommandSpec.new(argv: ["restic", "dump", snapshot, filename], env: env)
165
+ pipe_commands(restic_command, command, producer_label: "restic dump", consumer_label: command.argv.first)
166
+ end
158
167
  end
159
168
 
160
169
  def write_dump_to_path(snapshot, filename, target_path)
161
- command = CommandSpec.new(argv: ["restic", "dump", snapshot, filename], env: restic_env)
170
+ command = nil
162
171
  target_path = File.expand_path(target_path)
163
172
  FileUtils.mkdir_p(File.dirname(target_path))
164
173
  temp_path = "#{target_path}.kamal-backup-#{$$}.tmp"
165
174
 
166
- output = Command.output
167
- context = output&.command_start(command, redactor: redactor)
168
- Open3.popen3(command.env, *command.argv) do |stdin, stdout, stderr, wait_thread|
169
- stdin.close
170
- stderr_reader = Thread.new { Command.collect_stream(stderr, command_output: output, context: context, stream: :stderr, redactor: redactor) }
171
- File.open(temp_path, "wb") { |file| IO.copy_stream(stdout, file) }
172
- err = stderr_reader.value
173
- status = wait_thread.value
174
- output&.command_exit(context, status.exitstatus)
175
- raise_command_error(command, status, "", err) unless status.success?
175
+ with_restic_env do |env|
176
+ command = CommandSpec.new(argv: ["restic", "dump", snapshot, filename], env: env)
177
+ output = Command.output
178
+ context = output&.command_start(command, redactor: redactor)
179
+ Open3.popen3(command.env, *command.argv) do |stdin, stdout, stderr, wait_thread|
180
+ stdin.close
181
+ stderr_reader = Thread.new { Command.collect_stream(stderr, command_output: output, context: context, stream: :stderr, redactor: redactor) }
182
+ File.open(temp_path, "wb") { |file| IO.copy_stream(stdout, file) }
183
+ err = stderr_reader.value
184
+ status = wait_thread.value
185
+ output&.command_exit(context, status.exitstatus)
186
+ raise_command_error(command, status, "", err) unless status.success?
187
+ end
176
188
  end
177
189
  File.rename(temp_path, target_path)
178
190
  target_path
@@ -190,11 +202,13 @@ module KamalBackup
190
202
  end
191
203
 
192
204
  def run(args, log_output: true)
193
- Command.capture(
194
- CommandSpec.new(argv: ["restic"] + args, env: restic_env),
195
- redactor: redactor,
196
- log_output: log_output
197
- )
205
+ with_restic_env do |env|
206
+ Command.capture(
207
+ CommandSpec.new(argv: ["restic"] + args, env: env),
208
+ redactor: redactor,
209
+ log_output: log_output
210
+ )
211
+ end
198
212
  end
199
213
 
200
214
  def common_tags
@@ -256,6 +270,25 @@ module KamalBackup
256
270
  end
257
271
  end
258
272
 
273
+ def with_restic_env
274
+ env = restic_env
275
+ password_file = nil
276
+
277
+ if env["RESTIC_PASSWORD_FILE"] || env["RESTIC_PASSWORD_COMMAND"]
278
+ env.delete("RESTIC_PASSWORD")
279
+ elsif env["RESTIC_PASSWORD"]
280
+ password_file = Tempfile.new("kamal-backup-restic-password")
281
+ password_file.write(env.delete("RESTIC_PASSWORD"))
282
+ password_file.flush
283
+ File.chmod(0o600, password_file.path)
284
+ env["RESTIC_PASSWORD_FILE"] = password_file.path
285
+ end
286
+
287
+ yield env
288
+ ensure
289
+ password_file&.close!
290
+ end
291
+
259
292
  def pipe_commands(producer, consumer, producer_label:, consumer_label:)
260
293
  output = Command.output
261
294
  producer_context = output&.command_start(producer, redactor: redactor)
@@ -1,3 +1,3 @@
1
1
  module KamalBackup
2
- VERSION = "0.3.0.beta17"
2
+ VERSION = "0.3.0.beta18"
3
3
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: kamal-backup
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.3.0.beta17
4
+ version: 0.3.0.beta18
5
5
  platform: ruby
6
6
  authors:
7
7
  - crmne