Changeset 1264
- Timestamp:
- 11/29/06 17:53:53 (5 years ago)
- Files:
Legend:
- Unmodified
- Added
- Removed
- Modified
- Copied
- Moved
people/ilmari/modularisation-branch/node/lib/Munin/Node/Runner.pm.in
r1263 r1264 22 22 =head1 SYNOPSIS 23 23 24 use Munin::Node::Runner qw(:all);25 26 load_services() or die "No services";27 28 for my $service ( list_services()) {24 use Munin::Node::Runner; 25 26 my $runner = Munin::Node::Runner->load_services() or die "No services"; 27 28 for my $service ($runner->list_services()) { 29 29 30 30 # Print the service config 31 print run_service($service, 'config');31 print $runner->run_service($service, 'config'); 32 32 33 33 # Print the service values 34 print run_service($service);34 print $runner->run_service($service); 35 35 } 36 36 … … 45 45 use strict; 46 46 use warnings; 47 use base qw(Exporter);48 47 use POSIX qw(setsid); 49 48 use IPC::Run qw(run timeout new_chunker); 50 49 51 use vars qw($VERSION $DEBUG $conffile $do_version $servicedir $sconfdir52 $sconffile $paranoia $do_usage %EXPORT_TAGS @EXPORT_OK); 53 50 use vars qw($VERSION); 51 52 $VERSION = "@@VERSION@@"; 54 53 # Default values 55 $VERSION="@@VERSION@@"; 56 $DEBUG = 0; 57 $servicedir="@@CONFDIR@@/plugins"; 58 $sconfdir="@@CONFDIR@@/plugin-conf.d"; 59 $conffile="@@CONFDIR@@/munin-node.conf"; 60 $sconffile=undef; 61 $do_usage = 0; 62 $do_version = 0; 63 $paranoia = 0; 64 65 @EXPORT_OK = qw(load_services list_services run_service $VERSION $DEBUG 66 $conffile $do_version $servicedir $sconfdir $sconffile 67 $paranoia $do_usage); 68 %EXPORT_TAGS = ( all => \@EXPORT_OK ); 69 70 my %services; 71 my %nodes; 72 73 my $FQDN =""; 74 my $defuser = getpwnam ("@@PLUGINUSER@@"); 75 my $defgroup = getgrnam ("@@GROUP@@"); 76 my @ignores = (); 77 my %sconf = ('timeout' => 10); 78 my $caddr = ""; 79 my $tls; 80 my %tls_verified = ( "level" => 0, "cert" => "", "verified" => 0, "required_depth" => 5 ); 54 my %defaults = (servicedir => "@@CONFDIR@@/plugins", 55 sconfdir => "@@CONFDIR@@/plugin-conf.d", 56 conffile => "@@CONFDIR@@/munin-node.conf", 57 defuser => scalar getpwnam("@@PLUGINUSER@@"), 58 defgroup => scalar getgrnam("@@GROUP@@"), 59 timeout => 10, 60 tls_verified => { level => 0, 61 cert => '', 62 verified => 0, 63 required_depth => 5, 64 }, 65 ); 81 66 82 67 sub list_services { 83 my $node = shift || $FQDN; 84 return grep { has_access ($_); } keys %{$nodes{$node}} if exists $nodes{$node}; 68 my $self = shift; 69 my $node = shift || $self->{config}{FQDN}; 70 my $nodes = $self->{nodes}; 71 72 return grep { $self->has_access($_); } keys %{$nodes->{$node}} if exists $nodes->{$node}; 85 73 } 86 74 87 75 sub read_config { 88 if (!check_perms ($servicedir) or !check_perms ($conffile)) { 76 my $self = shift; 77 my $conf = $self->{config}; 78 my $conffile = $conf->{conffile}; 79 my $servicedir = $conf->{servicedir}; 80 81 if (!$self->check_perms($servicedir) or !$self->check_perms($conffile)) { 89 82 die "Fatal error. Bailing out."; 90 83 } 91 84 92 if (! -f $conffile) { 93 print "ERROR: Cannot open $conffile\n"; 94 exit 1; 95 } 96 97 open FILE, $conffile or die "Cannot open $conffile\n"; 98 while (<FILE>) { 85 open(my $file, $conffile) or die "Cannot open $conffile: $!\n"; 86 while (<$file>) { 99 87 chomp; 100 88 s/#.*//; # no comments … … 104 92 /(^\w*)\s+(.*)/; 105 93 if (($1 eq "host_name" or $1 eq "hostname") and $2) { 106 $ FQDN=$2;94 $conf->{FQDN} = $2; 107 95 } elsif (($1 eq "default_plugin_user" or $1 eq "default_client_user") and $2) { 108 96 my $tmpid = $2; 109 my $defuser= get_uid ($tmpid);110 if (! defined ($ defuser)) {97 $conf->{defuser} = get_uid ($tmpid); 98 if (! defined ($conf->{defuser})) { 111 99 die "Default user defined in \"$conffile\" does not exist ($tmpid)"; 112 100 } 113 101 } elsif (($1 eq "default_plugin_group" or $1 eq "default_client_group") and $2) { 114 102 my $tmpid = $2; 115 $ defgroup= get_gid ($tmpid);116 if (! defined ($ defgroup)) {103 $conf->{defgroup} = get_gid ($tmpid); 104 if (! defined ($conf->{defgroup})) { 117 105 die "Default group defined in \"$conffile\" does not exist ($tmpid)"; 118 106 } 119 107 } elsif (($1 eq "paranoia") and defined $2) { 120 108 if ("$2" eq "no" or "$2" eq "false" or "$2" eq "off" or "$2" eq "0") { 121 $ paranoia= 0;109 $conf->{paranoia} = 0; 122 110 } else { 123 $ paranoia= 1;111 $conf->{paranoia} = 1; 124 112 } 125 113 } elsif (($1 eq "ignore_file") and defined $2) { 126 push @ignores, $2; 127 } 128 } 129 $FQDN ||= &get_fq_hostname; 130 $ENV{FQDN}=$FQDN; 114 push @{$conf->{ignores}}, $2; 115 } 116 } 117 $conf->{FQDN} ||= get_fq_hostname(); 118 $ENV{FQDN} = $conf->{FQDN}; 119 120 if ($conf->{sconffile}) 121 { 122 if (!$self->load_auth_file($conf->{sconffile})) 123 { 124 warn "Something wicked happened while reading \"$conf->{sconffile}\". Check the previous log lin 125 es for spesifics."; 126 } 127 } 128 else 129 { 130 my $sconfdir = $conf->{sconfdir}; 131 if (opendir(my $dir, $sconfdir)) 132 { 133 FILES: 134 for my $file (grep { -f "$sconfdir/$_" } readdir ($dir)) 135 { 136 next if $file =~ m/^\./; # Hidden files 137 next if $file !~ m/^([-\w.]+)$/; # Skip if any weird chars 138 $file = $1; # Not tainted anymore. 139 foreach my $regex (@{$self->{ignores}}) 140 { 141 next FILES if $file =~ /$regex/; 142 } 143 if (!$self->load_auth_file("$sconfdir/$file")) 144 { 145 warn "Something wicked happened while reading \"$sconfdir/$file\". Check the previous log lines for spesifics."; 146 } 147 } 148 closedir($dir); 149 } 150 } 131 151 } 132 152 133 153 sub load_services { 134 read_config(); 135 136 if (opendir (DIR,$sconfdir)) 137 { 154 my $self = shift; 155 # Take config as first argument unless already initialised 156 # by a sublcass constructor 157 $self = bless {config => shift || {}}, $self unless ref $self; 158 159 # Load default values 160 my $conf = $self->{config}; 161 for my $key (keys %defaults) { 162 $conf->{$key} = $defaults{$key} unless exists $conf->{key}; 163 } 164 165 $self->read_config(); 166 167 my $services = $self->{services} ||= {}; 168 my $nodes = $self->{nodes} ||= {}; 169 170 my $servicedir = $conf->{servicedir}; 171 opendir(my $dir, $servicedir) or die "Cannot open plugindir: $servicedir $!"; 138 172 FILES: 139 for my $file (grep { -f "$sconfdir/$_" } readdir (DIR)) 140 { 141 next if $file =~ m/^\./; # Hidden files 142 next if $file !~ m/^([-\w.]+)$/; # Skip if any weird chars 143 $file = $1; # Not tainted anymore. 144 foreach my $regex (@ignores) 145 { 146 next FILES if $file =~ /$regex/; 147 } 148 if (!load_auth_file ($sconfdir, $file, \%sconf)) 149 { 150 warn "Something wicked happened while reading \"$servicedir/$file\". Check the previous log lines for spesifics."; 151 } 152 } 153 closedir (DIR); 154 } 155 156 opendir (DIR,$servicedir) || die "Cannot open plugindir: $servicedir $!"; 157 FILES: 158 for my $file (grep { -f "$servicedir/$_" } readdir(DIR)) { 173 for my $file (grep { -f "$servicedir/$_" } readdir($dir)) { 159 174 next if $file =~ m/^\./; # Hidden files 160 175 next if $file =~ m/.conf$/; # Config files 161 176 next if $file !~ m/^([-\w.]+)$/; # Skip if any weird chars 162 177 $file = $1; # Not tainted anymore. 163 foreach my $regex (@ ignores)178 foreach my $regex (@{$conf->{ignores}}) 164 179 { 165 180 next FILES if $file =~ /$regex/; 166 181 } 167 182 next if (! -x "$servicedir/$file"); # File not executeable 168 debug ("file: '$file'\n"); 169 $services{$file}=1; 170 my @rows = run_service($file,"config"); 171 my $node = get_var (\%sconf, $file, 'host_name'); 183 184 $self->debug("file: '$file'\n"); 185 $services->{$file}=1; 186 my @rows = $self->run_service($file, 'config'); 187 my $node = $self->get_var($file, 'host_name'); 172 188 173 189 for my $row (@rows) { 174 debug("row: $row\n");190 $self->debug("row: $row\n"); 175 191 if ($row =~ m/^host_name (.+)$/) { 176 debug("Found host_name, using it\n");192 $self->debug("Found host_name, using it\n"); 177 193 $node = $1; 178 194 } 179 195 } 180 $node ||= $FQDN; 181 $nodes{$node}{$file}=1; 182 } 183 closedir DIR; 184 return keys %services; 196 $node ||= $conf->{FQDN}; 197 $nodes->{$node}{$file}=1; 198 } 199 closedir($dir); 200 201 return $self; 185 202 } 186 203 187 204 sub run_service { 188 my ($service,$command) = @_; 205 my ($self, $service, $command) = @_; 206 my $conf = $self->{config}; 207 my $servicedir = $conf->{servicedir}; 208 189 209 $command ||= ''; 190 210 my @lines = ();; 191 211 my $timed_out = 0; 192 return "# Unknown service $service\n"193 unless $se rvices{$service} and ($caddr eq "" or has_access ($service));212 return "# Unknown service '$service'\n" 213 unless $self->{services}{$service} and $self->has_access($service); 194 214 195 215 # Untaint $service, we know it's safe (it's in the %services hash) … … 197 217 $service = $1; 198 218 199 my $timeout = get_var (\%sconf, $service, 'timeout'); 200 $timeout = $sconf{'timeout'} 219 if (!$self->check_perms("$servicedir/$service")) { 220 $self->logger("Error: unsafe permissions. Bailing out."); 221 return "# Unsafe permissions on service '$service'\n"; 222 } 223 224 my $timeout = $self->get_var($service, 'timeout'); 225 $timeout = $conf->{timeout} 201 226 unless defined $timeout and $timeout =~ /^\d+$/; 202 227 … … 205 230 $command = $1; 206 231 } else { 207 logger("Unknown command '$command'");232 $self->logger("Unknown command '$command'"); 208 233 return "# Unknown command '$command'\n"; 209 234 } 210 235 211 236 my @run; 212 if ( defined $sconf{$service}{'command'}) {237 if (my $cmd = $self->get_var($service, 'command')) { 213 238 @run = map { $_ eq '%c' ? "$servicedir/$service" : $_ } 214 @ {$sconf{$service}{'command'}}239 @$cmd; 215 240 } else { 216 241 @run = ("$servicedir/$service", $command); 217 242 } 243 244 $self->debug("About to run '", join("', '", @run), "'\n"); 218 245 219 246 eval { 220 247 run(\@run, 221 248 '>', new_chunker("\n"), sub { push @lines, @_ }, 222 '2>', new_chunker("\n"), sub { logger("$service: $_[0]") },223 init => sub { setup_environment($service) },249 '2>', new_chunker("\n"), sub { $self->logger("$service: $_[0]") }, 250 init => sub { $self->setup_environment($service) }, 224 251 timeout($timeout, exception => "plugin timed out"), 225 252 ); … … 227 254 228 255 if (@!) { 229 logger("Error running $service: @!");256 $self->logger("Error running $service: @!"); 230 257 return "# Error running $service: @!\n"; 231 258 } 259 $self->logger("No output from service '$service'\n") unless @lines; 232 260 return @lines; 233 261 } … … 235 263 # Called from the plugin child before exec. 236 264 sub setup_environment { 237 my $service = shift or die "internal error: service required"; 265 my ($self, $service) = @_; 266 die "internal error: service required" 267 unless $self and $service; 268 269 my $conf = $self->{config}; 270 my $user = $self->get_var($service, 'user'); 271 my $group = $self->get_var($service, 'group'); 272 my $env; $self->get_var($service, 'env', $env); 273 238 274 POSIX::setsid(); 239 # Setting environment240 $sconf{$service}{user} = get_var (\%sconf, $service, 'user');241 $sconf{$service}{group} = get_var (\%sconf, $service, 'group');242 $sconf{$service}{command} = get_var (\%sconf, $service, 'command');243 get_var (\%sconf, $service, 'env', \%{$sconf{$service}{env}});244 245 275 if ($< == 0) # If root... 246 276 { 247 277 # Giving up gid egid uid euid 248 my $u = (defined $sconf{$service}{'user'}? 249 $sconf{$service}{'user'}: 250 $defuser); 251 my $g = $defgroup; 252 my $gs = "$g $g" . 253 (defined $sconf{$service}{'group'} ? 254 " $sconf{$service}{group}" : ""); 278 my $u = defined $user ? $user : $conf->{defuser}; 279 my $g = $conf->{defgroup}; 280 my $gs = "$g $g" . (defined $group ? " $group" : ""); 255 281 256 debug("Want to run as euid/egid $u/$g\n");282 $self->debug("Want to run as euid/egid $u/$g\n"); 257 283 258 284 $( = $g unless $g == 0; … … 262 288 263 289 if ($> != $u or $g != (split (' ', $)))[0]) { 264 # net_write ("# Can't drop privileges. Bailing out. (wanted uid=", 265 # ($sconf{$service}{'user'} || $defuser), " gid=\"", 266 # $gs, "\"($g), got uid=$> gid=\"$)\"(", 267 # (split (' ', $)))[0], ").\n"); 268 logger ("Plugin \"$service\" Can't drop privileges. ". 269 "Bailing out. (wanted uid=". 270 ($sconf{$service}{'user'} || $defuser). " gid=\"". 290 $self->logger("Plugin \"$service\" Can't drop privileges. ". 291 "Bailing out. (wanted uid=$u gid=\"". 271 292 $gs. "\"($g), got uid=$> gid=\"$)\"(". 272 293 (split (' ', $)))[0]. ")."); … … 274 295 } 275 296 } 276 debug ("Running as uid/gid/euid/egid $</$(/$>/$)\n"); 277 if (!check_perms ("$servicedir/$service")) { 278 net_write ("# Error: unsafe permissions. Bailing out."); 279 logger ("Error: unsafe permissions. Bailing out."); 280 exit 2; 281 } 282 297 $self->debug("Running as uid/gid/euid/egid $</$(/$>/$)\n"); 283 298 # Setting environment... 284 if (defined $sconf{$service}{'env'}) { 285 foreach my $key (keys %{$sconf{$service}{'env'}}) { 286 debug ("Setting environment $key=$sconf{$service}{env}{$key}\n"); 287 $ENV{"$key"} = $sconf{$service}{'env'}{$key}; 288 } 289 } 290 } 291 299 foreach my $key (keys %$env) { 300 $self->debug("Setting environment $key=$env->{$key}\n"); 301 $ENV{"$key"} = $env->{$key}; 302 } 303 } 304 305 # Override for real access control 292 306 sub has_access { 293 my $serv = shift; 294 my $host = $caddr; 295 my $rights = get_var_arr (\%sconf, $serv, 'allow_deny'); 296 297 unless (@{$rights}) 298 { 299 return 1; 300 } 301 debug ("Checking access: $host;$serv;\n"); 302 foreach my $ruleset (@{$rights}) 303 { 304 foreach my $rule (@{$ruleset}) 305 { 306 debug ("Checking access: $host;$serv;". $rule->[0].";".$rule->[1]); 307 if ($rule->[1] eq "tls" and $tls_verified{"verified"}) 308 { # tls 309 if ($rule->[0] eq "allow") 310 { 311 return 1; 312 } 313 else 314 { 315 return 0; 316 } 317 } 318 # elsif ($rule->[1] =~ /\//) 319 # { # CIDR 320 # print "DEBUG: CIDR $host;$serv;$rule->[1];\n"; 321 # return 1; 322 # } 323 else 324 { # regex 325 if ($host =~ m($rule->[1])) 326 { 327 if ($rule->[0] eq "allow") 328 { 329 return 1; 330 } 331 else 332 { 333 return 0; 334 } 335 } 336 } 337 } 338 } 339 return 1; 307 return 1; 340 308 } 341 309 342 310 sub check_perms 343 311 { 344 my $target = shift; 345 my @stat; 312 my ($self, $target) = @_; 313 my $conf = $self->{config}; 314 346 315 return undef if (!defined $target); 347 return 1 if (!$paranoia); 348 349 if (! -e "$target") 350 { 351 warn "Failed to check permissions on nonexistant target: \"$target\""; 316 return 1 if (!$self->{paranoia}); 317 318 my @stat = stat ($target); 319 if (!@stat) 320 { 321 warn "Failed to check permissions on target: \"$target\": $!\n"; 352 322 return undef; 353 323 } 354 324 355 @stat = stat ($target);356 325 if (!$stat[4] == 0 or 357 326 ($stat[5] != 0 and $stat[2] & 00020) or … … 365 334 { 366 335 (my $dirname = $target) =~ s/[^\/]+$//; 367 return check_perms($dirname);336 return $self->check_perms($dirname); 368 337 } 369 338 … … 397 366 sub load_auth_file 398 367 { 399 my ($ dir, $file, $sconf) = @_;368 my ($self, $file) = @_; 400 369 my $service = $file; 401 402 if (!defined $dir or !defined $file or !defined $sconf) 403 { 404 return undef; 405 } 406 407 return undef if (!check_perms ($dir)); 408 return undef if (!check_perms ("$dir/$file")); 409 410 if (!open (IN, "$dir/$file")) 411 { 412 warn "Could not open file \"$dir/$file\" for reading ($!), skipping plugin\n"; 413 return undef; 414 } 415 while (<IN>) 370 my $sconf = $self->{config}{services}; 371 372 return if (!$self->check_perms($file)); 373 374 my $in; 375 if (!open ($in, '<', $file)) 376 { 377 warn "Could not open file \"$file\" for reading ($!), skipping plugin\n"; 378 return; 379 } 380 381 while (<$in>) 416 382 { 417 383 chomp; … … 419 385 next unless /\S/; 420 386 s/\s+$//g; 421 debug("Config: $service: $_\n");387 $self->debug("Config: $service: $_\n"); 422 388 if (/^\s*\[([^\]]+)\]\s*$/) 423 389 { … … 428 394 my $tmpid = $1; 429 395 $sconf->{$service}{'user'} = get_uid ($tmpid); 430 debug("Config: $service->uid = ", $sconf->{$service}{'user'}, "\n");396 $self->debug("Config: $service->uid = ", $sconf->{$service}{'user'}, "\n"); 431 397 if (!defined $sconf->{$service}{'user'}) 432 398 { 433 warn "User \"$tmpid\" in configuration file \"$ dir/$file\" nonexistant. Skipping plugin.";399 warn "User \"$tmpid\" in configuration file \"$file\" nonexistant. Skipping plugin."; 434 400 return undef; 435 401 } … … 449 415 450 416 my $g = get_gid ($group); 451 debug("Config: $service->gid = $g\n") if defined $g;417 $self->debug("Config: $service->gid = $g\n") if defined $g; 452 418 if (!defined $g and !$optional) 453 419 { 454 warn "Group \"$group\" in configuration file \"$ dir/$file\" nonexistant. Skipping plugin.";420 warn "Group \"$group\" in configuration file \"$file\" nonexistant. Skipping plugin."; 455 421 return undef; 456 422 } 457 423 elsif (!defined $g and $optional) 458 424 { 459 debug("Skipping \"$group\" (optional).\n");425 $self->debug("Skipping \"$group\" (optional).\n"); 460 426 next; 461 427 } … … 481 447 { 482 448 $sconf->{$service}{'timeout'} = $1; 483 debug("$service: setting timeout to $1\n");449 $self->debug("$service: setting timeout to $1\n"); 484 450 } 485 451 elsif (/^\s*(allow)\s+(.+)\s*$/ or /^\s*(deny)\s+(.+)\s*$/) 486 452 { 487 453 push (@{$sconf->{$service}{'allow_deny'}}, [$1, $2]); 488 debug("Pushing allow_deny: $1, $2\n");454 $self->debug("Pushing allow_deny: $1, $2\n"); 489 455 } 490 456 elsif (/^\s*env\s+([^=\s]+)\s*=\s*(.+)$/) 491 457 { 492 458 $sconf->{$service}{'env'}{$1} = $2; 493 debug("Saving $service->env->$1 = $2...\n");494 warn "Warning: Deprecated format in \"$ dir/$file\" under \"[$service]\" (\"env $1=$2\" should be rewritten to \"env.$1 $2\").";459 $self->debug("Saving $service->env->$1 = $2...\n"); 460 warn "Warning: Deprecated format in \"$file\" under \"[$service]\" (\"env $1=$2\" should be rewritten to \"env.$1 $2\")."; 495 461 } 496 462 elsif (/^\s*env\.(\S+)\s+(.+)$/) 497 463 { 498 464 $sconf->{$service}{'env'}{$1} = $2; 499 debug("Saving $service->env->$1 = $2...\n");465 $self->debug("Saving $service->env->$1 = $2...\n"); 500 466 } 501 467 elsif (/^\s*(\w+)\s+(.+)$/) 502 468 { 503 469 $sconf->{$service}{'env'}{"lrrd_$1"} = $2; 504 debug("Saving $service->env->lrrd_$1 = $2...\n");505 warn "Warning: Deprecated format in \"$ dir/$file\" under \"[$service]\" (\"$1 $2\" should be rewritten to \"env lrrd_$1=$2\").";470 $self->debug("Saving $service->env->lrrd_$1 = $2...\n"); 471 warn "Warning: Deprecated format in \"$file\" under \"[$service]\" (\"$1 $2\" should be rewritten to \"env lrrd_$1=$2\")."; 506 472 } 507 473 elsif (/\S/) 508 474 { 509 warn "Warning: Unknown config option in \"$ dir/$file\" under \"[$service]\": $_";510 } 511 512 } 513 close (IN);475 warn "Warning: Unknown config option in \"$file\" under \"[$service]\": $_"; 476 } 477 478 } 479 close($in); 514 480 515 481 return 1; … … 518 484 sub get_var 519 485 { 520 my $s conf= shift;486 my $self = shift; 521 487 my $name = shift; 522 488 my $var = shift; 523 489 my $env = shift; 490 my $sconf = $self->{config}{services}; 524 491 525 492 if ($var eq 'env' and !defined $env) … … 537 504 (my $tmpservice = $wildservice) =~ s/\*$//; 538 505 next unless ($name =~ /^$tmpservice/); 539 debug("Checking $wildservice...\n");506 $self->debug("Checking $wildservice...\n"); 540 507 541 508 if ($var eq 'env') … … 548 515 { 549 516 $sconf->{$name}{'env'}{$key} = $sconf->{$wildservice}{'env'}{$key}; 550 debug("Saving $wildservice->$key\n");517 $self->debug("Saving $wildservice->$key\n"); 551 518 } 552 519 } … … 567 534 sub get_var_arr 568 535 { 569 my $s conf= shift;536 my $self = shift; 570 537 my $name = shift; 571 538 my $var = shift; 539 my $sconf = $self->{config}{services}; 572 540 my $result = []; 573 541 … … 581 549 (my $tmpservice = $wildservice) =~ s/\*$//; 582 550 next unless ($name =~ /^$tmpservice/); 583 debug("Checking $wildservice...\n");551 $self->debug("Checking $wildservice...\n"); 584 552 585 553 if (defined $sconf->{$wildservice}{$var}) 586 554 { 587 555 push (@{$result}, $sconf->{$wildservice}{$var}); 588 debug("Pushing: |", join (';', @{$sconf->{$wildservice}{$var}}), "|\n");556 $self->debug("Pushing: |", join (';', @{$sconf->{$wildservice}{$var}}), "|\n"); 589 557 } 590 558 } … … 607 575 608 576 sub debug { 609 print STDERR "DEBUG: ", @_ if $DEBUG; 577 my $self = shift; 578 print STDERR "DEBUG: ", @_ if $self->{config}{DEBUG}; 610 579 } 611 580 612 581 sub net_write { 582 my $self = shift; 613 583 print STDERR @_; 614 584 } 615 585 sub logger { 586 my $self = shift; 616 587 print STDERR @_; 617 588 } people/ilmari/modularisation-branch/node/munin-run.in
r1044 r1264 23 23 use strict; 24 24 use Getopt::Long; 25 use Munin::Node::Runner qw(:all);25 use Munin::Node::Runner; 26 26 # "Clean" environment to disable taint-checking on the environment. We _know_ 27 27 # that the environment is insecure, but we want to let admins shoot themselves … … 40 40 delete @ENV{'IFS', 'CDPATH', 'ENV', 'BASH_ENV'}; 41 41 42 $do_usage=1 unless 43 GetOptions ( "config=s" => \$conffile, 44 "debug!" => \$DEBUG, 45 "version!" => \$do_version, 46 "servicedir=s" => \$servicedir, 47 "sconfdir=s" => \$sconfdir, 48 "sconffile=s" => \$sconffile, 49 "paranoia!" => \$paranoia, 50 "help" => \$do_usage ); 42 my $config = {}; 43 GetOptions ($config, 44 qw(config=s 45 debug! 46 version! 47 servicedir=s 48 sconfdir=s 49 sconffile=s 50 paranoia! 51 help)) 52 or $config->{help} = 1; 51 53 52 if ($ do_usage)54 if ($config->{help}) 53 55 { 54 56 print "Usage: $0 [options] … … 73 75 } 74 76 75 if ($conffile =~ /^([-\/\@_\w\.]+)$/) 76 { 77 $conffile = $1; # $data now untainted78 } 79 else 80 { 81 die "Bad data in $conffile"; # log this somewhere77 for my $option (qw(conffile sconfdir sconffile servicedir)) { 78 next unless exists $config->{$option}; 79 if ($config->{$option} =~ /^([-\/\@_\w\.]+)$/) { 80 $config->{$option} = $1; # $data now untainted 81 } else { 82 die "Bad data in $option"; # log this somewhere 83 } 82 84 } 83 if ($sconfdir =~ /^([-\/\@_\w\.]+)$/) 84 { 85 $sconfdir = $1; # $data now untainted 86 } 87 else 88 { 89 die "Bad data in $sconfdir"; # log this somewhere 90 } 91 if (defined $sconffile and $sconffile =~ /^([-\/\@_\w\.]+)$/) 92 { 93 $sconffile = $1; # $data now untainted 94 } 95 elsif (defined $sconffile) 96 { 97 die "Bad data in $sconffile"; # log this somewhere 98 } 99 if ($servicedir =~ /^([-\/\@_\w\.]+)$/) 100 { 101 $servicedir = $1; # $data now untainted 102 } 103 else 104 { 105 die "Bad data in $servicedir"; # log this somewhere 106 } 107 108 if ($do_version) 85 if ($config->{version}) 109 86 { 110 87 print <<"EOT"; 111 munin-run (munin-node) version $ VERSION.88 munin-run (munin-node) version $Munin::Node::Runner::VERSION. 112 89 Written by Jimmy Olsen / Linpro AS 113 90 … … 123 100 } 124 101 125 load_services();126 print run_service(@ARGV);102 my $runner = Munin::Node::Runner->load_services($config); 103 print $runner->run_service(@ARGV); 127 104 128 105 =head1 NAME people/ilmari/modularisation-branch/t/node-runner.t
r1043 r1264 2 2 # Tests for the Munin::Node::Runner module 3 3 4 use Test::More tests => 9;4 use Test::More tests => 10; 5 5 use strict; 6 6 7 7 sub run { 8 my $ plugin= shift;9 my @lines = run_service($plugin,@_)10 or warn "No output from '$ plugin' plugin\n";8 my $runner = shift; 9 my @lines = $runner->run_service(@_) 10 or warn "No output from '$_[0]' plugin\n"; 11 11 12 12 my %ret; … … 22 22 } 23 23 24 BEGIN { use_ok('Munin::Node::Runner' , qw(:all)); }24 BEGIN { use_ok('Munin::Node::Runner'); } 25 25 26 ok(load_services(), "loading services"); 27 ok(list_services(), "listing services"); 26 my $runner; 27 ok ($runner = Munin::Node::Runner->load_services, "loading services"); 28 isa_ok($runner, 'Munin::Node::Runner'); 29 ok ($runner->list_services(), "listing services"); 28 30 29 31 SKIP: { … … 32 34 unless getpwnam('nobody') && getgrnam('nogroup'); 33 35 34 my %id = run( 'id_default');36 my %id = run($runner, 'id_default'); 35 37 is($id{uid}{extinfo}, 'nobody', "default user"); 36 38 like($id{gid}{extinfo}, qr/\bnogroup\b/, "default group"); 37 39 38 my %id = run( 'id_root');40 my %id = run($runner, 'id_root'); 39 41 is($id{uid}{value}, 0, 'user override'); 40 42 like($id{gid}{extinfo}, qr/\broot\b/, 'group override'); 41 43 } 42 44 43 my %env = run( 'env');45 my %env = run($runner, 'env'); 44 46 is_deeply(\%env, 45 47 { … … 53 55 local $TODO = "munin-run doesn't handle this"; 54 56 55 my %config = run( 'env config');57 my %config = run($runner, qw(env config)); 56 58 is($config{host_name}, 'test.example.com', 'host_name override'); 57 59
