App-MBUtiny

 view release on metacpan or  search on metacpan

lib/App/MBUtiny/Collector.pm  view on Meta::CPAN

=cut

use vars qw/ $VERSION @EXPORT @EXPORT_OK /;
$VERSION = '1.03';

use Carp;
use CTK::ConfGenUtil;
use CTK::TFVals qw/ :ALL /;
use App::MBUtiny::Collector::DBI;
use App::MBUtiny::Collector::Client;
use App::MBUtiny::Util qw/hide_password/;

use constant {
        COLLECTOR_TYPES => {
                internal => 0,
                external => 1,
            },
    };

use base qw/Exporter/;
@EXPORT_OK = qw/

lib/App/MBUtiny/Collector.pm  view on Meta::CPAN

    my $collectors = $self->{collectors};
    return scalar(@$collectors) unless wantarray;
    return @$collectors;
}

sub check {
    my $self = shift;
    $self->error("");
    my $dbi = $self->dbi;
    return "" unless $self->collectors;
    my @ret = (); # List of DSN/URL_wo_password
    foreach my $collector ($self->collectors) {
        my $type = $collector->{type};
        if ($type eq 'internal') { # Internal
            if ($dbi->error) {
                $self->error($dbi->error());
                next;
            };
            push @ret, $dbi->dsn;
        } else { # External
            my $url = $collector->{url} || "";

lib/App/MBUtiny/Collector.pm  view on Meta::CPAN

                );
            unless ($client->status) {
                $self->error(join("%s\n%s", $client->transaction, $client->error));
                next;
            }
            my $check = $client->check;
            unless ($client->status) {
                $self->error(join("\n", $client->transaction, $client->error));
                next;
            }
            push @ret, hide_password($url);
        }
    }
    return @ret ? join("\n", @ret) : "";
}
sub fixup {
    my $self = shift;
    my %args = @_;
    $self->error("");
    my $dbi = $self->dbi;
    return "" unless $self->collectors;
    my @ret = (); # List of DSN/URL_wo_password

    foreach my $collector ($self->collectors) {
        my $type = $collector->{type};
        my $url = $collector->{url} || "";
        my $timeout = $collector->{timeout} || 0;
        my $comment = join("\n", grep {$_} ($args{comment}, $collector->{comment})) // "";
        my $op = $args{operation} || '';
        if ($op =~ /^(del)|(rem)/) { # Delete (op)
            if ($type eq 'internal') { # Internal
                $dbi->del(

lib/App/MBUtiny/Collector.pm  view on Meta::CPAN

                    next;
                }
                $client->del(
                    type    => _type2int($type),
                    name    => $args{name},
                    file    => $args{file},
                ) or do {
                    $self->error(join("\n", $client->transaction, $client->error));
                    next;
                };
                push @ret, hide_password($url);
            }
        } else { # Put (op)
            if ($type eq 'internal') { # Internal
                $dbi->add(
                    type    => _type2int($type),
                    name    => $args{name},
                    file    => $args{file},
                    size    => $args{size},
                    md5     => $args{md5},
                    sha1    => $args{sha1},

lib/App/MBUtiny/Collector.pm  view on Meta::CPAN

                    size    => $args{size},
                    md5     => $args{md5},
                    sha1    => $args{sha1},
                    status  => $args{status},
                    error   => $args{error},
                    comment => $comment,
                ) or do {
                    $self->error(join("\n", $client->transaction, $client->error));
                    next;
                };
                push @ret, hide_password($url);
            }
        }
    }

    return @ret ? join("\n", @ret) : "";
}
sub info {
    my $self = shift;
    my %args = @_;
    $self->error("");

lib/App/MBUtiny/Collector/DBI.pm  view on Meta::CPAN


Version 1.02

=head1 SYNOPSIS

    use App::MBUtiny::Collector::DBI;

    my $dbi = new App::MBUtiny::Collector::DBI(
        dsn => "DBI:mysql:database=mbutiny;host=mysql.example.com",
        user => "username",
        password => "password",
        set => [
            "RaiseError        0",
            "PrintError        0",
            "mysql_enable_utf8 1",
        ],
    );
    print STDERR $dbi->error if $dbi->error;

=head1 DESCRIPTION

Collector database interface

=head2 new

    my $dbi = new App::MBUtiny::Collector::DBI(
        dsn => "DBI:mysql:database=mbutiny;host=mysql.example.com",
        user => "username",
        password => "password",
        set => [
            "RaiseError        0",
            "PrintError        0",
            "mysql_enable_utf8 1",
        ],
    );

Creates DBI object

=head2 add

lib/App/MBUtiny/Collector/DBI.pm  view on Meta::CPAN


use constant {
    PREFIX                  => 'mbutiny',
    COLLECTOR_DB_FILENAME   => 'mbutiny.db',
    DEFAULT_ADDR            => '127.0.0.1',
    REPORT_PERIOD           => 24*60*60 + 1, # Yesterday + 1sec
    DEFAULT_DSN_MASK        => 'dbi:SQLite:dbname=%s',
    DEFAULT_DBI_ATTR        => {
            dsn         => '', # See DEFAULT_DSN_MASK
            user        => '',
            password    => '',
            set         => [
                    'RaiseError 0',
                    'PrintError 0',
                    'sqlite_unicode 1',
                ],
        },
};

use constant COLLECTOR_DDL  => <<'DDL';
CREATE TABLE IF NOT EXISTS mbutiny (

lib/App/MBUtiny/Collector/DBI.pm  view on Meta::CPAN

        }
    }
    my $file = $args{file} || COLLECTOR_DB_FILE();
    my $dsn = $args{dsn} || sprintf(DEFAULT_DSN_MASK, $file);

    # DB
    my $db = new CTK::DBI(
        -dsn    => $dsn,
        -debug  => 0,
        -username => $args{'user'},
        -password => $args{'password'},
        -attr     => _attr($args{'set'}),
        $args{timeout} ? (
            -timeout_connect => $args{timeout},
            -timeout_request => $args{timeout},
        ) : (),
        $args{user} ? () : (),
    );
    my $dbh = $db->connect if $db;

    # SQLite

