You've already forked pgbackrest
							
							
				mirror of
				https://github.com/pgbackrest/pgbackrest.git
				synced 2025-10-30 23:37:45 +02:00 
			
		
		
		
	Working on copy.
This commit is contained in:
		| @@ -88,6 +88,15 @@ while ($strCommand ne OP_EXIT) | ||||
|  | ||||
|             $oRemote->output_write($oFile->exists(PATH_ABSOLUTE, $oParamHash{path}) ? "Y" : "N"); | ||||
|         } | ||||
|         elsif ($strCommand eq OP_FILE_COPY_IN) | ||||
|         { | ||||
|             if (!defined($oParamHash{destination_file})) | ||||
|             { | ||||
|                 confess "destination_file must be defined"; | ||||
|             } | ||||
|  | ||||
|             $oFile->copy(PIPE_STDOUT, undef, PATH_ABSOLUTE, $oParamHash{destination_file}); | ||||
|         } | ||||
|         else | ||||
|         { | ||||
|             if ($strCommand ne OP_NOOP) | ||||
|   | ||||
| @@ -188,33 +188,6 @@ sub clone | ||||
|     ); | ||||
| } | ||||
|  | ||||
| #################################################################################################################################### | ||||
| # ERROR_GET | ||||
| #################################################################################################################################### | ||||
| # sub error_get | ||||
| # { | ||||
| #     my $self = shift; | ||||
| # | ||||
| #     my $strErrorFile = $self->path_get(PATH_LOCK_ERR, "file"); | ||||
| # | ||||
| #     open my $hFile, '<', $strErrorFile or return "error opening ${strErrorFile} to read STDERR output"; | ||||
| # | ||||
| #     my $strError = do {local $/; <$hFile>}; | ||||
| #     close $hFile; | ||||
| # | ||||
| #     return trim($strError); | ||||
| # } | ||||
|  | ||||
| #################################################################################################################################### | ||||
| # ERROR_CLEAR | ||||
| #################################################################################################################################### | ||||
| # sub error_clear | ||||
| # { | ||||
| #     my $self = shift; | ||||
| # | ||||
| #     unlink($self->path_get(PATH_LOCK_ERR, "file")); | ||||
| # } | ||||
|  | ||||
| #################################################################################################################################### | ||||
| # PATH_TYPE_GET | ||||
| #################################################################################################################################### | ||||
| @@ -808,42 +781,30 @@ sub copy | ||||
|                 or confess &log(ERROR, "cannot open ${strDestinationTmpOp}: " . $!); | ||||
|         } | ||||
|     } | ||||
|  | ||||
|      | ||||
|     # If source or destination are remote | ||||
|     if ($bSourceRemote || $bDestinationRemote) | ||||
|     { | ||||
|         # Get the ssh connection | ||||
|         my $oSSH; | ||||
|  | ||||
|         # If source is local and destination is remote then use the destination connection | ||||
|         if (!$bSourceRemote && $bDestinationRemote) | ||||
|         { | ||||
|             $oSSH = $self->remote_get($strDestinationPathType); | ||||
|         } | ||||
|         # Else source connection is always used (because if both are remote they must be the same remote) | ||||
|         else | ||||
|         { | ||||
|             $oSSH = $self->remote_get($strSourcePathType); | ||||
|         } | ||||
|  | ||||
|         print "got outside\n"; | ||||
|         # Build the command and open the local file | ||||
|         my $hFile; | ||||
|         my $strCommand; | ||||
|         my $strOperation; | ||||
|         my %oParamHash; | ||||
|  | ||||
|         # If source is remote and destination is local | ||||
|         if ($bSourceRemote && !$bDestinationRemote) | ||||
|         { | ||||
|             # Build the command string | ||||
|             $strCommand = $self->{strCommand} . | ||||
|                           " --compress copy_in ${strSourceOp}"; | ||||
|             return false; | ||||
|         } | ||||
|         # Else if source is local and destination is remote | ||||
|         elsif (!$bSourceRemote && $bDestinationRemote) | ||||
|         { | ||||
|             # Build the command string | ||||
|             $strCommand = $self->{strCommand} . | ||||
|                           ($bCompress ? " --compress" : " --uncompress") . | ||||
|                           " copy_out ${strDestinationOp}"; | ||||
|             $strOperation = OP_FILE_COPY_IN; | ||||
|             $oParamHash{destination_file} = ${strDestinationOp}; | ||||
|  | ||||
|             # Build debug string | ||||
| #            $strDebug = "${strOperation}: remote (" . $self->{oRemote}->command_param_string(\%oParamHash) . "): " . $strDebug; | ||||
| #            &log(DEBUG, $strDebug); | ||||
|         } | ||||
|         # Else source and destination are remote | ||||
|         else | ||||
| @@ -858,24 +819,25 @@ sub copy | ||||
|         } | ||||
|  | ||||
|         # Trace command | ||||
|         &log(TRACE, "${strErrorPrefix} command:" . $strCommand); | ||||
|         &log(TRACE, "${strErrorPrefix} operation:" . $strOperation); | ||||
|  | ||||
|         # Execute the ssh command | ||||
|         my ($hIn, $hOut, $hErr, $pId) = $oSSH->open3($strCommand); | ||||
|         # Execute the operation | ||||
|         $self->{oRemote}->command_write($strOperation, \%oParamHash); | ||||
|  | ||||
|         # If source is remote and destination is local | ||||
|         if ($bSourceRemote && !$bDestinationRemote) | ||||
|         { | ||||
|             $self->pipe($hOut, $hDestinationFile, $bCompress, !$bCompress); | ||||
|             #$self->pipe($hOut, $hDestinationFile, $bCompress, !$bCompress); | ||||
|         } | ||||
|         # Else if source is local and destination is remote | ||||
|         elsif (!$bSourceRemote && $bDestinationRemote) | ||||
|         { | ||||
|             $self->pipe($hSourceFile, $hIn, $bCompress, !$bCompress); | ||||
|             $self->{oRemote}->binary_xfer($hSourceFile, $self->{hOut}, 'out'); | ||||
| #            $self->pipe($hSourceFile, $hIn, $bCompress, !$bCompress); | ||||
|         } | ||||
|  | ||||
|         # Wait for process exit (and error) | ||||
|         $self->wait_pid($pId, $strCommand, $hIn, $hOut, $hErr); | ||||
| #        $self->wait_pid($pId, $strCommand, $hIn, $hOut, $hErr); | ||||
|     } | ||||
|     else | ||||
|     { | ||||
|   | ||||
| @@ -33,6 +33,14 @@ has hIn => (is => 'bare');               # SSH object | ||||
| has hOut => (is => 'bare');               # SSH object | ||||
| has hErr => (is => 'bare');               # SSH object | ||||
|  | ||||
| #################################################################################################################################### | ||||
| # Remote xfer block size constant | ||||
| #################################################################################################################################### | ||||
| use constant | ||||
| { | ||||
|     BLOCK_SIZE  => 8192 | ||||
| }; | ||||
|  | ||||
| #################################################################################################################################### | ||||
| # CONSTRUCTOR | ||||
| #################################################################################################################################### | ||||
| @@ -178,6 +186,86 @@ sub error_write | ||||
|     } | ||||
| } | ||||
|  | ||||
| #################################################################################################################################### | ||||
| # BINARY_XFER | ||||
| # | ||||
| # Copies data from one file handle to another, optionally compressing or decompressing the data in stream. | ||||
| #################################################################################################################################### | ||||
| sub binary_xfer | ||||
| { | ||||
|     my $self = shift; | ||||
|     my $hIn = shift; | ||||
|     my $hOut = shift; | ||||
|     my $strRemote = shift; | ||||
|     my $bCompress = shift; | ||||
|  | ||||
|     my $bDone = false; | ||||
|     my $iBlockSize = BLOCK_SIZE; | ||||
|     my $iBlockIn; | ||||
|     my $strBlock; | ||||
|  | ||||
|     print "got to begin\n"; | ||||
|  | ||||
|     while (!$bDone) | ||||
|     { | ||||
|         if ($strRemote eq 'in') | ||||
|         { | ||||
|             my $strBlockHeader = readline($hIn); | ||||
|  | ||||
|             if ($strBlockHeader !~ /^block [0-9]+$/) | ||||
|             { | ||||
|                 confess "unable to read block header ${strBlockHeader}"; | ||||
|             } | ||||
|  | ||||
|             $iBlockSize = substr($strBlockHeader, index($strBlockHeader, " ") + 1); | ||||
|              | ||||
|             $iBlockIn = sysread($hIn, $strBlock, $iBlockSize); | ||||
|  | ||||
|             if (!defined($iBlockIn) || $iBlockIn != $iBlockSize) | ||||
|             { | ||||
|                 confess "unable to read ${iBlockSize} bytes from remote" . (defined($!) ? ": " . $! : ""); | ||||
|             } | ||||
|         } | ||||
|         else | ||||
|         { | ||||
|             if (!defined($bCompress)) | ||||
|             { | ||||
|                 $iBlockIn = sysread($hIn, $strBlock, $iBlockSize); | ||||
|                  | ||||
|                 if (!defined($iBlockIn)) | ||||
|                 { | ||||
|                     confess "unable to read ${iBlockSize} bytes from remote: " . $!; | ||||
|                 } | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         if ($iBlockIn > 0) | ||||
|         { | ||||
|             if ($strRemote eq 'out') | ||||
|             { | ||||
|                 print "wrote block header\n"; | ||||
|                  | ||||
|                 if (!syswrite($hOut, "block ${iBlockIn}")) | ||||
|                 { | ||||
|                     confess "unable to write block header"; | ||||
|                 } | ||||
|             } | ||||
|  | ||||
|             # Write to the output handle | ||||
|             my $iBlockOut = syswrite($hOut, $strBlock, $iBlockIn); | ||||
|  | ||||
|             if (!defined($iBlockOut) || $iBlockOut != $iBlockIn) | ||||
|             { | ||||
|                 confess "unable to write ${iBlockIn} bytes" . (defined($!) ? ": " . $! : ""); | ||||
|             } | ||||
|         } | ||||
|         else | ||||
|         { | ||||
|             $bDone = true; | ||||
|         } | ||||
|     } | ||||
| } | ||||
|  | ||||
| #################################################################################################################################### | ||||
| # OUTPUT_READ | ||||
| #################################################################################################################################### | ||||
| @@ -359,10 +447,10 @@ sub command_execute | ||||
| { | ||||
|     my $self = shift; | ||||
|     my $strCommand = shift; | ||||
|     my $strOptions = shift; | ||||
|     my $oParamRef = shift; | ||||
|     my $strErrorPrefix = shift; | ||||
|  | ||||
|     $self->command_write($strCommand, $strOptions); | ||||
|     $self->command_write($strCommand, $oParamRef); | ||||
|  | ||||
|     my ($strOutput, $bError, $iErrorCode) = $self->output_read(); | ||||
|  | ||||
|   | ||||
| @@ -380,8 +380,8 @@ sub log | ||||
|     } | ||||
|  | ||||
|     $strMessageFormat = sprintf("%4d-%02d-%02d %02d:%02d:%02d", $year+1900, $mon+1, $mday, $hour, $min, $sec) . | ||||
|                         (" " x (7 - length($strLevel))) . "${strLevel} " . (" " x (2 - length(threads->tid()))) . | ||||
|                         threads->tid() . ": ${strMessageFormat}" . | ||||
|                         sprintf(" T%02d", threads->tid()) . | ||||
|                         (" " x (7 - length($strLevel))) . "${strLevel}: ${strMessageFormat}" . | ||||
|                         (defined($iCode) ? " (code ${iCode})" : "") . "\n"; | ||||
|  | ||||
|     if ($oLogLevelRank{"${strLevel}"}{rank} <= $oLogLevelRank{"${strLogLevelConsole}"}{rank}) | ||||
|   | ||||
| @@ -671,7 +671,7 @@ sub BackRestFileTest | ||||
|                 { | ||||
|                     if ($oFile->hash(PATH_BACKUP_ABSOLUTE, $strFile) ne '06364afe79d801433188262478a76d19777ef351') | ||||
|                     { | ||||
|                         confess "bExists is set to ${bExists}, but exists() returned " . !$bExists; | ||||
|                         confess "incorrect hash returned"; | ||||
|                     } | ||||
|                 }; | ||||
|  | ||||
| @@ -790,10 +790,10 @@ sub BackRestFileTest | ||||
|     { | ||||
|         $iRun = 0; | ||||
|  | ||||
|         for (my $bBackupRemote = 0; $bBackupRemote <= 1; $bBackupRemote++) | ||||
|         for (my $bBackupRemote = 0; $bBackupRemote <= 0; $bBackupRemote++) | ||||
|         { | ||||
|             # Loop through source compression | ||||
|             for (my $bDbRemote = 0; $bDbRemote <= 1; $bDbRemote++) | ||||
|             for (my $bDbRemote = 1; $bDbRemote <= 1; $bDbRemote++) | ||||
|             { | ||||
|                 # Backup and db cannot both be remote | ||||
|                 if ($bBackupRemote && $bDbRemote) | ||||
| @@ -802,13 +802,14 @@ sub BackRestFileTest | ||||
|                 } | ||||
|  | ||||
|                 # Loop through destination compression | ||||
|                 for (my $bDestinationCompressed = 0; $bDestinationCompressed <= 1; $bDestinationCompressed++) | ||||
|                 for (my $bDestinationCompressed = 0; $bDestinationCompressed <= 0; $bDestinationCompressed++) | ||||
|                 { | ||||
|                     my $oFile = BackRest::File->new | ||||
|                     ( | ||||
|                         strStanza => "db", | ||||
|                         strCommand => $strCommand, | ||||
|                         bCompress => $bDestinationCompressed, | ||||
|                         strRemote => $bBackupRemote ? 'backup' : $bDbRemote ? 'db' : undef, | ||||
|                         strBackupClusterPath => undef, | ||||
|                         strBackupPath => ${strTestPath}, | ||||
|                         strBackupHost => $bBackupRemote ? $strHost : undef, | ||||
| @@ -817,14 +818,14 @@ sub BackRestFileTest | ||||
|                         strDbUser => $bDbRemote ? $strUser : undef | ||||
|                     ); | ||||
|  | ||||
|                     for (my $bSourceCompressed = 0; $bSourceCompressed <= 1; $bSourceCompressed++) | ||||
|                     for (my $bSourceCompressed = 0; $bSourceCompressed <= 0; $bSourceCompressed++) | ||||
|                     { | ||||
|                         for (my $bSourcePathType = 0; $bSourcePathType <= 1; $bSourcePathType++) | ||||
|                         for (my $bSourcePathType = 0; $bSourcePathType <= 0; $bSourcePathType++) | ||||
|                         { | ||||
|                             my $strSourcePathType = $bSourcePathType ? PATH_DB_ABSOLUTE : PATH_BACKUP_ABSOLUTE; | ||||
|                             my $strSourcePath = $bSourcePathType ? "db" : "backup"; | ||||
|  | ||||
|                             for (my $bDestinationPathType = 0; $bDestinationPathType <= 1; $bDestinationPathType++) | ||||
|                             for (my $bDestinationPathType = 1; $bDestinationPathType <= 1; $bDestinationPathType++) | ||||
|                             { | ||||
|                                 my $strDestinationPathType = $bDestinationPathType ? PATH_DB_ABSOLUTE : PATH_BACKUP_ABSOLUTE; | ||||
|                                 my $strDestinationPath = $bDestinationPathType ? "db" : "backup"; | ||||
|   | ||||
		Reference in New Issue
	
	Block a user