Daemon-Shutdown

 view release on metacpan or  search on metacpan

lib/Daemon/Shutdown.pm~  view on Meta::CPAN


Default: 0

=item shutdown_binary <Str>

The full path to the shutdown binary

Default: /sbin/poweroff

=item shutdown_args <ArrayRef>

Any args to pass to your shutdown_binary

Default: none

=item shutdown_after_triggered_monitors <Str>

The number of monitors which need to be triggered at the same time to cause a 
shutdown. Can be a number or the word 'all'.

Default: 1

=back

=head3 Example (YAML formatted) configuration file
 
---
log_level: INFO
log_file: /var/log/sdd.log
shutdown_binary: /sbin/shutdown
shutdown_args:
  - -h
  - now
exit_after_trigger: 0
sleep_before_run: 30
verbose: 0
use_sudo: 0
monitor:
  hdparm:
    loop_sleep: 60
    disks: 
      - /dev/sdb
      - /dev/sdc
      - /dev/sdd

=cut

sub new {
    my $class = shift;

    my %params = @_;

    # Remove any undefined parameters from the params hash
    map { delete( $params{$_} ) if not $params{$_} } keys %params;

    # Validate the config file
    %params = validate_with(
        params => \%params,
        spec   => {
            config => {
                callbacks => {
                    'File exists' => sub { -f shift }
                },
                default => '/etc/sdd.conf',
            },
        },
        allow_extra => 1,
    );
    my $self = {};

    # Read the config file
    if ( not $params{config} ) {
        $params{config} = '/etc/sdd.conf';
    }
    if ( not -f $params{config} ) {
        die( "Config file $params{config} not found\n" );
    }
    my $file_config = LoadFile( $params{config} );
    delete( $params{config} );

    # Merge the default, config file, and passed parameters
    %params = ( %$file_config, %params );

    my @validate = map { $_, $params{$_} } keys( %params );
    %params = validate_with(
        params => \%params,
        spec   => {
            log_file => {
                default   => '/var/log/sdd.log',
                callbacks => {
                    'Log file is writable' => sub {
                        my $filepath = shift;
                        if ( -f $filepath ) {
                            return -w $filepath;
                        } else {

                            # Is directory writable
                            return -w dirname( $filepath );
                        }
                    },
                },
            },
            log_level => {
                default => 'INFO',
                regex   => qr/^(DEBUG|INFO|WARN|ERROR)$/,
            },
            verbose => {
                default => 0,
                regex   => qr/^[1|0]$/,
            },
            test => {
                default => 0,
                regex   => qr/^[1|0]$/,
            },
            sleep_before_run => {
                default => 3600,
                regex   => qr/^\d*$/,
            },
            exit_after_trigger => {
                default => 0,
                regex   => qr/^[1|0]$/,
            },
            use_sudo => {
                default => 0,
                regex   => qr/^[1|0]$/,
            },
            shutdown_binary => {
                default   => '/sbin/poweroff',
                type      => SCALAR,
                callbacks => {
                    'Shutdown binary exists' => sub {
                        -x shift();
                    },
                },
            },
            shutdown_args => {
                type     => ARRAYREF,
                optional => 1
            },
            monitor                           => { type => HASHREF, },
            shutdown_after_triggered_monitors => {
                default => 1,
                type    => SCALAR,
                regex   => qr/^(all|\d+)$/,
            }
        },

        # A little less verbose than Carp...
        on_fail => sub { die( shift() ) },
    );

    $self->{params} = \%params;

    bless $self, $class;

    # Set up the logging
    my $log4perl_conf = sprintf 'log4perl.rootLogger = %s, Logfile', $params{log_level} || 'WARN';
    if ( $params{verbose} > 0 ) {
        $log4perl_conf .= q(, Screen
            log4perl.appender.Screen         = Log::Log4perl::Appender::Screen
            log4perl.appender.Screen.stderr  = 0
            log4perl.appender.Screen.layout   = Log::Log4perl::Layout::PatternLayout
            log4perl.appender.Screen.layout.ConversionPattern = [%d] %p %m%n
        );

    }

    $log4perl_conf .= q(
        log4perl.appender.Logfile          = Log::Log4perl::Appender::File
        log4perl.appender.Logfile.layout   = Log::Log4perl::Layout::PatternLayout
        log4perl.appender.Logfile.layout.ConversionPattern = [%d] %p %m%n
    );
    $log4perl_conf .= sprintf "log4perl.appender.Logfile.filename = %s\n", $params{log_file};

    # ... passed as a reference to init()
    Log::Log4perl::init( \$log4perl_conf );
    my $logger = Log::Log4perl->get_logger();
    $self->{logger} = $logger;

    $self->{is_root} = ( User->Login eq 'root' ? 1 : 0 );
    $self->{logger}->info( "You are " . User->Login );

    if ( not $self->{is_root} ) {
        $self->{logger}->warn( "You are not root. SDD will probably not work..." );
    }

    # Load the monitors
    my %monitors;
    foreach my $monitor_name ( keys( %{ $params{monitor} } ) ) {
        eval {



( run in 1.111 second using v1.01-cache-2.11-cpan-39bf76dae61 )