kamal-backup 0.2.0 → 0.2.2
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 +4 -4
- data/lib/kamal_backup/cli.rb +2 -1
- data/lib/kamal_backup/kamal_bridge.rb +52 -4
- data/lib/kamal_backup/restic.rb +19 -5
- data/lib/kamal_backup/version.rb +1 -1
- metadata +1 -1
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 49afc009b695f3cf7f456e1b68b2b744f5adc7138f7ca4d0c84ffb1f0d3b766d
|
|
4
|
+
data.tar.gz: fc0261dc6c744a19e02460f27aab7e8f7555de779ea1fe7827a2fdf077042071
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 39839b0f31f1e5a9bf561e63ee2248330d1857f5f21c2736e1668aed2e226c79e3c6063c6195a6bb09e05c180bfd42a6cd6901271638e3dbba2a36ab8146844f
|
|
7
|
+
data.tar.gz: 3bb459e3ff320cff130ac29c523a09c50b85b3efb98ad977410cdd2db0a53e333fce935f8a92aaa65325b7d421ce36be4ed92c49a6f46d5836184f2a4009e94e
|
data/lib/kamal_backup/cli.rb
CHANGED
|
@@ -6,10 +6,11 @@ module KamalBackup
|
|
|
6
6
|
DEFAULT_CONFIG_FILE = "config/deploy.yml"
|
|
7
7
|
VERSION_LINE_PATTERN = /\A\d+(?:\.\d+)+(?:[-.][A-Za-z0-9]+)*\z/
|
|
8
8
|
|
|
9
|
-
def initialize(redactor:, config_file: nil, destination: nil)
|
|
9
|
+
def initialize(redactor:, config_file: nil, destination: nil, env: ENV)
|
|
10
10
|
@redactor = redactor
|
|
11
11
|
@config_file = config_file
|
|
12
12
|
@destination = destination
|
|
13
|
+
@env = env
|
|
13
14
|
end
|
|
14
15
|
|
|
15
16
|
def accessory_name(preferred: nil)
|
|
@@ -104,16 +105,54 @@ module KamalBackup
|
|
|
104
105
|
def normalize_secret_env(values)
|
|
105
106
|
case values
|
|
106
107
|
when Hash
|
|
107
|
-
values.each_with_object({})
|
|
108
|
+
values.each_with_object({}) do |(key, secret_key), env|
|
|
109
|
+
add_resolved_secret(env, target: key, source: secret_key)
|
|
110
|
+
end
|
|
108
111
|
when Array
|
|
109
|
-
values.each_with_object({})
|
|
112
|
+
values.each_with_object({}) do |entry, env|
|
|
113
|
+
target, source = parse_secret_entry(entry)
|
|
114
|
+
add_resolved_secret(env, target: target, source: source)
|
|
115
|
+
end
|
|
110
116
|
when String, Symbol
|
|
111
|
-
{
|
|
117
|
+
{}.tap do |env|
|
|
118
|
+
target, source = parse_secret_entry(values)
|
|
119
|
+
add_resolved_secret(env, target: target, source: source)
|
|
120
|
+
end
|
|
112
121
|
else
|
|
113
122
|
{}
|
|
114
123
|
end
|
|
115
124
|
end
|
|
116
125
|
|
|
126
|
+
def parse_secret_entry(entry)
|
|
127
|
+
target, source = entry.to_s.split(":", 2)
|
|
128
|
+
[ target, source || target ]
|
|
129
|
+
end
|
|
130
|
+
|
|
131
|
+
def add_resolved_secret(env, target:, source:)
|
|
132
|
+
if value = resolved_secret(source)
|
|
133
|
+
env[target.to_s] = value
|
|
134
|
+
end
|
|
135
|
+
end
|
|
136
|
+
|
|
137
|
+
def resolved_secret(key)
|
|
138
|
+
raw = resolved_secrets[key.to_s] || @env[key.to_s]
|
|
139
|
+
value = raw.to_s.strip
|
|
140
|
+
value.empty? ? nil : value
|
|
141
|
+
end
|
|
142
|
+
|
|
143
|
+
def resolved_secrets
|
|
144
|
+
@resolved_secrets ||= parse_secret_output(capture_kamal(kamal_secrets_print_argv).stdout)
|
|
145
|
+
end
|
|
146
|
+
|
|
147
|
+
def parse_secret_output(output)
|
|
148
|
+
output.to_s.lines.each_with_object({}) do |line, secrets|
|
|
149
|
+
key, value = line.chomp.split("=", 2)
|
|
150
|
+
next if key.to_s.empty?
|
|
151
|
+
|
|
152
|
+
secrets[key] = value.to_s
|
|
153
|
+
end
|
|
154
|
+
end
|
|
155
|
+
|
|
117
156
|
def fetch(hash, key)
|
|
118
157
|
hash[key] || hash[key.to_s] || hash[key.to_sym]
|
|
119
158
|
end
|
|
@@ -139,6 +178,15 @@ module KamalBackup
|
|
|
139
178
|
]
|
|
140
179
|
end
|
|
141
180
|
|
|
181
|
+
def kamal_secrets_print_argv
|
|
182
|
+
[
|
|
183
|
+
"kamal",
|
|
184
|
+
"secrets",
|
|
185
|
+
"print",
|
|
186
|
+
*kamal_option_argv
|
|
187
|
+
]
|
|
188
|
+
end
|
|
189
|
+
|
|
142
190
|
def kamal_option_argv
|
|
143
191
|
argv = []
|
|
144
192
|
argv.concat(["-c", @config_file]) if @config_file
|
data/lib/kamal_backup/restic.rb
CHANGED
|
@@ -6,6 +6,8 @@ require_relative "command"
|
|
|
6
6
|
|
|
7
7
|
module KamalBackup
|
|
8
8
|
class Restic
|
|
9
|
+
RESTIC_ENV_PATTERN = /\A(?:RESTIC_|AWS_|B2_|AZURE_|GOOGLE_|RCLONE_|OS_|ST_|HP_|HTTP_|HTTPS_|NO_PROXY)/i
|
|
10
|
+
|
|
9
11
|
attr_reader :config, :redactor
|
|
10
12
|
|
|
11
13
|
def initialize(config, redactor:)
|
|
@@ -25,13 +27,19 @@ module KamalBackup
|
|
|
25
27
|
end
|
|
26
28
|
|
|
27
29
|
def backup_stream(command, filename:, tags:)
|
|
28
|
-
restic_command = CommandSpec.new(
|
|
30
|
+
restic_command = CommandSpec.new(
|
|
31
|
+
argv: ["restic", "backup", "--stdin", "--stdin-filename", filename] + tag_args(common_tags + tags),
|
|
32
|
+
env: restic_env
|
|
33
|
+
)
|
|
29
34
|
log("backing up stream as #{filename}")
|
|
30
35
|
pipe_commands(command, restic_command, producer_label: "dump", consumer_label: "restic backup")
|
|
31
36
|
end
|
|
32
37
|
|
|
33
38
|
def backup_file(path, filename:, tags:)
|
|
34
|
-
command = CommandSpec.new(
|
|
39
|
+
command = CommandSpec.new(
|
|
40
|
+
argv: ["restic", "backup", "--stdin", "--stdin-filename", filename] + tag_args(common_tags + tags),
|
|
41
|
+
env: restic_env
|
|
42
|
+
)
|
|
35
43
|
log("backing up file content as #{filename}")
|
|
36
44
|
|
|
37
45
|
File.open(path, "rb") do |file|
|
|
@@ -126,12 +134,12 @@ module KamalBackup
|
|
|
126
134
|
end
|
|
127
135
|
|
|
128
136
|
def pipe_dump_to_command(snapshot, filename, command)
|
|
129
|
-
restic_command = CommandSpec.new(argv: ["restic", "dump", snapshot, filename])
|
|
137
|
+
restic_command = CommandSpec.new(argv: ["restic", "dump", snapshot, filename], env: restic_env)
|
|
130
138
|
pipe_commands(restic_command, command, producer_label: "restic dump", consumer_label: command.argv.first)
|
|
131
139
|
end
|
|
132
140
|
|
|
133
141
|
def write_dump_to_path(snapshot, filename, target_path)
|
|
134
|
-
command = CommandSpec.new(argv: ["restic", "dump", snapshot, filename])
|
|
142
|
+
command = CommandSpec.new(argv: ["restic", "dump", snapshot, filename], env: restic_env)
|
|
135
143
|
target_path = File.expand_path(target_path)
|
|
136
144
|
FileUtils.mkdir_p(File.dirname(target_path))
|
|
137
145
|
temp_path = "#{target_path}.kamal-backup-#{$$}.tmp"
|
|
@@ -160,7 +168,7 @@ module KamalBackup
|
|
|
160
168
|
end
|
|
161
169
|
|
|
162
170
|
def run(args)
|
|
163
|
-
Command.capture(CommandSpec.new(argv: ["restic"] + args), redactor: redactor)
|
|
171
|
+
Command.capture(CommandSpec.new(argv: ["restic"] + args, env: restic_env), redactor: redactor)
|
|
164
172
|
end
|
|
165
173
|
|
|
166
174
|
def common_tags
|
|
@@ -172,6 +180,12 @@ module KamalBackup
|
|
|
172
180
|
tags.compact.each_with_object([]) { |tag, args| args.concat(["--tag", tag]) }
|
|
173
181
|
end
|
|
174
182
|
|
|
183
|
+
def restic_env
|
|
184
|
+
config.env.each_with_object({}) do |(key, value), env|
|
|
185
|
+
env[key] = value if key.to_s.match?(RESTIC_ENV_PATTERN)
|
|
186
|
+
end
|
|
187
|
+
end
|
|
188
|
+
|
|
175
189
|
def pipe_commands(producer, consumer, producer_label:, consumer_label:)
|
|
176
190
|
Open3.popen3(producer.env, *producer.argv) do |producer_stdin, producer_stdout, producer_stderr, producer_wait|
|
|
177
191
|
producer_stdin.close
|
data/lib/kamal_backup/version.rb
CHANGED