restic-service 0.3.0 → 0.4.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/lib/restic/service.rb +2 -0
- data/lib/restic/service/conf.rb +4 -2
- data/lib/restic/service/targets/base.rb +34 -1
- data/lib/restic/service/targets/rclone_b2.rb +4 -0
- data/lib/restic/service/targets/restic.rb +1 -7
- data/lib/restic/service/targets/restic_sftp.rb +9 -27
- data/lib/restic/service/targets/rsync.rb +50 -0
- data/lib/restic/service/targets/ssh_target.rb +42 -0
- data/lib/restic/service/version.rb +1 -1
- metadata +4 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: b797f08f3ae90d533967c28a43d70b695d2d5ff4
|
4
|
+
data.tar.gz: 695d8520af725f6f9002c0764ff2e5aec4f503ca
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: da19f6808c3d4ddee424c67629a3c733da6dbc1cfb98039679c75cc1490e9dcc33d0f218495dfdceb6eed46bccdd4b6f74201b24dc0ceafb0acefaf3b13f88ce
|
7
|
+
data.tar.gz: c2ad3daec120eabe099b2e3e67135aa5cd19555d6b48a16ad6c12c26a29b9be189e326b96dbed484dbd642bb62dd51f8e191205ee89f543b417e51da9fe91224
|
data/lib/restic/service.rb
CHANGED
@@ -5,11 +5,13 @@ require 'tempfile'
|
|
5
5
|
require "restic/service/version"
|
6
6
|
require "restic/service/auto_update"
|
7
7
|
require "restic/service/targets/base"
|
8
|
+
require "restic/service/targets/ssh_target"
|
8
9
|
require "restic/service/targets/restic"
|
9
10
|
require "restic/service/targets/b2"
|
10
11
|
require "restic/service/targets/restic_b2"
|
11
12
|
require "restic/service/targets/restic_file"
|
12
13
|
require "restic/service/targets/restic_sftp"
|
13
14
|
require "restic/service/targets/rclone_b2"
|
15
|
+
require "restic/service/targets/rsync"
|
14
16
|
require "restic/service/ssh_keys"
|
15
17
|
require "restic/service/conf"
|
data/lib/restic/service/conf.rb
CHANGED
@@ -37,7 +37,8 @@ module Restic
|
|
37
37
|
'restic-b2' => Targets::ResticB2,
|
38
38
|
'restic-sftp' => Targets::ResticSFTP,
|
39
39
|
'restic-file' => Targets::ResticFile,
|
40
|
-
'rclone-b2' => Targets::RcloneB2
|
40
|
+
'rclone-b2' => Targets::RcloneB2,
|
41
|
+
'rsync' => Targets::Rsync]
|
41
42
|
|
42
43
|
TOOLS = %w{restic rclone}
|
43
44
|
|
@@ -73,7 +74,8 @@ module Restic
|
|
73
74
|
|
74
75
|
target_class = target_class_from_type(target['type'])
|
75
76
|
if !target_class
|
76
|
-
raise InvalidConfigurationFile, "target type #{target['type']} does not exist,
|
77
|
+
raise InvalidConfigurationFile, "target type #{target['type']} does not exist, "\
|
78
|
+
"available targets: #{TARGET_CLASS_FROM_TYPE.keys.sort.join(", ")}"
|
77
79
|
end
|
78
80
|
|
79
81
|
name = target['name'].to_s
|
@@ -6,8 +6,18 @@ module Restic
|
|
6
6
|
|
7
7
|
def initialize(name)
|
8
8
|
@name = name
|
9
|
-
|
10
9
|
@bandwidth_limit = nil
|
10
|
+
@io_class = nil
|
11
|
+
@io_priority = nil
|
12
|
+
@cpu_priority = nil
|
13
|
+
end
|
14
|
+
|
15
|
+
def self.normalize_yaml(yaml)
|
16
|
+
yaml.dup
|
17
|
+
end
|
18
|
+
|
19
|
+
def available?
|
20
|
+
true
|
11
21
|
end
|
12
22
|
|
13
23
|
def setup_from_conf(conf, yaml)
|
@@ -15,6 +25,29 @@ module Restic
|
|
15
25
|
if limit = yaml.fetch('bandwidth_limit', conf.bandwidth_limit)
|
16
26
|
Conf.parse_bandwidth_limit(limit)
|
17
27
|
end
|
28
|
+
if (io_class = yaml['io_class'])
|
29
|
+
@io_class = Integer(io_class)
|
30
|
+
end
|
31
|
+
if (io_priority = yaml['io_priority'])
|
32
|
+
@io_priority = Integer(io_priority)
|
33
|
+
end
|
34
|
+
if (cpu_priority = yaml['cpu_priority'])
|
35
|
+
@cpu_priority = Integer(cpu_priority)
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
def nice_commands
|
40
|
+
result = []
|
41
|
+
if @io_class
|
42
|
+
result << 'ionice' << '-c' << @io_class.to_s
|
43
|
+
if @io_priority
|
44
|
+
result << '-n' << @io_priority.to_s
|
45
|
+
end
|
46
|
+
end
|
47
|
+
if @cpu_priority
|
48
|
+
result << "nice" << "-#{@cpu_priority}"
|
49
|
+
end
|
50
|
+
result
|
18
51
|
end
|
19
52
|
end
|
20
53
|
end
|
@@ -19,6 +19,7 @@ module Restic
|
|
19
19
|
@rclone_path = conf.tool_path('rclone')
|
20
20
|
@src = yaml['src']
|
21
21
|
@filter = yaml['filter'] || []
|
22
|
+
@verbose = yaml.fetch('verbose', true)
|
22
23
|
@conf_path = conf.conf_path
|
23
24
|
end
|
24
25
|
|
@@ -27,6 +28,9 @@ module Restic
|
|
27
28
|
if @bandwidth_limit
|
28
29
|
extra_args << '--bwlimit' << @bandwidth_limit.to_s
|
29
30
|
end
|
31
|
+
if @verbose
|
32
|
+
extra_args << "--verbose"
|
33
|
+
end
|
30
34
|
|
31
35
|
Tempfile.create "rclone-#{@name}", @conf_path.to_path, perm: 0600 do |io|
|
32
36
|
io.puts <<-EOCONF
|
@@ -96,14 +96,8 @@ module Restic
|
|
96
96
|
extra_args << '--limit-download' << limit_KiB.to_s << '--limit-upload' << limit_KiB.to_s
|
97
97
|
end
|
98
98
|
|
99
|
-
ionice_args = []
|
100
|
-
if @io_class != 3
|
101
|
-
ionice_args << '-n' << @io_priority.to_s
|
102
|
-
end
|
103
|
-
|
104
99
|
system(Hash['HOME' => home, 'RESTIC_PASSWORD' => @password].merge(env),
|
105
|
-
|
106
|
-
'nice', "-#{@cpu_priority}",
|
100
|
+
*nice_commands,
|
107
101
|
@restic_path.to_path, "--cleanup-cache", *args, *extra_args, in: :close, **options)
|
108
102
|
end
|
109
103
|
|
@@ -5,18 +5,12 @@ module Restic
|
|
5
5
|
#
|
6
6
|
# See README.md for the YAML configuration file format
|
7
7
|
class ResticSFTP < Restic
|
8
|
+
include SSHTarget
|
9
|
+
|
8
10
|
def initialize(name)
|
9
11
|
super
|
10
|
-
@host = nil
|
11
12
|
@username = nil
|
12
13
|
@path = nil
|
13
|
-
@host_keys = []
|
14
|
-
end
|
15
|
-
|
16
|
-
def available?
|
17
|
-
ssh = SSHKeys.new
|
18
|
-
actual_keys = ssh.query_keys(@host)
|
19
|
-
valid?(actual_keys)
|
20
14
|
end
|
21
15
|
|
22
16
|
def self.normalize_yaml(yaml)
|
@@ -29,36 +23,24 @@ module Restic
|
|
29
23
|
end
|
30
24
|
|
31
25
|
def setup_from_conf(conf, yaml)
|
26
|
+
super
|
32
27
|
@target_name = yaml['name']
|
33
|
-
@key_path = conf.conf_keys_path_for(self)
|
34
|
-
@host_keys = SSHKeys.load_keys_from_file(@key_path)
|
35
|
-
@host = yaml['host'].to_str
|
36
28
|
@username = yaml['username'].to_str
|
37
29
|
@path = yaml['path'].to_str
|
38
30
|
@password = yaml['password'].to_str
|
39
31
|
super
|
40
32
|
end
|
41
33
|
|
42
|
-
def valid?(actual_keys)
|
43
|
-
actual_keys.any? { |k| @host_keys.include?(k) }
|
44
|
-
end
|
45
|
-
|
46
34
|
def run
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
run_backup('-r', "sftp:#{ssh_config_name}:#{@path}", 'backup')
|
51
|
-
ensure
|
52
|
-
ssh.ssh_cleanup_config
|
35
|
+
with_ssh_config do |ssh_config_name|
|
36
|
+
run_backup('-r', "sftp:#{ssh_config_name}:#{@path}", 'backup')
|
37
|
+
end
|
53
38
|
end
|
54
39
|
|
55
40
|
def forget
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
run_forget('-r', "sftp:#{ssh_config_name}:#{@path}", 'forget')
|
60
|
-
ensure
|
61
|
-
ssh.ssh_cleanup_config
|
41
|
+
with_ssh_config do |ssh_config_name|
|
42
|
+
run_forget('-r', "sftp:#{ssh_config_name}:#{@path}", 'forget')
|
43
|
+
end
|
62
44
|
end
|
63
45
|
end
|
64
46
|
end
|
@@ -0,0 +1,50 @@
|
|
1
|
+
module Restic
|
2
|
+
module Service
|
3
|
+
module Targets
|
4
|
+
class Rsync < Base
|
5
|
+
include SSHTarget
|
6
|
+
|
7
|
+
def self.normalize_yaml(yaml)
|
8
|
+
yaml = super
|
9
|
+
if !yaml['host']
|
10
|
+
raise Conf::InvalidConfigurationFile, "no host given"
|
11
|
+
elsif !yaml['source']
|
12
|
+
raise Conf::InvalidConfigurationFile, "no source given"
|
13
|
+
elsif !yaml['target']
|
14
|
+
raise Conf::InvalidConfigurationFile, "no target given"
|
15
|
+
end
|
16
|
+
yaml
|
17
|
+
end
|
18
|
+
|
19
|
+
def setup_from_conf(conf, yaml)
|
20
|
+
super
|
21
|
+
@source = yaml.fetch('source')
|
22
|
+
@target = yaml.fetch('target')
|
23
|
+
@one_file_system = yaml.fetch('one_file_system', false)
|
24
|
+
@filters = yaml.fetch('filters', [])
|
25
|
+
end
|
26
|
+
|
27
|
+
def run(*args, **options)
|
28
|
+
extra_args = []
|
29
|
+
if @one_file_system
|
30
|
+
extra_args << "--one-file-system"
|
31
|
+
end
|
32
|
+
if @bandwidth_limit
|
33
|
+
limit_KiB = @bandwidth_limit / 1000
|
34
|
+
extra_args << "--bwlimit=#{limit_KiB}"
|
35
|
+
end
|
36
|
+
|
37
|
+
home = ENV['HOME'] || '/root'
|
38
|
+
|
39
|
+
with_ssh_config do |ssh_config_name|
|
40
|
+
system(Hash['HOME' => home], *nice_commands,
|
41
|
+
'rsync', '-a', '--delete-during',
|
42
|
+
*@filters.map { |arg| "--filter=#{arg}" },
|
43
|
+
*extra_args, @source, "#{ssh_config_name}:#{@target}")
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
@@ -0,0 +1,42 @@
|
|
1
|
+
module Restic
|
2
|
+
module Service
|
3
|
+
module Targets
|
4
|
+
module SSHTarget
|
5
|
+
def initialize(name)
|
6
|
+
super
|
7
|
+
@key_path = nil
|
8
|
+
@host = nil
|
9
|
+
@username = nil
|
10
|
+
@host_keys = []
|
11
|
+
end
|
12
|
+
|
13
|
+
def setup_from_conf(conf, yaml)
|
14
|
+
super
|
15
|
+
@username = yaml.fetch('username').to_str
|
16
|
+
@host = yaml.fetch('host').to_str
|
17
|
+
@key_path = conf.conf_keys_path_for(self)
|
18
|
+
@host_keys = SSHKeys.load_keys_from_file(@key_path)
|
19
|
+
end
|
20
|
+
|
21
|
+
def available?
|
22
|
+
ssh = SSHKeys.new
|
23
|
+
actual_keys = ssh.query_keys(@host)
|
24
|
+
valid?(actual_keys)
|
25
|
+
end
|
26
|
+
|
27
|
+
def valid?(actual_keys)
|
28
|
+
actual_keys.any? { |k| @host_keys.include?(k) }
|
29
|
+
end
|
30
|
+
|
31
|
+
def with_ssh_config
|
32
|
+
ssh = SSHKeys.new
|
33
|
+
ssh_config_name = ssh.ssh_setup_config(
|
34
|
+
name, @username, @host, @key_path)
|
35
|
+
yield(ssh_config_name)
|
36
|
+
ensure
|
37
|
+
ssh.ssh_cleanup_config if ssh_config_name
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
42
|
+
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.
|
4
|
+
version: 0.4.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-05-
|
11
|
+
date: 2018-05-18 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: thor
|
@@ -111,6 +111,8 @@ files:
|
|
111
111
|
- lib/restic/service/targets/restic_b2.rb
|
112
112
|
- lib/restic/service/targets/restic_file.rb
|
113
113
|
- lib/restic/service/targets/restic_sftp.rb
|
114
|
+
- lib/restic/service/targets/rsync.rb
|
115
|
+
- lib/restic/service/targets/ssh_target.rb
|
114
116
|
- lib/restic/service/version.rb
|
115
117
|
- restic-service.gemspec
|
116
118
|
- restic-service.service
|