Changeset 84

Show
Ignore:
Timestamp:
02/21/10 22:52:19 (4 years ago)
Author:
depesz
Message:

initial work done. state is handled, segment is copied to temporary location with proper state and checksumming

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • trunk/omnipitr/lib/OmniPITR/Archive.pm

    r82 r84  
    44use base qw( OmniPITR::Program ); 
    55use Carp; 
     6use English qw( -no_match_vars ); 
     7use File::Basename; 
    68use File::Spec; 
     9use File::Path qw( make_path ); 
     10use File::Copy; 
     11use Storable; 
    712use Getopt::Long; 
     13use Data::Dumper; 
     14use Digest::MD5; 
    815 
    916sub run { 
    1017    my $self = shift; 
    11     print "YAY, it worked!\n"; 
    12     print Dumper($self); 
     18    $self->read_state(); 
     19    $self->prepare_temp_directory(); 
     20    $self->copy_segment_to_temp_dir(); 
     21
     22 
     23sub copy_segment_to_temp_dir { 
     24    my $self = shift; 
     25    return if $self->segment_already_copied(); 
     26    my $new_file = $self->get_temp_filename_for( 'none' ); 
     27    unless ( copy( $self->{'segment'}, $new_file ) ) { 
     28        $self->log->fatal('Cannot copy %s to %s : %s', $self->{'segment'}, $new_file, $OS_ERROR ); 
     29    } 
     30    my $has_md5 = $self->md5sum( $new_file ); 
     31    $self->{'state'}->{'compressed'}->{'none'} = $has_md5; 
     32    $self->save_state(); 
     33    return; 
     34
     35 
     36sub segment_already_copied { 
     37    my $self = shift; 
     38    return unless $self->{ 'state' }->{ 'compressed' }->{ 'none' }; 
     39    my $want_md5 = $self->{ 'state' }->{ 'compressed' }->{ 'none' }; 
     40 
     41    my $temp_file_name = $self->get_temp_filename_for( 'none' ); 
     42    return unless -e $temp_file_name; 
     43 
     44    my $has_md5 = $self->md5sum( $temp_file_name ); 
     45    if ( $has_md5 eq $want_md5 ) { 
     46        $self->log->log('Segment has been already copied to temp location.'); 
     47        return 1; 
     48    } 
     49 
     50    unlink $temp_file_name; 
     51    $self->log->error( 'Segment already copied, but with bad MD5 ?!' ); 
     52 
     53    return; 
     54
     55 
     56sub get_temp_filename_for { 
     57    my $self = shift; 
     58    my $type = shift; 
     59 
     60    return File::Spec->catfile( $self->{ 'temp-dir' }, $type ); 
     61
     62 
     63sub md5sum { 
     64    my $self     = shift; 
     65    my $filename = shift; 
     66 
     67    my $ctx = Digest::MD5->new; 
     68 
     69    open my $fh, '<', $filename or $self->log->fatal( 'Cannot open file for md5summing %s : %s', $filename, $OS_ERROR ); 
     70    $ctx->addfile( $fh ); 
     71    my $md5 = $ctx->hexdigest(); 
     72    close $fh; 
     73 
     74    return $md5; 
     75
     76 
     77sub prepare_temp_directory { 
     78    my $self = shift; 
     79    my $full_temp_dir = File::Spec->catfile( $self->{ 'temp-dir' }, basename( $PROGRAM_NAME ), basename( $self->{ 'segment' } ) ); 
     80    make_path( $full_temp_dir ); 
     81    $self->{ 'temp-dir' } = $full_temp_dir; 
     82    return; 
     83
     84 
     85sub read_state { 
     86    my $self = shift; 
     87    $self->{ 'state' } = {}; 
     88 
     89    return unless $self->{ 'state-dir' }; 
     90 
     91    $self->{ 'state-file' } = File::Spec->catfile( $self->{ 'state-dir' }, basename( $self->{ 'segment' } ) ); 
     92    return unless -f $self->{ 'state-file' }; 
     93    $self->{ 'state' } = retrieve( $self->{ 'state-file' } ); 
     94    return; 
     95
     96 
     97sub save_state { 
     98    my $self = shift; 
     99 
     100    return unless $self->{ 'state-file' }; 
     101 
     102    store( $self->{ 'state' }, $self->{ 'state-file' } ); 
     103 
     104    return; 
    13105} 
    14106 
    15107sub read_args { 
    16108    my $self = shift; 
     109 
     110    my @argv_copy = @ARGV; 
    17111 
    18112    my %args = ( 
    19113        'data-dir' => '.', 
     114        'temp-dir' => $ENV{ 'TMPDIR' } || '/tmp', 
    20115    ); 
     116 
    21117    croak( 'Error while reading command line arguments. Please check documentation in doc/omnipitr-archive.pod' ) 
    22118        unless GetOptions( 
     
    31127        'verbose|v' 
    32128        ); 
     129 
    33130    croak( '--log was not provided - cannot continue.' ) unless $args{ 'log' }; 
    34131 
     
    57154 
    58155    # We do it here so it will actually work for reporing problems in validation 
    59     $self->{ 'log' }          = OmniPITR::Log->new( $args{ 'log' } ); 
    60     $self->{ 'log_template' } = OmniPITR::Log->new( $args{ 'log_template' } ); 
     156    $self->{ 'log_template' } = $args{ 'log' }; 
     157    $self->{ 'log' }          = OmniPITR::Log->new( $self->{ 'log_template' } ); 
     158 
     159    # These could theoretically go into validation, but we need to check if we can get anything to {'segment'} 
     160    $self->log->fatal( 'WAL segment file name has not been given' ) if 0 == scalar @ARGV; 
     161    $self->log->fatal( 'More than 1 WAL segment file name has been given' ) if 1 < scalar @ARGV; 
     162 
     163    $self->{ 'segment' } = shift @ARGV; 
     164 
     165    $self->log->log( 'Called with parameters: %s', join( ' ', @argv_copy ) ) if $self->{ 'verbose' }; 
    61166 
    62167    return; 
     
    78183    } 
    79184 
     185    $self->log->fatal( 'Given segment name is not valid (%s)', $self->{ 'segment' } ) unless basename( $self->{ 'segment' } ) =~ m{\A[a-f0-9]{24}\z}; 
     186    my $segment_file_name = $self->{ 'segment' }; 
     187    $segment_file_name = File::Spec->catfile( $self->{ 'data-dir' }, $self->{ 'segment' } ) unless $self->{ 'segment' } =~ m{^/}; 
     188 
     189    $self->log->fatal( 'Given segment (%s) does not exist.',  $segment_file_name ) unless -e $segment_file_name; 
     190    $self->log->fatal( 'Given segment (%s) is not a file.',   $segment_file_name ) unless -f $segment_file_name; 
     191    $self->log->fatal( 'Given segment (%s) is not readable.', $segment_file_name ) unless -r $segment_file_name; 
     192 
     193    my $expected_size = 256**3; 
     194    my $file_size     = ( -s $segment_file_name ); 
     195    $self->log->fatal( 'Given segment (%s) has incorrect size (%u vs %u).', $segment_file_name, $file_size, $expected_size ) unless $expected_size == $file_size; 
     196 
     197    $self->{ 'segment' } = $segment_file_name; 
    80198    return; 
    81199}