Phoenix.pm: Website Updates with Perl

Kevin Buettner kev at primenet.com
Tue Feb 8 22:04:38 CST 2000


On Feb 8,  4:53pm, Pablo Velasquez wrote:

> I was wondering if you've ever heard of some Perl site management script, 
> that does the following: allows you to keep a "test" copy of you website, 
> then when you press the magic button it updates any changed files to your 
> "real-production" machine.
> 
> I few years ago I worked with a company that used such a script, they 
> called it WebScript.pl

It's not written in perl, but take a look at

	http://samba.anu.edu.au/rsync/

This utility won't update and/or fix links, but it will move your
changed sources from one place to another *very* efficiently.  (And
your links shouldn't be a problem if you use relative links anyway.)

I started using this utility earlier this week to help me manage
development of some sources on some remote machines at work.  (Where
"remote" is in another state.) I've written a perl script to sync in
both directions.  First it attempts to fetch any new or updated files
from the remote machine.  Next it attempts to put any new/updated
files from the local machine to the remote.

This allows me to be fairly undisciplined and change files on both
sides.  So long as I don't make changes to the same file on both
sides, I won't be in trouble.  Below is my script; I've named the
script to something appropriate for the project that I'm working on
and have actually hardwired $REMOTE_SRC and $LOCAL_SRC to the appropriate
paths.  I also have $RSYNC_PATH set to the location of rsync in my
home directory.  (rsync is installed on the remote machine, but it
is a much older version than the one I'm using on the local machine
and I wanted to make sure that the protocols matched.)

I use ssh to transfer the files securely.  If you don't already have
ssh-agent managing your key data for you, it'll start one up and
prompt you for your passphrase prior to invoking the rsyncs.  The
reason for this is to avoid having to enter your passphrase more
than once.

If you give it command line arguments, these are interpreted as
paths relative to the main hierarchy to synchronize.  These can
be either actual filenames or directories somewhere within the
main hierarchy.

---sync-local-remote---
#!/usr/bin/perl -w

$REMOTE_SRC = "remote.host.com:/path/to/remote/src";
$LOCAL_SRC = "/path/to/local/src";
$RSYNC_PATH = "/usr/local/bin/rsync";

$ENV{RSYNC_RSH} = 'ssh';

if (!$ENV{SSH_AGENT_PID}) {
    my $agentdata = `ssh-agent -s`;
    die "Problem starting ssh-agent"	if (!defined($agentdata));
    my ($agent_pid)  = $agentdata =~ /^SSH_AGENT_PID=([^;]*);/m;
    my ($agent_sock) = $agentdata =~ /^SSH_AUTH_SOCK=([^;]*);/m;
    die "Can't fetch ssh agent environment variables"
					unless defined($agent_pid)
					    && defined($agent_sock);

    print "agent_pid=$agent_pid; agent_sock=$agent_sock\n";
    $ENV{SSH_AGENT_PID} = $agent_pid;
    $ENV{SSH_AUTH_SOCK} = $agent_sock;

    system("ssh-add");
    sleep(4);
}

if (@ARGV) {
    foreach $arg (@ARGV) {
	sync_dir("$REMOTE_SRC/$arg", "$LOCAL_SRC/$arg");
    }
}
else {
    sync_dir($REMOTE_SRC, $LOCAL_SRC);
}
system("ssh-agent -k");

sub sync_dir {
    my ($remote_src, $local_src) = @_;
    my $remote_dir = $remote_src;
    $remote_dir =~ s#/[^/]*$##;
    my $local_dir = $local_src;
    $local_dir =~ s#/[^/]*$##;
    system("rsync -avuz --exclude '*~' --rsync-path=$RSYNC_PATH $remote_src $local_dir");
    system("rsync -Cavuz --exclude '*~' --rsync-path=$RSYNC_PATH $local_src $remote_dir");
}
--- end sync-local-remote ---

-- 
Kevin Buettner
kev at primenet.com, kevinb at redhat.com



More information about the Phoenix-pm mailing list