Skip to content
Snippets Groups Projects

Issue #3266092: Make sure staging root is unique for each Drupal site

Files
4
@@ -40,6 +40,16 @@ use Symfony\Contracts\EventDispatcher\EventDispatcherInterface;
* operations on the staging area, and the stage must be "claimed" by its owner
* before any such operations are done. A stage is claimed by presenting a
* unique token that is generated when the stage is created.
*
* Although a site can only have one staging area, it is possible for privileged
* users to destroy a stage created by another user. To prevent such actions
* from putting the file system into an uncertain state (for example, if a stage
* is destroyed by another user while it is still being created), the staging
* directory has a randomly generated name. For additional cleanliness, all
* staging directories created by a specific site live in a single directory,
* called the "staging root" and identified by the UUID of the current site
* (e.g. `/tmp/.package_managerSITE_UUID`), which is deleted when any stage
* created by that site is destroyed.
*/
class Stage {
@@ -348,20 +358,17 @@ class Stage {
}
$this->dispatch(new PreDestroyEvent($this));
// Delete all directories in parent staging directory.
$parent_stage_dir = static::getStagingRoot();
if (is_dir($parent_stage_dir)) {
try {
$this->fileSystem->deleteRecursive($parent_stage_dir, function (string $path): void {
$this->fileSystem->chmod($path, 0777);
});
}
catch (FileException $e) {
// Deliberately swallow the exception so that the stage will be marked
// as available and the post-destroy event will be fired, even if the
// staging area can't actually be deleted. The file system service logs
// the exception, so we don't need to do anything else here.
}
// Delete the staging root and everything in it.
try {
$this->fileSystem->deleteRecursive($this->getStagingRoot(), function (string $path): void {
$this->fileSystem->chmod($path, 0777);
});
}
catch (FileException $e) {
// Deliberately swallow the exception so that the stage will be marked
// as available and the post-destroy event will be fired, even if the
// staging area can't actually be deleted. The file system service logs
// the exception, so we don't need to do anything else here.
}
$this->markAsAvailable();
$this->dispatch(new PostDestroyEvent($this));
@@ -509,8 +516,6 @@ class Stage {
*
* @throws \LogicException
* If this method is called before the stage has been created or claimed.
*
* @todo Make this method public in https://www.drupal.org/i/3251972.
*/
public function getStageDirectory(): string {
if (!$this->lock) {
Loading