├── README ├── dell └── manifests │ └── init.pp ├── dirvish ├── files │ ├── bin │ │ ├── dirvish │ │ ├── dirvish-expire │ │ ├── dirvish-locate │ │ └── dirvish-runall │ └── man │ │ ├── dirvish-expire.8 │ │ ├── dirvish-locate.8 │ │ ├── dirvish-runall.8 │ │ ├── dirvish.8 │ │ └── dirvish.conf.5 ├── manifests │ └── init.pp └── templates │ ├── branch.conf.erb │ ├── dirvish-stats.erb │ └── master.conf.erb ├── heartbeat ├── manifests │ ├── heartbeat-old.pp │ └── init.pp └── templates │ ├── authkeys.erb │ ├── ha.cf.erb │ └── haresources.erb ├── md3000 ├── files │ ├── lvm.conf │ ├── minirc.dfl │ └── multipath.conf └── manifests │ └── init.pp ├── network ├── manifests │ └── init.pp └── templates │ ├── hostname.carp.erb │ ├── hostname.trunk.erb │ ├── ifcfg.erb │ └── network.erb ├── pmwiki ├── files │ ├── htaccess │ └── rsync-pmwiki └── manifests │ └── init.pp ├── selinux ├── files │ ├── apache.te │ ├── base.te │ ├── cronolog.te │ ├── logsurfer.te │ ├── multipathd.te │ ├── postfix.te │ └── syslog-ng.te ├── manifests │ └── init.pp └── templates │ └── setup.erb └── users ├── files └── someuser │ ├── .bashrc │ └── .ssh │ └── authorized_keys └── manifests ├── init.pp ├── people.pp └── web.pp /README: -------------------------------------------------------------------------------- 1 | This repository is The SANS Institute's public Puppet Configuration. 2 | 3 | The SANS Institute uses, but does not endorse Puppet or git. 4 | 5 | http://www.sans.org/ 6 | Contact: noc@sans.org 7 | -------------------------------------------------------------------------------- /dell/manifests/init.pp: -------------------------------------------------------------------------------- 1 | # class name_of_class { } 2 | # define definition { } 3 | # 4 | # Classes and Definitions here. 5 | 6 | class dell { 7 | 8 | class srvadmin { 9 | 10 | class base { 11 | package { ["instsvc-drivers", "srvadmin-omhip", "srvadmin-old", "srvadmin-cm"]: 12 | ensure => installed, 13 | require => Yumrepo["sans"], 14 | } 15 | 16 | #service { "dsm_om_shrsvc": 17 | # ensure => running, 18 | # enable => true, 19 | # hasrestart => true, 20 | # require => [Package["instsvc-drivers"], Package["srvadmin-omhip"], Package["srvadmin-old"], Package["srvadmin-cm"]], 21 | #} 22 | 23 | exec { "srvadmin-base-start": 24 | command => "/usr/bin/srvadmin-services.sh start", 25 | creates => "/var/run/dsm_sa_datamgr32d.pid", 26 | require => Package[srvadmin-omhip], 27 | } 28 | } 29 | 30 | class rac { 31 | package { ["srvadmin-racadm5", "srvadmin-racdrsc5"]: 32 | ensure => installed, 33 | require => Yumrepo["sans"], 34 | } 35 | 36 | } 37 | 38 | class storage { 39 | package { "srvadmin-storage": 40 | ensure => installed, 41 | require => Yumrepo["sans"], 42 | } 43 | 44 | } 45 | 46 | class webserver { 47 | package { "srvadmin-iws": 48 | ensure => installed, 49 | require => Yumrepo["sans"], 50 | } 51 | 52 | service { "dsm_om_connsvc": 53 | ensure => running, 54 | enable => true, 55 | hasrestart => true, 56 | require => Package["srvadmin-iws"], 57 | } 58 | } 59 | 60 | } 61 | } 62 | 63 | # vim modeline - have 'set modeline' and 'syntax on' in your ~/.vimrc. 64 | # vi:syntax=puppet:filetype=puppet:ts=4:et: 65 | # EOF 66 | -------------------------------------------------------------------------------- /dirvish/files/bin/dirvish: -------------------------------------------------------------------------------- 1 | #!/usr/bin/perl 2 | 3 | $CONFDIR = "/etc/dirvish"; 4 | 5 | # $Id: dirvish.pl,v 12.0 2004/02/25 02:42:15 jw Exp $ $Name: Dirvish-1_2 $ 6 | 7 | $VERSION = ('$Name: Dirvish-1_2 $' =~ /Dirvish/i) 8 | ? ('$Name: Dirvish-1_2 $' =~ m/^.*:\s+dirvish-(.*)\s*\$$/i)[0] 9 | : '1.1.2 patch' . ('$Id: dirvish.pl,v 12.0 2004/02/25 02:42:15 jw Exp $' 10 | =~ m/^.*,v(.*:\d\d)\s.*$/)[0]; 11 | $VERSION =~ s/_/./g; 12 | 13 | ######################################################################### 14 | # # 15 | # Copyright 2002 and $Date: 2004/02/25 02:42:15 $ 16 | # Pegasystems Technologies and J.W. Schultz # 17 | # # 18 | # Licensed under the Open Software License version 2.0 # 19 | # # 20 | # This program is free software; you can redistribute it # 21 | # and/or modify it under the terms of the Open Software # 22 | # License, version 2.0 by Lauwrence E. Rosen. # 23 | # # 24 | # This program is distributed in the hope that it will be # 25 | # useful, but WITHOUT ANY WARRANTY; without even the implied # 26 | # warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR # 27 | # PURPOSE. See the Open Software License for details. # 28 | # # 29 | ######################################################################### 30 | 31 | 32 | 33 | ######################################################### 34 | # EXIT CODES 35 | # 36 | # 0 success 37 | # 1-19 warnings 38 | # 20-39 finalization error 39 | # 40-49 post-* error 40 | # 50-59 post-client error code % 10forwarded 41 | # 60-69 post-server error code % 10forwarded 42 | # 70-79 pre-* error 43 | # 80-89 pre-server error code % 10 forwarded 44 | # 90-99 pre-client error code % 10 forwarded 45 | # 100-149 non-fatal error 46 | # 150-199 fatal error 47 | # 200-219 loadconfig error. 48 | # 220-254 configuration error 49 | # 255 usage error 50 | 51 | 52 | use POSIX qw(strftime); 53 | use Getopt::Long; 54 | use Time::ParseDate; 55 | use Time::Period; 56 | 57 | @rsyncargs = qw(-vrltH --delete); 58 | 59 | %RSYNC_CODES = ( 60 | 0 => [ 'success', "No errors" ], 61 | 1 => [ 'fatal', "syntax or usage error" ], 62 | 2 => [ 'fatal', "protocol incompatibility" ], 63 | 3 => [ 'fatal', "errors selecting input/output files, dirs" ], 64 | 4 => [ 'fatal', "requested action not supported" ], 65 | 5 => [ 'fatal', "error starting client-server protocol" ], 66 | 67 | 10 => [ 'error', "error in socket IO" ], 68 | 11 => [ 'error', "error in file IO" ], 69 | 12 => [ 'check', "error in rsync protocol data stream" ], 70 | 13 => [ 'check', "errors with program diagnostics" ], 71 | 14 => [ 'error', "error in IPC code" ], 72 | 73 | 20 => [ 'error', "status returned when sent SIGUSR1, SIGINT" ], 74 | 21 => [ 'error', "some error returned by waitpid()" ], 75 | 22 => [ 'error', "error allocating core memory buffers" ], 76 | 23 => [ 'error', "partial transfer" ], 77 | #KHL 2005/02/18: rsync code 24 changed from 'error' to 'warning' 78 | 24 => [ 'warning', "file vanished on sender" ], 79 | 80 | 30 => [ 'error', "timeout in data send/receive" ], 81 | 82 | 124 => [ 'fatal', "remote shell failed" ], 83 | 125 => [ 'error', "remote shell killed" ], 84 | 126 => [ 'fatal', "command could not be run" ], 85 | 127 => [ 'fatal', "command not found" ], 86 | ); 87 | 88 | @BOOLEAN_FIELDS = qw( 89 | permissions 90 | checksum 91 | devices 92 | init 93 | numeric-ids 94 | sparse 95 | stats 96 | whole-file 97 | xdev 98 | zxfer 99 | ); 100 | 101 | %RSYNC_OPT = ( # simple options 102 | permissions => '-pgo', 103 | devices => '-D', 104 | sparse => '-S', 105 | checksum => '-c', 106 | 'whole-file' => '-W', 107 | xdev => '-x', 108 | zxfer => '-z', 109 | stats => '--stats', 110 | 'numeric-ids' => '--numeric-ids', 111 | ); 112 | 113 | %RSYNC_POPT = ( # parametered options 114 | 'password-file' => '--password-file', 115 | 'rsync-client' => '--rsync-path', 116 | ); 117 | 118 | sub errorscan; 119 | sub logappend; 120 | sub scriptrun; 121 | sub seppuku; 122 | 123 | sub usage 124 | { 125 | my $message = shift(@_); 126 | 127 | length($message) and print STDERR $message, "\n\n"; 128 | 129 | $! and exit(255); # because getopt seems to send us here for death 130 | 131 | print STDERR < join(' ', @ARGV), 152 | 'numeric-ids' => 1, 153 | 'devices' => 1, 154 | permissions => 1, 155 | 'stats' => 1, 156 | exclude => [ ], 157 | 'expire-rule' => [ ], 158 | 'rsync-option' => [ ], 159 | bank => [ ], 160 | 'image-default' => '%Y%m%d%H%M%S', 161 | rsh => 'ssh', 162 | summary => 'short', 163 | config => 164 | sub { 165 | loadconfig('f', $_[1], $Options); 166 | }, 167 | client => 168 | sub { 169 | $$Options{$_[0]} = $_[1]; 170 | loadconfig('fog', "$CONFDIR/$_[1]", $Options); 171 | }, 172 | branch => 173 | sub { 174 | if ($_[1] =~ /:/) 175 | { 176 | ($$Options{vault}, $$Options{branch}) 177 | = split(/:/, $_[1]); 178 | } else { 179 | $$Options{$_[0]} = $_[1]; 180 | } 181 | loadconfig('f', "$$Options{branch}", $Options); 182 | }, 183 | vault => 184 | sub { 185 | if ($_[1] =~ /:/) 186 | { 187 | ($$Options{vault}, $$Options{branch}) 188 | = split(/:/, $_[1]); 189 | loadconfig('f', "$$Options{branch}", $Options); 190 | } else { 191 | $$Options{$_[0]} = $_[1]; 192 | loadconfig('f', 'default.conf', $Options); 193 | } 194 | }, 195 | reset => 196 | sub { 197 | $$Options{$_[1]} = ref($$Options{$_[1]}) eq 'ARRAY' 198 | ? [ ] 199 | : undef; 200 | }, 201 | version => sub { 202 | print STDERR "dirvish version $VERSION\n"; 203 | exit(0); 204 | }, 205 | help => \&usage, 206 | }; 207 | 208 | if ($CONFDIR =~ /dirvish$/ && -f "$CONFDIR.conf") 209 | { 210 | loadconfig('f', "$CONFDIR.conf", $Options); 211 | } 212 | elsif (-f "$CONFDIR/master.conf") 213 | { 214 | loadconfig('f', "$CONFDIR/master.conf", $Options); 215 | } 216 | elsif (-f "$CONFDIR/dirvish.conf") 217 | { 218 | seppuku 250, < 1, NOW => $n); 309 | if (!$now) 310 | { 311 | $now = parsedate($$Options{'image-time'}, NOW => $n); 312 | $now > $n && $$Options{'image-time'} !~ /\+/ and $now -= 24*60*60; 313 | } 314 | $now or seppuku 222, "ERROR: image-time unparseable: $$Options{'image-time'}"; 315 | } 316 | $$Options{'Image-now'} = strftime('%Y-%m-%d %H:%M:%S', localtime($now)); 317 | 318 | $$Options{Image} =~ /%/ 319 | and $$Options{Image} = strftime($$Options{Image}, localtime($now)); 320 | $image =~ /%/ 321 | and $image = strftime($image, localtime($now)); 322 | 323 | !$$Options{branch} || ref($$Options{branch}) 324 | and $$Options{branch} = $$Options{'branch-default'} || 'default'; 325 | 326 | $seppuku_prefix = join(':', $$Options{vault}, $$Options{branch}, $image); 327 | 328 | if (-d "$vault/$$Options{'image-temp'}" && $image eq $$Options{'image-temp'}) 329 | { 330 | my $iinfo; 331 | $iinfo = loadconfig('R', "$vault/$image/summary"); 332 | $$iinfo{Image} or seppuku 223, "cannot cope with existing $image"; 333 | if ($$Options{'no-run'}) 334 | { 335 | print "ACTION: rename $vault/$image $vault/$$iinfo{Image}\n\n"; 336 | $have_temp = 1; 337 | } else { 338 | rename ("$vault/$image", "$vault/$$iinfo{Image}"); 339 | } 340 | } 341 | 342 | -d "$vault/$$Options{Image}" and seppuku 224, "ERROR: image $$Options{Image} already exists in $vault"; 343 | -d "$vault/$image" && !$have_temp and seppuku 225, "ERROR: image $image already exists in $vault"; 344 | 345 | $$Options{Reference} = $$Options{reference} || $$Options{branch}; 346 | if (!$$Options{init} && -f "$vault/dirvish/$$Options{Reference}.hist") 347 | { 348 | my (@images, $i, $s); 349 | open(IMAGES, "$vault/dirvish/$$Options{Reference}.hist"); 350 | @images = ; 351 | close IMAGES; 352 | while ($i = pop(@images)) 353 | { 354 | $i =~ s/\s.*$//s; 355 | -d "$vault/$i/tree" or next; 356 | 357 | $$Options{Reference} = $i; 358 | last; 359 | } 360 | } 361 | $$Options{init} || -d "$vault/$$Options{Reference}" 362 | or seppuku 227, "ERROR: no images for branch $$Options{branch} found"; 363 | 364 | if(!$$Options{expire} && $$Options{expire} !~ /never/i 365 | && scalar(@{$$Options{'expire-rule'}})) 366 | { 367 | my ($rule, $p, $t, $e); 368 | my @cron; 369 | my @pnames = qw(min hr md mo wd); 370 | 371 | for $rule (reverse(@{$$Options{'expire-rule'}})) 372 | { 373 | if ($rule =~ /\{.*\}/) 374 | { 375 | ($p, $e) = $rule =~ m/^(.*\175)\s*([^\175]*)$/; 376 | } else { 377 | @cron = split(/\s+/, $rule, 6); 378 | $e = $cron[5] || ''; 379 | $p = ''; 380 | for ($t = 0; $t < @pnames; $t++) 381 | { 382 | $cron[$t] eq '*' and next; 383 | ($p .= "$pnames[$t] { $cron[$t] } ") 384 | =~ tr/,/ /; 385 | } 386 | } 387 | if (!$p) 388 | { 389 | $$Options{'Expire-rule'} = $rule; 390 | $$Options{Expire} = $e; 391 | last; 392 | } 393 | $t = inPeriod($now, $p); 394 | if ($t == 1) 395 | { 396 | $e ||= 'Never'; 397 | $$Options{'Expire-rule'} = $rule; 398 | $$Options{Expire} = $e; 399 | last; 400 | } 401 | $t == -1 and printf STDERR "WARNING: invalid expire rule %s\n", $rule; 402 | next; 403 | } 404 | } else { 405 | $$Options{Expire} = $$Options{expire}; 406 | } 407 | 408 | $$Options{Expire} ||= $$Options{'expire-default'}; 409 | 410 | if ($$Options{Expire} && $$Options{Expire} !~ /Never/i) 411 | { 412 | $$Options{Expire} .= strftime(' == %Y-%m-%d %H:%M:%S', 413 | localtime(parsedate($$Options{Expire}, NOW => $now))); 414 | } else { 415 | $$Options{Expire} = 'Never'; 416 | } 417 | 418 | #+SIS: KHL 2005-02-18 SpacesInSource fix 419 | #-SIS: ($srctree, $aliastree) = split(/\s+/, $$Options{tree}) 420 | ($srctree, $aliastree) = split(/[^\\]\s+/, $$Options{tree}) 421 | or seppuku 228, "ERROR: no source tree defined"; 422 | $srctree =~ s(\\ )( )g; #+SIS 423 | $srctree =~ s(/+$)(); 424 | $aliastree =~ s(/+$)(); 425 | $aliastree ||= $srctree; 426 | 427 | $destree = join("/", $vault, $image, 'tree'); 428 | $reftree = join('/', $vault, $$Options{Reference}, 'tree'); 429 | $err_temp = join("/", $vault, $image, 'rsync_error.tmp'); 430 | $err_file = join("/", $vault, $image, 'rsync_error'); 431 | $log_file = join("/", $vault, $image, 'log'); 432 | $log_temp = join("/", $vault, $image, 'log.tmp'); 433 | $exl_file = join("/", $vault, $image, 'exclude'); 434 | $fsb_file = join("/", $vault, $image, 'fsbuffer'); 435 | 436 | while (($k, $v) = each %RSYNC_OPT) 437 | { 438 | $$Options{$k} and push @rsyncargs, $v; 439 | } 440 | 441 | while (($k, $v) = each %RSYNC_POPT) 442 | { 443 | $$Options{$k} and push @rsyncargs, $v . '=' . $$Options{$k}; 444 | } 445 | 446 | $$Options{'speed-limit'} 447 | and push @rsyncargs, '--bwlimit=' . $$Options{'speed-limit'} * 100; 448 | 449 | scalar @{$$Options{'rsync-option'}} 450 | and push @rsyncargs, @{$$Options{'rsync-option'}}; 451 | 452 | scalar @{$$Options{exclude}} 453 | and push @rsyncargs, '--exclude-from=' . $exl_file; 454 | 455 | if (!$$Options{'no-run'}) 456 | { 457 | mkdir "$vault/$image", 0700 458 | or seppuku 230, "mkdir $vault/$image failed"; 459 | mkdir $destree, 0755; 460 | 461 | open(SUMMARY, ">$vault/$image/summary") 462 | or seppuku 231, "cannot create $vault/$image/summary"; 463 | } else { 464 | open(SUMMARY, ">-"); 465 | } 466 | 467 | $Set = $Unset = ''; 468 | for (@BOOLEAN_FIELDS) 469 | { 470 | $$Options{$_} 471 | and $Set .= $_ . ' ' 472 | or $Unset .= $_ . ' '; 473 | } 474 | 475 | @summary_fields = qw( 476 | client tree rsh 477 | Server Bank vault branch 478 | Image image-temp Reference 479 | Image-now Expire Expire-rule 480 | exclude 481 | rsync-option 482 | Enabled 483 | ); 484 | $summary_reset = 0; 485 | for $key (@summary_fields, 'RESET', sort(keys(%$Options))) 486 | { 487 | if ($key eq 'RESET') 488 | { 489 | $summary_reset++; 490 | $Set and print SUMMARY "SET $Set\n"; 491 | $Unset and print SUMMARY "UNSET $Unset\n"; 492 | print SUMMARY "\n"; 493 | $$Options{summary} ne 'long' && !$$Options{'no-run'} and last; 494 | next; 495 | } 496 | grep(/^$key$/, @BOOLEAN_FIELDS) and next; 497 | $summary_reset && grep(/^$key$/, @summary_fields) and next; 498 | 499 | $val = $$Options{$key}; 500 | if(ref($val) eq 'ARRAY') 501 | { 502 | my $v; 503 | scalar(@$val) or next; 504 | print SUMMARY "$key:\n"; 505 | for $v (@$val) 506 | { 507 | printf SUMMARY "\t%s\n", $v; 508 | } 509 | } 510 | ref($val) and next; 511 | $val or next; 512 | printf SUMMARY "%s: %s\n", $key, $val; 513 | } 514 | 515 | $$Options{init} or push @rsyncargs, "--link-dest=$reftree"; 516 | 517 | $rclient = undef; 518 | $$Options{client} ne $$Options{Server} 519 | and $rclient = $$Options{client} . ':'; 520 | 521 | $ENV{RSYNC_RSH} = $$Options{rsh}; 522 | 523 | @cmd = ( 524 | ($$Options{rsync} ? $$Options{rsync} : 'rsync'), 525 | @rsyncargs, 526 | $rclient . $srctree . '/', 527 | $destree 528 | ); 529 | printf SUMMARY "\n%s: %s\n", 'ACTION', join (' ', @cmd); 530 | 531 | $$Options{'no-run'} and exit 0; 532 | 533 | printf SUMMARY "%s: %s\n", 'Backup-begin', strftime('%Y-%m-%d %H:%M:%S', localtime); 534 | 535 | $env_srctree = $srctree; #+SIS: 536 | $env_srctree =~ s/ /\\ /g; #+SIS: 537 | 538 | $WRAPPER_ENV = sprintf (" %s=%s" x 5, 539 | 'DIRVISH_SERVER', $$Options{Server}, 540 | 'DIRVISH_CLIENT', $$Options{client}, 541 | #-SIS: 'DIRVISH_SRC', $srctree, 542 | 'DIRVISH_SRC', $env_srctree, #+SIS: 543 | 'DIRVISH_DEST', $destree, 544 | 'DIRVISH_IMAGE', join(':', 545 | $$Options{vault}, 546 | $$Options{branch}, 547 | $$Options{Image}), 548 | ); 549 | 550 | if(scalar @{$$Options{exclude}}) 551 | { 552 | open(EXCLUDE, ">$exl_file"); 553 | for (@{$$Options{exclude}}) 554 | { 555 | print EXCLUDE $_, "\n"; 556 | } 557 | close(EXCLUDE); 558 | $ENV{DIRVISH_EXCLUDE} = $exl_file; 559 | } 560 | 561 | if ($$Options{'pre-server'}) 562 | { 563 | $status{'pre-server'} = scriptrun( 564 | lable => 'Pre-Server', 565 | cmd => $$Options{'pre-server'}, 566 | now => $now, 567 | log => $log_file, 568 | dir => $destree, 569 | env => $WRAPPER_ENV, 570 | ); 571 | 572 | if ($status{'pre-server'}) 573 | { 574 | my $s = $status{'pre-server'} >> 8; 575 | printf SUMMARY "pre-server failed (%d)\n", $s; 576 | printf STDERR "%s:%s pre-server failed (%d)\n", 577 | $$Options{vault}, $$Options{branch}, 578 | $s; 579 | exit 80 + ($s % 10); 580 | } 581 | } 582 | 583 | if ($$Options{'pre-client'}) 584 | { 585 | $status{'pre-client'} = scriptrun( 586 | lable => 'Pre-Client', 587 | cmd => $$Options{'pre-client'}, 588 | now => $now, 589 | log => $log_file, 590 | dir => $srctree, 591 | env => $WRAPPER_ENV, 592 | shell => (($$Options{client} eq $$Options{Server}) 593 | ? undef 594 | : "$$Options{rsh} $$Options{client}"), 595 | ); 596 | if ($status{'pre-client'}) 597 | { 598 | my $s = $status{'pre-client'}; 599 | printf SUMMARY "pre-client failed (%d)\n", $s; 600 | printf STDERR "%s:%s pre-client failed (%d)\n", 601 | $$Options{vault}, $$Options{branch}, 602 | $s; 603 | 604 | ($$Options{'pre-server'}) && scriptrun( 605 | lable => 'Post-Server', 606 | cmd => $$Options{'post-server'}, 607 | now => $now, 608 | log => $log_file, 609 | dir => $destree, 610 | env => $WRAPPER_ENV . ' DIRVISH_STATUS=fail', 611 | ); 612 | exit 90 + ($s % 10); 613 | } 614 | } 615 | 616 | # create a buffer to allow logging to work after full fileystem 617 | open (FSBUF, ">$fsb_file"); 618 | print FSBUF " \n" x 6553; 619 | close FSBUF; 620 | 621 | for ($runloops = 0; $runloops < 5; ++$runloops) 622 | { 623 | logappend($log_file, sprintf("\n%s: %s\n", 'ACTION', join(' ', @cmd))); 624 | 625 | # create error file and connect rsync STDERR to it. 626 | # preallocate 64KB so there will be space if rsync 627 | # fills the filesystem. 628 | open (INHOLD, "<&STDIN"); 629 | open (ERRHOLD, ">&STDERR"); 630 | open (STDERR, ">$err_temp"); 631 | print STDERR " \n" x 6553; 632 | seek STDERR, 0, 0; 633 | 634 | open (OUTHOLD, ">&STDOUT"); 635 | open (STDOUT, ">$log_temp"); 636 | 637 | $status{code} = (system(@cmd) >> 8) & 255; 638 | 639 | open (STDERR, ">&ERRHOLD"); 640 | open (STDOUT, ">&OUTHOLD"); 641 | open (STDIN, "<&INHOLD"); 642 | 643 | open (LOG_FILE, ">>$log_file"); 644 | open (LOG_TEMP, "<$log_temp"); 645 | while () 646 | { 647 | chomp; 648 | m(/$) and next; 649 | m( [-=]> ) and next; 650 | print LOG_FILE $_, "\n"; 651 | } 652 | close (LOG_TEMP); 653 | close (LOG_FILE); 654 | unlink $log_temp; 655 | 656 | $status{code} and errorscan(\%status, $err_file, $err_temp); 657 | 658 | $status{warning} || $status{error} 659 | and logappend($log_file, sprintf( 660 | "RESULTS: warnings = %d, errors = %d", 661 | $status{warning}, $status{error} 662 | ) 663 | ); 664 | if ($RSYNC_CODES{$status{code}}[0] eq 'check') 665 | { 666 | $status{fatal} and last; 667 | $status{error} or last; 668 | } else { 669 | $RSYNC_CODES{$status{code}}[0] eq 'fatal' and last; 670 | $RSYNC_CODES{$status{code}}[0] eq 'error' or last; 671 | } 672 | } 673 | 674 | scalar @{$$Options{exclude}} && unlink $exl_file; 675 | -f $fsb_file and unlink $fsb_file; 676 | 677 | if ($status{code}) 678 | { 679 | if ($RSYNC_CODES{$status{code}}[0] eq 'check') 680 | { 681 | if ($status{fatal}) { $Status = 'fatal'; } 682 | elsif ($status{error}) { $Status = 'error'; } 683 | elsif ($status{warning}) { $Status = 'warning'; } 684 | $Status_msg = sprintf "%s (%d) -- %s", 685 | ($Status eq 'fatal' ? 'fatal error' : $Status), 686 | $status{code}, 687 | $status{message}{$Status}; 688 | } elsif ($RSYNC_CODES{$status{code}}[0] eq 'fatal') 689 | { 690 | $Status_msg = sprintf "fatal error (%d) -- %s", 691 | $status{code}, 692 | $RSYNC_CODES{$status{code}}[1]; 693 | } 694 | 695 | if (!$Status_msg) 696 | { 697 | $RSYNC_CODES{$status{code}}[0] eq 'fatal' and $Status = 'fatal'; 698 | $RSYNC_CODES{$status{code}}[0] eq 'error' and $Status = 'error'; 699 | $RSYNC_CODES{$status{code}}[0] eq 'warning' and $Status = 'warning'; 700 | $RSYNC_CODES{$status{code}}[0] eq 'check' and $Status = 'unknown'; 701 | exists $RSYNC_CODES{$status{code}} or $Status = 'unknown'; 702 | $Status_msg = sprintf "%s (%d) -- %s", 703 | ($Status eq 'fatal' ? 'fatal error' : $Status), 704 | $status{code}, 705 | $RSYNC_CODES{$status{code}}[1]; 706 | } 707 | if ($Status eq 'fatal' || $Status eq 'error' || $status eq 'unknown') 708 | { 709 | printf STDERR "dirvish %s:%s %s\n", 710 | $$Options{vault}, $$Options{branch}, 711 | $Status_msg; 712 | } 713 | } else { 714 | $Status = $Status_msg = 'success'; 715 | } 716 | $WRAPPER_ENV .= ' DIRVISH_STATUS=' . $Status; 717 | 718 | if ($$Options{'post-client'}) 719 | { 720 | $status{'post-client'} = scriptrun( 721 | lable => 'Post-Client', 722 | cmd => $$Options{'post-client'}, 723 | now => $now, 724 | log => $log_file, 725 | dir => $srctree, 726 | env => $WRAPPER_ENV, 727 | shell => (($$Options{client} eq $$Options{Server}) 728 | ? undef 729 | : "$$Options{rsh} $$Options{client}"), 730 | ); 731 | if ($status{'post-client'}) 732 | { 733 | my $s = $status{'post-client'} >> 8; 734 | printf SUMMARY "post-client failed (%d)\n", $s; 735 | printf STDERR "%s:%s post-client failed (%d)\n", 736 | $$Options{vault}, $$Options{branch}, 737 | $s; 738 | } 739 | } 740 | 741 | if ($$Options{'post-server'}) 742 | { 743 | $status{'post-server'} = scriptrun( 744 | lable => 'Post-Server', 745 | cmd => $$Options{'post-server'}, 746 | now => $now, 747 | log => $log_file, 748 | dir => $destree, 749 | env => $WRAPPER_ENV, 750 | ); 751 | if ($status{'post-server'}) 752 | { 753 | my $s = $status{'post-server'} >> 8; 754 | printf SUMMARY "post-server failed (%d)\n", $s; 755 | printf STDERR "%s:%s post-server failed (%d)\n", 756 | $$Options{vault}, $$Options{branch}, 757 | $s; 758 | } 759 | } 760 | 761 | if($status{fatal}) 762 | { 763 | system ("rm -rf $destree"); 764 | unlink $err_temp; 765 | printf SUMMARY "%s: %s\n", 'Status', $Status_msg; 766 | exit 199; 767 | } else { 768 | unlink $err_temp; 769 | -z $err_file and unlink $err_file; 770 | } 771 | 772 | printf SUMMARY "%s: %s\n", 773 | 'Backup-complete', strftime('%Y-%m-%d %H:%M:%S', localtime); 774 | 775 | printf SUMMARY "%s: %s\n", 'Status', $Status_msg; 776 | 777 | # We assume warning and unknown produce useful results 778 | $Status eq 'warning' || $Status eq 'unknown' and $Status = 'success'; 779 | 780 | if ($Status eq 'success') 781 | { 782 | -s "$vault/dirvish/$$Options{branch}.hist" or $newhist = 1; 783 | if (open(HIST, ">>$vault/dirvish/$$Options{branch}.hist")) 784 | { 785 | $newhist == 1 and printf HIST ("#%s\t%s\t%s\t%s\n", 786 | qw(IMAGE CREATED REFERECE EXPIRES)); 787 | printf HIST ("%s\t%s\t%s\t%s\n", 788 | $$Options{Image}, 789 | strftime('%Y-%m-%d %H:%M:%S', localtime), 790 | $$Options{Reference} || '-', 791 | $$Options{Expire} 792 | ); 793 | close (HIST); 794 | } 795 | } else { 796 | printf STDERR "dirvish error: branch %s:%s image %s failed\n", 797 | $vault, $$Options{branch}, $$Options{Image}; 798 | } 799 | 800 | length($$Options{'meta-perm'}) 801 | and chmod oct($$Options{'meta-perm'}), 802 | "$vault/$image/summary", 803 | "$vault/$image/rsync_error", 804 | "$vault/$image/log"; 805 | 806 | $Status eq 'success' or exit 149; 807 | 808 | $$Options{log} =~ /.*(gzip)|(bzip2)/ 809 | and system "$$Options{log} $vault/$image/log"; 810 | 811 | if ($$Options{index} && $$Options{index} !~/^no/i) 812 | { 813 | 814 | open(INDEX, ">$vault/$image/index"); 815 | open(FIND, "find $destree -ls|") or seppuku 21, "dirvish $vault:$image cannot build index"; 816 | while () 817 | { 818 | s/ $destree\// $aliastree\//g; 819 | print INDEX $_ or seppuku 22, "dirvish $vault:$image error writing index"; 820 | } 821 | close FIND; 822 | close INDEX; 823 | 824 | length($$Options{'meta-perm'}) 825 | and chmod oct($$Options{'meta-perm'}), "$vault/$image/index"; 826 | $$Options{index} =~ /.*(gzip)|(bzip2)/ 827 | and system "$$Options{index} $vault/$image/index"; 828 | } 829 | 830 | chmod oct($$Options{'image-perm'}) || 0755, "$vault/$image"; 831 | 832 | exit 0; 833 | 834 | sub errorscan 835 | { 836 | my ($status, $err_file, $err_temp) = @_; 837 | my $err_this_loop = 0; 838 | my ($action, $pattern, $severity, $message); 839 | my @erraction = ( 840 | [ 'fatal', '^ssh:.*nection refused', ], 841 | [ 'fatal', '^\S*sh: .* No such file', ], 842 | [ 'fatal', '^ssh:.*No route to host', ], 843 | [ 'error', '^file has vanished: ', ], 844 | [ 'warning', 'readlink .*: no such file or directory', ], 845 | 846 | [ 'fatal', 'failed to write \d+ bytes:', 847 | 'write error, filesystem probably full' ], 848 | [ 'fatal', 'write failed', 849 | 'write error, filesystem probably full' ], 850 | [ 'error', 'error: partial transfer', 851 | 'partial transfer' ], 852 | [ 'error', 'error writing .* exiting: Broken pipe', 853 | 'broken pipe' ], 854 | ); 855 | 856 | open (ERR_FILE, ">>$err_file"); 857 | open (ERR_TEMP, "<$err_temp"); 858 | while () 859 | { 860 | chomp; 861 | s/\s+$//; 862 | length or next; 863 | if (!$err_this_loop) 864 | { 865 | printf ERR_FILE "\n\n*** Execution cycle %d ***\n\n", 866 | $runloops; 867 | $err_this_loop++ 868 | } 869 | print ERR_FILE $_, "\n"; 870 | 871 | $$status{code} or next; 872 | 873 | for $action (@erraction) 874 | { 875 | ($severity, $pattern, $message) = @$action; 876 | /$pattern/ or next; 877 | 878 | ++$$status{$severity}; 879 | $msg = $message || $_; 880 | $$status{message}{$severity} ||= $msg; 881 | logappend($log_file, $msg); 882 | $severity eq 'fatal' 883 | and printf STDERR "dirvish %s:%s fatal error: %s\n", 884 | $$Options{vault}, $$Options{branch}, 885 | $msg; 886 | last; 887 | } 888 | if (/No space left on device/) 889 | { 890 | $msg = 'filesystem full'; 891 | $$status{message}{fatal} eq $msg and next; 892 | 893 | -f $fsb_file and unlink $fsb_file; 894 | ++$$status{fatal}; 895 | $$status{message}{fatal} = $msg; 896 | logappend($log_file, $msg); 897 | printf STDERR "dirvish %s:%s fatal error: %s\n", 898 | $$Options{vault}, $$Options{branch}, 899 | $msg; 900 | } 901 | if (/error: error in rsync protocol data stream/) 902 | { 903 | ++$$status{error}; 904 | $msg = $message || $_; 905 | $$status{message}{error} ||= $msg; 906 | logappend($log_file, $msg); 907 | } 908 | } 909 | close ERR_TEMP; 910 | close ERR_FILE; 911 | } 912 | 913 | sub logappend 914 | { 915 | my ($file, @messages) = @_; 916 | my $message; 917 | 918 | open (LOGFILE, '>>' . $file) or seppuku 20, "cannot open log file $file"; 919 | for $message (@messages) 920 | { 921 | print LOGFILE $message, "\n"; 922 | } 923 | close LOGFILE; 924 | } 925 | 926 | sub scriptrun 927 | { 928 | my (%A) = @_; 929 | my ($cmd, $rcmd, $return); 930 | 931 | $A{now} ||= time; 932 | $A{log} or seppuku 229, "must specify logfile for scriptrun()"; 933 | ref($A{cmd}) and seppuku 232, "$A{lable} option specification error"; 934 | 935 | $cmd = strftime($A{cmd}, localtime($A{now})); 936 | 937 | #KHL 2005-02-18 BadShellCommandCWD: fix inverted logic 938 | # if ($A{dir} =~ /^:/) 939 | if ($A{dir} !~ /^:/) 940 | { 941 | $rcmd = sprintf ("%s 'cd %s; %s %s' >>%s", 942 | ("$A{shell}" || "/bin/sh -c"), 943 | $A{dir}, $A{env}, 944 | $cmd, 945 | $A{log} 946 | ); 947 | } else { 948 | $rcmd = sprintf ("%s '%s %s' >>%s", 949 | ("$A{shell}" || "/bin/sh -c"), 950 | $A{env}, 951 | $cmd, 952 | $A{log} 953 | ); 954 | } 955 | 956 | $A{lable} =~ /^Post/ and logappend($A{log}, "\n"); 957 | 958 | logappend($A{log}, "$A{lable}: $cmd"); 959 | 960 | $return = system($rcmd); 961 | 962 | $A{lable} =~ /^Pre/ and logappend($A{log}, "\n"); 963 | 964 | return $return; 965 | } 966 | 967 | # Get patch level of loadconfig.pl in case exit codes 968 | # are needed. 969 | # $Id: loadconfig.pl,v 12.0 2004/02/25 02:42:15 jw Exp $ 970 | 971 | 972 | ######################################################################### 973 | # # 974 | # Copyright 2002 and $Date: 2004/02/25 02:42:15 $ 975 | # Pegasystems Technologies and J.W. Schultz # 976 | # # 977 | # Licensed under the Open Software License version 2.0 # 978 | # # 979 | ######################################################################### 980 | 981 | sub seppuku # Exit with code and message. 982 | { 983 | my ($status, $message) = @_; 984 | 985 | chomp $message; 986 | if ($message) 987 | { 988 | $seppuku_prefix and print STDERR $seppuku_prefix, ': '; 989 | print STDERR $message, "\n"; 990 | } 991 | exit $status; 992 | } 993 | 994 | sub slurplist 995 | { 996 | my ($key, $filename, $Options) = @_; 997 | my $f; 998 | my $array; 999 | 1000 | $filename =~ m(^/) and $f = $filename; 1001 | if (!$f && ref($$Options{vault}) ne 'CODE') 1002 | { 1003 | $f = join('/', $$Options{Bank}, $$Options{vault}, 1004 | 'dirvish', $filename); 1005 | -f $f or $f = undef; 1006 | } 1007 | $f or $f = "$CONFDIR/$filename"; 1008 | open(PATFILE, "<$f") or seppuku 229, "cannot open $filename for $key list"; 1009 | $array = $$Options{$key}; 1010 | while() 1011 | { 1012 | chomp; 1013 | length or next; 1014 | push @{$array}, $_; 1015 | } 1016 | close PATFILE; 1017 | } 1018 | 1019 | # loadconfig -- load configuration file 1020 | # SYNOPSYS 1021 | # loadconfig($opts, $filename, \%data) 1022 | # 1023 | # DESCRIPTION 1024 | # load and parse a configuration file into the data 1025 | # hash. If the filename does not contain / it will be 1026 | # looked for in the vault if defined. If the filename 1027 | # does not exist but filename.conf does that will 1028 | # be read. 1029 | # 1030 | # OPTIONS 1031 | # Options are case sensitive, upper case has the 1032 | # opposite effect of lower case. If conflicting 1033 | # options are given only the last will have effect. 1034 | # 1035 | # f Ignore fields in config file that are 1036 | # capitalized. 1037 | # 1038 | # o Config file is optional, return undef if missing. 1039 | # 1040 | # R Do not allow recoursion. 1041 | # 1042 | # g Only load from global directory. 1043 | # 1044 | # 1045 | # 1046 | # LIMITATIONS 1047 | # Only way to tell whether an option should be a list 1048 | # or scalar is by the formatting in the config file. 1049 | # 1050 | # Options reqiring special handling have to have that 1051 | # hardcoded in the function. 1052 | # 1053 | 1054 | sub loadconfig 1055 | { 1056 | my ($mode, $configfile, $Options) = @_; 1057 | my $confile = undef; 1058 | my ($key, $val); 1059 | my $CONFIG; 1060 | ref($Options) or $Options = {}; 1061 | my %modes; 1062 | my ($conf, $bank, $k); 1063 | 1064 | $modes{r} = 1; 1065 | for $_ (split(//, $mode)) 1066 | { 1067 | if (/[A-Z]/) 1068 | { 1069 | $_ =~ tr/A-Z/a-z/; 1070 | $modes{$_} = 0; 1071 | } else { 1072 | $modes{$_} = 1; 1073 | } 1074 | } 1075 | 1076 | 1077 | $CONFIG = 'CFILE' . scalar(@{$$Options{Configfiles}}); 1078 | 1079 | $configfile =~ s/^.*\@//; 1080 | 1081 | if($configfile =~ m[/]) 1082 | { 1083 | $confile = $configfile; 1084 | } 1085 | elsif($configfile ne '-') 1086 | { 1087 | if(!$modes{g} && $$Options{vault} && $$Options{vault} ne 'CODE') 1088 | { 1089 | if(!$$Options{Bank}) 1090 | { 1091 | my $bank; 1092 | for $bank (@{$$Options{bank}}) 1093 | { 1094 | if (-d "$bank/$$Options{vault}") 1095 | { 1096 | $$Options{Bank} = $bank; 1097 | last; 1098 | } 1099 | } 1100 | } 1101 | if ($$Options{Bank}) 1102 | { 1103 | $confile = join('/', $$Options{Bank}, 1104 | $$Options{vault}, 'dirvish', 1105 | $configfile); 1106 | -f $confile || -f "$confile.conf" 1107 | or $confile = undef; 1108 | } 1109 | } 1110 | $confile ||= "$CONFDIR/$configfile"; 1111 | } 1112 | 1113 | if($configfile eq '-') 1114 | { 1115 | open($CONFIG, $configfile) or seppuku 221, "cannot open STDIN"; 1116 | } else { 1117 | ! -f $confile && -f "$confile.conf" and $confile .= '.conf'; 1118 | 1119 | if (! -f "$confile") 1120 | { 1121 | $modes{o} and return undef; 1122 | seppuku 222, "cannot open config file: $configfile"; 1123 | } 1124 | 1125 | grep(/^$confile$/, @{$$Options{Configfiles}}) 1126 | and seppuku 224, "ERROR: config file looping on $confile"; 1127 | 1128 | open($CONFIG, $confile) 1129 | or seppuku 225, "cannot open config file: $configfile"; 1130 | } 1131 | push(@{$$Options{Configfiles}}, $confile); 1132 | 1133 | while(<$CONFIG>) 1134 | { 1135 | chomp; 1136 | s/\s*#.*$//; 1137 | s/\s+$//; 1138 | /\S/ or next; 1139 | 1140 | if(/^\s/ && $key) 1141 | { 1142 | s/^\s*//; 1143 | push @{$$Options{$key}}, $_; 1144 | } 1145 | elsif(/^SET\s+/) 1146 | { 1147 | s/^SET\s+//; 1148 | for $k (split(/\s+/)) 1149 | { 1150 | $$Options{$k} = 1; 1151 | } 1152 | } 1153 | elsif(/^UNSET\s+/) 1154 | { 1155 | s/^UNSET\s+//; 1156 | for $k (split(/\s+/)) 1157 | { 1158 | $$Options{$k} = undef; 1159 | } 1160 | } 1161 | elsif(/^RESET\s+/) 1162 | { 1163 | ($key = $_) =~ s/^RESET\s+//; 1164 | $$Options{$key} = [ ]; 1165 | } 1166 | elsif(/^[A-Z]/ && $modes{f}) 1167 | { 1168 | $key = undef; 1169 | } 1170 | elsif(/^\S+:/) 1171 | { 1172 | ($key, $val) = split(/:\s*/, $_, 2); 1173 | length($val) or next; 1174 | $k = $key; $key = undef; 1175 | 1176 | if ($k eq 'config') 1177 | { 1178 | $modes{r} and loadconfig($mode . 'O', $val, $Options); 1179 | next; 1180 | } 1181 | if ($k eq 'client') 1182 | { 1183 | if ($modes{r} && ref ($$Options{$k}) eq 'CODE') 1184 | { 1185 | loadconfig($mode . 'og', "$CONFDIR/$val", $Options); 1186 | } 1187 | $$Options{$k} = $val; 1188 | next; 1189 | } 1190 | if ($k eq 'file-exclude') 1191 | { 1192 | $modes{r} or next; 1193 | 1194 | slurplist('exclude', $val, $Options); 1195 | next; 1196 | } 1197 | if (ref ($$Options{$k}) eq 'ARRAY') 1198 | { 1199 | push @{$$Options{$k}}, $_; 1200 | } else { 1201 | $$Options{$k} = $val; 1202 | } 1203 | } 1204 | } 1205 | close $CONFIG; 1206 | return $Options; 1207 | } 1208 | -------------------------------------------------------------------------------- /dirvish/files/bin/dirvish-expire: -------------------------------------------------------------------------------- 1 | #!/usr/bin/perl 2 | 3 | $CONFDIR = "/etc/dirvish"; 4 | 5 | # $Id: dirvish-expire.pl,v 12.0 2004/02/25 02:42:14 jw Exp $ $Name: Dirvish-1_2 $ 6 | 7 | $VERSION = ('$Name: Dirvish-1_2 $' =~ /Dirvish/i) 8 | ? ('$Name: Dirvish-1_2 $' =~ m/^.*:\s+dirvish-(.*)\s*\$$/i)[0] 9 | : '1.1.2 patch' . ('$Id: dirvish-expire.pl,v 12.0 2004/02/25 02:42:14 jw Exp $' 10 | =~ m/^.*,v(.*:\d\d)\s.*$/)[0]; 11 | $VERSION =~ s/_/./g; 12 | 13 | 14 | ######################################################################### 15 | # # 16 | # Copyright 2002 and $Date: 2004/02/25 02:42:14 $ 17 | # Pegasystems Technologies and J.W. Schultz # 18 | # # 19 | # Licensed under the Open Software License version 2.0 # 20 | # # 21 | # This program is free software; you can redistribute it # 22 | # and/or modify it under the terms of the Open Software # 23 | # License, version 2.0 by Lauwrence E. Rosen. # 24 | # # 25 | # This program is distributed in the hope that it will be # 26 | # useful, but WITHOUT ANY WARRANTY; without even the implied # 27 | # warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR # 28 | # PURPOSE. See the Open Software License for details. # 29 | # # 30 | ######################################################################### 31 | 32 | use Time::ParseDate; 33 | use POSIX qw(strftime); 34 | use File::Find; 35 | use Getopt::Long; 36 | 37 | sub loadconfig; 38 | sub check_expire; 39 | sub findop; 40 | sub imsort; 41 | sub seppuku; 42 | 43 | sub usage 44 | { 45 | my $message = shift(@_); 46 | 47 | length($message) and print STDERR $message, "\n\n"; 48 | 49 | print STDERR < \&usage, 67 | version => sub { 68 | print STDERR "dirvish version $VERSION\n"; 69 | exit(0); 70 | }, 71 | }; 72 | 73 | if ($CONFDIR =~ /dirvish$/ && -f "$CONFDIR.conf") 74 | { 75 | loadconfig(undef, "$CONFDIR.conf", $Options); 76 | } 77 | elsif (-f "$CONFDIR/master.conf") 78 | { 79 | loadconfig(undef, "$CONFDIR/master.conf", $Options); 80 | } 81 | elsif (-f "$CONFDIR/dirvish.conf") 82 | { 83 | seppuku 250, < $expire_time and return 0; 198 | 199 | return 1; 200 | } 201 | 202 | sub findop 203 | { 204 | if ($_ eq 'tree') 205 | { 206 | $File::Find::prune = 1; 207 | return 0; 208 | } 209 | if ($_ eq 'summary') 210 | { 211 | my $summary; 212 | my ($etime, $path); 213 | 214 | $path = $File::Find::dir; 215 | 216 | $summary = loadconfig('R', $File::Find::name); 217 | $status = check_expire($summary, $expire_time); 218 | 219 | $status < 0 and return; 220 | 221 | $$summary{vault} && $$summary{branch} && $$summary{Image} 222 | or return; 223 | 224 | if ($status == 0) 225 | { 226 | $$summary{Status} =~ /^success/ && -d ($path . '/tree') 227 | and ++$unexpired{$$summary{vault}}{$$summary{branch}}; 228 | return; 229 | } 230 | 231 | -d ($path . ($$Options{tree} ? '/tree': undef)) or return; 232 | 233 | push (@expires, { 234 | vault => $$summary{vault}, 235 | branch => $$summary{branch}, 236 | client => $$summary{client}, 237 | tree => $$summary{tree}, 238 | image => $$summary{Image}, 239 | created => $$summary{'Backup-complete'}, 240 | expire => $$summary{Expire}, 241 | status => $$summary{Status}, 242 | path => $path, 243 | } 244 | ); 245 | } 246 | } 247 | 248 | ## WARNING: don't mess with the sort order, it is needed so that if 249 | ## WARNING: all images are expired the newest will be retained. 250 | sub imsort 251 | { 252 | $$a{vault} cmp $$b{vault} 253 | || $$a{branch} cmp $$b{branch} 254 | || $$a{created} cmp $$b{created}; 255 | } 256 | 257 | # Get patch level of loadconfig.pl in case exit codes 258 | # are needed. 259 | # $Id: loadconfig.pl,v 12.0 2004/02/25 02:42:15 jw Exp $ 260 | 261 | 262 | ######################################################################### 263 | # # 264 | # Copyright 2002 and $Date: 2004/02/25 02:42:15 $ 265 | # Pegasystems Technologies and J.W. Schultz # 266 | # # 267 | # Licensed under the Open Software License version 2.0 # 268 | # # 269 | ######################################################################### 270 | 271 | sub seppuku # Exit with code and message. 272 | { 273 | my ($status, $message) = @_; 274 | 275 | chomp $message; 276 | if ($message) 277 | { 278 | $seppuku_prefix and print STDERR $seppuku_prefix, ': '; 279 | print STDERR $message, "\n"; 280 | } 281 | exit $status; 282 | } 283 | 284 | sub slurplist 285 | { 286 | my ($key, $filename, $Options) = @_; 287 | my $f; 288 | my $array; 289 | 290 | $filename =~ m(^/) and $f = $filename; 291 | if (!$f && ref($$Options{vault}) ne 'CODE') 292 | { 293 | $f = join('/', $$Options{Bank}, $$Options{vault}, 294 | 'dirvish', $filename); 295 | -f $f or $f = undef; 296 | } 297 | $f or $f = "$CONFDIR/$filename"; 298 | open(PATFILE, "<$f") or seppuku 229, "cannot open $filename for $key list"; 299 | $array = $$Options{$key}; 300 | while() 301 | { 302 | chomp; 303 | length or next; 304 | push @{$array}, $_; 305 | } 306 | close PATFILE; 307 | } 308 | 309 | # loadconfig -- load configuration file 310 | # SYNOPSYS 311 | # loadconfig($opts, $filename, \%data) 312 | # 313 | # DESCRIPTION 314 | # load and parse a configuration file into the data 315 | # hash. If the filename does not contain / it will be 316 | # looked for in the vault if defined. If the filename 317 | # does not exist but filename.conf does that will 318 | # be read. 319 | # 320 | # OPTIONS 321 | # Options are case sensitive, upper case has the 322 | # opposite effect of lower case. If conflicting 323 | # options are given only the last will have effect. 324 | # 325 | # f Ignore fields in config file that are 326 | # capitalized. 327 | # 328 | # o Config file is optional, return undef if missing. 329 | # 330 | # R Do not allow recoursion. 331 | # 332 | # g Only load from global directory. 333 | # 334 | # 335 | # 336 | # LIMITATIONS 337 | # Only way to tell whether an option should be a list 338 | # or scalar is by the formatting in the config file. 339 | # 340 | # Options reqiring special handling have to have that 341 | # hardcoded in the function. 342 | # 343 | 344 | sub loadconfig 345 | { 346 | my ($mode, $configfile, $Options) = @_; 347 | my $confile = undef; 348 | my ($key, $val); 349 | my $CONFIG; 350 | ref($Options) or $Options = {}; 351 | my %modes; 352 | my ($conf, $bank, $k); 353 | 354 | $modes{r} = 1; 355 | for $_ (split(//, $mode)) 356 | { 357 | if (/[A-Z]/) 358 | { 359 | $_ =~ tr/A-Z/a-z/; 360 | $modes{$_} = 0; 361 | } else { 362 | $modes{$_} = 1; 363 | } 364 | } 365 | 366 | 367 | $CONFIG = 'CFILE' . scalar(@{$$Options{Configfiles}}); 368 | 369 | $configfile =~ s/^.*\@//; 370 | 371 | if($configfile =~ m[/]) 372 | { 373 | $confile = $configfile; 374 | } 375 | elsif($configfile ne '-') 376 | { 377 | if(!$modes{g} && $$Options{vault} && $$Options{vault} ne 'CODE') 378 | { 379 | if(!$$Options{Bank}) 380 | { 381 | my $bank; 382 | for $bank (@{$$Options{bank}}) 383 | { 384 | if (-d "$bank/$$Options{vault}") 385 | { 386 | $$Options{Bank} = $bank; 387 | last; 388 | } 389 | } 390 | } 391 | if ($$Options{Bank}) 392 | { 393 | $confile = join('/', $$Options{Bank}, 394 | $$Options{vault}, 'dirvish', 395 | $configfile); 396 | -f $confile || -f "$confile.conf" 397 | or $confile = undef; 398 | } 399 | } 400 | $confile ||= "$CONFDIR/$configfile"; 401 | } 402 | 403 | if($configfile eq '-') 404 | { 405 | open($CONFIG, $configfile) or seppuku 221, "cannot open STDIN"; 406 | } else { 407 | ! -f $confile && -f "$confile.conf" and $confile .= '.conf'; 408 | 409 | if (! -f "$confile") 410 | { 411 | $modes{o} and return undef; 412 | seppuku 222, "cannot open config file: $configfile"; 413 | } 414 | 415 | grep(/^$confile$/, @{$$Options{Configfiles}}) 416 | and seppuku 224, "ERROR: config file looping on $confile"; 417 | 418 | open($CONFIG, $confile) 419 | or seppuku 225, "cannot open config file: $configfile"; 420 | } 421 | push(@{$$Options{Configfiles}}, $confile); 422 | 423 | while(<$CONFIG>) 424 | { 425 | chomp; 426 | s/\s*#.*$//; 427 | s/\s+$//; 428 | /\S/ or next; 429 | 430 | if(/^\s/ && $key) 431 | { 432 | s/^\s*//; 433 | push @{$$Options{$key}}, $_; 434 | } 435 | elsif(/^SET\s+/) 436 | { 437 | s/^SET\s+//; 438 | for $k (split(/\s+/)) 439 | { 440 | $$Options{$k} = 1; 441 | } 442 | } 443 | elsif(/^UNSET\s+/) 444 | { 445 | s/^UNSET\s+//; 446 | for $k (split(/\s+/)) 447 | { 448 | $$Options{$k} = undef; 449 | } 450 | } 451 | elsif(/^RESET\s+/) 452 | { 453 | ($key = $_) =~ s/^RESET\s+//; 454 | $$Options{$key} = [ ]; 455 | } 456 | elsif(/^[A-Z]/ && $modes{f}) 457 | { 458 | $key = undef; 459 | } 460 | elsif(/^\S+:/) 461 | { 462 | ($key, $val) = split(/:\s*/, $_, 2); 463 | length($val) or next; 464 | $k = $key; $key = undef; 465 | 466 | if ($k eq 'config') 467 | { 468 | $modes{r} and loadconfig($mode . 'O', $val, $Options); 469 | next; 470 | } 471 | if ($k eq 'client') 472 | { 473 | if ($modes{r} && ref ($$Options{$k}) eq 'CODE') 474 | { 475 | loadconfig($mode . 'og', "$CONFDIR/$val", $Options); 476 | } 477 | $$Options{$k} = $val; 478 | next; 479 | } 480 | if ($k eq 'file-exclude') 481 | { 482 | $modes{r} or next; 483 | 484 | slurplist('exclude', $val, $Options); 485 | next; 486 | } 487 | if (ref ($$Options{$k}) eq 'ARRAY') 488 | { 489 | push @{$$Options{$k}}, $_; 490 | } else { 491 | $$Options{$k} = $val; 492 | } 493 | } 494 | } 495 | close $CONFIG; 496 | return $Options; 497 | } 498 | -------------------------------------------------------------------------------- /dirvish/files/bin/dirvish-locate: -------------------------------------------------------------------------------- 1 | #!/usr/bin/perl 2 | 3 | $CONFDIR = "/etc/dirvish"; 4 | 5 | # $Id: dirvish-locate.pl,v 12.0 2004/02/25 02:42:14 jw Exp $ $Name: Dirvish-1_2 $ 6 | 7 | $VERSION = ('$Name: Dirvish-1_2 $' =~ /Dirvish/i) 8 | ? ('$Name: Dirvish-1_2 $' =~ m/^.*:\s+dirvish-(.*)\s*\$$/i)[0] 9 | : '1.1.2 patch' . ('$Id: dirvish-locate.pl,v 12.0 2004/02/25 02:42:14 jw Exp $' 10 | =~ m/^.*,v(.*:\d\d)\s.*$/)[0]; 11 | $VERSION =~ s/_/./g; 12 | 13 | 14 | ######################################################################### 15 | # # 16 | # Copyright 2003 and $Date: 2004/02/25 02:42:14 $ 17 | # Pegasystems Technologies and J.W. Schultz # 18 | # # 19 | # Licensed under the Open Software License version 2.0 # 20 | # # 21 | # This program is free software; you can redistribute it # 22 | # and/or modify it under the terms of the Open Software # 23 | # License, version 2.0 by Lauwrence E. Rosen. # 24 | # # 25 | # This program is distributed in the hope that it will be # 26 | # useful, but WITHOUT ANY WARRANTY; without even the implied # 27 | # warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR # 28 | # PURPOSE. See the Open Software License for details. # 29 | # # 30 | ######################################################################### 31 | 32 | use Time::ParseDate; 33 | use POSIX qw(strftime); 34 | use File::Find; 35 | use Getopt::Long; 36 | 37 | sub loadconfig; 38 | sub check_expire; 39 | sub findop; 40 | sub imsort; 41 | sub seppuku; 42 | 43 | $KILLCOUNT = 1000; 44 | $MAXCOUNT = 100; 45 | 46 | sub usage 47 | { 48 | my $message = shift(@_); 49 | 50 | length($message) and print STDERR $message, "\n\n"; 51 | 52 | print STDERR < \&usage, 64 | version => sub { 65 | print STDERR "dirvish version $VERSION\n"; 66 | exit(0); 67 | }, 68 | }; 69 | 70 | if ($CONFDIR =~ /dirvish$/ && -f "$CONFDIR.conf") 71 | { 72 | loadconfig(undef, "$CONFDIR.conf", $Options); 73 | } 74 | elsif (-f "$CONFDIR/master.conf") 75 | { 76 | loadconfig(undef, "$CONFDIR/master.conf", $Options); 77 | } 78 | elsif (-f "$CONFDIR/dirvish.conf") 79 | { 80 | seppuku 250, < $imdir, 129 | image => $$conf{Image}, 130 | branch => $$conf{branch}, 131 | created => $$conf{'Backup-complete'}, 132 | } 133 | } 134 | 135 | for $image (sort(imsort @images)) 136 | { 137 | $imdir = $$image{imdir}; 138 | 139 | $index = undef; 140 | -f "$imdir/index.bz2" and $index = "bzip2 -d -c $imdir/index.bz2|"; 141 | -f "$imdir/index.gz" and $index = "gzip -d -c $imdir/index|"; 142 | -f "$imdir/index" and $index = "<$imdir/index"; 143 | $index or next; 144 | 145 | ++$imagecount; 146 | 147 | open INDEX, $index or next; 148 | while () 149 | { 150 | chomp; 151 | 152 | m($partpattern) or next; 153 | 154 | # this parse operation is too slow. It might be faster as a 155 | # split with trimmed leading whitespace and remerged modtime 156 | $f = { image => $image }; 157 | ( 158 | $$f{inode}, 159 | $$f{blocks}, 160 | $$f{perms}, 161 | $$f{links}, 162 | $$f{owner}, 163 | $$f{group}, 164 | $$f{bytes}, 165 | $$f{mtime}, 166 | $path 167 | ) = m<^ 168 | \s*(\S+) # inode 169 | \s+(\S+) # block count 170 | \s+(\S+) # perms 171 | \s+(\S+) # link count 172 | \s+(\S+) # owner 173 | \s+(\S+) # group 174 | \s+(\S+) # byte count 175 | \s+(\S+\s+\S+\s+\S+) # date 176 | \s+(\S.*) # path 177 | $>x; 178 | $$f{perms} =~ /^[dl]/ and next; 179 | $path =~ m($fullpattern) or next; 180 | 181 | exists($match{$path}) or ++$pathcount; 182 | push @{$match{$path}}, $f; 183 | } 184 | if ($pathcount >= $KILLCOUNT) 185 | { 186 | printf "dirvish-locate: too many paths match pattern, interupting search\n"; 187 | last; 188 | } 189 | } 190 | 191 | printf "%d matches in %d images\n", $pathcount, $imagecount; 192 | $pathcount >= $MAXCOUNT 193 | and printf "Pattern '%s' too vague, listing paths only.\n", 194 | $Pattern; 195 | 196 | for $path (sort(keys(%match))) 197 | { 198 | $last = undef; 199 | print $path; 200 | 201 | if ($pathcount >= $MAXCOUNT) 202 | { 203 | print "\n"; 204 | next; 205 | } 206 | 207 | for $hit (@{$match{$path}}) 208 | { 209 | $inode = $$hit{inode}; 210 | $mtime = $$hit{mtime}; 211 | $image = $$hit{image}{image}; 212 | if ($inode ne $last) 213 | { 214 | $linesize = 5 + length($mtime) + length($image); 215 | printf "\n %s %s", $mtime, $image; 216 | } else { 217 | $linesize += length($image) + 2; 218 | if ($linesize > 78) 219 | { 220 | $linesize = 5 + length($mtime) + length($image); 221 | print "\n", 222 | " " x (5 + length($mtime)), 223 | $image; 224 | } else { 225 | printf ", %s", $$hit{image}{image}; 226 | } 227 | } 228 | $last = $inode; 229 | } 230 | print "\n\n"; 231 | } 232 | 233 | exit 0; 234 | 235 | sub imsort 236 | { 237 | $$a{branch} cmp $$b{branch} 238 | || $$b{created} cmp $$a{created}; 239 | } 240 | 241 | # Get patch level of loadconfig.pl in case exit codes 242 | # are needed. 243 | # $Id: loadconfig.pl,v 12.0 2004/02/25 02:42:15 jw Exp $ 244 | 245 | 246 | ######################################################################### 247 | # # 248 | # Copyright 2002 and $Date: 2004/02/25 02:42:15 $ 249 | # Pegasystems Technologies and J.W. Schultz # 250 | # # 251 | # Licensed under the Open Software License version 2.0 # 252 | # # 253 | ######################################################################### 254 | 255 | sub seppuku # Exit with code and message. 256 | { 257 | my ($status, $message) = @_; 258 | 259 | chomp $message; 260 | if ($message) 261 | { 262 | $seppuku_prefix and print STDERR $seppuku_prefix, ': '; 263 | print STDERR $message, "\n"; 264 | } 265 | exit $status; 266 | } 267 | 268 | sub slurplist 269 | { 270 | my ($key, $filename, $Options) = @_; 271 | my $f; 272 | my $array; 273 | 274 | $filename =~ m(^/) and $f = $filename; 275 | if (!$f && ref($$Options{vault}) ne 'CODE') 276 | { 277 | $f = join('/', $$Options{Bank}, $$Options{vault}, 278 | 'dirvish', $filename); 279 | -f $f or $f = undef; 280 | } 281 | $f or $f = "$CONFDIR/$filename"; 282 | open(PATFILE, "<$f") or seppuku 229, "cannot open $filename for $key list"; 283 | $array = $$Options{$key}; 284 | while() 285 | { 286 | chomp; 287 | length or next; 288 | push @{$array}, $_; 289 | } 290 | close PATFILE; 291 | } 292 | 293 | # loadconfig -- load configuration file 294 | # SYNOPSYS 295 | # loadconfig($opts, $filename, \%data) 296 | # 297 | # DESCRIPTION 298 | # load and parse a configuration file into the data 299 | # hash. If the filename does not contain / it will be 300 | # looked for in the vault if defined. If the filename 301 | # does not exist but filename.conf does that will 302 | # be read. 303 | # 304 | # OPTIONS 305 | # Options are case sensitive, upper case has the 306 | # opposite effect of lower case. If conflicting 307 | # options are given only the last will have effect. 308 | # 309 | # f Ignore fields in config file that are 310 | # capitalized. 311 | # 312 | # o Config file is optional, return undef if missing. 313 | # 314 | # R Do not allow recoursion. 315 | # 316 | # g Only load from global directory. 317 | # 318 | # 319 | # 320 | # LIMITATIONS 321 | # Only way to tell whether an option should be a list 322 | # or scalar is by the formatting in the config file. 323 | # 324 | # Options reqiring special handling have to have that 325 | # hardcoded in the function. 326 | # 327 | 328 | sub loadconfig 329 | { 330 | my ($mode, $configfile, $Options) = @_; 331 | my $confile = undef; 332 | my ($key, $val); 333 | my $CONFIG; 334 | ref($Options) or $Options = {}; 335 | my %modes; 336 | my ($conf, $bank, $k); 337 | 338 | $modes{r} = 1; 339 | for $_ (split(//, $mode)) 340 | { 341 | if (/[A-Z]/) 342 | { 343 | $_ =~ tr/A-Z/a-z/; 344 | $modes{$_} = 0; 345 | } else { 346 | $modes{$_} = 1; 347 | } 348 | } 349 | 350 | 351 | $CONFIG = 'CFILE' . scalar(@{$$Options{Configfiles}}); 352 | 353 | $configfile =~ s/^.*\@//; 354 | 355 | if($configfile =~ m[/]) 356 | { 357 | $confile = $configfile; 358 | } 359 | elsif($configfile ne '-') 360 | { 361 | if(!$modes{g} && $$Options{vault} && $$Options{vault} ne 'CODE') 362 | { 363 | if(!$$Options{Bank}) 364 | { 365 | my $bank; 366 | for $bank (@{$$Options{bank}}) 367 | { 368 | if (-d "$bank/$$Options{vault}") 369 | { 370 | $$Options{Bank} = $bank; 371 | last; 372 | } 373 | } 374 | } 375 | if ($$Options{Bank}) 376 | { 377 | $confile = join('/', $$Options{Bank}, 378 | $$Options{vault}, 'dirvish', 379 | $configfile); 380 | -f $confile || -f "$confile.conf" 381 | or $confile = undef; 382 | } 383 | } 384 | $confile ||= "$CONFDIR/$configfile"; 385 | } 386 | 387 | if($configfile eq '-') 388 | { 389 | open($CONFIG, $configfile) or seppuku 221, "cannot open STDIN"; 390 | } else { 391 | ! -f $confile && -f "$confile.conf" and $confile .= '.conf'; 392 | 393 | if (! -f "$confile") 394 | { 395 | $modes{o} and return undef; 396 | seppuku 222, "cannot open config file: $configfile"; 397 | } 398 | 399 | grep(/^$confile$/, @{$$Options{Configfiles}}) 400 | and seppuku 224, "ERROR: config file looping on $confile"; 401 | 402 | open($CONFIG, $confile) 403 | or seppuku 225, "cannot open config file: $configfile"; 404 | } 405 | push(@{$$Options{Configfiles}}, $confile); 406 | 407 | while(<$CONFIG>) 408 | { 409 | chomp; 410 | s/\s*#.*$//; 411 | s/\s+$//; 412 | /\S/ or next; 413 | 414 | if(/^\s/ && $key) 415 | { 416 | s/^\s*//; 417 | push @{$$Options{$key}}, $_; 418 | } 419 | elsif(/^SET\s+/) 420 | { 421 | s/^SET\s+//; 422 | for $k (split(/\s+/)) 423 | { 424 | $$Options{$k} = 1; 425 | } 426 | } 427 | elsif(/^UNSET\s+/) 428 | { 429 | s/^UNSET\s+//; 430 | for $k (split(/\s+/)) 431 | { 432 | $$Options{$k} = undef; 433 | } 434 | } 435 | elsif(/^RESET\s+/) 436 | { 437 | ($key = $_) =~ s/^RESET\s+//; 438 | $$Options{$key} = [ ]; 439 | } 440 | elsif(/^[A-Z]/ && $modes{f}) 441 | { 442 | $key = undef; 443 | } 444 | elsif(/^\S+:/) 445 | { 446 | ($key, $val) = split(/:\s*/, $_, 2); 447 | length($val) or next; 448 | $k = $key; $key = undef; 449 | 450 | if ($k eq 'config') 451 | { 452 | $modes{r} and loadconfig($mode . 'O', $val, $Options); 453 | next; 454 | } 455 | if ($k eq 'client') 456 | { 457 | if ($modes{r} && ref ($$Options{$k}) eq 'CODE') 458 | { 459 | loadconfig($mode . 'og', "$CONFDIR/$val", $Options); 460 | } 461 | $$Options{$k} = $val; 462 | next; 463 | } 464 | if ($k eq 'file-exclude') 465 | { 466 | $modes{r} or next; 467 | 468 | slurplist('exclude', $val, $Options); 469 | next; 470 | } 471 | if (ref ($$Options{$k}) eq 'ARRAY') 472 | { 473 | push @{$$Options{$k}}, $_; 474 | } else { 475 | $$Options{$k} = $val; 476 | } 477 | } 478 | } 479 | close $CONFIG; 480 | return $Options; 481 | } 482 | -------------------------------------------------------------------------------- /dirvish/files/bin/dirvish-runall: -------------------------------------------------------------------------------- 1 | #!/usr/bin/perl 2 | 3 | $CONFDIR = "/etc/dirvish"; 4 | 5 | # $Id: dirvish-runall.pl,v 12.0 2004/02/25 02:42:14 jw Exp $ $Name: Dirvish-1_2 $ 6 | 7 | $VERSION = ('$Name: Dirvish-1_2 $' =~ /Dirvish/i) 8 | ? ('$Name: Dirvish-1_2 $' =~ m/^.*:\s+dirvish-(.*)\s*\$$/i)[0] 9 | : '1.1.2 patch' . ('$Id: dirvish-runall.pl,v 12.0 2004/02/25 02:42:14 jw Exp $' 10 | =~ m/^.*,v(.*:\d\d)\s.*$/)[0]; 11 | $VERSION =~ s/_/./g; 12 | 13 | 14 | ######################################################################### 15 | # # 16 | # Copyright 2002 and $Date: 2004/02/25 02:42:14 $ 17 | # Pegasystems Technologies and J.W. Schultz # 18 | # # 19 | # Licensed under the Open Software License version 2.0 # 20 | # # 21 | # This program is free software; you can redistribute it # 22 | # and/or modify it under the terms of the Open Software # 23 | # License, version 2.0 by Lauwrence E. Rosen. # 24 | # # 25 | # This program is distributed in the hope that it will be # 26 | # useful, but WITHOUT ANY WARRANTY; without even the implied # 27 | # warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR # 28 | # PURPOSE. See the Open Software License for details. # 29 | # # 30 | ######################################################################### 31 | 32 | use Time::ParseDate; 33 | use POSIX qw(strftime); 34 | use Getopt::Long; 35 | 36 | sub loadconfig; 37 | sub seppuku; 38 | 39 | sub usage 40 | { 41 | my $message = shift(@_); 42 | 43 | length($message) and print STDERR $message, "\n\n"; 44 | 45 | $! and exit(255); # because getopt seems to send us here for death 46 | 47 | print STDERR < sub { 62 | print STDERR "dirvish version $VERSION\n"; 63 | exit(0); 64 | }, 65 | help => \&usage, 66 | }; 67 | 68 | GetOptions($Options, qw( 69 | config=s 70 | quiet no-run|dry-run 71 | version help 72 | )) or usage; 73 | 74 | if ($$Options{config}) 75 | { 76 | $Config = loadconfig(undef, $$Options{config}) 77 | } 78 | elsif ($CONFDIR =~ /dirvish$/ && -f "$CONFDIR.conf") 79 | { 80 | $Config = loadconfig(undef, "$CONFDIR.conf"); 81 | } 82 | elsif (-f "$CONFDIR/master.conf") 83 | { 84 | $Config = loadconfig(undef, "$CONFDIR/master.conf"); 85 | } 86 | elsif (-f "$CONFDIR/dirvish.conf") 87 | { 88 | seppuku 250, <) 165 | { 166 | chomp; 167 | length or next; 168 | push @{$array}, $_; 169 | } 170 | close PATFILE; 171 | } 172 | 173 | # loadconfig -- load configuration file 174 | # SYNOPSYS 175 | # loadconfig($opts, $filename, \%data) 176 | # 177 | # DESCRIPTION 178 | # load and parse a configuration file into the data 179 | # hash. If the filename does not contain / it will be 180 | # looked for in the vault if defined. If the filename 181 | # does not exist but filename.conf does that will 182 | # be read. 183 | # 184 | # OPTIONS 185 | # Options are case sensitive, upper case has the 186 | # opposite effect of lower case. If conflicting 187 | # options are given only the last will have effect. 188 | # 189 | # f Ignore fields in config file that are 190 | # capitalized. 191 | # 192 | # o Config file is optional, return undef if missing. 193 | # 194 | # R Do not allow recoursion. 195 | # 196 | # g Only load from global directory. 197 | # 198 | # 199 | # 200 | # LIMITATIONS 201 | # Only way to tell whether an option should be a list 202 | # or scalar is by the formatting in the config file. 203 | # 204 | # Options reqiring special handling have to have that 205 | # hardcoded in the function. 206 | # 207 | 208 | sub loadconfig 209 | { 210 | my ($mode, $configfile, $Options) = @_; 211 | my $confile = undef; 212 | my ($key, $val); 213 | my $CONFIG; 214 | ref($Options) or $Options = {}; 215 | my %modes; 216 | my ($conf, $bank, $k); 217 | 218 | $modes{r} = 1; 219 | for $_ (split(//, $mode)) 220 | { 221 | if (/[A-Z]/) 222 | { 223 | $_ =~ tr/A-Z/a-z/; 224 | $modes{$_} = 0; 225 | } else { 226 | $modes{$_} = 1; 227 | } 228 | } 229 | 230 | 231 | $CONFIG = 'CFILE' . scalar(@{$$Options{Configfiles}}); 232 | 233 | $configfile =~ s/^.*\@//; 234 | 235 | if($configfile =~ m[/]) 236 | { 237 | $confile = $configfile; 238 | } 239 | elsif($configfile ne '-') 240 | { 241 | if(!$modes{g} && $$Options{vault} && $$Options{vault} ne 'CODE') 242 | { 243 | if(!$$Options{Bank}) 244 | { 245 | my $bank; 246 | for $bank (@{$$Options{bank}}) 247 | { 248 | if (-d "$bank/$$Options{vault}") 249 | { 250 | $$Options{Bank} = $bank; 251 | last; 252 | } 253 | } 254 | } 255 | if ($$Options{Bank}) 256 | { 257 | $confile = join('/', $$Options{Bank}, 258 | $$Options{vault}, 'dirvish', 259 | $configfile); 260 | -f $confile || -f "$confile.conf" 261 | or $confile = undef; 262 | } 263 | } 264 | $confile ||= "$CONFDIR/$configfile"; 265 | } 266 | 267 | if($configfile eq '-') 268 | { 269 | open($CONFIG, $configfile) or seppuku 221, "cannot open STDIN"; 270 | } else { 271 | ! -f $confile && -f "$confile.conf" and $confile .= '.conf'; 272 | 273 | if (! -f "$confile") 274 | { 275 | $modes{o} and return undef; 276 | seppuku 222, "cannot open config file: $configfile"; 277 | } 278 | 279 | grep(/^$confile$/, @{$$Options{Configfiles}}) 280 | and seppuku 224, "ERROR: config file looping on $confile"; 281 | 282 | open($CONFIG, $confile) 283 | or seppuku 225, "cannot open config file: $configfile"; 284 | } 285 | push(@{$$Options{Configfiles}}, $confile); 286 | 287 | while(<$CONFIG>) 288 | { 289 | chomp; 290 | s/\s*#.*$//; 291 | s/\s+$//; 292 | /\S/ or next; 293 | 294 | if(/^\s/ && $key) 295 | { 296 | s/^\s*//; 297 | push @{$$Options{$key}}, $_; 298 | } 299 | elsif(/^SET\s+/) 300 | { 301 | s/^SET\s+//; 302 | for $k (split(/\s+/)) 303 | { 304 | $$Options{$k} = 1; 305 | } 306 | } 307 | elsif(/^UNSET\s+/) 308 | { 309 | s/^UNSET\s+//; 310 | for $k (split(/\s+/)) 311 | { 312 | $$Options{$k} = undef; 313 | } 314 | } 315 | elsif(/^RESET\s+/) 316 | { 317 | ($key = $_) =~ s/^RESET\s+//; 318 | $$Options{$key} = [ ]; 319 | } 320 | elsif(/^[A-Z]/ && $modes{f}) 321 | { 322 | $key = undef; 323 | } 324 | elsif(/^\S+:/) 325 | { 326 | ($key, $val) = split(/:\s*/, $_, 2); 327 | length($val) or next; 328 | $k = $key; $key = undef; 329 | 330 | if ($k eq 'config') 331 | { 332 | $modes{r} and loadconfig($mode . 'O', $val, $Options); 333 | next; 334 | } 335 | if ($k eq 'client') 336 | { 337 | if ($modes{r} && ref ($$Options{$k}) eq 'CODE') 338 | { 339 | loadconfig($mode . 'og', "$CONFDIR/$val", $Options); 340 | } 341 | $$Options{$k} = $val; 342 | next; 343 | } 344 | if ($k eq 'file-exclude') 345 | { 346 | $modes{r} or next; 347 | 348 | slurplist('exclude', $val, $Options); 349 | next; 350 | } 351 | if (ref ($$Options{$k}) eq 'ARRAY') 352 | { 353 | push @{$$Options{$k}}, $_; 354 | } else { 355 | $$Options{$k} = $val; 356 | } 357 | } 358 | } 359 | close $CONFIG; 360 | return $Options; 361 | } 362 | -------------------------------------------------------------------------------- /dirvish/files/man/dirvish-expire.8: -------------------------------------------------------------------------------- 1 | .\" $Id: dirvish-expire.8,v 12.0 2004/02/25 02:42:14 jw Exp $ $Name: Dirvish-1_2 $ 2 | .ds d \-\^\- 3 | .ds o \fR[\fP 4 | .ds c \fR]\fP 5 | .ds | \fR|\fP 6 | .ds bank \fIbank\fP 7 | .ds vault \fIvault\fP 8 | .ds branch \fIbranch\fP 9 | .ds image \fIimage\fP 10 | .de D 11 | \\.B \*d\\$1 12 | .. 13 | .de DR 14 | \\.BR \*d\\$1 \\$2 15 | .. 16 | .de Bi 17 | \\.BI \\$1 " \\$2" 18 | .. 19 | .de DI 20 | \\.BI \*d\\$1 \\$2 21 | .. 22 | .de Di 23 | \\.BI \*d\\$1 " \\$2" 24 | .. 25 | .de See 26 | See \fB\\$1\fP for more details. 27 | .. 28 | .de SeeIn 29 | See \fB\\$1\fP in \fB\\$2\fP for more details. 30 | .. 31 | .de multiple 32 | Multiple \fB\\$1:\fP values will accumulate. 33 | .. 34 | .de default 35 | Default value: \fB\\$1\fP 36 | .. 37 | .TH DIRVISH-EXPIRE 8 38 | .SH NAME 39 | dirvish\-expire \- delete expired dirvish images 40 | .SH SYNOPSIS 41 | .BI dirvish\-expire [OPTIONS] 42 | .SH DESCRIPTION 43 | Delete dirvish image trees or whole images that have expired. 44 | 45 | Each image 46 | .B summary 47 | file is checked for the 48 | .B Expire: 49 | field. 50 | If that field indicates the image has expired 51 | .B dirvish\-expire 52 | will delete that image from the vault. 53 | 54 | By default all subdirectories of all banks will be treated as vaults 55 | and all directories therein 56 | except the one named 57 | .B dirvish 58 | will be checked for summary files. 59 | 60 | The removal of an image will have no effect on other images. 61 | 62 | .B Dirvish\-expire 63 | will not delete an image 64 | unless it finds at least one image in that branch 65 | that has an intact image tree and 66 | .B "Status: success" 67 | in the summary that is not expired. 68 | .SH OPTIONS 69 | Each option on the command line may be specified any number of times. 70 | Those options that support lists in the config files 71 | will accumulate all of their arguments 72 | otherwise each specification will override the ones before. 73 | 74 | Each option may be unambiguously abbreviated. 75 | .TP 76 | .Di time time_expression 77 | Execute as though 78 | .I time_expression 79 | were the current time. 80 | 81 | .I Time_expression 82 | is processed by 83 | .B Time::Parsedate(3pm) 84 | so relative time and date strings are permitted. 85 | .See Time::Parsedate(3pm) 86 | .TP 87 | .D tree 88 | Only delete the image tree, 89 | leave in place the rest of the image directory with summary, 90 | log and any other image administrative files. 91 | .TP 92 | .Di vault vault 93 | Restrict expiration to the specified 94 | .IR vault . 95 | .TP 96 | .D no\-run 97 | Don't actually do anything. 98 | Just display what would have happened. 99 | .TP 100 | .D quiet 101 | Run quietly, only report errors. 102 | 103 | Normally 104 | .B dirvish\-expire 105 | will report the images deleted. 106 | .SH EXIT CODES 107 | To facilitate further automation and integration of 108 | .B dirvish-expire 109 | with other tools 110 | .B dirvish-expire 111 | provides rationalised exit codes. 112 | The exit codes are range based. While the code for 113 | a specific error may change from one version to another it 114 | will remain within the specified range. So don't test for 115 | specific exit codes but instead test for a range of values. 116 | To the degree possible higher value ranges indicate more 117 | severe errors. 118 | .TP 119 | 0 120 | success 121 | .TP 122 | 200-219 123 | An error was encountered in loading a configuration file. 124 | .TP 125 | 220-254 126 | An error was detected in the configuration. 127 | .TP 128 | 255 129 | Incorrect usage. 130 | .SH FILES 131 | .TP 132 | .B /etc/dirvish/master.conf 133 | alternate master configuration file. 134 | .TP 135 | .B /etc/dirvish.conf 136 | master configuration file. 137 | .TP 138 | .IB bank/vault/image/ summary 139 | image creation summary. 140 | .TP 141 | .IB bank/vault/image/ tree 142 | actual image of source directory tree. 143 | .SH SEE ALSO 144 | .nf 145 | dirvish.conf(5) 146 | Time::ParseDate(3pm) 147 | .SH BUGS 148 | .B Dirvish\-expire 149 | will walk the file hierarchy of all banks 150 | or the specified vault looking for summary files. 151 | Anything non-dirvish in there may cause excess file-walking. 152 | -------------------------------------------------------------------------------- /dirvish/files/man/dirvish-locate.8: -------------------------------------------------------------------------------- 1 | .\" $Id: dirvish-locate.8,v 12.0 2004/02/25 02:42:14 jw Exp $ $Name: Dirvish-1_2 $ 2 | .ds d \-\^\- 3 | .ds o \fR[\fP 4 | .ds c \fR]\fP 5 | .ds | \fR|\fP 6 | .ds bank \fIbank\fP 7 | .ds vault \fIvault\fP 8 | .ds branch \fIbranch\fP 9 | .ds image \fIimage\fP 10 | .de D 11 | \\.B \*d\\$1 12 | .. 13 | .de DR 14 | \\.BR \*d\\$1 \\$2 15 | .. 16 | .de Bi 17 | \\.BI \\$1 " \\$2" 18 | .. 19 | .de DI 20 | \\.BI \*d\\$1 \\$2 21 | .. 22 | .de Di 23 | \\.BI \*d\\$1 " \\$2" 24 | .. 25 | .de See 26 | See \fB\\$1\fP for details. 27 | .. 28 | .de SeeIn 29 | See \fB\\$1\fP in \fB\\$2\fP for details. 30 | .. 31 | .de multiple 32 | Multiple \fB\\$1:\fP values will accumulate. 33 | .. 34 | .de default 35 | Default value: \fB\\$1\fP 36 | .. 37 | .TH DIRVISH-LOCATE 8 38 | .SH NAME 39 | dirvish\-locate \- locate file versions in dirvish images 40 | .SH SYNOPSIS 41 | .B dirvish\-locate 42 | .I vault\*o:branch\*c 43 | .I pattern 44 | .SH DESCRIPTION 45 | Locate versions of files in a dirvish vault 46 | 47 | The index of each image specified \*[vault] is searched for paths matching 48 | .IR pattern . 49 | Each path found matching the 50 | .I pattern 51 | will be reported followed by a modification time of each version of the 52 | file and all images having a link to it. 53 | 54 | The optional \*[branch] specification will restrict 55 | searching to the specified branch. 56 | 57 | Images with an error status will be skipped as will any 58 | without index files. The index file may be compressed by 59 | gzip or bzip2. 60 | See 61 | .B tree 62 | and 63 | .B index 64 | in 65 | .B dirvish.conf(5) 66 | for details. 67 | 68 | The 69 | .I pattern 70 | is a 71 | .B perl 72 | regular expression to match the final component of the path. 73 | Append 74 | .B .* 75 | to the end of the pattern if you wish to match any substring 76 | of the whole path 77 | or 78 | .B $ 79 | if you wish to anchor the pattern to the end of the path. 80 | .See perlre(1) 81 | 82 | Directories are excluded from matching as they would wind up 83 | matching every file within them anyway. 84 | Symlinks are also excluded from matching. 85 | 86 | If the 87 | .I pattern 88 | matches too many paths 89 | .B dirvish\-locate 90 | will only report the paths matched and not versions. 91 | As a sanity check if the number of matches is really excessive 92 | .B dirvish\-locate 93 | will limit the number of images searched. 94 | Excessive matches is an indication of an insufficiently 95 | specific 96 | .IR pattern . 97 | Use the resulting path list to compose a more specific one. 98 | .SH EXIT CODES 99 | To facilitate further automation and integration of 100 | .B dirvish-locate 101 | with other tools 102 | .B dirvish-locate provides rationalised exit codes. 103 | The exit codes are range based. While the code for 104 | a specific error may change from one version to another it 105 | will remain within the specified range. So don't test for 106 | specific exit codes but instead test for a range of values. 107 | To the degree possible higher value ranges indicate more 108 | severe errors. 109 | .TP 110 | 0 111 | success 112 | 200-219 113 | An error was encountered in loading a configuration file. 114 | .TP 115 | 220-254 116 | An error was detected in the configuration. 117 | .TP 118 | 255 119 | Incorrect usage. 120 | .SH FILES 121 | .TP 122 | .B /etc/dirvish/master.conf 123 | alternate master configuration file. 124 | .TP 125 | .B /etc/dirvish.conf 126 | master configuration file. 127 | .TP 128 | .IB bank/vault/image/ summary 129 | image creation summary. 130 | .TP 131 | .IB bank/vault/image/ index 132 | .TP 133 | .IB bank/vault/image/ index.gz 134 | .TP 135 | .IB bank/vault/image/ index.bz2 136 | dirvish index file. 137 | .SH SEE ALSO 138 | .nf 139 | dirvish.conf(5) 140 | .SH BUGS 141 | -------------------------------------------------------------------------------- /dirvish/files/man/dirvish-runall.8: -------------------------------------------------------------------------------- 1 | .\" $Id: dirvish-runall.8,v 12.0 2004/02/25 02:42:14 jw Exp $ $Name: Dirvish-1_2 $ 2 | .ds d \-\^\- 3 | .ds o \fR[\fP 4 | .ds c \fR]\fP 5 | .ds | \fR|\fP 6 | .ds bank \fIbank\fP 7 | .ds vault \fIvault\fP 8 | .ds branch \fIbranch\fP 9 | .ds image \fIimage\fP 10 | .de D 11 | \\.B \*d\\$1 12 | .. 13 | .de DR 14 | \\.BR \*d\\$1 \\$2 15 | .. 16 | .de Bi 17 | \\.BI \\$1 " \\$2" 18 | .. 19 | .de DI 20 | \\.BI \*d\\$1 \\$2 21 | .. 22 | .de Di 23 | \\.BI \*d\\$1 " \\$2" 24 | .. 25 | .de See 26 | See \fB\\$1\fP for more details. 27 | .. 28 | .de SeeIn 29 | See \fB\\$1\fP in \fB\\$2\fP for more details. 30 | .. 31 | .de multiple 32 | Multiple \fB\\$1:\fP values will accumulate. 33 | .. 34 | .de default 35 | Default value: \fB\\$1\fP 36 | .. 37 | .TH DIRVISH-RUNALL 8 38 | .SH NAME 39 | dirvish\-runall \- run a set of dirvish backup jobs. 40 | .SH SYNOPSIS 41 | .BI dirvish\-runall [OPTIONS] 42 | .SH DESCRIPTION 43 | Run all the jobs specified in the 44 | .B Runall 45 | field of the dirvish master configuration file. 46 | .SH OPTIONS 47 | Each option may be unambiguously abbreviated. 48 | .TP 49 | .Di config configfile 50 | Read 51 | .I configfile 52 | for the 53 | .B Runall: 54 | field. 55 | By default 56 | .B dirvish\-runall 57 | will use the 58 | .B Runall: 59 | field from the master configuration file. 60 | 61 | This will only be used by 62 | .B dirvish-runall 63 | itself 64 | and not be propagated to the 65 | .B dirvish 66 | processes. 67 | 68 | .See dirvish.conf(5) 69 | .TP 70 | .D no\-run 71 | .TP 72 | .D dry\-run 73 | Don't actually do anything. 74 | Just display what would have happened. 75 | .TP 76 | .D quiet 77 | Run quietly, only report errors. 78 | 79 | Normally 80 | .B dirvish\-runall 81 | will report the dirvish commands invoked with timestamps. 82 | .TP 83 | .D version 84 | Print the version information and exit. 85 | .SH EXIT CODES 86 | To facilitate further automation and integration of 87 | .B dirvish-runall 88 | with other tools 89 | .B dirvish-runall 90 | provides rationalised exit codes. 91 | The exit codes are range based. While the code for 92 | a specific error may change from one version to another it 93 | will remain within the specified range. So don't test for 94 | specific exit codes but instead test for a range of values. 95 | To the degree possible higher value ranges indicate more 96 | severe errors. 97 | .TP 98 | 0 99 | success 100 | .TP 101 | 1-199 102 | Number of 103 | .B dirvish 104 | jobs that failed. If more than 199 jobs 105 | failed 199 will be the exit code. 106 | .TP 107 | 200-219 108 | An error was encountered in loading a configuration file. 109 | .TP 110 | 220-254 111 | An error was detected in the configuration. 112 | .TP 113 | 255 114 | Incorrect usage. 115 | .SH FILES 116 | .TP 117 | .B /etc/dirvish/master.conf 118 | alternate master configuration file. 119 | .TP 120 | .B /etc/dirvish.conf 121 | master configuration file. 122 | .SH SEE ALSO 123 | .nf 124 | dirvish.conf(5) 125 | .SH BUGS 126 | -------------------------------------------------------------------------------- /dirvish/files/man/dirvish.8: -------------------------------------------------------------------------------- 1 | .\" $Id: dirvish.8,v 12.0 2004/02/25 02:42:14 jw Exp $ $Name: Dirvish-1_2 $ 2 | .ds d \-\^\- 3 | .ds o \fR[\fP 4 | .ds c \fR]\fP 5 | .ds | \fR|\fP 6 | .de D 7 | \\.B \*d\\$1 8 | .. 9 | .de DI 10 | \\.BI \*d\\$1 \\$2 11 | .. 12 | .de DR 13 | \\.BR \*d\\$1 \\$2 14 | .. 15 | .de Di 16 | \\.BI \*d\\$1 " \\$2" 17 | .. 18 | .de Db 19 | \\.B \*d\\$1 " \\$2" 20 | .. 21 | .de Df 22 | \\.B \*d\*ono\*c\\$1 23 | .. 24 | .de See 25 | See \fB\\$1\fP for details. 26 | .. 27 | .de SeeIn 28 | See \fB\\$1\fP in \fB\\$2\fP for details. 29 | .. 30 | .de multiple 31 | Multiple \fB\*d\\$1\fP values will accumulate. 32 | .. 33 | .de default 34 | Default value: \fB\\$1\fP 35 | .. 36 | .TH DIRVISH 8 37 | .SH NAME 38 | dirvish \- Disk based virtual image network backup system 39 | .SH SYNOPSIS 40 | .B dirvish \-\^\-vault 41 | .I vault 42 | [ 43 | .I OPTIONS 44 | ] 45 | .SH DESCRIPTION 46 | .P 47 | Create a backup image of a client directory tree. 48 | .P 49 | Each image is a directory containing transfer 50 | .BR log, 51 | .BR summary, 52 | .B tree 53 | and if transfer errors were detected an 54 | .B rsync_error 55 | file. 56 | The transfer 57 | .B log 58 | retains the the output of any pre and post processing commands 59 | and the rsync log listing all files that were changed or added with some statistical information. 60 | The 61 | .B summary 62 | file 63 | contains all the information about how the image was created 64 | and meta-data for managing the image 65 | in config file format. 66 | Tree is the copy of the client tree. 67 | .P 68 | The client directory tree is compared with an existing image 69 | to create a new image. 70 | Unchanged files are shared between images. 71 | For changed files 72 | only those parts that actually change are transfered over the network. 73 | Unchanged portions of files are copied from the reference image. 74 | .P 75 | The resulting images contain complete copies of the original trees 76 | preserving ownership and file permissions. 77 | In this way even though the backups are made incrementally, 78 | each image can be used independently for restores 79 | or to make removable-media off-site copies or archives. 80 | .P 81 | The removal of an image will have no effect on other images. 82 | .SH OPTIONS 83 | Each option on the command line may be specified any number of times. 84 | Those options that support lists in the config files 85 | will accumulate all of their arguments 86 | otherwise each specification will override the ones before. 87 | .P 88 | As configuration files are loaded 89 | they may override options on the command line. 90 | .P 91 | Each option may be unambiguously abbreviated. 92 | .TP 93 | .Di branch \*ovault:\*cbranch_name 94 | Specify a branch to use. 95 | 96 | A branch is a sequence of images. 97 | 98 | If a vault has been specified either here or with 99 | .D vault 100 | the first time this option is used it will 101 | attempt to load the config file 102 | .I branch_name 103 | or 104 | .IB branch_name .conf 105 | from the vault. 106 | .TP 107 | .Di config config-file 108 | Load options from the specified file. 109 | 110 | If this precedes 111 | .D vault 112 | the 113 | .D vault 114 | option will not 115 | load it's own config file. 116 | 117 | If vault has been set and 118 | .I config-file 119 | is a bare filename the presence of one in the vault will take 120 | precedence over one in the current directory. 121 | To specify one in the current directory after 122 | .D vault 123 | use 124 | .B ./ 125 | to precede the name. 126 | 127 | The master configuration file will be read prior to 128 | processing options. 129 | .TP 130 | .Di expire expire_date 131 | Specify a time for the image to expire. 132 | 133 | .See Time::ParseDate(3pm) 134 | 135 | This does not actually expire anything. 136 | What it does do is add an 137 | .B Expire: 138 | field to the image summary file containing an absolute time 139 | so that a 140 | .B dirvish-expire 141 | or another tool outside of dirvish can decide when to remove old images. 142 | .TP 143 | .Di image image_name 144 | Specify a name for the image. 145 | 146 | .I image_name 147 | is passed through 148 | .B POSIX::strftime 149 | 150 | .See strftime(3) 151 | .TP 152 | .Di image-time parsedate_expression 153 | Time to use when creating the image name. 154 | 155 | If an absolute time without a date is provided it will be forced into the past. 156 | If this isn't set the current time will be used. 157 | 158 | .See Time::ParseDate(3pm) 159 | .TP 160 | .D init 161 | Create an initial image. 162 | 163 | Create the image entirely from the source tree 164 | without the use of a reference image. 165 | .TP 166 | .D no\-run 167 | .TP 168 | .D dry\-run 169 | Don't actually do anything. 170 | 171 | Process all configuration files, options and tests 172 | then produce a summary/configuration file on standard output and exit. 173 | .TP 174 | .Di reference branch_name\*|image_name 175 | Specify an existing image or a branch from which to create the new image. 176 | 177 | If a branch_name is specified, 178 | the last existing image from its history file will be used. 179 | A branch will take precedence over an image of the same name. 180 | .TP 181 | .Di reset option 182 | Reset the values in an accumulating 183 | .IR option . 184 | .TP 185 | .Db summary short\*|long 186 | Specify summary format. 187 | 188 | A short summary will only include final used values. 189 | A long summary will include all configuration values. 190 | 191 | .default short 192 | .TP 193 | .Di vault vault\*o:branch_name\*c 194 | Specify the vault to store the image in. 195 | 196 | If not preceeded by 197 | .D config 198 | this will attempt to load the config file 199 | .B default 200 | or 201 | .B default.conf 202 | within the 203 | .IR vault . 204 | 205 | If 206 | .I branch_name 207 | is specified here this will behave exactly like the 208 | .D branch 209 | option and 210 | .I branch_name 211 | or 212 | .IR branch_name .conf 213 | will be attempted instead of 214 | .BR default.conf . 215 | .TP 216 | .D version 217 | Print version string and exit. 218 | .SH EXIT CODES 219 | To facilitate further automation and integration of 220 | .B dirvish 221 | with other tools 222 | .B dirvish 223 | provides rationalised exit codes. 224 | The exit codes are range based. While the code for 225 | a specific error may change from one version to another it 226 | will remain within the specified range. So don't test for 227 | specific exit codes but instead test for a range of values. 228 | To the degree possible higher value ranges indicate more 229 | severe errors. 230 | .TP 231 | 0 232 | success 233 | .TP 234 | 1-19 235 | The backup job reported warnings. 236 | .TP 237 | 20-39 238 | An error occurred during index generation and cleanup. 239 | .TP 240 | 40-49 241 | A post-client or post-server command could not be run. 242 | .TP 243 | 50-59 244 | The post-client command reported an error. 245 | Its exit code modulo 10 is added to 50 246 | .TP 247 | 60-69 248 | The post-server command reported an error. 249 | Its exit code modulo 10 is added to 60 250 | .TP 251 | 70-79 252 | A post-client or post-server command could not be run. 253 | .TP 254 | 80-89 255 | The pre-server command reported an error. 256 | Its exit code modulo 10 is added to 80 257 | .TP 258 | 90-99 259 | The pre-server command reported an error. 260 | Its exit code modulo 10 is added to 90 261 | .TP 262 | 100-149 263 | Rsync encountered a non-fatal error. 264 | .TP 265 | 150-199 266 | Rsync encountered a fatal error. 267 | .TP 268 | 200-219 269 | An error was encountered in loading a configuration file. 270 | .TP 271 | 220-254 272 | An error was detected in the configuration. 273 | .TP 274 | 255 275 | Incorrect usage. 276 | .SH FILES 277 | .TP 278 | .B /etc/dirvish/master.conf 279 | alternate master configuration file. 280 | .TP 281 | .B /etc/dirvish.conf 282 | master configuration file. 283 | .TP 284 | .B /etc/dirvish/\fIclient\fP[.conf] 285 | client configuration file. 286 | .TP 287 | .IB bank/vault/ dirvish/default[.conf] 288 | default vault configuration file. 289 | .TP 290 | .IB bank/vault/\fBdirvish\fP/branch [.conf] 291 | branch configuration file. 292 | .TP 293 | .IB bank/vault/\fBdirvish\fP/branch .hist 294 | branch history file. 295 | .TP 296 | .IB bank/vault/image/ summary 297 | image creation summary. 298 | .TP 299 | .IB bank/vault/image/ log 300 | image creation log. 301 | .TP 302 | .IB bank/vault/image/ tree 303 | actual image of source directory tree. 304 | .TP 305 | .IB bank/vault/image/ rsync_error 306 | Error output from rsync if errors or warnings were detected. 307 | .SH SEE ALSO 308 | .nf 309 | dirvish.conf(5) 310 | dirvish\-runall(8) 311 | dirvish\-expire(8) 312 | dirvish\-locate(8) 313 | ssh(1) 314 | rsync(1) 315 | Time::ParseDate(3pm) 316 | strftime(3) 317 | .SH AUTHOR 318 | Dirvish was created by J.W. Schultz of Pegasystems Technologies. 319 | .SH BUGS AND ISSUES 320 | Fields set in configuration files will override command line options 321 | that have been set before the file is read. 322 | This behaviour while consistent may occasionally confuse. 323 | For this reason 324 | most command line options should be specified after any options 325 | that may cause a configuration file to be loaded. 326 | 327 | In order to preserve permissions 328 | it is necessary for dirvish to run as root 329 | on the backup server. 330 | 331 | The root user must have non-interactive ssh access to the client systems. 332 | It is not necessary that this access be as the root user on the client. 333 | 334 | File ownership is preserved using numeric values 335 | so it is not necessary to have user accounts on the backup server. 336 | Making the vaults network accessible 337 | using protocols that map UIDs based on names instead of number 338 | could allow access controls on files to be violated. 339 | 340 | Making the vaults 341 | writable by users will compromise the integrity of the backups. 342 | Therefore any access to the vaults by users 343 | should be done through a read-only mount. 344 | -------------------------------------------------------------------------------- /dirvish/files/man/dirvish.conf.5: -------------------------------------------------------------------------------- 1 | .\" $Id: dirvish.conf.5,v 12.0 2004/02/25 02:42:15 jw Exp $ $Name: Dirvish-1_2 $ 2 | .ds d \-\^\- 3 | .ds o \fR[\fP 4 | .ds c \fR]\fP 5 | .ds | \fR|\fP 6 | .ds bank \fIbank\fP 7 | .ds vault \fIvault\fP 8 | .ds branch \fIbranch\fP 9 | .ds image \fIimage\fP 10 | .de D 11 | \\.B \*d\\$1 12 | .. 13 | .de Dr 14 | \\.BR \*d\\$1 \\$2 15 | .. 16 | .de Bi 17 | \\.BI \\$1 " \\$2" " \fR\\$3" 18 | .. 19 | .de Br 20 | \\.BR "\\$1" " \\$2" 21 | .. 22 | .de DI 23 | \\.BI \*d\\$1 \\$2 24 | .. 25 | .de Di 26 | \\.BI \*d\\$1 " \\$2" 27 | .. 28 | .de See 29 | See \fB\\$1\fP for more details. 30 | .. 31 | .de SeeIn 32 | See \fB\\$1\fP in \fB\\$2\fP for more details. 33 | .. 34 | .de multiple 35 | Multiple \fB\\$1:\fP values will accumulate. 36 | .. 37 | .de default 38 | Default value: \fB\\$1\fP 39 | .. 40 | .de usedefault 41 | Setting this in a config file 42 | may cause the command line option to be overridden. 43 | Use \fB\\$1\-default:\fP instead. 44 | .. 45 | .TH DIRVISH.CONF 5 46 | .SH NAME 47 | dirvish.conf \- dirvish configuration file. 48 | .SH DESCRIPTION 49 | The dirvish.conf file provides configuration information and 50 | default values for dirvish. 51 | 52 | The file format is fairly simple. 53 | Each option requires either a single-value 54 | or a list of values 55 | and unless otherwise indicated 56 | must be specified according to its expected type. 57 | Single value options are specified by lines of the form 58 | .BR "option: value" . 59 | Options expecting list must be specified in a multi-line 60 | format as shown here 61 | where the lines specifying values are indented by any 62 | kind of whitespace even if only one value is being specified. 63 | .br 64 | \fB 65 | .in +.5i 66 | .nf 67 | option: 68 | .in +.5i 69 | value1 70 | value2 71 | \&. 72 | \&. 73 | \&. 74 | valueN 75 | .br 76 | .fi 77 | .in -1i 78 | \fR 79 | Each value must be provided on its own line. 80 | Any leading and trailing whitespace is discarded. 81 | Options whose names with an initial capital (ex: Foo) 82 | are discarded by dirvish itself but may be used by support utilities. 83 | Blank lines are ignored. 84 | 85 | While this simplistic format may allow for configuration 86 | errors it allows arbitrary options to be declared that custom 87 | support scripts could use. 88 | 89 | A 90 | .B # 91 | introduces a comment to the end of the line. 92 | 93 | On startup the dirvish utilities will first load a master dirvish.conf file. 94 | .B /etc/dirvish.conf 95 | will be tried first but if not present 96 | .B /etc/dirvish/master.conf 97 | will be tried. 98 | 99 | During installation dirvish may have been configured expect 100 | the system-wide configuration files in some location other 101 | than /etc/dirvish. 102 | 103 | Multiple configuration files will be loaded by the 104 | .DR config , 105 | .D vault 106 | and 107 | .D branch 108 | command-line options as well as the 109 | .B config: 110 | and 111 | .B client: 112 | configuration parameters. 113 | To prevent looping each configuration file can only be loaded once. 114 | 115 | .SH DIRVISH OPTIONS 116 | Like the command line each option may be specified any number of 117 | times. Those options that expect lists will accumulate all of 118 | their arguments 119 | and for single value options 120 | each specification will override the ones before. 121 | 122 | Boolean values need to specified as 123 | .B 1 124 | or 125 | .B 0 126 | or may be specified using 127 | .B SET 128 | or 129 | .BR UNSET . 130 | Some Boolean values are set by default and must be 131 | explicitly unset if unwanted. 132 | 133 | Each option is marked here with one of (B) for Boolean, (S) 134 | single value, (L) list or (0) other. 135 | 136 | .TP 137 | .Bi SET "option option ..." (O) 138 | .TP 139 | .Bi UNSET "option option ..." (O) 140 | Set or unset one or more boolean options. 141 | 142 | NOTE: The SET and UNSET directives do not use colons <:>. 143 | .TP 144 | .Bi RESET option (O) 145 | Reset a list option so that it contains no values. 146 | 147 | This may be used to start specification of the option. 148 | 149 | NOTE: The RESET directive does not use a colon <:>. 150 | .TP 151 | .Br bank: (L) 152 | Specify paths to directories containing vaults. 153 | 154 | A \*[bank] is a directory containing one or more \*[vault]s. 155 | The system supports multiple \*[bank]s 156 | so that filesystem mount-points can be managed more effectively. 157 | 158 | When a \*[vault] is specified the \*[bank]s will be searched 159 | in list order until the \*[vault] is found. 160 | This way 161 | \*[vault]s can be moved between \*[bank]s 162 | or added 163 | without having to update a master index. 164 | 165 | .multiple bank 166 | .TP 167 | .Bi branch: branch_name (S) 168 | Specify a \*[branch] to use. 169 | 170 | A \*[branch] is a sequence of \*[image]s. 171 | 172 | This also specifies a default value for 173 | .BR reference: . 174 | 175 | .usedefault branch 176 | .TP 177 | .Bi branch\-default: branch_name (S) 178 | Specify a default \*[branch] to use. 179 | .TP 180 | .Bi client: \*ousername@\*cclient_name (S) 181 | specify a client to back up. 182 | 183 | Setting this to the same value as hostname 184 | will cause dirvish to do a local copy and stay off the 185 | network. This automatically invokes \fBwhole\-file\fP. 186 | 187 | The first time this parameter is set 188 | .B /etc/dirvish/\fIclient_name\fP 189 | or 190 | .B /etc/dirvish/\fIclient_name\fP.conf 191 | will be loaded. 192 | .TP 193 | .Br checksum: (B) 194 | Force the checksum comparison of file contents even 195 | when the inode fails to indicate a change has 196 | occurred. 197 | 198 | .default 0 199 | .TP 200 | .Bi config: filename (S) 201 | Load configuration file. 202 | 203 | Similar to #include, 204 | .I filename 205 | or 206 | .IB filename .conf 207 | will be loaded immediately. 208 | 209 | If 210 | .I filename 211 | is a relative path it will be looked for in the vault 212 | and then the system-wide configuration directories. 213 | 214 | .TP 215 | .Br devices: (B) 216 | If this is unset device special files will be excluded from 217 | backups. 218 | 219 | This may need to be unset when doing backups of where the 220 | client OS uses device numbers or types unsupported by the 221 | server OSs or where the presence of device nodes in the 222 | vault present a security issue. 223 | 224 | .TP 225 | .Br exclude: (L) 226 | Specify a filename patterns to exclude. 227 | 228 | Patterns are based on shell glob with some 229 | enhancements. 230 | 231 | .See rsync(1) 232 | 233 | .multiple exclude 234 | .TP 235 | .Bi file\-exclude: filename (S) 236 | Load a set of patterns from a file. 237 | 238 | If 239 | .I filename 240 | is a relative path it will be looked for in the vault 241 | and then the system-wide configuration directories. 242 | .TP 243 | .Bi expire: expire_date (S) 244 | Specify a time for the \*[image] to expire. 245 | 246 | This does not actually expire anything. 247 | What it does do is add an 248 | .B Expire: 249 | option to the \*[image] summary file 250 | with the absolute time appended so that 251 | .B dirvish\-expire 252 | can automate old \*[image] removal. 253 | 254 | .usedefault "expire\-rule: \fRand\fP expire" 255 | 256 | .See Time::ParseDate(3pm) 257 | .TP 258 | .Bi expire\-default: expire_date (S) 259 | Specify a default expiration time. 260 | 261 | This value will only be used if expire is not set 262 | and expire\-rule doesn't have a match. 263 | .TP 264 | .Br expire\-rule: (L) 265 | specify rules for expiration. 266 | 267 | Rules are specified similar to crontab or in 268 | .BR Time::Period format . 269 | 270 | .See "EXPIRE RULES" 271 | 272 | .multiple expire\-rule 273 | .TP 274 | .Bi image: image_name (S) 275 | Specify a name for the \*[image]. 276 | 277 | .I image_name 278 | is passed through 279 | .B POSIX::strftime 280 | 281 | .usedefault image 282 | 283 | .See strftime(3) 284 | .TP 285 | .Bi image\-default: image_name (S) 286 | Set the default 287 | .IR image_name . 288 | 289 | This value will only be used if 290 | .B image: 291 | is not set. 292 | .TP 293 | .Bi image\-perm: octal_mode (S) 294 | Set the permissions for the \*[image]. 295 | 296 | While the \*[image] is being created the \*[image] directory 297 | permissions will be 298 | .BR 0700 . 299 | After completion it will be changed to 300 | .I octal_mode 301 | or 302 | .BR 0755 . 303 | 304 | .See "chmod(1) and umask(2)" 305 | .TP 306 | .Bi image\-time: parsedate_expression (S) 307 | Time to use when creating the \*[image] name. 308 | 309 | If an absolute time without a date is provided it will be forced into the past. 310 | 311 | If this isn't set the current time will be used. 312 | 313 | .See Time::ParseDate(3pm) 314 | .TP 315 | .Bi image\-temp: dirname (S) 316 | Temporary directory name to use for new \*[image]. 317 | This allows you to have \*[image]s created with the same 318 | directory name each run so that automatic processes can access them. 319 | 320 | The next time an image is made on the \*[branch] 321 | this option will cause the directory to be renamed to its official name. 322 | .TP 323 | .B "index: none\*|text\*|gzip\*|bzip2" (S) 324 | Create an index file listing all files in the \*[image]. 325 | 326 | The index file will be created using 327 | .B "find -ls" 328 | so the list will be in the same format as 329 | .BR ls -dils 330 | with paths converted to reflect the source location. 331 | 332 | If index is set to bzip2 or gzip or a path to one the 333 | index file will be compressed accordingly. 334 | 335 | This index will be used by 336 | .B dirvish\-locate 337 | to locate versions of files. 338 | .See dirvish\-locate(8) 339 | .TP 340 | .Br init: (B) 341 | Create an initial \*[image]. 342 | 343 | Turning this on will prevent backups from being incremental. 344 | .TP 345 | .B "log: text\*|gzip\*|bzip2" (S) 346 | Specify format for the image log file. 347 | 348 | If 349 | .B log 350 | is set to bzip2 or gzip or a path to one the 351 | log file will be compressed accordingly. 352 | .TP 353 | .Bi meta\-perm: octal\-mode (S) 354 | Set the permissions for the \*[image] meta-data files. 355 | 356 | If this value is set 357 | the permissions of the meta-data files in the \*[image] 358 | will be changed after the \*[image] is created. 359 | Otherwise the active umask will prevail. 360 | 361 | SECURITY NOTE: 362 | The log, index, and error files contain lists 363 | of files. It may be possible that filenames themselves may 364 | be or contain confidential information so uncontrolled 365 | access may constitute a security weakness. 366 | 367 | .See "chmod(1) and umask(2)" 368 | .TP 369 | .Br numeric\-ids: (B) 370 | Use numeric uid/gid values instead of looking up user/group 371 | names for setting permissions. 372 | 373 | .See rsync(1) 374 | 375 | .default 1 376 | .TP 377 | .Bi password\-file: filepath (S) 378 | Specify file containing password 379 | for connection to an 380 | .B rsync 381 | daemon on backup client. 382 | 383 | This is not useful for remote shell passwords. 384 | 385 | .SeeIn \*dpassword\-file rsync(1) 386 | .TP 387 | .Br permissions: (B) 388 | Preserve file permissions. If this is unset permissions 389 | will not be checked or preserved. 390 | 391 | With rsync version 2.5.6 392 | not preserving permissions will break the linking. Only 393 | unset this if you are running a later version of rsync. 394 | 395 | .See rsync(1) 396 | 397 | .default 1 398 | .TP 399 | .Bi pre\-server: shell_command (S) 400 | .TP 401 | .Bi pre\-client: shell_command (S) 402 | .TP 403 | .Bi post\-client: shell_command (S) 404 | .TP 405 | .Bi post\-server: shell_command (S) 406 | Execute 407 | .I shell_command 408 | on client or server before or after making backup. 409 | 410 | The client commands are run on the client system using the 411 | remote shell command (see the \fBrsh\fR: parameter). 412 | 413 | The order of execution is 414 | .BR pre\-server , 415 | .BR pre\-client , 416 | .BR rsync , 417 | .BR post\-client , 418 | .BR post\-server . 419 | The 420 | .I shell_command 421 | will be passed through 422 | .B strftime(3) 423 | to allow date strings to be expanded. 424 | 425 | Each pre or post 426 | .IR shell_command s 427 | will be run with these environment variables 428 | .BR DIRVISH_SERVER , 429 | .BR DIRVISH_CLIENT, 430 | .BR DIRVISH_SRC , 431 | .B DIRVISH_DEST 432 | and 433 | .B DIRVISH_IMAGE 434 | set. 435 | The current directory will be 436 | .B DIRVISH_SRC 437 | on the client and 438 | .B DIRVISH_DEST 439 | on the server. 440 | If there are any exclude patterns defined 441 | the 442 | .B pre\-server 443 | shell command will also have the exclude file's path in 444 | .B DIRVISH_EXCLUDE 445 | so it may read or modify the exlude list. 446 | 447 | .SM STDOUT from each 448 | .I shell_command 449 | will be written to the \*[image] log file. 450 | 451 | The exit status of each script will be checked. Non-zero 452 | values will be recognised as failure and logged. 453 | Failure of the 454 | .B pre\-server 455 | command will halt all further action. 456 | Failure of the 457 | .B pre\-client 458 | command will prevent the rsync from running and the 459 | .B post\-server 460 | command, if any, will be run. 461 | 462 | Post 463 | .IR shell_command s 464 | will also have 465 | .B DIRVISH_STATUS 466 | set to 467 | .BR success , 468 | .BR warning , 469 | .BR error , 470 | or 471 | .BR "fatal error" . 472 | 473 | This is useful for multiple things. 474 | The client 475 | .IR shell_command s 476 | can be used to stop and start services so their files can be 477 | backed up safely. 478 | You might use 479 | .B post\-server: 480 | to schedule replication or a tape backup of the new \*[image]. 481 | Use your imagination. 482 | .TP 483 | .Bi reference: branch_name\*|image_name (S) 484 | Specify an existing \*[image] or a \*[branch] from which to 485 | create the new \*[image]. 486 | 487 | If a 488 | .I branch_name 489 | is specified, the last existing \*[image] from its history file will be used. 490 | A \*[branch] will take precedence over an \*[image] of the same name. 491 | 492 | If this isn't specified the \*[branch] name will be used as a default value. 493 | .TP 494 | .Bi rsh: command (S) 495 | Remote shell utility. 496 | 497 | This can be used to specify the location of 498 | .B ssh 499 | or 500 | .B rsh 501 | and/or to provide addition options for said utility 502 | such as 503 | .Bi \-p port 504 | for 505 | .B ssh 506 | to use an alternate port number. 507 | 508 | If not specified 509 | .B ssh 510 | will be used. 511 | 512 | This remote shell command will be used not only as the 513 | default rsync transport but also for any 514 | .B pre\-client 515 | and 516 | .B post\-client 517 | commands. 518 | .TP 519 | .Bi rsync: command (S) 520 | Path to rsync executable on the server. 521 | .TP 522 | .Bi rsync\-client: command (S) 523 | Path to rsync executable on the client. 524 | .TP 525 | .Br rsync\-option: (L) 526 | Specify additional options for the rsync command. 527 | 528 | Only one option per list item is supported. 529 | 530 | This allows you to use rsync features 531 | that are not directly supported by 532 | .BR dirvish . 533 | Where 534 | .B dirvish 535 | does support an rsync feature it is probably better to 536 | use the the 537 | .B dirvish 538 | supplied mechanism for setting it. 539 | 540 | .multiple rsync\-options 541 | .TP 542 | .Br sparse: (B) 543 | Try to handle sparse files efficiently so they take up 544 | less space in the \*[vault]. 545 | 546 | NOTE: Some filesystem types may have problems seeking over null regions. 547 | .TP 548 | .Bi speed\-limit: Mbps (S) 549 | Specify a maximum transfer rate. 550 | 551 | This allows you to limit the network bandwidth consumed. 552 | The value is specified in approximate Mega-bits per second 553 | which correlates to network transport specifications. 554 | An adaptive algorithm is used so the actual bandwidth usage may exceed 555 | .I Mbps 556 | occasionally. 557 | 558 | .SeeIn --bwlimit rsync(1) 559 | .TP 560 | .Br stats: (B) 561 | Have rsync report transfer statistics. 562 | 563 | .See rsync(1) 564 | 565 | .default 1 566 | .TP 567 | .Br "summary: short\*|long" (S) 568 | Specify summary format. 569 | 570 | A short summary will only include final used values. 571 | A long summary will include all configuration values. 572 | 573 | With long format you custom options in the 574 | configuration files will appear in the summary. 575 | 576 | The default is short. 577 | .TP 578 | .Bi tree: "path [alias]" (S) 579 | Specify a directory path on the client to backup. 580 | 581 | If 582 | .I path 583 | is prefixed with a colon 584 | the transfer will be done from an 585 | .B rsync 586 | daemon on the client 587 | otherwise the transfer will be done through a remote shell process. 588 | 589 | The optional 590 | .I alias 591 | specifies the path that should appear in the index 592 | so 593 | .B dirvish\-locate 594 | will report paths consistant with common usage. 595 | This can help reduce confusion when dealing with users 596 | unfamiliar with the physical topology of their network provided files. 597 | .TP 598 | .Br no\-run: (B) 599 | Don't actually do anything. 600 | 601 | Process all configuration files, options and tests 602 | then produce a summary/configuration file on standard output 603 | and exit. 604 | 605 | I can't think why you would do this in a configuration file 606 | but if you want to shoot yourself in the foot, be my guest. 607 | .TP 608 | .Bi vault: vault (S) 609 | Specify the \*[vault] to store the \*[image] in. 610 | 611 | Although multiple \*[vault]s may share a filesystem a 612 | given \*[vault] cannot span filesystems. For filesystem 613 | purposes the \*[vault] is the level of atomicity. 614 | 615 | This will seldom be specified in a configuration file. 616 | .TP 617 | .Br whole\-file: (B) 618 | Transfer whole files instead of just the parts that have changed. 619 | 620 | This may be slightly faster for files that have 621 | more changed than left the same 622 | such as compressed or encrypted files. 623 | In most cases this will be slower when transferring over the network 624 | but will use less CPU resources. 625 | This will be faster 626 | if the transfers are not over the network 627 | or when the network is faster than the destination disk subsystem. 628 | .TP 629 | .Br xdev: (B) 630 | Do not cross mount-points when traversing the tree on the client. 631 | .TP 632 | .Br zxfer: (B) 633 | Enable compression on data-transfer. 634 | .SH SCHEDULING OPTIONS 635 | .TP 636 | .Bi Dirvish: path (S) 637 | Location of dirvish executable. 638 | 639 | If not set defaults to 640 | .BR dirvish . 641 | .if 0 \{ \" parameters for dirvish-sched 642 | .TP 643 | .Bi Frequency: parsedate_expression (S) 644 | How often this backup is allowed to run. 645 | 646 | If the time the last \*[image] of this \*[branch] was created 647 | is more than parsedate_expression old and we are 648 | within a time Window it may commence a backup. 649 | .TP 650 | .Bi Load: load_units (S) 651 | Set a relative load value for a job. 652 | 653 | The load that a job places on the server will vary 654 | depending on the frequency of file changes, 655 | end-to-end network bandwidth (and 656 | .BR speed\-limit ), 657 | and the processing speed of the client. 658 | .TP 659 | .Bi Load\-default: load_units (S) 660 | Set the default value for Load. 661 | 662 | This option can only be set in the master configuration file 663 | and if left unset will default to 664 | .BR 100 . 665 | .TP 666 | .Bi Max\-jobs: count (S) 667 | Set the maximum number of simultaneous jobs permitted. 668 | 669 | When set in the master configuration file 670 | this applies to the server. 671 | When set in the client config file 672 | this will limit only limit the number of simultaneous jobs on that client. 673 | .TP 674 | .Bi Max\-load: load_units (S) 675 | Set the maximum load permitted. 676 | 677 | The total load_units of all jobs running will not exceed this value. 678 | If not set no load limiting will be done. 679 | 680 | When set in the master configuration file 681 | this applies to the server. 682 | hen set in the client config file 683 | this will limit only limit the load of simultaneous jobs on that client. 684 | .TP 685 | .Bi Priority: priority (S) 686 | Set a priority value for a job. 687 | 688 | Relative priorities will be used in scheduling jobs. 689 | \} 690 | .TP 691 | .Br Runall: (L) 692 | Specify \*[branch]es to be scheduled for automated backups. 693 | Each value is specified in the form 694 | .ti +.5i 695 | .br 696 | vault:branch [image_time] 697 | .br 698 | 699 | If image_time is set here it will be used. 700 | 701 | This option can only be set in the master configuration file 702 | and multiple values will accumulate. 703 | .if 0 \{ \" parameters for dirvish-sched 704 | .TP 705 | .Bi Schedule: vault:branch (L) 706 | Specify \*[branch]es to be scheduled for automated backups. 707 | 708 | This option can only be set in the master configuration file 709 | and multiple \*[branch]es will accumulate. 710 | .TP 711 | .Bi Window: time_pattern (L) 712 | time pattern expression for scheduling backups. 713 | 714 | The time_patterns will be tested and if any one 715 | matches the current time and the last \*[image] is old 716 | enough it may commence a backup. 717 | 718 | See EXPIRE RULES for details of time_pattern 719 | expressions. 720 | 721 | Multiple patterns will accumulate so if a client or 722 | \*[branch] requires more restrictive windows use RESET. 723 | \} 724 | .SH EXPIRE RULES 725 | Expire rules is a list of rules used to determine an 726 | expiration time for an \*[image]. 727 | 728 | The last rule that matches will apply so list order is significant. 729 | This allows rules to be set in client, 730 | \*[vault] and 731 | \*[branch] configuration files to override rules set in the 732 | master configuration file without having to use 733 | .BR RESET . 734 | In most cases 735 | it is better to use a 736 | .B expire\-default: 737 | value than to define a rule that matches all possible times. 738 | 739 | Each rule has an pattern expression against which the current 740 | time is compared followed by a date specifier in 741 | .B Time::ParseDate 742 | format. 743 | .See Time::ParseDate(3pm) 744 | 745 | A matching rule with an empty/missing 746 | date specifier or specifying 747 | .B never 748 | will result in no expiration. 749 | 750 | The time pattern expression may be in either 751 | .B crontab 752 | or in 753 | .B Time::Period 754 | format. 755 | .See "crontab(5) and Time::Period(3pm)" 756 | 757 | The crontab formated patterns are converted to 758 | .B Time::Period 759 | format 760 | so the limitations and extensions for the specification of option values of 761 | .B Time::Period 762 | apply to the 763 | .B crontab 764 | format as well. 765 | Most notable is that the days of the week are numbered 766 | \fB1\fP\-\fB7\fP for \fBsun\fP\-\fBsat\fP so 767 | .B 0 768 | is not a valid wday but 769 | .B sat 770 | is. 771 | 772 | Here are two equivalent examples of an expire\-rule list. 773 | 774 | .nf 775 | .ft CR 776 | .ta .5i T 6m 777 | expire\-default: +5 weeks 778 | expire\-rule: 779 | 780 | #MIN HR DOM MON DOW EXPIRE 781 | * * * * 1 +3 months 782 | * * 1\-7 * su +1 year 783 | * * 1\-7 1,4,7,10 1 never 784 | * 10\-20 * * * +10 days 785 | or: 786 | .ta +.5i +36m 787 | wd { sun } +3 months 788 | wd { sun } md { 1\-7 } +1 year 789 | wd { 1 } md { 1\-7 } mo { 1,4,7,10 } never 790 | hr { 10\-20 } +10 days 791 | .ft R 792 | .fi 793 | 794 | This describes is an aggressive retention schedule. If the 795 | nightly backup is made dated the 1st Sunday of each quarter it is 796 | is kept forever, the 1st Sunday of any other month is kept for 797 | 1 year, all other Sunday's are kept for 3 months, the remaining 798 | nightlies are kept for 5 weeks. In addition, if the backup is 799 | made between 10AM and 8PM it will expire after 10 days. This 800 | would be appropriate for someone with a huge backup server who 801 | is so paranoid he makes two backups per day. The other 802 | possibility for the hour spec would be for ad-hoc special 803 | backups to have a default that differs from the normal 804 | dailies. 805 | 806 | It should be noted that all expiration rules will do is to 807 | cause dirvish to put an 808 | .B Expire: 809 | option in the summary file. 810 | The 811 | .B dirvish\-expire 812 | utility will have to be run to actually delete any expired \*[image]s. 813 | 814 | .SH FILES 815 | .TP 816 | .B /etc/dirvish/master.conf 817 | alternate master configuration file. 818 | .TP 819 | .B /etc/dirvish.conf 820 | master configuration file. 821 | .TP 822 | .B /etc/dirvish/\fIclient\fP[.conf] 823 | client configuration file. 824 | .TP 825 | .IB bank/vault/ dirvish/default[.conf] 826 | default vault configuration file. 827 | .TP 828 | .IB bank/vault/\fBdirvish\fP/branch [.conf] 829 | branch configuration file. 830 | .TP 831 | .IB bank/vault/\fBdirvish\fP/branch .hist 832 | branch history file. 833 | .TP 834 | .IB bank/vault/image/ summary 835 | image creation summary. 836 | .TP 837 | .IB bank/vault/image/ log 838 | image creation log. 839 | .TP 840 | .IB bank/vault/image/ tree 841 | actual image of source directory tree. 842 | .TP 843 | .IB bank/vault/image/ rsync_error 844 | Error output from rsync if errors or warnings were detected. 845 | 846 | .SH SEE ALSO 847 | .nf 848 | dirvish(8) 849 | dirvish\-expire(8) 850 | dirvish\-runall(8) 851 | dirvish\-locate(8) 852 | ssh(1), 853 | rsync(1) 854 | Time::ParseDate(3pm) 855 | strftime(3) 856 | .SH AUTHOR 857 | Dirvish was created by J.W. Schultz of Pegasystems Technologies. 858 | .SH BUGS 859 | Rsync version 2.5.6 has a bug so that unsetting the 860 | .B perms 861 | option will not disable testing for permissions. 862 | Disabling perms will break image linking. 863 | 864 | Options set in configuration files 865 | will override command line options 866 | that have been set before the file is read. 867 | This behaviour while consistent may confuse users. 868 | For this reason 869 | the more frequently used command line options 870 | have options paired with a 871 | .I default 872 | option so the order of specification will be more forgiving. 873 | It is recommended that where such default options exist 874 | in configuration files they should be preferred over the primary option. 875 | 876 | It is possible to specify almost any command line option as a option. 877 | Some of them just don't make sense to use here. 878 | -------------------------------------------------------------------------------- /dirvish/manifests/init.pp: -------------------------------------------------------------------------------- 1 | # class name_of_class { } 2 | # define definition { } 3 | # 4 | # Classes and Definitions here. 5 | 6 | class dirvish { 7 | 8 | class client { 9 | # client portion is limited to installing an SSH key on the box 10 | # for the dirvish server to use to connect to it. 11 | # Since this is site specific, this is doen via our local module 12 | } 13 | 14 | class server { 15 | 16 | package { 17 | ["perl-Time-modules", 18 | "perl-Time-Period"]: 19 | ensure => installed, 20 | require => Yumrepo["rpmforge"], 21 | } 22 | 23 | file { "/etc/dirvish": 24 | ensure => directory, 25 | owner => "root", 26 | group => "root", 27 | mode => "0755", 28 | } 29 | 30 | file { 31 | "/usr/sbin/dirvish" : 32 | owner => "root", group => "root", mode => "0755", 33 | source => "puppet:///dirvish/bin/dirvish"; 34 | "/usr/sbin/dirvish-expire" : 35 | owner => "root", group => "root", mode => "0755", 36 | source => "puppet:///dirvish/bin/dirvish-expire"; 37 | "/usr/sbin/dirvish-locate" : 38 | owner => "root", group => "root", mode => "0755", 39 | source => "puppet:///dirvish/bin/dirvish-locate"; 40 | "/usr/sbin/dirvish-runall" : 41 | owner => "root", group => "root", mode => "0755", 42 | source => "puppet:///dirvish/bin/dirvish-runall"; 43 | } 44 | 45 | file { 46 | "/usr/share/man/man5/dirvish.conf.5" : 47 | owner => "root", group => "root", mode => "0644", 48 | source => "puppet:///dirvish/man/dirvish.conf.5"; 49 | "/usr/share/man/man8/dirvish.8" : 50 | owner => "root", group => "root", mode => "0644", 51 | source => "puppet:///dirvish/man/dirvish.8"; 52 | "/usr/share/man/man8/dirvish-expire.8" : 53 | owner => "root", group => "root", mode => "0644", 54 | source => "puppet:///dirvish/man/dirvish-expire.8"; 55 | "/usr/share/man/man8/dirvish-locate.8" : 56 | owner => "root", group => "root", mode => "0644", 57 | source => "puppet:///dirvish/man/dirvish-locate.8"; 58 | "/usr/share/man/man8/dirvish-runall.8" : 59 | owner => "root", group => "root", mode => "0644", 60 | source => "puppet:///dirvish/man/dirvish-runall.8", 61 | } 62 | } 63 | } 64 | 65 | define dirvish::config ($banks, $imagedef = "%Y%m%d", $index = "none", $log = "none", 66 | $excludes = [''], $runall = [''], $time = false, $expiredef = "+2 weeks", $expires = ['']) { 67 | 68 | file { "/etc/dirvish/master.conf": 69 | owner => "root", 70 | group => "root", 71 | mode => "0640", 72 | content => template("dirvish/master.conf.erb") 73 | } 74 | } 75 | 76 | define dirvish::bank ($bank) { 77 | file { "$bank": 78 | ensure => directory, 79 | owner => "root", 80 | group => "root", 81 | mode => "0750", 82 | } 83 | } 84 | 85 | define dirvish::vault ($bank, $vault) { 86 | file { "$bank/$vault": 87 | ensure => directory, 88 | owner => "root", 89 | group => "root", 90 | mode => "0750", 91 | } 92 | file { "$bank/$vault/dirvish": 93 | ensure => directory, 94 | owner => "root", 95 | group => "root", 96 | mode => "0750", 97 | require => File["$bank/$vault"], 98 | } 99 | } 100 | 101 | define dirvish::branch ($bank, $vault, $host, $fs, 102 | $xdev = "true", $index = "gzip", $excludes = [''], $parent = false) { 103 | 104 | file { "$bank/$vault/dirvish/$name.conf": 105 | owner => "root", 106 | group => "root", 107 | mode => "0640", 108 | content => template("dirvish/branch.conf.erb") 109 | } 110 | 111 | $cmd = $parent ? { 112 | false => "dirvish --init --branch $vault:$name", 113 | default => "dirvish --reference $parent --branch $vault:$name", 114 | } 115 | 116 | exec { "branch-create-$name": 117 | command => $cmd, 118 | creates => "$bank/$vault/dirvish/$name.hist", 119 | require => [File["/usr/sbin/dirvish"], File["$bank/$vault/dirvish/$name.conf"]] 120 | } 121 | } 122 | 123 | define dirvish::stats ($email, $period = "yesterday") { 124 | 125 | file { "/usr/sbin/$name": 126 | owner => "root", 127 | group => "root", 128 | mode => "0755", 129 | content => template("dirvish/dirvish-stats.erb") 130 | } 131 | } 132 | 133 | define dirvish::userkey ($user = "root", $group = "root", $key = false, $file = "authorized_keys2") { 134 | 135 | $dir = $user ? { 136 | "root" => "/root/.ssh", 137 | default => "/home/$user/.ssh", 138 | } 139 | 140 | exec { "dirvish-create-keydir": 141 | command => "/bin/mkdir -m 0700 -p $dir", 142 | creates => "$dir", 143 | } 144 | exec { "dirvish-modify-keydir": 145 | command => "/bin/chown $user:$group $dir", 146 | unless => "stat --printf='%U:%G\n' $dir | grep '$user:$group' 1>/dev/null", 147 | require => Exec["dirvish-create-keydir"] 148 | } 149 | 150 | line { "dirvish-pub-key": 151 | ensure => present, 152 | file => "$dir/$file", 153 | line => "$key", 154 | require => Exec["dirvish-modify-keydir"] 155 | } 156 | 157 | } 158 | 159 | 160 | # vim modeline - have 'set modeline' and 'syntax on' in your ~/.vimrc. 161 | # vi:syntax=puppet:filetype=puppet:ts=4:et: 162 | # EOF 163 | -------------------------------------------------------------------------------- /dirvish/templates/branch.conf.erb: -------------------------------------------------------------------------------- 1 | client: <%= host %> 2 | tree: <%= fs %> 3 | xdev: <%= xdev %> 4 | index: <%= index %> 5 | image-default: <%= name %>-%Y%m%d-%H%M%S 6 | exclude: 7 | <% excludes.each do |rule| %> <%= rule %> 8 | <% end %> 9 | 10 | -------------------------------------------------------------------------------- /dirvish/templates/dirvish-stats.erb: -------------------------------------------------------------------------------- 1 | #!/usr/bin/perl 2 | $CONFDIR = "/etc/dirvish"; 3 | $mailto='<%= email %>'; 4 | 5 | $yesterday=time-86400; 6 | $today=time; 7 | 8 | #$usedate=$yesterday; 9 | $usedate=$<%= period %>; 10 | 11 | # dstat.pl 12 | # Mike Lerley [mike@rentageekme.com], 4/10/06 13 | # Portions pulled from dirvish-runall.pl and dirvish-status.sh by 14 | 15 | 16 | 17 | 18 | # $Id: dirvish-runall.pl,v 12.0 2004/02/25 02:42:14 jw Exp $ $Name: Dirvish-1_2 $ 19 | 20 | $VERSION = ('$Name: Dirvish-1_2 $' =~ /Dirvish/i) 21 | ? ('$Name: Dirvish-1_2 $' =~ m/^.*:\s+dirvish-(.*)\s*\$$/i)[0] 22 | : '1.1.2 patch' . ('$Id: dirvish-runall.pl,v 12.0 2004/02/25 02:42:14 jw Exp $' 23 | =~ m/^.*,v(.*:\d\d)\s.*$/)[0]; 24 | $VERSION =~ s/_/./g; 25 | 26 | 27 | ######################################################################### 28 | # # 29 | # Copyright 2002 and $Date: 2004/02/25 02:42:14 $ 30 | # Pegasystems Technologies and J.W. Schultz # 31 | # # 32 | # Licensed under the Open Software License version 2.0 # 33 | # # 34 | # This program is free software; you can redistribute it # 35 | # and/or modify it under the terms of the Open Software # 36 | # License, version 2.0 by Lauwrence E. Rosen. # 37 | # # 38 | # This program is distributed in the hope that it will be # 39 | # useful, but WITHOUT ANY WARRANTY; without even the implied # 40 | # warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR # 41 | # PURPOSE. See the Open Software License for details. # 42 | # # 43 | ######################################################################### 44 | 45 | use Time::ParseDate; 46 | use POSIX qw(strftime); 47 | use Getopt::Long; 48 | 49 | sub loadconfig; 50 | sub seppuku; 51 | 52 | sub usage 53 | { 54 | my $message = shift(@_); 55 | 56 | length($message) and print STDERR $message, "\n\n"; 57 | 58 | $! and exit(255); # because getopt seems to send us here for death 59 | 60 | print STDERR < sub { 75 | print STDERR "dirvish version $VERSION\n"; 76 | exit(0); 77 | }, 78 | help => \&usage, 79 | }; 80 | 81 | GetOptions($Options, qw( 82 | config=s 83 | quiet no-run|dry-run 84 | version help 85 | )) or usage; 86 | 87 | if ($$Options{config}) 88 | { 89 | $Config = loadconfig(undef, $$Options{config}) 90 | } 91 | elsif ($CONFDIR =~ /dirvish$/ && -f "$CONFDIR.conf") 92 | { 93 | $Config = loadconfig(undef, "$CONFDIR.conf"); 94 | } 95 | elsif (-f "$CONFDIR/master.conf") 96 | { 97 | $Config = loadconfig(undef, "$CONFDIR/master.conf"); 98 | } 99 | elsif (-f "$CONFDIR/dirvish.conf") 100 | { 101 | seppuku 250, <) { 126 | chomp; 127 | if(m/image-default/) { 128 | (undef,$id)=split(/:\s*/); 129 | } 130 | } 131 | close C; 132 | $dir=$$Config{bank}[0]."/$v/$b-".strftime("%Y%m%d", localtime($usedate))."-000000"; 133 | 134 | 135 | $themail.="================== $v-$b ==================\n"; 136 | 137 | # Check for a summary or log file (at least one should be 138 | # present if a backup occurred 139 | if(!-e "$dir/log.gz" || !-e "$dir/summary") { 140 | # If no backup last night, then warn. 141 | # Also, try to guess the last night a backup occurred. 142 | # (yes, it's crude.) 143 | $themail.="** WARNING: This machine not backed up!\n"; 144 | $last=`(ls -dt [0-9]* 2>/dev/null)|head -1`; 145 | if(!$last) { $last="NEVER" }; 146 | $themail.=" (last backup: $last)\n"; 147 | $WARNINGS.=" $v-$b"; 148 | } else { 149 | # Otherwise, we assume that if there is no Status: success, 150 | # the backup wasn't successful. It could be that the backup is 151 | # still running, but is still worth a look. 152 | if(!`grep -c "Status: success" $dir/summary`) { 153 | $themail.="** WARNING: Backup not successful\n\n"; 154 | # Keep a list of machines with warnings. 155 | $WARNINGS.=" $v"; 156 | } 157 | 158 | # Copy the backup's summary file to the email, ignoring 159 | # any exclude: lines (to keep the email short, but useful.) 160 | $summ=''; 161 | open(F,"$dir/summary") || warn "Can't open summary file: $!"; 162 | while() { 163 | $fl=$_; 164 | $summ.=$_ if $fl!~/(^ |^exclude:|^$)/; 165 | } 166 | $themail.=$summ; 167 | 168 | # MDL 9/1/05 - copy end of log file to get file/byte counts too 169 | $themail.=`zcat $dir/log.gz |tail -13`; 170 | } 171 | $themail.="\n\n"; 172 | } 173 | 174 | $prefix="Disk usage:\n".`/bin/df -h`."\n"; 175 | 176 | # Include a [**] notation on the subject line if there were warnings. 177 | if($WARNINGS) { 178 | $WARNSUB="[**] "; 179 | $prefix="\nThe following branches had warnings:\n\t$WARNINGS\n\n".$prefix; 180 | } else { 181 | $WARNSUB=""; 182 | } 183 | $themail=$prefix.$themail; 184 | 185 | open(M,"|/bin/mail -s \"${WARNSUB}Dirvish status (`hostname`)\" $mailto") || warn "Can't mail: $!"; 186 | print M $themail; 187 | close M; 188 | 189 | 190 | exit ($errors < 200 ? $errors : 199); 191 | # Get patch level of loadconfig.pl in case exit codes 192 | # are needed. 193 | # $Id: loadconfig.pl,v 12.0 2004/02/25 02:42:15 jw Exp $ 194 | 195 | 196 | ######################################################################### 197 | # # 198 | # Copyright 2002 and $Date: 2004/02/25 02:42:15 $ 199 | # Pegasystems Technologies and J.W. Schultz # 200 | # # 201 | # Licensed under the Open Software License version 2.0 # 202 | # # 203 | ######################################################################### 204 | 205 | sub seppuku # Exit with code and message. 206 | { 207 | my ($status, $message) = @_; 208 | 209 | chomp $message; 210 | if ($message) 211 | { 212 | $seppuku_prefix and print STDERR $seppuku_prefix, ': '; 213 | print STDERR $message, "\n"; 214 | } 215 | exit $status; 216 | } 217 | 218 | sub slurplist 219 | { 220 | my ($key, $filename, $Options) = @_; 221 | my $f; 222 | my $array; 223 | 224 | $filename =~ m(^/) and $f = $filename; 225 | if (!$f && ref($$Options{vault}) ne 'CODE') 226 | { 227 | $f = join('/', $$Options{Bank}, $$Options{vault}, 228 | 'dirvish', $filename); 229 | -f $f or $f = undef; 230 | } 231 | $f or $f = "$CONFDIR/$filename"; 232 | open(PATFILE, "<$f") or seppuku 229, "cannot open $filename for $key list"; 233 | $array = $$Options{$key}; 234 | while() 235 | { 236 | chomp; 237 | length or next; 238 | push @{$array}, $_; 239 | } 240 | close PATFILE; 241 | } 242 | 243 | # loadconfig -- load configuration file 244 | # SYNOPSYS 245 | # loadconfig($opts, $filename, \%data) 246 | # 247 | # DESCRIPTION 248 | # load and parse a configuration file into the data 249 | # hash. If the filename does not contain / it will be 250 | # looked for in the vault if defined. If the filename 251 | # does not exist but filename.conf does that will 252 | # be read. 253 | # 254 | # OPTIONS 255 | # Options are case sensitive, upper case has the 256 | # opposite effect of lower case. If conflicting 257 | # options are given only the last will have effect. 258 | # 259 | # f Ignore fields in config file that are 260 | # capitalized. 261 | # 262 | # o Config file is optional, return undef if missing. 263 | # 264 | # R Do not allow recoursion. 265 | # 266 | # g Only load from global directory. 267 | # 268 | # 269 | # 270 | # LIMITATIONS 271 | # Only way to tell whether an option should be a list 272 | # or scalar is by the formatting in the config file. 273 | # 274 | # Options reqiring special handling have to have that 275 | # hardcoded in the function. 276 | # 277 | 278 | sub loadconfig 279 | { 280 | my ($mode, $configfile, $Options) = @_; 281 | my $confile = undef; 282 | my ($key, $val); 283 | my $CONFIG; 284 | ref($Options) or $Options = {}; 285 | my %modes; 286 | my ($conf, $bank, $k); 287 | 288 | $modes{r} = 1; 289 | for $_ (split(//, $mode)) 290 | { 291 | if (/[A-Z]/) 292 | { 293 | $_ =~ tr/A-Z/a-z/; 294 | $modes{$_} = 0; 295 | } else { 296 | $modes{$_} = 1; 297 | } 298 | } 299 | 300 | 301 | $CONFIG = 'CFILE' . scalar(@{$$Options{Configfiles}}); 302 | 303 | $configfile =~ s/^.*\@//; 304 | 305 | if($configfile =~ m[/]) 306 | { 307 | $confile = $configfile; 308 | } 309 | elsif($configfile ne '-') 310 | { 311 | if(!$modes{g} && $$Options{vault} && $$Options{vault} ne 'CODE') 312 | { 313 | if(!$$Options{Bank}) 314 | { 315 | my $bank; 316 | for $bank (@{$$Options{bank}}) 317 | { 318 | if (-d "$bank/$$Options{vault}") 319 | { 320 | $$Options{Bank} = $bank; 321 | last; 322 | } 323 | } 324 | } 325 | if ($$Options{Bank}) 326 | { 327 | $confile = join('/', $$Options{Bank}, 328 | $$Options{vault}, 'dirvish', 329 | $configfile); 330 | -f $confile || -f "$confile.conf" 331 | or $confile = undef; 332 | } 333 | } 334 | $confile ||= "$CONFDIR/$configfile"; 335 | } 336 | 337 | if($configfile eq '-') 338 | { 339 | open($CONFIG, $configfile) or seppuku 221, "cannot open STDIN"; 340 | } else { 341 | ! -f $confile && -f "$confile.conf" and $confile .= '.conf'; 342 | 343 | if (! -f "$confile") 344 | { 345 | $modes{o} and return undef; 346 | seppuku 222, "cannot open config file: $configfile"; 347 | } 348 | 349 | grep(/^$confile$/, @{$$Options{Configfiles}}) 350 | and seppuku 224, "ERROR: config file looping on $confile"; 351 | 352 | open($CONFIG, $confile) 353 | or seppuku 225, "cannot open config file: $configfile"; 354 | } 355 | push(@{$$Options{Configfiles}}, $confile); 356 | 357 | while(<$CONFIG>) 358 | { 359 | chomp; 360 | s/\s*#.*$//; 361 | s/\s+$//; 362 | /\S/ or next; 363 | 364 | if(/^\s/ && $key) 365 | { 366 | s/^\s*//; 367 | push @{$$Options{$key}}, $_; 368 | } 369 | elsif(/^SET\s+/) 370 | { 371 | s/^SET\s+//; 372 | for $k (split(/\s+/)) 373 | { 374 | $$Options{$k} = 1; 375 | } 376 | } 377 | elsif(/^UNSET\s+/) 378 | { 379 | s/^UNSET\s+//; 380 | for $k (split(/\s+/)) 381 | { 382 | $$Options{$k} = undef; 383 | } 384 | } 385 | elsif(/^RESET\s+/) 386 | { 387 | ($key = $_) =~ s/^RESET\s+//; 388 | $$Options{$key} = [ ]; 389 | } 390 | elsif(/^[A-Z]/ && $modes{f}) 391 | { 392 | $key = undef; 393 | } 394 | elsif(/^\S+:/) 395 | { 396 | ($key, $val) = split(/:\s*/, $_, 2); 397 | length($val) or next; 398 | $k = $key; $key = undef; 399 | 400 | if ($k eq 'config') 401 | { 402 | $modes{r} and loadconfig($mode . 'O', $val, $Options); 403 | next; 404 | } 405 | if ($k eq 'client') 406 | { 407 | if ($modes{r} && ref ($$Options{$k}) eq 'CODE') 408 | { 409 | loadconfig($mode . 'og', "$CONFDIR/$val", $Options); 410 | } 411 | $$Options{$k} = $val; 412 | next; 413 | } 414 | if ($k eq 'file-exclude') 415 | { 416 | $modes{r} or next; 417 | 418 | slurplist('exclude', $val, $Options); 419 | next; 420 | } 421 | if (ref ($$Options{$k}) eq 'ARRAY') 422 | { 423 | push @{$$Options{$k}}, $_; 424 | } else { 425 | $$Options{$k} = $val; 426 | } 427 | } 428 | } 429 | close $CONFIG; 430 | return $Options; 431 | } 432 | -------------------------------------------------------------------------------- /dirvish/templates/master.conf.erb: -------------------------------------------------------------------------------- 1 | # This file is under the control of Puppet - Do Not Edit Locally 2 | 3 | bank: 4 | <% banks.each do |bank| %> <%= bank %> 5 | <% end %> 6 | 7 | 8 | image-default: <%= imagedef %> 9 | index: <%= index %> 10 | log: <%= log %> 11 | 12 | exclude: 13 | # /var/cache/apt/archives/*.deb 14 | # /usr/src/**/*.o 15 | # lost+found/ 16 | <% excludes.each do |rule| %> <%= rule %> 17 | <% end %> 18 | 19 | Runall: 20 | <% runall.each do |run| %> <%= run %> <%= time %> 21 | <% end %> 22 | 23 | expire-default: <%= expiredef %> 24 | 25 | expire-rule: 26 | #MIN HR DOM MON DOW EXPIRE 27 | <% expires.each do |exp| %> <%= exp %> 28 | <% end %> 29 | 30 | -------------------------------------------------------------------------------- /heartbeat/manifests/heartbeat-old.pp: -------------------------------------------------------------------------------- 1 | class heartbeat { 2 | package { "heartbeat": 3 | ensure => present, 4 | require => Yumrepo["extras"], 5 | before => [ 6 | File["/etc/ha.d/ha.cf"], 7 | File["/etc/ha.d/haresources"], 8 | File["/etc/ha.d/authkeys"], 9 | File["/var/lib/heartbeat/crm/cib.xml"] 10 | ] 11 | } 12 | file { "/etc/ha.d/ha.cf": 13 | mode => "0644", 14 | source => "puppet:///heartbeat/ha.d/ha.cf", 15 | } 16 | file { "/etc/ha.d/haresources": 17 | mode => "0644", 18 | source => "puppet:///heartbeat/ha.d/haresources", 19 | } 20 | file { "/etc/ha.d/authkeys": 21 | mode => "0600", 22 | source => "puppet:///heartbeat/ha.d/authkeys", 23 | } 24 | file { "/var/lib/heartbeat/crm/cib.xml": 25 | owner => "hacluster", 26 | group => "haclient", 27 | mode => "0600", 28 | source => "puppet:///heartbeat/var_lib_heartbeat/crm/cib.xml", 29 | } 30 | # file { "/var/lib/heartbeat/crm/cib.xml.sig": 31 | # owner => "hacluster", 32 | # group => "haclient", 33 | # mode => "0600", 34 | # source => "puppet:///heartbeat/var_lib_heartbeat/crm/cib.xml.sig", 35 | # } 36 | } 37 | #define heartbeat::haip ( $serveralias, $ip ) { 38 | 39 | # } 40 | # vim modeline - have 'set modeline' and 'syntax on' in your ~/.vimrc. 41 | # vi:syntax=puppet:filetype=puppet:ts=4:et: 42 | # EOF 43 | -------------------------------------------------------------------------------- /heartbeat/manifests/init.pp: -------------------------------------------------------------------------------- 1 | 2 | class heartbeat { 3 | 4 | package { "heartbeat": 5 | ensure => installed, 6 | require => Yumrepo["extras"], 7 | } 8 | 9 | service { "heartbeat": 10 | hasstatus => true, 11 | hasrestart => true, 12 | } 13 | 14 | } 15 | 16 | # heartbeat::hacf creates a base cluster configuration file with sane 17 | # defaults for our environment. 18 | # 19 | # Variables used: 20 | # Each variable/parameter used corresponds to a value in the heartbeat ha.cf 21 | # file. For definitive documentation on the allowed options and values, see 22 | # the heartbeat documentation. Special notes here. 23 | # 24 | # $hosts: Must be passed as an array for the template to parse properly. 25 | # $ping: Must be passed as an array as well, see sample usage. 26 | # 27 | # Example usage: 28 | # heartbeat::hacf { "security wiki"": 29 | # hosts => ["web1e", "web1f"], 30 | # ping => ["10.1.0.1"], 31 | # } 32 | 33 | define heartbeat::hacf ( 34 | $logfacility = 'local0', $bcast = 'bond0', 35 | $keepalive = '1', $auto_failback = 'on', 36 | $deadtime = '10', $hosts, 37 | $warntime = '3', $ping, 38 | $initdead = '30', $crm = true 39 | ){ 40 | 41 | file { "/etc/ha.d/ha.cf": 42 | mode => 0644, 43 | content => template("heartbeat/ha.cf.erb"), 44 | notify => Service["heartbeat"], 45 | require => Package["heartbeat"], 46 | } 47 | 48 | } 49 | 50 | # heartbeat::haresources sets up a v1 haresources file as a baseline, then 51 | # runs the conversion script to create a v2 cib.xml file. 52 | # 53 | # Variables used: 54 | # 55 | # $primary: The primary system where the service should live. 56 | # $ipaddr: Ip address(es) used, must be passed as an array. 57 | # $service: The service for the resource group. Optional. 58 | # 59 | # Example usage: 60 | # 61 | # heartbeat::haresources { "security wiki": 62 | # primary => "web1e.den.giac.net", 63 | # ipaddr => ["10.1.0.151"], 64 | # service => "httpd", 65 | # } 66 | 67 | define heartbeat::haresources ( $primary, $ipaddr, $service = '') { 68 | 69 | file { "/etc/ha.d/haresources": 70 | mode => 0644, 71 | replace => false, 72 | content => template("heartbeat/haresources.erb"), 73 | require => [Package["heartbeat"], File["/etc/ha.d/ha.cf"]], 74 | } 75 | 76 | # Run the conversion file to create cib.xml for heartbeat v2. 77 | # the haresources2cib.py script checks for cib.xml. 78 | 79 | exec { "/usr/lib/heartbeat/haresources2cib.py": 80 | creates => "/var/lib/heartbeat/crm/cib.xml", 81 | require => File["/etc/ha.d/haresources"], 82 | } 83 | 84 | } 85 | 86 | # heartbeat::authkeys sets up the authentication keys files. 87 | # The template will perform an MD5 hash on the password. 88 | # 89 | # Variables used: 90 | # 91 | # $signature: The signature method. Valid values are md5, sha1 and crc. 92 | # $password: The password to create an md5 hash 93 | # 94 | # Example usage: 95 | # 96 | # heartbeat::authkeys { "security wiki": 97 | # password => "Security Wiki", 98 | # } 99 | define heartbeat::authkeys ($signature = 'sha1', $password) { 100 | 101 | file { "/etc/ha.d/authkeys": 102 | mode => 0600, 103 | content => template("heartbeat/authkeys.erb"), 104 | notify => Service["heartbeat"], 105 | require => Package["heartbeat"], 106 | } 107 | 108 | } 109 | # vi:syntax=puppet:filetype=puppet:ts=4:et: 110 | -------------------------------------------------------------------------------- /heartbeat/templates/authkeys.erb: -------------------------------------------------------------------------------- 1 | <% require 'digest/md5'-%>auth 1 2 | 1 <%= signature %> <% hash = Digest::MD5.hexdigest(password) -%><%= hash %> 3 | -------------------------------------------------------------------------------- /heartbeat/templates/ha.cf.erb: -------------------------------------------------------------------------------- 1 | logfacility <%= logfacility %> 2 | 3 | keepalive <%= keepalive %> 4 | deadtime <%= deadtime %> 5 | warntime <%= warntime %> 6 | initdead <%= initdead %> 7 | 8 | bcast <%= bcast %> 9 | auto_failback <%= auto_failback %> 10 | 11 | node <%= hosts.join(" ") %> 12 | ping <%= ping.join(" ") %> 13 | 14 | crm <%= crm %> 15 | -------------------------------------------------------------------------------- /heartbeat/templates/haresources.erb: -------------------------------------------------------------------------------- 1 | <%= primary %> <%= ipaddr.join(" ") %> <%= service %> 2 | -------------------------------------------------------------------------------- /md3000/files/lvm.conf: -------------------------------------------------------------------------------- 1 | # This is an example configuration file for the LVM2 system. 2 | # It contains the default settings that would be used if there was no 3 | # /etc/lvm/lvm.conf file. 4 | # 5 | # Refer to 'man lvm.conf' for further information including the file layout. 6 | # 7 | # To put this file in a different directory and override /etc/lvm set 8 | # the environment variable LVM_SYSTEM_DIR before running the tools. 9 | 10 | 11 | # This section allows you to configure which block devices should 12 | # be used by the LVM system. 13 | devices { 14 | 15 | # Where do you want your volume groups to appear ? 16 | dir = "/dev" 17 | 18 | # An array of directories that contain the device nodes you wish 19 | # to use with LVM2. 20 | scan = [ "/dev" ] 21 | 22 | # A filter that tells LVM2 to only use a restricted set of devices. 23 | # The filter consists of an array of regular expressions. These 24 | # expressions can be delimited by a character of your choice, and 25 | # prefixed with either an 'a' (for accept) or 'r' (for reject). 26 | # The first expression found to match a device name determines if 27 | # the device will be accepted or rejected (ignored). Devices that 28 | # don't match any patterns are accepted. 29 | 30 | # Be careful if there there are symbolic links or multiple filesystem 31 | # entries for the same device as each name is checked separately against 32 | # the list of patterns. The effect is that if any name matches any 'a' 33 | # pattern, the device is accepted; otherwise if any name matches any 'r' 34 | # pattern it is rejected; otherwise it is accepted. 35 | 36 | # Don't have more than one filter line active at once: only one gets used. 37 | 38 | # Run vgscan after you change this parameter to ensure that 39 | # the cache file gets regenerated (see below). 40 | # If it doesn't do what you expect, check the output of 'vgscan -vvvv'. 41 | 42 | 43 | # By default we accept every block device: 44 | #filter = [ "a/.*/" ] 45 | 46 | # LVM2 must be instructed not to look at the path but only at the multipaths 47 | filter = [ "r/disk/", "r/sd[b-z].*/", "a/.*/" ] 48 | 49 | # Exclude the cdrom drive 50 | # filter = [ "r|/dev/cdrom|" ] 51 | 52 | # When testing I like to work with just loopback devices: 53 | # filter = [ "a/loop/", "r/.*/" ] 54 | 55 | # Or maybe all loops and ide drives except hdc: 56 | # filter =[ "a|loop|", "r|/dev/hdc|", "a|/dev/ide|", "r|.*|" ] 57 | 58 | # Use anchors if you want to be really specific 59 | # filter = [ "a|^/dev/hda8$|", "r/.*/" ] 60 | 61 | # The results of the filtering are cached on disk to avoid 62 | # rescanning dud devices (which can take a very long time). By 63 | # default this cache file is hidden in the /etc/lvm directory. 64 | # It is safe to delete this file: the tools regenerate it. 65 | cache = "/etc/lvm/.cache" 66 | 67 | # You can turn off writing this cache file by setting this to 0. 68 | write_cache_state = 1 69 | 70 | # Advanced settings. 71 | 72 | # List of pairs of additional acceptable block device types found 73 | # in /proc/devices with maximum (non-zero) number of partitions. 74 | # types = [ "fd", 16 ] 75 | 76 | # In order to use a dm-crypt device as an lvm2 pv, 77 | # add this line to the devices block in /etc/lvm/lvm.conf: 78 | types = [ "device-mapper", 1 ] 79 | 80 | # If sysfs is mounted (2.6 kernels) restrict device scanning to 81 | # the block devices it believes are valid. 82 | # 1 enables; 0 disables. 83 | sysfs_scan = 1 84 | 85 | # By default, LVM2 will ignore devices used as components of 86 | # software RAID (md) devices by looking for md superblocks. 87 | # 1 enables; 0 disables. 88 | md_component_detection = 1 89 | } 90 | 91 | # This section that allows you to configure the nature of the 92 | # information that LVM2 reports. 93 | log { 94 | 95 | # Controls the messages sent to stdout or stderr. 96 | # There are three levels of verbosity, 3 being the most verbose. 97 | verbose = 0 98 | 99 | # Should we send log messages through syslog? 100 | # 1 is yes; 0 is no. 101 | syslog = 1 102 | 103 | # Should we log error and debug messages to a file? 104 | # By default there is no log file. 105 | #file = "/var/log/lvm2.log" 106 | 107 | # Should we overwrite the log file each time the program is run? 108 | # By default we append. 109 | overwrite = 0 110 | 111 | # What level of log messages should we send to the log file and/or syslog? 112 | # There are 6 syslog-like log levels currently in use - 2 to 7 inclusive. 113 | # 7 is the most verbose (LOG_DEBUG). 114 | level = 0 115 | 116 | # Format of output messages 117 | # Whether or not (1 or 0) to indent messages according to their severity 118 | indent = 1 119 | 120 | # Whether or not (1 or 0) to display the command name on each line output 121 | command_names = 0 122 | 123 | # A prefix to use before the message text (but after the command name, 124 | # if selected). Default is two spaces, so you can see/grep the severity 125 | # of each message. 126 | prefix = " " 127 | 128 | # To make the messages look similar to the original LVM tools use: 129 | # indent = 0 130 | # command_names = 1 131 | # prefix = " -- " 132 | 133 | # Set this if you want log messages during activation. 134 | # Don't use this in low memory situations (can deadlock). 135 | # activation = 0 136 | } 137 | 138 | # Configuration of metadata backups and archiving. In LVM2 when we 139 | # talk about a 'backup' we mean making a copy of the metadata for the 140 | # *current* system. The 'archive' contains old metadata configurations. 141 | # Backups are stored in a human readeable text format. 142 | backup { 143 | 144 | # Should we maintain a backup of the current metadata configuration ? 145 | # Use 1 for Yes; 0 for No. 146 | # Think very hard before turning this off! 147 | backup = 1 148 | 149 | # Where shall we keep it ? 150 | # Remember to back up this directory regularly! 151 | backup_dir = "/etc/lvm/backup" 152 | 153 | # Should we maintain an archive of old metadata configurations. 154 | # Use 1 for Yes; 0 for No. 155 | # On by default. Think very hard before turning this off. 156 | archive = 1 157 | 158 | # Where should archived files go ? 159 | # Remember to back up this directory regularly! 160 | archive_dir = "/etc/lvm/archive" 161 | 162 | # What is the minimum number of archive files you wish to keep ? 163 | retain_min = 10 164 | 165 | # What is the minimum time you wish to keep an archive file for ? 166 | retain_days = 30 167 | } 168 | 169 | # Settings for the running LVM2 in shell (readline) mode. 170 | shell { 171 | 172 | # Number of lines of history to store in ~/.lvm_history 173 | history_size = 100 174 | } 175 | 176 | 177 | # Miscellaneous global LVM2 settings 178 | global { 179 | 180 | # The file creation mask for any files and directories created. 181 | # Interpreted as octal if the first digit is zero. 182 | umask = 077 183 | 184 | # Allow other users to read the files 185 | #umask = 022 186 | 187 | # Enabling test mode means that no changes to the on disk metadata 188 | # will be made. Equivalent to having the -t option on every 189 | # command. Defaults to off. 190 | test = 0 191 | 192 | # Whether or not to communicate with the kernel device-mapper. 193 | # Set to 0 if you want to use the tools to manipulate LVM metadata 194 | # without activating any logical volumes. 195 | # If the device-mapper kernel driver is not present in your kernel 196 | # setting this to 0 should suppress the error messages. 197 | activation = 1 198 | 199 | # If we can't communicate with device-mapper, should we try running 200 | # the LVM1 tools? 201 | # This option only applies to 2.4 kernels and is provided to help you 202 | # switch between device-mapper kernels and LVM1 kernels. 203 | # The LVM1 tools need to be installed with .lvm1 suffices 204 | # e.g. vgscan.lvm1 and they will stop working after you start using 205 | # the new lvm2 on-disk metadata format. 206 | # The default value is set when the tools are built. 207 | # fallback_to_lvm1 = 0 208 | 209 | # The default metadata format that commands should use - "lvm1" or "lvm2". 210 | # The command line override is -M1 or -M2. 211 | # Defaults to "lvm1" if compiled in, else "lvm2". 212 | # format = "lvm1" 213 | 214 | # Location of proc filesystem 215 | proc = "/proc" 216 | 217 | # Type of locking to use. Defaults to local file-based locking (1). 218 | # Turn locking off by setting to 0 (dangerous: risks metadata corruption 219 | # if LVM2 commands get run concurrently). 220 | # Type 2 uses the external shared library locking_library. 221 | # Type 3 uses built-in clustered locking. 222 | locking_type = 1 223 | 224 | # If using external locking (type 2) and initialisation fails, 225 | # with this set to 1 an attempt will be made to use the built-in 226 | # clustered locking. 227 | # If you are using a customised locking_library you should set this to 0. 228 | fallback_to_clustered_locking = 1 229 | 230 | # If an attempt to initialise type 2 or type 3 locking failed, perhaps 231 | # because cluster components such as clvmd are not running, with this set 232 | # to 1 an attempt will be made to use local file-based locking (type 1). 233 | # If this succeeds, only commands against local volume groups will proceed. 234 | # Volume Groups marked as clustered will be ignored. 235 | fallback_to_local_locking = 1 236 | 237 | # Local non-LV directory that holds file-based locks while commands are 238 | # in progress. A directory like /tmp that may get wiped on reboot is OK. 239 | locking_dir = "/var/lock/lvm" 240 | 241 | # Other entries can go here to allow you to load shared libraries 242 | # e.g. if support for LVM1 metadata was compiled as a shared library use 243 | # format_libraries = "liblvm2format1.so" 244 | # Full pathnames can be given. 245 | 246 | # Search this directory first for shared libraries. 247 | # library_dir = "/lib" 248 | 249 | # The external locking library to load if locking_type is set to 2. 250 | # locking_library = "liblvm2clusterlock.so" 251 | } 252 | 253 | activation { 254 | # Device used in place of missing stripes if activating incomplete volume. 255 | # For now, you need to set this up yourself first (e.g. with 'dmsetup') 256 | # For example, you could make it return I/O errors using the 'error' 257 | # target or make it return zeros. 258 | missing_stripe_filler = "/dev/ioerror" 259 | 260 | # How much stack (in KB) to reserve for use while devices suspended 261 | reserved_stack = 256 262 | 263 | # How much memory (in KB) to reserve for use while devices suspended 264 | reserved_memory = 8192 265 | 266 | # Nice value used while devices suspended 267 | process_priority = -18 268 | 269 | # If volume_list is defined, each LV is only activated if there is a 270 | # match against the list. 271 | # "vgname" and "vgname/lvname" are matched exactly. 272 | # "@tag" matches any tag set in the LV or VG. 273 | # "@*" matches if any tag defined on the host is also set in the LV or VG 274 | # 275 | # volume_list = [ "vg1", "vg2/lvol1", "@tag1", "@*" ] 276 | 277 | # Size (in KB) of each copy operation when mirroring 278 | mirror_region_size = 512 279 | 280 | # 'mirror_image_fault_policy' and 'mirror_log_fault_policy' define 281 | # how a device failure affecting a mirror is handled. 282 | # A mirror is composed of mirror images (copies) and a log. 283 | # A disk log ensures that a mirror does not need to be re-synced 284 | # (all copies made the same) every time a machine reboots or crashes. 285 | # 286 | # In the event of a failure, the specified policy will be used to 287 | # determine what happens: 288 | # 289 | # "remove" - Simply remove the faulty device and run without it. If 290 | # the log device fails, the mirror would convert to using 291 | # an in-memory log. This means the mirror will not 292 | # remember its sync status across crashes/reboots and 293 | # the entire mirror will be re-synced. If a 294 | # mirror image fails, the mirror will convert to a 295 | # non-mirrored device if there is only one remaining good 296 | # copy. 297 | # 298 | # "allocate" - Remove the faulty device and try to allocate space on 299 | # a new device to be a replacement for the failed device. 300 | # Using this policy for the log is fast and maintains the 301 | # ability to remember sync state through crashes/reboots. 302 | # Using this policy for a mirror device is slow, as it 303 | # requires the mirror to resynchronize the devices, but it 304 | # will preserve the mirror characteristic of the device. 305 | # This policy acts like "remove" if no suitable device and 306 | # space can be allocated for the replacement. 307 | # Currently this is not implemented properly and behaves 308 | # similarly to: 309 | # 310 | # "allocate_anywhere" - Operates like "allocate", but it does not 311 | # require that the new space being allocated be on a 312 | # device is not part of the mirror. For a log device 313 | # failure, this could mean that the log is allocated on 314 | # the same device as a mirror device. For a mirror 315 | # device, this could mean that the mirror device is 316 | # allocated on the same device as another mirror device. 317 | # This policy would not be wise for mirror devices 318 | # because it would break the redundant nature of the 319 | # mirror. This policy acts like "remove" if no suitable 320 | # device and space can be allocated for the replacement. 321 | 322 | mirror_log_fault_policy = "allocate" 323 | mirror_device_fault_policy = "remove" 324 | } 325 | 326 | 327 | #################### 328 | # Advanced section # 329 | #################### 330 | 331 | # Metadata settings 332 | # 333 | # metadata { 334 | # Default number of copies of metadata to hold on each PV. 0, 1 or 2. 335 | # You might want to override it from the command line with 0 336 | # when running pvcreate on new PVs which are to be added to large VGs. 337 | 338 | # pvmetadatacopies = 1 339 | 340 | # Approximate default size of on-disk metadata areas in sectors. 341 | # You should increase this if you have large volume groups or 342 | # you want to retain a large on-disk history of your metadata changes. 343 | 344 | # pvmetadatasize = 255 345 | 346 | # List of directories holding live copies of text format metadata. 347 | # These directories must not be on logical volumes! 348 | # It's possible to use LVM2 with a couple of directories here, 349 | # preferably on different (non-LV) filesystems, and with no other 350 | # on-disk metadata (pvmetadatacopies = 0). Or this can be in 351 | # addition to on-disk metadata areas. 352 | # The feature was originally added to simplify testing and is not 353 | # supported under low memory situations - the machine could lock up. 354 | # 355 | # Never edit any files in these directories by hand unless you 356 | # you are absolutely sure you know what you are doing! Use 357 | # the supplied toolset to make changes (e.g. vgcfgrestore). 358 | 359 | # dirs = [ "/etc/lvm/metadata", "/mnt/disk2/lvm/metadata2" ] 360 | #} 361 | 362 | # Event daemon 363 | # 364 | # dmeventd { 365 | # mirror_library is the library used when monitoring a mirror device. 366 | # 367 | # "libdevmapper-event-lvm2mirror.so" attempts to recover from failures. 368 | # It removes failed devices from a volume group and reconfigures a 369 | # mirror as necessary. 370 | # 371 | # mirror_library = "libdevmapper-event-lvm2mirror.so" 372 | #} 373 | 374 | -------------------------------------------------------------------------------- /md3000/files/minirc.dfl: -------------------------------------------------------------------------------- 1 | # Machine-generated file - use "minicom -s" to change parameters. 2 | pr port /dev/ttyS0 3 | pu baudrate 115200 4 | pu bits 8 5 | pu parity N 6 | pu stopbits 1 7 | pu rtscts No 8 | -------------------------------------------------------------------------------- /md3000/files/multipath.conf: -------------------------------------------------------------------------------- 1 | ################################################ 2 | # # 3 | # THIS FILE IS MANAGED BY PUPPET. DO NOT EDIT! # 4 | # # 5 | ################################################ 6 | 7 | # This is an example configuration file for device mapper multipath. 8 | # For a complete list of the default configuration values, see 9 | # /usr/share/doc/device-mapper-multipath-0.4.5/multipath.conf.defaults 10 | # For a list of configuration options with descriptions, see 11 | # /usr/share/doc/device-mapper-multipath-0.4.5/multipath.conf.annotated 12 | 13 | 14 | # Blacklist all devices by default. Remove this to enable multipathing 15 | # on the default devices. 16 | #blacklist { 17 | #devnode "*" 18 | #} 19 | 20 | ## By default, devices with vendor = "IBM" and product = "S/390.*" are 21 | ## blacklisted. To enable mulitpathing on these devies, uncomment the 22 | ## following lines. 23 | #blacklist_exceptions { 24 | # device { 25 | # vendor "IBM" 26 | # product "S/390.*" 27 | # } 28 | #} 29 | 30 | ## Use user friendly names, instead of using WWIDs as names. 31 | #defaults { 32 | #user_friendly_names yes 33 | #} 34 | ## 35 | ## This is a template multipath-tools configuration file 36 | ## Uncomment the lines relevent to your environment 37 | ## 38 | #defaults { 39 | # udev_dir /dev 40 | # polling_interval 10 41 | # selector "round-robin 0" 42 | # path_grouping_policy multibus 43 | # getuid_callout "/sbin/scsi_id -g -u -s /block/%n" 44 | # prio_callout /bin/true 45 | # path_checker readsector0 46 | # rr_min_io 100 47 | # rr_weight priorities 48 | # failback immediate 49 | # no_path_retry fail 50 | # user_friendly_name yes 51 | #} 52 | ## 53 | ## The wwid line in the following blacklist section is shown as an example 54 | ## of how to blacklist devices by wwid. The 3 devnode lines are the 55 | ## compiled in default blacklist. If you want to blacklist entire types 56 | ## of devices, such as all scsi devices, you should use a devnode line. 57 | ## However, if you want to blacklist specific devices, you should use 58 | ## a wwid line. Since there is no guarantee that a specific device will 59 | ## not change names on reboot (from /dev/sda to /dev/sdb for example) 60 | ## devnode lines are not recommended for blacklisting specific devices. 61 | ## 62 | #blacklist { 63 | # wwid 26353900f02796769 64 | # devnode "^(ram|raw|loop|fd|md|dm-|sr|scd|st)[0-9]*" 65 | # devnode "^hd[a-z]" 66 | #} 67 | #multipaths { 68 | # multipath { 69 | # wwid 3600508b4000156d700012000000b0000 70 | # alias yellow 71 | # path_grouping_policy multibus 72 | # path_checker readsector0 73 | # path_selector "round-robin 0" 74 | # failback manual 75 | # rr_weight priorities 76 | # no_path_retry 5 77 | # } 78 | # multipath { 79 | # wwid 1DEC_____321816758474 80 | # alias red 81 | # } 82 | #} 83 | #devices { 84 | # device { 85 | # vendor "COMPAQ " 86 | # product "HSV110 (C)COMPAQ" 87 | # path_grouping_policy multibus 88 | # getuid_callout "/sbin/scsi_id -g -u -s /block/%n" 89 | # path_checker readsector0 90 | # path_selector "round-robin 0" 91 | # hardware_handler "0" 92 | # failback 15 93 | # rr_weight priorities 94 | # no_path_retry queue 95 | # } 96 | # device { 97 | # vendor "COMPAQ " 98 | # product "MSA1000 " 99 | # path_grouping_policy multibus 100 | # } 101 | #} 102 | defaults { 103 | user_friendly_names yes 104 | polling_interval 1 105 | udev_dir /dev 106 | no_path_retry 5 107 | } 108 | 109 | blacklist { 110 | devnode "^(ram|raw|loop|fd|md|sr|scd|st)[0-9]*" 111 | devnode "^hd[a-z][[0-9]*]" 112 | device { 113 | vendor "D(ELL|ell).*" 114 | product "(Universal|Virtual|PERC 5/i).*" 115 | } 116 | } 117 | 118 | devices { 119 | device { 120 | vendor "DELL" 121 | product "MD3000" 122 | getuid_callout "/sbin/scsi_id -g -u -s /block/%n" 123 | prio_callout "/sbin/mpath_prio_rdac /dev/%n" 124 | features "0" 125 | hardware_handler "1 rdac" 126 | path_grouping_policy group_by_prio 127 | failback immediate 128 | path_checker rdac 129 | } 130 | } 131 | -------------------------------------------------------------------------------- /md3000/manifests/init.pp: -------------------------------------------------------------------------------- 1 | class md3000 { 2 | 3 | case $operatingsystem { 4 | centos: { 5 | $osver = "el5" 6 | $kerneldev = "kernel-PAE-devel" 7 | $provider = "yum" 8 | Package { require => [Yumrepo["sans"], Yumrepo["base"]] } 9 | } 10 | redhat: { 11 | $osver = "el${redhatrelease}" 12 | $kerneldev = ["kernel-devel", "kernel-smp-devel"] 13 | $provider = "up2date" 14 | Package { 15 | require => File["/etc/sysconfig/rhn/up2date"] 16 | 17 | # comment out the above and uncomment the following when the 18 | # sans-el4 repo is fully functional and ready. 19 | #require => [ 20 | # Yumrepo["sans-el4"], 21 | # File["/etc/sysconfig/rhn/up2date"] 22 | #] 23 | } 24 | } 25 | } 26 | 27 | include md3000::devel 28 | include md3000::admin 29 | 30 | } 31 | 32 | class md3000::devel { 33 | 34 | # Get the appropriate dev packages installed. 35 | 36 | package { $kerneldev: 37 | ensure => installed, 38 | provider => $provider 39 | } 40 | 41 | package { "gcc": ensure => installed, } 42 | 43 | } 44 | 45 | class md3000::admin { 46 | 47 | # Install packages to administer the disk array. 48 | 49 | # minicom to provide access to the RAID controllers via serial password 50 | # reset cable. 51 | 52 | package { "minicom": ensure => installed, } 53 | 54 | file { "/etc/minirc.dfl": 55 | source => "puppet:///md3000/minirc.dfl", 56 | require => Package["minicom"], 57 | } 58 | 59 | # MD Storage Manager. 60 | 61 | package { ["SMagent", "SMruntime", "SMutil", "SMclient"]: 62 | ensure => installed, 63 | provider => yum, 64 | require => Yumrepo["sans"], 65 | } 66 | 67 | } 68 | 69 | # Use this class on systems utilizing the device mapper multipath driver for 70 | # multipath support. Do not use on systems utilizing MPP. 71 | class md3000::multipath { 72 | package { ["device-mapper-multipath", "kpartx"]: 73 | ensure => installed, 74 | } 75 | file { "/etc/multipath.conf": 76 | source => "puppet:///md3000/multipath.conf", 77 | require => Package["device-mapper-multipath"], 78 | } 79 | file { "/etc/lvm/lvm.conf": 80 | source => "puppet:///md3000/lvm.conf", 81 | require => Package["device-mapper-multipath"], 82 | } 83 | service { "multipathd": 84 | ensure => running, 85 | enable => true, 86 | hasrestart => true, 87 | hasstatus => true, 88 | subscribe => File["/etc/multipath.conf"], 89 | require => Package["device-mapper-multipath"], 90 | } 91 | } 92 | 93 | # md3000::driver defined type installs the proper HBA and multipath drivers 94 | # for RDAC MPP. 95 | # 96 | # Variables used: 97 | # $osver: Dell names directories rh#. This may not be needed when the md3000 98 | # rpms are available through yum. 99 | # $ensure: whether to install the drivers. Default is present. 100 | # $mptlinux: The specific version of the mptlinux package to install. 101 | # $linuxrdac: The specific version of the linuxrdac package to install. 102 | # The mptlinux and linuxrdac packages require specific parameters passed to 103 | # the dkms build and install commands in order to get the modules built for 104 | # the current running kernel. 105 | # 106 | # Example usage: 107 | # md3000::driver { 108 | # osver => "rh4", 109 | # mptlinux => "4.00.07.00-2dkms", 110 | # linuxrdac => "09.01.C6.06b-1dkms", 111 | # } 112 | 113 | #define md3000::driver ( 114 | # $osver = 'rh5', 115 | # $ensure = 'present', 116 | # $mptlinux, $linuxrdac 117 | #){ 118 | # 119 | #} 120 | # vi:syntax=puppet:filetype=puppet:ts=4:et: 121 | -------------------------------------------------------------------------------- /network/manifests/init.pp: -------------------------------------------------------------------------------- 1 | # networking defined type controls the /etc/sysconfig/network file. 2 | # Most of the work is handled with ruby logic in the template. If the 3 | # gwdev variable is set, the gateway variable needs to be set as well. 4 | # This will set the default gateway device for all interfaces. 5 | # $name is not used, it merely identifies the resource uniquely. 6 | # 7 | # Update: Added support for openbsd's /etc/mygate which has the contents 8 | # of the default gateway IP. 9 | # 10 | # Variables used: 11 | # $gw: default gateway IP for all interfaces. Specify a valid IP address. 12 | # This is optional. 13 | # $gwdev: default gateway device to use. Specify the device name to use, 14 | # eg, 'eth0' or 'bond0'. This is optional. 15 | # $ensure: whether networking is set up on this system. Valid values are 16 | # 'present' or 'absent'. This setting defaults to 'present'. 17 | # 18 | # Example: 19 | # networking { "network-${hostname}": 20 | # ensure => present, 21 | # gwdev => "eth0", 22 | # gw => "10.1.0.1", 23 | # } 24 | 25 | define networking ($gw = '', $gwdev = '', $ensure = 'present') { 26 | case $operatingsystem { 27 | centos,redhat: { 28 | $netstate = $ensure 29 | file { "/etc/sysconfig/network": 30 | content => template("network/network.erb"), 31 | } 32 | } 33 | openbsd: { 34 | file { "/etc/mygate": 35 | content => "${gw}\n", 36 | } 37 | } 38 | } 39 | } 40 | 41 | # netiface defined type controls the networking interface files in 42 | # /etc/sysconfig/network-scripts/ifcfg-*. It can handle normal, bonded, 43 | # alias, slaves or 'up' interfaces for use on SPAN ports. 44 | # 45 | # Variables used: 46 | # $ensure: Whether this interface is configured at boot or not. For aliases, 47 | # whether the alias is brought up with the parent interface or not. Valid 48 | # values are 'present' or 'absent'. Default is present. 49 | # $ifnum: Used for aliases to set the 'number' of the alias. For example, 50 | # if interface is eth0, set ifnum to 0 for eth0:0. 51 | # $bondopts: Set options for the bonding module. For more information, see 52 | # Red Hat 5.1 Deployment Guide, 41.5.2.1. bonding Module Directives. 53 | # $interface: The actual interface device. For example, eth0, eth1, bond0. 54 | # Do not use "eth0:0" for aliases. Instead specify the interface device 55 | # here and use $ifnum for the number of the alias. 56 | # $interface_type: Interface 'type'. Valid values are bond, alias, slave 57 | # and tap. Anything else is considered a 'normal' interface, which is the 58 | # default. 59 | # $netmask: Specify the interface netmask. This doesn't do error detection 60 | # so make sure your mask is correct for the network! 61 | # $master: For slave interface types, specify the interface of the master. 62 | # the master interface doesn't have to be created first. 63 | # $name: By default, the $name will be the IP address to use for the interface. 64 | # tap and slave devices do not have an IP address assigned, so use something 65 | # to uniquely identify those interfaces. 66 | # 67 | # Example normal: 68 | # $interface_type is not set, so assume 'normal'. 69 | # netiface { "10.1.0.170": 70 | # interface => "eth0", 71 | # netmask => "255.255.255.0", 72 | # } 73 | # 74 | # Example bonded: 75 | # Sets up a bonded interface. Don't forget to create the slave resources. 76 | # netiface { "10.1.0.170": 77 | # bondopts => "mode=balance-rr miimon=100", 78 | # interface => "bond0", 79 | # interface_type => "bond", 80 | # netmask => "255.255.255.0", 81 | # } 82 | # 83 | # Example alias: 84 | # The device created here will be bond0:0 ($interface:$ifnum). 85 | # netiface { "10.1.0.171": 86 | # interface => "bond0", 87 | # interface_type => "alias", 88 | # ifnum => "0", 89 | # netmask => "255.255.255.0", 90 | # } 91 | # 92 | # Example slave: 93 | # This is used for interfaces that are slaved to a bonded interface. 94 | # netiface { "eth0": 95 | # interface => "eth0", 96 | # interface_type => "slave", 97 | # master => "bond0", 98 | # } 99 | # 100 | # Example "up" or "tap": 101 | # This is used for interfaces that are listening on "SPAN" ports, ie, IDS. 102 | # netiface { "${hostname}-eth5-up": 103 | # interface => "eth5", 104 | # interface_type => "tap", 105 | # } 106 | define netiface ( 107 | $ensure = 'present', $ifnum = '', $bondopts = '', $interface, 108 | $interface_type = 'normal', $netmask = '255.255.255.0', $master = '' 109 | ) { 110 | $ifstate = $ensure 111 | case $interface_type { 112 | "alias": { 113 | file { "/etc/sysconfig/network-scripts/ifcfg-${interface}:${ifnum}": 114 | content => template("network/ifcfg.erb") 115 | } 116 | } 117 | "bond": { 118 | file { "/etc/sysconfig/network-scripts/ifcfg-${interface}": 119 | content => template("network/ifcfg.erb") 120 | } 121 | line { "modprobe-${hostname}-${interface}": 122 | file => "/etc/modprobe.conf", 123 | line => "alias ${interface} bonding # ${hostname}-${interface}", 124 | } 125 | } 126 | default: { 127 | file { "/etc/sysconfig/network-scripts/ifcfg-${interface}": 128 | content => template("network/ifcfg.erb") 129 | } 130 | if $bondopts { 131 | line { "modprobe-${hostname}-${interface}": 132 | file => "/etc/modprobe.conf", 133 | line => "alias ${interface} bonding # ${hostname}-${interface}", 134 | } 135 | } 136 | } 137 | } 138 | } 139 | 140 | # similar to the netiface above but specifically for trunk ports on OpenBSD. 141 | # Variables: 142 | # $interface: Specify the trunk# interface to use. 143 | # $trunkports: "Slave" trunkport interfaces used by the trunk. Specify as an 144 | # array. This will call the netiface::trunk::ports defined type to set up 145 | # the hostname.$trunkport interface files. 146 | # $trunkproto: Specify the trunk protocol used. Valid values are failover, 147 | # roundrobin, loadbalance, none per trunk man page. Default is failover. 148 | # $ip: Specify the IP address for the interface. 149 | # $netmask: Specify the netmask for the interface. Default is 255.255.255.0. 150 | # $bcast: Specify the broadcast if required, otherwise use NONE to have 151 | # BSD automatically detect the required broadcast. Default is NONE. 152 | # $routes: See below for detail. 153 | # 154 | # To add static routes for the interface, specify the routes as destination 155 | # and gateway pairs, as an array. The template will handle the rest. 156 | # 157 | # $routes = ["10.1.32.0/24 10.1.16.254", "10.1.48.0/24 10.1.16.254"] 158 | # $routes = $perimeter ? { # set $perimeter in the node context. 159 | # 'ext' => ["10.1.32.0/24 10.1.16.254", "10.1.48.0/24 10.1.16.254"], 160 | # 'int' => '' # or something else entirely as needed. 161 | # } 162 | # 163 | # Example usage: 164 | # netiface::trunk { "${hostname}-trunk0": 165 | # interface => "trunk0", 166 | # trunkports => ["em0", "em4"], 167 | # ip => "10.0.0.1", 168 | # } 169 | 170 | define netiface::trunk ($interface, $trunkports, $trunkproto = 'failover', 171 | $ip, $netmask = '255.255.255.0', $bcast = 'NONE', $routes = false) { 172 | file { "/etc/hostname.${interface}": 173 | content => template("network/hostname.trunk.erb"), 174 | } 175 | netiface::trunk::ports { $trunkports: } 176 | } 177 | # "slave" interfaces - trunkports for the trunk interface above. 178 | # See comments for netiface::trunk regarding trunk::ports. 179 | define netiface::trunk::ports () { 180 | file { "/etc/hostname.${name}": 181 | content => "up\n", 182 | } 183 | } 184 | 185 | # set up carp interfaces on bsd. 186 | # See man page for carp for more details on settings. 187 | # Variables: 188 | # $interface: Specify the carp# interface to use. 189 | # $aliases: Array of aliases bound to the carp interface shared by the 190 | # master and slave systems. 191 | # $ip: Specify the IP address for the interface. This is the same for all 192 | # hosts using this carp interface. 193 | # $netmask: Netmask required. Default is 255.255.255.0. 194 | # $bcast: Specify the broadcast if required, otherwise use NONE to have 195 | # BSD automatically detect the required broadcast. Default is NONE. 196 | # $vhid: Virtual host identifier, must be unique for each carp interface. 197 | # $pass: Passphrase required to connect to other carp hosts. 198 | # $advskew: Offset used for the carp timeout. Should be different for each 199 | # system that uses this carp interface. See man page. 200 | # 201 | # Example usage: 202 | # netiface::carp { "${hostname}-carp0": 203 | # interface => "carp0", 204 | # ip => "10.0.0.1", 205 | # aliases => ["10.0.0.100", "10.0.0.200"], 206 | # vhid => "1", 207 | # pass => 'P@ssPhra53!', 208 | # advskew => "1", 209 | # } 210 | 211 | define netiface::carp ($interface, $aliases = '', $ip, 212 | $netmask = '255.255.255.0', $bcast = 'NONE', $vhid, $pass, $advskew, $ifgroup = 'internalfw') { 213 | file { "/etc/hostname.${interface}": 214 | content => template("network/hostname.carp.erb"), 215 | } 216 | } 217 | 218 | # route defined type adds a static route to the static routes file, 219 | # /etc/sysconfig/network-scripts/route-$interface. This uses the append_line 220 | # defined type. 221 | # 222 | # Variables used: 223 | # $device: The interface this route is used on. Required. 224 | # $destination: The destination host or network, specify "default" for the 225 | # default route. Required. 226 | # $gateway: The gateway to the destination. Required. 227 | # 228 | # Example: 229 | # 230 | # route { "${hostname}-bond0-0": 231 | # device => "bond0", 232 | # destination => "default", 233 | # gateway => "10.1.0.254", 234 | # } 235 | # route { "${hostname}-bond0-1": 236 | # device => "bond0", 237 | # destination => "10.1.0.0/24", 238 | # gateway => "10.1.0.254", 239 | # } 240 | 241 | define route ($device, $destination, $gateway) { 242 | line { "route-${name}": 243 | file => "/etc/sysconfig/network-scripts/route-${device}", 244 | line => "${destination} via ${gateway} dev ${device}", 245 | } 246 | } 247 | # As above, but for trunk interfaces on OpenBSD. 248 | # This define appends the line to the trunk device file. 249 | define route::trunk ($device, $destination, $gateway) { 250 | line { "route-${name}": 251 | file => "/etc/hostname.${device}", 252 | line => "! route -qn add -net $destination $gateway", 253 | require => File["/etc/hostname.${device}"], 254 | } 255 | } 256 | 257 | # vim modeline - have 'set modeline' and 'syntax on' in your ~/.vimrc. 258 | # vi:syntax=puppet:filetype=puppet:ts=4:et: 259 | # EOF 260 | -------------------------------------------------------------------------------- /network/templates/hostname.carp.erb: -------------------------------------------------------------------------------- 1 | ################################################ 2 | # # 3 | # THIS FILE IS MANAGED BY PUPPET. DO NOT EDIT! # 4 | # # 5 | ################################################ 6 | inet <%= ip %> <%= netmask %> <%= bcast %> vhid <%= vhid %> pass <%= pass %> advskew <%= advskew %> group <%= ifgroup %> 7 | <% if ifgroup == 'externalfw' && /^10\./.match(ip) == nil 8 | iplist = (4..251).to_a.collect! {|i| /(\d{1,3}\.\d{1,3}\.\d{1,3}\.)\d{1,3}/.match(ip)[1] + i.to_s} 9 | elsif ifgroup == 'internalfw' 10 | iplist = aliases 11 | else 12 | iplist = '' 13 | end -%> 14 | <% iplist.each do |a| %>inet alias <%= a %> 255.255.255.255 15 | <% end -%> 16 | -------------------------------------------------------------------------------- /network/templates/hostname.trunk.erb: -------------------------------------------------------------------------------- 1 | ################################################ 2 | # # 3 | # THIS FILE IS MANAGED BY PUPPET. DO NOT EDIT! # 4 | # # 5 | ################################################ 6 | trunkproto <%= trunkproto %> <% trunkports.each do |tp| %> trunkport <%= tp %><% end %> 7 | inet <%= ip %> <%= netmask %> <%= bcast %> 8 | <% if routes -%> 9 | <% routes.each do |route| %>! route -qn add -net <%= route %> 10 | <% end -%> 11 | <% end -%> 12 | -------------------------------------------------------------------------------- /network/templates/ifcfg.erb: -------------------------------------------------------------------------------- 1 | ################################################ 2 | # # 3 | # THIS FILE IS MANAGED BY PUPPET. DO NOT EDIT! # 4 | # # 5 | ################################################ 6 | <% if interface_type == 'alias' -%> 7 | DEVICE=<%= interface %>:<%= ifnum %> 8 | <% if ifstate == 'present' -%> 9 | ONPARENT=yes 10 | <% elsif ifstate == 'absent' -%> 11 | ONPARENT=no 12 | <% end -%> 13 | <% else -%> 14 | DEVICE=<%= interface %> 15 | <% if ifstate == 'present' -%> 16 | ONBOOT=yes 17 | <% elsif ifstate == 'absent' -%> 18 | ONBOOT=no 19 | <% end -%> 20 | <% end -%> 21 | <% if interface_type != 'tap' && interface_type != 'slave' -%> 22 | <% if name.match(/^\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}$/) -%> 23 | IPADDR=<%= name %> 24 | NETMASK=<%= netmask %> 25 | <% end -%> 26 | <% end -%> 27 | <% if bondopts != '' && (interface_type == 'bond' || interface_type == 'tap') -%> 28 | BONDING_OPTS="<%= bondopts %>" 29 | <% end -%> 30 | <% if interface_type == 'slave' -%> 31 | MASTER=<%= master %> 32 | SLAVE=yes 33 | <% end -%> 34 | BOOTPROTO=none 35 | USERCTL=no 36 | -------------------------------------------------------------------------------- /network/templates/network.erb: -------------------------------------------------------------------------------- 1 | ################################################ 2 | # # 3 | # THIS FILE IS MANAGED BY PUPPET. DO NOT EDIT! # 4 | # # 5 | ################################################ 6 | <%if netstate == 'present' -%> 7 | NETWORKING=yes 8 | <% elsif netstate == 'absent' -%> 9 | NETWORKING=no 10 | <% end -%> 11 | NETWORKING_IPV6=no 12 | HOSTNAME=<%= fqdn %> 13 | NOZEROCONF=yes 14 | <% if gwdev != '' -%> 15 | GATEWAY=<%= gw %> 16 | GATEWAYDEV=<%= gwdev %> 17 | <% end -%> 18 | -------------------------------------------------------------------------------- /pmwiki/files/htaccess: -------------------------------------------------------------------------------- 1 | # Use mod_rewrite to enable "Clean URLs" for a PmWiki installation. 2 | RewriteEngine On 3 | # Define the rewrite base. 4 | RewriteBase / 5 | # Send requests without parameters to pmwiki.php. 6 | RewriteRule ^$ pmwiki.php [L] 7 | # Send requests for index.php to pmwiki.php. 8 | RewriteRule ^index\.php$ pmwiki.php [L] 9 | RewriteRule ^index\.html$ pmwiki.php [L] 10 | # Send requests to pmwiki.php, appending the query string part. 11 | RewriteRule ^([A-Z0-9\xa0-\xff].*)$ pmwiki.php?n=$1 [QSA,L] 12 | -------------------------------------------------------------------------------- /pmwiki/files/rsync-pmwiki: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | dest=$1 4 | dir=$2 5 | 6 | PATH="/bin:/usr/bin:/sbin:/usr/sbin:/usr/local/bin:/usr/local/sbin" 7 | 8 | rsync -cavz --delete --safe-links ${dir}/ ${dest}:${dir} 2>/dev/null 9 | -------------------------------------------------------------------------------- /pmwiki/manifests/init.pp: -------------------------------------------------------------------------------- 1 | # define pmwiki sets up a pmwiki instance in the specified directory. 2 | # This resource assumes Apache and Httpd configuration as well. 3 | # 4 | # Variables used: 5 | # 6 | # $docroot: The DocumentRoot from the VirtualHost. 7 | # $group: Group owner of the directories and files. 8 | # $path: Path on the download server where we get pmwiki tarball from. 9 | # $server: Web/FTP server where the pmwiki tarball is located. 10 | # $version: Version of PmWiki to install. 11 | # 12 | # Example usage: 13 | # pmwiki { "${hostname}-pmwiki": 14 | # docroot => "/srv/www/pmwiki", 15 | # group => "htdocs", 16 | # path => "pub/pmwiki", 17 | # server => "www.pmwiki.org", 18 | # version => "2.2.0-beta65", 19 | # } 20 | 21 | define pmwiki ( 22 | $docroot = '/srv/www/pmwiki', 23 | $group = 'htdocs', 24 | $path = 'pub/pmwiki', 25 | $server = 'puppet', 26 | $version = '' 27 | ) { 28 | 29 | Exec { 30 | path => "/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin", 31 | cwd => "/srv/www", 32 | require => File["/srv/www"], 33 | } 34 | 35 | File { 36 | owner => "root", 37 | group => "${group}", 38 | } 39 | 40 | exec { 41 | "wget-pmwiki": 42 | command => "wget http://${server}/${path}/pmwiki-${version}.tgz", 43 | creates => "${docroot}-${version}.tgz"; 44 | 45 | "untar-pmwiki": 46 | command => "tar --group ${group} -zxf ${docroot}-${version}.tgz", 47 | unless => "test -d ${docroot}-${version}", 48 | require => Exec["wget-pmwiki"]; 49 | } 50 | 51 | file { 52 | "${docroot}-${version}": 53 | recurse => true, 54 | require => Exec["untar-pmwiki"]; 55 | 56 | "${docroot}": 57 | ensure => "${docroot}-${version}", 58 | require => File["${docroot}-${version}"]; 59 | 60 | ["${docroot}/wiki.d", "${docroot}/uploads"]: 61 | ensure => directory, 62 | mode => "2775", 63 | require => File["${docroot}"]; 64 | 65 | "${docroot}/index.php": 66 | content => " File["${docroot}"]; 68 | 69 | "${docroot}/.htaccess": 70 | mode => "644", 71 | source => "puppet:///pmwiki/htaccess", 72 | require => File["${docroot}"]; 73 | } 74 | } 75 | 76 | # define pmwiki::sync sets up the script and cron entry to copy the 77 | # pmwiki directory tree via rsync from one node to the other. 78 | # 79 | # Variables used: 80 | # $dest: Destination node, passed to the rsync script in cron entry. 81 | # $dir: Directory to copy, passed to the rsync script in cron entry. 82 | # 83 | # Example usage: 84 | # pmwiki::sync { "${hostname}": 85 | # dest => "web1f", 86 | # dir => "/srv/www/pmwiki", 87 | # } 88 | define pmwiki::sync ($dest = '', $dir = '') { 89 | file { "/usr/local/bin/rsync-pmwiki": 90 | ensure => present, 91 | mode => 0755, 92 | source => "puppet:///pmwiki/rsync-pmwiki", 93 | } 94 | cron { "rsync-pmwiki": 95 | command => "/usr/local/bin/rsync-pmwiki ${dest} ${dir}", 96 | minute => "*/15", 97 | } 98 | } 99 | # vi:syntax=puppet:filetype=puppet:ts=4:et: 100 | # EOF 101 | -------------------------------------------------------------------------------- /selinux/files/apache.te: -------------------------------------------------------------------------------- 1 | module apache 1.0.8; 2 | 3 | require { 4 | class capability { sys_admin sys_resource }; 5 | class file { append execmod execute execute_no_trans getattr ioctl read unlink write }; 6 | class lnk_file { getattr read }; 7 | class process execheap; 8 | class tcp_socket name_connect; 9 | type default_t; 10 | type home_root_t; 11 | type hostname_exec_t; 12 | type httpd_log_t; 13 | type httpd_sys_script_t; 14 | type httpd_t; 15 | type httpd_tmp_t; 16 | type java_exec_t; 17 | type lib_t; 18 | type usr_t; 19 | type mysqld_port_t; 20 | type setfiles_t; 21 | type tmp_t; 22 | type unconfined_t; 23 | role system_r; 24 | type user_home_t; 25 | type user_home_dir_t; 26 | }; 27 | 28 | allow httpd_t default_t:lnk_file { getattr read }; 29 | allow httpd_t home_root_t:lnk_file { getattr read }; 30 | allow httpd_t hostname_exec_t:file { execute execute_no_trans getattr read }; 31 | allow httpd_t httpd_log_t:file { unlink write }; 32 | allow httpd_t mysqld_port_t:tcp_socket name_connect; 33 | allow httpd_t self:capability { sys_admin sys_resource }; 34 | allow httpd_t self:process execheap; 35 | allow httpd_t user_home_t:file { append execute execute_no_trans getattr ioctl read }; 36 | allow httpd_t user_home_dir_t:file { append getattr }; 37 | allow httpd_t usr_t:file execute_no_trans; 38 | allow httpd_t java_exec_t:file { read getattr execute_no_trans execute }; 39 | allow httpd_sys_script_t default_t:lnk_file read; 40 | allow httpd_sys_script_t httpd_tmp_t:file { read write }; 41 | allow setfiles_t tmp_t:file { read write }; 42 | allow unconfined_t lib_t:file execmod; 43 | -------------------------------------------------------------------------------- /selinux/files/base.te: -------------------------------------------------------------------------------- 1 | module base 1.0.0; 2 | 3 | require { 4 | class file write; 5 | type selinux_config_t; 6 | type semanage_t; 7 | type setfiles_t; 8 | type tmp_t; 9 | role system_r; 10 | }; 11 | 12 | allow semanage_t tmp_t:file write; 13 | allow setfiles_t selinux_config_t:file write; 14 | -------------------------------------------------------------------------------- /selinux/files/cronolog.te: -------------------------------------------------------------------------------- 1 | module cronolog 1.0.1; 2 | 3 | require { 4 | class lnk_file { create unlink }; 5 | type httpd_log_t; 6 | type httpd_t; 7 | role system_r; 8 | }; 9 | 10 | allow httpd_t httpd_log_t:lnk_file { create unlink }; 11 | -------------------------------------------------------------------------------- /selinux/files/logsurfer.te: -------------------------------------------------------------------------------- 1 | module logsurfer 1.0.13; 2 | 3 | require { 4 | class dir { add_name remove_name search write }; 5 | class fifo_file { getattr write }; 6 | class file { create execute execute_no_trans getattr read rename setattr write }; 7 | class process setrlimit; 8 | type postfix_postdrop_exec_t; 9 | type postfix_public_t; 10 | type postfix_spool_maildrop_t; 11 | type postfix_spool_t; 12 | type syslogd_exec_t; 13 | type proc_t; 14 | type syslogd_t; 15 | type var_spool_t; 16 | role system_r; 17 | }; 18 | 19 | allow syslogd_t postfix_postdrop_exec_t:file { execute execute_no_trans read }; 20 | allow syslogd_t postfix_public_t:dir search; 21 | allow syslogd_t postfix_public_t:fifo_file { getattr write }; 22 | allow syslogd_t postfix_spool_maildrop_t:dir { add_name remove_name search write }; 23 | allow syslogd_t postfix_spool_maildrop_t:file { create getattr rename setattr write }; 24 | allow syslogd_t postfix_spool_t:dir search; 25 | allow syslogd_t self:process setrlimit; 26 | allow syslogd_t var_spool_t:dir search; 27 | allow syslogd_t proc_t:file read; 28 | allow syslogd_t syslogd_exec_t:file execute_no_trans; 29 | -------------------------------------------------------------------------------- /selinux/files/multipathd.te: -------------------------------------------------------------------------------- 1 | 2 | module multipathd 1.0; 3 | 4 | require { 5 | type tmp_t; 6 | type sbin_t; 7 | type bin_t; 8 | type var_t; 9 | type lvm_t; 10 | type ramfs_t; 11 | class file { write read create execute execute_no_trans }; 12 | class dir { write search create add_name mounton }; 13 | class filesystem mount; 14 | } 15 | 16 | #============= lvm_t ============== 17 | allow lvm_t bin_t:dir mounton; 18 | allow lvm_t ramfs_t:dir { write search add_name }; 19 | allow lvm_t ramfs_t:file { write read create execute execute_no_trans }; 20 | allow lvm_t ramfs_t:filesystem mount; 21 | allow lvm_t sbin_t:dir mounton; 22 | allow lvm_t tmp_t:dir mounton; 23 | allow lvm_t var_t:dir { write create add_name mounton }; 24 | -------------------------------------------------------------------------------- /selinux/files/postfix.te: -------------------------------------------------------------------------------- 1 | module postfix 1.0.0; 2 | 3 | require { 4 | class dir getattr; 5 | type file_t; 6 | type postfix_master_t; 7 | role system_r; 8 | }; 9 | 10 | allow postfix_master_t file_t:dir getattr; 11 | -------------------------------------------------------------------------------- /selinux/files/syslog-ng.te: -------------------------------------------------------------------------------- 1 | module syslog-ng 1.0.7; 2 | 3 | require { 4 | type postfix_etc_t; 5 | type postfix_public_t; 6 | type postfix_spool_t; 7 | type file_t; 8 | type proc_t; 9 | type fs_t; 10 | type syslogd_exec_t; 11 | type var_spool_t; 12 | type postfix_postdrop_exec_t; 13 | type bin_t; 14 | type sbin_t; 15 | type syslogd_t; 16 | type postfix_spool_maildrop_t; 17 | type sendmail_exec_t; 18 | class process setrlimit; 19 | class fifo_file { write getattr }; 20 | class dir { create write remove_name search add_name setattr }; 21 | class file { rename execute setattr read create execute_no_trans write getattr append }; 22 | class filesystem associate; 23 | } 24 | 25 | #============= syslogd_t ============== 26 | allow syslogd_t bin_t:file { read execute getattr execute_no_trans }; 27 | allow syslogd_t file_t:file { create setattr append write }; 28 | allow syslogd_t file_t:dir { write create add_name setattr }; 29 | allow syslogd_t postfix_etc_t:dir search; 30 | allow syslogd_t postfix_etc_t:file { read getattr }; 31 | allow syslogd_t postfix_postdrop_exec_t:file { read execute execute_no_trans }; 32 | allow syslogd_t postfix_public_t:dir search; 33 | allow syslogd_t postfix_public_t:fifo_file { write getattr }; 34 | allow syslogd_t postfix_spool_maildrop_t:dir { write remove_name search add_name }; 35 | allow syslogd_t postfix_spool_maildrop_t:file { rename write create getattr setattr }; 36 | allow syslogd_t postfix_spool_t:dir search; 37 | allow syslogd_t proc_t:file { read getattr }; 38 | allow syslogd_t sbin_t:dir search; 39 | allow syslogd_t self:process setrlimit; 40 | allow syslogd_t self:dir { write create add_name setattr search }; 41 | allow syslogd_t self:file { create setattr append write }; 42 | allow syslogd_t fs_t:filesystem associate; 43 | allow syslogd_t sendmail_exec_t:file { read execute execute_no_trans }; 44 | allow syslogd_t syslogd_exec_t:file execute_no_trans; 45 | allow syslogd_t var_spool_t:dir search; 46 | -------------------------------------------------------------------------------- /selinux/manifests/init.pp: -------------------------------------------------------------------------------- 1 | # Create the directory where local policy templates are stored for loading 2 | # with the selinux::module defined type below. 3 | 4 | class selinux { 5 | file { "/etc/selinux/local": 6 | ensure => directory, 7 | mode => 0750, 8 | } 9 | } 10 | 11 | # selinux::module defined type adds a new SELinux template into 12 | # the running policy. This type does not require any arguments, it only 13 | # uses the name from the caller. 14 | # 15 | # This define requires creating an SELinux template to load. The best 16 | # method to create the template is to use audit2allow. For example, 17 | # 18 | # sudo audit2allow -m "multipathd" -i /var/log/audit/audit.log > multipathd.te 19 | # 20 | # The above assumes auditing is turned on and logging properly to the above 21 | # log file. See the audit2allow man page for more information. 22 | # 23 | # Example usage for a node (module from above audit2allow example): 24 | # 25 | # selinux::module { "multipathd": } 26 | 27 | define selinux::module () { 28 | file { "/etc/selinux/local/${name}.te": 29 | source => "puppet:///selinux/${name}.te", 30 | } 31 | 32 | file { "/etc/selinux/local/$name-setup.sh": 33 | ensure => present, 34 | mode => 0750, 35 | content => template ("selinux/setup.erb"), 36 | require => File["/etc/selinux/local"], 37 | } 38 | 39 | exec { "SELinux-$name-Update": 40 | command => "/etc/selinux/local/$name-setup.sh", 41 | refreshonly => true, 42 | require => File["/etc/selinux/local/$name-setup.sh"], 43 | subscribe => File["/etc/selinux/local/$name.te"], 44 | } 45 | } 46 | 47 | # Need documentation for this type - 48 | # example usage: 49 | # selinux::chcon { "postfix-lostfound": 50 | # user => "system_u", 51 | # type => "file_t", 52 | # file => "/var/spool/postfix/lost+found", 53 | # } 54 | 55 | define selinux::chcon ( $user = false, $role = false, $type = false, $file) { 56 | case $user { 57 | false: {} 58 | default: { 59 | exec { "$name-chcon-user": 60 | command => "/usr/bin/chcon -u $user $file", 61 | unless => "ls -ldZ $file | grep -q '$user'", 62 | } 63 | } 64 | } 65 | 66 | case $role { 67 | false: {} 68 | default: { 69 | exec { "$name-chcon-role": 70 | command => "/usr/bin/chcon -r $role $file", 71 | unless => "ls -ldZ $file | grep -q '$role'", 72 | } 73 | } 74 | } 75 | 76 | case $type { 77 | false: {} 78 | default: { 79 | exec { "$name-chcon-type": 80 | command => "/usr/bin/chcon -t $type $file", 81 | unless => "ls -ldZ $file | grep -q '$type'", 82 | } 83 | } 84 | } 85 | } 86 | 87 | # vim modeline - have 'set modeline' and 'syntax on' in your ~/.vimrc. 88 | # vi:syntax=puppet:filetype=puppet:ts=4:et: 89 | # EOF 90 | -------------------------------------------------------------------------------- /selinux/templates/setup.erb: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | # Where to store selinux related files 4 | SOURCE=/etc/selinux/local 5 | BUILD=/etc/selinux/local 6 | 7 | /usr/bin/checkmodule -M -m -o ${BUILD}/<%= name %>.mod ${SOURCE}/<%= name %>.te 8 | /usr/bin/semodule_package -o ${BUILD}/<%= name %>.pp -m ${BUILD}/<%= name %>.mod 9 | /usr/sbin/semodule -i ${BUILD}/<%= name %>.pp 10 | 11 | /bin/rm ${BUILD}/<%= name %>.mod ${BUILD}/<%= name %>.pp 12 | 13 | -------------------------------------------------------------------------------- /users/files/someuser/.bashrc: -------------------------------------------------------------------------------- 1 | ############################################################################# 2 | # Options and settings 3 | ############################################################################# 4 | shopt -s cdspell 5 | shopt -s checkhash 6 | shopt -s checkwinsize 7 | shopt -s cmdhist 8 | shopt -s dotglob 9 | shopt -s extglob 10 | shopt -s lithist 11 | shopt -s nocaseglob 12 | shopt -s no_empty_cmd_completion 13 | set -o vi 14 | set -o notify 15 | set -o allexport 16 | umask 027 17 | 18 | ############################################################################# 19 | # Environment variables 20 | ############################################################################# 21 | PATH="/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:/usr/X11R6/bin:$HOME/bin" 22 | MANPATH="/usr/man:/usr/local/man:/usr/share/man:/usr/local/share/man:/usr/X11R6/man" 23 | HISTSIZE="5000" 24 | # Set to avoid spamming up the history file 25 | HISTIGNORE="cd:ls:[bf]g:clear:exit" 26 | # Set to timestamp history entries and preserve across sessions 27 | HISTTIMEFORMAT="%D %R: " 28 | VISUAL="vi" 29 | EDITOR="vi" 30 | # this prompt will show the hostname in green if the last command returned 0, 31 | # otherwise it will be red. 32 | PS1="\[\`if [[ \$? = "0" ]]; then echo '\e[32m\h\e[0m'; else echo '\e[31m\h\e[0m' ; fi\`:\w\n\$ " 33 | PS2=" " 34 | PAGER="/usr/bin/less" 35 | # Adjust ls color output for a white background terminal (removes bold). 36 | LS_COLORS='no=00:fi=00:di=00;34:ln=00;36:pi=40;33:so=00;35:do=00;35:bd=40;33;01:cd=40;33;01:or=40;31;01:su=37;41:sg=30;43:ex=00;32:*.tar=00;31:*.tgz=00;31:*.arj=00;31:*.taz=00;31:*.lzh=00;31:*.zip=00;31:*.z=00;31:*.Z=00;31:*.gz=00;31:*.bz2=00;31:*.deb=00;31:*.rpm=00;31:*.jar=00;31:*.jpg=00;35:*.jpeg=00;35:*.gif=00;35:*.bmp=00;35:*.pbm=00;35:*.pgm=00;35:*.ppm=00;35:*.tga=00;35:*.xbm=00;35:*.xpm=00;35:*.tif=00;35:*.tiff=00;35:*.png=00;35:*.mov=00;35:*.mpg=00;35:*.mpeg=00;35:*.avi=00;35:*.fli=00;35:*.gl=00;35:*.dl=00;35:*.xcf=00;35:*.xwd=00;35:*.flac=00;35:*.mp3=00;35:*.mpc=00;35:*.ogg=00;35:*.wav=00;35:' 37 | 38 | # Make the titlebar of the window show where we are at if logged in via ssh 39 | # (putty window or X11 window) or from a local GNOME session (ie gnome-terminal) 40 | if [ ! -z $SSH_TTY ] || [ ! -z $GDMSESSION ] 41 | then 42 | PROMPT_COMMAND='echo -ne "\033]0;${HOSTNAME}:${PWD}\007"' 43 | # Run a couple informational commands upon login. 44 | df -h -l 45 | uptime 46 | fi 47 | 48 | ############################################################################# 49 | # Aliases 50 | ############################################################################# 51 | # make some common commands more useful. 52 | if [ 'OpenBSD' == `uname` ] 53 | then 54 | alias ls="ls -F" 55 | else 56 | alias ls="ls --color=auto -hF --file-type" 57 | fi 58 | 59 | alias lz="ls -FalZ --color=auto" 60 | alias du="du -mcx" 61 | alias df="df -Tm" 62 | alias free="free -m" 63 | alias today="date +%F" 64 | # navigation shortcuts 65 | alias ..="cd .." 66 | alias -- -="cd -" 67 | # old habits die hard 68 | alias more="/usr/bin/less" 69 | # Quickly add sshkey. 70 | alias sshkey="ssh-add $HOME/.ssh/id_dsa" 71 | # vim > vi 72 | alias vi=/usr/bin/vim 73 | alias ps="COLUMNS=320 ps" 74 | ############################################################################# 75 | # Set up other variables and configuration. 76 | ############################################################################# 77 | if [ -f ~/.bashrc.local ] 78 | then 79 | . ~/.bashrc.local 80 | fi 81 | 82 | function lsd { 83 | if [ -d $1 ]; then 84 | cd $1 85 | shift 86 | ls $@ 87 | else 88 | file $1 89 | fi 90 | } 91 | 92 | # Don't export all variables in the actual shell, just for the profile... 93 | set +o allexport 94 | 95 | # vim modeline - have 'set modeline' and 'syntax on' in your ~/.vimrc. 96 | # vi:syntax=sh:filetype=sh:ts=4:et: 97 | # EOF 98 | -------------------------------------------------------------------------------- /users/files/someuser/.ssh/authorized_keys: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sansnoc/puppet/8b5a3069e8469e319b8a477246f8f06925bc3bba/users/files/someuser/.ssh/authorized_keys -------------------------------------------------------------------------------- /users/manifests/init.pp: -------------------------------------------------------------------------------- 1 | # This module creates users using virtual resources via a called define, 2 | # useraccount. It also has some special handling of web team users because they 3 | # may be in a different primary group on database servers, for example. 4 | # 5 | # To use this module on a node, include the following, as appropriate. 6 | # include users::people # on all servers. 7 | # include users::noc # on all servers. 8 | # include groups::web # only on web servers. 9 | # include users::web # only on web servers. 10 | # include users::web::extra # only on web servers. 11 | # include users::database # only on database servers. 12 | 13 | # We have some other classes to grab too. 14 | import "people" 15 | import "web" 16 | 17 | # define useraccount 18 | # creates a user with their complete home directory, including ssh key(s), 19 | # shell profile(s) and anything else. 20 | # This define should be called to create a virtual resource so it can 21 | # be used to create all users, and then the users required on the particular 22 | # node are specified through the various user classes. 23 | # Example: 24 | # @useraccount { "username": 25 | # ensure => "present", 26 | # uid => 500, 27 | # pgroup => users, 28 | # groups => ["staff", "other"], 29 | # fullname => "New User", 30 | # homefs => "$homefs", 31 | # shell => "$shell", 32 | # } 33 | 34 | define useraccount ( $ensure = present, $uid, $pgroup = users, 35 | $groups, $fullname, $homefs, $shell) { 36 | $username = $name 37 | # This case statement will allow disabling an account by passing 38 | # ensure => absent, to set the home directory ownership to root. 39 | case $ensure { 40 | present: { 41 | $home_owner = $username 42 | $home_group = $pgroup 43 | } 44 | default: { 45 | $home_owner = "root" 46 | $home_group = "root" 47 | } 48 | } 49 | # Create the user with their groups as specified 50 | user { $username: 51 | ensure => $ensure, 52 | uid => $uid, 53 | gid => $pgroup, 54 | groups => $groups, 55 | comment => $fullname, 56 | home => "${homefs}/$username", 57 | shell => $shell, 58 | allowdupe => false, 59 | } 60 | file { "${homefs}/${username}": 61 | ensure => directory, 62 | owner => $home_owner, 63 | group => $home_group, 64 | mode => 750, 65 | require => User["${username}"], 66 | } 67 | file { "${homefs}/${username}/.ssh": 68 | ensure => directory, 69 | owner => $home_owner, 70 | group => $home_group, 71 | mode => 700, 72 | require => File["${homefs}/${username}"], 73 | } 74 | file { "${homefs}/${username}/.ssh/authorized_keys": 75 | ensure => present, 76 | owner => $home_owner, 77 | group => $home_group, 78 | mode => 600, 79 | require => File["${homefs}/${username}/.ssh"], 80 | source => "puppet:///users/${username}/.ssh/authorized_keys", 81 | } 82 | file { "${homefs}/${username}/.ssh/authorized_keys2": 83 | ensure => "${homefs}/${username}/.ssh/authorized_keys", 84 | require => File["${homefs}/${username}/.ssh/authorized_keys"], 85 | } 86 | file { "${homefs}/${username}/.bashrc": 87 | ensure => present, 88 | owner => $home_owner, 89 | group => $home_group, 90 | mode => 640, 91 | require => File["${homefs}/${username}"], 92 | source => "puppet:///users/${username}/.bashrc", 93 | } 94 | file { "${homefs}/${username}/.bash_profile": 95 | ensure => "${homefs}/${username}/.bashrc", 96 | require => File["${homefs}/${username}/.bashrc"], 97 | } 98 | } 99 | 100 | # class groups::web 101 | # This class virtual creates the required groups for the web team. 102 | class groups::web { 103 | @group { "htdocs": ensure => present, gid => "1502", } 104 | @group { "wwwcron": ensure => present, gid => "1501", } 105 | @group { "secure": ensure => present, gid => "2038", } 106 | } 107 | # Create another class to realize other groups. 108 | #class groups::newgrouptype { 109 | # @group { "newgroup": ensure => present, gid => "530", } 110 | #} 111 | # class users::noc 112 | # Make the virtual users with wheel as the primary group real. 113 | # This should be the NOC/Sysadmin team. 114 | class users::noc { 115 | Useraccount <| pgroup == wheel |> 116 | } 117 | 118 | # class users::web 119 | # Make the virtual users with htdocs as the primary group real. 120 | # This should be the webmaster team. 121 | class users::web { 122 | Group <| title == htdocs |> 123 | Group <| title == wwwcron |> 124 | Group <| title == secure |> 125 | Useraccount <| pgroup == htdocs |> 126 | Useraccount <| title == webalizer |> 127 | User <| title == cronman |> 128 | User <| title == secure |> 129 | } 130 | #class users::web::newwebgroup { 131 | # Group <| title == htdocs |> 132 | #} 133 | # Make the virtual users for the newgroup systems real. 134 | #class users::newgroup { 135 | # Group <| title == newgroup |> 136 | # Useraccount <| pgroup == newgroup |> 137 | #} 138 | # vim modeline - have 'set modeline' and 'syntax on' in your ~/.vimrc. 139 | # vi:syntax=puppet:filetype=puppet:ts=4:et: 140 | # EOF 141 | -------------------------------------------------------------------------------- /users/manifests/people.pp: -------------------------------------------------------------------------------- 1 | # class users::people 2 | # we separate this out because it is long from having all the useraccount define 3 | # calls. 4 | class users::people { # this class virtually calls the user:account define. 5 | # first set some defaults based on whether this node is openbsd or centos. 6 | $group = $operatingsystem ? { 7 | centos => "root", 8 | redhat => "root", 9 | openbsd => "wheel", 10 | default => "root", 11 | } 12 | # we should get bash installed on openbsd systems elsewhere, but just 13 | # in case: 14 | $shell = $operatingsystem ? { 15 | centos => "/bin/bash", 16 | redhat => "/bin/bash", 17 | openbsd => "/usr/local/bin/bash", 18 | default => "/bin/bash", 19 | } 20 | # We use /home as the default "home" filesystem. 21 | # TODO: maybe this should be handled through a define, instead. 22 | # we set the group here based on the default group by platform above. 23 | $homefs = "/home" 24 | file { $homefs: 25 | ensure => directory, 26 | owner => "root", 27 | group => $group, 28 | mode => 2755 29 | } 30 | # These are the NOC users. 31 | # use uids 500-509 for noc users. 32 | @useraccount { "someuser": 33 | ensure => "present", 34 | uid => "500", 35 | pgroup => "wheel", 36 | groups => ["users"], 37 | fullname => "Some User", 38 | homefs => $homefs, 39 | shell => $shell, 40 | } 41 | # These are the Web/database users. 42 | # use uids 510-529 for web users. 43 | @useraccount { "webguy1": 44 | ensure => "present", 45 | uid => "510", 46 | pgroup => "htdocs", 47 | groups => ["wwwcron"], 48 | fullname => "Web Guy One", 49 | homefs => $homefs, 50 | shell => "/bin/bash", 51 | } 52 | } 53 | # class users::database 54 | # Override the primary group for virtual web users to mysql. 55 | # Make these virtual users real. 56 | class users::database inherits users::people { 57 | Useraccount["webguy1"] { 58 | pgroup => "mysql", 59 | groups => "users", 60 | require => Group["mysql"], 61 | } 62 | Useraccount <| pgroup == mysql |> 63 | } 64 | # vim modeline - have 'set modeline' and 'syntax on' in your ~/.vimrc. 65 | # vi:syntax=puppet:filetype=puppet:ts=4:et: 66 | # EOF 67 | -------------------------------------------------------------------------------- /users/manifests/web.pp: -------------------------------------------------------------------------------- 1 | # class users::web::extra 2 | # This class creates the cronman and secure users required for the 3 | # web team to support various aspects of the web systems. 4 | # Only include this class on web systems. 5 | class users::web::extra { 6 | # cronman is a special user for the web team to manage crontabs centrally 7 | @user { "cronman": 8 | ensure => "present", 9 | uid => "2029", 10 | gid => "wwwcron", 11 | groups => ["htdocs"], 12 | comment => "WWW Cron Manager", 13 | home => "/home/cronman", 14 | shell => "/bin/bash", 15 | require => Group["wwwcron"], 16 | } 17 | # secure is a special user for the web team. 18 | @user { "secure": 19 | ensure => "present", 20 | uid => "2037", 21 | gid => "2038", 22 | groups => ["htdocs", "wwwcron"], 23 | comment => "Secure Web User", 24 | home => "/home/secure", 25 | shell => "/bin/bash", 26 | require => Group["secure"], 27 | } 28 | # webalizer needs to be created for automated ssh access from chipper1. 29 | # this is only on the web servers, and isn't a person, so it won't be in 30 | # the 'people' class, even though it uses the useraccount define. 31 | @useraccount { "webalizer": 32 | ensure => "present", 33 | uid => "2030", 34 | pgroup => "users", 35 | groups => ["apache", "htdocs"], 36 | fullname => "Web stats analyzer", 37 | homefs => "/home", 38 | shell => "/bin/bash", 39 | } 40 | } 41 | 42 | # vim modeline - have 'set modeline' and 'syntax on' in your ~/.vimrc. 43 | # vi:syntax=puppet:filetype=puppet:ts=4:et: 44 | # EOF 45 | --------------------------------------------------------------------------------