public function doUploadSnapshot($data, \Form $form)
{
$this->setCurrentActionType(self::ACTION_SNAPSHOT);
// Performs canView permission check by limiting visible projects
$project = $this->getCurrentProject();
if (!$project) {
return $this->project404Response();
}
$validEnvs = $project->DNEnvironmentList()->filterByCallback(function ($item) {
return $item->canUploadArchive();
});
// Validate $data['EnvironmentID'] by checking against $validEnvs.
$environment = $validEnvs->find('ID', $data['EnvironmentID']);
if (!$environment) {
throw new LogicException('Invalid environment');
}
$this->validateSnapshotMode($data['Mode']);
$dataArchive = DNDataArchive::create(['AuthorID' => Member::currentUserID(), 'EnvironmentID' => $data['EnvironmentID'], 'IsManualUpload' => true]);
// needs an ID and transfer to determine upload path
$dataArchive->write();
$dataTransfer = DNDataTransfer::create(['AuthorID' => Member::currentUserID(), 'Mode' => $data['Mode'], 'Origin' => 'ManualUpload', 'EnvironmentID' => $data['EnvironmentID']]);
$dataTransfer->write();
$dataArchive->DataTransfers()->add($dataTransfer);
$form->saveInto($dataArchive);
$dataArchive->write();
$workingDir = TEMP_FOLDER . DIRECTORY_SEPARATOR . 'deploynaut-transfer-' . $dataTransfer->ID;
$cleanupFn = function () use($workingDir, $dataTransfer, $dataArchive) {
$process = new AbortableProcess(sprintf('rm -rf %s', escapeshellarg($workingDir)));
$process->setTimeout(120);
$process->run();
$dataTransfer->delete();
$dataArchive->delete();
};
// extract the sspak contents so we can inspect them
try {
$dataArchive->extractArchive($workingDir);
} catch (Exception $e) {
$cleanupFn();
$form->sessionMessage('There was a problem trying to open your snapshot for processing. Please try uploading again', 'bad');
return $this->redirectBack();
}
// validate that the sspak contents match the declared contents
$result = $dataArchive->validateArchiveContents();
if (!$result->valid()) {
$cleanupFn();
$form->sessionMessage($result->message(), 'bad');
return $this->redirectBack();
}
// fix file permissions of extracted sspak files then re-build the sspak
try {
$dataArchive->fixArchivePermissions($workingDir);
$dataArchive->setArchiveFromFiles($workingDir);
} catch (Exception $e) {
$cleanupFn();
$form->sessionMessage('There was a problem processing your snapshot. Please try uploading again', 'bad');
return $this->redirectBack();
}
// cleanup any extracted sspak contents lying around
$process = new AbortableProcess(sprintf('rm -rf %s', escapeshellarg($workingDir)));
$process->setTimeout(120);
$process->run();
return $this->customise(['Project' => $project, 'CurrentProject' => $project, 'SnapshotsSection' => 1, 'DataArchive' => $dataArchive, 'DataTransferRestoreForm' => $this->getDataTransferRestoreForm($this->request, $dataArchive), 'BackURL' => $project->Link('snapshots')])->renderWith(['DNRoot_uploadsnapshot', 'DNRoot']);
}