diff options
Diffstat (limited to 'dev-util/svnreplicate/files/svnreplicate-59')
-rwxr-xr-x | dev-util/svnreplicate/files/svnreplicate-59 | 997 |
1 files changed, 0 insertions, 997 deletions
diff --git a/dev-util/svnreplicate/files/svnreplicate-59 b/dev-util/svnreplicate/files/svnreplicate-59 deleted file mode 100755 index dd9b176..0000000 --- a/dev-util/svnreplicate/files/svnreplicate-59 +++ /dev/null @@ -1,997 +0,0 @@ -#!/usr/bin/perl - -use Sys::Syslog; -use Getopt::Long; -use IPC::Open2; - -Getopt::Long::Configure ("bundling"); - -push @INC, "/etc/svnreplicate"; -push @INC, "/etc"; -# push @INC, "/root/svntest/src/svnreplicate"; # remove after debug -# my $dot = pop @INC; -# push @INC, $dot; - -require "svnreplicate.conf"; - -my $local_rep = '?'; - -# -# debug levels -# - -$LOG_EMERG = 'emerg'; -$LOG_ALERT = 'alert'; -$LOG_CRIT = 'crit'; -$LOG_ERR = 'err'; -$LOG_WARN = 'warning'; -$LOG_NOTICE = 'notice'; -$LOG_INFO = 'info'; -$LOG_DEBUG = 'debug'; - -# -# helper functions -# - -sub help() -{ - print "\nThis command replicates subversion repository while allowing commits on\n"; - print "all nodes as long as the nodes can reach the master node.\n"; - print "\nUsage: svnreplicate [--help|cmd [args]]\n"; - print "\n cmd can be:\n\n"; - print "\thook-start\t\t<hook-rep>\n"; - print "\thook-start-commit\t<hook-rep> <commit-user>\n"; - print "\thook-pre-commit\t\t<hook-rep> <commit-txn>\n"; - print "\thook-post-commit\t<hook-rep> <commit-rev>\n"; - print "\tsync\t\t\t<caller-rep> <callee-rep> <caller-youngest-rev>\n"; - print "\tlock-sync\t\t<caller-rep> <callee-rep> <caller-youngest-rev>\n"; - print "\tcommit-unlock\t\t<caller-rep> <callee-rep> <y.-rev> <oldest-rev>\n"; - print "\n"; - print "The command and it's arguments can be supplied on the command line or\n"; - print "on the first line of standard input\n"; - print "\n"; - exit(1); -} - -sub logger -{ - my $level = shift; - my @args = @_; - my $text = join(//, @args); - - syslog($level, "[$local_rep] $text") if ($DO_LOG_SYSLOG); - if ($DO_LOG_FILE) - { - if (open(L, ">> $LOG_FILE")) - { - my $date = `date '+%Y-%m-%d %X'`; chomp($date); - print L $date . " [$local_rep:$level] " . $text . "\n"; - } - else - { - logger(LOG_ALERT, "failed to open log file $LOG_FILE!"); - $DO_LOG_FILE = 0; - } - } - return; -} - -sub exit_logger -{ - my $code = shift; - my $level = shift; - my @args = @_; - my $text = join(//, @args); - - logger($level, @args); - logger(LOG_DEBUG, "--- exiting pid $$"); - exit($code); -} - -sub lock_pid -{ - my $rep = shift; - my $PID_FILE = $PID_PATH . "/svnreplicate." . $rep . ".pid"; - - stat($PID_FILE); - if (-f _ && -r _) - { - my $p = ''; - - if (open(P, "< $PID_FILE")) - { - $p = <P>; - chomp($p); - close(P); - } - else - { - logger(LOG_ALERT, "failed to open pid file '$PID_FILE'!"); - return -2; - } - - `ps $p | grep -v PID`; - if (! /^$/) - { - logger(LOG_WARNING, "failed to lock pid file '$PID_FILE'!"); - logger(LOG_WARNING, "process with pid $p is already running!"); - return $pid; - } - } - elsif (-f _) - { - logger(LOG_ALERT, "failed to read pid file '$PID_FILE'!"); - return -2; - } - - if (open(F, "> $PID_FILE")) - { - print F "$$\n"; - close(F); - - my $p = ''; - if (open(P, "< $PID_FILE")) - { - $p = <P>; - chomp($p); - close(P); - } - else - { - logger(LOG_ALERT, "failed to open pid file '$PID_FILE'!"); - return -2; - } - - if ($p != $$) - { - logger(LOG_WARNING, "failed to lock pid file '$PID_FILE'!"); - logger(LOG_WARNING, "process with pid $p is already running!"); - return $p; - } - - logger(LOG_DEBUG, "successfully locked pid file for repository '" . $rep . "'"); - return 0; - } - else - { - logger(LOG_ALERT, "failed to write pid file '$PID_FILE'"); - return -1; - } - - return -3; -} - -sub unlock_pid -{ - my $rep = shift; - my $PID_FILE = $PID_PATH . "/svnreplicate." . $rep . ".pid"; - - unlink($PID_FILE); - logger(LOG_DEBUG, "successfully removed pid file for repository '" . $rep . "'"); -} - -sub lock_server -{ - my $rep = shift; - my $PID_FILE = $PID_PATH . "/svnreplicate.lock." . $rep . ".pid"; - - stat($PID_FILE); - if (-f _ && -r _) - { - my $p = ''; - - if (open(F, "< $PID_FILE")) - { - $p = <F>; - chomp($p); - close(F); - } - else - { - logger(LOG_ALERT, "failed to open server lock file '$PID_FILE'!"); - return -2; - } - - `ps $p | grep -v PID`; - if (! /^$/) - { - logger(LOG_WARNING, "failed to lock server lock file '$PID_FILE'!"); - logger(LOG_WARNING, "process with pid $p is already running!"); - return $p; - } - } - elsif (-f _) - { - logger(LOG_ALERT, "failed to read server lock file '$PID_FILE'!"); - return -2; - } - - if (open(F, "> $PID_FILE")) - { - print F "$$\n"; - close(F); - - my $p = ''; - if (open(F, "< $PID_FILE")) - { - $p = <F>; - chomp($p); - close(F); - } - else - { - logger(LOG_ALERT, "failed to open server lock file '$PID_FILE'!"); - return -2; - } - - if ($p != $$) - { - logger(LOG_WARNING, "failed to lock server lock file '$PID_FILE'!"); - logger(LOG_WARNING, "process with pid $p is already running!"); - return $p; - } - - logger(LOG_DEBUG, "successfully locked server lock file for repository '" . $rep . "'"); - return 0; - } - else - { - logger(LOG_ALERT, "failed to write server lock file '$PID_FILE'"); - return -1; - } - - return -3; -} - -sub unlock_server -{ - my $rep = shift; - my $PID_FILE = $PID_PATH . "/svnreplicate.lock." . $rep . ".pid"; - - unlink($PID_FILE); - logger(LOG_DEBUG, "successfully removed server lock file for repository '" . $rep . "'"); -} - -# -# command parsing -# - -sub cmd_parse() -{ - my %res = (); - - if ($#ARGV >= 0) - { - my $args = join(' ', @ARGV); - - logger(LOG_DEBUG, "cmd is '$args'"); - - if ($ARGV[0] =~ /^(hook-.+)$/) - { - # a hook-* command - $res{'cmd'} = $ARGV[0]; - $res{'hook'} = 1; - $res{'local-rep-name'} = $rep_path2rep{$ARGV[1]}; - $res{'local-rep'} = $ARGV[1]; - $res{'hook-rep'} = $ARGV[1]; - $res{'hook-txn'} = $ARGV[2] if ($ARGV[0] =~ /^hook-pre-commit$/); - $res{'hook-user'} = $ARGV[2] if ($ARGV[0] =~ /^hook-start-commit$/); - $res{'hook-rev'} = $ARGV[2] if ($ARGV[0] =~ /^hook-post-commit$/); - } - elsif ($ARGV[0] eq 'sync') - { - $res{'cmd'} = $ARGV[0]; - $res{'hook'} = 0; - $res{'local-rep-name'} = $rep_path2rep{$ARGV[2]}; - $res{'local-rep'} = $ARGV[2]; - $res{'remote-rep'} = $ARGV[1]; - $res{'rev-youngest'} = $ARGV[3]; - } - elsif ($ARGV[0] eq 'lock-sync') - { - $res{'cmd'} = $ARGV[0]; - $res{'hook'} = 0; - $res{'local-rep-name'} = $rep_path2rep{$ARGV[2]}; - $res{'local-rep'} = $ARGV[2]; - $res{'remote-rep'} = $ARGV[1]; - $res{'rev-youngest'} = $ARGV[3]; - } - elsif ($ARGV[0] eq 'commit-unlock') - { - $res{'cmd'} = $ARGV[0]; - $res{'hook'} = 0; - $res{'local-rep-name'} = $rep_path2rep{$ARGV[2]}; - $res{'local-rep'} = $ARGV[2]; - $res{'remote-rep'} = $ARGV[1]; - $res{'rev-youngest'} = $ARGV[3]; - $res{'rev-oldest'} = $ARGV[4]; - } - elsif ($ARGV[0] eq 'slave-commit') - { - $res{'cmd'} = $ARGV[0]; - $res{'hook'} = 0; - $res{'local-rep-name'} = $rep_path2rep{$ARGV[2]}; - $res{'local-rep'} = $ARGV[2]; - $res{'remote-rep'} = $ARGV[1]; - $res{'rev-youngest'} = $ARGV[3]; - $res{'rev-oldest'} = $ARGV[4]; - } - } - else - { - my $args = <STDIN>; chomp($args); - - logger(LOG_DEBUG, "stdin command found!"); - logger(LOG_DEBUG, "cmd is '$args'"); - - if ($args =~ /^([^\s]+) ([^\s]+)$/) - { - if ($1 eq "hook-start") - { - $res{'cmd'} = $1; - $res{'hook'} = 1; - $res{'local-rep-name'} = $rep_path2rep{$2}; - $res{'local-rep'} = $2; - $res{'hook-rep'} = $2; - } - } - elsif ($args =~ /^([^\s]+) ([^\s]+) ([^\s]+)$/) - { - if ($1 eq 'hook-pre-commit' || $1 eq 'hook-start-commit' || $1 eq 'hook-post-commit') - { - $res{'cmd'} = $1; - $res{'hook'} = 1; - $res{'local-rep-name'} = $rep_path2rep{$2}; - $res{'local-rep'} = $2; - $res{'hook-rep'} = $2; - $res{'hook-txn'} = $3 if ($1 =~ /^hook-pre-commit$/); - $res{'hook-user'} = $3 if ($1 =~ /^hook-start-commit$/); - $res{'hook-rev'} = $3 if ($1 =~ /^hook-post-commit$/); - } - } - elsif ($args =~ /^([^\s]+) ([^\s]+) ([^\s]+) ([^\s]+)$/) - { - if ($1 eq 'sync') - { - $res{'cmd'} = $1; - $res{'hook'} = 0; - $res{'local-rep-name'} = $rep_path2rep{$2}; - $res{'local-rep'} = $2; - $res{'remote-rep'} = $3; - $res{'remote-rev-youngest'} = $4; - } - elsif ($1 eq 'lock-sync') - { - $res{'cmd'} = $1; - $res{'hook'} = 0; - $res{'local-rep-name'} = $rep_path2rep{$2}; - $res{'local-rep'} = $2; - $res{'remote-rep'} = $3; - $res{'remote-rev-youngest'} = $4; - } - } - elsif ($args =~ /^([^\s]+) ([^\s]+) ([^\s]+) ([^\s]+) ([^\s]+)$/) - { - if ($1 eq 'commit-unlock') - { - $res{'cmd'} = $1; - $res{'hook'} = 0; - $res{'local-rep-name'} = $rep_path2rep{$2}; - $res{'local-rep'} = $2; - $res{'remote-rep'} = $3; - $res{'rev-youngest'} = $4; - $res{'rev-oldest'} = $5; - } - elsif ($1 eq 'slave-commit') - { - $res{'cmd'} = $1; - $res{'hook'} = 0; - $res{'local-rep-name'} = $rep_path2rep{$2}; - $res{'local-rep'} = $2; - $res{'remote-rep'} = $3; - $res{'rev-youngest'} = $4; - $res{'rev-oldest'} = $5; - } - } - } - - $local_rep = $res{'local-rep-name'}; - - return \%res; -} - -sub cmd_dump -{ - my $cmdref = shift; - my %cmd = %$cmdref; - my @keys = sort keys %cmd; - - if ($#keys < 0) - { - logger(LOG_ALERT, "could not parse command!"); - exit_logger(1, LOG_ALERT, "cmd = '" . join(' ', @ARGV) . "'"); - } - - foreach $k (@keys) - { - logger(LOG_INFO, "[" . $k . "] = " . $cmd{$k}); - } - - return; -} - -sub svn_dump -{ - my $cmdref = shift; - my %cmd = %$cmdref; - my $to = `$cmd_svnlook youngest $rep_repl_path{$cmd{'local-rep-name'}}`; chomp($to); - my $from = $to; $from = $cmd{'remote-rev-youngest'} + 1 if ($cmd{'remote-rev-youngest'} =~ /^[0123456789]+$/); - my $res = ''; - - if ($from <= $to) - { - logger(LOG_INFO, "svn_dump() dump of repository '" . $cmd{'local-rep-name'} . "'"); - logger(LOG_INFO, "svn_dump() dumping revision " . $from . " to " . $to); - - # dump actual commit from this repository to %cmd - - my $dcmd = $cmd_svnadmin . " dump " . $rep_repl_path{$cmd{'local-rep-name'}} . " -r " . $from . ":" . $to . " --incremental 2>>" . $rep_repl_log{$cmd{'local-rep-name'}}; - - logger(LOG_DEBUG, "svn_dump() using '" . $dcmd . "'"); - - $res = "DUMP-DATA " . $from . " " . $to . "\n"; - if (open F, "$dcmd |") - { - while(<F>) - { - $res = $res . $_; - } - close(F); - - logger(LOG_INFO, "svn_dump() successfully dumped revisions $from to $to"); - } - else - { - exit_logger(0, LOG_ALERT, "svn_dump() failed to dump repository '" . $cmd{'local-rep'} . "'"); - } - } - else - { - logger(LOG_INFO, "svn_dump() no need to dump anything. both repository are in sync!"); - logger(LOG_INFO, "svn_dump() youngest revision is $to"); - $res = "DUMP-DATA " . $from . " " . $to . "\n"; - } - - $$cmdref{'dump'} = $res; - $$cmdref{'dump-rev-oldest'} = $from; - $$cmdref{'dump-rev-youngest'} = $to; - - return; -} - -sub svn_load -{ - my $cmdref = shift; - my %cmd = %$cmdref; - my $from = $cmd{'dump-rev-oldest'}; - my $to = $cmd{'dump-rev-youngest'}; - my $dump = $cmd{'dump'}; - - if ($from <= $to) - { - # load commit-dump from %cmd to this repository - - my $rev = `$cmd_svnlook youngest $rep_repl_path{$cmd{'local-rep-name'}}`; chomp($rev); - - logger(LOG_INFO, "svn_load() load of repository '" . $cmd{'local-rep-name'} . "'"); - logger(LOG_DEBUG, "svn_load() youngest revision before load is " . $rev); - logger(LOG_INFO, "svn_load() loading revisions " . $from . " to " . $to); - - my $lcmd = $cmd_svnadmin . " load " . $rep_repl_path{$cmd{'local-rep-name'}} . " >>" . $rep_repl_log{$cmd{'local-rep-name'}} . " 2>&1"; - - logger(LOG_DEBUG, "svn_load() using '" . $lcmd . "'"); - - if (open(F, "| $lcmd")) - { - print F $dump; - close(F); - } - - my $rev = `$cmd_svnlook youngest $rep_repl_path{$cmd{'local-rep-name'}}`; chomp($rev); - - logger(LOG_DEBUG, "svn_load() youngest revision after load is " . $rev); - - if ($rev ne $to) - { - exit_logger(1, LOG_ALERT, "svn_load() loading revisions " . $from . " to " . $to . " failed! youngest revision is " . $rev); - } - - logger(LOG_INFO, "svn_load() loading succeeded successfully!"); - } - else - { - logger(LOG_INFO, "svn_load() nothing to load. both repositories are in sync!"); - } -} - -sub dump_stdout -{ - my $cmdref = shift; - my %cmd = %$cmdref; - - print $cmd{'dump'} . "\n"; -} - -sub load_stdin -{ - my $cmdref = shift; - my %cmd = %$cmdref; - - my $dump = ''; - my $lines = 0; - my $res = <STDIN>; - - while(<STDIN>) - { - $dump = $dump . $_; - $lines++; - } - - if ($res =~ /^DUMP-DATA (.+) (.+)$/) - { - logger(LOG_INFO, "load_stdin() received repository dump [$lines lines] from repository '" . $rep_path2rep{$cmd{'remote-rep'}} . "'"); - $$cmdref{'dump'} = $dump; - $$cmdref{'dump-rev-oldest'} = $1; - $$cmdref{'dump-rev-youngest'} = $2; - } - else - { - exit_logger(1, LOG_ALERT, "load_stdin() failed to read dump from remote repository"); - } -} - -sub call_sync -{ - my $cmdref = shift; - my %cmd = %$cmdref; - - # call sync in master repository and store dump in %cmd - - logger(LOG_DEBUG, "call_sync() for master " . $rep_master . " called"); - - my $rev = `$cmd_svnlook youngest $rep_repl_path{$cmd{'local-rep-name'}}`; chomp($rev); - my $rcall = $rep_repl_comm{$cmd{'local-rep-name'}} . " " . $rep_repl_host{$rep_master} . " " . $rep_repl_script{$rep_master}; - my $rcmd = "sync " . $rep_repl_path{$rep_master} . " " . $cmd{'local-rep'} . " " . $rev; - - logger(LOG_INFO, "call_sync() found youngest revision is $rev"); - logger(LOG_INFO, "call_sync() sending command '" . $rcmd . "'"); - - if (open(F, "echo $rcmd | $rcall |")) - { - my $dump = ''; - my $lines = 0; - my $res = <F>; - - while(<F>) - { - $dump = $dump . $_; - $lines++; - } - close(F); - - if ($res =~ /^DUMP-DATA (.+) (.+)$/) - { - logger(LOG_INFO, "call_sync() received repository dump [$lines lines] from repository '" . $rep_master . "'"); - $$cmdref{'dump'} = $dump; - $$cmdref{'dump-rev-oldest'} = $1; - $$cmdref{'dump-rev-youngest'} = $2; - } - else - { - exit_logger(1, LOG_ALERT, "call_sync() failed to call 'sync' on remote repository"); - } - } - else - { - exit_logger(0, LOG_ALERT, "call_sync() failed to connect to master!"); - } -} - -sub call_lock_sync -{ - my $cmdref = shift; - my %cmd = %$cmdref; - - # call lock-sync in master repository and store dump in %cmd - - logger(LOG_DEBUG, "call_lock_sync() for master " . $rep_master . " called"); - - my $rev = `$cmd_svnlook youngest $rep_repl_path{$cmd{'local-rep-name'}}`; chomp($rev); - my $rcall = $rep_repl_comm{$cmd{'local-rep-name'}} . " " . $rep_repl_host{$rep_master} . " " . $rep_repl_script{$rep_master}; - my $rcmd = "lock-sync " . $rep_repl_path{$rep_master} . " " . $cmd{'local-rep'} . " " . $rev; - - logger(LOG_INFO, "call_lock_sync() found youngest revision is $rev"); - logger(LOG_INFO, "call_lock_sync() sending command '" . $rcmd . "'"); - - if (open(F, "echo $rcmd | $rcall |")) - { - my $dump = ''; - my $lines = 0; - my $res = <F>; - - while(<F>) - { - $dump = $dump . $_; - $lines++; - } - close(F); - - if ($res =~ /^DUMP-DATA (.+) (.+)$/) - { - logger(LOG_INFO, "call_lock_sync() received repository dump [$lines lines] from repository '" . $rep_master . "'"); - $$cmdref{'dump'} = $dump; - $$cmdref{'dump-rev-oldest'} = $1; - $$cmdref{'dump-rev-youngest'} = $2; - } - else - { - exit_logger(1, LOG_ALERT, "call_lock_sync() failed to call 'lock-sync' on remote repository"); - } - } - else - { - exit_logger(0, LOG_ALERT, "call_lock_sync() failed to connect to master!"); - } -} - -sub call_commit_unlock -{ - my $cmdref = shift; - my %cmd = %$cmdref; - - # call commit-unlock in master repository and send dump from %cmd - - logger(LOG_DEBUG, "call_commit_unlock() for master '" . $rep_master . "' called"); - - my $rev = `$cmd_svnlook youngest $rep_repl_path{$cmd{'local-rep-name'}}`; chomp($rev); -# my $rcall = $rep_repl_comm{$cmd{'local-rep-name'}} . " " . $rep_repl_host{$rep_master} . " " . $rep_repl_script{$rep_master}; - my $rcall = $rep_repl_comm{$rep_master} . " " . $rep_repl_host{$rep_master} . " " . $rep_repl_script{$rep_master}; - my $rcmd = "commit-unlock " . $rep_repl_path{$rep_master} . " " . $cmd{'local-rep'} . " " . $rev . " " . $rev; - - logger(LOG_INFO, "call_commit_unlock() found youngest revision is $rev"); - logger(LOG_INFO, "call_commit_unlock() sending command '" . $rcmd . "'"); - - if (open2(R, W, "$rcall")) - { - my $dump = ''; - my $lines = 0; - - print W $rcmd . "\n"; - print W $cmd{'dump'}; - close(W); - - my $res = <R>; chomp($res); - close(R); - - if (($res =~ /^OK (.+)$/) && ($1 eq $cmd{'dump-rev-youngest'})) - { - logger(LOG_INFO, "call_commit_unlock() successfully sent local repository dump to repository '" . $rep_master . "'"); - } - else - { - exit_logger(1, LOG_ALERT, "call_commit_unlock() failed to call 'commit_unlock' on remote repository"); - } - } - else - { - exit_logger(1, LOG_ALERT, "call_commit_unlock() failed to connect to master!"); - } -} - -sub call_slave_commit -{ - my $cmdref = shift; - my %cmd = %$cmdref; - my $rep_slave = shift; - - # call slave-commit in master repository and send dump from %cmd - - logger(LOG_DEBUG, "call_slave_commit() on slave '" . $rep_slave . "' called"); - - my $rev = `$cmd_svnlook youngest $rep_repl_path{$cmd{'local-rep-name'}}`; chomp($rev); - my $rcall = $rep_repl_comm{$rep_slave} . " " . $rep_repl_host{$rep_slave} . " " . $rep_repl_script{$rep_slave}; - my $rcmd = "slave-commit " . $rep_repl_path{$rep_slave} . " " .$rep_repl_path{$rep_master} . " " . $rev . " " . $rev; - - logger(LOG_INFO, "call_slave_commit() found youngest revision is $rev"); - logger(LOG_INFO, "call_slave_commit() sending command '" . $rcmd . "'"); - - if (open2(R, W, "$rcall")) - { - my $dump = ''; - my $lines = 0; - - print W $rcmd . "\n"; - print W $cmd{'dump'}; - close(W); - - my $res = <R>; chomp($res); - close(R); - - if (($res =~ /^OK (.+)$/) && ($1 eq $cmd{'dump-rev-youngest'})) - { - logger(LOG_INFO, "call_slave_commit() successfully sent local repository dump to repository '" . $rep_master . "'"); - } - else - { - logger(LOG_WARNING, "call_slave_commit() failed to call 'slave-commit' on remote repository"); - } - } - else - { - logger(LOG_WARNING, "call_slave_commit() failed to connect to slave!"); - } -} - -sub exec_hook_start -{ - my $cmdref = shift; - my %cmd = %$cmdref; - my $lrep = $cmd{'local-rep-name'}; - - logger(LOG_DEBUG, "hook_start() called for repository '$lrep'"); - - # check if this is the master - - if ($rep_type{$lrep} eq "MASTER") - { - logger(LOG_DEBUG, "hook_start() this is the master server, nothing to do"); - return 0; - } - - # this is a slave repository, we need to sync with the master - - call_sync($cmdref); - - # load the master's dump - - svn_load($cmdref); -} - -sub exec_hook_start_commit -{ - my $cmdref = shift; - my %cmd = %$cmdref; - my $lrep = $cmd{'local-rep-name'}; - - logger(LOG_DEBUG, "hook_start_commit() called for repository '$lrep'"); - - # check if this is the master - - if ($rep_type{$lrep} eq "MASTER") - { - exit_logger(0, LOG_DEBUG, "hook_start_commit() this is the master server, nothing to do"); - } - - # this is a slave repository, we need to lock-sync with the master - - call_lock_sync($cmdref); - - # load the master's dump - - svn_load($cmdref); -} - -sub exec_hook_pre_commit -{ - my $cmdref = shift; - my %cmd = %$cmdref; - my $lrep = $cmd{'local-rep-name'}; - - logger(LOG_DEBUG, "hook_pre_commit() called for repository '$lrep'"); - - # check if this is the master - - if ($rep_type{$lrep} eq "MASTER") - { - exit_logger(0, LOG_DEBUG, "hook_pre_commit() this is the master server, nothing to do"); - } - - # this is a slave repository - - exit_logger(0, LOG_DEBUG, "hook_pre_commit() this is the slave server, nothing to do"); -} - -sub exec_hook_post_commit -{ - my $cmdref = shift; - my %cmd = %$cmdref; - my $lrep = $cmd{'local-rep-name'}; - - logger(LOG_DEBUG, "hook_post_commit() called for repository '$lrep'"); - - # check if this is the master - - if ($rep_type{$lrep} eq "MASTER") - { - logger(LOG_INFO, "updating slaves to newest master revision"); - - # this is a master repository, dump actual commit - - svn_dump($cmdref); - - # this is a master repository, we may call slave_commit on the slaves - - foreach $i (keys %rep_type) - { - next if ($i eq $rep_master); - call_slave_commit($cmdref, $i); - } - } - else - { - # this is a slave repository, dump actual commit - - svn_dump($cmdref); - - # this is a slave repository, we need to commit_unlock with the master - - call_commit_unlock($cmdref); - } -} - -sub exec_sync -{ - my $cmdref = shift; - my %cmd = %$cmdref; - my $lrep = $cmd{'local-rep-name'}; - - logger(LOG_DEBUG, "sync() called for for repository '$lrep'"); - - # dump needed revisions - - svn_dump($cmdref); - - # return dump - - dump_stdout($cmdref); -} - -sub exec_lock_sync -{ - my $cmdref = shift; - my %cmd = %$cmdref; - my $lrep = $cmd{'local-rep-name'}; - - logger(LOG_DEBUG, "lock_sync() called for repository '$lrep'"); - - # lock server - - while ((my $res = lock_server($cmd{'local-rep-name'})) != 0) - { - exit_logger(1, LOG_ALERT, "could not lock master repository '" . $cmd{'local-rep-name'} . "'!") if ($res < 0); - logger(LOG_WARNING, "master repository already locked!"); - exit_logger(1, LOG_WARNING, "detected instance with pid $res! could not lock master repository '" . $cmd{'local-rep-name'} . "'!"); - } - - # dump needed revisions and return them - - svn_dump($cmdref); - - # return dump - - dump_stdout($cmdref); -} - -sub exec_commit_unlock -{ - my $cmdref = shift; - my %cmd = %$cmdref; - my $lrep = $cmd{'local-rep-name'}; - - logger(LOG_DEBUG, "commit_unlock() called for repository '$lrep'"); - - # receive dumped revision - - load_stdin($cmdref); - - # load received dump - - svn_load($cmdref); - - # this is a master repository, we may call slave_commit on the slaves - - logger(LOG_INFO, "updating slaves to newest master revision"); - - foreach $i (keys %rep_type) - { - next if ($i eq $rep_master); - next if ($i eq $rep_path2rep{$cmd{'remote-rep'}}); - call_slave_commit($cmdref, $i); - } - - # unlock server - - unlock_server($cmd{'local-rep-name'}); - - # return result - my $rev = `$cmd_svnlook youngest $rep_repl_path{$cmd{'local-rep-name'}}`; chomp($rev); - - print "OK " . $rev . "\n"; -} - -sub exec_slave_commit -{ - my $cmdref = shift; - my %cmd = %$cmdref; - my $lrep = $cmd{'local-rep-name'}; - - logger(LOG_DEBUG, "slave_commit() called for repository '$lrep'"); - - # receive dumped revision - - load_stdin($cmdref); - - # load received dump - - svn_load($cmdref); - - # return result - my $rev = `$cmd_svnlook youngest $rep_repl_path{$cmd{'local-rep-name'}}`; chomp($rev); - - print "OK " . $rev . "\n"; -} - -sub cmd_execute -{ - my $cmdref = shift; - my %cmd = %$cmdref; - - # hook calls - - exec_hook_start($cmdref) if ($cmd{'cmd'} eq 'hook-start'); - exec_hook_start_commit($cmdref) if ($cmd{'cmd'} eq 'hook-start-commit'); - exec_hook_pre_commit($cmdref) if ($cmd{'cmd'} eq 'hook-pre-commit'); - exec_hook_post_commit($cmdref) if ($cmd{'cmd'} eq 'hook-post-commit'); - - # protocol calls - - exec_sync($cmdref) if ($cmd{'cmd'} eq 'sync'); - exec_lock_sync($cmdref) if ($cmd{'cmd'} eq 'lock-sync'); - exec_commit_unlock($cmdref) if ($cmd{'cmd'} eq 'commit-unlock'); - exec_slave_commit($cmdref) if ($cmd{'cmd'} eq 'slave-commit'); -} - -# -# main -# - -MAIN: -{ - help() if ($ARGV[0] eq "--help"); - - openlog('svnreplicate', 'cons,pid', 'user'); - logger(LOG_DEBUG, "--- startup with pid $$"); - - my $cmdref = cmd_parse(); - cmd_dump($cmdref); - - my %cmd = %$cmdref; - if ($cmd{'local-rep-name'} =~ /^$/) - { - exit_logger(1, LOG_ALERT, "unknown repository $cmd{'local-rep'}!"); - } - - while ((my $res = lock_pid($cmd{'local-rep-name'})) != 0) - { - exit_logger(1, LOG_ALERT, "could not lock pid file!") if ($res < 0); - logger(LOG_WARNING, "detected instance with pid $res! waiting..."); - sleep(30); - } - - logger(LOG_DEBUG, "found master repository is '" . $rep_master . "'"); - - cmd_execute($cmdref); - unlock_pid($cmd{'local-rep-name'}); - - exit_logger(0, LOG_DEBUG, "run successfully finished"); -} |