Subversion Repositories sysadmin_scripts

Rev

Rev 11 | Show entire file | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 11 Rev 12
Line 1... Line 1...
1
#! /usr/bin/env perl
1
#! /usr/bin/env perl
2
 
2
 
3
# archvieProjects.pl
3
# archiveDirectorys.pl
4
# Author: R. W. Rodolico
4
# Author: R. W. Rodolico
5
# Date: 20180603
5
# Date: 20180603
6
# Copyright: 2018, Vanduzen Enterprises, Dallas TX
6
# Copyright: 2018, Vanduzen Enterprises, Dallas TX
7
 
7
 
8
# Script designed to be run from a cron job, which checks if any projects
8
# Script designed to be run from a cron job, which checks if any directorys
9
# are ready to be archived. A project is defined as a directory under
9
# are ready to be archived. A directory is defined as a directory under
10
# the root of $localProjectDirectory.
10
# the root of $localDirectoryDirectory.
11
 
11
 
12
# If found, all directories are moved into the staging area and 
12
# If found, all directories are moved into the staging area and 
13
# an md5 checksum is calculated for the entire tree.
13
# an md5 checksum is calculated for the entire tree.
14
# After all projects are moved, a second process looks in the staging
14
# After all directorys are moved, a second process looks in the staging
15
# area and copies the files (using rsync for reliability) into the staging
15
# area and copies the files (using rsync for reliability) into the staging
16
# area of $targetServer. When a project has been copied, a checksum is
16
# area of $targetServer. When a directory has been copied, a checksum is
17
# calculated on the remote copy and compared to the checksum calculated
17
# calculated on the remote copy and compared to the checksum calculated
18
# in the first stage and, if it passes, the project is then moved to the 
18
# in the first stage and, if it passes, the directory is then moved to the 
19
# $targetProjectDirectory.
19
# $targetDirectoryDirectory.
20
# After the copy and move, the project and its MD5 sum file are moved
20
# After the copy and move, the directory and its MD5 sum file are moved
21
# to the $trashDirectory (which is cleaned on the next invocation of
21
# to the $trashDirectory (which is cleaned on the next invocation of
22
# the script).
22
# the script).
23
 
23
 
24
# Script does NOT handle the situation where projects are being moved
24
# Script does NOT handle the situation where directorys are being moved
25
# while the script is running, so the script should be run at a time
25
# while the script is running, so the script should be run at a time
26
# when there is no other activity on the server.
26
# when there is no other activity on the server.
27
#
27
#
28
# Version: 1.0
28
# Version: 1.0
29
 
29
 
Line 31... Line 31...
31
use strict;
31
use strict;
32
use Cwd qw();
32
use Cwd qw();
33
use File::Copy qw(move);
33
use File::Copy qw(move);
34
use File::Basename;
34
use File::Basename;
35
 
35
 
-
 
36
# location where directorys are put by end users
36
my $localProjectDirectory = '/home/samba/transfers/denver_to_dallas/Archive_to_DaVinci';
37
my $localDirectoryDirectory = '/home/samba/transfers/denver_to_dallas/Archive_to_DaVinci';
-
 
38
# location where directories are moved while processing
37
my $trashDirectory = "$localProjectDirectory/.Trash";
39
my $rootWorkDirectory = '/home/transfer_work_area';
-
 
40
# location where directories are moved when job is completed
38
my $stagingArea = "$localProjectDirectory/.Staging";
41
my $trashDirectory = "$localDirectoryDirectory/.Trash";
39
my $targetProjectDirectory = '/home/samba/archives/fromDenver/';
42
# location where directories are moved while being transferred
40
my $targetStagingArea = '/home/samba/archives/fromDenver/.Staging/';
43
my $stagingArea = "$localDirectoryDirectory/.Staging";
-
 
44
# target server name/ip. Must be accessible via ssh with no password
41
my $targetServer = 'davinci';
45
my $targetServer = 'davinci';
-
 
46
# location on target server where directories are placed while copying
-
 
47
my $targetStagingArea = '/home/samba/archives/fromDenver/.Staging/';
-
 
48
# location on target server where directories are finally put
-
 
49
my $targetDirectoryDirectory = '/home/samba/archives/fromDenver/';
-
 
50
# suffix of md5 of directories
42
my $md5suffix = '.md5sum';
51
my $md5suffix = '.md5sum';
43
 
52
 
44
my @ProjectsToMove;
53
my @DirectorysToMove;
45
 
54
 
46
# look in the projects to move directory and see if there is anything 
55
# look in the directorys to move directory and see if there is anything 
47
# new in there.
56
# new in there.
48
sub getProjects {
57
sub getDirectorys {
49
   my $rootDir = shift;
58
   my $rootDir = shift;
50
   opendir( my $dh, $rootDir ) or die "Could not open directory $rootDir: $!\n";
59
   opendir( my $dh, $rootDir ) or die "Could not open directory $rootDir: $!\n";
51
   my @dirs = grep { ! /^\./ && -d "$rootDir/$_" } readdir( $dh );
60
   my @dirs = grep { ! /^\./ && -d "$rootDir/$_" } readdir( $dh );
52
   return @dirs;
61
   return @dirs;
53
}
62
}
Line 66... Line 75...
66
   my $md5 = `find '$directory' -type f -exec md5sum \\{\\} \\; | cut -d' ' -f1 | sort | md5sum | cut -d' ' -f1`;
