mirror of
https://github.com/getgrav/grav.git
synced 2025-10-26 07:56:07 +01:00
@@ -1614,6 +1614,14 @@ form:
|
||||
validate:
|
||||
type: bool
|
||||
|
||||
updates.staging_root:
|
||||
type: text
|
||||
label: PLUGIN_ADMIN.SAFE_UPGRADE_STAGING
|
||||
help: PLUGIN_ADMIN.SAFE_UPGRADE_STAGING_HELP
|
||||
placeholder: '/absolute/path/to/grav-upgrades'
|
||||
validate:
|
||||
type: string
|
||||
|
||||
http_section:
|
||||
type: section
|
||||
title: PLUGIN_ADMIN.HTTP_SECTION
|
||||
@@ -1929,4 +1937,3 @@ form:
|
||||
# pages.type:
|
||||
# type: hidden
|
||||
|
||||
|
||||
|
||||
@@ -205,6 +205,7 @@ gpm:
|
||||
|
||||
updates:
|
||||
safe_upgrade: true # Enable guarded staging+rollback pipeline for Grav self-updates
|
||||
staging_root: '' # Optional absolute path for staging backups (default: <grav parent>/grav-upgrades)
|
||||
|
||||
http:
|
||||
method: auto # Either 'curl', 'fopen' or 'auto'. 'auto' will try fopen first and if not available cURL
|
||||
|
||||
@@ -124,3 +124,5 @@ PLUGIN_ADMIN:
|
||||
UPDATES_SECTION: Updates
|
||||
SAFE_UPGRADE: Safe self-upgrade
|
||||
SAFE_UPGRADE_HELP: When enabled, Grav core updates use staged installation with automatic rollback support.
|
||||
SAFE_UPGRADE_STAGING: Staging directory
|
||||
SAFE_UPGRADE_STAGING_HELP: Optional absolute path for storing upgrade backups. Leave empty to use the default inside the parent directory.
|
||||
|
||||
@@ -76,10 +76,12 @@ class SafeUpgradeService
|
||||
$this->rootPath = rtrim($root, DIRECTORY_SEPARATOR);
|
||||
$this->parentDir = $options['parent_dir'] ?? dirname($this->rootPath);
|
||||
$defaultStaging = $options['staging_root'] ?? ($this->parentDir . DIRECTORY_SEPARATOR . 'grav-upgrades');
|
||||
try {
|
||||
Folder::create($defaultStaging);
|
||||
} catch (\RuntimeException $e) {
|
||||
throw new RuntimeException(sprintf('Unable to create staging directory at %s. Adjust permissions or configure system.updates.staging_root.', $defaultStaging));
|
||||
if (!$this->ensureWritable($defaultStaging)) {
|
||||
$fallback = getenv('HOME') ? getenv('HOME') . DIRECTORY_SEPARATOR . 'grav-upgrades' : sys_get_temp_dir() . DIRECTORY_SEPARATOR . 'grav-upgrades';
|
||||
if (!$this->ensureWritable($fallback)) {
|
||||
throw new RuntimeException(sprintf('Unable to create staging directory at %s or fallback %s. Adjust permissions or configure system.updates.staging_root.', $defaultStaging, $fallback));
|
||||
}
|
||||
$defaultStaging = $fallback;
|
||||
}
|
||||
$this->stagingRoot = realpath($defaultStaging) ?: $defaultStaging;
|
||||
$this->manifestStore = $options['manifest_store'] ?? ($this->rootPath . DIRECTORY_SEPARATOR . 'user' . DIRECTORY_SEPARATOR . 'data' . DIRECTORY_SEPARATOR . 'upgrades');
|
||||
@@ -501,6 +503,27 @@ class SafeUpgradeService
|
||||
file_put_contents($target, json_encode($manifest, JSON_PRETTY_PRINT));
|
||||
}
|
||||
|
||||
/**
|
||||
* Ensure directory exists and is writable.
|
||||
*
|
||||
* @param string $path
|
||||
* @return bool
|
||||
*/
|
||||
private function ensureWritable(string $path): bool
|
||||
{
|
||||
try {
|
||||
Folder::create($path);
|
||||
} catch (\RuntimeException $e) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!is_writable($path)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string|null $id
|
||||
* @return array|null
|
||||
|
||||
Reference in New Issue
Block a user