lib/App/MBUtiny/ConfigSkel.pm  view on Meta::CPAN


<SendMail>
    To          to@example.com
    Cc          cc@example.com
    From        from@example.com

    # SMTP server
    SMTP        192.168.0.1
    # Authorization SMTP
    #SMTPuser   user
    #SMTPpass   password
</SendMail>

#
# Reporting flags
# Default: off
#
SendReport no
SendErrorReport no


lib/App/MBUtiny/ConfigSkel.pm  view on Meta::CPAN

##
## Collector
##
##############################################################################

#
# Collector definitions (multiple blocks can be specified)
# Default: local collector, see "collector database interface"
#
#<Collector>
#    URL         https://user:password@collector.example.com/collector.cgi
#    Comment     Collector said blah-blah-blah # Optional for collector
#    #TimeOut    180
#</Collector>


##############################################################################
##
## Collector database interface
##
## See also collector.cgi.sample file

lib/App/MBUtiny/ConfigSkel.pm  view on Meta::CPAN

#    DSN "dbi:SQLite:dbname=/var/lib/mbutiny/mbutiny.db"
#    Set RaiseError     0
#    Set PrintError     0
#    Set sqlite_unicode 1
#</DBI>

# MySQL example:
#<DBI>
#    DSN "DBI:mysql:database=mbutiny;host=mysql.example.com"
#    User username
#    Password password
#    Set RaiseError          0
#    Set PrintError          0
#    Set mysql_enable_utf8   1
#</DBI>

# Oracle Example
#<DBI>
#    DSN "dbi:Oracle:MYSID"
#    User username
#    Password password
#    Set RaiseError 0
#    Set PrintError 0
#</DBI>

