Exemple #1
0
 /**
  * @param array $data
  * @param Form $form
  *
  * @return SS_HTTPResponse
  */
 public function doPostSnapshot($data, $form)
 {
     $this->setCurrentActionType(self::ACTION_SNAPSHOT);
     $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');
     }
     $dataArchive = DNDataArchive::create(array('UploadToken' => DNDataArchive::generate_upload_token()));
     $form->saveInto($dataArchive);
     $dataArchive->write();
     return $this->redirect(Controller::join_links($project->Link(), 'postsnapshotsuccess', $dataArchive->ID));
 }
 /**
  * Backs up database and/or assets to a designated folder,
  * and packs up the files into a single sspak.
  *
  * @param  DNDataTransfer    $dataTransfer
  * @param  DeploynautLogFile $log
  */
 protected function dataTransferBackup(DNDataTransfer $dataTransfer, DeploynautLogFile $log)
 {
     $environment = $dataTransfer->Environment();
     $name = $environment->getFullName();
     // Associate a new archive with the transfer.
     // Doesn't retrieve a filepath just yet, need to generate the files first.
     $dataArchive = DNDataArchive::create();
     $dataArchive->Mode = $dataTransfer->Mode;
     $dataArchive->AuthorID = $dataTransfer->AuthorID;
     $dataArchive->OriginalEnvironmentID = $environment->ID;
     $dataArchive->EnvironmentID = $environment->ID;
     $dataArchive->IsBackup = $dataTransfer->IsBackupDataTransfer();
     // Generate directory structure with strict permissions (contains very sensitive data)
     $filepathBase = $dataArchive->generateFilepath($dataTransfer);
     mkdir($filepathBase, 0700, true);
     $databasePath = $filepathBase . DIRECTORY_SEPARATOR . 'database.sql';
     // Backup database
     if (in_array($dataTransfer->Mode, array('all', 'db'))) {
         $log->write(sprintf('Backup of database from "%s" started', $name));
         $command = $this->getCommand('data:getdb', 'db', $environment, array('data_path' => $databasePath), $log);
         $command->run(function ($type, $buffer) use($log) {
             $log->write($buffer);
         });
         if (!$command->isSuccessful()) {
             $this->extend('dataTransferFailure', $environment, $log);
             throw new RuntimeException($command->getErrorOutput());
         }
         $log->write(sprintf('Backup of database from "%s" done', $name));
     }
     // Backup assets
     if (in_array($dataTransfer->Mode, array('all', 'assets'))) {
         $log->write(sprintf('Backup of assets from "%s" started', $name));
         $command = $this->getCommand('data:getassets', 'web', $environment, array('data_path' => $filepathBase), $log);
         $command->run(function ($type, $buffer) use($log) {
             $log->write($buffer);
         });
         if (!$command->isSuccessful()) {
             $this->extend('dataTransferFailure', $environment, $log);
             throw new RuntimeException($command->getErrorOutput());
         }
         $log->write(sprintf('Backup of assets from "%s" done', $name));
     }
     $sspakFilename = sprintf('%s.sspak', $dataArchive->generateFilename($dataTransfer));
     $sspakFilepath = $filepathBase . DIRECTORY_SEPARATOR . $sspakFilename;
     try {
         $dataArchive->attachFile($sspakFilepath, $dataTransfer);
         $dataArchive->setArchiveFromFiles($filepathBase);
     } catch (Exception $e) {
         $log->write($e->getMessage());
         throw new RuntimeException($e->getMessage());
     }
     // Remove any assets and db files lying around, they're not longer needed as they're now part
     // of the sspak file we just generated. Use --force to avoid errors when files don't exist,
     // e.g. when just an assets backup has been requested and no database.sql exists.
     $process = new Process(sprintf('rm -rf %s/assets && rm -f %s', $filepathBase, $databasePath));
     $process->run();
     if (!$process->isSuccessful()) {
         $log->write('Could not delete temporary files');
         throw new RuntimeException($process->getErrorOutput());
     }
     $log->write(sprintf('Creating sspak file done: %s', $dataArchive->ArchiveFile()->getAbsoluteURL()));
 }
 /**
  * Backs up database and/or assets to a designated folder,
  * and packs up the files into a single sspak.
  *
  * @param  DNDataTransfer    $dataTransfer
  * @param  DeploynautLogFile $log
  */
 protected function dataTransferBackup(DNDataTransfer $dataTransfer, DeploynautLogFile $log)
 {
     $environmentObj = $dataTransfer->Environment();
     $project = $environmentObj->Project();
     $projectName = $project->Name;
     $environmentName = $environmentObj->Name;
     $env = $project->getProcessEnv();
     $project = DNProject::get()->filter('Name', $projectName)->first();
     $name = $projectName . ':' . $environmentName;
     // Associate a new archive with the transfer.
     // Doesn't retrieve a filepath just yet, need to generate the files first.
     $dataArchive = DNDataArchive::create();
     $dataArchive->Mode = $dataTransfer->Mode;
     $dataArchive->AuthorID = $dataTransfer->AuthorID;
     $dataArchive->OriginalEnvironmentID = $dataTransfer->Environment()->ID;
     $dataArchive->EnvironmentID = $dataTransfer->Environment()->ID;
     $dataArchive->IsBackup = $dataTransfer->IsBackupDataTransfer();
     // Generate directory structure with strict permissions (contains very sensitive data)
     $filepathBase = $dataArchive->generateFilepath($dataTransfer);
     mkdir($filepathBase, 0700, true);
     $databasePath = $filepathBase . DIRECTORY_SEPARATOR . 'database.sql';
     // Backup database
     if (in_array($dataTransfer->Mode, array('all', 'db'))) {
         $log->write('Backup of database from "' . $name . '" started');
         $args = array('data_path' => $databasePath);
         $command = $this->getCommand("data:getdb", 'db', $name, $args, $env, $log);
         $command->run(function ($type, $buffer) use($log) {
             $log->write($buffer);
         });
         if (!$command->isSuccessful()) {
             throw new RuntimeException($command->getErrorOutput());
         }
         $log->write('Backup of database from "' . $name . '" done');
     }
     // Backup assets
     if (in_array($dataTransfer->Mode, array('all', 'assets'))) {
         $log->write('Backup of assets from "' . $name . '" started');
         $args = array('data_path' => $filepathBase);
         $command = $this->getCommand("data:getassets", 'web', $name, $args, $env, $log);
         $command->run(function ($type, $buffer) use($log) {
             $log->write($buffer);
         });
         if (!$command->isSuccessful()) {
             throw new RuntimeException($command->getErrorOutput());
         }
         $log->write('Backup of assets from "' . $name . '" done');
     }
     $log->write('Creating *.sspak file');
     $sspakFilename = sprintf('%s.sspak', $dataArchive->generateFilename($dataTransfer));
     $sspakCmd = sprintf('cd %s && sspak saveexisting %s 2>&1', $filepathBase, $sspakFilename);
     if ($dataTransfer->Mode == 'db') {
         $sspakCmd .= sprintf(' --db=%s', $databasePath);
     } elseif ($dataTransfer->Mode == 'assets') {
         $sspakCmd .= sprintf(' --assets=%s/assets', $filepathBase);
     } else {
         $sspakCmd .= sprintf(' --db=%s --assets=%s/assets', $databasePath, $filepathBase);
     }
     $process = new Process($sspakCmd);
     $process->setTimeout(3600);
     $process->run();
     if (!$process->isSuccessful()) {
         $log->write('Could not package the backup via sspak');
         throw new RuntimeException($process->getErrorOutput());
     }
     // HACK: find_or_make() expects path relative to assets/
     $sspakFilepath = ltrim(str_replace(array(ASSETS_PATH, realpath(ASSETS_PATH)), '', $filepathBase . DIRECTORY_SEPARATOR . $sspakFilename), DIRECTORY_SEPARATOR);
     try {
         $folder = Folder::find_or_make(dirname($sspakFilepath));
         $file = new File();
         $file->Name = $sspakFilename;
         $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.
         $dataArchive->ArchiveFileHash = md5_file($file->FullPath);
         $dataArchive->ArchiveFileID = $file->ID;
         $dataArchive->DataTransfers()->add($dataTransfer);
         $dataArchive->write();
     } catch (Exception $e) {
         $log->write('Failed to add sspak file: ' . $e->getMessage());
         throw new RuntimeException($e->getMessage());
     }
     // Remove any assets and db files lying around, they're not longer needed as they're now part
     // of the sspak file we just generated. Use --force to avoid errors when files don't exist,
     // e.g. when just an assets backup has been requested and no database.sql exists.
     $process = new Process(sprintf('rm -rf %s/assets && rm -f %s', $filepathBase, $databasePath));
     $process->run();
     if (!$process->isSuccessful()) {
         $log->write('Could not delete temporary files');
         throw new RuntimeException($process->getErrorOutput());
     }
     $log->write(sprintf('Creating *.sspak file done: %s', $file->getAbsoluteURL()));
 }
 public function testCanMoveTo()
 {
     $samantha = $this->objFromFixture('Member', 'project1-samantha');
     $sarah = $this->objFromFixture('Member', 'project1-sarah');
     $eva = $this->objFromFixture('Member', 'eva');
     $uat1 = $this->objFromFixture('DNEnvironment', 'project1-uat');
     $live1 = $this->objFromFixture('DNEnvironment', 'project1-live');
     $uat2 = $this->objFromFixture('DNEnvironment', 'project2-uat');
     $live2 = $this->objFromFixture('DNEnvironment', 'project2-live');
     $archive = DNDataArchive::create();
     $archive->EnvironmentID = $uat1->ID;
     $archive->write();
     // Samantha doesn't have upload permission to live1.
     $this->assertFalse($archive->canMoveTo($live1, $samantha));
     // Cross-project moves are forbidden.
     $this->assertFalse($archive->canMoveTo($uat2, $samantha));
     // Eva has upload permission to live1.
     $this->assertTrue($archive->canMoveTo($live1, $eva));
     // Cross-project moves are forbidden.
     $this->assertFalse($archive->canMoveTo($uat2, $eva));
     // Sarah has upload permission to live1, but not download to uat1.
     $this->assertFalse($archive->canMoveTo($live1, $sarah));
 }
Exemple #5
0
 public function doPostSnapshot($data, $form)
 {
     $project = $this->getCurrentProject();
     if (!$project) {
         return new SS_HTTPResponse("Project '" . Convert::raw2xml($this->getRequest()->latestParam('Project')) . "' not found.", 404);
     }
     $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');
     }
     $dataArchive = DNDataArchive::create(array('UploadToken' => DNDataArchive::generate_upload_token()));
     $form->saveInto($dataArchive);
     $dataArchive->write();
     return $this->redirect(Controller::join_links($project->Link(), 'postsnapshotsuccess', $dataArchive->ID));
 }
 public function testValidateArchiveContentsFileMissingFails()
 {
     $archive = DNDataArchive::create();
     $filename = __DIR__ . '/sspaks/not.found.sspak';
     $archive->ArchiveFile()->Filename = $filename;
     $result = $archive->validateArchiveContents('all');
     $this->assertFalse($result->valid());
     $this->assertEquals('SSPak file "' . $filename . '" cannot be read.', current($result->messageList()));
 }