Newer
Older
backup-commander / html / svc / backup.php
<?php

/**
 * This file is used by the child forks to run a single backup.
 * 
 * The parent handles database activity on a single thread using the SQLite DB. This file
 * should not open a DB connection. Instead it should deligate the work to the parent which
 * can be done using the RPC layer.
 */

$g_data_dir="data";

include_once "../shd/backup-funcs.php";


/**
 * Set (unset) the running datbase flag. Return true on success. The flag is
 * unaltered if running in test mode.
 */
function set_bu_running( $id, bool $setit, bool $bu_test ){
	
	if($bu_test) return true;

	[$err] = rpc( 'f:set_bu_running', $id, (bool)$setit );
	return $err;
}


/**
 * Runs a single backup and blocks until the backup is finished.
 */
function run_backup_block( $buid, $row, $bu_test ){
	
	//$row = get_bu_item( $buid );
		
	if( !$bu_test && $row[5]==1){
		return "Backup for item($buid) is already running\n";		
	}

	$bu_name = $row[0];
	$bu_src = $row[1];
	$bu_dest = $row[2];
	$exFiles = $row[3];
	$bu_type = $row[4];
	$bu_rnng = $row[5];

	// To ensure uniqueness, we add the backup ID on the end of the path as a subdirectory.	
	$bu_dest = "$bu_dest/bu_$buid";

	// Make sure that the directory exists
	if( !file_exists($bu_dest) ) {
		if( false===mkdir( $bu_dest, 0777, true )){
			return "Failed to create directory $bu_dest";
		}
	}
	
	if($bu_type==1 ){
		return run_backup_DB( $bu_test, $buid, $bu_src, $bu_dest );	
	}	

	return run_backup_F( $bu_test, $buid, $bu_src, $bu_dest, $exFiles );
}


/**
 * This function is now used directly by the backup service.
 */
function run_backup_F( $bu_test, $buid, $bu_src, $bu_dest, $exFiles ){
	
	global $g_data_dir;
	
	/*if(!set_bu_running( $buid, true, $bu_test )){
		return "Could not set the DB flag ";//.SQLite3::lastErrorMsg();		
	}*/

	$flags = '-anv';
	if($bu_test){
		$flags = '-anv';	// n is the dry run indicator
	}else{		
		$flags = '-av';
		rpc( 'f:set_bu_error', $buid, '' );		//clear any previous error		
		rpc( 'f:set_last_run_date', $buid, gmdate("Y-m-d H:i:s") );
	}

	$fn_o = getFilename_out( $buid, $bu_test, false );
	$fn_e = getFilename_out( $buid, $bu_test, true );

	//print("***** output file is $g_data_dir/$fn_o \n");

	// create the output files with the ID in the first line
	file_put_contents("$g_data_dir/$fn_o","ID: $buid\n");
	file_put_contents("$g_data_dir/$fn_e","ID: $buid\n");



	if( !file_exists( "$g_data_dir/$fn_e" )){   	  
	  return "exec failed to create file $fn_e";
	}

	$str_exPaths = '';
	if(trim( $exFiles )!=''){
		$fn_x = getFilename_tmp( $buid, 'x' );
		file_put_contents( "$g_data_dir/$fn_x", $exFiles );
		$str_exPaths = "--exclude-from=$g_data_dir/$fn_x";
	}

	// bash command
	//rsync -a --exclude-from=to-exclude.txt $PATH_SRC $BKUP_DEST
	//rsync -anv --exclude-from=to-exclude.txt $PATH_SRC $BKUP_DEST	<-- for testing
	$command = "rsync $flags $str_exPaths $bu_src $bu_dest 2>> $g_data_dir/$fn_e 1>> $g_data_dir/$fn_o";

	$output = array();
	$result_code = null;
	if( exec( $command, $output, $result_code )===FALSE){		
		//set_bu_running( $buid, false, $bu_test );
		return "rsync failed";
	}	
	//set_bu_running( $buid, false, $bu_test );

//print("***** command is\n$command\n");
//print("***** test is ". file_get_contents("$g_data_dir/$fn_o") ."\n");

	// can we find any error strings in the error file?
	$str_errs = file_get_contents( "$g_data_dir/$fn_e" );
	$pos = strpos($str_errs, 'error' );
	if($pos===FALSE){
		$pos = strpos($str_errs, 'failed' );
	}
	if($pos===FALSE ){
		if(!$bu_test){
			unlink("$g_data_dir/$fn_e");
			unlink("$g_data_dir/$fn_o");
		}
		return;
	}

	//place it in the database	
	rpc( 'f:set_bu_error', $buid, $str_errs );
}


/**
 * This function is now used directly by the backup service.
 */
function run_backup_DB( $bu_test, $buid, $bu_src, $bu_dest ){

	global $g_data_dir;

	/*if(!set_bu_running( $buid, true, $bu_test )){
		return "Could not set the DB flag";		
	}*/
	
	if(!is_dir($bu_dest) ){
		return "Destination ($bu_dest) is not a directory";
	}

	if($bu_test){
		$fn_o = getFilename_out( $buid, $bu_test, false );		
		$bu_dest = "$g_data_dir";
	}else{
		$fn_o = "$bu_src.sql";		
		rpc( 'f:set_bu_error', $buid, '' );	//clear any previous error		
		rpc( 'f:set_last_run_date', $buid, gmdate("Y-m-d H:i:s") );
	}

	// create the error files with the ID in the first line
	$fn_e = getFilename_out( $buid, $bu_test, true );
	exec("echo 'ID: $buid' > $g_data_dir/$fn_e");

	// bash command
	//mysqldump johntest > /home/johnp/tmp/dbs/johntest.sql
		
	$command = "mysqldump $bu_src 2>> $g_data_dir/$fn_e 1>> $bu_dest/$fn_o";

	$output = array();
	$result_code = null;
	if( exec( $command, $output, $result_code )===FALSE){		
		//set_bu_running( $buid, false, $bu_test );
		return "mysqldump failed";
	}	
	//set_bu_running( $buid, false, $bu_test );

	// can we find any error strings in the error file?
	$str_errs = file_get_contents( "$g_data_dir/$fn_e" );
	$pos = strpos($str_errs, 'error' );
	if($pos===FALSE){
		$pos = strpos($str_errs, 'failed' );
	}
	if($pos===FALSE){
		unlink("$g_data_dir/$fn_e");
		return;
	}

	//place it in the database
	rpc( 'f:set_bu_error', $buid, $str_errs );

}


?>