snapsync 0.4.2 → 0.5.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
  SHA256:
3
- metadata.gz: 4e8460c2d2ec6ca78697933413dd8d94ac0296c5fa6260b347142c2f4e63941b
4
- data.tar.gz: 8803931f41de5e109d0008a899426c50501df212d5bf11091e1ece40aa643471
3
+ metadata.gz: 65f1584da8033d0abd6635cbd1a004340bf0d1f32f3b0eccc7edaecae0e97363
4
+ data.tar.gz: e20b0ef8cc9a9a20a48e3b61175da55bb1c604614785a89f52f74ff5a2b2432c
5
5
  SHA512:
6
- metadata.gz: 94a27af03869d1b9dea48a8b0840db2e67fb65644faa41045d042ab220221ec685d3c79d57c4fe99a6a919e6f7d4ec478af8dc65b5230bdabecd33b9abb94dfc
7
- data.tar.gz: 2b1417846f0e16afe8b1780ffc1e0ef163705084ac126b870d6cdcca27e3f5a75d33f9a9e5b2f938b9e89871fdc3f67e018b045c26b6c6468a4e62a96dcf0ecb
6
+ metadata.gz: bcb3043948f97f82b2f1907ad13871327f7537bad3ac13fe510a1009b936bcb5096b44e27ebfbce490b31d6874412fbb527349b5ba1c5489261d52b920fe008a
7
+ data.tar.gz: b6bc9c3be836393fcb8cb9a4762b13323b1d72a61330d8fda857aeecbf64f46d9bd00249f76b60891428b2f549b5b1c5bf172186ecf3ec0ba2a55550af6548f1
data/README.md CHANGED
@@ -8,22 +8,23 @@ receive.
8
8
 
9
9
  It can be used in two modes:
10
10
  - in manual mode, you run snapsync
11
+ - systemd timer, runs snapsync periodically
11
12
 
12
13
  ## Installation
13
14
 
14
15
  You need to make sure that you've installed Ruby's bundler. On Ubuntu, run
15
- $ apt install bundler
16
+ `$ apt install bundler`
16
17
 
17
18
  Then, the following will install snapsync in /opt/snapsync
18
19
 
19
20
  $ wget https://raw.githubusercontent.com/doudou/snapsync/master/install.sh
20
21
  $ sh install.sh
21
22
 
22
- The script will use sudo to get root rights when required. Add /opt/snapsync/bin
23
- to your PATH if you want to use 'snapsync' as-is. Otherwise, you will have to
24
- refer to /opt/snapsync/bin/snapsync explicitely. If it seems that you are using
25
- systemd, the script also installs snapsync's systemd service file into the
26
- system, enables and starts it.
23
+ The script will use sudo to get root rights when required. Add `/opt/snapsync/bin`
24
+ to your PATH if you want to use `snapsync` as-is. Otherwise, you will have to
25
+ refer to `/opt/snapsync/bin/snapsync` explicitely.
26
+
27
+ If it seems that you are using systemd, the script also installs snapsync's systemd service and timer files into the system, enables the timer and starts it. By default the timer runs every day at 20:00.
27
28
 
28
29
  ## Usage
29
30
 
data/install.sh CHANGED
@@ -1,6 +1,6 @@
1
1
  #! /bin/sh -ex
2
2
 
3
- target=`mktemp -d`
3
+ target=`mktemp -d --suffix _snapsync-install`
4
4
  cd $target
5
5
  cat > Gemfile <<GEMFILE
6
6
  source "https://rubygems.org"
@@ -16,10 +16,9 @@ sudo chmod go+rX /opt/snapsync
16
16
 
17
17
  if test -d /lib/systemd/system; then
18
18
  snapsync_gem=`bundler show snapsync`
