/** * @param \Akeeba\Engine\Archiver\Base $archiver * @param \Akeeba\Engine\Configuration $configuration * * @return bool */ protected function postProcessDonePartFile(\Akeeba\Engine\Archiver\Base $archiver, \Akeeba\Engine\Configuration $configuration) { $filename = array_shift($archiver->finishedPart); Factory::getLog()->log(LogLevel::INFO, 'Preparing to post process ' . basename($filename)); $timer = Factory::getTimer(); $startTime = $timer->getRunningTime(); $post_proc = Factory::getPostprocEngine(); $result = $post_proc->processPart($filename); $this->propagateFromObject($post_proc); if ($result === false) { Factory::getLog()->log(LogLevel::WARNING, 'Failed to process file ' . $filename); Factory::getLog()->log(LogLevel::WARNING, 'Error received from the post-processing engine:'); Factory::getLog()->log(LogLevel::WARNING, implode("\n", array_merge($this->getWarnings(), $this->getErrors()))); $this->setWarning('Failed to process file ' . basename($filename)); } elseif ($result === true) { // Add this part's size to the volatile storage $volatileTotalSize = $configuration->get('volatile.engine.archiver.totalsize', 0); $volatileTotalSize += (int) @filesize($filename); $configuration->set('volatile.engine.archiver.totalsize', $volatileTotalSize); Factory::getLog()->log(LogLevel::INFO, 'Successfully processed file ' . basename($filename)); } else { // More work required Factory::getLog()->log(LogLevel::INFO, 'More post-processing steps required for file ' . $filename); $configuration->set('volatile.postproc.filename', $filename); // Let's push back the file into the archiver stack array_unshift($archiver->finishedPart, $filename); // Do we need to break the step? $endTime = $timer->getRunningTime(); $stepTime = $endTime - $startTime; $timeLeft = $timer->getTimeLeft(); if ($timeLeft < $stepTime) { // We predict that running yet another step would cause a timeout $configuration->set('volatile.breakflag', true); } else { // We have enough time to run yet another step $configuration->set('volatile.breakflag', false); } } // Should we delete the file afterwards? if ($configuration->get('engine.postproc.common.delete_after', false) && $post_proc->allow_deletes && $result === true) { Factory::getLog()->log(LogLevel::DEBUG, 'Deleting already processed file ' . basename($filename)); Platform::getInstance()->unlink($filename); } else { Factory::getLog()->log(LogLevel::DEBUG, 'Not removing processed file ' . $filename); } if ($post_proc->break_after && $result === true) { $configuration->set('volatile.breakflag', true); return true; } // This is required to let the backup continue even after a post-proc failure $this->resetErrors(); $this->setState('running'); return false; }
/** * @param \Akeeba\Engine\Archiver\Base $archiver * @param \Akeeba\Engine\Configuration $configuration * * @return bool */ protected function postProcessDonePartFile(\Akeeba\Engine\Archiver\Base $archiver, \Akeeba\Engine\Configuration $configuration) { $filename = array_shift($archiver->finishedPart); Factory::getLog()->log(LogLevel::INFO, 'Preparing to post process ' . basename($filename)); // Add this part's size to the volatile storage $volatileTotalSize = $configuration->get('volatile.engine.archiver.totalsize', 0); $volatileTotalSize += (int) @filesize($filename); $configuration->set('volatile.engine.archiver.totalsize', $volatileTotalSize); $post_proc = Factory::getPostprocEngine(); $result = $post_proc->processPart($filename); $this->propagateFromObject($post_proc); if ($result === false) { $this->setWarning('Failed to process file ' . basename($filename)); } else { Factory::getLog()->log(LogLevel::INFO, 'Successfully processed file ' . basename($filename)); } // Should we delete the file afterwards? if ($configuration->get('engine.postproc.common.delete_after', false) && $post_proc->allow_deletes && $result !== false) { Factory::getLog()->log(LogLevel::DEBUG, 'Deleting already processed file ' . basename($filename)); Platform::getInstance()->unlink($filename); } if ($post_proc->break_after && $result !== false) { $configuration->set('volatile.breakflag', true); return true; } // This is required to let the backup continue even after a post-proc failure $this->resetErrors(); $this->setState('running'); return false; }
/** * Runs a custom API call for the selected post-processing engine * * @return boolean */ public function dpeCustomAPICall() { $engine = $this->getState('engine'); $method = $this->getState('method'); $params = $this->getState('params', array()); // Get the Input object $params['input'] = $this->input->getData(); $engineObject = Factory::getPostprocEngine($engine); if ($engineObject === false) { return false; } return $engineObject->customApiCall($method, $params); }
/** * Apply quotas for remotely stored files * * @return bool True on success */ protected function apply_remote_quotas() { $this->setStep('Applying remote storage quotas'); $this->setSubstep(''); // Make sure we are enabled $config = Factory::getConfiguration(); $enableRemote = $config->get('akeeba.quota.remote', 0); if (!$enableRemote) { return true; } // Get the list of files to kill if (empty($this->remote_files_killlist)) { Factory::getLog()->log(LogLevel::DEBUG, 'Applying remote file quotas'); $this->remote_files_killlist = $this->get_remote_quotas(); if (empty($this->remote_files_killlist)) { Factory::getLog()->log(LogLevel::DEBUG, 'No remote files to apply quotas to were found'); return true; } } // Remove the files $timer = Factory::getTimer(); while ($timer->getRunningTime() && count($this->remote_files_killlist)) { $filename = array_shift($this->remote_files_killlist); list($engineName, $path) = explode('://', $filename); $engine = Factory::getPostprocEngine($engineName); if (!$engine->can_delete) { continue; } Factory::getLog()->log(LogLevel::DEBUG, "Removing {$filename}"); $result = $engine->delete($path); if (!$result) { Factory::getLog()->log(LogLevel::DEBUG, "Removal failed: " . $engine->getWarning()); } } // Return false if we have more work to do or true if we're done if (count($this->remote_files_killlist)) { Factory::getLog()->log(LogLevel::DEBUG, "Remote file removal will continue in the next step"); return false; } else { Factory::getLog()->log(LogLevel::DEBUG, "Remote file quotas applied successfully"); return true; } }
/** * Implements the _run() abstract method */ protected function _run() { // Check if we are already done if ($this->getState() == 'postrun') { Factory::getLog()->log(LogLevel::DEBUG, __CLASS__ . " :: Already finished"); $this->setStep(""); $this->setSubstep(""); return; } // Mark ourselves as still running (we will test if we actually do towards the end ;) ) $this->setState('running'); // Check if we are still adding a database dump part to the archive, or if // we have to post-process a part if (Factory::getEngineParamsProvider()->getScriptingParameter('db.saveasname', 'normal') != 'output') { $archiver = Factory::getArchiverEngine(); $configuration = Factory::getConfiguration(); if ($configuration->get('engine.postproc.common.after_part', 0)) { if (!empty($archiver->finishedPart)) { $filename = array_shift($archiver->finishedPart); Factory::getLog()->log(LogLevel::INFO, 'Preparing to post process ' . basename($filename)); $timer = Factory::getTimer(); $startTime = $timer->getRunningTime(); $post_proc = Factory::getPostprocEngine(); $result = $post_proc->processPart($filename); $this->propagateFromObject($post_proc); if ($result === false) { Factory::getLog()->log(LogLevel::WARNING, 'Failed to process file ' . $filename); Factory::getLog()->log(LogLevel::WARNING, 'Error received from the post-processing engine:'); Factory::getLog()->log(LogLevel::WARNING, implode("\n", array_merge($this->getWarnings(), $this->getErrors()))); $this->setWarning('Failed to process file ' . basename($filename)); } elseif ($result === true) { // Add this part's size to the volatile storage $volatileTotalSize = $configuration->get('volatile.engine.archiver.totalsize', 0); $volatileTotalSize += (int) @filesize($filename); $configuration->set('volatile.engine.archiver.totalsize', $volatileTotalSize); Factory::getLog()->log(LogLevel::INFO, 'Successfully processed file ' . basename($filename)); } else { // More work required Factory::getLog()->log(LogLevel::INFO, 'More post-processing steps required for file ' . $filename); $configuration->set('volatile.postproc.filename', $filename); // Let's push back the file into the archiver stack array_unshift($archiver->finishedPart, $filename); // Do we need to break the step? $endTime = $timer->getRunningTime(); $stepTime = $endTime - $startTime; $timeLeft = $timer->getTimeLeft(); if ($timeLeft < $stepTime) { // We predict that running yet another step would cause a timeout $configuration->set('volatile.breakflag', true); } else { // We have enough time to run yet another step $configuration->set('volatile.breakflag', false); } } // Should we delete the file afterwards? if ($configuration->get('engine.postproc.common.delete_after', false) && $post_proc->allow_deletes && $result === true) { Factory::getLog()->log(LogLevel::DEBUG, 'Deleting already processed file ' . basename($filename)); Platform::getInstance()->unlink($filename); } if ($post_proc->break_after) { $configuration->set('volatile.breakflag', true); return; } } } if ($configuration->get('volatile.engine.archiver.processingfile', false)) { // We had already started archiving the db file, but it needs more time $finished = true; Factory::getLog()->log(LogLevel::DEBUG, "Continuing adding the SQL dump part to the archive"); $archiver->addFile(null, null, null); $this->propagateFromObject($archiver); if ($this->getError()) { return; } $finished = !$configuration->get('volatile.engine.archiver.processingfile', false); if ($finished) { $this->getNextDumpPart(); } else { return; } } } $this->stepDatabaseDump(); $null = null; $this->writeline($null); }
/** * Runs a custom API call for the selected post-processing engine * * @return boolean */ public function dpeCustomAPICall() { $engine = $this->getState('engine'); $method = $this->getState('method'); $params = $this->getState('params', array()); $engine = Factory::getPostprocEngine($engine); if ($engine === false) { return false; } return $engine->customApiCall($method, $params); }