#!/usr/bin/perl # Update binary tool # Copyright (c) 2010 Artica Soluciones Tecnologicas S.L. # Copyright (c) Sancho Lerena use strict; use warnings; use POSIX qw(strftime); use Cwd 'abs_path'; use File::Basename; use File::Copy; use FindBin; use Digest::MD5 qw(md5); # Time to wait before the service stops use constant SERVICE_STOP_WAIT => 5; # This tool is intented to be used to update pandora agent binaries using # the file collection feature. This will work using a module like this: # Unix # module_begin # module_name Pandora_Update # module_type async_string # module_exec nohup pandora_update fc_1 2> /dev/null && tail -1 nohup.out 2> /dev/null # module_description Module to check new version of pandora agent and update itself # module_end # Windows: # module_begin # module_name Pandora_Update # module_type async_string # module_exec pandora_update.exe fc_1 # module_description Module to check new version of pandora agent and update itself # module_end # This small function return the current base path (where this tool is stored) sub return_basepath () { return $FindBin::Bin; } # Function to compare two binary files. Return 0 if different 1 if equal, 2 error sub compare_twofiles ($$) { my $file1 = $_[0]; my $file2 = $_[1]; my $size1 = -s $file1; my $size2 = -s $file2; # Size matters; if ((!defined($size1)) || (!defined($size2))){ return 2; } if ($size1 != $size2){ return 0; } open FILE1, $file1; binmode FILE1; my $data1 = join ('', ); close FILE1; my $hash1 = md5($data1); open FILE2, $file2; binmode FILE2; my $data2 = join ('', ); close FILE2; my $hash2 = md5($data2); if ($hash1 eq $hash2){ return 1; } return 0; } # Get agent pid sub get_agent_pid ($$) { my $daemon = shift; my $app_path = shift; $ENV{'COLUMNS'}=400; my $os_name=`uname -s`; my $pid = ""; my $cmd = ""; if ($os_name eq "HP-UX") { $cmd ="ps -ex | grep \"$daemon $app_path\" | grep -v grep | head -1 | awk '{ print \$1 }'"; } elsif ($os_name =~ /SunOS/) { my $cmd_aux="echo \"$daemon $app_path\" | cut -c1-40"; my $truncated_daemon = `$cmd_aux`; chop($truncated_daemon); my $zone = `/bin/zonename`; if ( $zone =~ /global/) { $cmd ="ps -f -z global | grep \"$truncated_daemon\" | grep -v grep | head -1 | awk '{ print \$2 }'"; } else { $cmd ="ps -Af | grep \"$truncated_daemon\" | grep -v grep | head -1 | awk '{ print \$2 }'"; } } else { $cmd ="ps -Af | grep \"$daemon $app_path\" | grep -v grep | head -1 | awk '{ print \$2 }'"; } $pid = `$cmd`; return $pid; } # ------------------------------------------------------------------------- # MAIN CODE starts here # Get the required path (relative to basepath) to find pandora agent binary if ($#ARGV < 0) { print "Usage: $0 $local_log"); close (FILE3); my $ppid = get_agent_pid($running_binary, $conf_path); # Kill parent process (a.k.a the Agent) my $output = `kill -9 $ppid`; sleep SERVICE_STOP_WAIT; # Copy the updated agent copy($updated_binary, $running_binary) or unlink $local_log; # Starting the agent again my $log = $opt_dir."/var/log/pandora/pandora_agent.log"; $output = `nohup $running_binary $conf_path >/dev/null 2>$log &` } else { if (-e $local_log){ print "Updated binary from $updated_binary\n"; unlink $local_log; } } exit;