75
   my $md5 = `find '$directory' -type f -exec md5sum \\{\\} \\; | cut -d' ' -f1 | sort | md5sum | cut -d' ' -f1`;
67
   chomp $md5;
76
   chomp $md5;
68
   return $md5;
77
   return $md5;
69
}
78
}
70
 
79
 
71
# moves project to staging area and puts the md5 sum into a file
80
# moves directory to staging area and puts the md5 sum into a file
72
# with the same name, but a .md5sum suffix
81
# with the same name, but a .md5sum suffix
73
sub moveToStaging {
82
sub moveToStaging {
74
   my ( $project, $stagingArea, $md5 ) = @_;
83
   my ( $directory, $stagingArea, $md5 ) = @_;
75
   mkdir $stagingArea unless -d $stagingArea;
84
   mkdir $stagingArea unless -d $stagingArea;
76
   move( "$localProjectDirectory/$project", "$stagingArea/$project" );
85
   move( "$localDirectoryDirectory/$directory", "$stagingArea/$directory" );
77
   my $md5File = "$stagingArea/$project" . $md5suffix;
86
   my $md5File = "$stagingArea/$directory" . $md5suffix;
78
   open DATA,">$md5File" or die "Could not create md5sum file [$md5File]: $!\n";
87
   open DATA,">$md5File" or die "Could not create md5sum file [$md5File]: $!\n";
79
   print DATA "$md5\n";
88
   print DATA "$md5\n";
80
   close DATA;
89
   close DATA;
81
   return;
90
   return;
82
}
91
}
83
   
92
   
84
# verifies the project is correct on the server by comparing the checksums
93
# verifies the directory is correct on the server by comparing the checksums
85
# calculated locally and remote server. If valid, moves it into the final
94
# calculated locally and remote server. If valid, moves it into the final
86
# location on the remote server
95
# location on the remote server
87
sub validateTarget {
96
sub validateTarget {
88
   my ( $remoteServer, $remoteStaging, $remoteTarget, $project, $checksum ) = @_;
97
   my ( $remoteServer, $remoteStaging, $remoteTarget, $directory, $checksum ) = @_;
89
   my $md5sum = `ssh $remoteServer "find '$remoteStaging/$project' -type f -exec md5sum \\{\\} \\; | cut -d' ' -f1 | sort | md5sum | cut -d' ' -f1"`;
98
   my $md5sum = `ssh $remoteServer "find '$remoteStaging/$directory' -type f -exec md5sum \\{\\} \\; | cut -d' ' -f1 | sort | md5sum | cut -d' ' -f1"`;
90
   chomp $md5sum;
99
   chomp $md5sum;
91
   if ( $checksum eq $md5sum ) {
100
   if ( $checksum eq $md5sum ) {
92
      my $command = "ssh $remoteServer \"mv '$remoteStaging/$project' '$remoteTarget'\"";
101
      my $command = "ssh $remoteServer \"mv '$remoteStaging/$directory' '$remoteTarget'\"";
93
      if ( system( $command ) == 0 ) {
102
      if ( system( $command ) == 0 ) {
94
         return 1;
103
         return 1;
95
      } else {
104
      } else {
96
         &logit( "Unable to move $project to $remoteServer:$remoteTarget" );
105
         &logit( "Unable to move $directory to $remoteServer:$remoteTarget" );
97
         return 0;
106
         return 0;
98
      }
107
      }
99
   } else {
108
   } else {
100
      &logit( "Invalid checksum moving project $project" );
109
      &logit( "Invalid checksum moving directory $directory" );
101
      return 0;
110
      return 0;
102
   }
111
   }
103
}
112
}
104
 
113
 
105
# reads the checksum file
114
# reads the checksum file
106
sub getCheckSum {
115
sub getCheckSum {
107
   my ( $project, $staging )  = @_;
116
   my ( $directory, $staging )  = @_;
108
   $project .= $md5suffix;
117
   $directory .= $md5suffix;
109
   if ( open DATA, "<$staging/$project" ) {
118
   if ( open DATA, "<$staging/$directory" ) {
110
      my $cksum = <DATA>;
119
      my $cksum = <DATA>;
111
      chomp $cksum;
120
      chomp $cksum;
112
      close DATA;
121
      close DATA;
113
      return $cksum;
122
      return $cksum;
114
   } 
123
   } 
115
   &logit( "Could not open $staging/$project: $!" );
124
   &logit( "Could not open $staging/$directory: $!" );
116
   return '';
125
   return '';
117
}
126
}
118
   
127
   
