class LSync::Script

The main backup/synchronisation mechanism is the backup script. It specifies all servers and directories, and these are then combined specifically to produce the desired data replication behaviour.

Attributes

directories[R]

All directories which may be synchronised.

log[R]

Log data (an IO) specific to the current script.

logger[RW]

The script logger which will be provided all events when the script is run.

master[RW]

The master server name (e.g. symbolic or host name)

method[RW]

A specific method which will perform the backup (e.g. an isntance of LSync::Method)

servers[R]

All servers which are participating in the backup process.

Public Class Methods

new(options = {}, &block) click to toggle source
# File lib/lsync/script.rb, line 33
def initialize(options = {}, &block)
        if options[:logger]
                @logger = options[:logger]
        else
                @logger = Logger.new($stdout)
                @logger.formatter = LSync::MinimalLogFormat.new
        end
        
        @method = nil

        @servers = {}
        @directories = []
        @master = "localhost"

        @log = nil

        if block_given?
                instance_eval &block
        end
end

Public Instance Methods

[](name)
Alias for: find_named_server
backup(*paths)
Alias for: copy
copy(*paths) { |directory| ... } click to toggle source

Backup a particular path (or paths).

# File lib/lsync/script.rb, line 120
def copy(*paths)
        paths.each do |path|
                directory = Directory.new(path)

                yield directory if block_given?

                @directories << directory
        end
end
Also aliased as: backup
find_current_server() click to toggle source

Find the server that matches the current machine

# File lib/lsync/script.rb, line 82
def find_current_server
        master = find_master_server
        server = nil

        # There might be the case that the the local machine is both the master server and the backup server..
        # thus we check first if the master server is the local machine:
        if master.local?
                server = master
        else
                # Find a server config that specifies the local host
                server = @servers.values.find { |s| s.local? }
        end

        # At this point we must know the current server or we can't continue
        if server == nil
                raise ScriptError.new("Could not determine current server!", :script => self)
        end

        return server
end
find_master_server() click to toggle source

Find the master server based on the name master= specified

# File lib/lsync/script.rb, line 70
def find_master_server
        server = find_named_server(@master)
        
        # At this point we must know the current server or we can't continue
        if server == nil
                raise ScriptError.new("Could not determine master server!", :script => self, :name => @master)
        end
        
        return server
end
find_named_server(name) click to toggle source

Given a name, find out which server config matches it

# File lib/lsync/script.rb, line 55
def find_named_server(name)
        if @servers.key? name
                return @servers[name]
        else
                hostname = Socket.gethostbyname(name)[0] rescue name
                return @servers.values.find { |s| s.host == hostname }
        end
        
        # No server was found for this name
        return nil
end
Also aliased as: []
run!(options = {}) click to toggle source

Run the backup process for all servers and directories specified.

# File lib/lsync/script.rb, line 151
def run!(options = {})
        start_time = Time.now

        logger.info "===== Starting backup at #{start_time} ====="

        # We buffer the log data so that if there is an error it is available to the notification sub-system
        @log = StringIO.new
        local_logger = Logger.new(@log)
        local_logger.formatter = MinimalLogFormat.new
        logger = @logger.tee(local_logger)

        master = find_master_server
        current = find_current_server

        if master.local?
                logger.info "We are the master server..."
        else
                logger.info "We are not the master server..."
                logger.info "Master server is #{@master}..."
        end

        master_controller = ServerController.new(self, logger, master)

        self.try(master_controller) do
                # This allows events to run on the master server if specified, before running any backups.
                master.try(master_controller) do
                        method.try(master_controller) do
                                logger.info "Running backups for server #{current}..."

                                run_backups!(master, current, logger, options)
                        end
                end
        end

        end_time = Time.now
        logger.info "[Time]: (#{end_time - start_time}s)."
        logger.info "===== Finished backup at #{end_time} ====="
end
server(name) { |server| ... } click to toggle source

Register a server with the backup script.

# File lib/lsync/script.rb, line 104
def server(name)
        case name
        when Symbol
                host = "localhost"
        else
                host = name.to_s
        end

        server = Server.new(host)

        yield server if block_given?

        @servers[name] = server
end

Protected Instance Methods

run_backups!(master, current, logger, options = {}) click to toggle source

This function runs the method for each directory and server combination specified.

# File lib/lsync/script.rb, line 193
def run_backups!(master, current, logger, options = {})
        @servers.each do |name, server|
                # S is always a data destination, therefore s can't be @master
                next if server == master

                next unless server.role?(options[:role] || :any)

                server_controller = CopyController.new(self, logger, master, server, current)

                # Skip servers that shouldn't be processed
                unless @method.should_run?(server_controller)
                        logger.info "===== Skipping ====="
                        logger.info "[Master]: #{master}"
                        logger.info "[Target]: #{server}"
                        next
                end

                logger.info "===== Processing ====="
                logger.info "[Master]: #{master}"
                logger.info "[Target]: #{server}"
                
                server.try(server_controller) do
                        @directories.each do |directory|
                                directory_controller = DirectoryController.new(self, logger, master, server, current, directory)

                                logger.info "[Directory]: #{directory}"
                                directory.try(directory_controller) do
                                        method.run(directory_controller)
                                end
                        end
                end
        end
end