File Coverage

/.cpan/build/Simulation-Automate-1.0.1-vTiPpZ/blib/lib/Simulation/Automate/Remote.pm
Criterion Covered Total %
statement 13 69 18.8
branch 1 16 6.2
condition 1 6 16.6
subroutine 5 7 71.4
pod 0 3 0.0
total 20 101 19.8


line stmt bran cond sub pod time code
1             package Simulation::Automate::Remote;
2              
3 2     2   11 use vars qw( $VERSION );
  2         3  
  2         113  
4             $VERSION = "1.0.1";
5              
6             #################################################################################
7             # #
8             # Copyright (C) 2003 Wim Vanderbauwhede. All rights reserved. #
9             # This program is free software; you can redistribute it and/or modify it #
10             # under the same terms as Perl itself. #
11             # #
12             #################################################################################
13              
14             #headers
15             #
16             #Support module for remote runs
17             #This implementation requires:
18             #-ssh access to remote host
19             #-scp access to remote host
20             #-rsync server on the local host
21             #-or,alternatively, an NFS mounted home directory
22             #-as such, it'll probably only work on Linux and similar systems
23             #
24             #$Id$
25             #
26              
27             #usage:
28             #sub synsim {
29             #if(&check_for_remote_host==1){
30             #&run_on_remote_host()
31             #} else {
32             #&run_local(); # new name for sub synsim
33             #}
34             #}
35              
36 2     2   8 use strict;
  2         3  
  2         52  
37 2     2   8 use Cwd;
  2         2  
  2         178  
38 2     2   12 use Exporter;
  2         3  
  2         1990  
