You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@vcl.apache.org by jf...@apache.org on 2008/12/12 19:20:18 UTC
svn commit: r726079 [13/32] - in /incubator/vcl/tags/import: ./
managementnode/ managementnode/bin/ managementnode/etc/
managementnode/etc/vcl/ managementnode/legacy_vcl_vbs_scripts/
managementnode/lib/ managementnode/lib/VCL/ managementnode/lib/VCL/Mo...
Added: incubator/vcl/tags/import/managementnode/lib/VCL/utils.pm
URL: http://svn.apache.org/viewvc/incubator/vcl/tags/import/managementnode/lib/VCL/utils.pm?rev=726079&view=auto
==============================================================================
--- incubator/vcl/tags/import/managementnode/lib/VCL/utils.pm (added)
+++ incubator/vcl/tags/import/managementnode/lib/VCL/utils.pm Fri Dec 12 10:20:10 2008
@@ -0,0 +1,9911 @@
+#!/usr/bin/perl -w
+
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements. See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership.
+# The ASF licenses this file to You under the Apache License, Version 2.0
+# (the "License"); you may not use this file except in compliance with
+# the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+##############################################################################
+# $Id: utils.pm 1953 2008-12-12 14:23:17Z arkurth $
+##############################################################################
+
+=head1 NAME
+
+VCL::utils
+
+=head1 SYNOPSIS
+
+ use VCL::utils;
+
+=head1 DESCRIPTION
+
+ This module contains general VCL utility subroutines.
+
+=cut
+
+##############################################################################
+package VCL::utils;
+
+# Specify the lib path using FindBin
+use FindBin;
+use lib "$FindBin::Bin/..";
+
+# Configure inheritance
+use base qw();
+
+# Specify the version of this module
+our $VERSION = '2.00';
+
+# Specify the version of Perl to use
+use 5.008000;
+
+use strict;
+use warnings;
+use diagnostics;
+
+use Mail::Mailer;
+use Shell qw(mkdir);
+use File::Find;
+use Time::Local;
+use DBI;
+use DBI::Const::GetInfoType;
+use diagnostics;
+use Net::Ping;
+use Fcntl qw(:DEFAULT :flock);
+use FindBin;
+use Getopt::Long;
+use Carp;
+use Text::Wrap;
+use English;
+use List::Util qw(min max);
+
+
+#use Date::Calc qw(Delta_DHMS Time_to_Date Date_to_Time);
+
+require Exporter;
+our @ISA = qw(Exporter);
+
+our @EXPORT = qw(
+ _checknstartservice
+ _getcurrentimage
+ _is_user_added
+ _killsysprep
+ _machine_os
+ _pingnode
+ _set_sshd_startmode
+ _sshd_status
+ add_user
+ add_users_by_group
+ changelinuxpassword
+ changewindowspasswd
+ check_blockrequest_time
+ check_connection
+ check_endtimenotice_interval
+ check_ssh
+ check_time
+ check_uptime
+ checkonprocess
+ clearfromblockrequest
+ collectsshkeys
+ construct_image_name
+ controlVM
+ convert_to_datetime
+ convert_to_epoch_seconds
+ database_execute
+ database_select
+ del_user
+ delete_computerloadlog_reservation
+ delete_request
+ disablesshd
+ doesimageexists
+ enablesshd
+ firewall_compare_update
+ format_data
+ get_computer_current_state_name
+ get_highest_imagerevision_info
+ get_image_info
+ get_imagemeta_info
+ get_imagerevision_info
+ get_ip_address_from_hosts
+ get_management_node_blockrequests
+ get_management_node_id
+ get_management_node_info
+ get_management_node_requests
+ get_next_image_default
+ get_production_imagerevision_info
+ get_request_by_computerid
+ get_request_end
+ get_request_info
+ get_reservation_remote_ip
+ get_vmhost_info
+ getanothermachine
+ getdynamicaddress
+ getimagesize
+ getnewdbh
+ getpw
+ getusergroupmembers
+ hostname
+ insert_reload_request
+ insert_request
+ insertloadlog
+ is_inblockrequest
+ is_request_deleted
+ is_request_imaging
+ isconnected
+ isfilelocked
+ kill_reservation_process
+ known_hosts
+ lockfile
+ mail
+ makedatestring
+ monitorloading
+ nmap_port
+ notify
+ notify_via_IM
+ notify_via_msg
+ notify_via_wall
+ preplogfile
+ remotedesktopport
+ rename_vcld_process
+ reservation_being_processed
+ reservations_ready
+ restoresshkeys
+ round
+ run_scp_command
+ run_ssh_command
+ set_hash_process_id
+ set_logfile_path
+ setimageid
+ setpreferredimage
+ setstaticaddress
+ string_to_ascii
+ switch_state
+ switch_vmhost_id
+ system_monitoring
+ time_exceeded
+ timefloor15interval
+ unlockfile
+ update_blockrequest_processing
+ update_cluster_info
+ update_computer_address
+ update_computer_state
+ update_currentimage
+ update_image_name
+ update_lastcheckin
+ update_log_ending
+ update_log_loaded_time
+ update_preload_flag
+ update_request_password
+ update_request_state
+ update_reservation_lastcheck
+ update_sublog_ipaddress
+ virtual_status_unix
+ virtual_status_vm
+ windowsroutetable
+ write_currentimage_txt
+
+ $CONF_FILE_PATH
+ $DATABASE
+ $DEFAULTHELPEMAIL
+ $DEFAULTURL
+ $ETHDEVICE
+ $FQDN
+ $IDENTITY_bladerhel
+ $IDENTITY_wxp
+ $IDENTITY_linux_lab
+ $IDENTITY_solaris_lab
+ $IPCONFIGURATION
+ $jabPass
+ $jabPort
+ $jabResource
+ $jabServer
+ $jabUser
+ $LINUX_IMAGE
+ $LINUX_IMAGEREPOSITORY
+ $LOGFILE
+ $MYSQL_SSL
+ $MYSQL_SSL_CERT
+ $PIDFILE
+ $PROCESSNAME
+ $WINDOWS_ROOT_PASSWORD
+ $SERVER
+ $SYSADMIN
+ $SYSPREP
+ $SYSPREP_2003
+ $TESTING
+ $THROTTLE
+ $TOOLS
+ $VERBOSE
+ $VMWAREREPOSITORY
+ $WRTPASS
+ $WRTUSER
+ %ERRORS
+ %OPTIONS
+
+ $IMAGELIBENABLE
+ $IMAGELIBUSER
+ $IMAGELIBKEY
+ $IMAGESERVERS
+
+ $TOOLS
+ $VMWAREREPOSITORY
+ $SYSPREP_2003
+ $SYSPREP
+ $SYSPREP_VMWARE
+ $SYSPREP_VMWARE2003
+ $VERBOSE
+);
+
+#our %ERRORS=('DEPENDENT'=>4,'UNKNOWN'=>3,'OK'=>0,'WARNING'=>1,'CRITICAL'=>2,'MAILMASTERS'=>5);
+
+BEGIN {
+ #parse config file and set globals
+
+ our ($JABBER, $jabServer, $jabUser, $jabPass, $jabResource, $jabPort) = 0;
+ our ($LOGFILE, $PIDFILE, $PROCESSNAME) = 0;
+ our ($DATABASE, $SERVER, $WRTUSER, $WRTPASS, $LockerRdUser, $rdPass) = 0;
+ our ($SYSADMIN, $SHARED_MAILBOX, $DEFAULTURL, $DEFAULTHELPEMAIL) = 0;
+ our ($XCATROOT) = 0;
+ our ($FQDN) = 0;
+ our ($MYSQL_SSL, $MYSQL_SSL_CERT);
+ our ($IPCONFIGURATION, $DNSserver, $GATEWAY, $NETMASK, $ETHDEVICE) = 0;
+ our ($LINUX_IMAGE, $THROTTLE);
+ our ($CORE_IMAGEREPOSITORY, $WIN_IMAGEREPOSITORY, $LINUX_IMAGEREPOSITORY);
+ our ($IDENTITY_linux_lab, $IDENTITY_solaris_lab, $IDENTITY_wxp, $IDENTITY_newwxp, $IDENTITY_bladerhel);
+ our ($IMAGELIBENABLE) = 0;
+ our ($IMAGESERVERS, $IMAGELIBUSER, $IMAGELIBKEY);
+ our ($VMWARETYPE, $VMWARE_DISK);
+ our ($WINDOWS_ROOT_PASSWORD);
+
+ # Set Getopt pass_through so this module doesn't erase parameters that other modules may use
+ Getopt::Long::Configure('pass_through');
+
+ # Set the VERBOSE flag to 0 by default
+ our ($VERBOSE) = 0;
+
+ # Set the TESTING flag to 0 by default
+ our ($TESTING) = 0;
+
+ # Use the default configuration file path if -conf isn't specified on the command line
+ our $BIN_PATH = $FindBin::Bin;
+ print STDOUT "BIN PATH: $BIN_PATH\n";
+ our ($CONF_FILE_PATH) = 'C:/vcldev.conf';
+ if (!-f $CONF_FILE_PATH) {
+ if ($BIN_PATH =~ /dev/) {
+ $CONF_FILE_PATH = "/etc/vcl/vcldev.conf";
+ }
+ else {
+ $CONF_FILE_PATH = "/etc/vcl/vcld.conf";
+ }
+ }
+
+ # Store the command line options in this hash
+ our %OPTIONS;
+
+ GetOptions(\%OPTIONS, 'verbose', 'testing', 'config=s', 'logfile=s');
+
+ # Get the command line parameters
+ $CONF_FILE_PATH = $OPTIONS{config} if (defined($OPTIONS{config} && $OPTIONS{config}));
+
+ print STDOUT "pre-execution: config file being used: $CONF_FILE_PATH\n";
+
+ if (open(CONF, $CONF_FILE_PATH)) {
+ my @conf = <CONF>;
+ close(CONF);
+ foreach my $l (@conf) {
+ # Remove all new line and carriage return characters from the end of the line
+ # Chomp doesn't always remove carriage returns
+ $l =~ s/[\r\n]*$//;
+
+ #logfile
+ if ($l =~ /^log=(.*)/ && (!defined($LOGFILE) || !($LOGFILE))) {
+ chomp($l);
+ $LOGFILE = $1;
+ }
+ #pidfile
+ if ($l =~ /^pidfile=(.*)/) {
+ chomp($l);
+ $PIDFILE = $1;
+ }
+
+ if ($l =~ /^DEFAULTURL=(.*)/) {
+ $DEFAULTURL = $1;
+ }
+
+ if ($l =~ /^DEFAULTHELPEMAIL=(.*)/) {
+ $DEFAULTHELPEMAIL = $1;
+ }
+
+ #FQDN - to many issues trying to figure out my FQDN so just tell me
+ if ($l =~ /^FQDN=([-.a-zA-Z0-9]*)/) {
+ $FQDN = $1;
+ }
+
+ #mysql settings
+ #name of db
+ if ($l =~ /^database=([a-zA-Z0-9]*)/) {
+ $DATABASE = $1;
+ }
+ #name of database server
+ if ($l =~ /^server=([.a-zA-Z0-9]*)/) {
+ $SERVER = $1;
+ }
+ #write user name
+ if ($l =~ /^LockerWrtUser=([-a-zA-Z0-9]*)/) {
+ $WRTUSER = $1;
+ }
+
+ #write user password
+ #if($l =~ /^wrtPass=([-a-zA-Z0-9]*)/){
+ if ($l =~ /^wrtPass=(.*)/) {
+ $WRTPASS = $1;
+ }
+
+ #read user name
+ if ($l =~ /^LockerRdUser=([-a-zA-Z0-9]*)/) {
+ $LockerRdUser = $1;
+ }
+
+ #read user password
+ if ($l =~ /^rdPass=(.*)/) {
+ $rdPass = $1;
+ }
+ #is mysql ssl option enabled
+ if ($l =~ /^enable_mysql_ssl=(yes)/) {
+ $MYSQL_SSL = 1;
+ }
+ elsif ($l =~ /^enable_mysql_ssl=(no)/) {
+ $MYSQL_SSL = 0;
+ }
+
+ #collect path to cert -- only valid if $MYSQL_SSL is true
+ if ($l =~ /^mysql_ssl_cert=(.*)/) {
+ $MYSQL_SSL_CERT = $1;
+ }
+
+ #ipconfiguration
+ if ($l =~ /^ipconfiguration=(static|manualDHCP|dynamicDHCP)/) {
+ $IPCONFIGURATION = $1;
+ }
+
+ if ($l =~ /^DNSserver=([,.0-9]*)/) {
+ $DNSserver = $1;
+ }
+ if ($l =~ /^GATEWAY=([.0-9]*)/) {
+ $GATEWAY = $1;
+ }
+ if ($l =~ /^NETMASK=([.0-9]*)/) {
+ $NETMASK = $1;
+ }
+ if ($l =~ /^ETHDEVICE=(eth[0-9])/) {
+ $ETHDEVICE = $1;
+ }
+ #Sysadmin list
+ if ($l =~ /^sysadmin=([,.\@a-zA-Z0-9]*)/) {
+ $SYSADMIN = $1;
+ }
+
+ #sharedmailbox
+ if ($l =~ /^sharedmailbox=([,-.\@a-zA-Z0-9]*)/) {
+ $SHARED_MAILBOX = $1;
+ }
+
+ #jabber - stuff
+ if ($l =~ /^jabber=(yes)/) {
+ $JABBER = 1;
+ }
+ if ($l =~ /^jabber=(no)/) {
+ $JABBER = 0;
+ }
+ #collect remaining pieces of the jabber settings
+ #$jabServer,$jabUser,$jabPass,$jabResource,$jabPort
+ if ($l =~ /^jabServer=([.a-zA-Z0-9]*)/) {
+ $jabServer = $1;
+ }
+ if ($l =~ /^jabPort=([0-9]*)/) {
+ $jabPort = $1;
+ }
+ if ($l =~ /^jabUser=([.a-zA-Z0-9]*)/) {
+ $jabUser = $1;
+ }
+ if ($l =~ /^jabPass=([a-zA-Z0-9]*)/) {
+ $jabPass = $1;
+ }
+ if ($l =~ /^jabResource=([a-zA-Z0-9]*)/) {
+ $jabResource = $1;
+ }
+
+ #process name
+ if ($l =~ /^processname=([-_a-zA-Z0-9]*)/) {
+ $PROCESSNAME = $1;
+ }
+
+ #xcat linux image path
+ # linux kernal 2.4 - we had to modify xcat to load from seperate install tree.
+ if ($l =~ /^LINUXIMAGEid=(image|linux_image)/) {
+ $LINUX_IMAGE = $1;
+ }
+
+ #Linux_imagerepository
+ if ($l =~ /^LINUX_IMAGEREPOSITORY=([\/a-zA-Z0-9]*)/) {
+ $LINUX_IMAGEREPOSITORY = $1;
+ }
+
+ #throttle
+ if ($l =~ /^THROTTLE=([0-9]*)/) {
+ $THROTTLE = $1;
+ }
+
+ #ssh private keys
+ if ($l =~ /^IDENTITY_blade_linux=(.*)/) {
+ $IDENTITY_bladerhel = $1;
+ }
+ if ($l =~ /^IDENTITY_blade_win=(.*)/) {
+ $IDENTITY_wxp = $1;
+ }
+ if ($l =~ /^IDENTITY_solaris_lab=(.*)/) {
+ $IDENTITY_solaris_lab = $1;
+ }
+ if ($l =~ /^IDENTITY_linux_lab=(.*)/) {
+ $IDENTITY_linux_lab = $1;
+ }
+
+ #image library share - sync images across multiple management nodes
+ # $IMAGELIBENABLE,$IMAGESERVERS,$IMAGELIBUSER,$IMAGELIBKEY
+ if ($l =~ /^IMAGELIBENABLE=(yes)/) {
+ $IMAGELIBENABLE = 1;
+ }
+ elsif ($l =~ /^IMAGELIBENABLE=(no)/) {
+ $IMAGELIBENABLE = 0;
+ }
+ if ($l =~ /^imageservers=(.*)/) {
+ $IMAGESERVERS = $1;
+ }
+ if ($l =~ /^imagelibuser=([a-z0-9]*)/) {
+ $IMAGELIBUSER = $1;
+ }
+ if ($l =~ /^imagelibuser=([-a-zA-Z0-9]*)/) {
+ $IMAGELIBUSER = $1;
+ }
+ if ($l =~ /^imagelibidkey=(.*)/) {
+ $IMAGELIBKEY = $1;
+ }
+ #vmware settings
+ # localdisk
+ if ($l =~ /^VMWARE_DISK=(localdisk|networkdisk)/) {
+ $VMWARE_DISK = $1;
+ }
+
+ if ($l =~ /^windows_root_password=(.*)/i) {
+ $WINDOWS_ROOT_PASSWORD = $1;
+ }
+
+ if ($l =~ /^verbose=(.*)/i) {
+ $VERBOSE = $1;
+ }
+
+ if ($l =~ /^test=(.*)/i) {
+ $TESTING = $1;
+ }
+ } # Close foreach line in conf file
+ } # Close open conf file
+
+ else {
+ die "VCLD : $CONF_FILE_PATH does not exist, exiting -- $! \n";
+ }
+
+ if (!$PROCESSNAME) {
+ $PROCESSNAME = "vcld";
+ }
+ if (!($LOGFILE) && $LOGFILE ne '0') {
+ #set default
+ $LOGFILE = "/var/log/$PROCESSNAME.log";
+ }
+
+ if (!$THROTTLE) {
+ $THROTTLE = 0;
+ }
+
+ if (!$IDENTITY_bladerhel) {
+
+ }
+ if (!$IDENTITY_wxp) {
+
+ }
+ if (!$IDENTITY_solaris_lab) {
+ }
+ if (!$IDENTITY_linux_lab) {
+ }
+
+ if (!$WINDOWS_ROOT_PASSWORD) {
+ $WINDOWS_ROOT_PASSWORD = "clOudy";
+ }
+
+ if (!($FQDN)) {
+ print STDOUT "FQDN is not listed\n";
+ }
+ if (!($PIDFILE)) {
+ #set default
+ $PIDFILE = "/var/run/$PROCESSNAME.pid";
+ }
+ if (!$IPCONFIGURATION) {
+ #default
+ $IPCONFIGURATION = "manualDHCP";
+ }
+ elsif ($IPCONFIGURATION eq "static") {
+ #check for dependiencies
+ if (!$DNSserver) {
+ print STDOUT "pre-execution: ipconfiguration is $IPCONFIGURATION dnsserver setting is missing in configuration file\n";
+ }
+ if (!$GATEWAY) {
+ print STDOUT "pre-execution: ipconfiguration is $IPCONFIGURATION gateway setting is missing in configuration file\n";
+ }
+ if (!$NETMASK) {
+ print STDOUT "pre-execution: ipconfiguration is $IPCONFIGURATION netmask setting is missing in configuration file\n";
+ }
+ } ## end elsif ($IPCONFIGURATION eq "static") [ if (!$IPCONFIGURATION)
+
+ if (!$LINUX_IMAGE) {
+ $LINUX_IMAGE = "image";
+ }
+
+ if ($JABBER) {
+ #jabber is enabled - import required jabber module
+ # todo - check if Jabber module is installed
+ # i.e. perl -MNet::Jabber -e1
+ # check version -- perl -MNet::Jabber -e'print $Net::Jabber::VERSION\n";'
+ require "Net/Jabber.pm";
+ import Net::Jabber qw(client);
+ }
+
+ # Get the remaining command line parameters
+ $VERBOSE = $OPTIONS{verbose} if (defined($OPTIONS{verbose} && $OPTIONS{verbose}));
+ $TESTING = $OPTIONS{testing} if (defined($OPTIONS{testing} && $OPTIONS{testing}));
+ $LOGFILE = $OPTIONS{logfile} if (defined($OPTIONS{logfile} && $OPTIONS{logfile}));
+
+ print STDOUT "pre-execution: process name is set to: $PROCESSNAME\n";
+ print STDOUT "pre-execution: verbose mode is set to: $VERBOSE\n";
+ print STDOUT "pre-execution: testing mode is set to: $TESTING\n";
+ print STDOUT "pre-execution: log file being used: $LOGFILE\n";
+ print STDOUT "pre-execution: PID file being used: $PIDFILE\n";
+} ## end BEGIN
+
+
+#use Net::Jabber qw(Client);
+our ($JABBER, $PROCESSNAME);
+our %ERRORS = ('DEPENDENT' => 4, 'UNKNOWN' => 3, 'OK' => 0, 'WARNING' => 1, 'CRITICAL' => 2, 'MAILMASTERS' => 5, 'DEBUG' => 6);
+our ($LockerWrtUser, $wrtPass, $database, $server);
+our ($jabServer, $jabUser, $jabPass, $jabResource, $jabPort);
+our ($vcldquerykey, $SYSADMIN, $SHARED_MAILBOX, $DEFAULTURL, $DEFAULTHELPEMAIL);
+our ($LOGFILE, $PIDFILE, $VCLDRPCQUERYKEY);
+our ($SERVER, $DATABASE, $WRTUSER, $WRTPASS);
+our ($MYSQL_SSL, $MYSQL_SSL_CERT);
+our ($IPCONFIGURATION, $DNSserver, $GATEWAY, $NETMASK, $ETHDEVICE);
+our ($LINUX_IMAGE, $THROTTLE);
+our ($FQDN);
+our ($IDENTITY_linux_lab, $IDENTITY_solaris_lab, $IDENTITY_wxp, $IDENTITY_bladerhel);
+our ($IMAGELIBENABLE, $IMAGESERVERS, $IMAGELIBUSER, $IMAGELIBKEY);
+our ($VMWARE_DISK);
+our $IDENTITY_newwxp = "$FindBin::Bin/../lib/VCL/newwinxp_blade.key";
+our $XCATROOT = "/opt/xcat";
+our $TOOLS = "$FindBin::Bin/../tools";
+our $VMWAREREPOSITORY = "/install/vmware_images";
+our $SYSPREP_2003 = "$TOOLS/Sysprep_2003";
+our $SYSPREP = "$TOOLS/Sysprep";
+our $SYSPREP_VMWARE = "$TOOLS/Sysprep_vmware";
+our $SYSPREP_VMWARE2003 = "$TOOLS/Sysprep_vmware2003";
+our $VERBOSE;
+our $TESTING;
+our $CONF_FILE_PATH;
+our $WINDOWS_ROOT_PASSWORD;
+
+sub makedatestring;
+
+#/////////////////////////////////////////////////////////////////////////////
+
+=head2 preplogfile
+
+ Parameters : nothing
+ Returns : nothing
+ Description : writes header to global log file
+
+=cut
+
+sub preplogfile {
+ my $currenttime = makedatestring();
+ my ($package, $filename, $line, $sub) = caller(0);
+ $filename =~ s(^.*/)(); #remove leading path from filename
+ # print initial info to log file
+ print STDERR "===========================================================\n";
+ print STDERR "OUTPUT for $filename run on $currenttime\n";
+ print STDERR "===========================================================\n";
+}
+
+#/////////////////////////////////////////////////////////////////////////////
+
+=head2 notify
+
+ Parameters : $error, $LOG, $string, $data
+ Returns : nothing
+ Description : based on error value write string and/or data to
+ provide or default log file
+=cut
+
+sub notify {
+ my $error = shift;
+ my $LOG = shift;
+ my $string = shift;
+ my @data = @_;
+
+ # Just return if DEBUG and verbose isn't enabled
+ return if ($error == 6 && !$VERBOSE);
+
+ # Get the current time
+ my $currenttime = makedatestring();
+
+ # Redirect STDOUT and STDERR to the log file
+ $LOG = $LOGFILE if (!$LOG);
+ open(STDOUT, ">>$LOG") if $LOG;
+ open(STDERR, ">>$LOG") if $LOG;
+
+ # Get info about the subroutine which called this subroutine
+ my ($package, $filename, $line, $sub) = caller(0);
+
+ # Remove leading path from filename
+ $filename =~ s/.*\///;
+
+ # Remove the leading package path from the sub name (VC::...)
+ $sub =~ s/.*:://;
+
+ # Assemble the caller information
+ my $caller_info;
+ if (caller(1)) {
+ my ($caller_previous_package, $caller_previous_filename, $caller_previous_line, $caller_previous_sub) = caller(1);
+ $caller_previous_filename =~ s/.*\///;
+ $caller_previous_sub =~ s/.*:://;
+ $caller_info = "$filename:$caller_previous_sub($line)";
+ }
+ else {
+ $caller_info = "$filename:$sub($line)";
+ }
+
+ # Get the caller trace information
+ my $caller_trace = get_caller_trace(6);
+
+
+ # Format the message string
+ # Remove Windows carriage returns from the message string for consistency
+ $string =~ s/\r//g;
+
+ # Remove newlines from the beginning and end of the message string
+ $string =~ s/^\n+//;
+ $string =~ s/\n+$//;
+
+ # Remove any spaces from the beginning or end of the string
+ $string =~ s/^\s+//;
+ $string =~ s/\s+$//;
+
+ # Replace consecutive spaces with a single space to keep log file concise as long as string doesn't contain a quote
+ if ($string !~ /[\'\"]/gs) {
+ $string =~ s/[ \t]+/ /gs;
+ }
+
+ # Assemble the process identifier string
+ my $process_identifier = $PID;
+ $process_identifier .= "|$ENV{request_id}:$ENV{reservation_id}" if (defined $ENV{request_id} && defined $ENV{reservation_id});
+ $process_identifier .= "|$ENV{state}" if (defined $ENV{state});
+
+ # Assemble the log message
+ my $log_message = "$currenttime|$process_identifier|$caller_info|$string";
+
+ # Format the data if WARNING or CRITICAL, and @data was passed
+ my $formatted_data;
+ if (@data && ($error == 1 || $error == 2)) {
+ # Add the data to the message body if it was passed
+ $formatted_data = "DATA:\n" . format_data(\@data, 'DATA');
+ chomp $formatted_data;
+ }
+
+ # Assemble an email message body if CRITICAL or MAILMASTERS
+ my $body;
+ if ($error == 2 || ($error == 5 && $SHARED_MAILBOX)) {
+ # Get the previous several log file entries for this process
+ my $log_history_count = 100;
+ my $log_history = "RECENT LOG ENTRIES FOR THIS PROCESS:\n";
+ $log_history .= `grep "|$PID|" $LOG | tail -n $log_history_count`;
+ chomp $log_history;
+
+ # Assemble the e-mail message body
+ $body = <<"END";
+$string
+
+Time: $currenttime
+PID: $PID
+Caller: $caller_info
+
+$caller_trace
+
+$log_history
+END
+
+ # Add the formatted data to the message body if data was passed
+ $body .= "\n\n$formatted_data\n" if $formatted_data;
+ } ## end if ($error == 2 || ($error == 5 && $SHARED_MAILBOX...
+
+
+ # OK, VERBOSE
+ if (!$error || ($error == 6 && $VERBOSE)) {
+
+ }
+
+ # WARNING
+ if ($error == 1) {
+ $log_message = "\n---- WARNING ---- \n$log_message\n$caller_trace\n\n";
+ }
+
+ # CRITICAL
+ elsif ($error == 2) {
+ $log_message = "\n---- CRITICAL ---- \n$log_message\n$caller_trace\n";
+ $log_message .= "$formatted_data\n" if $formatted_data;
+ $log_message .= "\n";
+
+ my $from = "root\@$FQDN";
+ my $to = $SYSADMIN;
+ my $subject = "PROBLEM -- $filename";
+ mail($to, $subject, $body, $from);
+ } ## end elsif ($error == 2) [ if ($error == 1)
+
+ # MAILMASTERS - only for email notifications
+ elsif ($error == 5 && $SHARED_MAILBOX) {
+ my $to = $SHARED_MAILBOX;
+ my $from = "root\@$FQDN";
+ my $subject = "Informational -- $filename";
+ mail($to, $subject, $body, $from);
+ }
+
+ # Add the process identifier to every line of the log message
+ chomp $log_message;
+ $log_message =~ s/\n([^\n])/\n|$process_identifier| $1/g;
+
+ # Print the log message to the log file
+ print STDOUT "$log_message\n";
+
+} ## end sub notify
+
+#/////////////////////////////////////////////////////////////////////////////
+
+=head2 makedatestring
+
+ Parameters : empty
+ Returns : current time in date_time format
+ Description :
+
+=cut
+
+sub makedatestring {
+ my ($sec, $min, $hour, $mday, $mon, $year, $wday, $yday, $isdst) = localtime();
+ $year += 1900;
+ $mon++;
+ my $datestring = sprintf("%04d-%02d-%02d %02d:%02d:%02d", $year, $mon, $mday, $hour, $min, $sec);
+ return $datestring;
+}
+
+#/////////////////////////////////////////////////////////////////////////////
+
+=head2 convert_to_datetime
+
+ Parameters : time in epoch format
+ Returns : date in datetime format
+ Description : accepts time in epoch format (10 digit) and
+ returns time in datetime format
+
+=cut
+
+sub convert_to_datetime {
+ my ($epochtime) = shift;
+
+ if (!defined($epochtime) || $epochtime == 0) {
+ $epochtime = time();
+ }
+
+ my ($sec, $min, $hour, $mday, $mon, $year, $wday, $yday, $isdst) = localtime($epochtime);
+ $year += 1900;
+ $mon++;
+ my $datestring = sprintf("%04d-%02d-%02d %02d:%02d:%02d", $year, $mon, $mday, $hour, $min, $sec);
+ return $datestring;
+
+} ## end sub convert_to_datetime
+
+#/////////////////////////////////////////////////////////////////////////////
+
+=head2 convert_to_epoch_seconds
+
+ Parameters : datetime
+ Returns : time in epoch format
+ Description : takes input(optional) and returns epoch 10 digit string of
+ the supplied date_time or the current time
+
+=cut
+
+sub convert_to_epoch_seconds {
+ my ($date_time) = shift;
+ if (!defined($date_time)) {
+ return time();
+ }
+ #somehow we got a null timestamp, set it to current time
+ if ($date_time =~ /0000-00-00 00:00:00/) {
+ $date_time = makedatestring;
+ }
+
+ #format received: year-mon-mday hr:min:sec
+ my ($vardate, $vartime) = split(/ /, $date_time);
+ my ($yr, $mon, $mday) = split(/-/, $vardate);
+ my ($hr, $min, $sec) = split(/:/, $vartime);
+ $mon = $mon - 1; #time uses 0-11 for months :(
+ my $epoch_time = timelocal($sec, $min, $hr, $mday, $mon, $yr);
+ return $epoch_time;
+} ## end sub convert_to_epoch_seconds
+
+
+#/////////////////////////////////////////////////////////////////////////////
+
+=head2 check_endtimenotice_interval
+
+ Parameters : endtime
+ Returns : scalar: 2week, 1week, 2day, 1day, 30min, or 0
+ Description : used to send a notice to owner regarding how far out the end of
+ their reservation is
+
+=cut
+
+sub check_endtimenotice_interval {
+ my $end = $_[0];
+ my ($package, $filename, $line, $sub) = caller(0);
+ notify($ERRORS{'WARNING'}, 0, "endtime not set") if (!defined($end));
+ my $now = time();
+ my $epochend = convert_to_epoch_seconds($end);
+ #flag on: 2 & 1 week; 2,1 day, 1 hour, 30,15,10,5 minutes
+ #2 week: between 14 days and a 14 day -15 minutes window
+ if ($epochend <= (14 * 60 * 60 * 24) && $epochend >= (14 * 60 * 60 * 24 - 15 * 60)) {
+ return (1, "2week");
+ }
+ #1 week: between 7 days and a 14 day -15 minute window
+ elsif ($epochend <= (7 * 60 * 60 * 24) && $epochend >= (7 * 60 * 60 * 24 - 15 * 60)) {
+ return (1, "1week");
+ }
+ #2 day: between 2 days and a 2 day -15 minute window
+ if ($epochend <= (2 * 60 * 60 * 24) && $epochend >= (2 * 60 * 60 * 24 - 15 * 60)) {
+ return (1, "2day");
+ }
+ #1 day: between 1 days and a 1 day -15 minute window
+ if ($epochend <= (1 * 60 * 60 * 24) && $epochend >= (1 * 60 * 60 * 24 - 15 * 60)) {
+ return (1, "1day");
+ }
+ #30-25 minutes
+ if ($epochend <= (30 * 60) && $epochend >= (25 * 60)) {
+ return (1, "30min");
+ }
+} ## end sub check_endtimenotice_interval
+#sub new_check_endtimenotice_interval {
+# my ($request_end, $base_time) = @_;
+# my ($package, $filename, $line, $sub) = caller(0);
+#
+# # Check the parameter
+# if (!defined($request_end)) {
+# notify($ERRORS{'WARNING'}, 0, "request end time was not specified"");
+# return 0;
+# }
+# elsif (!$request_end) {
+# notify($ERRORS{'WARNING'}, 0, "request end time was specified but is blank"");
+# return 0;
+# }
+#
+# # Convert the request end time to epoch seconds
+# my $end_epoch_seconds = convert_to_epoch_seconds($request_end);
+#
+# # This is only used for testing
+# my @now;
+# if ($base_time) {
+# my $base_epoch_seconds = convert_to_epoch_seconds($base_time);
+# @now = Time_to_Date($base_epoch_seconds);
+# }
+# else {
+# @now = Time_to_Date();
+# }
+#
+# # Get arrays from the Date::Calc::Time_to_Date functions for now and the end time
+# my @end = Time_to_Date($end_epoch_seconds);
+#
+# # Calculate the difference
+# my ($days, $hours, $minutes, $seconds) = Delta_DHMS(@now, @end);
+#
+# # Return a value on: 2 & 1 week; 2,1 day, 1 hour, 30,15,10,5 minutes
+# my $return_value = 0;
+#
+# # Ignore: over 14 days away
+# if ($days >= 14){
+# $return_value = 0;
+# }
+# # 2 week notice: between 14 days and a 14 day - 15 minute window
+# elsif ($days >= 13 && $hours >= 23 && $minutes >= 45){
+# $return_value = "2 weeks";
+# }
+# # Ignore: between 7 days and 14 day - 15 minute window
+# elsif ($days >= 7) {
+# $return_value = 0;
+# }
+# # 1 week notice: between 7 days and a 7 day -15 minute window
+# elsif ($days >= 6 && $hours >= 23 && $minutes >= 45) {
+# $return_value = "1 week";
+# }
+# # Ignore: between 2 days and 7 day - 15 minute window
+# elsif ($days >= 2) {
+# $return_value = 0;
+# }
+# # 2 day notice: between 2 days and a 2 day -15 minute window
+# elsif($days >= 1 && $hours >= 23 && $minutes >= 45) {
+# $return_value = "2 days";
+# }
+# # Ignore: between 1 days and 2 day - 15 minute window
+# elsif ($days >= 1) {
+# $return_value = 0;
+# }
+# # 1 day notice: between 1 days and a 1 day -15 minute window
+# elsif($days >= 0 && $hours >= 23 && $minutes >= 45) {
+# $return_value = "1 day";
+# }
+# #30-25 minutes
+# elsif ($minutes >= 25 && $minutes <= 30) {
+# $return_value = "30 minutes";
+# }
+
+# notify($ERRORS{'OK'}, 0, "days: time difference is days:$days hours:$hours minutes:$minutes, returning $return_value");
+# return $return_value;
+#}
+
+#/////////////////////////////////////////////////////////////////////////////
+
+=head2 check_blockrequest_time
+
+ Parameters : start, end, and expire times
+ Returns : 0 or 1 and task
+ Description : check current time against all three tasks
+ expire time overides end, end overrides start
+
+=cut
+
+sub check_blockrequest_time {
+ my ($start_datetime, $end_datetime, $expire_datetime) = @_;
+
+ # Check the arguments
+ if (!$start_datetime) {
+ notify($ERRORS{'WARNING'}, 0, "start time argument was not passed correctly");
+ return;
+ }
+ if (!$end_datetime) {
+ notify($ERRORS{'WARNING'}, 0, "end time argument was not passed correctly");
+ return;
+ }
+ if (!$expire_datetime) {
+ notify($ERRORS{'WARNING'}, 0, "expire time argument was not passed correctly");
+ return;
+ }
+
+ # Get the current time in epoch seconds
+ my $current_time_epoch_seconds = time();
+
+ my $expire_time_epoch_seconds = convert_to_epoch_seconds($expire_datetime);
+ my $expire_delta_minutes = int(($expire_time_epoch_seconds - $current_time_epoch_seconds) / 60);
+ #notify($ERRORS{'DEBUG'}, 0, "expire: $expire_datetime, epoch: $expire_time_epoch_seconds, delta: $expire_delta_minutes minutes");
+
+ # If expire time is in the past, remove it
+ if ($expire_delta_minutes < 0) {
+ # Block request has expired
+ notify($ERRORS{'OK'}, 0, "block request expired " . abs($expire_delta_minutes) . " minutes ago, returning 'expire'");
+ return "expire";
+ }
+
+ if ($start_datetime =~ /^-?\d*$/ || $end_datetime =~ /^-?\d*$/) {
+ notify($ERRORS{'DEBUG'}, 0, "block request is not expired but has no block times assigned to it, returning 0");
+ return 0;
+ }
+
+ # Convert the argument datetimes to epoch seconds for easy calculation
+ my $start_time_epoch_seconds = convert_to_epoch_seconds($start_datetime);
+ my $end_time_epoch_seconds = convert_to_epoch_seconds($end_datetime);
+
+ # Calculate # of seconds away start, end, and expire times are from now
+ # Positive value means time is in the future
+ my $start_delta_minutes = int(($start_time_epoch_seconds - $current_time_epoch_seconds) / 60);
+ my $end_delta_minutes = int(($end_time_epoch_seconds - $current_time_epoch_seconds) / 60);
+
+ #notify($ERRORS{'DEBUG'}, 0, "start: $start_datetime, epoch: $start_time_epoch_seconds, delta: $start_delta_minutes minutes");
+ #notify($ERRORS{'DEBUG'}, 0, "end: $end_datetime, epoch: $end_time_epoch_seconds, delta: $end_delta_minutes minutes");
+
+ # 4:00 to 4:15 hours in advance: start assigning resources
+ if ($start_delta_minutes >= (4 * 60) && $start_delta_minutes <= (4 * 60 + 10)) {
+ # Block request within start window
+ notify($ERRORS{'OK'}, 0, "block request start time is within start window ($start_delta_minutes minutes from now), returning 'start'");
+ return "start";
+ }
+
+ # 2:00 to 2:15 hours in advance: start assigning resources
+ if ($start_delta_minutes >= (2 * 60) && $start_delta_minutes <= (2 * 60 + 10)) {
+ # Block request within start window
+ notify($ERRORS{'OK'}, 0, "block request start time is within start window ($start_delta_minutes minutes from now), returning 'start'");
+ return "start";
+ }
+
+ # End time it is less than 1 minute
+ if ($end_delta_minutes < 0) {
+ # Block request end time is near
+ notify($ERRORS{'OK'}, 0, "block request end time has been reached ($end_delta_minutes minutes from now), returning 'end'");
+ return "end";
+ }
+
+ #notify($ERRORS{'DEBUG'}, 0, "block request does not need to be processed now, returning 0");
+ return 0;
+
+} ## end sub check_blockrequest_time
+
+#/////////////////////////////////////////////////////////////////////////////
+
+=head2 check_time
+
+ Parameters : $request_start, $request_end, $reservation_lastcheck, $request_state_name, $request_laststate_name
+ Returns : start, preload, end, poll, old, remove, or 0
+ Description : based on the input return a value used by vcld
+=cut
+
+sub check_time {
+ my ($request_start, $request_end, $reservation_lastcheck, $request_state_name, $request_laststate_name) = @_;
+
+ my ($package, $filename, $line, $sub) = caller(0);
+
+ # Check the arguments
+ if (!defined($request_state_name)) {
+ notify($ERRORS{'WARNING'}, 0, "\$request_state_name argument is not defined");
+ return 0;
+ }
+ if (!defined($request_laststate_name)) {
+ notify($ERRORS{'WARNING'}, 0, "\$request_laststate_name argument is not defined");
+ return 0;
+ }
+
+ # If lastcheck isn't set, set it to now
+ if (!defined($reservation_lastcheck) || !$reservation_lastcheck) {
+ $reservation_lastcheck = makedatestring();
+ }
+
+ # First convert to datetime in case epoch seconds was passed
+ if ($reservation_lastcheck !~ /\d{4}-\d{2}-\d{2}\s\d{2}:\d{2}:\d{2}/) {
+ $reservation_lastcheck = convert_to_datetime($reservation_lastcheck);
+ }
+ if ($request_end !~ /\d{4}-\d{2}-\d{2}\s\d{2}:\d{2}:\d{2}/) {
+ $request_end = convert_to_datetime($request_end);
+ }
+ if ($request_start !~ /\d{4}-\d{2}-\d{2}\s\d{2}:\d{2}:\d{2}/) {
+ $request_start = convert_to_datetime($request_start);
+ }
+
+ # Convert times to epoch seconds
+ my $lastcheck_epoch_seconds = convert_to_epoch_seconds($reservation_lastcheck);
+ my $start_time_epoch_seconds = convert_to_epoch_seconds($request_start);
+ my $end_time_epoch_seconds = convert_to_epoch_seconds($request_end);
+
+ # Get the current time epoch seconds
+ my $current_time_epoch_seconds = time();
+
+ # Calculate time differences from now in seconds
+ # These will be positive if in the future, negative if in the past
+ my $lastcheck_diff_seconds = $lastcheck_epoch_seconds - $current_time_epoch_seconds;
+ my $start_diff_seconds = $start_time_epoch_seconds - $current_time_epoch_seconds;
+ my $end_diff_seconds = $end_time_epoch_seconds - $current_time_epoch_seconds;
+
+ # Calculate the time differences from now in minutes
+ # These will be positive if in the future, negative if in the past
+ my $lastcheck_diff_minutes = round($lastcheck_diff_seconds / 60);
+ my $start_diff_minutes = round($start_diff_seconds / 60);
+ my $end_diff_minutes = round($end_diff_seconds / 60);
+
+ # Print the time differences
+ #notify($ERRORS{'OK'}, 0, "reservation lastcheck difference: $lastcheck_diff_minutes minutes");
+ #notify($ERRORS{'OK'}, 0, "request start time difference: $start_diff_minutes minutes");
+ #notify($ERRORS{'OK'}, 0, "request end time difference: $end_diff_minutes minutes");
+
+ # Check the state, and then figure out the return code
+ if ($request_state_name =~ /new|imageprep|reload|tomaintenance|tovmhostinuse/) {
+ if ($start_diff_minutes > 0) {
+ # Start time is either now or in future, $start_diff_minutes is positive
+
+ if ($start_diff_minutes > 35) {
+ #notify($ERRORS{'DEBUG'}, 0, "reservation will start in more than 35 minutes ($start_diff_minutes)");
+ return "0";
+ }
+ elsif ($start_diff_minutes >= 25 && $start_diff_minutes <= 35) {
+ notify($ERRORS{'DEBUG'}, 0, "reservation will start in 25-35 minutes ($start_diff_minutes)");
+ return "preload";
+ }
+ else {
+ #notify($ERRORS{'DEBUG'}, 0, "reservation will start less than 25 minutes ($start_diff_minutes)");
+ return "0";
+ }
+ } ## end if ($start_diff_minutes > 0)
+ else {
+ # Start time is in past, $start_diff_minutes is negative
+
+ if ($start_diff_minutes >= -17) {
+ notify($ERRORS{'DEBUG'}, 0, "reservation start time was in the past 17 minutes ($start_diff_minutes)");
+ return "start";
+ }
+ else {
+ notify($ERRORS{'DEBUG'}, 0, "reservation start time was more than 17 minutes ago ($start_diff_minutes)");
+ return "old";
+ }
+ } ## end else [ if ($start_diff_minutes > 0)
+ } ## end if ($request_state_name =~ /new|imageprep|reload|tomaintenance|tovmhostinuse/)
+
+ elsif ($request_state_name =~ /inuse|imageinuse/) {
+ if ($end_diff_minutes <= 10) {
+ #notify($ERRORS{'DEBUG'}, 0, "reservation will end in 10 minutes or less ($end_diff_minutes)");
+ return "end";
+ }
+ else {
+ # End time is more than 10 minutes in the future
+ #notify($ERRORS{'DEBUG'}, 0, "reservation will end in more than 10 minutes ($end_diff_minutes)");
+
+ if ($lastcheck_diff_minutes <= -5) {
+ #notify($ERRORS{'DEBUG'}, 0, "reservation was last checked more than 5 minutes ago ($lastcheck_diff_minutes)");
+ return "poll";
+ }
+ else {
+ #notify($ERRORS{'DEBUG'}, 0, "reservation has been checked within the past 5 minutes ($lastcheck_diff_minutes)");
+ return 0;
+ }
+ } ## end else [ if ($end_diff_minutes <= 10)
+ } ## end elsif ($request_state_name =~ /inuse|imageinuse/) [ if ($request_state_name =~ /new|imageprep|reload|tomaintenance|tovmhostinuse/)
+
+ elsif ($request_state_name =~ /complete|failed/) {
+ # Don't need to keep requests in database if laststate was...
+ if ($request_laststate_name =~ /image|deleted|makeproduction|reload|tomaintenance|tovmhostinuse/) {
+ return "remove";
+ }
+
+ if ($end_diff_minutes < 0) {
+ notify($ERRORS{'DEBUG'}, 0, "reservation end time was in the past ($end_diff_minutes)");
+ return "remove";
+ }
+ else {
+ # End time is now or in the future
+ #notify($ERRORS{'DEBUG'}, 0, "reservation end time is either right now or in the future ($end_diff_minutes)");
+ return "0";
+ }
+ } # Close if state is complete or failed
+
+ # Just return start for all other states
+ else {
+ return "start";
+ }
+
+} ## end sub check_time
+
+#/////////////////////////////////////////////////////////////////////////////
+
+=head2 time_exceeded
+
+ Parameters : $time_slice, $limit
+ Returns : 1(success) or 0(failure)
+ Description : preform a difference check,
+ if delta of now and input $time_slice
+ is less than input $limit return 1(true)
+=cut
+
+sub time_exceeded {
+
+ my ($time_slice, $limit) = @_;
+ my ($package, $filename, $line, $sub) = caller(0);
+ my $now = time();
+ my $diff = $now - $time_slice;
+ if ($diff > ($limit * 60)) {
+ #time exceeded
+ return 1;
+ }
+ else {
+ return 0;
+ }
+} ## end sub time_exceeded
+
+#/////////////////////////////////////////////////////////////////////////////
+
+=head2 mail
+
+ Parameters : $to, $subject, $mailstring, $from
+ Returns : 1(success) or 0(failure)
+ Description : send an email
+=cut
+
+sub mail {
+ my ($to, $subject, $mailstring, $from) = @_;
+ my ($package, $filename, $line, $sub) = caller(0);
+
+ # Mail::Mailer relies on sendmail as written, this causes a "die" on Windows
+ # TODO: Reqork this subroutine to not rely on sendmail
+ my $osname = lc($^O);
+ if ($osname =~ /win/i) {
+ notify($ERRORS{'OK'}, 0, "sending mail from Windows not yet supported\n-----\nTo: $to\nSubject: $subject\nFrom: $from\n$mailstring\n-----");
+ return;
+ }
+
+ # Wrap text for lines longer than 72 characters
+ #$Text::Wrap::columns = 72;
+ #$mailstring = wrap('', '', $mailstring);
+
+ # compare requestor and owner, if same only mail one
+ if (!(defined($from))) {
+ $from = "vcl_help\@ncsu.edu";
+ }
+ my $mailer = Mail::Mailer->new("sendmail", "-fitecs-vclsysroot\@engr.ncsu.edu");
+
+ if ($SHARED_MAILBOX) {
+ my $bcc = $SHARED_MAILBOX;
+ if ($mailer->open({From => $from,
+ To => $to,
+ Bcc => $bcc,
+ Subject => $subject,}))
+ {
+ print $mailer $mailstring;
+ $mailer->close();
+ notify($ERRORS{'OK'}, 0, "SUCCESS -- Sending mail To: $to, $subject");
+ }
+ else {
+ notify($ERRORS{'WARNING'}, 0, "NOTICE -- Problem sending mail to: $to From");
+ }
+ } ## end if ($SHARED_MAILBOX)
+ else {
+ if ($mailer->open({From => $from,
+ To => $to,
+ Subject => $subject,}))
+ {
+ print $mailer $mailstring;
+ $mailer->close();
+ notify($ERRORS{'OK'}, 0, "SUCCESS -- Sending mail To: $to, $subject");
+ }
+ else {
+ notify($ERRORS{'WARNING'}, 0, "NOTICE -- Problem sending mail to: $to From");
+ }
+ } ## end else [ if ($SHARED_MAILBOX)
+} ## end sub mail
+
+#/////////////////////////////////////////////////////////////////////////////
+
+=head2 setstaticaddress
+
+ Parameters : $node, $osname, $IPaddress
+ Returns : 1,0 -- success failure
+ Description : assigns statically assigned IPaddress
+=cut
+
+sub setstaticaddress {
+ my ($node, $osname, $IPaddress) = @_;
+ my ($package, $filename, $line, $sub) = caller(0);
+ notify($ERRORS{'OK'}, 0, "nodename not set") if (!defined($node));
+ notify($ERRORS{'OK'}, 0, "osname not set") if (!defined($osname));
+ notify($ERRORS{'CRITICAL'}, 0, "IPaddress not set") if (!defined($IPaddress));
+ #collect private address -- read hosts file only useful if running
+ # xcat setup and private addresses are listsed in the local
+ # /etc/hosts file
+ #should also store/pull private address from the database
+ my $privateIP;
+ if (open(HOSTS, "/etc/hosts")) {
+ my @hosts = <HOSTS>;
+ close(HOSTS);
+ foreach my $line (@hosts) {
+ if ($line =~ /([0-9]*.[0-9]*.[0-9]*.[0-9]*)\s+($node)/) {
+ $privateIP = $1;
+ notify($ERRORS{'OK'}, 0, "PrivateIP address for $node collected $privateIP");
+ last;
+ }
+ }
+ } ## end if (open(HOSTS, "/etc/hosts"))
+ if (!defined($privateIP)) {
+ notify($ERRORS{'WARNING'}, 0, "private IP address not found for $node, possible issue with regex");
+
+ }
+
+ my $identity;
+ my @sshcmd;
+ if ($osname =~ /^(rh|fc|esx)/) {
+ $identity = $IDENTITY_bladerhel;
+ #create local tmp file
+ # down interface
+ #copy tmpfile to /etc/sysconfig/network-scripts/ifcfg-eth1
+ # up interface
+ #set route for correct gateway
+ my @eth1file;
+ my $tmpfile = "/tmp/ifcfg-eth_device-$node";
+ push(@eth1file, "DEVICE=eth1\n");
+ push(@eth1file, "BOOTPROTO=static\n");
+ push(@eth1file, "IPADDR=$IPaddress\n");
+ push(@eth1file, "NETMASK=$NETMASK\n");
+ push(@eth1file, "STARTMODE=onboot\n");
+ push(@eth1file, "ONBOOT=yes\n");
+
+ #write to tmpfile
+ if (open(TMP, ">$tmpfile")) {
+ print TMP @eth1file;
+ close(TMP);
+ }
+ else {
+ #print "could not write $tmpfile $!\n";
+
+ }
+ @sshcmd = run_ssh_command($node, $identity, "/etc/sysconfig/network-scripts/ifdown $ETHDEVICE", "root");
+ foreach my $l (@{$sshcmd[1]}) {
+ if ($l) {
+ #potential problem
+ notify($ERRORS{'OK'}, 0, "sshcmd outpuer ifdown $node $l");
+ }
+ }
+ #copy new ifcfg-Device
+ if (run_scp_command($tmpfile, "$node:/etc/sysconfig/network-scripts/ifcfg-$ETHDEVICE", $identity)) {
+
+ #confirm it got there
+ undef @sshcmd;
+ @sshcmd = run_ssh_command($node, $identity, "cat /etc/sysconfig/network-scripts/ifcfg-$ETHDEVICE", "root");
+ my $success = 0;
+ foreach my $i (@{$sshcmd[1]}) {
+ if ($i =~ /$IPaddress/) {
+ notify($ERRORS{'OK'}, 0, "SUCCESS - copied ifcfg_$ETHDEVICE\n");
+ $success = 1;
+ }
+ }
+ if (unlink($tmpfile)) {
+ notify($ERRORS{'OK'}, 0, "unlinking $tmpfile");
+ }
+
+ if (!$success) {
+ notify($ERRORS{'WARNING'}, 0, "unable to copy $tmpfile to $node file ifcfg-$ETHDEVICE did get updated with $IPaddress ");
+ return 0;
+ }
+ } ## end if (run_scp_command($tmpfile, "$node:/etc/sysconfig/network-scripts/ifcfg-$ETHDEVICE"...
+
+ #bring device up
+ undef @sshcmd;
+ @sshcmd = run_ssh_command($node, $identity, "/etc/sysconfig/network-scripts/ifup $ETHDEVICE", "root");
+ #should be empty
+ foreach my $l (@{$sshcmd[1]}) {
+ if ($l) {
+ #potential problem
+ notify($ERRORS{'OK'}, 0, "possible problem with ifup $ETHDEVICE $l");
+ }
+ }
+ #correct route table - delete old default and add new in same line
+ undef @sshcmd;
+ @sshcmd = run_ssh_command($node, $identity, "/sbin/route del default", "root");
+ #should be empty
+ foreach my $l (@{$sshcmd[1]}) {
+ if ($l =~ /Usage:/) {
+ #potential problem
+ notify($ERRORS{'OK'}, 0, "possible problem with route del default $l");
+ }
+ if ($l =~ /No such process/) {
+ notify($ERRORS{'OK'}, 0, "$l - ok just no default route since we downed eth device");
+ }
+ }
+
+ notify($ERRORS{'OK'}, 0, "Setting default route");
+ undef @sshcmd;
+ @sshcmd = run_ssh_command($node, $identity, "/sbin/route add default gw $GATEWAY metric 0 $ETHDEVICE", "root");
+ #should be empty
+ foreach my $l (@{$sshcmd[1]}) {
+ if ($l =~ /Usage:/) {
+ #potential problem
+ notify($ERRORS{'OK'}, 0, "possible problem with route add default gw $GATEWAY metric 0 $ETHDEVICE");
+ }
+ if ($l =~ /No such process/) {
+ notify($ERRORS{'CRITICAL'}, 0, "problem with $node $l add default gw $GATEWAY metric 0 $ETHDEVICE ");
+ return 0;
+ }
+ } ## end foreach my $l (@{$sshcmd[1]})
+
+ #correct external sshd file
+ undef @sshcmd;
+ @sshcmd = run_ssh_command($node, $identity, "cat /etc/ssh/external_sshd_config", "root");
+ foreach my $i (@{$sshcmd[1]}) {
+ if ($i =~ /No such file or directory/) {
+ notify($ERRORS{'OK'}, 0, "possible problem $i could not read $node /etc/ssh/external_sshd_config");
+ #problem
+ }
+
+ if ($i =~ s/ListenAddress (.*)/ListenAddress $IPaddress/) {
+ notify($ERRORS{'OK'}, 0, "changed Listen Address on $node");
+ }
+
+ } ## end foreach my $i (@{$sshcmd[1]})
+
+ #Write contents to tmp file
+ my $extsshtmpfile = "/tmp/extsshtmpfile$node";
+ if (open(TMPFILE, ">$extsshtmpfile")) {
+ print TMPFILE @{$sshcmd[1]};
+ close(TMPFILE);
+ }
+ else {
+ notify($ERRORS{'OK'}, 0, "could not write tmpfile $extsshtmpfile $!");
+ }
+
+ #copy back to host
+ if (run_scp_command($extsshtmpfile, "$node:/etc/ssh/external_sshd_config", $identity)) {
+ notify($ERRORS{'OK'}, 0, "success copied $extsshtmpfile to $node");
+ }
+ else {
+ notify($ERRORS{'WARNING'}, 0, "could not write copy $extsshtmpfile to $node");
+ }
+ if (unlink($extsshtmpfile)) {
+ notify($ERRORS{'OK'}, 0, "unlinking $extsshtmpfile");
+ }
+
+ #modify /etc/resolve.conf
+ my $search;
+ undef @sshcmd;
+ @sshcmd = run_ssh_command($node, $identity, "cat /etc/resolv.conf", "root");
+ foreach my $l (@{$sshcmd[1]}) {
+ chomp($l);
+ if ($l =~ /search/) {
+ $search = $l;
+ }
+ }
+
+ if (defined($search)) {
+ my @resolvconf;
+ push(@resolvconf, "$search\n");
+ my ($s1, $s2, $s3);
+ if ($DNSserver =~ /,/) {
+ ($s1, $s2, $s3) = split(/,/, $DNSserver);
+ }
+ else {
+ $s1 = $DNSserver;
+ }
+ push(@resolvconf, "nameserver $s1\n");
+ push(@resolvconf, "nameserver $s2\n") if (defined($s2));
+ push(@resolvconf, "nameserver $s3\n") if (defined($s3));
+ my $rtmpfile = "/tmp/resolvconf$node";
+ if (open(RES, ">$rtmpfile")) {
+ print RES @resolvconf;
+ close(RES);
+ }
+ else {
+ notify($ERRORS{'OK'}, 0, "could not write to $rtmpfile $!");
+ }
+ #put resolve.conf file back on node
+ notify($ERRORS{'OK'}, 0, "copying in new resolv.conf");
+ if (run_scp_command($rtmpfile, "$node:/etc/resolv.conf", $identity)) {
+ notify($ERRORS{'OK'}, 0, "SUCCESS copied new resolv.conf to $node");
+ }
+ else {
+ notify($ERRORS{'OK'}, 0, "FALIED to copied new resolv.conf to $node");
+ return 0;
+ }
+
+ if (unlink($rtmpfile)) {
+ notify($ERRORS{'OK'}, 0, "unlinking $rtmpfile");
+ }
+ } ## end if (defined($search))
+ else {
+ notify($ERRORS{'WARNING'}, 0, "pulling resolve.conf from $node failed output= @{ $sshcmd[1] }");
+ }
+ } ## end if ($osname =~ /^(rh|fc|esx)/)
+ elsif ($osname =~ /^(win|vmwarewin|vista)/) {
+ $identity = $IDENTITY_wxp;
+ #scan adapter list to figure out which adapter is public
+ # run netsh command to set the public adapter to static
+ # correct the route table
+
+ my $myadapter;
+ my %ip;
+ my ($privateadapter, $publicadapter);
+ undef @sshcmd;
+ @sshcmd = run_ssh_command($node, $identity, "ipconfig -all", "root");
+ # build hash of needed info and set the correct private adapter.
+ my $id = 1;
+ foreach my $a (@{$sshcmd[1]}) {
+ if ($a =~ /Ethernet adapter (.*):/) {
+ $myadapter = $1;
+ $ip{$myadapter}{"id"} = $id;
+ $ip{$myadapter}{"private"} = 0;
+ }
+ if ($a =~ /IP Address([\s.]*): $privateIP/) {
+ $ip{$myadapter}{"private"} = 1;
+ }
+ if ($a =~ /Physical Address([\s.]*): ([-0-9]*)/) {
+ $ip{$myadapter}{"MACaddress"} = $2;
+ }
+
+ $id++;
+ } ## end foreach my $a (@{$sshcmd[1]})
+
+
+ foreach my $key (keys %ip) {
+ if (defined($ip{$key}{private})) {
+ if (!($ip{$key}{private})) {
+ $publicadapter = "\"$key\"";
+ }
+ }
+ }
+
+ #Make sure we have publicadapter defined
+ if (!defined($publicadapter)) {
+ notify($ERRORS{'WARNING'}, 0, "publicadapter not detected from $node");
+ return 0;
+ }
+
+ #setting publicadapter to static
+ notify($ERRORS{'OK'}, 0, "executing netsh interface ip set address name=\\\"$publicadapter\\\" source=static addr=$IPaddress mask=$NETMASK gateway=$GATEWAY gwmetric=2\n");
+ undef @sshcmd;
+ my $cmdstring = "netsh interface ip set address name=\\\"$publicadapter\\\" source=static addr=$IPaddress mask=$NETMASK gateway=$GATEWAY gwmetric=2";
+ @sshcmd = run_ssh_command($node, $identity, $cmdstring, "root");
+ foreach my $l (@{$sshcmd[1]}) {
+ if ($l =~ /Ok/) {
+ notify($ERRORS{'OK'}, 0, "successfully set $publicadapter to static");
+ }
+ }
+
+ #set dns
+ my ($s1, $s2, $s3);
+ if ($DNSserver =~ /,/) {
+ ($s1, $s2, $s3) = split(/,/, $DNSserver);
+ }
+ else {
+ $s1 = $DNSserver;
+ }
+ notify($ERRORS{'OK'}, 0, "executing setting DNS netsh interface ip set dns name=\\\"$publicadapter\\\" source=static addr=$s1 register=none\n");
+ undef @sshcmd;
+ $cmdstring = "netsh interface ip set dns name=\\\"$publicadapter\\\" source=static addr=$s1 register=none";
+ @sshcmd = run_ssh_command($node, $identity, $cmdstring, "root");
+ foreach my $l (@{$sshcmd[1]}) {
+ if ($l =~ /Ok/) {
+ notify($ERRORS{'OK'}, 0, "successfully set dns $publicadapter ");
+ }
+ }
+
+ #correct route table - delete old default and add new in same line
+ undef @sshcmd;
+ @sshcmd = run_ssh_command($node, $identity, "route del 0.0.0.0", "root");
+ #should be empty
+ foreach my $l (@{$sshcmd[1]}) {
+ if ($l) {
+ #potential problem
+ notify($ERRORS{'OK'}, 0, "possible problem with route del default $l");
+ }
+ }
+
+ notify($ERRORS{'OK'}, 0, "Setting default route");
+ undef @sshcmd;
+ @sshcmd = run_ssh_command($node, $identity, "route -p ADD 0.0.0.0 MASK 0.0.0.0 $GATEWAY METRIC 2", "root");
+ #should be empty
+ foreach my $l (@{$sshcmd[1]}) {
+ if ($l) {
+ #potential problem
+ notify($ERRORS{'OK'}, 0, "possible problem with route add default gw $GATEWAY metric 0 $ETHDEVICE");
+ }
+ }
+
+ } ## end elsif ($osname =~ /^(win|vmwarewin|vista)/) [ if ($osname =~ /^(rh|fc|esx)/)
+ else {
+
+ # osname not defined
+ }
+
+
+} ## end sub setstaticaddress
+
+#/////////////////////////////////////////////////////////////////////////////
+
+=head2 getdynamicaddress
+
+ Parameters : $node, $osname
+ Returns : assigned ipaddress
+ Description : collects the dynamically assigned ipaddress
+=cut
+
+sub getdynamicaddress {
+ my ($node, $osname) = @_;
+ my ($package, $filename, $line, $sub) = caller(0);
+ notify($ERRORS{'OK'}, 0, "nodename not set") if (!defined($node));
+ notify($ERRORS{'OK'}, 0, "osname not set") if (!defined($osname));
+
+ #collect private address -- read hosts file only useful if running
+ # xcat setup and private addresses are listsed in the local
+ # /etc/hosts file
+ #should also store/pull private address from the database
+ my $privateIP;
+ my @sshcmd;
+ if (open(HOSTS, "/etc/hosts")) {
+ my @hosts = <HOSTS>;
+ close(HOSTS);
+ foreach my $line (@hosts) {
+ if ($line =~ /([0-9]*.[0-9]*.[0-9]*.[0-9]*)\s+($node)/) {
+ $privateIP = $1;
+ notify($ERRORS{'OK'}, 0, "PrivateIP address for $node collected $privateIP");
+ last;
+ }
+ }
+ } ## end if (open(HOSTS, "/etc/hosts"))
+ if (!defined($privateIP)) {
+ notify($ERRORS{'WARNING'}, 0, "private IP address not found for $node, possible issue with regex");
+ }
+
+ my $identity;
+ my $dynaIPaddress = 0;
+ if ($osname =~ /win|vmwarewin/) {
+ $identity = $IDENTITY_wxp;
+
+ @sshcmd = run_ssh_command($node, $identity, "netsh diag show ip", "root");
+ for my $l (@{$sshcmd[1]}) {
+ next if ($l =~ /IPAddress = $privateIP/);
+ if ($l =~ /IPAddress = ([.0-9]*)/) {
+ if ($l !~ /IPAddress = $privateIP/) {
+ #to cover sites using eth0 as public
+ $dynaIPaddress = $1;
+ }
+ }
+ }
+
+ } ## end if ($osname =~ /win|vmwarewin/)
+ elsif ($osname =~ /^(rh|fc)/) {
+ $identity = $IDENTITY_bladerhel;
+ undef @sshcmd;
+ @sshcmd = run_ssh_command($node, $identity, "/sbin/ifconfig \|grep inet", "root");
+ for my $l (@{$sshcmd[1]}) {
+ # skip class a,b,c private addresses
+ next if ($l =~ /inet addr:$privateIP/);
+ next if ($l =~ /inet addr:10.([.0-9]*)/);
+ next if ($l =~ /inet addr:127([.0-9]*)/);
+ next if ($l =~ /inet addr:172([.0-9]*)/);
+ next if ($l =~ /inet addr:192.168([.0-9]*)/);
+ if ($l =~ /inet addr:([.0-9]*)/) {
+ if ($l !~ /inet addr:$privateIP/) {
+ #to cover sites using eth0 as public
+ $dynaIPaddress = $1;
+ }
+ }
+ } ## end for my $l (@{$sshcmd[1]})
+
+ } ## end elsif ($osname =~ /^(rh|fc)/) [ if ($osname =~ /win|vmwarewin/)
+ else {
+ notify($ERRORS{'WARNING'}, 0, "OSname $osname not supported ");
+ return 0;
+ }
+ return $dynaIPaddress;
+
+} ## end sub getdynamicaddress
+
+#/////////////////////////////////////////////////////////////////////////////
+
+=head2 _set_sshd_startmode
+
+ Parameters : $node, $mode
+ Returns : 1 or 0
+ Description : sets the sshd service on winxp images to auto or manual
+=cut
+
+sub _set_sshd_startmode {
+ my ($node, $mode) = @_;
+ my ($package, $filename, $line, $sub) = caller(0);
+ notify($ERRORS{'OK'}, 0, "nodename not set") if (!defined($node));
+ notify($ERRORS{'OK'}, 0, "ipaddress not set") if (!defined($mode));
+
+ #specific to sc command
+ $mode = "demand" if ($mode eq "manual");
+
+ # start using sc to change the start mode
+ my $cmd = "cmd /c C:\/WINDOWS\/system32\/sc config sshd start= $mode";
+ my @SC = run_ssh_command($node, $IDENTITY_wxp, $cmd);
+ for my $line (@{$SC[1]}) {
+ if ($line =~ /ChangeServiceConfig SUCCESS/) {
+ notify($ERRORS{'OK'}, 0, "successfully set sshd on $node to $mode");
+ return 1;
+ }
+ }
+ notify($ERRORS{'WARNING'}, 0, "_set_sshd_startmode failed return status $SC[0] array= @{ $SC[1] }");
+
+ return 0;
+} ## end sub _set_sshd_startmode
+
+#/////////////////////////////////////////////////////////////////////////////
+
+=head2 _checknstartservice
+
+ Parameters : $service name
+ Returns : 1 or 0
+ Description : checks for running local service attempts to restart
+ xCAT specific
+=cut
+
+sub _checknstartservice {
+ my $service = $_[0];
+ my ($package, $filename, $line, $sub) = caller(0);
+ notify($ERRORS{'OK'}, 0, "service not set") if (!defined($service));
+ my $status = 0;
+ if (open(SERVICE, "/sbin/service $service status |")) {
+ while (<SERVICE>) {
+ chomp($_);
+ #notify($ERRORS{'OK'},0,"_checknstartservice: $_");
+ if ($_ =~ /running/) {
+ $status = 1;
+ notify($ERRORS{'OK'}, 0, "_checknstartservice: $service is running");
+ }
+ }
+ close(SERVICE);
+ if ($status == 1) {
+ return 1;
+ }
+ else {
+ notify($ERRORS{'OK'}, 0, "_checknstartservice: $service is not running will try to start");
+ # try to start service
+ if (open(SERVICE, "/sbin/service $service start |")) {
+ while (<SERVICE>) {
+ chomp($_);
+ notify($ERRORS{'WARNING'}, 0, "_checknstartservice: $_");
+ if ($_ =~ /started/) {
+ $status = 1;
+ last;
+ }
+ }
+ close(SERVICE);
+ if ($status == 1) {
+ return 1;
+ }
+ else {
+ notify($ERRORS{'WARNING'}, 0, "_checknstartservice: $service could not start");
+ return 0;
+ }
+ } ## end if (open(SERVICE, "/sbin/service $service start |"...
+ else {
+ notify($ERRORS{'WARNING'}, 0, "_checknstartservice: WARNING -- could not run service command for $service start. $! ");
+ return 0;
+ }
+ } ## end else [ if ($status == 1)
+ } ## end if (open(SERVICE, "/sbin/service $service status |"...
+ else {
+ notify($ERRORS{'WARNING'}, 0, "_checknstartservice: WARNING -- could not run service command for $service check. $! ");
+ return 0;
+ }
+} ## end sub _checknstartservice
+
+#/////////////////////////////////////////////////////////////////////////////
+
+=head2 check_connection
+
+ Parameters : $nodename, $ipaddress, $type, $remoteIP, $time_limit, $osname, $dbh, $requestid, $user
+ Returns : value - deleted failed timeout connected conn_wrong_ip
+ Description : uses ssh to log into remote node and preform checks on user connection
+=cut
+
+sub check_connection {
+ my ($nodename, $ipaddress, $type, $remoteIP, $time_limit, $osname, $dbh, $requestid, $user) = @_;
+ my ($package, $filename, $line, $sub) = caller(0);
+ notify($ERRORS{'OK'}, 0, "nodename not set") if (!defined($nodename));
+ notify($ERRORS{'OK'}, 0, "ipaddress not set") if (!defined($ipaddress));
+ notify($ERRORS{'OK'}, 0, "type not set") if (!defined($type));
+ notify($ERRORS{'OK'}, 0, "remoteIP not set") if (!defined($remoteIP));
+ notify($ERRORS{'OK'}, 0, "time_limit not set") if (!defined($time_limit));
+ notify($ERRORS{'OK'}, 0, "osname not set") if (!defined($osname));
+ notify($ERRORS{'OK'}, 0, "dbh not set") if (!defined($dbh));
+ notify($ERRORS{'OK'}, 0, "requestid not set") if (!defined($requestid));
+ notify($ERRORS{'OK'}, 0, "user not set") if (!defined($user));
+
+ my $start_time = time();
+ my $time_exceeded = 0;
+ my $break = 0;
+ my $ret_val = "no";
+
+ $dbh = getnewdbh() if !$dbh;
+ my $identity;
+ if ($osname =~ /win|vmwarewin|vmwareesxwin|vista/) {
+ $identity = $IDENTITY_wxp;
+ }
+ elsif ($osname =~ /^(rh[0-9]image|rhel[0-9]|fc[0-9]image|rhfc[0-9]|rhas[0-9]|centos)/) {
+ $identity = $IDENTITY_bladerhel;
+ }
+ # Figure out number of loops for log messates
+ my $maximum_loops = $time_limit * 2;
+ my $loop_count = 0;
+ my @SSHCMD;
+
+ while (!$break) {
+ $loop_count++;
+
+ notify($ERRORS{'OK'}, 0, "checking for connection by $user on $nodename, attempt $loop_count ");
+
+ # confirm we still have an active db handle
+ if (!$dbh || !($dbh->ping)) {
+ notify($ERRORS{'WARNING'}, 0, "database handle died, trying to create another one");
+ $dbh = getnewdbh();
+ notify($ERRORS{'OK'}, 0, "database handle re-set") if ($dbh->ping);
+ notify($ERRORS{'WARNING'}, 0, "inuse process: database handle NOT re-set") if (!($dbh->ping));
+ }
+ if (is_request_deleted($requestid)) {
+ notify($ERRORS{'OK'}, 0, "user has deleted request");
+ $break = 1;
+ $ret_val = "deleted";
+ return $ret_val;
+ }
+ #notify($ERRORS{'OK'},0,"comparing wait time for connection");
+ $time_exceeded = time_exceeded($start_time, $time_limit);
+ if ($time_exceeded) {
+ notify($ERRORS{'OK'}, 0, "$time_limit minute time limit exceeded begin cleanup process");
+ #time_exceeded, begin cleanup process
+ $break = 1;
+ if ($package =~ /reserved/) {
+ notify($ERRORS{'OK'}, 0, "user never logged in returning nologin");
+ $ret_val = "nologin";
+ }
+ else {
+ $ret_val = "timeout";
+ }
+ return $ret_val;
+ } ## end if ($time_exceeded)
+ else { #time not exceeded check for connection
+ if ($type =~ /blade|virtualmachine/) {
+ my $shortnodename = $nodename;
+ $shortnodename = $1 if ($nodename =~ /([-_a-zA-Z0-9]*)\./);
+ if ($osname =~ /win|vmwarewin/) {
+ undef @SSHCMD;
+ @SSHCMD = run_ssh_command($shortnodename, $identity, "netstat -an", "root", 22, 1);
+ foreach my $line (@{$SSHCMD[1]}) {
+ #check for rdp and ssh connections
+ # rdp:3389,ssh:22
+ #check for connection refused, if ssh is gone something
+ #has happenned put in timeout state
+ if ($line =~ /Connection refused|Permission denied/) {
+ chomp($line);
+ notify($ERRORS{'WARNING'}, 0, "$line");
+ if ($package =~ /reserved/) {
+ $ret_val = "failed";
+ }
+ else {
+ $ret_val = "timeout";
+ }
+ return $ret_val;
+ } ## end if ($line =~ /Connection refused|Permission denied/)
+ if ($line =~ /\s+($ipaddress:3389)\s+([.0-9]*):([0-9]*)\s+(ESTABLISHED)/) {
+ if ($2 eq $remoteIP) {
+ $break = 1;
+ $ret_val = "connected";
+ return $ret_val;
+ }
+ else {
+ #this isn't the remoteIP
+ $ret_val = "conn_wrong_ip";
+ return $ret_val;
+ }
+ } ## end if ($line =~ /\s+($ipaddress:3389)\s+([.0-9]*):([0-9]*)\s+(ESTABLISHED)/)
+ } #foreach
+
+ } ## end if ($osname =~ /win|vmwarewin/)
+ #elsif($osname =~ /^(rhel|rh3image|rh4image|rhfc|fc)/){
+ elsif ($osname =~ /^(rh[0-9]image|rhel[0-9]|fc[0-9]image|rhfc[0-9]|rhas[0-9]|centos)/) {
+ #run two checks
+ # 1:check connected IP address
+ # 2:simply check who ouput
+ my @lines;
+ undef @SSHCMD;
+ @SSHCMD = run_ssh_command($shortnodename, $identity, "netstat -an", "root", 22, 1);
+ foreach my $line (@{$SSHCMD[1]}) {
+ if ($line =~ /Connection refused|Permission denied/) {
+ chomp($line);
+ notify($ERRORS{'WARNING'}, 0, "$line");
+ if ($package =~ /reserved/) {
+ $ret_val = "failed";
+ }
+ else {
+ $ret_val = "timeout";
+ }
+ return $ret_val;
+ } ## end if ($line =~ /Connection refused|Permission denied/)
+ if ($line =~ /tcp\s+([0-9]*)\s+([0-9]*)\s($ipaddress:22)\s+([.0-9]*):([0-9]*)(.*)(ESTABLISHED)/) {
+ if ($4 eq $remoteIP) {
+ $break = 1;
+ $ret_val = "connected";
+ return $ret_val;
+ }
+ else {
+ #this isn't the remoteIP
+ $ret_val = "conn_wrong_ip";
+ return $ret_val;
+ }
+ } # tcp check
+ } #foreach
+ #who; too make sure we didn't miss it through netstat
+ undef @SSHCMD;
+ @SSHCMD = run_ssh_command($shortnodename, $identity, "who", "root");
+ foreach my $w (@{$SSHCMD[1]}) {
+ if ($w =~ /$user/) {
+ $break = 1;
+ notify($ERRORS{'CRITICAL'}, 0, "found user connected through who command on node $nodename , strange that netstat missed it\nnetstat output:\n @lines");
+ $ret_val = "connected";
+ return $ret_val;
+ }
+ }
+
+ } ## end elsif ($osname =~ /^(rh[0-9]image|rhel[0-9]|fc[0-9]image|rhfc[0-9]|rhas[0-9]|centos)/) [ if ($osname =~ /win|vmwarewin/)
+ } ## end if ($type =~ /blade|virtualmachine/)
+ elsif ($type eq "lab") {
+ my $identity;
+ if ($osname =~ /sun4x_/) {
+ $identity = $IDENTITY_solaris_lab;
+ }
+ elsif ($osname =~ /rhel/) {
+ $identity = $IDENTITY_linux_lab;
+ }
+ else {
+ #if all else fails
+ $identity = $IDENTITY_solaris_lab;
+ }
+ undef @SSHCMD;
+ @SSHCMD = run_ssh_command($nodename, $identity, "netstat -an", "vclstaff", 24, 1);
+ foreach my $line (@{$SSHCMD[1]}) {
+ chomp($line);
+ if ($line =~ /Connection refused|Permission denied/) {
+ notify($ERRORS{'WARNING'}, 0, "$line");
+ if ($package =~ /reserved/) {
+ $ret_val = "failed";
+ }
+ else {
+ $ret_val = "timeout";
+ }
+ return $ret_val;
+ } ## end if ($line =~ /Connection refused|Permission denied/)
+ if ($osname =~ /sun4x_/) {
+ if ($line =~ /\s*($ipaddress\.22)\s+([.0-9]*)\.([0-9]*)(.*)(ESTABLISHED)/) {
+ if ($2 eq $remoteIP) {
+ $break = 1;
+ $ret_val = "connected";
+ return $ret_val;
+ }
+ else {
+ #this isn't the remoteIP
+ $ret_val = "conn_wrong_ip";
+ return $ret_val;
+ }
+ } ## end if ($line =~ /\s*($ipaddress\.22)\s+([.0-9]*)\.([0-9]*)(.*)(ESTABLISHED)/)
+ } ## end if ($osname =~ /sun4x_/)
+ elsif ($osname =~ /rhel/) {
+ if ($line =~ /tcp\s+([0-9]*)\s+([0-9]*)\s($ipaddress:22)\s+([.0-9]*):([0-9]*)(.*)(ESTABLISHED)/) {
+ if ($4 eq $remoteIP) {
+ $break = 1;
+ $ret_val = "connected";
+ return $ret_val;
+ }
+ else {
+ #this isn't the remoteIP
+ $ret_val = "conn_wrong_ip";
+ return $ret_val;
+ }
+ } ## end if ($line =~ /tcp\s+([0-9]*)\s+([0-9]*)\s($ipaddress:22)\s+([.0-9]*):([0-9]*)(.*)(ESTABLISHED)/)
+ if ($line =~ /tcp\s+([0-9]*)\s+([0-9]*)\s::ffff:($ipaddress:22)\s+::ffff:([.0-9]*):([0-9]*)(.*)(ESTABLISHED) /) {
+ if ($4 eq $remoteIP) {
+ $break = 1;
+ $ret_val = "connected";
+ return $ret_val;
+ }
+ else {
+ #this isn't the remoteIP
+ $ret_val = "conn_wrong_ip";
+ return $ret_val;
+ }
+ } ## end if ($line =~ /tcp\s+([0-9]*)\s+([0-9]*)\s::ffff:($ipaddress:22)\s+::ffff:([.0-9]*):([0-9]*)(.*)(ESTABLISHED) /)
+ } ## end elsif ($osname =~ /rhel/) [ if ($osname =~ /sun4x_/)
+ } #foreach
+ } #if lab
+ } #else
+ #sleep 30;
+ sleep 20;
+ } #while
+ return $ret_val;
+} ## end sub check_connection
+
+#/////////////////////////////////////////////////////////////////////////////
+
+=head2 isconnected
+
+ Parameters : $nodename, $type, $remoteIP, $osname, $ipaddress
+ Returns : 1 connected 0 not connected
+ Description : confirms user is connected to node
+ assumes port 3389 for windows and port 22 for linux/solaris
+=cut
+
+sub isconnected {
+ my ($nodename, $type, $remoteIP, $osname, $ipaddress) = @_;
+ my ($package, $filename, $line, $sub) = caller(0);
+ notify($ERRORS{'OK'}, 0, "nodename not set") if (!defined($nodename));
+ notify($ERRORS{'OK'}, 0, "type not set") if (!defined($type));
+ notify($ERRORS{'OK'}, 0, "remoteIP not set") if (!defined($remoteIP));
+ notify($ERRORS{'OK'}, 0, "osname not set") if (!defined($osname));
+ notify($ERRORS{'OK'}, 0, "ipaddress not set") if (!defined($ipaddress));
+
+ my @netstat;
+ my @SSHCMD;
+ if ($type =~ /blade|virtualmachine/) {
+ my $shortname = 0;
+ $shortname = $1 if ($nodename =~ /([-_a-zA-Z0-9]*)\./);
+ if ($shortname) {
+ #convert shortname
+ $nodename = $shortname;
+ }
+
+ if ($osname =~ /win|vmwarewin/) {
+ #notify($ERRORS{'OK'},0,"checking $nodename $ipaddress");
+ undef @SSHCMD;
+ @SSHCMD = run_ssh_command($shortname, $IDENTITY_wxp, "netstat -an", "root", 22, 1);
+ foreach my $line (@{$SSHCMD[1]}) {
+ chomp($line);
+ if ($line =~ /Connection refused/) {
+ notify($ERRORS{'WARNING'}, 0, "$line");
+ return 0;
+ }
+ #if($line =~ /\s+($ipaddress:3389)\s+([.0-9]*):([0-9]*)\s+(ESTABLISHED)/){
+ if ($line =~ /\s+(TCP\s+[.0-9]*:3389)\s+([.0-9]*):([0-9]*)\s+(ESTABLISHED)/) {
+ #notify($ERRORS{'WARNING'},0,"$line");
+ return 1 if ($2 eq $remoteIP);
+ if ($2 ne $remoteIP) {
+ notify($ERRORS{'WARNING'}, 0, "not correct remote IP is connected");
+ return 1;
+ }
+ }
+ } ## end foreach my $line (@{$SSHCMD[1]})
+ } ## end if ($osname =~ /win|vmwarewin/)
+ elsif ($osname =~ /^(rh[0-9]image|rhel[0-9]|fc[0-9]image|rhfc[0-9]|rhas[0-9])/) {
+ undef @SSHCMD;
+ @SSHCMD = run_ssh_command($nodename, $IDENTITY_bladerhel, "netstat -an", "root", 22, 1);
+ foreach my $line (@{$SSHCMD[1]}) {
+ chomp($line);
+ if ($line =~ /Warning/) {
+ if (known_hosts($nodename, "linux", $ipaddress)) {
+ #good
+ }
+ next;
+ }
+ if ($line =~ /Connection refused/) {
+ notify($ERRORS{'WARNING'}, 0, "$line");
+ return 0;
+ }
+ if ($line =~ /tcp\s+([0-9]*)\s+([0-9]*)\s($ipaddress:22)\s+([.0-9]*):([0-9]*)(.*)(ESTABLISHED)/) {
+ return 1 if ($4 eq $remoteIP);
+ if ($4 ne $remoteIP) {
+ notify($ERRORS{'WARNING'}, 0, "not correct remote IP connected: $line");
+ return 1;
+ }
+ }
+ } ## end foreach my $line (@{$SSHCMD[1]})
+ } ## end elsif ($osname =~ /^(rh[0-9]image|rhel[0-9]|fc[0-9]image|rhfc[0-9]|rhas[0-9])/) [ if ($osname =~ /win|vmwarewin/)
+ return 0;
+ } ## end if ($type =~ /blade|virtualmachine/)
+ elsif ($type eq "lab") {
+ my $identity;
+ if ($osname =~ /sun4x_/) {
+ $identity = $IDENTITY_solaris_lab;
+ }
+ elsif ($osname =~ /realmrhel/) {
+ $identity = $IDENTITY_linux_lab;
+ }
+ else {
+ #if all else fails
+ notify($ERRORS{'OK'}, 0, "osname $osname not found setting identity file to default");
+ $identity = $IDENTITY_solaris_lab;
+ }
+ undef @SSHCMD;
+ @SSHCMD = run_ssh_command($nodename, $identity, "netstat -an", "vclstaff", 24, 1);
+ foreach my $line (@{$SSHCMD[1]}) {
+ chomp($line);
+ if ($line =~ /Connection refused/) {
+ notify($ERRORS{'WARNING'}, 0, "$nodename $line");
+ return 0;
+ }
+ if ($osname =~ /sun4x_/) {
+ if ($line =~ /\s*($ipaddress\.22)\s+([.0-9]*)\.([0-9]*)(.*)(ESTABLISHED)/) {
+ return 1 if ($2 eq $remoteIP);
+ if ($2 ne $remoteIP) {
+ notify($ERRORS{'WARNING'}, 0, "not correct remote IP connected $4");
+ return 1;
+ }
+ }
+ }
+ elsif ($osname =~ /realmrhel3/) {
+ if ($line =~ /tcp\s+([0-9]*)\s+([0-9]*)\s($ipaddress:22)\s+([.0-9]*):([0-9]*)(.*)(ESTABLISHED)/) {
+ return 1 if ($4 eq $remoteIP);
+ if ($4 ne $remoteIP) {
+ notify($ERRORS{'WARNING'}, 0, "not correct remote IP connected $4");
+ return 1;
+ }
+ }
+ }
+ } ## end foreach my $line (@{$SSHCMD[1]})
+ return 0;
+ } ## end elsif ($type eq "lab") [ if ($type =~ /blade|virtualmachine/)
+} ## end sub isconnected
+
+#/////////////////////////////////////////////////////////////////////////////
+
+=head2 update_preload_fla
+
+ Parameters : request id, flag 1,0
+ Returns : 1 success 0 failure
+ Description : update preload flag
+
+=cut
+
+sub update_preload_flag {
+ my ($request_id, $flag) = @_;
+
+ my ($package, $filename, $line, $sub) = caller(0);
+
+ notify($ERRORS{'WARNING'}, 0, "request id is not defined") unless (defined($request_id));
+ notify($ERRORS{'WARNING'}, 0, "preload flag is not defined") unless (defined($flag));
+
+ my $update_statement = "
+ UPDATE
+ request
+ SET
+ preload = $flag
+ WHERE
+ id = $request_id
+ ";
+
+ # Call the database execute subroutine
+ if (database_execute($update_statement)) {
+ # Update successful
+ notify($ERRORS{'OK'}, $LOGFILE, "preload flag updated for request_id $request_id ");
+ return 1;
+ }
+ else {
+ notify($ERRORS{'CRITICAL'}, 0, "unable to update preload flag updated for request_id $request_id");
+ return 0;
+ }
+} ## end sub update_preload_flag
+
+#/////////////////////////////////////////////////////////////////////////////
+
+=head2 update_request_state
+
+ Parameters : request id, state name, last state(optional), log(optional)
+ Returns : 1 success 0 failure
+ Description : update states
+
+=cut
+
+sub update_request_state {
+ my ($request_id, $state_name, $laststate_name, $log) = @_;
+ my ($package, $filename, $line, $sub) = caller(0);
+
+ # Check the passed parameters
+ if (!defined($request_id)) {
+ notify($ERRORS{'WARNING'}, $log, "unable to update request state, request id is not defined");
+ return 0;
+ }
+ if (!defined($state_name)) {
+ notify($ERRORS{'WARNING'}, $log, "unable to update request $request_id state, state name not defined");
+ return 0;
+ }
+
+ my $update_statement;
+
+ # Determine whether or not to update laststate, construct the SQL statement
+ if (defined $laststate_name && $laststate_name ne "") {
+ $update_statement = "
+ UPDATE
+ request,
+ state state,
+ state laststate
+ SET
+ request.stateid = state.id,
+ request.laststateid = laststate.id
+ WHERE
+ state.name = \'$state_name\'
+ AND laststate.name = \'$laststate_name\'
+ AND request.id = $request_id
+ ";
+ } ## end if (defined $laststate_name && $laststate_name...
+ else {
+ $update_statement = "
+ UPDATE
+ request,
+ state state
+ SET
+ request.stateid = state.id
+ WHERE
+ state.name = \'$state_name\'
+ AND request.id = $request_id
+ ";
+
+ $laststate_name = 'unchanged';
+ } ## end else [ if (defined $laststate_name && $laststate_name...
+
+ # Call the database execute subroutine
+ if (database_execute($update_statement)) {
+ # Update successful
+ notify($ERRORS{'OK'}, $LOGFILE, "request $request_id state updated to: $state_name, laststate to: $laststate_name");
+ return 1;
+ }
+ else {
+ notify($ERRORS{'CRITICAL'}, 0, "unable to update states for request $request_id");
+ return 0;
+ }
+} ## end sub update_request_state
+
+#/////////////////////////////////////////////////////////////////////////////
+
+=head2 update_computer_state
+
+ Parameters : $computer_id, $state_name, $log
+ Returns : 1 success 0 failure
+ Description : update computer state
+
+=cut
+
+sub update_computer_state {
+ my ($computer_id, $state_name, $log) = @_;
+
+ my ($package, $filename, $line, $sub) = caller(0);
+
+ notify($ERRORS{'WARNING'}, $log, "computer id is not defined") unless (defined($computer_id));
+ notify($ERRORS{'WARNING'}, $log, "statename is not defined") unless (defined($state_name));
+ return 0 unless (defined $computer_id && defined $state_name);
+
+ my $update_statement = "
+ UPDATE
+ computer,
+ state
+ SET
+ computer.stateid = state.id
+ WHERE
+ state.name = \'$state_name\'
+ AND computer.id = $computer_id
+ ";
+
+ # Call the database execute subroutine
+ if (database_execute($update_statement)) {
+ # Update successful
+ notify($ERRORS{'OK'}, $LOGFILE, "computer $computer_id state updated to: $state_name");
+ return 1;
+ }
+ else {
+ notify($ERRORS{'CRITICAL'}, 0, "unable to update states for computer $computer_id");
+ return 0;
+ }
+} ## end sub update_computer_state
+
+#/////////////////////////////////////////////////////////////////////////////
+
+=head2 update_request_password
+
+ Parameters : $reservation_id, $password
+ Returns : 1 success 0 failure
+ Description : updates password field for reservation id
+
+=cut
+
+sub update_request_password {
+ my ($reservation_id, $password) = @_;
+
+ my ($package, $filename, $line, $sub) = caller(0);
+
+ notify($ERRORS{'WARNING'}, 0, "reservation id is not defined") unless (defined($reservation_id));
+ notify($ERRORS{'WARNING'}, 0, "password is not defined") unless (defined($password));
+
+ my $update_statement = "
+ UPDATE
+ reservation
+ SET
+ pw = \'$password\'
+ WHERE
+ id = $reservation_id
+ ";
+
+ # Call the database execute subroutine
+ if (database_execute($update_statement)) {
+ # Update successful
+ notify($ERRORS{'OK'}, $LOGFILE, "password updated for reservation_id $reservation_id ");
+ return 1;
+ }
+ else {
+ notify($ERRORS{'CRITICAL'}, 0, "unable to update password for reservation $reservation_id");
+ return 0;
+ }
+} ## end sub update_request_password
+
+#/////////////////////////////////////////////////////////////////////////////
+
+=head2 is_request_deleted
+
+ Parameters : $request_id
+ Returns : return 1 if request state or laststate is set to deleted or if request does not exist
+ return 0 if request exists and neither request state nor laststate is set to deleted1 success 0 failure
+ Description : checks if request has been deleted
+
+=cut
+
+sub is_request_deleted {
+
+ my ($request_id) = @_;
+ my ($package, $filename, $line, $sub) = caller(0);
+
+ # Check the passed parameter
+ if (!(defined($request_id))) {
+ notify($ERRORS{'WARNING'}, 0, "request ID was not specified");
+ return 0;
+ }
+
+ # Create the select statement
+ my $select_statement = "
+ SELECT
+ request.stateid AS currentstate_id,
+ request.laststateid AS laststate_id,
+ currentstate.name AS currentstate_name,
+ laststate.name AS laststate_name
+ FROM
+ request, state currentstate, state laststate
+ WHERE
+ request.id = $request_id
+ AND request.stateid = currentstate.id
+ AND request.laststateid = laststate.id
+ ";
+
+ # Call the database select subroutine
+ # This will return an array of one or more rows based on the select statement
+ my @selected_rows = database_select($select_statement);
+
+ # Check to make sure 1 row was returned
+ if (scalar @selected_rows == 0) {
+ return 1;
+ }
+ elsif (scalar @selected_rows > 1) {
+ notify($ERRORS{'WARNING'}, 0, "" . scalar @selected_rows . " rows were returned from database select");
+ return 0;
+ }
+
+ my $state_name = $selected_rows[0]{currentstate_name};
+ my $laststate_name = $selected_rows[0]{laststate_name};
+
+ #notify($ERRORS{'DEBUG'}, 0,"state=$state_name, laststate=$laststate_name");
+
+ if ($state_name eq 'deleted' || $laststate_name eq 'deleted') {
+ return 1;
+ }
+
+ return 0;
+} ## end sub is_request_deleted
+
+#/////////////////////////////////////////////////////////////////////////////
+
+=head2 is_reservation_deleted
+
+ Parameters : $reservation_id
+ Returns : return 1 if reservation's request state or laststate is set to deleted or if reservation does not exist
+ return 0 if reservation exists and neither request state nor laststate is set to deleted: 1 success, 0 failure
+ Description : checks if reservation has been deleted
+
+=cut
+
+sub is_reservation_deleted {
+ my ($reservation_id) = @_;
+
+ # Check the passed parameter
+ if (!(defined($reservation_id))) {
+ notify($ERRORS{'WARNING'}, 0, "reservation ID was not specified");
+ return 0;
+ }
+
+ # Create the select statement
+ my $select_statement = "
+ SELECT
+ reservation.id AS reservation_id,
+ request.stateid AS currentstate_id,
+ request.laststateid AS laststate_id,
+ currentstate.name AS currentstate_name,
+ laststate.name AS laststate_name
+ FROM
+ reservation, request, state currentstate, state laststate
+ WHERE
+ reservation.id = $reservation_id
+ AND reservation.requestid = request.id
+ AND request.stateid = currentstate.id
+ AND request.laststateid = laststate.id
+ ";
+
+ # Call the database select subroutine
+ # This will return an array of one or more rows based on the select statement
+ my @selected_rows = database_select($select_statement);
+
+ # Check to make sure 1 row was returned
+ if (scalar @selected_rows == 0) {
+ return 1;
+ }
+ elsif (scalar @selected_rows > 1) {
+ notify($ERRORS{'WARNING'}, 0, "" . scalar @selected_rows . " rows were returned from database select");
+ return 0;
+ }
+
+ my $state_name = $selected_rows[0]{currentstate_name};
+ my $laststate_name = $selected_rows[0]{laststate_name};
+
+ #notify($ERRORS{'DEBUG'}, 0,"state=$state_name, laststate=$laststate_name");
+
+ if ($state_name eq 'deleted' || $laststate_name eq 'deleted') {
+ return 1;
+ }
+
+ return 0;
+} ## end sub is_reservation_deleted
+
+#/////////////////////////////////////////////////////////////////////////////
+
+=head2 is_request_imaging
+
+ Parameters : $request_id
+ Returns : return 1 if request state or laststate is set to image or if request does not exist
+ return 0 if request exists and neither request state nor laststate is set to image success 0 failure
+ Description : checks if request is in imaging mode
+
+=cut
+
+sub is_request_imaging {
+
+ my ($request_id) = @_;
+ my ($package, $filename, $line, $sub) = caller(0);
+
+ # Check the passed parameter
+ if (!(defined($request_id))) {
+ notify($ERRORS{'WARNING'}, 0, "request ID was not specified");
+ return 0;
+ }
+
+ # Create the select statement
+ my $select_statement = "
+ SELECT
+ request.stateid AS currentstate_id,
+ request.laststateid AS laststate_id,
+ currentstate.name AS currentstate_name,
+ laststate.name AS laststate_name
+ FROM
+ request, state currentstate, state laststate
+ WHERE
+ request.id = $request_id
+ AND request.stateid = currentstate.id
+ AND request.laststateid = laststate.id
+ ";
+
+ # Call the database select subroutine
+ # This will return an array of one or more rows based on the select statement
+ my @selected_rows = database_select($select_statement);
+
+ # Check to make sure 1 row was returned
+ if (scalar @selected_rows == 0) {
+ return 1;
+ }
+ elsif (scalar @selected_rows > 1) {
+ notify($ERRORS{'WARNING'}, 0, "" . scalar @selected_rows . " rows were returned from database select");
+ return 0;
+ }
+
+ my $state_name = $selected_rows[0]{currentstate_name};
+ my $laststate_name = $selected_rows[0]{laststate_name};
+
+ notify($ERRORS{'DEBUG'}, 0, "is_request_imaging currentstate= $state_name laststate= $laststate_name");
+
+ if ($state_name eq 'image' || $laststate_name eq 'image') {
+ return 1;
+ }
+
+ return 0;
+} ## end sub is_request_imaging
+
+#/////////////////////////////////////////////////////////////////////////////
+
+=head2 get_next_image_default
+
+ Parameters : $computerid
+ Returns : imageid,imagerevisionid,imagename
+ Description : Looks for any upcoming reservations
+ for supplied computerid, if starttime is
+ within 50 minutes return that imageid. Else
+ fetch and return preferred image
+=cut
+
+sub get_next_image_default {
+ my ($computerid) = @_;
+ my ($calling_package, $calling_filename, $calling_line, $calling_sub) = caller(0);
+
+ if (!defined($computerid)) {
+ notify($ERRORS{'WARNING'}, 0, "$calling_sub $calling_package missing mandatory variable: computerid ");
+ return 0;
+ }
+
+ my $select_statement = "
+ SELECT DISTINCT
+ req.start AS starttime,
+ ir.imagename AS imagename,
+ res.imagerevisionid AS imagerevisionid,
+ res.imageid AS imageid
+ FROM
+ reservation res,
+ request req,
+ image i,
+ state s,
+ imagerevision ir
+ WHERE
+ res.requestid = req.id
+ AND req.stateid = s.id
+ AND i.id = res.imageid
+ AND ir.id = res.imagerevisionid
+ AND res.computerid = $computerid
+ AND (s.name = \'new\' OR s.name = \'reload\' OR s.name = \'imageprep\')
+ ";
+
+ # Call the database select subroutine
+ # This will return an array of one or more rows based on the select statement
+ my @selected_rows = database_select($select_statement);
+ my @ret_array;
+
+ # Check to make sure 1 or more rows were returned
+ if (scalar @selected_rows > 0) {
+ # Loop through list of upcoming reservations
+ # Based on the start time load the next one
+
+ my $now = time();
+
+ # It contains a hash
+ for (@selected_rows) {
+ my %reservation_row = %{$_};
+ # $reservation_row{starttime}
+ # $reservation_row{imagename}
+ # $reservation_row{imagerevisionid}
+ # $reservation_row{imageid}
+ my $epoch_start = convert_to_epoch_seconds($reservation_row{starttime});
+ my $diff = $epoch_start - $now;
+ # If start time is less than 50 minutes from now return this image
+ notify($ERRORS{'OK'}, 0, "get_next_image_default : diff= $diff image= $reservation_row{imagename} imageid=$reservation_row{imageid}");
+ if ($diff < (50 * 60)) {
+ notify($ERRORS{'OK'}, 0, "get_next_image_default : future reservation detected diff= $diff image= $reservation_row{imagename} imageid=$reservation_row{imageid}");
+ push(@ret_array, $reservation_row{imagename}, $reservation_row{imageid}, $reservation_row{imagerevisionid});
+ return @ret_array;
+ }
+ } ## end for (@selected_rows)
+ } ## end if (scalar @selected_rows > 0)
+
+ # No upcoming reservations - fetch preferred image information
+ my $select_preferredimage = "
+ SELECT DISTINCT
+ imagerevision.imagename AS imagename,
+ imagerevision.id AS imagerevisionid,
+ image.id AS imageid
+ FROM
+ image,
+ computer,
+ imagerevision
+ WHERE
+ imagerevision.imageid = computer.preferredimageid
+ AND imagerevision.production = 1
+ AND computer.preferredimageid = image.id
+ AND computer.id = $computerid
+ ";
+
+ # Call the database select subroutine
+ # This will return an array of one or more rows based on the select statement
+ my @preferred_selected_rows = database_select($select_preferredimage);
+
+ # Check to make sure at least 1 row were returned
+ if (scalar @preferred_selected_rows == 0) {
+ notify($ERRORS{'WARNING'}, 0, "get_next_image_default failed to fetch preferred image for computerid $computerid");
+ return 0;
+ }
+ elsif (scalar @preferred_selected_rows > 1) {
+ notify($ERRORS{'WARNING'}, 0, "" . scalar @preferred_selected_rows . " rows were returned from database select");
+ return 0;
+ }
+ notify($ERRORS{'OK'}, 0, "get_next_image_default : returning preferredimage image=$preferred_selected_rows[0]{imagename} imageid=$preferred_selected_rows[0]{imageid}");
+ push(@ret_array, $preferred_selected_rows[0]{imagename}, $preferred_selected_rows[0]{imageid}, $preferred_selected_rows[0]{imagerevisionid});
+ return @ret_array;
+
+} ## end sub get_next_image
+
+#/////////////////////////////////////////////////////////////////////////////
+
+=head2 setimagid
+
+ Parameters : $dbh, $computerid, $image, $imageid, $imagerevisionid
+ Returns : 1
+ Description : updates imageid and imagerevisionid on provided computerid
+
+sub setimageid {
+ my ($dbh, $computerid, $image, $imageid, $imagerevisionid) = @_;
+ my ($package, $filename, $line, $sub) = caller(0);
+ notify($ERRORS{'WARNING'}, 0, "setimageid: computerid is not defined") if (!(defined($computerid)));
+ notify($ERRORS{'WARNING'}, 0, "setimageid: image is not defined") if (!(defined($image)));
+ notify($ERRORS{'WARNING'}, 0, "setimageid: imageid is not defined") if (!(defined($imageid)));
+ $imagerevisionid = 0 if (!(defined($imagerevisionid)));
+
+
+ my $update_statement="UPDATE computer c SET c.currentimageid = $imageid,c.imagerevisionid = $imagerevisionid WHERE c.id = $computerid" ;
+ # Call the database execute subroutine
+ if (database_execute($update_statement)) {
+ return 1;
+ }
+ else {
+ notify($ERRORS{'WARNING'}, 0, "unable to update preferredimageid");
+ return 0;
+ }
+} ## end sub setimageid
+=cut
+
+#/////////////////////////////////////////////////////////////////////////////
+
+=head2 setpreferredimage
+
+ Parameters : $computerid, $image
+ Returns : 1 success, 0 failed
+ Description : updates preferredimageid on provided computerid
+=cut
+
+sub setpreferredimage {
+ my ($computerid, $imageid) = @_;
+ my ($package, $filename, $line, $sub) = caller(0);
+ notify($ERRORS{'WARNING'}, 0, "computerid: node is not defined") if (!(defined($computerid)));
+ notify($ERRORS{'WARNING'}, 0, "imageid: node is not defined") if (!(defined($imageid)));
+
+ my $update_statement = " UPDATE computer SET preferredimageid = $imageid WHERE id = $computerid ";
+
+ # Call the database execute subroutine
+ if (database_execute($update_statement)) {
+ return 1;
+ }
+ else {
+ notify($ERRORS{'WARNING'}, 0, "unable to update preferredimageid");
+ return 0;
+ }
+} ## end sub setpreferredimage
+
+#/////////////////////////////////////////////////////////////////////////////
+
+=head2 _getcurrentimage
+
+ Parameters : $node
+ Returns : retrieve the currentimage from currentimage.txt file on the node
+ Description :
+
+=cut
+
+sub _getcurrentimage {
+
+ my $node = $_[0];
+ my ($package, $filename, $line, $sub) = caller(0);
+ notify($ERRORS{'WARNING'}, 0, "node is not defined") if (!(defined($node)));
+ # TODO - loop through the available ssh keys to figure out which one works
+ my $identity = $IDENTITY_bladerhel;
+ my @sshcmd = run_ssh_command($node, $identity, "cat currentimage.txt");
+ foreach my $s (@{$sshcmd[1]}) {
+ if ($s =~ /Warning: /) {
+ #need to run makesshgkh
+ #if (VCL::Module::Provisioning::xCAT::makesshgkh($node)) {
+ #success
+ #not worth output here
+ #}
+ #else {
+ #}
+ }
+ if ($s =~ /^(rh|win|fc|vmware)/) {
+ chomp($s);
+ if ($s =~ s/\x0d//) {
+ notify($ERRORS{'OK'}, 0, "stripped dos newline $s");
+ }
+ return $s;
+ }
+ } ## end foreach my $s (@{$sshcmd[1]})
+ return 0;
+} ## end sub _getcurrentimage
+
+#/////////////////////////////////////////////////////////////////////////////
+
+=head2 check_ssh
+
+ Parameters : $node, $port, $log
+ Returns : 1(active) or 0(inactive)
+ Description : uses check_ssh binary from tools dir to check
+ the sshd statuse on the remote node
+=cut
+
+sub check_ssh {
+ my ($node, $port, $log) = @_;
+ my ($package, $filename, $line, $sub) = caller(0);
+ $log = 0 if (!(defined($log)));
+ notify($ERRORS{'WARNING'}, $log, "node is not defined") if (!(defined($node)));
+ notify($ERRORS{'WARNING'}, $log, "port is not defined") if (!(defined($port)));
+
+ if (!defined($node)) {
+ return 0;
+ }
+ if (!defined($port)) {
+ $port = 22;
+ }
+ if (open(CHECKSSH, "$TOOLS/check_ssh -t 5 -p $port -H $node 2>&1 |")) {
+ my @ssh = <CHECKSSH>;
+ close(CHECKSSH);
+ foreach my $l (@ssh) {
+ if ($l =~ /SSH OK/) {
+ chomp($l);
+ notify($ERRORS{'OK'}, $log, " $node check_ssh module $l");
+ return 1;
+ }
+ if ($l =~ /check_ssh|No such file|Permission|socket/) {
+ chomp($l);
+ notify($ERRORS{'CRITICAL'}, $log, "$node $TOOLS/check_ssh problem $l");
+ return 0;
+ }
+ } ## end foreach my $l (@ssh)
+ return 0;
+ } ## end if (open(CHECKSSH, "$TOOLS/check_ssh -t 5 -p $port -H $node 2>&1 |"...
+
+} ## end sub check_ssh
+
+#/////////////////////////////////////////////////////////////////////////////
+
+=head2 _sshd_status
+
+ Parameters : $node, $imagename, $log
+ Returns : on or off
+ Description : actually logs into remote node
+=cut
+
+sub _sshd_status {
+ my ($node, $imagename, $log) = @_;
+ my ($package, $filename, $line, $sub) = caller(0);
+ $log = 0 if (!defined($log));
+ notify($ERRORS{'WARNING'}, $log, "node is not defined") if (!(defined($node)));
+
+ if (!nmap_port($node, 22)) {
+ return "off";
+ }
+
+ if (!(check_ssh($node, 22))) {
+ return "off";
+ }
+
+ my $identity = $IDENTITY_wxp;
+ if (defined($imagename)) {
+ $identity = $IDENTITY_bladerhel if ($imagename =~ /^(rh[0-9]image|rhel[0-9]|fc[0-9]image|rhfc[0-9]|rhas[0-9]|esx[0-9]+)/);
+ }
+ #notify($ERRORS{'OK'},$log,"identity file $identity for imagename $imagename");
+ my @sshcmd = run_ssh_command($node, $identity, "uname -s", "root");
+ foreach my $l (@{$sshcmd[1]}) {
+ if ($l =~ /^Warning:/) {
+ #if (VCL::Module::Provisioning::xCAT::makesshgkh($node)) {
+ #}
+ }
+ return "off" if ($l =~ /noping/);
+ return "off" if ($l =~ /No route to host/);
+ return "off" if ($l =~ /Connection refused/);
+ return "off" if ($l =~ /Permission denied/);
+ } ## end foreach my $l (@{$sshcmd[1]})
+ return "on";
+} ## end sub _sshd_status
+
+#/////////////////////////////////////////////////////////////////////////////
+
+=head2 _machine_os
+
+ Parameters : $node, $imagename, $log
+ Returns : 0 or system type name
+ Description : actually logs into remote node
+=cut
+
+sub _machine_os {
+ my ($node, $imagename) = @_;
+ my ($package, $filename, $line, $sub) = caller(0);
+ notify($ERRORS{'WARNING'}, 0, "node is not defined") if (!(defined($node)));
+ if (!nmap_port($node, 22)) {
+ notify($ERRORS{'OK'}, 0, "ssh port not open cannot check $node OS");
+ return 0;
+ }
+ my $identity;
+ if (defined($imagename)) {
+ $identity = $IDENTITY_bladerhel if ($imagename =~ /^(rhel|rh3image|fc|rh|esx)/);
+ }
+ else {
+ $identity = $IDENTITY_wxp;
+ }
+ my @sshcmd = run_ssh_command($node, $identity, "uname -s", "root");
+ foreach my $l (@{$sshcmd[1]}) {
+ if ($l =~ /CYGWIN_NT-5\.1/) {
+ return "WinXp";
+ }
+ elsif ($l =~ "CYGWIN_NT-5\.2") {
+ return "win2003";
+ }
+ elsif ($l =~ /Linux/) {
+ return "Linux";
+ }
+ elsif ($l =~ /Connection refused/) {
+ return 0;
+ }
+ elsif ($l =~ /No route to host/) {
+ return 0;
+ }
[... 7070 lines stripped ...]