119
# simple little logger that records some information   
128
# simple little logger that records some information   
120
sub logit {
129
sub logit {
121
   my $message = shift;
130
   my $message = shift;
122
   my ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = localtime(time);
131
   my ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = localtime(time);
123
   my $now = sprintf( "%04d-%02d-%02d %02d:%-2d:%02d", $year+1900, $mon+1, $mday, $hour, $min, $sec );
132
   my $now = sprintf( "%04d-%02d-%02d %02d:%-2d:%02d", $year+1900, $mon+1, $mday, $hour, $min, $sec );
124
   open LOG, ">>/tmp/archiveProjects.log" or die "could not write to archiveProjects.log: $!\n";
133
   open LOG, ">>/tmp/archiveDirectorys.log" or die "could not write to archiveDirectorys.log: $!\n";
125
   print LOG "$now\t$message\n";   
134
   print LOG "$now\t$message\n";   
126
   close LOG;
135
   close LOG;
127
}
136
}
128
   
137
   
129
# simply remove everything from the trash directory
138
# simply remove everything from the trash directory
Line 131... Line 140...
131
   my $trashDir = shift;
140
   my $trashDir = shift;
132
   `rm -fR $trashDir/*`;
141
   `rm -fR $trashDir/*`;
133
}
142
}
134
 
143
 
135
 
144
 
136
#&cleanTrash( $trashDirectory ) if &getProjectsToMove( $trashDirectory );
145
#&cleanTrash( $trashDirectory ) if &getDirectorysToMove( $trashDirectory );
137
   
146
   
138
   
147
   
139
# first, check and see if we have any projects we need to move
148
# first, check and see if we have any directorys we need to move
140
@ProjectsToMove = &getProjects( $localProjectDirectory );
149
@DirectorysToMove = &getDirectorys( $localDirectoryDirectory );
141
 
150
 
142
foreach my $project ( @ProjectsToMove ) {
151
foreach my $directory ( @DirectorysToMove ) {
143
   my $md5 = &calcMD5( "$localProjectDirectory/$project" );
152
   my $md5 = &calcMD5( "$localDirectoryDirectory/$directory" );
144
   &logit( "New Project $md5\t$project" );
153
   &logit( "New Directory $md5\t$directory" );
145
   &moveToStaging( $project, $stagingArea, $md5 );
154
   &moveToStaging( $directory, $stagingArea, $md5 );
146
}
155
}
147
 
156
 
148
# done with that, now we need to see if there is anything in the staging area
157
# done with that, now we need to see if there is anything in the staging area
149
# that needs to be sent to the remote server
158
# that needs to be sent to the remote server
150
opendir( my $dh, $stagingArea ) or die "Could not read $stagingArea: $!\n";
159
opendir( my $dh, $stagingArea ) or die "Could not read $stagingArea: $!\n";
151
my @directories;
160
my @directories;
152
my @toMove = grep { /$md5suffix$/ } readdir( $dh );
161
my @toMove = grep { /$md5suffix$/ } readdir( $dh );
153
foreach my $project ( @toMove ) {
162
foreach my $directory ( @toMove ) {
154
   $project =~ m/^(.*)\.md5sum/;
163
   $directory =~ m/^(.*)\.md5sum/;
155
   $project = $1;
164
   $directory = $1;
156
   my $md5sum = &getCheckSum( $project, $stagingArea );
165
   my $md5sum = &getCheckSum( $directory, $stagingArea );
157
   next unless $md5sum;
166
   next unless $md5sum;
158
   my $rsync = "rsync -av '$stagingArea/$project' $targetServer:$targetStagingArea/ > /tmp/lastrsync.log";
167
   my $rsync = "rsync -av '$stagingArea/$directory' $targetServer:$targetStagingArea/ > /tmp/lastrsync.log";
159
   &logit( $rsync );
168
   &logit( $rsync );
160
   if ( system ( $rsync ) == 0 ) { # we succeeded
169
   if ( system ( $rsync ) == 0 ) { # we succeeded
161
      if ( &validateTarget( $targetServer, $targetStagingArea, $targetProjectDirectory, $project, $md5sum ) ) {
170
      if ( &validateTarget( $targetServer, $targetStagingArea, $targetDirectoryDirectory, $directory, $md5sum ) ) {
162
         `mkdir -p $trashDirectory` unless -d $trashDirectory;
171
         `mkdir -p $trashDirectory` unless -d $trashDirectory;
163
         move( "$stagingArea/$project", "$trashDirectory/$project" );
172
         move( "$stagingArea/$directory", "$trashDirectory/$directory" );
164
         $project .= $md5suffix;
173
         $directory .= $md5suffix;
165
         move( "$stagingArea/$project", "$trashDirectory/$project" );
174
         move( "$stagingArea/$directory", "$trashDirectory/$directory" );
166
         &logit( "Successfully moved project $project to $targetServer" );
175
         &logit( "Successfully moved directory $directory to $targetServer" );
167
      } else {
176
      } else {
168
         &logit( "Unable to validate target for $project" );
177
         &logit( "Unable to validate target for $directory" );
169
      }
178
      }
170
   } else {
179
   } else {
171
      &logit( "Unknown error attempting to rsync $project" );
180
      &logit( "Unknown error attempting to rsync $directory" );
172
   }
181
   }
173
}
182
}
174
 
183
 
175
 
184
 
176
1;
185
1;