Skip to content

Commit

Permalink
Merge branch 'MAGETWO-34700-Separate-Updater-Application' of ../magen…
Browse files Browse the repository at this point in the history
…to2ce-updater
  • Loading branch information
arkadiych committed Apr 27, 2015
2 parents 2159b45 + 92b3894 commit be256fb
Show file tree
Hide file tree
Showing 109 changed files with 29,231 additions and 0 deletions.
11 changes: 11 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
/var/*
!/var/.htaccess
/vendor
/.buildpath
/.cache
/.metadata
/.project
/.settings
atlassian*
/.idea
/.gitattributes
6 changes: 6 additions & 0 deletions .htaccess
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
Order deny,allow
Deny from all

<Files index.php>
Allow from all
</Files>
15 changes: 15 additions & 0 deletions app/bootstrap.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
<?php
/**
* Copyright © 2015 Magento. All rights reserved.
* See COPYING.txt for license details.
*/

error_reporting(E_ALL);

define('UPDATER_BP', realpath(__DIR__ . '/../'));
define('UPDATER_BACKUP_DIR', UPDATER_BP . '/var/backup/');
define('MAGENTO_BP', realpath(__DIR__ . '/../../'));

date_default_timezone_set('UTC');

require_once UPDATER_BP . '/vendor/autoload.php';
78 changes: 78 additions & 0 deletions app/code/Magento/Update/Backup.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
<?php
/**
* Copyright © 2015 Magento. All rights reserved.
* See COPYING.txt for license details.
*/

namespace Magento\Update;

use Magento\Update\Backup\BackupInfo;
use Magento\Update\Status;

/**
* Class for creating Magento codebase backups.
*/
class Backup
{
/**
* @var BackupInfo
*/
protected $backupInfo;

/**
* @var Status
*/
protected $status;

/**
* Initialize dependencies.
*
* @param BackupInfo|null $backupInfo
* @param Status|null $status
*/
public function __construct(BackupInfo $backupInfo = null, Status $status = null)
{
$this->backupInfo = $backupInfo ? $backupInfo : new BackupInfo();
$this->status = $status ? $status : new Status();
}

/**
* Create backup archive using unix zip tool.
*
* @return $this
* @throws \RuntimeException
*/
public function execute()
{
$backupFilePath = $this->backupInfo->getBackupPath() . $this->backupInfo->generateBackupFilename();
$command = $this->buildShellCommand($backupFilePath);
$this->status->add(sprintf('Creating backup archive "%s" ...', $backupFilePath));
exec($command, $output, $return);
if ($return) {
throw new \RuntimeException(
sprintf('Cannot create backup with command "%s": %s', $command, implode("\n", $output))
);
}
$this->status->add(sprintf('Backup archive "%s" has been created.', $backupFilePath));
return $this;
}

/**
* Construct shell command for creating backup archive.
*
* @param string $backupFilePath
* @return string
*/
protected function buildShellCommand($backupFilePath)
{
$excludedElements = '';
foreach ($this->backupInfo->getBlacklist() as $excludedElement) {
$elementPath = $excludedElement;
$fullPath = $this->backupInfo->getArchivedDirectory() . '/' . $elementPath;
$excludedElements .= is_dir($fullPath) ? $elementPath . '\* ' : $elementPath . ' ';
}
$changeDirectoryCommand = sprintf("cd %s", $this->backupInfo->getArchivedDirectory());
$zipCommand = sprintf("zip -r %s . -x %s", $backupFilePath, $excludedElements);
return $changeDirectoryCommand . ' && ' . $zipCommand;
}
}
90 changes: 90 additions & 0 deletions app/code/Magento/Update/Backup/BackupInfo.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
<?php
/**
* Copyright © 2015 Magento. All rights reserved.
* See COPYING.txt for license details.
*/

namespace Magento\Update\Backup;

/**
* Data object, which stores information about files to be archived.
*/
class BackupInfo
{
/**
* @var string
*/
protected $blacklistFilePath;

/**
* @var string[]
*/
protected $blacklist;

/**
* Init backup info
*
* @param string $blacklistFilePath
*/
public function __construct($blacklistFilePath = null)
{
$this->blacklistFilePath = $blacklistFilePath ? $blacklistFilePath : __DIR__ . '/../etc/backup_blacklist.txt';
}

/**
* Generate backup filename based on current timestamp.
*
* @return string
*/
public function generateBackupFilename()
{
$currentDate = date('Y-m-d-H-i-s', time());
return 'backup-' . $currentDate . '-' . date_default_timezone_get() . '.zip';
}

/**
* Return files/directories, which need to be excluded from backup
*
* @return string[]
*/
public function getBlacklist()
{
if (null === $this->blacklist) {
$blacklistContent = file_get_contents($this->blacklistFilePath);
if ($blacklistContent === FALSE) {
throw new \RuntimeException('Could not read the blacklist file: ' . $this->blacklistFilePath);
}
/** Ignore commented and empty lines */
$blacklistArray = explode("\n", $blacklistContent);
$blacklistArray = array_filter(
$blacklistArray,
function ($value) {
$value = trim($value);
return (empty($value) || strpos($value, '#') === 0) ? false : true;
}
);
$this->blacklist = $blacklistArray;
}
return $this->blacklist;
}

/**
* Return path to a directory, which need to be archived
*
* @return string
*/
public function getArchivedDirectory()
{
return MAGENTO_BP;
}

/**
* Return path, where backup have to be saved
*
* @return string
*/
public function getBackupPath()
{
return UPDATER_BACKUP_DIR;
}
}
87 changes: 87 additions & 0 deletions app/code/Magento/Update/MaintenanceMode.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
<?php
/**
* Copyright © 2015 Magento. All rights reserved.
* See COPYING.txt for license details.
*/
namespace Magento\Update;

