use strict; use warnings; # geef een lijst met rare processen die draaien op de gegeven node. sub check_processes($) { my ($node) = @_; my @allowed_ps = qw( bufdaemon cron csh dhcpd g_down getty g_event g_up idle init ktrace lvrouted.opt named ntpd pagedaemon pagezero pen ps random snmpd sshd swapper syncer syslogd top vmdaemon vnlru watchdogd ); my $ps = `ssh root\@$node "ps ax -o pid,comm=Command"`; my @ps = split "\n", $ps; shift @ps; my @illegal = (); foreach (@ps) { s/^\s*//g; my ($pid, $command) = split " "; push @illegal, $command unless ($pid < 100 || grep ($_ eq $command, @allowed_ps)); } return @illegal; } sub get_file_list($) { my ($node) = @_; my $s = `ssh root\@$node 'find /tmp -type f -exec sh -c "md5 {} ; stat -f %p {}" \\;'`; return $s; } # voor de gegeven node, bouw een dictionary op met als keys een pad en als # value een array (reference) met als eerste waarde de md5sum en als tweede # waarde de numerieke mode. sub parse_file_list($) { my ($s) = @_; my %res = (); while ($s =~ /MD5 \(([^)]*)\) = ([0-9a-f]{32})\n([0-7]{6})/g) { my @a = ($2, $3); $res{$1} = \@a; } return %res; } # bekijk de verschillen tussen de gegeven dicts (volgens het formaat van # fetch_stuff(). geef: # - een dict met dingen die in de een maar niet in de ander zitten # - een dict met dingen die in de ander maar niet in de een zitten # - een dict met keys die in allebei zitten maar waarvan de waarden # verschillen. sub diff_dicts(\%\%) { my ($a, $b) = @_; my %a = %{ $a }; my %b = %{ $b }; my %in_a_but_not_in_b = (); my %in_b_but_not_in_a = (); my %different = (); foreach (keys %a) { my $path = $_; my ($md5_a, $mode_a) = @{ $a{$path} }; if (exists $b{$path}) { my ($md5_b, $mode_b) = @{ $b{$path} }; if ($md5_a ne $md5_b or $mode_a ne $mode_b) { my @e = ($md5_a, $mode_a, $md5_b, $mode_b); $different{$path} = \@e; } } else { $in_a_but_not_in_b{$path} = $a{$path}; } } foreach (keys %b) { my $path = $_; $in_b_but_not_in_a{$path} = $b{$path} if (not exists $a{$path}); } return (\%in_a_but_not_in_b, \%in_b_but_not_in_a, \%different); } sub read_whole_file($) { my ($s) = @_; open INPUT, "<$s" or die "kan reference.txt niet openen!"; undef $/; my $content = ; close INPUT; $/ = "\n"; return $content; } #print get_file_list('lcpl'); my %reference_dict = parse_file_list(read_whole_file('reference.txt')); my @nodes = qw( lcpl ); foreach (@nodes) { my ($node) = $_; my %node_dict = parse_file_list(get_file_list($node)); my ($a, $b, $c) = diff_dicts(%node_dict, %reference_dict); my %in_a_but_not_in_b = %{ $a }; my %in_b_but_not_in_a = %{ $b }; my %different = %{ $c }; if (keys %in_a_but_not_in_b) { print "extra files on node $node:\n"; foreach (keys %in_a_but_not_in_b) { print "\t$_\n"; } } if (keys %in_b_but_not_in_a) { print "missing files on node $node:\n"; foreach (keys %in_b_but_not_in_a) { print "\t$_\n"; } } if (keys %different) { print "changed files on node $node:\n"; foreach (keys %different) { print "\t$_\n"; } } }