### ### Copyright 2000-2007 University of Illinois Board of Trustees ### All rights reserved. ### ### PSGConf::Control::logrotate - psgconf control class for controlling log rotation/pruning ### ### Campus Information Technologies and Educational Services ### University of Illinois at Urbana-Champaign ### package PSGConf::Control::logrotate; use PSGConf::Action::MkDir; use PSGConf::Action::GenerateFile::Literal; use PSGConf::Action::Remove; use PSGConf::Data::Boolean; use PSGConf::Data::Hash; ############################################################################### ### policies ############################################################################### sub _add_files { my ($psgconf, $cmd, $missing, @files) = @_; my ($files, $file); $files = $psgconf->data_obj('logrotate_files')->get(); foreach $file ( @files ) { if ( ! exists $files->{$file} ) { $files->{$file}->{sharedscripts} = undef; $files->{$file}->{postrotate} = "\n\t\t" . $cmd . "\n\tendscript" if ( defined $cmd ); $files->{$file}->{missingok} = undef if ( defined $missing ); } } } sub _policy_add_syslog_files { my ($self, $psgconf) = @_; my (@logs); return if ($psgconf->data_obj('syslog_enable')->equals('false') || $psgconf->data_obj('logrotate_enable')->equals('false')); map { push @logs, $_ if ( -f $_ ); } keys %{$psgconf->data_obj('syslog')->get()}; &_add_files ($psgconf, "/usr/bin/killall -HUP syslogd", undef, @logs ); } sub _policy_add_www_files { my ($self, $psgconf) = @_; my (@logs); return if ($psgconf->data_obj('www_enable')->equals('false') || $psgconf->data_obj('logrotate_enable')->equals('false')); @logs = ( $psgconf->data_obj('www_log_dir')->get() . '/suexec.log', $psgconf->data_obj('www_log_dir')->get() . '/error_log', $psgconf->data_obj('www_log_dir')->get() . '/access_log' ); map { push @logs, $_; } values %{$psgconf->data_obj('www_vh_access_log')->get()}; push @logs, $psgconf->data_obj('www_log_dir')->get() . '/ssl_engine_log' if ( $psgconf->data_obj('www_vh_ssl')->count() ); push @logs, $psgconf->data_obj('www_jk_logfile')->get() if ( $psgconf->data_obj('www_jk_enable')->equals('true') ); ### ### FIXME: Need to add the bluestem and any other logs not in ### the stock psgconf modules. This really screams to be put ### into a method that other Control modules can call from w/i ### one of their policies. ### &_add_files ( $psgconf, $psgconf->data_obj('www_apachectl_path')->get() . " graceful > /dev/null 2>&1", 1, @logs); } sub _policy_add_ftp_files { my ($self, $psgconf) = @_; return if ($psgconf->data_obj('anon_ftp_enable')->equals('false') || $psgconf->data_obj('logrotate_enable')->equals('false')); if ( $psgconf->data_obj('anon_ftp_use_vsftpd')->equals('true') ) { &_add_files ($psgconf, undef, undef, ( $psgconf->data_obj('log_dir')->get() . '/vsftpd.log' )); } else { &_add_files ($psgconf, undef, undef, ( $psgconf->data_obj('log_dir')->get() . '/xferlog' )); } } ############################################################################### ### contstructor ############################################################################### sub new { my ($class, $psgconf) = @_; my ($self); $self = {}; bless($self, $class); $self->{name} = 'logrotate'; $self->{enable} = $self->{name} . '_enable'; $self->{packages} = $self->{name} . '_packages'; $psgconf->register_data( 'logrotate_enable' => PSGConf::Data::Boolean->new( 'value' => 'false' ), 'logrotate_options' => PSGConf::Data::Hash->new( value_optional => 1 ), 'logrotate_files' => PSGConf::Data::Hash->new( value_type => 'HASH' ) ); $psgconf->register_policy($self, logrotate_add_syslog_files => '_policy_add_syslog_files', logrotate_add_ftp_files => '_policy_add_ftp_files', logrotate_add_www_files => '_policy_add_www_files' ); return $self; } ############################################################################### ### decide() method ### ### create /etc/logrotate.d if it doesn't exist ### ### generate /etc/logrotate.conf based on options and files ### specified in psg.conf ############################################################################### sub decide { my ($self, $psgconf) = @_; my ($conffile); my ($options) = $psgconf->data_obj('logrotate_options')->get(); my ($files) = $psgconf->data_obj('logrotate_files')->get(); return if ($psgconf->data_obj('logrotate_enable')->equals('false')); # generate the global options in the /etc/logrotate.conf file map { $conffile .= "$_ " . $options->{"$_"} . "\n"; } (keys %$options); $conffile .= "include /etc/logrotate.d\n\n\n"; # generate the file section of /etc/logrotate.conf map { my ($file, $fileops); $file = $_; $fileops = $files->{"$file"}; $conffile .= "$file {\n"; # the file name is the key to the first hash - # the value is another hash containing options for the file map { $conffile .= "\t$_ " . $fileops->{"$_"} . "\n"; } (sort keys %$fileops); $conffile .= "}\n\n"; } (sort keys %$files); ### create /etc/logrotate.conf $psgconf->register_actions( PSGConf::Action::GenerateFile::Literal->new( name => '/etc/logrotate.conf', content => $conffile ), PSGConf::Action::MkDir->new( name => '/etc/logrotate.d' ) ); $psgconf->register_actions( PSGConf::Action::Remove->new( name => '/etc/logrotate.d/syslog', backup => 0 ) ) if ( $psgconf->data_obj('syslog_enable')->equals('true') ); $psgconf->register_actions( PSGConf::Action::Remove->new( name => '/etc/logrotate.d/httpd', backup => 0 ) ) if ( $psgconf->data_obj('www_enable')->equals('true') ); $psgconf->register_actions( PSGConf::Action::Remove->new( name => '/etc/logrotate.d/vsftpd.log', backup => 0 ) ) if ( $psgconf->data_obj('anon_ftp_enable')->equals('true') && $psgconf->data_obj('anon_ftp_use_vsftpd')->equals('true') ); } 1; __END__ =head1 NAME PSGConf::Control::logrotate - psgconf control class for controlling log rotation/pruning =head1 SYNOPSIS In F: Control PSGConf::Control::logrotate =head1 DESCRIPTION The B module provides a B control object for rotating system logs using the logrotate facility. It supports the following methods: =over 4 =item new() The constructor. Its parameter is a reference to the B object. It registers the following data objects: =over 4 =item I A B object to enable/disable this feature =item I A B object for global logrotate options to be added to the logrotate.conf file: logrotate_options { "compress", "rotate" => "14", "daily" } =item I A B object of B objects with the key to the main hash being the path to a log file, and the contained has being options for that specific log file: logrotate_files { "/var/log/wtmp" => { "daily", "create 0664 root utmp", "rotate 14" } }; =back The constructor also registers the following policy methods: =over 4 =item I Requests that the C files be rotated. =item I Requests that the C log files be rotated. =item I Requests that the C log files be rotated. =back =item decide() Registers a B Action object to generate the F file. It will also remove the f file if it exists and we are configured to rotate syslog files. =back =head1 SEE ALSO L Clogrotate(8)E> L L L L L L L =cut