class Snapsync::AutoSync

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

Constants

AutoSyncTarget
DEFAULT_CONFIG_PATH

Attributes

config_dir[R]
partitions[R]
targets[R]

Public Class Methods

load_default() click to toggle source
# File lib/snapsync/auto_sync.rb, line 16
def self.load_default
    result = new
    result.load_config
    result
end
new(config_dir = SnapperConfig.default_config_dir) click to toggle source
# 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

Public Instance Methods

add(target) click to toggle source
# 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() { |t| ... } click to toggle source

Enumerates the declared autosync targets

@yieldparam [AutoSync] target @return [void]

# 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() { |mp| ... } click to toggle source

Enumerates the available autosync targets

It may mount partitions as needed

@yieldparam [Pathname] path the path to the target's base dir

(suitable to be processed by e.g. AutoSync)

@yieldparam [AutoSyncTarget] target the target located at 'path' @return [void]

# 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() { |config, target| ... } click to toggle source

Enumerates the available synchronization targets

It may mount partitions as needed

@yieldparam [LocalTarget] target the available target @return [void]

# 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) click to toggle source
# 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) click to toggle source
# 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) click to toggle source
# 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: 600) click to toggle source
# File lib/snapsync/auto_sync.rb, line 157
def run(period: 600)
    while true
        sync
        Snapsync.info "done all declared autosync partitions, sleeping #{period}s"
        sleep period
    end
end
sync() click to toggle source
# File lib/snapsync/auto_sync.rb, line 149
def sync
    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
end
write_config(path) click to toggle source
# 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