Include hosts/*.conf

-----END FILE-----

-----BEGIN FILE-----
Name: foo.conf.sample

lib/App/MBUtiny/ConfigSkel.pm  view on Meta::CPAN

    #
    #<SendMail>
    #    To          to@example.com
    #    #Cc          cc@example.com
    #    #From        from@example.com
    #
    #    # SMTP server
    #    #SMTP        192.168.0.1
    #    # Authorization SMTP
    #    #SMTPuser   user
    #    #SMTPpass   password
    #</SendMail>

    #
    # Reporting flags (optional, see general config file)
    # Default: off
    #
    SendReport      no
    SendErrorReport yes

    #

lib/App/MBUtiny/ConfigSkel.pm  view on Meta::CPAN

    Trigger echo test > ./test/foo/test1.txt
    Trigger echo test > ./test/foo/test2.txt
    Trigger ls -la > ./test/foo/dir.lst
    Trigger test -d ./test/bar || mkdir ./test/bar
    Trigger echo test > ./test/bar/test1.txt
    Trigger echo test > ./test/bar/test2.txt
    Trigger echo test > ./test/bar/test3.txt
    Trigger ls -la > ./test/bar/dir.lst
    Trigger test -d ./test/bar/exc || mkdir ./test/bar/exc
    Trigger ls -la > ./test/bar/exc/dir.lst
    #Trigger mysqldump -f -h mysql.host.com -u user --port=3306 --password=password \
    #        --add-drop-table --default-character-set=utf8 \
    #        --databases databasename > ./test/databasename.sql

    #
    # Objects (source files and directories)
    #
    Object ./test/dir.lst
    Object ./test/foo

    #

lib/App/MBUtiny/ConfigSkel.pm  view on Meta::CPAN

        # Excluded object list (files and directories)
        Exclude test1.txt
        Exclude exc/dir.lst
    </Exclude>

    #
    # Collector definitions (multiple blocks can be specified)
    # Also see general config file
    #
    #<Collector>
    #    URL         https://user:password@collector.example.com/collector.cgi
    #    Comment     Collector said blah-blah-blah # Optional for collector
    #    #TimeOut    180
    #</Collector>

    #
    # Local storage (multiple blocks can be specified)
    #
    <Local>
        FixUP       off
        Localdir    ./test/mbutimy-local1

lib/App/MBUtiny/ConfigSkel.pm  view on Meta::CPAN

    #    Set         timeout  180
    #    Set         key_path  /path/to/private/file.key
    #    Comment     SFTP storage said blah-blah-blah # Optional for collector
    #</SFTP>

    #
    # FTP storage (multiple blocks can be specified)
    #
    #<FTP>
    #    FixUP       on
    #    URL         ftp://user:password@example.com:21/path/to/backup/dir1
    #    URL         ftp://user:password@example.com:21/path/to/backup/dir2
    #    Set         Passive 1
    #    Set         Debug 1
    #    Comment     FTP storage said blah-blah-blah # Optional for collector
    #</FTP>

    #
    # HTTP storage (multiple blocks can be specified)
    # See eg/server.cgi example file on CPAN web site
    #
    #<HTTP>
    #    FixUP       on
    #    URL         https://user:password@example.com/mbuserver/path/to/backup/dir1
    #    URL         https://user:password@example.com/mbuserver/to/backup/dir2
    #    Set         User-Agent TestServer/1.00
    #    Set         X-Test Foo Bar Baz
    #    Comment     HTTP storage said blah-blah-blah # Optional for collector
    #</HTTP>

    #
    # Command storage (multiple blocks can be specified)
    #
    #<Command>
    #    FixUP       on

lib/App/MBUtiny/Storage/FTP.pm  view on Meta::CPAN


=head1 VIRSION

Version 1.00

=head1 SYNOPSIS

  <Host "foo">
    <FTP>
        #FixUP   on
        URL     ftp://user:password@example.com:21/path/to/backup/dir1
        URL     ftp://user:password@example.com:21/path/to/backup/dir2
        Set     Passive 1
        Set     Debug 1
        Comment FTP storage said blah-blah-blah # Optional for collector
    </FTP>

    # . . .

  </Host>

=head1 DESCRIPTION

lib/App/MBUtiny/Storage/FTP.pm  view on Meta::CPAN


use vars qw/ $VERSION /;
$VERSION = '1.00';

use Storable qw/dclone/;
use Net::FTP;
use URI;
use List::Util qw/uniq/;
use CTK::ConfGenUtil;
use CTK::TFVals qw/ :ALL /;
use App::MBUtiny::Util qw/ node2anode set2attr hide_password filesize /;

use constant {
        STORAGE_SIGN => 'FTP',
    };

sub init {
    my $self = shift;
    $self->maybe::next::method();
    $self->storage_status(STORAGE_SIGN, -1);
    my $useftp = 0;

    my $ftp_nodes = dclone(node2anode(node($self->{host}, 'ftp')));
    #print explain($ftp_nodes), "\n";

    my %ftp_storages;
    foreach my $ftp_node (@$ftp_nodes) {
        my $urls = array($ftp_node, 'url') || [];
        my $attr = set2attr($ftp_node),
        my $cmnt = value($ftp_node, 'comment') || "";
        foreach my $url (@$urls) {
            my $url_wop = hide_password($url, 2);
            $ftp_storages{$url} = {
                    url     => $url,
                    url_wop => $url_wop,
                    attr    => $attr,
                    comment => join("\n", grep {$_} ($url_wop, $cmnt)),
                    fixup   => value($ftp_node, 'fixup') ? 1 : 0,
                };
            $useftp++;
        }
    }

lib/App/MBUtiny/Storage/FTP.pm  view on Meta::CPAN


        # Create object
        my $ftp = new Net::FTP($uri->host, %$attr) or do {
            my $err = sprintf("Can't connect to %s: %s", $url_wop, $@);
            $self->storage_status($sign, 0);
            push @test, [0, $url_wop, $err];
            next;
        };

        # Login
        $ftp->login($uri->user || "anonymous", $uri->password || "anonymous\@example.com") or do {
            my $err = sprintf("Can't login to %s: %s", $url_wop, $ftp->message);
            $self->storage_status($sign, 0);
            push @test, [0, $url_wop, $err];
            next;
        };

        # Change dir (chdir + mkdir)
        my $path = $uri->path // ""; $path =~ s/^\///;
        if (length($path)) {
            $ftp->cwd($path) or do {

lib/App/MBUtiny/Storage/FTP.pm  view on Meta::CPAN

        my $ostat = 1;

        # Create object
        my $ftp = new Net::FTP($uri->host, %$attr) or do {
            $self->error(sprintf("Can't connect to %s: %s", $url_wop, $@));
            $ostat = 0;
        };

        # Login
        if ($ostat) {
            $ftp->login($uri->user || "anonymous", $uri->password || "anonymous\@example.com") or do {
                $self->error(sprintf("Can't login to %s: %s", $url_wop, $ftp->message));
                $ostat = 0;
            };
        }

        # Change dir
        if ($ostat && length($path)) {
            $ftp->cwd($path) or do {
                $self->error(sprintf("Can't change directory %s on %s: %s", $path, $url_wop, $ftp->message));
                $ostat = 0;

lib/App/MBUtiny/Storage/FTP.pm  view on Meta::CPAN

        my $attr = dclone($storage->{attr});
        $attr->{Port} = $uri->port if $uri->port;

        # Create object
        my $ftp = new Net::FTP($uri->host, %$attr) or do {
            $self->error(sprintf("Can't connect to %s: %s", $url_wop, $@));
            next;
        };

        # Login
        $ftp->login($uri->user || "anonymous", $uri->password || "anonymous\@example.com") or do {
            $self->error(sprintf("Can't login to %s: %s", $url_wop, $ftp->message));
            $ftp->quit if $ftp; # Quit
            next;
        };

        # Change dir
        if (length($path)) {
            $ftp->cwd($path) or do {
                $self->error(sprintf("Can't change directory %s on %s: %s", $path, $url_wop, $ftp->message));
                $ftp->quit if $ftp; # Quit

lib/App/MBUtiny/Storage/FTP.pm  view on Meta::CPAN

        my $ostat = 1;

        # Create object
        my $ftp = new Net::FTP($uri->host, %$attr) or do {
            $self->error(sprintf("Can't connect to %s: %s", $url_wop, $@));
            $ostat = 0;
        };

        # Login
        if ($ostat) {
            $ftp->login($uri->user || "anonymous", $uri->password || "anonymous\@example.com") or do {
                $self->error(sprintf("Can't login to %s: %s", $storage->{url_wop}, $ftp->message));
                $ostat = 0;
            };
        }

        # Change dir
        if ($ostat && length($path)) {
            $ftp->cwd($path) or do {
                $self->error(sprintf("Can't change directory %s on %s: %s", $path, $url_wop, $ftp->message));
                $ostat = 0;

lib/App/MBUtiny/Storage/FTP.pm  view on Meta::CPAN

        my $ostat = 1;

        # Create object
        my $ftp = new Net::FTP($uri->host, %$attr) or do {
            $self->error(sprintf("Can't connect to %s: %s", $url_wop, $@));
            $ostat = 0;
        };

        # Login
        if ($ostat) {
            $ftp->login($uri->user || "anonymous", $uri->password || "anonymous\@example.com") or do {
                $self->error(sprintf("Can't login to %s: %s", $storage->{url_wop}, $ftp->message));
                $ostat = 0;
            };
        }

        # Change dir
        if ($ostat && length($path)) {
            $ftp->cwd($path) or do {
                $self->error(sprintf("Can't change directory %s on %s: %s", $path, $url_wop, $ftp->message));
                $ostat = 0;

lib/App/MBUtiny/Storage/HTTP.pm  view on Meta::CPAN


=head1 VIRSION

Version 1.00

=head1 SYNOPSIS

  <Host "foo">
    <HTTP>
        FixUP   on
        URL     https://user:password@example.com/mbuserver/foo/dir1
        URL     https://user:password@example.com/mbuserver/foo/dir2
        Set     User-Agent TestServer/1.00
        Set     X-Test Foo Bar Baz
        Comment HTTP storage said blah-blah-blah # Optional for collector
    </HTTP>

    # . . .

  </Host>

=head1 DESCRIPTION

lib/App/MBUtiny/Storage/HTTP.pm  view on Meta::CPAN

=cut

use vars qw/ $VERSION /;
$VERSION = '1.00';

use Storable qw/dclone/;
use URI;
use List::Util qw/uniq/;
use CTK::ConfGenUtil;
use CTK::TFVals qw/ :ALL /;
use App::MBUtiny::Util qw/ node2anode set2attr hide_password filesize /;

use constant {
        STORAGE_SIGN => 'HTTP',
    };

sub init {
    my $self = shift;
    $self->maybe::next::method();
    $self->storage_status(STORAGE_SIGN, -1);
    my $usehttp = 0;

lib/App/MBUtiny/Storage/HTTP.pm  view on Meta::CPAN

    my $http_nodes = dclone(node2anode(node($self->{host}, 'http')));
    #print explain($http_nodes), "\n";

    my %http_storages;
    foreach my $http_node (@$http_nodes) {
        my $urls = array($http_node, 'url') || [];
        my $attr = set2attr($http_node),
        my $timeout = uv2zero(value($http_node, 'timeout'));
        my $cmnt = value($http_node, 'comment') || "";
        foreach my $url (@$urls) {
            my $url_wop = hide_password($url, 2);
            $http_storages{$url} = {
                    url     => $url,
                    url_wop => $url_wop,
                    attr    => dclone($attr),
                    timeout => $timeout,
                    comment => join("\n", grep {$_} ($url_wop, $cmnt)),
                    fixup   => value($http_node, 'fixup') ? 1 : 0,
                };
            $usehttp++;
        }

lib/App/MBUtiny/Storage/SFTP.pm  view on Meta::CPAN


use vars qw/ $VERSION /;
$VERSION = '1.01';

use Storable qw/dclone/;
use Fcntl ':mode';
use URI;
use List::Util qw/uniq/;
use CTK::ConfGenUtil;
use CTK::TFVals qw/ :ALL /;
use App::MBUtiny::Util qw/ node2anode set2attr hide_password filesize /;

my $NET_SFTP_FOREIGN = 1; # Loaded!
my $NET_SFTP_FOREIGN_MESSAGE = "SFTP storage type is available";

eval { require Net::SFTP::Foreign; 1 } or do {
    $NET_SFTP_FOREIGN = 0;
    $NET_SFTP_FOREIGN_MESSAGE = "SFTP storage type is not available, Net::SFTP::Foreign is not installed or failed to load: $@";
};

use constant {

lib/App/MBUtiny/Storage/SFTP.pm  view on Meta::CPAN

    my $sftp_nodes = dclone(node2anode(node($self->{host}, 'sftp')));
    #print explain($ftp_nodes), "\n";

    my %sftp_storages;
    foreach my $sftp_node (@$sftp_nodes) {
        my $urls = array($sftp_node, 'url') || [];
        my $gattr = set2attr($sftp_node),
        my $cmnt = value($sftp_node, 'comment') || "";
        foreach my $url (@$urls) {
            my $uri = new URI($url);
            my $url_wop = hide_password($url, 2);
            my $attr = dclone($gattr);
               $attr->{host} = $uri->host;
               $attr->{port} = $uri->port if $uri->port;
               $attr->{user} = $uri->user if $uri->user;
               $attr->{password} = $uri->password if $uri->password;
            $sftp_storages{$url} = {
                    url     => $url,
                    url_wop => $url_wop,
                    path    => $uri->path,
                    attr    => $attr,
                    comment => join("\n", grep {$_} ($url_wop, $cmnt)),
                    fixup   => value($sftp_node, 'fixup') ? 1 : 0,
                };
            $usesftp++;
        }

lib/App/MBUtiny/Util.pm  view on Meta::CPAN


App::MBUtiny::Util - Internal utilities used by App::MBUtiny module

=head1 VERSION

Version 1.03

=head1 SYNOPSIS

    use App::MBUtiny::Util qw/
            filesize explain hide_password md5sum
            resolv sha1sum
        /;

    my $fsize = filesize( $file );
    print explain( $object );
    print hide_password('http://user:password@example.com');
    my $md5 = md5sum( $file );
    my $name = resolv( $IPv4 );
    my $sha1 = sha1sum( $filename );

=head1 DESCRIPTION

Internal utility functions

=over 8

lib/App/MBUtiny/Util.pm  view on Meta::CPAN

    print explain( $object );

Returns Data::Dumper dump

=item B<filesize>

    my $fsize = filesize( $file );

Returns file size

=item B<hide_password>

    print hide_password('http://user:password@example.com'); # 'http://user:*****@example.com'

Returns specified URL but without password

=item B<md5sum>

    my $md5 = md5sum( $filename );

See L<Digest::MD5>

=item B<node2anode>

    my $anode = node2anode({});

Returns array of nodes

=item B<parse_credentials>

    my ($user, $password) = parse_credentials( 'http://user:password@example.com' );
    my ($user, $password) = parse_credentials( new URI('http://user:password@example.com') );

Returns credentials pair by URL or URI object

=item B<resolv>

    my $name = resolv( $IPv4 );
    my $ip = resolv( $name );

Resolv ip to a hostname or hostname to ip. See L<Sys::Net/"resolv">, L<Socket/"inet_ntoa">
and L<Socket/"inet_aton">

lib/App/MBUtiny/Util.pm  view on Meta::CPAN

    DIRMODE => 0777,
};

use base qw/Exporter/;
@EXPORT_OK = qw/
        filesize sha1sum md5sum
        resolv
        explain
        xcopy
        node2anode set2attr
        parse_credentials hide_password
    /;

sub sha1sum {
    my $f = shift;
    my $sha1 = new Digest::SHA1;
    my $sum = '';
    return $sum unless -e $f;
    open( my $sha1_fh, '<', $f) or (carp("Can't open '$f': $!") && return $sum);
    if ($sha1_fh) {
        binmode($sha1_fh);

lib/App/MBUtiny/Util.pm  view on Meta::CPAN

sub parse_credentials {
    my $url = shift || return ();
    my $uri = (ref($url) eq 'URI') ? $url : URI->new($url);
    my $info = $uri->userinfo() // "";
    my $user = $info;
    my $pass = $info;
    $user =~ s/:.*//;
    $pass =~ s/^[^:]*://;
    return (uri_unescape($user // ''), uri_unescape($pass // ''));
}
sub hide_password {
    my $url = shift || return "";
    my $full = shift || 0; # 0 - starts, 1 - no_credentials; 2 - user_only
    my $uri = new URI($url);
    my ($u,$p) = parse_credentials($uri);
    return $url unless defined($p) && length($p);
    $uri->userinfo($full ? ($full == 1 ? undef : $u) : sprintf("%s:*****", $u));
    return $uri->canonical->as_string;
}
sub set2attr {
    my $in = shift;

share/manual_ru.pod  view on Meta::CPAN


Для случая извлечения файлов из арива:

    FILE     -- Имя архива (с расширением)
    DIRDST   -- Каталог для исзвлечения содержимого архивов
    DIROUT   -- = DIRDST

Работа с коллектором определяется множетвом секций Collector:

    <Collector>
        URL         https://user:password@collector.example.com/collector.cgi
        Comment     Collector said blah-blah-blah # Optional for collector
        TimeOut    180
    </Collector>

Блок содержит URL коллектора, комментария для сохранения на нем и таймаутом операций с коллектором

Этот блок может быть определен как в этом файле, так и в файлах определения хостов

    # MySQL example:
    <DBI>
        DSN "DBI:mysql:database=mbutiny;host=mysql.example.com"
        User username
        Password password
        Set RaiseError          0
        Set PrintError          0
        Set mysql_enable_utf8   1
    </DBI>

Секция DBI определяет настройки для соединения с базой данных локального коллектора

Поддерживаются базы: MySQL, PostgreSQL, SQLite, Oracle и некоторые другие SQL базы данных

=head2 hosts/foo.conf

share/manual_ru.pod  view on Meta::CPAN

одноименных глобальных определений.

    Trigger mkdir /tmp/test
    Trigger echo foo > /tmp/test/foo.txt

Триггеры. Это команды, выполняющиеся до того как будет сформирован конечный список обрабатываемых
объекстов (файлов и папок). Триггеры выполняются один за другим, но порядок их выполнения является
неопределнным. Для соблюдения требуемого порядкя следует использовать сложные команды или выносить
их в отдельные внешние скрипты.

    Trigger mysqldump -f -h mysql.host.com -u user --port=3306 --password=password \
            --add-drop-table --default-character-set=utf8 \
            --databases databasename > /tmp/test/databasename.sql

Данный пример иллюстрирует то как можно получать объект для резервного копирования в виде дампа
небольшой базы данных. Это и есть способ резервного копирования баз данных.

    Object /tmp/test/foo.txt
    Object /tmp/test/databasename.sql

или

share/manual_ru.pod  view on Meta::CPAN


Следует заметить, что значение директивы Target будет автоматически добавлено в список объектов
что не обеспечивают триггеры. Для каждого триггера (см. описание выше) нужно указывать свой объект
с помощью директивы Object, как это иллюстрируется в приведнном примере. Говоря о примере, следует
прокоментировать: первым шагом создается каталог /tmp/test, затем в каталог /tmp/test пишется
файл foo.txt с содержимым foo. Для того, чтобы сделать резервную копию файла /tmp/test/foo.txt
необходимо указать в качестве объекта либо сам файл /tmp/test/foo.txt либо всю папку /tmp/test.
Таким образом происходит связка триггеров с объектами.

    <Collector>
        URL        https://user:password@collector.example.com/mbutiny
        Comment    "My comment"
        TimeOut    180
    </Collector>

Данная секция определяет коллектор. Таких секций может быть несколько в рамках данного хоста.
Здесь URL - Адрес до хранилища (коллектора). Логин и пароль HTTP авторизации указывается
в теле URL. TimeOut - Таймаут. По умолчанию 180 секунд.

    <Local>
        FixUP       off

share/manual_ru.pod  view on Meta::CPAN

(резервные копии). Данных директив Localdir может быть несколько, тогда произойдёт копирование
бэкапа в различные локальные хранилища.

FixUP - Указывает выполнять фиксацию результата работы на коллекторе. может быть значение on или off

Comment - Комментарий для коллектора. Полезен для мониторинга и отладки. Настоятельно рекомендуем
не оставлять данную директиву пустой.

    <FTP>
        FixUP       on
        URL         ftp://user:password@example.com:21/path/to/backup/dir1
        URL         ftp://user:password@example.com:21/path/to/backup/dir2
        Set         Passive 1
        Set         Debug 1
        Comment     FTP storage said blah-blah-blah # Optional for collector
    </FTP>

Секция <FTP>...</FTP> определяет параметры удаленного FTP-хранилища. <FTP> секций может быть
несколько в рамках данного хоста. В этом случае выполнится работа над каждым из указанных
FTP-хранилищ. Директивы URL - определяют расположения хранилищ, когда как директивы FixUP и Comment
аналогичны по значению секции <Local>...</Local>. Директива Set устанавливает атрибуты соединения FTP

    <HTTP>
        FixUP      on
        URL        https://user:password@collector.example.com/mbuserver
        Comment    HTTP said blah-blah-blah for collector # Optional for collector
        TimeOut    180
    </HTTP>

Секция <HTTP>...</HTTP> определяет параметры удаленного HTTP-хранилища. Секций <HTTP> может быть
несколько. В этом случае выполнится работа над каждым HTTP-хранилищем. Не следует путать с
коллектором, секция <HTTP>...</HTTP> определяет отдельный канал для "заливки" файлов, когда как
коллектор регистрирует результат заливки. Хотя как правило и коллектор и хранилище HTTP находятся на
одном физическом сервере. URL - Адрес до хранилища (как и коллектора). FixUP - Указывает
выполнять фиксацию результата работы на коллекторе. Может аналогично FTP и Local секциям принимать



( run in 1.509 second using v1.01-cache-2.11-cpan-49f99fa48dc )