#!/usr/bin/perl #---------------------------------------------------------------------------------- # Filename: deploy.pl # # This script is executed by the deploy tool as part of the standard # deploy process. This script moves batch SE work flow batch scripts to the correct # locations where <> expect to find them within the local filesystem. # # Date Developer Comment # ---------- ---------------- -------------------------------------------- # 02-06-2019 R. Eaglestone Initial creation # 05-21-2019 Brother Holli Waxing and Polishing #---------------------------------------------------------------------------------- use Modern::Perl; use File::Copy; use Sub::Signatures; use Config::Any; # This subroutine ensures that all files are present. sub checkDeployValidity ($installDir, $executionDir, $filesToDeploy) { # First, check that the install directory exists. if ( !(-d $installDir) ) { return "install directory $installDir was not deployed."; } # Then, check that the base execution directory exists. if ( ! (-d $executionDir) ) { return "execution directory $executionDir does not exist."; } # Next, set permissions on the installation directory. if ( ! chmod(0775, $installDir) ) { return "Setting permissions on directory $installDir failed."; } # Now, check that all files were deployed. my @scriptFileNames = sort(keys(%$filesToDeploy)); foreach my $fileName (@scriptFileNames) { my $currentFile = "$installDir/$fileName"; if ( !(-f $currentFile) ) { return "file $currentFile was not deployed."; } } # Finally, if all files are present, then return success. return ""; } # This subroutine builds any missing directories. sub setUpDirectoryStructure ($dirsToDeploy) { # Build any subdirectories, if necessary. my @directoryNames = sort(keys(%$dirsToDeploy)); foreach my $dirName (@directoryNames) { # Check whether the directory exists... if ( -d $dirName ) { # If so, then set its permissions appropriately. if ( ! chmod(oct($dirsToDeploy->{$dirName}), $dirName) ) { print "\tunable to do 'chmod $dirsToDeploy->{$dirName} $dirName'.\n"; } } elsif ( ! mkdir($dirName, $dirsToDeploy->{$dirName}) ) { print "\tunable to create directory '$dirName'.\n"; } } # Finally, return success once all directories exist with proper permissions. return ""; } # This subroutine removes carriage return characters from specific files. sub dosToUnix ($installDir, $filesToConvert) { foreach my $fileName ( @$filesToConvert ) { my $file = "$installDir/$fileName"; my $tempFile = "$file.tmp_dos2Unix"; open(my $DOS_FILE, "<", $file) || return "cannot open $file for read: $!"; open(my $UNIX_FILE, ">", $tempFile) || return "cannot open $tempFile for write: $!"; # Remove all carriage return ('\r') characters. while (<$DOS_FILE>) { s/\r//g; print $UNIX_FILE || return "cannot write to $tempFile: $!"; } close($UNIX_FILE) || return "cannot close $tempFile: $!"; close($DOS_FILE) || return "cannot close $file: $!"; rename($file, "$file.orig") || return "cannot rename $file to $file.orig: $!"; rename($tempFile, $file) || return "cannot rename $tempFile to $file: $!"; unlink("$file.orig") || return "cannot delete $file.orig: $!"; } return ""; } # This subroutine copies files from the install dir to the execution dir. sub copyFilesToTarget ($installDir, $pathsToDeploy, $filesToDeploy) { my @fileNames = sort(keys(%$filesToDeploy)); foreach my $fileName (@fileNames) { my $source = "$installDir/$fileName"; my $path = $pathsToDeploy->{$fileName}; my $target = "$path/$fileName"; if ( -f $target) { chmod(0777, $target) || return "chmod 777 for existing file '$target' failed."; } copy($source, $target) || return "file copy to '$target' failed."; chmod(oct($filesToDeploy->{$fileName}), $target) || return "chmod for '$target' failed."; } return ""; } # This subroutine orchestrates the deploy process. sub deploy ( $configFile ) { die("ERROR - Cannot find config file") unless -e $configFile && -f $configFile; my $config = Config::Any->load_files({ files => [$configFile], use_ext => 1, flatten_to_hash => 0 })->{$configFile}; # Start by setting umask to 0 to simplify mkdir commands. my $oldUMask = umask(0000); # Next, check that all of the files exist. my $errorMessage = checkDeployValidity( $config->{installDir}, $config->{executionDir}, $config->{filesToDeploy} ); if ( $errorMessage ) { umask($oldUMask); die("$0: ERROR - $errorMessage"); } # Then, set up the execution directory structure. $errorMessage = setUpDirectoryStructure( $config->{dirsToDeploy} ); if ( $errorMessage ) { umask($oldUMask); die("$0: ERROR - $errorMessage"); } # Convert files from DOS format to Unix format. $errorMessage = dosToUnix( $config->{installDir}, $config->{filesToConvert} ); if ( $errorMessage ) { umask($oldUMask); die("$0: ERROR - $errorMessage"); } # Now, copy the files over. $errorMessage = copyFilesToTarget( $config->{installDir}, $config->{pathsToDeploy}, $config->{filesToDeploy} ); if ( $errorMessage ) { umask($oldUMask); die("$0: ERROR - $errorMessage"); } # Finally, restore the old umask value (in case this process is reused). umask($oldUMask); print "Copy succeeded. Job finished successfully.\n"; exit(0); } deploy( $ARGV[0] // "deploy.json" ); #### { "installDir":"/whatever/jobs/", "executionDir":"/whatever/data/output/", "dirsToDeploy":{ "/whatever/jobs/boo":"0777", "/whatever/jobs/boo/jum":"0777", "/whatever/data/output/boo/jum":"0777", "/whatever/data/output/boo":"0777" }, "filesToDeploy":{ "fileSanity.pl":"0775", "transferFile.sh":"0775", "MY_LAUNCHER_11023200099.sh":"0775" }, "filesToConvert":[ "MY_LAUNCHER_11023200099.sh", "fileSanity.pl", "transferFile.sh" ], "pathsToDeploy":{ "transferFile.sh":"/fancy/deploy/path", "fileSanity.pl":"/fancy/deploy/path", "MY_LAUNCHER_11023200099.sh":"/fancy/deploy/path" } }