#! /usr/bin/env perl # Script to start any virtuals which are down. Designed to be run # from a cron job. The first pass, it will determine a virtual down # and create a flag file file into /tmp/virtname.down # on the next pass, it will see the virtual is still down and # the flag file exists in /tmp. At that point, it will start the virtual # and remove the file. # on any pass, if it sees a virtual is up, it will remove the flag file # if it exists. # thus, length of time a virtual can be off is 2x periodicity of cron entry. # we run it every 5 minutes, meaning the average down time is 7.5 min, and max # is 10 min # Looks for checkVirtuals.cfg in the same directory as the script. # that file contains a list of virtuals found with virsh list # any line with a pound sign in the first column will be ignored. use strict; use warnings; my $configFileSuffix = '.cfg'; my @servers; use File::Spec::Functions qw(rel2abs); use File::Basename; # loads the config file into $servers, which is a reference to an array sub loadConfig { my ($confName, $servers ) = @_; if ( -f $confName ) { open CONF, "<$confName" or die "Could not read $confName: $!\n"; @$servers = grep { ! m/^#/ } ; close CONF; chomp @$servers; } } # Figure out full path and name of script so we can find # config file my ( $scriptname, $path ) = fileparse( $0 ); $path = rel2abs($path); # remove any suffix, if it exists if ( $scriptname =~ m/^(.*)\.[^.]+$/ ) { $scriptname = $1; } my $configFile = $path . '/' . $scriptname . $configFileSuffix; &loadConfig( $configFile , \@servers ); die "No configuration file found at $configFile\n" unless @servers; #die "$configFile\n" . join( "\n", @servers ) . "\n"; # command used to start a virtual my $virsh = '/usr/bin/virsh start '; # find all running virtuals my $output = `virsh list`; # go through each virtual in @servers and make sure it is running foreach my $server ( @servers ) { if ( $output =~ m/$server/ ) { # its running, so unlink the flag file if it exists unlink "/tmp/$server.down" if -e "/tmp/$server.down"; } else { # not running if ( -e "/tmp/$server.down" ) { # second iteration it has been down, so start it print "$server has been down for a while, starting back up\n"; `$virsh $server`; unlink "/tmp/$server.down"; } else { # first time we've seen it, so just flag it `touch /tmp/$server.down`; } } } 1;