Class: Snapsync::AutoSync

Inherits:
Object
  • Object
show all
Defined in:
lib/snapsync/auto_sync.rb

Overview

Implementation of the auto-sync feature

This class implements the ‘snapsync auto’ functionality. It monitors for partition availability, and will run sync-all on each (declared) targets when they are available, optionally auto-mounting them

Defined Under Namespace

Classes: AutoSyncTarget

Constant Summary collapse

DEFAULT_CONFIG_PATH =
Pathname.new('/etc/snapsync.conf')

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(config_dir = SnapperConfig.default_config_dir) ⇒ AutoSync

Returns a new instance of AutoSync.



22
23
24
25
26
# File 'lib/snapsync/auto_sync.rb', line 22

def initialize(config_dir = SnapperConfig.default_config_dir)
    @config_dir = config_dir
    @targets = Hash.new
    @partitions = PartitionsMonitor.new
end

Instance Attribute Details

#config_dirObject (readonly)

Returns the value of attribute config_dir.



10
11
12
# File 'lib/snapsync/auto_sync.rb', line 10

def config_dir
  @config_dir
end

#partitionsObject (readonly)

Returns the value of attribute partitions.



12
13
14
# File 'lib/snapsync/auto_sync.rb', line 12

def partitions
  @partitions
end

#targetsObject (readonly)

Returns the value of attribute targets.



11
12
13
# File 'lib/snapsync/auto_sync.rb', line 11

def targets
  @targets
end

Class Method Details

.load_defaultObject



16
17
18
19
20
# File 'lib/snapsync/auto_sync.rb', line 16

def self.load_default
    result = new
    result.load_config
    result
end

Instance Method Details

#add(target) ⇒ Object



134
135
136
137
138
# File 'lib/snapsync/auto_sync.rb', line 134

def add(target)
    targets[target.partition_uuid] ||= Array.new
    targets[target.partition_uuid] << target
    partitions.monitor_for(target.partition_uuid)
end

#each_autosync_target {|target| ... } ⇒ void

This method returns an undefined value.

Enumerates the declared autosync targets

Yield Parameters:



58
59
60
61
62
63
# File 'lib/snapsync/auto_sync.rb', line 58

def each_autosync_target
    return enum_for(__method__) if !block_given?
    targets.each_value do |targets|
        targets.each { |t| yield(t) }
    end
end

#each_available_autosync_target {|path, target| ... } ⇒ void

This method returns an undefined value.

Enumerates the available autosync targets

It may mount partitions as needed

Yield Parameters:

  • path (Pathname)

    the path to the target’s base dir (suitable to be processed by e.g. AutoSync)

  • target (AutoSyncTarget)

    the target located at ‘path’



73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
# File 'lib/snapsync/auto_sync.rb', line 73

def each_available_autosync_target
    return enum_for(__method__) if !block_given?
    partitions.poll

    partitions.known_partitions.each do |uuid, fs|
        autosync_targets = targets[uuid]
        next if autosync_targets.empty?

        mp = fs['MountPoints'].first
        if mp
            mp = Pathname.new(mp[0..-2].pack("U*"))
        end

        begin
            mounted = false

            if !mp
                if !autosync_targets.any?(&:automount)
                    Snapsync.info "partition #{uuid} is present, but not mounted and automount is false. Ignoring"
                    next
                end

                Snapsync.info "partition #{uuid} is present, but not mounted, automounting"
                begin
                    mp = fs.Mount([]).first
                rescue Exception => e
                    Snapsync.warn "failed to mount, ignoring this target"
                    next
                end
                mp = Pathname.new(mp)
                mounted = true
            end

            autosync_targets.each do |target|
                yield(mp + target.path, target)
            end

        ensure
            if mounted
                fs.Unmount([])
            end
        end
    end
end

#each_available_target {|target| ... } ⇒ void

This method returns an undefined value.

Enumerates the available synchronization targets

It may mount partitions as needed

Yield Parameters:



124
125
126
127
128
129
130
131
132
# File 'lib/snapsync/auto_sync.rb', line 124

def each_available_target
    return enum_for(__method__) if !block_given?
    each_available_autosync_target do |path, t|
        op = SyncAll.new(path, config_dir: config_dir)
        op.each_target do |config, target|
            yield(config, target)
        end
    end
end

#load_config(path = DEFAULT_CONFIG_PATH) ⇒ Object



28
29
30
31
# File 'lib/snapsync/auto_sync.rb', line 28

def load_config(path = DEFAULT_CONFIG_PATH)
    conf = YAML.load(path.read) || Array.new
    parse_config(conf)
end

#parse_config(conf) ⇒ Object



33
34
35
36
37
38
39
40
# File 'lib/snapsync/auto_sync.rb', line 33

def parse_config(conf)
    conf.each do |hash|
        target = AutoSyncTarget.new
        hash.each { |k, v| target[k] = v }
        target.path = Pathname.new(target.path)
        add(target)
    end
end

#remove(**matcher) ⇒ Object



140
141
142
143
144
145
146
147
# File 'lib/snapsync/auto_sync.rb', line 140

def remove(**matcher)
    targets.delete_if do |uuid, list|
        list.delete_if do |t|
            matcher.all? { |k, v| t[k] == v }
        end
        list.empty?
    end
end

#run(period: 60) ⇒ Object



149
150
151
152
153
154
155
156
157
158
159
# File 'lib/snapsync/auto_sync.rb', line 149

def run(period: 60)
    while true
        each_available_autosync_target do |path, t|
            Snapsync.info "sync-all on #{path} (partition #{t.partition_uuid})"
            op = SyncAll.new(path, config_dir: config_dir)
            op.run
        end
        Snapsync.info "done all declared autosync partitions, sleeping #{period}s"
        sleep period
    end
end

#write_config(path) ⇒ Object



42
43
44
45
46
47
48
49
50
51
52
# File 'lib/snapsync/auto_sync.rb', line 42

def write_config(path)
    data = each_autosync_target.map do |target|
        Hash['partition_uuid' => target.partition_uuid,
             'path' => target.path.to_s,
             'automount' => !!target.automount,
             'name' => target.name]
    end
    File.open(path, 'w') do |io|
        YAML.dump(data, io)
    end
end