/** * Creates an export of a instance * * @param Instance $instance The instance of the exports * @param array $exports Array of files to include in the snapshot * @param Filesystem $destination The destination upon which to place the export. Currently unused * If null, the instance's snapshot storage area is used. * @param int $keepDays The number of days to keep the snapshot * * @return array|boolean The snapshot metadata array or false on failure. */ public function createFromExports(Instance $instance, array $exports, Filesystem $destination = null, $keepDays = EnterpriseDefaults::SNAPSHOT_DAYS_TO_KEEP) { // Build our "mise en place", as it were... $_success = false; $_stamp = date('YmdHis'); // Create the snapshot ID $_snapshotId = $_stamp . '.' . Inflector::neutralize($instance->instance_name_text); $_snapshotName = str_replace('{id}', $_snapshotId, config('snapshot.templates.snapshot-file-name')); // Set up the temp dir $this->setWorkPath($instance->getSnapshotPath()); // Create the snapshot archive and stuff it full of goodies /** @var SnapshotManifest $_manifest */ list($_fsSnapshot, $_manifest, $_routeHash, $_routeLink) = $this->createExportArchive($_snapshotId, $_snapshotName, ['timestamp' => $_stamp, 'guest-location' => $instance->guest_location_nbr, 'instance-id' => $instance->instance_id_text, 'cluster-id' => (int) $instance->cluster_id, 'db-server-id' => (int) $instance->db_server_id, 'web-server-id' => (int) $instance->web_server_id, 'app-server-id' => (int) $instance->app_server_id, 'owner-id' => (int) $instance->user->id, 'owner-email-address' => $instance->user->email_addr_text, 'owner-storage-key' => $instance->user->storage_id_text, 'storage-key' => $instance->storage_id_text], $keepDays); try { $this->addFilesToArchive($exports, $_fsSnapshot); try { // Write our snapshot manifesto $_manifest->write(); // Close up the files /** @noinspection PhpUndefinedMethodInspection */ $this->flushZipArchive($_fsSnapshot); // Look up the hash entry if (null === ($_routeHash = RouteHash::byHash($_routeHash)->first())) { throw new \LogicException('Previously created route hash not found.'); } // Create our snapshot record Snapshot::create(['user_id' => $instance->user_id, 'instance_id' => $instance->id, 'route_hash_id' => $_routeHash->id, 'snapshot_id_text' => $_snapshotId, 'public_ind' => true, 'public_url_text' => $_routeLink, 'expire_date' => $_routeHash->expire_date]); // Copy to $destination if requested if ($destination) { if (false === ($_fd = fopen($this->workPath . $_snapshotName, 'r'))) { throw new FileSystemException('Unable to open export file "' . $this->workPath . $_snapshotName . '".'); } $destination->putStream($_snapshotName, $_fd); fclose($_fd); } // Let the user know... $this->notifyInstanceOwner($instance, 'Export successful', ['firstName' => $instance->user->first_name_text, 'headTitle' => 'Export Complete', 'contentHeader' => 'Your export has completed', 'emailBody' => <<<HTML <p>Your export is complete. It may be downloaded it for up to {$keepDays} days, from the following link:<br/> <br/> <strong><a href="{$_routeLink}" target="_blank">{$_routeLink}</a></strong> </p> HTML ]); $_success = true; } catch (\Exception $_ex) { $this->error('exception building snapshot archive: ' . $_ex->getMessage()); throw $_ex; } } catch (\Exception $_ex) { $this->error('exception during sub-provisioner export call: ' . $_ex->getMessage()); $this->notifyInstanceOwner($instance, 'Export failure', ['firstName' => $instance->user->first_name_text, 'headTitle' => 'Export Failure', 'contentHeader' => 'Your export was not created', 'emailBody' => <<<HTML <p>The export requested did not complete properly. Please make sure your instance is up and running, then try again. If the issue persists, please contact support.</p> HTML ]); $_success = false; } finally { // Cleanup $_fsSnapshot = null; } return $_success ? $_manifest->toArray() : false; }