39              
40             @Simulation::Automate::Remote::ISA = qw(Exporter);
41             @Simulation::Automate::Remote::EXPORT = qw(
42             &check_for_remote_host
43             &run_on_remote_host
44             );
45             #------------------------------------------------------------------------------
46             sub check_for_remote_host {
47 1 50 33 1 0 88 (!@ARGV || $ARGV[@ARGV-1]=~/^\-/) && return 0; # not a host name
48 0           my $arg=@ARGV[@ARGV-1];
49              
50 0           my $remotehost='';
51 0 0 0       if(($arg!~/\.data/)&&($arg ne '-h')) {
52 0           $remotehost=pop @ARGV;
53 0           chomp(my $reply=`ssh $remotehost hostname -s 2>&1`);
54 0           my $remotehostshort=$remotehost;
55 0           $remotehostshort=~s/\..*$//;
56 0 0         if($reply ne $remotehostshort){
57 0           $remotehost.='FAIL';
58             }
59             }
60 0           return $remotehost; #0: local; 1: remote OK; 2: remote FAIL
61             } #END of check_for_remote_host
62             #------------------------------------------------------------------------------
63             sub run_on_remote_host {
64 0     0 0   my $remotehost=shift;
65 0 0         if( $remotehost=~s/FAIL//) {
66 0           die "Could not establish SSH connection to $remotehost\n";
67             }
68 0           my $datafile=@ARGV[@ARGV-1];
69 0           my $user=$ENV{USER};
70 0           chomp(my $localhost= `hostname -s 2>&1`);
71              
72 0           my $localsynsimpath=cwd();
73 0           my $rundir=$localsynsimpath;
74 0           my $homepath=$localsynsimpath;
75 0           $homepath=~s/$user.*$//;
76 0           $homepath.=$user;
77 0           $rundir=~s/^.*\///;
78 0           $localsynsimpath=~s/\w+$//; #dangerous!
79 0           $localsynsimpath=~s/.*$user\///; #dangerous!
80 0           $localsynsimpath=~s/\/$//;
81              
82 0           my $remotesynsimpath=$localsynsimpath;
83              
84 0           chomp(my $simdir=`egrep '^SIMTYPE' $datafile`);
85 0           $simdir=~s/SIMTYPE\s+:\s+//;
86 0           $simdir.='-'.$datafile;
87 0           $simdir=~s/\.data$//;
88              
89 0           my %simdata=(
90             '_DATAFILE'=>$datafile,
91             '_USER'=>$user,
92             '_LOCALHOST'=>$localhost,
93             '_RUNDIR'=>$rundir,
94             '_HOMEPATH'=>$homepath,
95             '_LOCALPATH'=>$localsynsimpath,
96             '_REMOTEPATH'=>$remotesynsimpath,
97             );
98              
99             #to run SynSim on a remote machine:
100 0           my $templfilename="TEMPLATES/synsim_remote.templ";
101 0 0         if(not -e $templfilename) {
102 0           &create_template($templfilename);
103             }
104 0           my $scriptname="synsim_remote.pl";
105 0           open (PL,">$scriptname");
106 0 0         open (TEMPL, "<$templfilename")||die "Can't open $templfilename\n";
107 0           while (my $line = ) {
108              
109 0           foreach my $key (keys %simdata) {
110 0 0         ($key!~/^_/) && next;
111 0           $line =~ s/$key(?!\w)/$simdata{$key}/g;
112             } # foreach
113 0           print PL $line;
114             } # while
115 0           close TEMPL;
116 0           close PL;
117              
118             # In case we use NFS, we should not scp or rsync.
119             #Simple check: create a file with the name of the localhost, and check for its existence over ssh
120 0           my $nfstest="$homepath/$localsynsimpath/$rundir/$localhost";
121 0           system("touch $nfstest");
122             #print STDERR qq(ssh $remotehost perl -e \'if ( -e "$nfstest" ){print "0"}else{print "1"}\');die;
123 0           my $nonfs=`ssh $remotehost "perl -e 'if ( -e qq($nfstest) ){print 0}else{print 1}'"`;
124 0 0         if($nonfs) {
125             #first time, or at start of run
126             #actually, the best way is to create synsim_remote.pl on the fly
127 0           system("scp $scriptname $remotehost:$scriptname");
128             #clean up;
129 0           unlink $scriptname;
130             #at start of synsim run
131 0           system("ssh $remotehost perl $scriptname");
132             #after synsim run, collect the data
133             #system("rsync -uva ${remotehost}::home/$user/$remotesynsimpath/$rundir/$simdir .");
134 0           system("scp -C -r ${remotehost}:/local/home/$user/$remotesynsimpath/$rundir/$simdir .");
135             } else {
136             # In case of NFS homedir, it's simpler:
137 0           system("ssh $remotehost 'cd $homepath/$localsynsimpath/$rundir && ./synsim -p -f $datafile'");
138              
139             }
140             } # END of run_on_remote_host
141             #------------------------------------------------------------------------------
142             sub create_template {
143 0     0 0   my $templfilename=shift;
144 0           open(TEMPL,">$templfilename");
145 0           print TEMPL <<'ENDTEMPL';
146             #!/usr/bin/perl -w
147             use strict;
148              
149             #to run SynSim on a remote machine:
150             #1. Needs a remote directory structure:
151             #-all relative to $homepath
152              
153             my $datafile='_DATAFILE';
154             my $user='_USER';
155             my $localhost='_LOCALHOST';
156             my $rundir='_RUNDIR';
157             my $localsynsimpath='_LOCALPATH';
158             my $remotesynsimpath='_REMOTEPATH';
159             my $homepath='_HOMEPATH';
160             $remotesynsimpath=~s/^\///;
161             $remotesynsimpath=~s/\/$//;
162             my @pathparts=split('/',$remotesynsimpath);
163             $remotesynsimpath='';
164             chdir "$homepath";
165             foreach my $part (@pathparts){
166             $remotesynsimpath.="$part/";
167             if (not -d "$remotesynsimpath"){mkdir "$remotesynsimpath"};
168             }
169             chdir "$remotesynsimpath";
170              
171             #Beware!
172             #This requires an rsync server with a module "home" on the local host;
173             #${localhost}::home/$user must correspond to $homepath!
174              
175             system("rsync -uva ${localhost}::home/$user/$localsynsimpath/Simulation .");
176              
177             if (not -d "$rundir"){mkdir "$rundir" or die $!};
178             chdir "$rundir";
179             #system("rsync -uva ${localhost}::home/$user/$localsynsimpath/$rundir/SOURCES .");
180             #system("rsync -uva ${localhost}::home/$user/$localsynsimpath/$rundir/TEMPLATES .");
181             #system("rsync -uva ${localhost}::home/$user/$localsynsimpath/$rundir/synsim .");
182             #system("rsync -uva ${localhost}::home/$user/$localsynsimpath/$rundir/$datafile .");
183             system('scp -r -C ${localhost}:$homepath/$user/$localsynsimpath/$rundir/SOURCES .");
184             system('scp -r -C ${localhost}:$homepath/$user/$localsynsimpath/$rundir/TEMPLATES .");
185             system('scp -r -C ${localhost}:$homepath/$user/$localsynsimpath/$rundir/synsim .");
186             system('scp -r -C ${localhost}:$homepath/$user/$localsynsimpath/$rundir/$datafile .");
187             #now run synsim
188             system("./synsim -v -p -f $datafile");
189              
190             #to get the results back, we'll scp from the other side
191              
192             ENDTEMPL
193             }
194             #------------------------------------------------------------------------------
195             1;