use Magento\Update\Status;

/**
* Class for handling Magento maintenance mode.
*/
class MaintenanceMode
{
/**
* Path to the maintenance flag file
*
* @var string
*/
protected $flagFile;

/**
* Path to the file with white-listed IP addresses
*
* @var string
*/
protected $ipFile;

/**
* @var Status
*/
protected $status;

/**
* Initialize.
*
* @param string|null $flagFile
* @param string|null $ipFile
* @param Status|null $status
*/
public function __construct($flagFile = null, $ipFile = null, Status $status = null)
{
$this->flagFile = $flagFile ? $flagFile : MAGENTO_BP . '/var/.maintenance.flag';
$this->ipFile = $ipFile ? $ipFile : MAGENTO_BP . '/var/.maintenance.ip';
$this->status = $status ? $status : new Status();
}

/**
* Check whether Magento maintenance mode is on.
*
* @return bool
*/
public function isOn()
{
return file_exists($this->flagFile);
}

/**
* Set maintenance mode.
*
* @param bool $isOn
* @return $this
* @throws \RuntimeException
*/
public function set($isOn)
{
if ($isOn) {
if (touch($this->flagFile)) {
$this->status->add("Magento maintenance mode is enabled.");
} else {
throw new \RuntimeException("Magento maintenance mode cannot be enabled.");
}
} else if (file_exists($this->flagFile)) {
if (file_exists($this->ipFile)) {
/** Maintenance mode should not be unset from updater application if it was set manually by the admin */
$this->status->add(
"Magento maintenance mode was not disabled. It can be disabled form the Magento Backend."
);
} else if (unlink($this->flagFile)) {
$this->status->add("Magento maintenance mode is disabled.");
} else {
throw new \RuntimeException("Magento maintenance mode cannot be disabled.");
}
}
return $this;
}
}
91 changes: 91 additions & 0 deletions app/code/Magento/Update/Queue.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
<?php
/**
* Copyright © 2015 Magento. All rights reserved.
* See COPYING.txt for license details.
*/

namespace Magento\Update;

use Magento\Update\Queue\Reader;
use Magento\Update\Queue\AbstractJob;
use Magento\Update\Queue\JobFactory;

/**
* Class for access to the queue of Magento updater application jobs.
*/
class Queue
{
/**#@+
* Key used in queue file.
*/
const KEY_JOBS = 'jobs';
const KEY_JOB_NAME = 'name';
const KEY_JOB_PARAMS = 'params';
/**#@-*/

/**
* @var Reader
*/
protected $reader;

/**
* @var JobFactory
*/
protected $jobFactory;

/**
* Initialize dependencies.
*
* @param Reader|null $reader
* @param JobFactory|null $jobFactory
*/
public function __construct(Reader $reader = null, JobFactory $jobFactory = null)
{
$this->reader = $reader ? $reader : new Reader();
$this->jobFactory = $jobFactory ? $jobFactory : new JobFactory();
}

/**
* Pop all updater application queued jobs.
*
* Note, that this method is not idempotent, queue will be cleared after its execution
*
* @return AbstractJob[]
* @throws \RuntimeException
*/
public function popQueuedJobs()
{
$jobs = [];
$queue = json_decode($this->reader->read(), true);
if (!is_array($queue)) {
return $jobs;
}
if (isset($queue[self::KEY_JOBS]) && is_array($queue[self::KEY_JOBS])) {
/** @var object $job */
foreach ($queue[self::KEY_JOBS] as $job) {
$this->validateJobDeclaration($job);
$jobs[] = $this->jobFactory->create($job[self::KEY_JOB_NAME], $job[self::KEY_JOB_PARAMS]);
}
} else {
throw new \RuntimeException(sprintf('"%s" field is missing or is not an array.', self::KEY_JOBS));
}
$this->reader->clearQueue();
return $jobs;
}

/**
* Make sure job declaration is correct.
*
* @param object $job
* @throws \RuntimeException
*/
protected function validateJobDeclaration($job)
{
$requiredFields = [self::KEY_JOB_NAME, self::KEY_JOB_PARAMS];
foreach ($requiredFields as $field) {
if (!isset($job[$field])) {
throw new \RuntimeException(sprintf('"%s" field is missing for one or more jobs.', $field));
}
}
}
}
Loading

0 comments on commit be256fb

Please sign in to comment.