public function perform() { echo "[-] DataTransferJob starting" . PHP_EOL; $log = new DeploynautLogFile($this->args['logfile']); $project = $this->DNData()->DNProjectList()->filter('Name', $this->args['projectName'])->First(); $dataTransfer = DNDataTransfer::get()->byID($this->args['dataTransferID']); $environment = $dataTransfer->Environment(); $backupJob = null; if ($dataTransfer->Direction == 'push') { $backupJob = new DNDataTransfer(); $backupJob->EnvironmentID = $environment->ID; $backupJob->Direction = 'get'; $backupJob->Mode = $dataTransfer->Mode; $backupJob->DataArchiveID = null; $backupJob->ResqueToken = $dataTransfer->ResqueToken; $backupJob->AuthorID = $dataTransfer->AuthorID; $backupJob->write(); $dataTransfer->BackupDataTransferID = $backupJob->ID; $dataTransfer->write(); } // This is a bit icky, but there is no easy way of capturing a failed run by using the PHP Resque try { // Disallow concurrent jobs (don't rely on queuing implementation to restrict this) $runningTransfers = DNDataTransfer::get()->filter(array('EnvironmentID' => $environment->ID, 'Status' => array('Queued', 'Started')))->exclude('ID', $dataTransfer->ID); if ($runningTransfers->count()) { $runningTransfer = $runningTransfers->First(); throw new RuntimeException(sprintf('[-] Error: another transfer seems to be already in progress (started at %s by %s)', $runningTransfer->dbObject('Created')->Nice(), $runningTransfer->Author()->Title)); } // before we push data to an environment, we'll make a backup first if ($backupJob) { $log->write('Backing up existing data'); $this->DNData()->Backend()->dataTransfer($backupJob, $log); } $this->DNData()->Backend()->dataTransfer($dataTransfer, $log); } catch (RuntimeException $exc) { $log->write($exc->getMessage()); if ($backupJob) { $backupJob->Status = 'Failed'; $backupJob->write(); } $this->updateStatus('Failed'); echo "[-] DataTransferJob failed" . PHP_EOL; throw $exc; } if ($backupJob) { $backupJob->Status = 'Finished'; $backupJob->write(); } echo "[-] DataTransferJob finished" . PHP_EOL; }
public function testGenerateFileName() { $project1 = $this->objFromFixture('DNProject', 'project1'); $project1uatEnv = $this->objFromFixture('DNEnvironment', 'project1-uat'); $dataTransfer = new DNDataTransfer(); $dataTransfer->Direction = 'get'; $dataTransfer->Mode = 'all'; $dataTransfer->write(); $archive = new DNDataArchive(); $archive->OriginalEnvironmentID = $project1uatEnv->ID; $archive->write(); $filename = $archive->generateFilename($dataTransfer); $this->assertNotNull($filename); $this->assertContains('project_1', $filename); $this->assertContains('uat', $filename); $this->assertContains('all', $filename); }
/** * Attach an sspak file path to this archive and associate the transfer. * Does the job of creating a {@link File} record, and setting correct paths into the assets directory. * * @param string $sspakFilepath * @param DNDataTransfer $dataTransfer * @return bool */ public function attachFile($sspakFilepath, DNDataTransfer $dataTransfer) { $sspakFilepath = ltrim(str_replace(array(ASSETS_PATH, realpath(ASSETS_PATH)), '', $sspakFilepath), DIRECTORY_SEPARATOR); $folder = Folder::find_or_make(dirname($sspakFilepath)); $file = new File(); $file->Name = basename($sspakFilepath); $file->Filename = $sspakFilepath; $file->ParentID = $folder->ID; $file->write(); // "Status" will be updated by the job execution $dataTransfer->write(); // Get file hash to ensure consistency. // Only do this when first associating the file since hashing large files is expensive. // Note that with CapistranoDeploymentBackend the file won't be available yet, as it // gets put in place immediately after this method gets called. In which case, it will // be hashed in setArchiveFromFiles() if (file_exists($file->FullPath)) { $this->ArchiveFileHash = md5_file($file->FullPath); } $this->ArchiveFileID = $file->ID; $this->DataTransfers()->add($dataTransfer); $this->write(); return true; }
public function doDataTransfer($data, $form) { // Performs canView permission check by limiting visible projects $project = $this->getCurrentProject(); if (!$project) { return new SS_HTTPResponse("Project '" . Convert::raw2xml($this->getRequest()->latestParam('Project')) . "' not found.", 404); } $member = Member::currentUser(); $dataArchive = null; // Validate direction. if ($data['Direction'] == 'get') { $validEnvs = $this->getCurrentProject()->DNEnvironmentList()->filterByCallback(function ($item) { return $item->canBackup(); }); } else { if ($data['Direction'] == 'push') { $validEnvs = $this->getCurrentProject()->DNEnvironmentList()->filterByCallback(function ($item) { return $item->canRestore(); }); } else { throw new LogicException('Invalid direction'); } } // Validate $data['EnvironmentID'] by checking against $validEnvs. $environment = $validEnvs->find('ID', $data['EnvironmentID']); if (!$environment) { throw new LogicException('Invalid environment'); } // Validate mode. if (!in_array($data['Mode'], array('all', 'assets', 'db'))) { throw new LogicException('Invalid mode'); } // Only 'push' direction is allowed an association with an existing archive. if ($data['Direction'] == 'push' && isset($data['DataArchiveID']) && is_numeric($data['DataArchiveID'])) { $dataArchive = DNDataArchive::get()->byId($data['DataArchiveID']); if (!$dataArchive) { throw new LogicException('Invalid data archive'); } if (!$dataArchive->canDownload()) { throw new SS_HTTPResponse_Exception('Not allowed to access archive', 403); } } $job = new DNDataTransfer(); $job->EnvironmentID = $environment->ID; $job->Direction = $data['Direction']; $job->Mode = $data['Mode']; $job->DataArchiveID = $dataArchive ? $dataArchive->ID : null; $job->write(); $job->start(); $this->redirect($job->Link()); }
/** * Attach an sspak file path to this archive and associate the transfer. * Does the job of creating a {@link File} record, and setting correct paths into the assets directory. * * @param string $sspakFilepath * @param DNDataTransfer $dataTransfer * @return bool */ public function attachFile($sspakFilepath, DNDataTransfer $dataTransfer) { $sspakFilepath = ltrim(str_replace(array(ASSETS_PATH, realpath(ASSETS_PATH)), '', $sspakFilepath), DIRECTORY_SEPARATOR); $folder = Folder::find_or_make(dirname($sspakFilepath)); $file = new File(); $file->Name = basename($sspakFilepath); $file->Filename = $sspakFilepath; $file->ParentID = $folder->ID; $file->write(); // "Status" will be updated by the job execution $dataTransfer->write(); $this->ArchiveFileID = $file->ID; $this->DataTransfers()->add($dataTransfer); $this->write(); return true; }