root/lib/Resmon/Updater.pm

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

Moving the update script to be an integral part of resmon. Run ./resmon -u to
update. Also takes the -d flag for debug info.

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