/** * (non-PHPDoc) * * @see \phpbu\App\Backup\Sync::sync() * @param \phpbu\App\Backup\Target $target * @param \phpbu\App\Result $result * @throws \phpbu\App\Backup\Sync\Exception */ public function sync(Target $target, Result $result) { $sourcePath = $target->getPathname(); $dropboxPath = $this->path . $target->getFilename(); $client = new DropboxApi\Client($this->token, "phpbu/1.1.0"); $pathError = DropboxApi\Path::findErrorNonRoot($dropboxPath); if (substr(__FILE__, 0, 7) == 'phar://') { DropboxApi\RootCertificates::useExternalPaths(); } if ($pathError !== null) { throw new Exception(sprintf('Invalid \'dropbox-path\': %s', $pathError)); } $size = null; if (stream_is_local($sourcePath)) { $size = filesize($sourcePath); } try { $fp = fopen($sourcePath, 'rb'); $res = $client->uploadFile($dropboxPath, DropboxApi\WriteMode::add(), $fp, $size); fclose($fp); } catch (\Exception $e) { throw new Exception($e->getMessage(), null, $e); } $result->debug('upload: done (' . $res['size'] . ')'); }
/** * @see \phpbu\App\Backup\Check::pass() * @param \phpbu\App\Backup\Target $target * @param string $value * @param \phpbu\App\Backup\Collector $collector * @param \phpbu\App\Result $result * @return boolean * @throws \phpbu\App\Exception */ public function pass(Target $target, $value, Collector $collector, Result $result) { // throws App\Exception if file doesn't exist $actualSize = $target->getSize(); $testSize = Str::toBytes($value); return $testSize <= $actualSize; }
/** * Cleanup your backup directory. * * @see \phpbu\App\Backup\Cleanup::cleanup() * @param \phpbu\App\Backup\Target $target * @param \phpbu\App\Backup\Collector $collector * @param \phpbu\App\Result $result * @throws \phpbu\App\Backup\Cleaner\Exception */ public function cleanup(Target $target, Collector $collector, Result $result) { $files = $collector->getBackupFiles(); $size = $target->getSize(); /** @var \phpbu\App\Backup\File $file */ foreach ($files as $file) { $size += $file->getSize(); } // backups exceed capacity? if ($size > $this->capacityBytes) { // oldest backups first ksort($files); while ($size > $this->capacityBytes && count($files) > 0) { $file = array_shift($files); $size -= $file->getSize(); if (!$file->isWritable()) { throw new Exception(sprintf('can\'t delete file: %s', $file->getPathname())); } $result->debug(sprintf('delete %s', $file->getPathname())); $file->unlink(); } // deleted all old backups but still exceeding the space limit // delete the currently created backup as well if ($this->deleteTarget && $size > $this->capacityBytes) { $target->unlink(); } } }
/** * Returns the executable for this action. * * @param \phpbu\App\Backup\Target $target * @return \phpbu\App\Cli\Executable */ public function getExecutable(Target $target) { if (null === $this->executable) { $cmd = $target->getCompressor()->getCommand(); $this->executable = new Compressor($cmd, $this->pathToCommand); $this->executable->force(true)->compressFile($this->path); } return $this->executable; }
/** * Returns the executable for this action. * * @param \phpbu\App\Backup\Target $target * @return \phpbu\App\Cli\Executable */ public function getExecutable(Target $target) { if (null === $this->executable) { $this->executable = new Tar($this->pathToCommand); $this->executable->archiveDirectory($this->path); $archiveName = Tar::isCompressorValid($target->getCompressor()->getCommand()) ? $target->getPathname() : $target->getPathnamePlain(); $this->executable->archiveTo($archiveName)->useCompression($target->getCompressor()->getCommand())->removeSourceDirectory(true); } return $this->executable; }
/** * Compress the configured directory. * * @param \phpbu\App\Backup\Target $target * @param \phpbu\App\Result $result * @throws \phpbu\App\Exception */ public function compress(Target $target, Result $result) { if (!$target->shouldBeCompressed()) { throw new Exception('target should not be compressed'); } $res = $this->execute($target); $result->debug($res->getCmd()); if (0 !== $res->getCode()) { throw new Exception('Failed to \'compress\' file: ' . $this->path); } }
/** * Compress the configured directory. * * @param \phpbu\App\Backup\Target $target * @param \phpbu\App\Result $result * @return string * @throws \phpbu\App\Exception */ public function compress(Target $target, Result $result) { if (!$target->shouldBeCompressed()) { throw new Exception('target should not be compressed'); } if (!$this->isPathValid($this->path)) { throw new Exception('path to compress should be valid'); } $res = $this->execute($target); $result->debug($res->getCmd()); if (0 !== $res->getCode()) { throw new Exception('Failed to \'compress\' file: ' . $this->path); } return $this->getArchiveFile($target); }
/** * (non-PHPDoc) * * @see \phpbu\App\Backup\Sync::sync() * @param \phpbu\App\Backup\Target $target * @param \phpbu\App\Result $result * @throws \phpbu\App\Backup\Sync\Exception */ public function sync(Target $target, Result $result) { // silence phpseclib $old = error_reporting(0); $sftp = new phpseclib\Net\SFTP($this->host); if (!$sftp->login($this->user, $this->password)) { error_reporting($old); throw new Exception(sprintf('authentication failed for %s@%s%s', $this->user, $this->host, empty($this->password) ? '' : ' with password ****')); } error_reporting($old); $remoteFilename = $target->getFilename(); $localFile = $target->getPathname(); if ('' !== $this->remotePath) { $remoteDirs = explode('/', $this->remotePath); foreach ($remoteDirs as $dir) { if (!$sftp->is_dir($dir)) { $result->debug(sprintf('creating remote dir \'%s\'', $dir)); $sftp->mkdir($dir); } $result->debug(sprintf('change to remote dir \'%s\'', $dir)); $sftp->chdir($dir); } } $result->debug(sprintf('store file \'%s\' as \'%s\'', $localFile, $remoteFilename)); $result->debug(sprintf('last error \'%s\'', $sftp->getLastSFTPError())); /** @noinspection PhpInternalEntityUsedInspection */ if (!$sftp->put($remoteFilename, $localFile, phpseclib\Net\SFTP::SOURCE_LOCAL_FILE)) { throw new Exception(sprintf('error uploading file: %s - %s', $localFile, $sftp->getLastSFTPError())); } }
/** * (non-PHPDoc) * * @see \phpbu\App\Backup\Sync::sync() * @param \phpbu\App\Backup\Target $target * @param \phpbu\App\Result $result * @throws \phpbu\App\Backup\Sync\Exception */ public function sync(Target $target, Result $result) { // silence ftp errors $old = error_reporting(0); if (!($ftpConnection = ftp_connect($this->host))) { throw new Exception(sprintf('Unable to connect to ftp server %s', $this->host)); } if (!ftp_login($ftpConnection, $this->user, $this->password)) { error_reporting($old); throw new Exception(sprintf('authentication failed for %s@%s%s', $this->user, $this->host, empty($this->password) ? '' : ' with password ****')); } $remoteFilename = $target->getFilename(); $localFile = $target->getPathname(); if ('' !== $this->remotePath) { $remoteDirs = explode('/', $this->remotePath); foreach ($remoteDirs as $dir) { if (!ftp_chdir($ftpConnection, $dir)) { $result->debug(sprintf('creating remote dir \'%s\'', $dir)); ftp_mkdir($ftpConnection, $dir); ftp_chdir($ftpConnection, $dir); } else { $result->debug(sprintf('change to remote dir \'%s\'', $dir)); } } } $result->debug(sprintf('store file \'%s\' as \'%s\'', $localFile, $remoteFilename)); if (!ftp_put($ftpConnection, $remoteFilename, $localFile, FTP_BINARY)) { $error = error_get_last(); $message = $error['message']; throw new Exception(sprintf('error uploading file: %s - %s', $localFile, $message)); } error_reporting($old); }
/** * @see \phpbu\App\Backup\Check::pass() * @param \phpbu\App\Backup\Target $target * @param string $value * @param \phpbu\App\Backup\Collector $collector * @param \phpbu\App\Result $result * @return boolean * @throws \phpbu\App\Exception */ public function pass(Target $target, $value, Collector $collector, Result $result) { // throws App\Exception if file doesn't exist $backupSize = $target->getSize(); $history = $collector->getBackupFiles(); $historyCount = count($history); $pass = true; if ($historyCount > 0) { // oldest backups first ksort($history); /* @var $prevFile \SplFileInfo */ $prevFile = array_shift($history); $prevSize = $prevFile->getSize(); $diffPercent = Math::getDiffInPercent($backupSize, $prevSize); $pass = $diffPercent < $value; } return $pass; }
/** * (non-PHPDoc) * * @see \phpbu\App\Backup\Sync::sync() * @param \phpbu\App\Backup\Target $target * @param \phpbu\App\Result $result * @throws \phpbu\App\Backup\Sync\Exception */ public function sync(Target $target, Result $result) { $sourcePath = $target->getPathname(); $yandexDiskPath = $this->path . $target->getFilename(); $this->disk = new Disk($this->token); $size = null; if (stream_is_local($sourcePath)) { $size = filesize($sourcePath); } $file = $this->disk->resource(); $this->createFolders(); try { $file = $this->disk->resource($yandexDiskPath); $file->getContents(); } catch (NotFoundException $exc) { $file->upload($sourcePath, true); } if ($file->has()) { $result->debug('upload: done (' . $size . ')'); } else { $result->debug('upload: error while uploading file'); } }
/** * Recursive backup collecting. * * @param string $path * @param integer $depth */ protected function collect($path, $depth) { $dItter = new DirectoryIterator($path); // collect all matching subdirs and get all the backup files if ($depth < $this->target->countChangingPathElements()) { foreach ($dItter as $i => $file) { if ($file->isDot()) { continue; } // TODO: match directory against dir-regex Target::getChangingPathElements if ($file->isDir()) { $this->collect($file->getPathname(), $depth + 1); } } } else { // create regex to match only created backup files $fileRegex = Str::datePlaceholdersToRegex($this->target->getFilenameRaw()); if ($this->target->shouldBeCompressed()) { $fileRegex .= '.' . $this->target->getCompressor()->getSuffix(); } /** @var \SplFileInfo $file */ foreach ($dItter as $i => $file) { if ($file->isDir()) { continue; } // skip currently created backup if ($file->getPathname() == $this->target->getPathname()) { continue; } if (preg_match('#' . $fileRegex . '#i', $file->getFilename())) { $index = date('YmdHis', $file->getMTime()) . '-' . $i . '-' . $file->getPathname(); $this->files[$index] = new File($file->getFileInfo()); } } } }
/** * (non-PHPDoc) * * @see \phpbu\App\Backup\Sync::sync() * @param \phpbu\App\backup\Target $target * @param \phpbu\App\Result $result * @throws \phpbu\App\Backup\Sync\Exception */ public function sync(Target $target, Result $result) { $sourcePath = $target->getPathname(); $targetPath = $this->path . $target->getFilename(); $options = array('adapter' => ObjectStorage_Http_Client::SOCKET, 'timeout' => 20); $objectStorage = new ObjectStorage($this->host, $this->user, $this->secret, $options); $result->debug('softlayer source: ' . $sourcePath); $result->debug('softlayer target: ' . $targetPath); try { /** @var \ObjectStorage_Container $container */ $container = $objectStorage->with($this->container . $targetPath)->setLocalFile($sourcePath)->setMeta('description', 'PHPBU Backup: ' . date('r', time()))->setHeader('Content-Type', $target->getMimeType()); $container->create(); } catch (\Exception $e) { throw new Exception($e->getMessage(), null, $e); } $result->debug('upload: done'); }
/** * Execute the sync * * @see \phpbu\App\Backup\Sync::sync() * @param \phpbu\App\Backup\Target $target * @param \phpbu\App\Result $result * @throws \phpbu\App\Backup\Sync\Exception */ public function sync(Target $target, Result $result) { $sourcePath = $target->getPathname(); $targetPath = $this->path . $target->getFilename(); $s3 = S3Client::factory(array('signature' => 'v4', 'region' => $this->region, 'credentials' => array('key' => $this->key, 'secret' => $this->secret))); try { $fh = fopen($sourcePath, 'r'); $s3->upload($this->bucket, $targetPath, $fh, $this->acl); } catch (\Exception $e) { throw new Exception($e->getMessage(), null, $e); } $result->debug('upload: done'); }
/** * Create the Executable to run the elasticdump command. * * @param \phpbu\App\Backup\Target $target * @return \phpbu\App\Cli\Executable * @throws \phpbu\App\Exception */ public function getExecutable(Target $target) { if (null == $this->executable) { $this->executable = new Executable\Elasticdump($this->pathToElasticdump); $this->executable->useHost($this->host)->credentials($this->user, $this->password)->dumpIndex($this->index)->dumpType($this->type)->dumpTo($target->getPathnamePlain())->showStdErr($this->showStdErr); } return $this->executable; }
/** * Return final archive file. * * @param \phpbu\App\Backup\Target $target * @return string */ public function getArchiveFile(Target $target) { return $target->getPathname(); }
/** * Setup the Executable to run the 'tar' command. * * @param \phpbu\App\Backup\Target * @return \phpbu\App\Cli\Executable */ public function getExecutable(Target $target) { if (null == $this->executable) { // check if tar supports requested compression if ($target->shouldBeCompressed()) { if (!Executable\Tar::isCompressorValid($target->getCompressor()->getCommand())) { $this->pathToArchive = $target->getPathnamePlain(); } else { // compression could be handled by the tar command $this->pathToArchive = $target->getPathname(); $this->compression = $target->getCompressor()->getCommand(); } } else { // no compression at all $this->pathToArchive = $target->getPathname(); } $this->executable = new Executable\Tar($this->pathToTar); $this->executable->archiveDirectory($this->path)->useCompression($this->compression)->archiveTo($this->pathToArchive)->showStdErr($this->showStdErr); } return $this->executable; }
/** * Create the Exec to run the 'mcrypt' command. * * @param \phpbu\App\Backup\Target $target * @return \phpbu\App\Cli\Executable */ public function getExecutable(Target $target) { if (null == $this->executable) { $this->executable = new Executable\OpenSSL($this->pathToOpenSSL); $this->executable->encryptFile($target->getPathname()); // use key or password to encrypt if (!empty($this->certFile)) { $this->executable->useSSLCert($this->certFile); } else { $this->executable->usePassword($this->password)->encodeBase64(true); } $this->executable->useAlgorithm($this->algorithm)->deleteUncrypted(!$this->keepUncrypted)->showStdErr($this->showStdErr); } return $this->executable; }
/** * Return sync source. * * @param \phpbu\App\Backup\Target * @return string */ public function getSyncSource(Target $target) { return $this->isDirSync ? $target->getPath() : $target->getPathname(); }
/** * Create a target. * * @param \phpbu\App\Configuration\Backup\Target $conf * @return \phpbu\App\Backup\Target * @throws \phpbu\App\Exception */ protected function createTarget(Configuration\Backup\Target $conf) { $target = new Target($conf->dirname, $conf->filename); $target->setupPath(); // add possible compressor if (!empty($conf->compression)) { $compressor = Compressor::create($conf->compression); $target->setCompressor($compressor); } return $target; }
/** * (non-PHPDoc) * * @see \phpbu\App\Backup\Sync::sync() * @param \phpbu\App\Backup\Target $target * @param \phpbu\App\Result $result * @throws \phpbu\App\Backup\Sync\Exception */ public function sync(Target $target, Result $result) { $sourcePath = $target->getPathname(); $targetPath = $this->path . $target->getFilename(); $copy = new CopycomApi($this->appKey, $this->appSecret, $this->userKey, $this->userSecret); try { // open a file to upload $fh = fopen($sourcePath, 'rb'); // upload the file in 1MB chunks $parts = array(); while ($data = fread($fh, 1024 * 1024)) { $part = $copy->sendData($data); array_push($parts, $part); } fclose($fh); // finalize the file $copy->createFile($targetPath, $parts); } catch (\Exception $e) { throw new Exception($e->getMessage(), null, $e); } $result->debug('upload: done'); }
/** * (non-PHPDoc) * * @see \phpbu\App\Backup\Source * @param \phpbu\App\Backup\Target $target * @param \phpbu\App\Result $result * @return \phpbu\App\Backup\Source\Status * @throws \phpbu\App\Exception */ public function backup(Target $target, Result $result) { // setup dump location and execute the dump $this->dumpPathname = $target->getPathnamePlain(); $mysqldump = $this->execute($target); $result->debug($mysqldump->getCmd()); if (!$mysqldump->wasSuccessful()) { throw new Exception('mysqldump failed'); } return Status::create()->uncompressed()->dataPath($this->dumpPathname); }
/** * Returns the executable for this action. * * @param \phpbu\App\Backup\Target $target * * @return \phpbu\App\Cli\Executable */ public function getExecutable(Target $target) { if (!$this->executable) { $this->executable = new Rsync(); $this->executable->setSourceUser($this->user)->setSourceHost($this->host)->setSourcePort($this->port)->setSourcePath($this->path)->exclude($this->excludes)->compressed($target->shouldBeCompressed())->setTargetPath($target->getPath()); } return $this->executable; }
/** * Copy the redis RDB file to its backup location. * * @param \phpbu\App\Backup\Target $target * @return string * @throws \phpbu\App\Exception */ private function copyDumpToTargetDir(Target $target) { if (!file_exists($this->pathToRedisData)) { throw new Exception('Redis data not found at: \'' . $this->pathToRedisCli . '\''); } $targetFile = $target->getPathnamePlain(); copy($this->pathToRedisData, $targetFile); return $targetFile; }
/** * Create the Exec to run the 'mcrypt' command. * * @param \phpbu\App\Backup\Target $target * @return \phpbu\App\Cli\Executable */ public function getExecutable(Target $target) { if (null == $this->executable) { $this->executable = new Executable\Mcrypt($this->pathToMcrypt); $this->executable->useAlgorithm($this->algorithm)->useKey($this->key)->useKeyFile($this->keyFile)->useConfig($this->config)->useHash($this->hash)->saveAt($target->getPathname())->deleteUncrypted(!$this->keepUncrypted)->showStdErr($this->showStdErr); } return $this->executable; }
/** * Compress the backup if the source did not handle the compression. * * @param \phpbu\App\Backup\Source\Status $status * @param \phpbu\App\Backup\Target $target * @param \phpbu\App\Result $result * @throws \phpbu\App\Exception */ protected function compress(Status $status, Target $target, Result $result) { if ($target->shouldBeCompressed() && !$status->handledCompression()) { $this->handleCompression($target, $result, $status->getDataPath()); } }
/** * Get the MongoDB dump directory. * * @param \phpbu\App\Backup\Target $target * @return string */ public function getDumpDir(Target $target) { return $target->getPath() . '/dump'; }
/** * Compress the configured directory. * * @param \phpbu\App\Backup\Target $target * @param \phpbu\App\Result $result * @return string * @throws \phpbu\App\Exception */ public function compress(Target $target, Result $result) { $target->setMimeType('application/x-tar'); return parent::compress($target, $result); }