root/lib/Resmon/Updater.pm

Revision 021df693bf0087dac900e2f698d4065c8c2856e7, 4.7 kB (checked in by Mark Harrison <mark@omniti.com>, 6 years ago)

Removing hardcoded reference to /opt/resmon

git-svn-id: https://labs.omniti.com/resmon/trunk@140 8c0face9-b7db-6ec6-c4b3-d5f7145c7d55

  • Property mode set to 100644
Line 
1 package Resmon::Updater;
2 use strict;
3 use File::Find;
4 use IO::Socket;
5
6 my $assess;
7 my $newfiles;
8 my $changedfiles;
9 my %times;
10 my $debug;
11 my $resmondir;
12
13 sub update {
14     # Ignore a HUP, otherwise we will kill ourselves when we try to reload
15     # because we are called as 'resmon'
16     $SIG{'HUP'} = 'IGNORE';
17
18     # Debug mode (currently specified with the -d option to resmon). WARNING:
19     # turning this on will reload resmon on every invocation regardless of
20     # whether there were any files updated or not.
21     $debug = shift;
22
23     $resmondir = shift;
24
25     # Check for subversion
26     my $svn;
27     foreach my $i (qw(svn /usr/bin/svn /usr/local/bin/svn /opt/omni/bin/svn)) {
28         if (-x "$i") {
29             print "Found subversion at $i\n" if $debug;
30             $svn = $i;
31             last;
32         }
33     }
34     if (!$svn) {
35         print STDERR "Cannot find subversion. Exiting.\n";
36         return 2;
37     }
38
39     # Find the last revision, in case we need to revert
40     my $last_rev=`$svn info $resmondir | awk '/^Revision/ {print \$2;}'`;
41     chomp $last_rev;
42     print "Last rev: $last_rev\n" if $debug;
43
44     # Run the update
45     chdir $resmondir || die "Cannot chdir to $resmondir: $!\n";
46
47     $assess = 0;
48     $newfiles = 0;
49     $changedfiles = 0;
50     %times = ();
51     my @dirs = ("$resmondir/lib/Resmon/Module");
52
53     find( { wanted => \&track_mod_times, no_chdir => 1 }, @dirs);
54     `$svn update -q`;
55     $assess = 1;
56     find( { wanted => \&track_mod_times, no_chdir => 1 }, @dirs);
57
58     print "Newfiles: $newfiles   ChangedFiles: $changedfiles\n" if $debug;
59
60     if ($newfiles + $changedfiles || $debug) {
61         print "We have changed files, reloading resmon...\n" if $debug;
62
63         reload_resmon();
64         ## Check to see if everything went OK
65         sleep(3);
66         if (!get_resmon_status()) {
67             print STDERR "There is a problem with the update, reverting to ";
68             print STDERR "revision $last_rev\n";
69             my $output = `$svn update -r $last_rev $resmondir`;
70             print $output if $debug;
71             reload_resmon();
72             return 3;
73         }
74         return 1;
75     }
76     return 0;
77 }
78
79 sub get_resmon_status {
80     # Load resmon config file and find what port we need to connect to to
81     # check if everything went OK
82     my $port = 0;
83     my $state, my $modstatus, my $configstatus, my $message, my $revision;
84
85     if (!open(CONF, "<$resmondir/resmon.conf")) {
86         print STDERR "Unable to open config file";
87         return 0;
88     }
89
90     while(<CONF>) {
91         if (/PORT\W*(.+);/) {
92             $port = $1;
93         }
94     }
95     close(CONF);
96     if (!$port) {
97         print STDERR "Unable to determine port";
98         return 0;
99     }
100     print "Port is: $port\n" if $debug;
101
102     my $host = "127.0.0.1";
103     my $handle = IO::Socket::INET->new(Proto     => "tcp",
104                                     PeerAddr  => $host,
105                                     PeerPort  => $port);
106     if (!$handle) {
107         print STDERR "can't connect to port $port on $host: $!";
108         return 0;
109     }
110
111     print $handle "GET /RESMON/resmon HTTP/1.0\n\n";
112     while(<$handle>) {
113         if (/<state>(\w+)<\/state>/) {
114             $state=$1;
115         } elsif (/<modstatus>(\w+)<\/modstatus>/) {
116             $modstatus=$1;
117         } elsif (/<configstatus>(\w+)<\/configstatus>/) {
118             $configstatus=$1;
119         } elsif (/<message>(.+)<\/message>/) {
120             $message=$1;
121         } elsif (/<revision>r(\d+)<\/revision>/) {
122             $revision=$1;
123         }
124     }
125
126     print "State: $state\nModules: $modstatus\n" if $debug;
127     print "Config: $configstatus\nRevision: $revision\n" if $debug;
128     print "Message: $message\n" if $debug;
129
130     if ("$state" eq "OK") {
131         print "Status is OK\n" if $debug;
132         return 1;
133     } elsif ("$state" eq "BAD") {
134         print "Status is BAD\n" if $debug;
135         return 0;
136     } else {
137         print STDERR "Unable to determine resmon status\n";
138         return 0;
139     }
140 }
141
142 sub reload_resmon {
143     ## Get a process listing
144     my $pscmd;
145     if ($^O eq 'linux' || $^O eq 'openbsd') {
146         $pscmd = 'ps ax -o pid,args';
147     } elsif ($^O eq 'solaris') {
148         $pscmd = 'ps -ef -o pid,args';
149     }
150     my $psout = `$pscmd`;
151
152     my @procs=grep(/perl (\/opt\/resmon\/|.\/)resmon/, split(/\n/, $psout));
153     foreach my $proc (@procs) {
154         $proc =~ s/^\s//;
155         print "$proc\n" if $debug;
156         my ($pid, $args) = split(/\W/, $proc, 2);
157         print "Killing PID:$pid\n" if $debug;
158         kill('HUP', $pid);
159     }
160 }
161
162 sub track_mod_times {
163   my $mtime = (stat $_)[9];
164   return unless -f $_;
165   return if /\/\.svn$/ || /\/\.svn\//;
166   if($assess == 0) {
167     $times{$_} = $mtime;
168   } else {
169     $newfiles++ unless(exists($times{$_}));
170     $changedfiles++ if(exists($times{$_}) and ($times{$_} != $mtime));
171   }
172 }
173
174 1;
Note: See TracBrowser for help on using the browser.