19
- sudo cp $snapsync_gem/snapsync.service /lib/systemd/system
20
- ( sudo systemctl stop snapsync.service
21
- sudo systemctl enable snapsync.service
22
- sudo systemctl start snapsync.service )
19
+ sudo ln -s /opt/snapsync/systemd/* /lib/systemd/system
20
+ ( sudo systemctl enable snapsync-local.timer
21
+ sudo systemctl enable snapsync-remote.timer)
23
22
  fi
24
23
 
25
24
  rm -rf $target
@@ -0,0 +1,52 @@
1
+ require 'libnotify'
2
+
3
+ module Snapsync
4
+ # This class abstracts notifying each user on the system
5
+ # NOTE: Not multi-thread safe!
6
+ class Notification
7
+ # @return [Hash{Integer => Libnotify::API}]
8
+ attr_reader :notified_users
9
+
10
+ def initialize(config)
11
+ @notified_users = {}
12
+
13
+
14
+ Dir.each_child('/run/user') do |user_id|
15
+ # seteuid _must_ be set for session dbus to accept the connection
16
+ Process::Sys.seteuid(user_id.to_i)
17
+ ENV['DBUS_SESSION_BUS_ADDRESS'] = "unix:path=/run/user/#{user_id}/bus"
18
+
19
+ n = Libnotify.new(config)
20
+ @notified_users[user_id.to_i] = n
21
+ n.show!
22
+ end
23
+ # set euid back, so all commands works normally
24
+ Process::Sys.seteuid Process::Sys.getuid
25
+ end
26
+
27
+ def update(config)
28
+ each_raw_notification do |n|
29
+ n.update(config)
30
+ end
31
+ end
32
+
33
+ def close
34
+ each_raw_notification do |n|
35
+ n.close
36
+ end
37
+ end
38
+
39
+ # @yieldparam [Libnotify::API] n
40
+ private def each_raw_notification
41
+ notified_users.each do |user_id, n|
42
+ # seteuid _must_ be set for session dbus to accept the connection
43
+ Process::Sys.seteuid(user_id)
44
+ ENV['DBUS_SESSION_BUS_ADDRESS'] = "unix:path=/run/user/#{user_id}/bus"
45
+
46
+ yield n
47
+ end
48
+ # set euid back, so all commands works normally
49
+ Process::Sys.seteuid Process::Sys.getuid
50
+ end
51
+ end
52
+ end
@@ -72,7 +72,7 @@ module Snapsync
72
72
  Snapsync.debug "Btrfs(\"#{mountpoint}\").popen: #{args}"
73
73
 
74
74
  if @mountpoint.is_a? RemotePathname
75
- proc = SSHPopen.new(@mountpoint, [btrfs_prog, *args], **options)
75
+ proc = SSHPopenExe.new(@mountpoint, [btrfs_prog, *args], **options)
76
76
  return yield(proc)
77
77
  else
78
78
  # @type [IO,IO]
data/lib/snapsync/cli.rb CHANGED
@@ -2,10 +2,16 @@ require 'thor'
2
2
  require 'snapsync'
3
3
  require 'set'
4
4
 
5
+ require_relative 'tasks/AutoSync'
6
+
5
7
  module Snapsync
6
8
  class CLI < Thor
7
9
  class_option :debug, type: :boolean, default: false
8
10
  class_option :ssh_debug, type: :boolean, default: false
11
+ class_option :systemd, type: :boolean, default: false,
12
+ desc: "Tells snapsync it is being run from a systemd service"
13
+ class_option :notify, type: :boolean, default: false,
14
+ desc: "Use libnotify to notify all users in system"
9
15
 
10
16
  no_commands do
11
17
  def config_from_name(name)
@@ -25,6 +31,8 @@ module Snapsync
25
31
  end
26
32
 
27
33
  Snapsync.SSH_DEBUG = options[:ssh_debug]
34
+ Snapsync.SYSTEMD = options[:systemd]
35
+ Snapsync.NOTIFY = options[:notify]
28
36
  end
29
37
 
30
38
  # Resolves a path (or nil) into a list of snapsync targets and
@@ -301,13 +309,25 @@ While it can easily be done manually, this command makes sure that the snapshots
301
309
  default: false
302
310
  option :config_file, desc: "path to the config file (defaults to /etc/snapsync.conf)",
303
311
  default: '/etc/snapsync.conf'
312
+ option :local_only, desc: "Only synchronize to local targets", type: :boolean, default: false
313
+ option :remote_only, desc: "Only synchronize to remote targets", type: :boolean, default: false
304
314
  def auto_sync
305
315
  handle_class_options
306
- auto = AutoSync.new(SnapperConfig.default_config_dir, snapsync_config_file: Pathname.new(options[:config_file]))
307
- if options[:one_shot]
308
- auto.sync
309
- else
316
+
317
+ if options[:local_only] and options[:remote_only]
318
+ raise ArgumentError, '--local-only and --remote-only cannot be used together'
319
+ end
320
+
321
+ while true
322
+ auto = AutoSync.new(SnapperConfig.default_config_dir,
323
+ snapsync_config_file: Pathname.new(options[:config_file]),
324
+ sync_local: options[:local_only] || !options[:remote_only],
325
+ sync_remote: options[:remote_only] || !options[:local_only])
310
326
  auto.run
327
+ break if options[:one_shot]
328
+
329
+ Snapsync.info "done all declared autosync partitions, sleeping #{period}s"
330
+ sleep 600
311
331
  end
312
332
  end
313
333
 
@@ -300,6 +300,7 @@ module Snapsync
300
300
  end
301
301
 
302
302
  def read
303
+ Snapsync.debug "RemotePathname ('#{uri}').read"
303
304
  begin
304
305
  sftp_f.open(uri.path).read
305
306
  rescue Net::SFTP::StatusException => e
@@ -60,17 +60,18 @@ module Snapsync
60
60
  raise ExitSignal, "Exited due to signal: #{exit_signal}"
61
61
  end
62
62
 
63
- channel.on_process do
64
- begin
65
- channel.send_data(write_buffer_out.read_nonblock(2 << 20))
66
- rescue IO::EAGAINWaitReadable
67
- end
68
- end
69
-
70
63
  channel.exec(Shellwords.join command)
71
64
  end
72
65
 
73
- ssh.loop(0.001) {
66
+ write_buffer_out.extend(Net::SSH::BufferedIo)
67
+ ssh.listen_to(write_buffer_out) do
68
+ begin
69
+ channel.send_data(write_buffer_out.read_nonblock(2 << 20))
70
+ rescue IO::EAGAINWaitReadable
71
+ end
72
+ end
73
+
74
+ ssh.loop {
74
75
  if write_buffer_out.closed?
75
76
  channel.close
76
77
  end
@@ -0,0 +1,52 @@
1
+ module Snapsync
2
+ class SSHPopenExe
3
+ # @return [IO]
4
+ attr_reader :ssh_proc
5
+
6
+ class NonZeroExitCode < RuntimeError
7
+ end
8
+ class ExitSignal < RuntimeError
9
+ end
10
+
11
+ # @return [IO]
12
+ attr_reader :read_buffer
13
+
14
+ # @return [IO]
15
+ attr_reader :write_buffer
16
+
17
+ # @param machine [RemotePathname]
18
+ # @param [Array] command
19
+ # @param options [Hash]
20
+ def initialize(machine, command, **options)
21
+ # @type [IO,IO]
22
+ @err_r, err_w = IO.pipe
23
+ full_cmd = ['ssh', machine.uri.host, *command]
24
+ Snapsync.debug "Opening SSH Tunnel: #{full_cmd}"
25
+ @ssh_proc = IO.popen(full_cmd, err: err_w, mode: 'r+')
26
+ end
27
+
28
+ def sync=(sync)
29
+ # ignore
30
+ end
31
+
32
+ def read(nbytes = nil)
33
+ begin
34
+ return ssh_proc.read nbytes
35
+ rescue Errno::EWOULDBLOCK
36
+ return ''
37
+ end
38
+ end
39
+
40
+ def write(data)
41
+ ssh_proc.write data
42
+ end
43
+
44
+ def close
45
+ ssh_proc.close_write
46
+ end
47
+
48
+ def err
49
+ @err_r.read
50
+ end
51
+ end
52
+ end
@@ -1,10 +1,12 @@
1
+ require_relative 'Task'
2
+
1
3
  module Snapsync
2
4
  # Implementation of the auto-sync feature
3
5
  #
4
6
  # This class implements the 'snapsync auto' functionality. It monitors for
5
7
  # partition availability, and will run sync-all on each (declared) targets
6
8
  # when they are available, optionally auto-mounting them
7
- class AutoSync
9
+ class AutoSync < Task
8
10
  AutoSyncTarget = Struct.new :partition_uuid, :mountpoint, :relative, :automount, :name
9
11
 
10
12
  attr_reader :config_dir
@@ -14,9 +16,16 @@ module Snapsync
14
16
 
15
17
  DEFAULT_CONFIG_PATH = Pathname.new('/etc/snapsync.conf')
16
18
 
17
- def initialize(config_dir = SnapperConfig.default_config_dir, snapsync_config_file: DEFAULT_CONFIG_PATH)
19
+ def initialize(config_dir = SnapperConfig.default_config_dir,
20
+ snapsync_config_file: DEFAULT_CONFIG_PATH,
21
+ sync_local: true,
22
+ sync_remote: true)
18
23
  @config_dir = config_dir
19
24
  @targets = Hash.new
25
+
26
+ @sync_local = sync_local
27
+ @sync_remote = sync_remote
28
+
20
29
  @partitions = PartitionsMonitor.new
21
30
  partitions.poll
22
31
 
@@ -34,7 +43,7 @@ module Snapsync
34
43
  migrated = false
35
44
  if conf.is_a? Array
36
45
  # Version 1
37
- Snapsync.info "Migrating config from v1 to v2"
46
+ info "Migrating config from v1 to v2"
38
47
  conf = config_migrate_v1_v2(conf)
39
48
  migrated = true
40
49
  elsif conf['version'] != 2
@@ -47,7 +56,7 @@ module Snapsync
47
56
  end
48
57
 
49
58
  private def config_migrate_v1_v2(conf)
50
- Snapsync.info "Migrating config from version 1 to version 2"
59
+ info "Migrating config from version 1 to version 2"
51
60
  targets = conf.map do |target|
52
61
  target['relative'] = target['path']
53
62
  target.delete('path')
@@ -122,11 +131,11 @@ module Snapsync
122
131
  mountpoint = target.mountpoint
123
132
  if not mountpoint.mountpoint?
124
133
  if not target.automount
125
- Snapsync.info "partition #{uuid} is present, but not mounted and automount is false. Ignoring"
134
+ info "partition #{uuid} is present, but not mounted and automount is false. Ignoring"
126
135
  next
127
136
  end
128
137
 
129
- Snapsync.info "partition #{uuid} is present, but not mounted, automounting"
138
+ info "partition #{uuid} is present, but not mounted, automounting"
130
139
  begin
131
140
  if mountpoint.is_a? RemotePathname
132
141
  # TODO: automounting of remote paths
@@ -136,7 +145,7 @@ module Snapsync
136
145
  end
137
146
  mounted = true
138
147
  rescue Exception => e
139
- Snapsync.warn "failed to mount, ignoring this target"
148
+ warn "failed to mount, ignoring this target"
140
149
  next
141
150
  end
142
151
  end
@@ -182,21 +191,17 @@ module Snapsync
182
191
  end
183
192
  end
184
193
 
185
- def sync
194
+ def _task_name
195
+ 'Auto-Sync'
196
+ end
197
+
198
+ def _run
186
199
  each_available_autosync_target do |path, t|
187
- Snapsync.info "sync-all on #{path} (partition #{t.partition_uuid})"
200
+ info "sync-all on #{path} (partition #{t.partition_uuid})"
188
201
  op = SyncAll.new(path, config_dir: config_dir)
189
202
  op.run
190
203
  end
191
204
  end
192
-
193
- def run(period: 600)
194
- while true
195
- sync
196
- Snapsync.info "done all declared autosync partitions, sleeping #{period}s"
197
- sleep period
198
- end
199
- end
200
205
  end
201
206
  end
202
207
 
@@ -0,0 +1,79 @@
1
+ require_relative '../Notification'
2
+
3
+ module Snapsync
4
+ # Tasks extending this should implement `_run`, `_task_name`
5
+ #
6
+ # All messages should be sent through `info`, `warn`, `error`
7
+ # All sub-tasks should be executed by `task` or appropriately adding parent to <Task>.new
8
+ # Progress (if the task implements it) should be notified by `set_progress`
9
+ class Task
10
+
11
+ def info(msg)
12
+ Snapsync.info msg
13
+ if Snapsync.NOTIFY
14
+ @notification.update({:body => msg})
15
+ end
16
+ end
17
+
18
+ def warn(msg)
19
+ Snapsync.warn msg
20
+ if Snapsync.NOTIFY
21
+ @notification.update({:body => msg, :urgency => :critical})
22
+ end
23
+ end
24
+
25
+ def error(msg)
26
+ Snapsync.error msg
27
+ if Snapsync.NOTIFY
28
+ @notification.update({:body => msg, :urgency => :critical})
29
+ end
30
+ end
31
+
32
+ # @param [Integer] percent
33
+ def set_progress(percent)
34
+ if Snapsync.NOTIFY
35
+ @notification.update({:body => "[#{'#'*(percent / 10)}]"})
36
+ end
37
+ end
38
+
39
+ # @param [Task, nil] parent
40
+ def initialize(parent: nil)
41
+ @parent = parent
42
+ end
43
+
44
+ def set_status(status)
45
+ if Snapsync.NOTIFY
46
+ @notification.update({ :summary => "#{_task_name} #{status}" })
47
+ end
48
+ end
49
+
50
+
51
+ def run
52
+ if Snapsync.NOTIFY
53
+ @notification = Notification.new({
54
+ :app_name => "Snapsync"+(Snapsync.SYSTEMD ? ' [systemd service]' : ''),
55
+ :body => "Starting...", :summary => "#{_task_name} Running",
56
+ :urgency => :normal, :append => false, :transient => false, :timeout => 15.0,
57
+ :icon_path => "/usr/share/icons/gnome/scalable/emblems/emblem-default.svg"})
58
+ end
59
+
60
+ begin
61
+ _run
62
+ rescue Exception => e
63
+ set_status "Failed"
64
+ error e.message
65
+ raise e
66
+ end
67
+
68
+ set_status "Finished"
69
+ end
70
+
71
+ def _task_name
72
+ raise NotImplementedError
73
+ end
74
+
75
+ def _run
76
+ raise NotImplementedError
77
+ end
78
+ end
79
+ end
@@ -1,3 +1,3 @@
1
1
  module Snapsync
2
- VERSION = "0.4.2"
2
+ VERSION = "0.5.0"
3
3
  end
data/lib/snapsync.rb CHANGED
@@ -24,6 +24,7 @@ require 'snapsync/cleanup'
24
24
 
25
25
  require 'snapsync/remote_pathname'
26
26
  require 'snapsync/ssh_popen'
27
+ require 'snapsync/ssh_popen_exe'
27
28
 
28
29
  require 'snapsync/default_sync_policy'
29
30
  require 'snapsync/timeline_sync_policy'
@@ -32,7 +33,7 @@ require 'snapsync/sync_last_policy'
32
33
  require 'snapsync/partitions_monitor'
33
34
  require 'snapsync/sync'
34
35
  require 'snapsync/sync_all'
35
- require 'snapsync/auto_sync'
36
+
36
37
 
37
38
  module Logging
38
39
  module Installer
@@ -103,8 +104,12 @@ module Snapsync
103
104
 
104
105
  class << self
105
106
  attr_accessor :SSH_DEBUG
107
+ attr_accessor :SYSTEMD
108
+ attr_accessor :NOTIFY
106
109
  end
107
110
  Snapsync.SSH_DEBUG = false
111
+ Snapsync.SYSTEMD = false
112
+ Snapsync.NOTIFY = false
108
113
 
109
114
  # @param [String] dir
110
115
  # @return [AgnosticPath]
data/snapsync.gemspec CHANGED
@@ -29,10 +29,11 @@ EOD
29
29
  spec.add_dependency 'ruby-dbus', "~> 0.16.0"
30
30
  spec.add_dependency 'thor', "~> 1.1"
31
31
  spec.add_dependency 'uri-ssh_git', "~> 2.0.0"
32
- spec.add_dependency 'eximius-net-ssh', ">= 6.3.1"
33
- spec.add_dependency 'net-sftp', "~> 3.0.0"
32
+ spec.add_dependency 'net-ssh', "~> 7.0"
33
+ spec.add_dependency 'net-sftp', ">= 4.0.0.rc1", "< 5.0"
34
34
  spec.add_dependency 'ed25519', ">= 1.2"
35
35
  spec.add_dependency 'bcrypt_pbkdf', ">= 1.0"
36
+ spec.add_dependency 'libnotify', '~> 0.9'
36
37
 
37
38
  spec.add_development_dependency "bundler", "~> 2"
38
39
  spec.add_development_dependency "rake", "~> 13"
@@ -0,0 +1,10 @@
1
+ [Unit]
2
+ Description=Checks if the current default connection is unmetered
3
+ After=NetworkManager-dispatcher.service
4
+
5
+ [Service]
6
+ Type=oneshot
7
+ ExecStart=/usr/local/lib/snapsync/snapsync-check-is-connection-unmetered.sh
8
+
9
+ [Install]
10
+ WantedBy=NetworkManager-dispatcher.service
@@ -0,0 +1,8 @@
1
+ [Unit]
2
+ Description=Checks if the current default connection is unmetered
3
+
4
+ [Service]
5
+ ExecStart=/usr/bin/sleep infinity
6
+
7
+ [Install]
8
+ WantedBy=NetworkManager-dispatcher.service
@@ -4,7 +4,7 @@ Wants=udisks2.service
4
4
 
5
5
  [Service]
6
6
  Type=simple
7
- ExecStart=/usr/bin/env HOME=/root /usr/bin/snapsync auto-sync --one-shot
7
+ ExecStart=/usr/bin/env HOME=/root /usr/bin/snapsync auto-sync --one-shot --systemd --notify --local-only
8
8
  Nice=19
9
9
  IOSchedulingClass=idle
10
10
  KillSignal=SIGINT
@@ -1,5 +1,5 @@
1
1
  [Unit]
2
- Description=Run snapsync
2
+ Description=Run snapsync for local filesystems
3
3
 
4
4
  [Timer]
5
5
  OnCalendar=*-*-* 20:00:00
@@ -0,0 +1,13 @@
1
+ [Unit]
2
+ Description=service that synchronizes snapper snapshots to other media
3
+ Wants=udisks2.service
4
+
5
+ [Service]
6
+ Type=simple
7
+ ExecStart=/usr/bin/env HOME=/root /usr/bin/snapsync auto-sync --one-shot --systemd --notify --remote-only
8
+ Nice=19
9
+ IOSchedulingClass=idle
10
+ KillSignal=SIGINT
11
+
12
+ [Install]
13
+ WantedBy=default.target
@@ -0,0 +1,12 @@
1
+ [Unit]
2
+ Description=Run snapsync for remote filesystems
3
+ BindsTo=snapsync-is-connection-unmetered.service
4
+ After=snapsync-is-connection-unmetered.service
5
+
6
+ [Timer]
7
+ OnCalendar=*-*-* 20:00:00
8
+ RandomizedDelaySec=5min
9
+ Persistent=true
10
+
11
+ [Install]
12
+ WantedBy=snapsync-is-connection-unmetered.service
@@ -0,0 +1,22 @@
1
+ #!/usr/bin/env bash
2
+
3
+ set -e
4
+
5
+ default_dev=$(ip r | grep '^default via' | cut -d ' ' -f 5)
6
+
7
+ if [ "$default_dev" == '' ]; then
8
+ # Disconnected
9
+ echo "State: Disconnected"
10
+ systemctl stop snapsync-is-connection-unmetered.service
11
+ exit 0
12
+ fi
13
+
14
+ if [ "$(nmcli -g general.metered dev show "$default_dev" | cut -d ' ' -f 1)" == 'no' ]; then
15
+ echo "State: Unmetered"
16
+ systemctl start snapsync-is-connection-unmetered.service
17
+ else
18
+ echo "State: Metered"
19
+ systemctl stop snapsync-is-connection-unmetered.service
20
+ fi
21
+
22
+
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: snapsync
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.4.2
4
+ version: 0.5.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Sylvain Joyeux
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2022-04-21 00:00:00.000000000 Z
11
+ date: 2022-10-19 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rexml
@@ -101,33 +101,39 @@ dependencies:
101
101
  - !ruby/object:Gem::Version
102
102
  version: 2.0.0
103
103
  - !ruby/object:Gem::Dependency
104
- name: eximius-net-ssh
104
+ name: net-ssh
105
105
  requirement: !ruby/object:Gem::Requirement
106
106
  requirements:
107
- - - ">="
107
+ - - "~>"
108
108
  - !ruby/object:Gem::Version
109
- version: 6.3.1
109
+ version: '7.0'
110
110
  type: :runtime
111
111
  prerelease: false
112
112
  version_requirements: !ruby/object:Gem::Requirement
113
113
  requirements:
114
- - - ">="
114
+ - - "~>"
115
115
  - !ruby/object:Gem::Version
116
- version: 6.3.1
116
+ version: '7.0'
117
117
  - !ruby/object:Gem::Dependency
118
118
  name: net-sftp
119
119
  requirement: !ruby/object:Gem::Requirement
120
120
  requirements:
121
- - - "~>"
121
+ - - ">="
122
122
  - !ruby/object:Gem::Version
123
- version: 3.0.0
123
+ version: 4.0.0.rc1
124
+ - - "<"
125
+ - !ruby/object:Gem::Version
126
+ version: '5.0'
124
127
  type: :runtime
125
128
  prerelease: false
126
129
  version_requirements: !ruby/object:Gem::Requirement
127
130
  requirements:
128
- - - "~>"
131
+ - - ">="
132
+ - !ruby/object:Gem::Version
133
+ version: 4.0.0.rc1
134
+ - - "<"
129
135
  - !ruby/object:Gem::Version
130
- version: 3.0.0
136
+ version: '5.0'
131
137
  - !ruby/object:Gem::Dependency
132
138
  name: ed25519
133
139
  requirement: !ruby/object:Gem::Requirement
@@ -156,6 +162,20 @@ dependencies:
156
162
  - - ">="
157
163
  - !ruby/object:Gem::Version
158
164
  version: '1.0'
165
+ - !ruby/object:Gem::Dependency
166
+ name: libnotify
167
+ requirement: !ruby/object:Gem::Requirement
168
+ requirements:
169
+ - - "~>"
170
+ - !ruby/object:Gem::Version
171
+ version: '0.9'
172
+ type: :runtime
173
+ prerelease: false
174
+ version_requirements: !ruby/object:Gem::Requirement
175
+ requirements:
176
+ - - "~>"
177
+ - !ruby/object:Gem::Version
178
+ version: '0.9'
159
179
  - !ruby/object:Gem::Dependency
160
180
  name: bundler
161
181
  requirement: !ruby/object:Gem::Requirement
@@ -273,7 +293,7 @@ files:
273
293
  - bin/snapsync
274
294
  - install.sh
275
295
  - lib/snapsync.rb
276
- - lib/snapsync/auto_sync.rb
296
+ - lib/snapsync/Notification.rb
277
297
  - lib/snapsync/btrfs.rb
278
298
  - lib/snapsync/btrfs_subvolume.rb
279
299
  - lib/snapsync/cleanup.rb
@@ -286,17 +306,25 @@ files:
286
306
  - lib/snapsync/snapshot.rb
287
307
  - lib/snapsync/snapshot_transfer.rb
288
308
  - lib/snapsync/ssh_popen.rb
309
+ - lib/snapsync/ssh_popen_exe.rb
289
310
  - lib/snapsync/sync.rb
290
311
  - lib/snapsync/sync_all.rb
291
312
  - lib/snapsync/sync_last_policy.rb
292
313
  - lib/snapsync/sync_target.rb
314
+ - lib/snapsync/tasks/AutoSync.rb
315
+ - lib/snapsync/tasks/Task.rb
293
316
  - lib/snapsync/test.rb
294
317
  - lib/snapsync/timeline_sync_policy.rb
295
318
  - lib/snapsync/util.rb
296
319
  - lib/snapsync/version.rb
297
320
  - snapsync.gemspec
298
- - snapsync.service
299
- - snapsync.timer
321
+ - systemd/snapsync-check-is-connection-unmetered.service
322
+ - systemd/snapsync-is-connection-unmetered.service
323
+ - systemd/snapsync-local.service
324
+ - systemd/snapsync-local.timer
325
+ - systemd/snapsync-remote.service
326
+ - systemd/snapsync-remote.timer
327
+ - usrlib/snapsync-check-is-connection-unmetered.sh
300
328
  homepage: https://github.com/doudou/snapsync
301
329
  licenses:
302
330
  - MIT
@@ -316,7 +344,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
316
344
  - !ruby/object:Gem::Version
317
345
  version: '0'
318
346
  requirements: []
319
- rubygems_version: 3.3.8
347
+ rubygems_version: 3.3.23
320
348
  signing_key:
321
349
  specification_version: 4
322
350
  summary: tool to automate backing up snapper snapshots to other medias