MYDan

 view release on metacpan or  search on metacpan

dan/oncall/bin/cal  view on Meta::CPAN

 $0 name [--zone timezone] [--level number] \
 [--year year] [--month month] [--grep regex]

=cut
my %o = MYDan::Util::OptConf->load()
    ->get( qw( year=i month=s zone=s level=i grep=s ) )->dump;

my $dt = DateTime->now()->set_time_zone( $o{zone} ||= $MYDan::Oncall::LTZ )
    ->set( day => 1, map { $_ => 0 } qw( hour minute second ) );

my ( $year, $month, $grep, %busy ) = @o{ qw( year month grep ) };

if ( $year ) { $dt->set( year => $year < 1000 ? $year += 2000 : $year ) }
else { $year = $dt->year }

if ( $month )
{
    if ( $month !~ /^\d+$/ )
    {
        for ( 0 .. $#MON )
        {

dan/oncall/bin/cal  view on Meta::CPAN

    my $policy = MYDan::Oncall::Policy->new( "$o{data}/$ARGV[0]" );
    my @level = 1 .. ( $o{level} || 3 );
    my $end = $dt->clone->add( months => 1 )->epoch;

    for ( my ( $now, $then ) = $dt->epoch; $now < $end; $now = $then )
    {
        my ( $month, $day ) = map { $dt->$_ } qw( month day );

        $then = $dt->add( days => 1 )->epoch;
        $policy->set( $now, $then );
        $busy{$month}{$day} = 1 if grep { $_->{item} =~ $grep }
            map { values %{ $policy->list( $_ ) } } @level;
    }
}

MYDan::Oncall::Calendar->new( $year, %busy )->print( $month );
exit 0;

lib/MYDan/Util/MIO/CMD.pm  view on Meta::CPAN

Returns HASH of HASH of nodes. First level is indexed by type
( I<stdout>, I<stderr>, or I<error> ). Second level is indexed by message.

=cut
sub run
{
    local $| = 1;

    my $self = shift;
    my @node = keys %$self;
    my ( $run, $ext, %run, %result, %busy ) = ( 1, "$Script.$$", %RUN, @_ );
    my ( $max, $timeout, $interchange ) = @run{ qw( max timeout interchange ) };
    my $input = defined $run{input} ? $run{input} : -t STDIN ? '' : <STDIN>;

    $SIG{INT} = $SIG{TERM} = sub
    {
        print STDERR "killed\n";
        $run = 0;
    };

    for ( my $time = time; $run && ( @node || %busy ); )
    {
        $run = 0 if time - $time > $timeout;

        while ( @node && keys %busy < $max )
        {
            my $node = shift @node;
	    my $log = "/tmp/$node.$ext";
            my $cmd = $self->{$node};
            my @cmd = map { my $t = $_; $t =~ s/$interchange/$node/g; $t } @$cmd;

            if ( $run{noop} )
            {
                print join ' ', @cmd, "\n";
                next;
            }

            print "$node started.\n" if $run{verbose};

            if ( my $pid = fork() ) { $busy{$pid} = [ $log, $node ]; next } 

	    open STDOUT, ">>$log";
	    open STDERR, ">>$log";
	    
	    exec sprintf join ' ', @cmd;
	    exit 0;
        }

        for ( keys %busy )
        {
            my $pid = waitpid( -1, WNOHANG );
            next if $pid <= 0;

	    my $stat = $? >> 8;

            my ( $log, $node ) = @{ delete $busy{$pid} };

            print "$node done.\n" if $run{verbose};

            tie my @log, 'Tie::File', $log,recsep => "\n";

	    my $tmp = join "\n", @log;
	    $tmp =~ s/$node/$interchange/g if $run{xx};
            push @{ $result{output}{ join "\n", $tmp, "--- $stat", '' } }, $node;
            unlink $log;
        }
    }

    kill 9, keys %busy;
    push @{ $result{output}{killed} }, map{ $busy{$_}[1]}keys %busy;
    push @{ $result{output}{norun} }, @node;
    unlink glob "/tmp/*.$ext";
    unlink $input if $input && -f $input;

    return wantarray ? %result : \%result;
}

1;

lib/MYDan/Util/MIO/SSH.pm  view on Meta::CPAN

 user : ( default logname ) connect as user
 pass : password

=cut
sub run
{
    local $/ = "\n";

    my $self = shift;
    my @node = keys %$self;
    my ( $run, %run, %result, %busy ) = ( 1, %RUN, @_ );
    my ( $ext, $prompt ) = ( "$Script.$$", 'password:' );
    my ( $max, $timeout, $user, $sudo, $pass, $input ) =
        @run{ qw( max timeout user sudo pass input ) };

    my $percent =  MYDan::Util::Percent->new( scalar @node, 'run ..' );

    $SIG{INT} = $SIG{TERM} = sub
    {
        print STDERR "killed\n";
        $run = 0;
    };

    my %hosts = MYDan::Util::Hosts->new()->match( @node );
    my $p = MYDan::Util::Proxy->new( "$MYDan::PATH/etc/util/conf/proxy" );

    do
    {
        while ( @node && keys %busy < $max )
        {
            my $node = shift @node;
            my $cmd = $self->{$node};
            my $log = "/tmp/$node.$ext";

	    my %x = $p->search( $hosts{$node} );

            my $ssh = $user ? "$SSH -l $user $hosts{$node} " : "$SSH $hosts{$node} ";
	    $ssh.= " -o ProxyCommand='nc -X 5 -x $x{$hosts{$node}} %h %p' " if $x{$hosts{$node}};

            if( @$cmd )
            {
                $ssh .= join ' ',
                    $sudo ? map { "sudo -p '$prompt' -u $sudo $_" } @$cmd : @$cmd;
            }
            else { $ssh .= " < $input"; }

            if ( $run{noop} ) { warn "$ssh\n"; next }
            if ( my $pid = fork() ) { $busy{$pid} = [ $log, $node ]; next }
            
            my ( $exp, %expect ) = Expect->new();

	    if( $pass->{$node} && ref $pass->{$node} )
	    {
		%expect = %{$pass->{$node}};
                for( keys %expect )
		{
                    next unless $expect{$_} =~ /googlecode\s*:\s*(\w+)/;
		    $expect{$_} = Authen::OATH->new->totp(  decode_base32( $1 ));

lib/MYDan/Util/MIO/SSH.pm  view on Meta::CPAN

            if ( $exp->spawn( $ssh ) )
            {
                $exp->expect( $timeout, 
	        map{ my $v = $expect{$_};[ qr/$_/ => sub { $exp->send( "$v\n" ); exp_continue; } ] }keys %expect        
		);
            }
 
            exit 0;
        }

        for ( keys %busy )
        {
            my $pid = waitpid( -1, WNOHANG );
            next if $pid <= 0;

	    my $stat = $? >> 8;

            next unless my $data = delete $busy{$pid};

            $percent->add()->print() if $run{verbose};

            my ( $log, $node ) = @$data;
            tie my @log, 'Tie::File', $log;

            my @i = grep { $log[$_] =~ /$prompt/ } 0 .. $#log;
            splice @log, 0, $i[-1] + 1 if @i;

	    unless( $ENV{MYDan_DEBUG} )

lib/MYDan/Util/MIO/SSH.pm  view on Meta::CPAN

	        @log = grep { $_ !~ m{Warning: Permanently added .+ to the list of known hosts\.}m } @log;
                @log = grep { $_ !~ m{Pseudo-terminal will not be allocated because stdin is not a terminal\.}m } @log;
	        pop @log if @log && $log[-1] =~ /^Last login: .*\d+:\d+:\d+/;
            }

	    my $end = $input ? '' : "--- $stat\n";
            push @{ $result{output}{ join "\n", @log, $end } }, $node if @log;
            unlink $log;
        }
    }
    while $run && ( @node || %busy );

    kill 9, keys %busy;

    push @{ $result{output}{killed} }, map{ $busy{$_}[1]}keys %busy;
    push @{ $result{output}{norun} }, @node;

    unlink glob "/tmp/*.$ext";
    unlink $input if $input && -f $input;

    return wantarray ? %result : \%result;
}

1;

lib/MYDan/Util/MIO/TCP.pm  view on Meta::CPAN

=cut
sub run
{
    confess "poll: $!" unless my $poll = IO::Poll->new();

    local $| = 1;
    local $/ = undef;

    my $self = shift;
    my @node = keys %$self;
    my ( %run, %result, %buffer, %busy ) = ( %RUN, @_ );
    my ( $log, $max, $timeout, $input ) = @run{ qw( log max timeout input ) };

    $input ||= -t STDIN ? '' : <STDIN>;

    for ( my $time = time; @node || $poll->handles; )
    {
        if ( time - $time > $timeout ) ## timeout
        {
            for my $sock ( keys %busy )
            {
                $poll->remove( $sock );
                eval { $sock->shutdown( 2 ) };
                push @{ $result{error}{timeout} }, delete $busy{$sock};
            }

            print $log "timeout!\n";
            last;
        }

        while ( @node && keys %busy < $max )
        {
            my $node = shift @node;
            my %inet =
            (
                PeerAddr => $node, Blocking => 0, Timeout => $timeout,
                Proto => 'tcp', Type => SOCK_STREAM,
            );

            my $sock = $self->{$node}
                ? IO::Socket::INET->new( %inet )
                : IO::Socket::UNIX->new( %inet );

            unless ( $sock )
            {
                push @{ $result{error}{ "socket: $!" } }, $node;
                next;
            }

            $poll->mask( $sock => POLLIN | POLLOUT );
            $busy{$sock} = $node;
            print $log "$node started.\n" if $run{verbose};
        }

        $poll->poll( $MAX{period} );

        for my $sock ( $poll->handles( POLLIN ) ) ## read
        {
            my $buffer; $sock->recv( $buffer, $MAX{buffer} );
            $buffer{$sock} .= $buffer;
        }

        for my $sock ( $poll->handles( POLLOUT ) ) ## write
        {
            $sock->send( $input ) if defined $input;
            $poll->mask( $sock, $poll->mask( $sock ) & ~POLLOUT );
            eval { $sock->shutdown( 1 ) };
        }

        for my $sock ( $poll->handles( POLLHUP ) ) ## done
        {
            my $node = delete $busy{$sock};

            push @{ $result{mesg}{ delete $buffer{$sock} } }, $node;
            $poll->remove( $sock );
            eval { $sock->shutdown( 0 ) };
            print $log "$node done.\n" if $run{verbose};
        }
    }

    push @{ $result{error}{'not run'} }, @node if @node;
    return wantarray ? %result : \%result;

lib/MYDan/Util/MIO/UDP.pm  view on Meta::CPAN

=cut
sub run
{
    confess "poll: $!" unless my $poll = IO::Poll->new();

    local $| = 1;
    local $/ = undef;

    my $self = shift;
    my @node = keys %$self;
    my ( %run, %result, %busy ) = ( resp => 1, %RUN, @_ );
    my ( $log, $max, $timeout, $input, $resp ) =
        @run{ qw( log max timeout input resp ) };

    $input ||= -t STDIN ? '' : <STDIN>;

    for ( my $time = time; @node || $poll->handles; )
    {
        if ( time - $time > $timeout ) ## timeout
        {
            for my $sock ( keys %busy )
            {
                $poll->remove( $sock );
                eval { $sock->shutdown( 2 ) };
                push @{ $result{error}{timeout} }, delete $busy{$sock};
            }

            print $log "timeout!\n";
            last;
        }

        while ( @node && keys %busy < $max )
        {
            my $node = shift @node;
            my %inet =
            (
                PeerAddr => $node, Blocking => 0, Timeout => $timeout,
                Proto => 'udp', Type => SOCK_DGRAM,
            );

            my $sock = $self->{$node}
                ? IO::Socket::INET->new( %inet )

lib/MYDan/Util/MIO/UDP.pm  view on Meta::CPAN

                push @{ $result{error}{ "socket: $!" } }, $node;
                next;
            }

            $sock->send( $input ) if defined $input;
            print $log "$node started.\n" if $run{verbose};

            if ( $resp )
            {
                $poll->mask( $sock => POLLIN );
                $busy{$sock} = $node;
            }
            else
            {
                eval { $sock->shutdown( 2 ) };
                print $log "$node done.\n" if $run{verbose};
            }
        }

        next unless $resp;
        $poll->poll( $MAX{period} );

        for my $sock ( $poll->handles( POLLIN ) ) ## read
        {
            my $buffer; $sock->recv( $buffer, $MAX{buffer} );
            my $node = delete $busy{$sock};

            push @{ $result{mesg}{$buffer} }, $node;
            $poll->remove( $sock );
            eval { $sock->shutdown( 2 ) };
            print $log "$node done.\n" if $run{verbose};
        }
    }

    push @{ $result{error}{'not run'} }, @node if @node;
    return wantarray ? %result : \%result;

lib/MYDan/Util/Phasic.pm  view on Meta::CPAN

    {
        my ( $h, $i ) = $w8queue[1]->dequeue( 2 );
        $w8{$h} = $i; $count --;
        last unless $count;
    }

    my %src = map { $_ => $w8{$_} } @{ $self->{src} };
    my %dst = map { $_ => $w8{$_} } @{ $self->{dst} };
    my %quiesce = map { $_ => 1 } @{ $self->{quiesce} };

    my ( %multi, %busy, %err ) = map{ $_ => $MULTI }keys %src;

    for ( my $now = time; %dst || %busy; sleep $POLL )
    {
        while ( $queue[1]->pending() )
        {
            my ( $src, $dst, $ok, $info ) = $queue[1]->dequeue_nb( 4 );
            delete @busy{ $src, $dst };

            $multi{$src} ++ if defined $src{$src};

            $src{$src} = $w8{$src} unless $quiesce{$src};

            if ( $ok )
            {
                unless( $quiesce{$dst} )
                { 
                    $src{$dst} = $w8{$dst};

lib/MYDan/Util/Phasic.pm  view on Meta::CPAN

        }

        if ( $timeout && time - $now > $timeout )
        {
            map{
                unless( defined $multi{$_} )
                {
                    $err{$_} = $retry +1;
                    $log->say( "$_: timeout" );
                }
            }keys %busy, keys %dst; last;
        }
        elsif ( %src && %dst )
        {
            my $dst = ( keys %dst )[ int( rand time ) % 2 ? -1 : 0 ];
            my $w8 = $busy{$dst} = delete $dst{$dst};
            my %dist = map { $_ => abs( $w8{$_} - $w8 ) }keys %src;
            my $src = ( sort { $dist{$a} <=> $dist{$b} } keys %dist )[0];

            $busy{$src} = delete $src{$src};
	    $log->say( "$src => $dst: RSYNC" );
            $queue[0]->enqueue( $src, $dst );
        }
        elsif( $MULTI && %dst && ( scalar keys %dst ) > $split ) 
        {
            next unless my @multi = grep{ $multi{$_} > 0 }keys %multi;

            my $dst = ( keys %dst )[ int( rand time ) % 2 ? -1 : 0 ];
            my $w8 = $busy{$dst} = delete $dst{$dst};
            my %dist = map { $_ => abs( $w8{$_} - $w8 ) }@multi;
            my $src = ( sort { $dist{$a} <=> $dist{$b} } keys %dist )[0];

            $multi{$src} --;
	    $log->say( "$src => $dst: MULTI" );
            $queue[0]->enqueue( $src, $dst );
        }
    }

    $self->{failed} = [ grep { $err{$_} > $retry } keys %err ];

lib/MYDan/VSSH.pm  view on Meta::CPAN

{
    my ( $class, %self ) =  @_;

    $self{config} = +{};

    bless \%self, ref $class || $class;
}

sub run
{
    my ( $this, %run, %busy ) = ( shift, %RUN, @_ );
 
    my $history = MYDan::VSSH::History->new();
    my $execute = MYDan::VSSH::Execute->new( node => $this->{node} );
    my $print = MYDan::VSSH::Print->new();
    $print->welcome();

    my $audit = $run{audit};
    my $c = scalar @{$this->{node}};
    while ( 1 )
    {



( run in 0.280 second using v1.01-cache-2.11-cpan-87723dcf8b7 )