diff --git a/Panel/modules/administration/panel_update.php b/Panel/modules/administration/panel_update.php
index 199aeadf..5773699a 100644
--- a/Panel/modules/administration/panel_update.php
+++ b/Panel/modules/administration/panel_update.php
@@ -22,9 +22,6 @@ defined('GSP_UPDATE_LOG') || define('GSP_UPDATE_LOG', GSP_ROOT_DIR . '/logs/upda
defined('GSP_VERSION_FILE') || define('GSP_VERSION_FILE', GSP_PANEL_DIR . '/includes/panel_version.php');
defined('GSP_VERSION_JSON') || define('GSP_VERSION_JSON', GSP_ROOT_DIR . '/version.json');
defined('GSP_PATCH_DIR') || define('GSP_PATCH_DIR', GSP_PANEL_DIR . '/modules/update/patches');
-defined('GSP_EXPECTED_ROOT') || define('GSP_EXPECTED_ROOT', '/var/www/html/GSP');
-defined('GSP_EXPECTED_PANEL') || define('GSP_EXPECTED_PANEL', GSP_EXPECTED_ROOT . '/Panel');
-defined('GSP_EXPECTED_WEBSITE') || define('GSP_EXPECTED_WEBSITE', GSP_EXPECTED_ROOT . '/Website');
defined('GSP_CANONICAL_TIMESTAMP_FILE') || define('GSP_CANONICAL_TIMESTAMP_FILE', GSP_WEBSITE_DIR . '/timestamp.txt');
defined('GSP_BILLING_TIMESTAMP_FILE') || define('GSP_BILLING_TIMESTAMP_FILE', GSP_PANEL_DIR . '/modules/billing/timestamp.txt');
defined('GSP_LAST_UPDATE_FILE') || define('GSP_LAST_UPDATE_FILE', GSP_ROOT_DIR . '/LAST_UPDATE.txt');
@@ -32,11 +29,7 @@ defined('GSP_DEFAULT_REPO_URL') || define('GSP_DEFAULT_REPO_URL', 'http://forge.
defined('GSP_DEFAULT_BRANCH') || define('GSP_DEFAULT_BRANCH', 'Panel-unstable');
defined('GSP_DEFAULT_REPO_ROOT') || define('GSP_DEFAULT_REPO_ROOT', '/var/www/html/GSP');
defined('GSP_DEFAULT_PANEL_PATH') || define('GSP_DEFAULT_PANEL_PATH', '/var/www/html/GSP/Panel');
-defined('GSP_DEFAULT_WEBSITE_PATH') || define('GSP_DEFAULT_WEBSITE_PATH', '/var/www/html/GSP/Website');
defined('GSP_DEFAULT_PANEL_SOURCE') || define('GSP_DEFAULT_PANEL_SOURCE', 'Panel');
-defined('GSP_DEFAULT_LINUX_AGENT_SOURCE') || define('GSP_DEFAULT_LINUX_AGENT_SOURCE', 'Agent_Linux');
-defined('GSP_DEFAULT_WINDOWS_AGENT_SOURCE') || define('GSP_DEFAULT_WINDOWS_AGENT_SOURCE', 'Agent-Windows');
-defined('GSP_DEFAULT_WEBSITE_SOURCE') || define('GSP_DEFAULT_WEBSITE_SOURCE', 'Website');
defined('GSP_DEFAULT_BACKUP_RETENTION') || define('GSP_DEFAULT_BACKUP_RETENTION', 5);
$gspPatchManager = GSP_PANEL_DIR . '/modules/update/patch_manager.php';
@@ -230,24 +223,16 @@ function gsp_update_settings()
global $settings;
$repo_root = !empty($settings['gsp_update_repo_root']) ? (string)$settings['gsp_update_repo_root'] : GSP_DEFAULT_REPO_ROOT;
$panel_path = !empty($settings['gsp_update_panel_path']) ? (string)$settings['gsp_update_panel_path'] : GSP_DEFAULT_PANEL_PATH;
-$website_path = !empty($settings['gsp_update_website_path']) ? (string)$settings['gsp_update_website_path'] : GSP_DEFAULT_WEBSITE_PATH;
return [
'repo_url' => !empty($settings['gsp_update_repo_url']) ? (string)$settings['gsp_update_repo_url'] : GSP_DEFAULT_REPO_URL,
'branch' => !empty($settings['gsp_update_branch']) ? (string)$settings['gsp_update_branch'] : GSP_DEFAULT_BRANCH,
'repo_root' => rtrim($repo_root, '/'),
'panel_path' => rtrim($panel_path, '/'),
-'website_path' => rtrim($website_path, '/'),
'panel_source_path' => !empty($settings['gsp_update_panel_source_path']) ? trim((string)$settings['gsp_update_panel_source_path'], '/') : GSP_DEFAULT_PANEL_SOURCE,
-'linux_agent_source_path' => !empty($settings['gsp_update_linux_agent_source_path']) ? trim((string)$settings['gsp_update_linux_agent_source_path'], '/') : GSP_DEFAULT_LINUX_AGENT_SOURCE,
-'windows_agent_source_path' => !empty($settings['gsp_update_windows_agent_source_path']) ? trim((string)$settings['gsp_update_windows_agent_source_path'], '/') : GSP_DEFAULT_WINDOWS_AGENT_SOURCE,
-'website_source_path' => !empty($settings['gsp_update_website_source_path']) ? trim((string)$settings['gsp_update_website_source_path'], '/') : GSP_DEFAULT_WEBSITE_SOURCE,
'git_path' => !empty($settings['gsp_update_git_path']) ? trim((string)$settings['gsp_update_git_path']) : 'git',
'backup_path' => !empty($settings['gsp_update_backup_path']) ? rtrim((string)$settings['gsp_update_backup_path'], '/') : GSP_BACKUP_BASE,
'backup_retention' => !empty($settings['gsp_update_backup_retention']) ? (string)$settings['gsp_update_backup_retention'] : (string)GSP_DEFAULT_BACKUP_RETENTION,
'panel_post_update_command' => !empty($settings['gsp_update_panel_post_update_command']) ? (string)$settings['gsp_update_panel_post_update_command'] : '',
-'website_post_update_command' => !empty($settings['gsp_update_website_post_update_command']) ? (string)$settings['gsp_update_website_post_update_command'] : '',
-'linux_agent_post_update_command' => !empty($settings['gsp_update_linux_agent_post_update_command']) ? (string)$settings['gsp_update_linux_agent_post_update_command'] : '',
-'windows_agent_post_update_command' => !empty($settings['gsp_update_windows_agent_post_update_command']) ? (string)$settings['gsp_update_windows_agent_post_update_command'] : '',
'backup_before_update' => !isset($settings['gsp_update_backup_before']) ? '1' : (string)$settings['gsp_update_backup_before'],
];
}
@@ -275,15 +260,15 @@ if (trim((string)$cfg[$key]) === '' || strpos((string)$cfg[$key], "\0") !== fals
$errors[] = ucfirst(str_replace('_', ' ', $key)) . ' is invalid.';
}
}
- foreach (['website_path', 'backup_path'] as $key) {
- if (isset($cfg[$key]) && (trim((string)$cfg[$key]) === '' || strpos((string)$cfg[$key], "\0") !== false || strpos((string)$cfg[$key], '..') !== false || strpos((string)$cfg[$key], '/') !== 0)) {
- $errors[] = ucfirst(str_replace('_', ' ', $key)) . ' must be a safe absolute path.';
- }
- }
+foreach (['backup_path'] as $key) {
+if (isset($cfg[$key]) && (trim((string)$cfg[$key]) === '' || strpos((string)$cfg[$key], "\0") !== false || strpos((string)$cfg[$key], '..') !== false || strpos((string)$cfg[$key], '/') !== 0)) {
+$errors[] = ucfirst(str_replace('_', ' ', $key)) . ' must be a safe absolute path.';
+}
+}
if (isset($cfg['backup_retention']) && (!preg_match('/^\d+$/', (string)$cfg['backup_retention']) || (int)$cfg['backup_retention'] < 1 || (int)$cfg['backup_retention'] > 200)) {
$errors[] = 'Backup retention must be a whole number between 1 and 200.';
}
-foreach (['panel_source_path', 'linux_agent_source_path', 'windows_agent_source_path', 'website_source_path'] as $key) {
+foreach (['panel_source_path'] as $key) {
$value = isset($cfg[$key]) ? trim((string)$cfg[$key], '/') : '';
if ($value === '' || strpos($value, "\0") !== false || strpos($value, '..') !== false || !preg_match('/^[A-Za-z0-9._\/-]+$/', $value)) {
$errors[] = ucfirst(str_replace('_', ' ', $key)) . ' is invalid.';
@@ -292,7 +277,7 @@ $errors[] = ucfirst(str_replace('_', ' ', $key)) . ' is invalid.';
if (isset($cfg['git_path']) && trim((string)$cfg['git_path']) !== '' && (strpos((string)$cfg['git_path'], "\0") !== false || strpos((string)$cfg['git_path'], "\n") !== false || strpos((string)$cfg['git_path'], "\r") !== false)) {
$errors[] = 'Git executable path is invalid.';
}
-foreach (['panel_post_update_command', 'website_post_update_command', 'linux_agent_post_update_command', 'windows_agent_post_update_command'] as $key) {
+foreach (['panel_post_update_command'] as $key) {
if (isset($cfg[$key]) && (strpos((string)$cfg[$key], "\0") !== false || strpos((string)$cfg[$key], "\n") !== false || strpos((string)$cfg[$key], "\r") !== false)) {
$errors[] = ucfirst(str_replace('_', ' ', $key)) . ' must be a single-line admin command.';
}
@@ -334,41 +319,6 @@ $data = [
@file_put_contents(GSP_VERSION_JSON, json_encode($data, JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES));
}
-function gsp_fetch_github_releases($repo_owner, $repo_name)
-{
-$url = "https://api.github.com/repos/{$repo_owner}/{$repo_name}/releases?per_page=30";
-if (function_exists('curl_init')) {
-$ch = curl_init($url);
-curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
-curl_setopt($ch, CURLOPT_USERAGENT, 'GSP-Panel-Updater');
-curl_setopt($ch, CURLOPT_TIMEOUT, 15);
-curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, true);
-curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 2);
-$data = curl_exec($ch);
-$code = curl_getinfo($ch, CURLINFO_HTTP_CODE);
-curl_close($ch);
-if ($code === 200 && $data) {
-return json_decode($data, true);
-}
-}
-$ctx = stream_context_create([
-'http' => [
-'method' => 'GET',
-'header' => "User-Agent: GSP-Panel-Updater\r\n",
-'timeout' => 15,
-],
-'ssl' => [
-'verify_peer' => true,
-'verify_peer_name' => true,
-],
-]);
-$data = @file_get_contents($url, false, $ctx);
-if ($data) {
-return json_decode($data, true);
-}
-return false;
-}
-
function gsp_preflight_check(array $update_cfg = null)
{
$errors = [];
@@ -378,27 +328,21 @@ $cwd = getcwd();
$cwd_real = $cwd ? (realpath($cwd) ?: $cwd) : '';
$root_path = rtrim((string)$update_cfg['repo_root'], '/');
$panel_path = rtrim((string)$update_cfg['panel_path'], '/');
- $website_path = !empty($update_cfg['website_path']) ? rtrim((string)$update_cfg['website_path'], '/') : ($root_path . '/Website');
$backup_base = gsp_get_backup_base($update_cfg);
$root_real = realpath($root_path) ?: $root_path;
$panel_real = realpath($panel_path) ?: $panel_path;
-$website_real = realpath($website_path) ?: $website_path;
$layout = [
'cwd' => $cwd,
'cwd_real' => $cwd_real,
'expected_root' => $root_path,
'expected_panel' => $panel_path,
-'expected_website' => $website_path,
'gsp_root' => $root_path,
'gsp_root_real' => $root_real,
'panel_dir' => $panel_path,
'panel_dir_real' => $panel_real,
-'website_dir' => $website_path,
-'website_dir_real' => $website_real,
'backup_dir' => $backup_base,
'config_file' => $panel_path . '/includes/config.inc.php',
'destination_panel' => $panel_path,
-'destination_website' => $website_path,
];
if (!$layout['cwd']) {
@@ -412,9 +356,6 @@ $errors[] = 'Detected GSP root path is missing.';
if (!is_dir($panel_path)) {
$errors[] = 'Panel directory is missing.';
}
-if (!is_dir($website_path)) {
-$warnings[] = 'Website directory is missing. Panel updates can still continue, but Website files will not sync cleanly.';
-}
if (!file_exists($layout['config_file'])) {
$errors[] = 'Panel includes/config.inc.php was not found and cannot be preserved.';
}
@@ -685,7 +626,6 @@ function gsp_create_full_backup($update_target_type, $update_target_version, $in
'backup_base' => $backup_base,
'gsp_root' => GSP_ROOT_DIR,
'panel_root' => GSP_PANEL_DIR,
-'website_root' => GSP_WEBSITE_DIR,
'update_target_type' => $update_target_type,
'update_target_version' => $update_target_version,
'created_at' => date('Y-m-d H:i:s'),
@@ -710,16 +650,6 @@ return ['success' => false, 'error' => $panel_backup['error']];
}
$meta['panel_archive'] = basename($panel_backup['file']);
-$website_backup = gsp_create_archive(
-GSP_WEBSITE_DIR,
-$backup_dir . '/website-files.tar.gz',
-['./logs', './cache', './tmp']
-);
-if (!$website_backup['success']) {
-return ['success' => false, 'error' => $website_backup['error']];
-}
-$meta['website_archive'] = basename($website_backup['file']);
-
if (file_exists(GSP_VERSION_JSON)) {
@copy(GSP_VERSION_JSON, $backup_dir . '/version.json.bak');
$meta['version_json_backup'] = 'version.json.bak';
@@ -749,133 +679,6 @@ $meta['apache_backup_error'] = $apache_backup['error'];
];
}
-function gsp_download_zip($repo_owner, $repo_name, $ref, $temp_dir)
-{
-$url = "https://api.github.com/repos/{$repo_owner}/{$repo_name}/zipball/{$ref}";
-$zip_file = $temp_dir . '/gsp_update.zip';
-if (function_exists('curl_init')) {
-$ch = curl_init($url);
-curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
-curl_setopt($ch, CURLOPT_USERAGENT, 'GSP-Panel-Updater');
-curl_setopt($ch, CURLOPT_TIMEOUT, 180);
-curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, true);
-curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 2);
-curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
-$data = curl_exec($ch);
-$code = curl_getinfo($ch, CURLINFO_HTTP_CODE);
-curl_close($ch);
-if ($code !== 200 || !$data) {
-return false;
-}
-@file_put_contents($zip_file, $data);
-} else {
-$ctx = stream_context_create([
-'http' => [
-'method' => 'GET',
-'header' => "User-Agent: GSP-Panel-Updater\r\n",
-'timeout' => 180,
-],
-'ssl' => [
-'verify_peer' => true,
-'verify_peer_name' => true,
-],
-]);
-$data = @file_get_contents($url, false, $ctx);
-if (!$data) {
-return false;
-}
-@file_put_contents($zip_file, $data);
-}
-if (!file_exists($zip_file) || filesize($zip_file) < 1000) {
-return false;
-}
-return $zip_file;
-}
-
-function gsp_extract_update_source($zip_file)
-{
-$temp_dir = sys_get_temp_dir() . '/gsp_upd_' . time() . '_' . mt_rand(1000, 9999);
-if (!@mkdir($temp_dir, 0750, true)) {
-return ['success' => false, 'error' => 'Cannot create temp extraction directory.'];
-}
-require_once(GSP_PANEL_DIR . '/modules/update/unzip.php');
-$result = extractZip($zip_file, $temp_dir);
-if (!is_array($result)) {
-gsp_rmdir_recursive($temp_dir);
-return ['success' => false, 'error' => 'ZIP extraction failed: ' . $result];
-}
-$source_root = $temp_dir;
-$subdirs = glob($temp_dir . '/*', GLOB_ONLYDIR);
-if ($subdirs && count($subdirs) === 1) {
-$source_root = $subdirs[0];
-}
-return ['success' => true, 'temp_dir' => $temp_dir, 'source_root' => $source_root];
-}
-
-function gsp_resolve_source_layout($temp_checkout_path, $source_root, array $update_cfg = null)
-{
-$update_cfg = $update_cfg ?: gsp_update_settings();
-$source_root_real = realpath($source_root) ?: $source_root;
-$candidates = [$source_root_real];
-if (basename($source_root_real) === 'Panel' || basename($source_root_real) === 'Website') {
-$candidates[] = dirname($source_root_real);
-}
-$candidates = array_values(array_unique(array_filter($candidates)));
-$repo_root = null;
-foreach ($candidates as $candidate) {
-if (is_dir($candidate . '/Panel') && is_dir($candidate . '/Website')) {
-$repo_root = realpath($candidate) ?: $candidate;
-break;
-}
-}
-
-$layout = [
-'cwd' => getcwd() ?: '',
-'live_gsp_root' => rtrim((string)$update_cfg['repo_root'], '/'),
-'live_panel_path' => rtrim((string)$update_cfg['panel_path'], '/'),
-'live_website_path' => !empty($update_cfg['website_path']) ? rtrim((string)$update_cfg['website_path'], '/') : (rtrim((string)$update_cfg['repo_root'], '/') . '/Website'),
-'temporary_git_checkout_path' => $temp_checkout_path,
-'source_root' => $source_root_real,
-'source_repo_root' => $repo_root,
-'source_panel_path' => $repo_root ? ($repo_root . '/' . trim((string)$update_cfg['panel_source_path'], '/')) : '',
-'source_website_path' => $repo_root ? ($repo_root . '/' . trim((string)$update_cfg['website_source_path'], '/')) : '',
-'destination_panel_path' => rtrim((string)$update_cfg['panel_path'], '/'),
-'destination_website_path' => !empty($update_cfg['website_path']) ? rtrim((string)$update_cfg['website_path'], '/') : (rtrim((string)$update_cfg['repo_root'], '/') . '/Website'),
-];
-
-$errors = [];
-if (!$repo_root) {
-$errors[] = 'Unable to resolve source repository root containing both Panel/ and Website/.';
-} else {
-if (!is_dir($layout['source_panel_path'])) {
-$errors[] = 'Source Panel path is missing: ' . $layout['source_panel_path'];
-}
-if (!is_dir($layout['source_website_path'])) {
-$errors[] = 'Source Website path is missing: ' . $layout['source_website_path'];
-}
-}
-if (strpos((string)$layout['destination_panel_path'], '/Panel/Panel') !== false) {
-$errors[] = 'Destination Panel path is nested incorrectly: ' . $layout['destination_panel_path'];
-}
-if (strpos((string)$layout['destination_website_path'], '/Website/Website') !== false) {
-$errors[] = 'Destination Website path is nested incorrectly: ' . $layout['destination_website_path'];
-}
-if (!is_dir($layout['destination_panel_path'])) {
-$errors[] = 'Destination Panel path does not exist: ' . $layout['destination_panel_path'];
-}
-
-gsp_update_log('Deployment layout detection: ' . json_encode($layout));
-foreach ($errors as $error) {
-gsp_update_log('Deployment layout error: ' . $error);
-}
-
-return [
-'success' => empty($errors),
-'errors' => $errors,
-'layout' => $layout,
-];
-}
-
function gsp_normalize_rel($path)
{
$path = str_replace('\\', '/', $path);
@@ -883,34 +686,6 @@ $path = ltrim($path, '/');
return $path;
}
-function gsp_is_preserved_path($relative_path)
-{
-$relative_path = gsp_normalize_rel($relative_path);
-$exact = [
-'Panel/includes/config.inc.php',
-];
-$prefixes = [
-'logs/',
-'backups/',
-'Panel/logs/',
-'Panel/backups/',
-'Website/logs/',
-'Website/uploads/',
-'Website/upload/',
-'Panel/uploads/',
-'Panel/upload/',
-];
-if (in_array($relative_path, $exact, true)) {
-return true;
-}
-foreach ($prefixes as $prefix) {
-if (strpos($relative_path, $prefix) === 0) {
-return true;
-}
-}
-return false;
-}
-
function gsp_copy_file($src, $dst)
{
$parent = dirname($dst);
@@ -920,216 +695,6 @@ if (!is_dir($parent)) {
return @copy($src, $dst);
}
-function gsp_copy_tree($src_root, $dst_root, $base_rel = '')
-{
-$copied = 0;
-$skipped = [];
-$copied_files = [];
-$source = rtrim($src_root, '/');
-$iter = new RecursiveIteratorIterator(
-new RecursiveDirectoryIterator($source, RecursiveDirectoryIterator::SKIP_DOTS),
-RecursiveIteratorIterator::SELF_FIRST
-);
-foreach ($iter as $item) {
-$rel = gsp_normalize_rel(($base_rel !== '' ? $base_rel . '/' : '') . substr($item->getPathname(), strlen($source) + 1));
-if (gsp_is_preserved_path($rel)) {
-$skipped[] = $rel;
-continue;
-}
-$dst = rtrim($dst_root, '/') . '/' . $rel;
-if ($item->isDir()) {
-if (!is_dir($dst)) {
-@mkdir($dst, 0755, true);
-}
-continue;
-}
-if (gsp_copy_file($item->getPathname(), $dst)) {
-$copied++;
-if (count($copied_files) < 200) {
-$copied_files[] = $rel;
-}
-}
-}
-return ['copied' => $copied, 'skipped' => $skipped, 'copied_files' => $copied_files];
-}
-
-function gsp_updater_watch_list()
-{
-return [
-'Panel/modules/administration/panel_update.php',
-'Panel/modules/update/update.php',
-'Panel/modules/update/updating.php',
-'Panel/modules/update/post_update.php',
-'Panel/modules/update/module.php',
-'Panel/modules/update/unzip.php',
-'Panel/modules/update/blacklist.php',
-'Panel/modules/update/patch_manager.php',
-'Panel/modules/update/patches',
-];
-}
-
-function gsp_collect_files_under($path, $base_rel)
-{
-$list = [];
-if (is_file($path)) {
-$list[] = gsp_normalize_rel($base_rel);
-return $list;
-}
-if (!is_dir($path)) {
-return $list;
-}
-$iter = new RecursiveIteratorIterator(
-new RecursiveDirectoryIterator($path, RecursiveDirectoryIterator::SKIP_DOTS),
-RecursiveIteratorIterator::LEAVES_ONLY
-);
-foreach ($iter as $item) {
-if ($item->isFile()) {
-$list[] = gsp_normalize_rel($base_rel . '/' . substr($item->getPathname(), strlen($path) + 1));
-}
-}
-return $list;
-}
-
-function gsp_detect_updater_drift_files($source_root, $target_root)
-{
-$drift = [];
-foreach (gsp_updater_watch_list() as $rel) {
-$src = rtrim($source_root, '/') . '/' . $rel;
-$files = gsp_collect_files_under($src, $rel);
-foreach ($files as $fileRel) {
-$s = rtrim($source_root, '/') . '/' . $fileRel;
-$d = rtrim($target_root, '/') . '/' . $fileRel;
-if (!file_exists($d)) {
-$drift[] = $fileRel;
-continue;
-}
-if (@hash_file('sha256', $s) !== @hash_file('sha256', $d)) {
-$drift[] = $fileRel;
-}
-}
-}
-return array_values(array_unique($drift));
-}
-
-function gsp_apply_updater_files_only($source_root, $target_root, array $drift_files)
-{
-$copied = 0;
-foreach ($drift_files as $rel) {
-$src = rtrim($source_root, '/') . '/' . $rel;
-$dst = rtrim($target_root, '/') . '/' . $rel;
-if (is_file($src) && gsp_copy_file($src, $dst)) {
-$copied++;
-}
-}
-return $copied;
-}
-
-function gsp_apply_layout_sync(array $layout)
-{
-$source_root = $layout['source_repo_root'];
-$source_panel = $layout['source_panel_path'];
-$source_website = $layout['source_website_path'];
-$destination_panel = $layout['destination_panel_path'];
-$destination_website = $layout['destination_website_path'];
-$top_level = scandir($source_root);
-$skip = ['.', '..', '.git', '.github', '.gitignore', '.vscode'];
-$copied = 0;
-$panel_copied = 0;
-$website_copied = 0;
-$skipped = [];
-$copied_files = [];
-gsp_update_log('Layout sync source mapping: ' . $source_panel . ' => ' . $destination_panel . ' ; ' . $source_website . ' => ' . $destination_website);
-foreach ((array)$top_level as $entry) {
-if (in_array($entry, $skip, true)) {
-continue;
-}
-if ($entry === 'Panel' || $entry === 'Website' || $entry === 'backups' || $entry === 'logs') {
-continue;
-}
-$src = rtrim($source_root, '/') . '/' . $entry;
-$dst = rtrim($layout['live_gsp_root'], '/') . '/' . $entry;
-if (is_file($src)) {
-$rel = gsp_normalize_rel($entry);
-if (gsp_is_preserved_path($rel)) {
-$skipped[] = $rel;
-continue;
-}
-if (gsp_copy_file($src, $dst)) {
-$copied++;
-if (count($copied_files) < 200) {
-$copied_files[] = $rel;
-}
-}
-continue;
-}
-if (is_dir($src)) {
-$part = gsp_copy_tree($src, $layout['live_gsp_root'], $entry);
-$copied += $part['copied'];
-$copied_files = array_merge($copied_files, array_slice((array)$part['copied_files'], 0, max(0, 200 - count($copied_files))));
-$skipped = array_merge($skipped, $part['skipped']);
-}
-}
-$panel_part = gsp_copy_tree($source_panel, dirname($destination_panel), basename($destination_panel));
-$copied += $panel_part['copied'];
-$panel_copied += $panel_part['copied'];
-$copied_files = array_merge($copied_files, array_slice((array)$panel_part['copied_files'], 0, max(0, 200 - count($copied_files))));
-$skipped = array_merge($skipped, $panel_part['skipped']);
-
-$website_part = gsp_copy_tree($source_website, dirname($destination_website), basename($destination_website));
-$copied += $website_part['copied'];
-$website_copied += $website_part['copied'];
-$copied_files = array_merge($copied_files, array_slice((array)$website_part['copied_files'], 0, max(0, 200 - count($copied_files))));
-$skipped = array_merge($skipped, $website_part['skipped']);
-
-return [
-'success' => true,
-'files_copied' => $copied,
-'panel_files_copied' => $panel_copied,
-'website_files_copied' => $website_copied,
-'skipped' => array_values(array_unique($skipped)),
-'copied_files' => array_slice(array_values(array_unique($copied_files)), 0, 200),
-];
-}
-
-function gsp_validate_layout_sync_result(array $layout, array $sync)
-{
-$errors = [];
-$checks = [
-'Panel/modules/administration/panel_update.php',
-'Panel/modules/addonsmanager/addons_manager.php',
-'Website/index.php',
-];
-foreach ($checks as $rel) {
-$src = rtrim($layout['source_repo_root'], '/') . '/' . $rel;
-$dst = rtrim($layout['live_gsp_root'], '/') . '/' . $rel;
-if (!is_file($src)) {
-continue;
-}
-if (!is_file($dst)) {
-$errors[] = 'Missing deployed file: ' . $rel;
-continue;
-}
-$src_hash = @hash_file('sha256', $src);
-$dst_hash = @hash_file('sha256', $dst);
-if ($src_hash === false || $dst_hash === false || $src_hash !== $dst_hash) {
-$errors[] = 'Copied file verification failed: ' . $rel;
-}
-}
-if (!empty($sync['copied_files']) && intval($sync['panel_files_copied']) === 0) {
-$errors[] = 'No Panel files were copied during layout sync.';
-}
-if (!empty($sync['copied_files']) && intval($sync['website_files_copied']) === 0) {
-$errors[] = 'No Website files were copied during layout sync.';
-}
-foreach ($errors as $error) {
-gsp_update_log('Layout sync validation error: ' . $error);
-}
-return [
-'success' => empty($errors),
-'errors' => $errors,
-];
-}
-
function gsp_write_last_update_markers($repo_root = null)
{
$line = 'Last Updated at ' . date('g:ia') . ' on ' . date('Y-m-d');
@@ -1165,90 +730,6 @@ return [
return ['success' => true, 'run' => $run];
}
-function gsp_apply_update_from_zip($zip_file, $restart_nonce = '', array $update_cfg = null)
-{
-$update_cfg = $update_cfg ?: gsp_update_settings();
-$extract = gsp_extract_update_source($zip_file);
-if (!$extract['success']) {
-return $extract;
-}
-$temp_dir = $extract['temp_dir'];
-$source_root = $extract['source_root'];
-$resolved_layout = gsp_resolve_source_layout($temp_dir, $source_root, $update_cfg);
-if (!$resolved_layout['success']) {
-gsp_rmdir_recursive($temp_dir);
-return ['success' => false, 'error' => 'Deployment layout validation failed: ' . implode(' | ', $resolved_layout['errors'])];
-}
-$layout = $resolved_layout['layout'];
-$_SESSION['gsp_last_update_layout'] = $layout;
-$updater_version = substr((string)@hash_file('sha256', $layout['source_panel_path'] . '/modules/administration/panel_update.php'), 0, 12);
-
-$drift_files = gsp_detect_updater_drift_files($layout['source_repo_root'], GSP_ROOT_DIR);
-if (!empty($drift_files) && empty($restart_nonce)) {
-$copied = gsp_apply_updater_files_only($layout['source_repo_root'], GSP_ROOT_DIR, $drift_files);
-$nonce = gsp_random_token(12);
-$_SESSION['gsp_update_restart_nonce'] = $nonce;
-gsp_update_log('Updater self-update applied (' . $copied . ' files); restart nonce=' . $nonce);
-gsp_rmdir_recursive($temp_dir);
- return [
- 'success' => false,
- 'restart_required' => true,
- 'restart_nonce' => $nonce,
- 'updater_files_updated' => $copied,
- 'drift_files' => $drift_files,
- ];
- }
-
- if (!empty($restart_nonce)) {
- $expected = isset($_SESSION['gsp_update_restart_nonce']) ? $_SESSION['gsp_update_restart_nonce'] : null;
- if ($expected === null || !hash_equals($expected, $restart_nonce)) {
- gsp_rmdir_recursive($temp_dir);
- return ['success' => false, 'error' => 'Invalid updater restart marker.'];
- }
- unset($_SESSION['gsp_update_restart_nonce']);
- }
-
- $patches = gsp_run_required_patches($updater_version);
- if (!$patches['success']) {
- gsp_rmdir_recursive($temp_dir);
- return ['success' => false, 'error' => $patches['error']];
- }
-
- $sync = gsp_apply_layout_sync($layout);
- gsp_rmdir_recursive($temp_dir);
- if (!$sync['success']) {
- return $sync;
- }
- $sync_validation = gsp_validate_layout_sync_result($layout, $sync);
- if (!$sync_validation['success']) {
- return ['success' => false, 'error' => 'Deployed file validation failed: ' . implode(' | ', $sync_validation['errors'])];
- }
- gsp_update_log('Layout sync complete: copied=' . $sync['files_copied'] . ', skipped=' . count($sync['skipped']));
- gsp_update_log('Layout sync totals: Panel=' . intval($sync['panel_files_copied']) . ', Website=' . intval($sync['website_files_copied']));
- if (!empty($sync['skipped'])) {
- gsp_update_log('Preserved paths: ' . implode(', ', array_slice($sync['skipped'], 0, 50)));
- }
- if (!empty($sync['copied_files'])) {
- $copied_sample = array_slice((array)$sync['copied_files'], 0, 50);
- gsp_update_log('Copied file sample: ' . implode(', ', $copied_sample));
- $addons_updates = array_values(array_filter((array)$sync['copied_files'], function ($rel) {
- return strpos($rel, 'Panel/modules/addonsmanager/') === 0;
- }));
- if (!empty($addons_updates)) {
- gsp_update_log('Addonsmanager files copied: ' . implode(', ', array_slice($addons_updates, 0, 50)));
- }
- }
- return [
- 'success' => true,
- 'files_copied' => $sync['files_copied'],
- 'panel_files_copied' => $sync['panel_files_copied'],
- 'website_files_copied' => $sync['website_files_copied'],
- 'preserved' => $sync['skipped'],
- 'copied_files' => $sync['copied_files'],
- 'patches' => $patches['run'],
- ];
-}
-
function gsp_checkout_update_source(array $update_cfg)
{
$repo_url = (string)$update_cfg['repo_url'];
@@ -1277,68 +758,6 @@ gsp_update_log('Configured git checkout completed from ' . $repo_url . ' branch
return ['success' => true, 'temp_dir' => $temp_dir, 'source_root' => $temp_dir, 'output' => implode("\n", $out)];
}
-function gsp_apply_update_from_source($source_root, $restart_nonce = '', array $update_cfg = null)
-{
-$update_cfg = $update_cfg ?: gsp_update_settings();
-$resolved_layout = gsp_resolve_source_layout($source_root, $source_root, $update_cfg);
-if (!$resolved_layout['success']) {
-return ['success' => false, 'error' => 'Deployment layout validation failed: ' . implode(' | ', $resolved_layout['errors'])];
-}
-$layout = $resolved_layout['layout'];
-$_SESSION['gsp_last_update_layout'] = $layout;
-$updater_version = substr((string)@hash_file('sha256', $layout['source_panel_path'] . '/modules/administration/panel_update.php'), 0, 12);
-
-$drift_files = gsp_detect_updater_drift_files($layout['source_repo_root'], $layout['live_gsp_root']);
-if (!empty($drift_files) && empty($restart_nonce)) {
-$copied = gsp_apply_updater_files_only($layout['source_repo_root'], $layout['live_gsp_root'], $drift_files);
-$nonce = gsp_random_token(12);
-$_SESSION['gsp_update_restart_nonce'] = $nonce;
-gsp_update_log('Updater self-update applied (' . $copied . ' files); restart nonce=' . $nonce);
-return [
-'success' => false,
-'restart_required' => true,
-'restart_nonce' => $nonce,
-'updater_files_updated' => $copied,
-'drift_files' => $drift_files,
-];
-}
-if (!empty($restart_nonce)) {
-$expected = isset($_SESSION['gsp_update_restart_nonce']) ? $_SESSION['gsp_update_restart_nonce'] : null;
-if ($expected === null || !hash_equals($expected, $restart_nonce)) {
-return ['success' => false, 'error' => 'Invalid updater restart marker.'];
-}
-unset($_SESSION['gsp_update_restart_nonce']);
-}
-
-$config_file = rtrim($layout['destination_panel_path'], '/') . '/includes/config.inc.php';
-$config_backup = is_file($config_file) ? @file_get_contents($config_file) : false;
-$patches = gsp_run_required_patches($updater_version);
-if (!$patches['success']) {
-return ['success' => false, 'error' => $patches['error']];
-}
-$sync = gsp_apply_layout_sync($layout);
-if ($config_backup !== false) {
-@file_put_contents($config_file, $config_backup, LOCK_EX);
-}
-if (!$sync['success']) {
-return $sync;
-}
-$sync_validation = gsp_validate_layout_sync_result($layout, $sync);
-if (!$sync_validation['success']) {
-return ['success' => false, 'error' => 'Deployed file validation failed: ' . implode(' | ', $sync_validation['errors'])];
-}
-gsp_update_log('Layout sync complete: copied=' . $sync['files_copied'] . ', skipped=' . count($sync['skipped']));
-return [
-'success' => true,
-'files_copied' => $sync['files_copied'],
-'panel_files_copied' => $sync['panel_files_copied'],
-'website_files_copied' => $sync['website_files_copied'],
-'preserved' => $sync['skipped'],
-'copied_files' => $sync['copied_files'],
-'patches' => $patches['run'],
-];
-}
-
function gsp_fix_permissions($root_dir)
{
@system(
@@ -1364,73 +783,6 @@ foreach (glob($cache . '/*.cache') ?: [] as $f) {
}
}
-function gsp_do_update($repo_owner, $repo_name, $ref, $update_type, $restart_nonce = '')
-{
-global $db;
-$preflight = gsp_preflight_check();
-if (!$preflight['success']) {
-return ['success' => false, 'error' => 'Preflight failed: ' . implode(' | ', $preflight['errors'])];
-}
-
-$backup = gsp_create_full_backup($update_type, $ref, false);
-if (!$backup['success']) {
-return $backup;
-}
-gsp_update_log("Backup created at {$backup['backup_ts']} before {$update_type} update to {$ref}");
-
-$temp_dir = sys_get_temp_dir() . '/gsp_dl_' . time() . '_' . mt_rand(1000, 9999);
-@mkdir($temp_dir, 0750, true);
-$zip_file = gsp_download_zip($repo_owner, $repo_name, $ref, $temp_dir);
-if (!$zip_file) {
-gsp_rmdir_recursive($temp_dir);
-return ['success' => false, 'error' => 'Failed to download update ZIP from GitHub.'];
-}
-
-$apply = gsp_apply_update_from_zip($zip_file, $restart_nonce);
-@unlink($zip_file);
-gsp_rmdir_recursive($temp_dir);
-if (!empty($apply['restart_required'])) {
-$apply['backup_dir'] = $backup['backup_dir'];
-$apply['success'] = false;
-return $apply;
-}
-if (!$apply['success']) {
-return $apply;
-}
-
-$commit_after = gsp_get_git_commit();
-gsp_fix_permissions(GSP_ROOT_DIR);
-gsp_clear_panel_cache(GSP_PANEL_DIR);
-gsp_write_version_file($ref, $update_type);
-$vsource = ($update_type === 'release') ? 'GitHub Releases' : $ref;
-$vversion = ($update_type === 'release') ? $ref : ($commit_after ?: $ref);
-gsp_write_version_json($update_type, $vsource, $vversion, $commit_after);
-gsp_write_last_update_markers(GSP_ROOT_DIR);
-$db->setSettings(['ogp_version' => $ref, 'version_type' => $update_type]);
-
-if (file_exists(GSP_PANEL_DIR . '/modules/modulemanager/module_handling.php')) {
-require_once(GSP_PANEL_DIR . '/modules/modulemanager/module_handling.php');
-}
-if (function_exists('updateAllPanelModules')) {
-updateAllPanelModules();
-}
-if (function_exists('runPostUpdateOperations')) {
-runPostUpdateOperations();
-}
-
-gsp_update_log("Update to {$ref} (type={$update_type}) complete");
-return [
-'success' => true,
-'files_copied' => $apply['files_copied'],
-'panel_files_copied' => isset($apply['panel_files_copied']) ? $apply['panel_files_copied'] : 0,
-'website_files_copied' => isset($apply['website_files_copied']) ? $apply['website_files_copied'] : 0,
-'copied_files' => isset($apply['copied_files']) ? $apply['copied_files'] : [],
-'backup_dir' => $backup['backup_dir'],
-'preserved' => $apply['preserved'],
-'patches' => $apply['patches'],
-];
-}
-
function gsp_do_configured_git_update(array $update_cfg, $restart_nonce = '')
{
global $db;
@@ -1456,27 +808,50 @@ $checkout = gsp_checkout_update_source($update_cfg);
if (!$checkout['success']) {
return $checkout;
}
-$apply = gsp_apply_update_from_source($checkout['source_root'], $restart_nonce, $update_cfg);
+$panel_source = gsp_component_source_path($checkout['source_root'], $update_cfg['panel_source_path']);
+if ($panel_source === false || !is_dir($panel_source)) {
gsp_rmdir_recursive($checkout['temp_dir']);
-if (!empty($apply['restart_required'])) {
-$apply['backup_dir'] = $backup['backup_dir'];
-$apply['success'] = false;
-return $apply;
+return ['success' => false, 'error' => 'Source Panel folder is invalid or missing: ' . $update_cfg['panel_source_path']];
+}
+$panel_dest = rtrim((string)$update_cfg['panel_path'], '/');
+if (strpos($panel_dest, '/') !== 0 || strpos($panel_dest, '..') !== false || strpos($panel_dest, "\0") !== false) {
+gsp_rmdir_recursive($checkout['temp_dir']);
+return ['success' => false, 'error' => 'Panel destination path is invalid.'];
+}
+if (!is_dir($panel_dest) && !@mkdir($panel_dest, 0755, true) && !is_dir($panel_dest)) {
+gsp_rmdir_recursive($checkout['temp_dir']);
+return ['success' => false, 'error' => 'Cannot create Panel destination directory: ' . $panel_dest];
+}
+$panel_backup = ['success' => true, 'backup_dir' => null];
+if (!empty($update_cfg['backup_before_update'])) {
+$panel_backup = gsp_create_full_backup('panel-update', $update_cfg['branch'], false, $update_cfg);
+if (!$panel_backup['success']) {
+gsp_rmdir_recursive($checkout['temp_dir']);
+return $panel_backup;
+}
+gsp_update_log("Backup created before panel update to {$update_cfg['branch']}: {$panel_backup['backup_dir']}");
+}
+$sync = gsp_component_copy_tree($panel_source, $panel_dest, 'Panel');
+gsp_rmdir_recursive($checkout['temp_dir']);
+if (!$sync['success']) {
+return $sync;
+}
+if (!empty($update_cfg['panel_post_update_command'])) {
+$post = gsp_run_admin_post_update_command($update_cfg['panel_post_update_command'], $panel_dest);
+if (!$post['success']) {
+return ['success' => false, 'error' => 'Panel post-update command failed: ' . $post['error'], 'output' => $post['output']];
}
-if (!$apply['success']) {
-return $apply;
}
-
$commit_after = gsp_get_git_commit();
-gsp_fix_permissions($update_cfg['repo_root']);
-gsp_clear_panel_cache($update_cfg['panel_path']);
+gsp_fix_permissions($panel_dest);
+gsp_clear_panel_cache($panel_dest);
gsp_write_version_file($update_cfg['branch'], 'git');
gsp_write_version_json('git', $update_cfg['repo_url'], $commit_after ?: $update_cfg['branch'], $commit_after);
-gsp_write_last_update_markers();
+gsp_write_last_update_markers($update_cfg['repo_root']);
$db->setSettings(['ogp_version' => $update_cfg['branch'], 'version_type' => 'git']);
-if (file_exists($update_cfg['panel_path'] . '/modules/modulemanager/module_handling.php')) {
-require_once($update_cfg['panel_path'] . '/modules/modulemanager/module_handling.php');
+if (file_exists($panel_dest . '/modules/modulemanager/module_handling.php')) {
+require_once($panel_dest . '/modules/modulemanager/module_handling.php');
}
if (function_exists('updateAllPanelModules')) {
updateAllPanelModules();
@@ -1485,57 +860,17 @@ if (function_exists('runPostUpdateOperations')) {
runPostUpdateOperations();
}
-gsp_update_log("Configured git update complete: {$update_cfg['repo_url']} {$update_cfg['branch']}");
+gsp_update_log("Configured git panel update complete: {$update_cfg['repo_url']} {$update_cfg['branch']}");
return [
'success' => true,
-'files_copied' => $apply['files_copied'],
-'panel_files_copied' => isset($apply['panel_files_copied']) ? $apply['panel_files_copied'] : 0,
-'website_files_copied' => isset($apply['website_files_copied']) ? $apply['website_files_copied'] : 0,
-'copied_files' => isset($apply['copied_files']) ? $apply['copied_files'] : [],
-'backup_dir' => $backup['backup_dir'],
-'preserved' => $apply['preserved'],
-'patches' => $apply['patches'],
+'files_copied' => $sync['files_copied'],
+'panel_files_copied' => $sync['files_copied'],
+'backup_dir' => $panel_backup['backup_dir'],
+'preserved' => $sync['skipped'],
+'copied_files' => isset($sync['copied_files']) ? $sync['copied_files'] : [],
];
}
-function gsp_safe_component_backup($component, $source_path, $backup_base, $retention = GSP_DEFAULT_BACKUP_RETENTION)
-{
- $component = preg_replace('/[^A-Za-z0-9._-]/', '_', (string)$component);
- $backup_base = rtrim((string)$backup_base, '/');
- if ($backup_base === '' || strpos($backup_base, '/') !== 0) {
- $backup_base = gsp_get_backup_base();
- }
- $backup_base_ready = gsp_ensure_directory($backup_base, 'component backup path');
- if (!$backup_base_ready['success']) {
- return ['success' => false, 'error' => $backup_base_ready['error']];
- }
- $ts = date('Y-m-d_H-i-s');
- $backup_dir = $backup_base . '/component_' . $component . '_' . $ts;
- $backup_dir_ready = gsp_ensure_directory($backup_dir, 'component backup directory');
- if (!$backup_dir_ready['success']) {
- return ['success' => false, 'error' => $backup_dir_ready['error']];
- }
-if (!is_dir($source_path)) {
-return ['success' => true, 'backup_dir' => $backup_dir, 'skipped' => true];
-}
-$archive = $backup_dir . '/' . $component . '.tar.gz';
-$archive_result = gsp_create_archive($source_path, $archive, ['./logs', './cache', './tmp', './backups', './uploads', './upload', './Cfg', './ServerFiles', './Schedule', './steamcmd', './startups']);
-if (!$archive_result['success']) {
-return $archive_result;
-}
-@file_put_contents($backup_dir . '/backup.json', json_encode([
-'component' => $component,
-'source_path' => $source_path,
- 'created_at' => date('Y-m-d H:i:s'),
- 'archive' => basename($archive),
- ], JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES));
- $prune = gsp_prune_old_backups((int)$retention, $backup_base);
- if (!empty($prune['deleted'])) {
- gsp_update_log('Component backup retention pruned ' . count($prune['deleted']) . ' entries from ' . $backup_base . ': ' . implode(', ', $prune['deleted']));
- }
- return ['success' => true, 'backup_dir' => $backup_dir, 'archive' => $archive];
-}
-
function gsp_component_source_path($source_root, $relative)
{
$relative = trim((string)$relative, '/');
@@ -1632,204 +967,6 @@ exec('cd ' . escapeshellarg($cwd) . ' && ' . $command . ' 2>&1', $out, $ret);
return ['success' => $ret === 0, 'exit_code' => $ret, 'output' => implode("\n", $out), 'error' => $ret === 0 ? '' : implode("\n", $out)];
}
-function gsp_do_local_component_update(array $update_cfg, array $components)
-{
-$allowed = array('panel', 'website');
-$components = array_values(array_intersect($allowed, array_unique($components)));
-if (empty($components)) {
-return ['success' => true, 'files_copied' => 0, 'results' => []];
-}
-$validation = gsp_validate_update_settings($update_cfg);
-if (!empty($validation)) {
-return ['success' => false, 'error' => implode(' | ', $validation)];
-}
-$checkout = gsp_checkout_update_source($update_cfg);
-if (!$checkout['success']) {
-return $checkout;
-}
-$results = [];
-$total = 0;
-$all_skipped = [];
-$all_copied = [];
-$map = [
-'panel' => ['source' => $update_cfg['panel_source_path'], 'dest' => $update_cfg['panel_path'], 'post' => $update_cfg['panel_post_update_command']],
-'website' => ['source' => $update_cfg['website_source_path'], 'dest' => $update_cfg['website_path'], 'post' => $update_cfg['website_post_update_command']],
-];
-foreach ($components as $component) {
-$source = gsp_component_source_path($checkout['source_root'], $map[$component]['source']);
-if ($source === false) {
-gsp_rmdir_recursive($checkout['temp_dir']);
-return ['success' => false, 'error' => 'Source folder for ' . $component . ' is invalid or missing.'];
-}
-$dest = rtrim((string)$map[$component]['dest'], '/');
-if (strpos($dest, '/') !== 0 || strpos($dest, '..') !== false || strpos($dest, "\0") !== false) {
-gsp_rmdir_recursive($checkout['temp_dir']);
-return ['success' => false, 'error' => 'Destination path for ' . $component . ' is invalid.'];
-}
-$backup = ['success' => true, 'backup_dir' => null];
-if (!empty($update_cfg['backup_before_update'])) {
- $backup = gsp_safe_component_backup($component, $dest, gsp_get_backup_base($update_cfg), gsp_get_backup_retention($update_cfg));
-if (!$backup['success']) {
-gsp_rmdir_recursive($checkout['temp_dir']);
-return $backup;
-}
-}
-$sync = gsp_component_copy_tree($source, $dest, ucfirst($component));
-if (!$sync['success']) {
-gsp_rmdir_recursive($checkout['temp_dir']);
-return $sync;
-}
-$post = gsp_run_admin_post_update_command($map[$component]['post'], $dest);
-if (!$post['success']) {
-gsp_rmdir_recursive($checkout['temp_dir']);
-return ['success' => false, 'error' => ucfirst($component) . ' post-update command failed: ' . $post['error'], 'results' => $results];
-}
-$results[$component] = [
-'source' => $source,
-'destination' => $dest,
-'backup_dir' => $backup['backup_dir'],
-'files_copied' => $sync['files_copied'],
-'skipped' => $sync['skipped'],
-'post_update' => $post,
-];
-$total += (int)$sync['files_copied'];
-$all_skipped = array_merge($all_skipped, $sync['skipped']);
-$all_copied = array_merge($all_copied, $sync['copied_files']);
-gsp_update_log('Local component update complete: ' . $component . ' copied=' . intval($sync['files_copied']) . ' source=' . $source . ' dest=' . $dest);
-}
-gsp_rmdir_recursive($checkout['temp_dir']);
-gsp_write_last_update_markers($update_cfg['repo_root']);
-if (in_array('panel', $components, true)) {
-gsp_clear_panel_cache($update_cfg['panel_path']);
-gsp_fix_permissions($update_cfg['panel_path']);
-}
-return [
-'success' => true,
-'files_copied' => $total,
-'results' => $results,
-'preserved' => array_values(array_unique($all_skipped)),
-'copied_files' => array_slice(array_values(array_unique($all_copied)), 0, 200),
-];
-}
-
-function gsp_update_payload_encode(array $payload)
-{
-$lines = [];
-foreach ($payload as $key => $value) {
-if (is_array($value)) {
-$value = json_encode($value, JSON_UNESCAPED_SLASHES);
-}
-$lines[] = $key . '=' . base64_encode((string)$value);
-}
-return implode("\n", $lines);
-}
-
-function gsp_infer_agent_os(array $remote_server, $reported_os = '')
-{
-$reported = strtolower((string)$reported_os);
-$haystack = strtolower((string)$remote_server['remote_server_name'] . ' ' . (string)$remote_server['agent_ip'] . ' ' . $reported);
-if (strpos($haystack, 'windows') !== false || strpos($haystack, 'cygwin') !== false || strpos($haystack, 'mingw') !== false) {
-return 'windows';
-}
-return 'linux';
-}
-
-function gsp_get_remote_agent_rows()
-{
-global $db;
-$rows = $db->getRemoteServers();
-return is_array($rows) ? $rows : [];
-}
-
-function gsp_dispatch_remote_agent_update(array $remote_server, array $update_cfg, $component)
-{
-if (!function_exists('xmlrpc_encode_request') || !function_exists('xmlrpc_decode')) {
-return ['success' => false, 'status' => 'missing_xmlrpc', 'message' => 'PHP xmlrpc extension is required for remote agent updates.'];
-}
-require_once(GSP_PANEL_DIR . '/includes/lib_remote.php');
-$component = ($component === 'windows_agent') ? 'windows_agent' : 'linux_agent';
-$source_path = ($component === 'windows_agent') ? $update_cfg['windows_agent_source_path'] : $update_cfg['linux_agent_source_path'];
-$post_cmd = ($component === 'windows_agent') ? $update_cfg['windows_agent_post_update_command'] : $update_cfg['linux_agent_post_update_command'];
-$payload = [
-'component' => $component,
-'repo_url' => $update_cfg['repo_url'],
-'branch' => $update_cfg['branch'],
-'source_path' => $source_path,
-'install_path' => '',
-'git_path' => $update_cfg['git_path'],
-'backup_path' => '',
-'post_update_command' => $post_cmd,
-'requested_at' => date('Y-m-d H:i:s'),
-];
-$remote = new OGPRemoteLibrary($remote_server['agent_ip'], $remote_server['agent_port'], $remote_server['encryption_key'], $remote_server['timeout']);
-if ((int)$remote->status_chk() !== 1) {
-return ['success' => false, 'status' => 'agent_unreachable', 'message' => 'Agent unreachable or encryption mismatch.'];
-}
-if (!method_exists($remote, 'component_update')) {
-return ['success' => false, 'status' => 'panel_missing_rpc_wrapper', 'message' => 'Panel remote library does not expose component_update().'];
-}
-$response = $remote->component_update(gsp_update_payload_encode($payload));
-if (is_array($response)) {
-return $response;
-}
-return ['success' => false, 'status' => 'unexpected_response', 'message' => 'Unexpected agent response: ' . substr((string)$response, 0, 300)];
-}
-
-function gsp_do_remote_agents_update(array $update_cfg, array $remote_ids, array $component_filters)
-{
-global $db;
-if (!function_exists('xmlrpc_encode_request') || !function_exists('xmlrpc_decode')) {
-return ['success' => false, 'results' => [], 'success_count' => 0, 'message' => 'PHP xmlrpc extension is required for remote agent updates.'];
-}
-require_once(GSP_PANEL_DIR . '/includes/lib_remote.php');
-$remote_ids = array_map('intval', $remote_ids);
-$remote_ids = array_values(array_filter(array_unique($remote_ids)));
-if (empty($remote_ids)) {
-return ['success' => true, 'results' => [], 'message' => 'No remote agents selected.'];
-}
-$all = gsp_get_remote_agent_rows();
-$by_id = [];
-foreach ($all as $row) {
-$by_id[(int)$row['remote_server_id']] = $row;
-}
-$results = [];
-$success_count = 0;
-foreach ($remote_ids as $remote_id) {
-if (empty($by_id[$remote_id])) {
-$results[$remote_id] = ['success' => false, 'status' => 'not_found', 'message' => 'Remote host not found.'];
-continue;
-}
-$row = $by_id[$remote_id];
-$reported_os = '';
-try {
-$probe = new OGPRemoteLibrary($row['agent_ip'], $row['agent_port'], $row['encryption_key'], $row['timeout']);
-$reported_os = (string)$probe->what_os();
-} catch (Exception $e) {
-$reported_os = '';
-}
-$agent_os = gsp_infer_agent_os($row, $reported_os);
-if ($agent_os === 'linux' && !in_array('linux_agent', $component_filters, true)) {
-$results[$remote_id] = ['success' => true, 'status' => 'skipped', 'message' => 'Skipped Linux agent by filter.', 'agent_os' => $agent_os];
-continue;
-}
-if ($agent_os === 'windows' && !in_array('windows_agent', $component_filters, true)) {
-$results[$remote_id] = ['success' => true, 'status' => 'skipped', 'message' => 'Skipped Windows agent by filter.', 'agent_os' => $agent_os];
-continue;
-}
-$component = ($agent_os === 'windows') ? 'windows_agent' : 'linux_agent';
-$result = gsp_dispatch_remote_agent_update($row, $update_cfg, $component);
-$result['agent_os'] = $agent_os;
-$result['remote_server_name'] = $row['remote_server_name'];
-$result['agent_ip'] = $row['agent_ip'];
-$results[$remote_id] = $result;
-if (!empty($result['success'])) {
-$success_count++;
-}
-gsp_update_log('Remote agent update requested: id=' . $remote_id . ' component=' . $component . ' result=' . json_encode($result));
-}
-return ['success' => true, 'results' => $results, 'success_count' => $success_count];
-}
-
function gsp_get_available_backups($backup_base = null)
{
$backups = [];
@@ -1931,26 +1068,16 @@ $db->setSettings([
]);
}
-$panel_restore = gsp_restore_archive($backup_dir . '/panel-files.tar.gz', GSP_PANEL_DIR);
-if (!$panel_restore['success']) {
-if (!$had_maintenance) {
-$db->setSettings(['maintenance_mode' => '0']);
-}
-return $panel_restore;
-}
-$website_archive = $backup_dir . '/website-files.tar.gz';
-if (file_exists($website_archive)) {
-$website_restore = gsp_restore_archive($website_archive, GSP_WEBSITE_DIR);
-if (!$website_restore['success']) {
-if (!$had_maintenance) {
-$db->setSettings(['maintenance_mode' => '0']);
-}
-return $website_restore;
-}
-}
-if (file_exists($backup_dir . '/version.json.bak')) {
-@copy($backup_dir . '/version.json.bak', GSP_VERSION_JSON);
-}
+ $panel_restore = gsp_restore_archive($backup_dir . '/panel-files.tar.gz', GSP_PANEL_DIR);
+ if (!$panel_restore['success']) {
+ if (!$had_maintenance) {
+ $db->setSettings(['maintenance_mode' => '0']);
+ }
+ return $panel_restore;
+ }
+ if (file_exists($backup_dir . '/version.json.bak')) {
+ @copy($backup_dir . '/version.json.bak', GSP_VERSION_JSON);
+ }
$db_restore = gsp_restore_database_from_backup($backup_dir);
if (!$db_restore['success']) {
gsp_update_log('Revert warning: ' . $db_restore['error']);
@@ -2449,7 +1576,7 @@ print_success(htmlspecialchars(isset($disable['message']) ? $disable['message']
} else {
print_failure('Disable SSL vhost failed: ' . htmlspecialchars($disable['error']));
}
- } elseif ($action === 'backup_only') {
+} elseif ($action === 'backup_only') {
$result = gsp_create_full_backup('backup-only', 'manual', false, $update_cfg);
if ($result['success']) {
print_success('Backup created: ' . htmlspecialchars($result['backup_dir']) . '');
@@ -2462,18 +1589,11 @@ $new_cfg = [
'branch' => isset($_POST['gsp_update_branch']) ? trim((string)$_POST['gsp_update_branch']) : '',
'repo_root' => isset($_POST['gsp_update_repo_root']) ? rtrim(trim((string)$_POST['gsp_update_repo_root']), '/') : '',
'panel_path' => isset($_POST['gsp_update_panel_path']) ? rtrim(trim((string)$_POST['gsp_update_panel_path']), '/') : '',
-'website_path' => isset($_POST['gsp_update_website_path']) ? rtrim(trim((string)$_POST['gsp_update_website_path']), '/') : '',
'panel_source_path' => isset($_POST['gsp_update_panel_source_path']) ? trim((string)$_POST['gsp_update_panel_source_path'], '/') : '',
-'linux_agent_source_path' => isset($_POST['gsp_update_linux_agent_source_path']) ? trim((string)$_POST['gsp_update_linux_agent_source_path'], '/') : '',
-'windows_agent_source_path' => isset($_POST['gsp_update_windows_agent_source_path']) ? trim((string)$_POST['gsp_update_windows_agent_source_path'], '/') : '',
-'website_source_path' => isset($_POST['gsp_update_website_source_path']) ? trim((string)$_POST['gsp_update_website_source_path'], '/') : '',
'git_path' => isset($_POST['gsp_update_git_path']) ? trim((string)$_POST['gsp_update_git_path']) : '',
'backup_path' => isset($_POST['gsp_update_backup_path']) ? rtrim(trim((string)$_POST['gsp_update_backup_path']), '/') : '',
'backup_retention' => isset($_POST['gsp_update_backup_retention']) ? trim((string)$_POST['gsp_update_backup_retention']) : '',
'panel_post_update_command' => isset($_POST['gsp_update_panel_post_update_command']) ? trim((string)$_POST['gsp_update_panel_post_update_command']) : '',
-'website_post_update_command' => isset($_POST['gsp_update_website_post_update_command']) ? trim((string)$_POST['gsp_update_website_post_update_command']) : '',
-'linux_agent_post_update_command' => isset($_POST['gsp_update_linux_agent_post_update_command']) ? trim((string)$_POST['gsp_update_linux_agent_post_update_command']) : '',
-'windows_agent_post_update_command' => isset($_POST['gsp_update_windows_agent_post_update_command']) ? trim((string)$_POST['gsp_update_windows_agent_post_update_command']) : '',
'backup_before_update' => !empty($_POST['gsp_update_backup_before']) ? '1' : '0',
];
$errors = gsp_validate_update_settings($new_cfg);
@@ -2485,126 +1605,37 @@ $db->setSettings([
'gsp_update_branch' => $new_cfg['branch'],
'gsp_update_repo_root' => $new_cfg['repo_root'],
'gsp_update_panel_path' => $new_cfg['panel_path'],
-'gsp_update_website_path' => $new_cfg['website_path'],
'gsp_update_panel_source_path' => $new_cfg['panel_source_path'],
-'gsp_update_linux_agent_source_path' => $new_cfg['linux_agent_source_path'],
-'gsp_update_windows_agent_source_path' => $new_cfg['windows_agent_source_path'],
-'gsp_update_website_source_path' => $new_cfg['website_source_path'],
'gsp_update_git_path' => $new_cfg['git_path'],
'gsp_update_backup_path' => $new_cfg['backup_path'],
'gsp_update_backup_retention' => $new_cfg['backup_retention'],
'gsp_update_panel_post_update_command' => $new_cfg['panel_post_update_command'],
-'gsp_update_website_post_update_command' => $new_cfg['website_post_update_command'],
-'gsp_update_linux_agent_post_update_command' => $new_cfg['linux_agent_post_update_command'],
-'gsp_update_windows_agent_post_update_command' => $new_cfg['windows_agent_post_update_command'],
'gsp_update_backup_before' => $new_cfg['backup_before_update'],
]);
$settings['gsp_update_repo_url'] = $new_cfg['repo_url'];
$settings['gsp_update_branch'] = $new_cfg['branch'];
$settings['gsp_update_repo_root'] = $new_cfg['repo_root'];
$settings['gsp_update_panel_path'] = $new_cfg['panel_path'];
-$settings['gsp_update_website_path'] = $new_cfg['website_path'];
$settings['gsp_update_panel_source_path'] = $new_cfg['panel_source_path'];
-$settings['gsp_update_linux_agent_source_path'] = $new_cfg['linux_agent_source_path'];
-$settings['gsp_update_windows_agent_source_path'] = $new_cfg['windows_agent_source_path'];
-$settings['gsp_update_website_source_path'] = $new_cfg['website_source_path'];
$settings['gsp_update_git_path'] = $new_cfg['git_path'];
$settings['gsp_update_backup_path'] = $new_cfg['backup_path'];
$settings['gsp_update_backup_retention'] = $new_cfg['backup_retention'];
$settings['gsp_update_panel_post_update_command'] = $new_cfg['panel_post_update_command'];
-$settings['gsp_update_website_post_update_command'] = $new_cfg['website_post_update_command'];
-$settings['gsp_update_linux_agent_post_update_command'] = $new_cfg['linux_agent_post_update_command'];
-$settings['gsp_update_windows_agent_post_update_command'] = $new_cfg['windows_agent_post_update_command'];
$settings['gsp_update_backup_before'] = $new_cfg['backup_before_update'];
$update_cfg = gsp_update_settings();
print_success('Update settings saved.');
}
-} elseif ($action === 'update_components') {
-$update_cfg = [
-'repo_url' => isset($_POST['gsp_update_repo_url']) ? trim((string)$_POST['gsp_update_repo_url']) : $update_cfg['repo_url'],
-'branch' => isset($_POST['gsp_update_branch']) ? trim((string)$_POST['gsp_update_branch']) : $update_cfg['branch'],
-'repo_root' => isset($_POST['gsp_update_repo_root']) ? rtrim(trim((string)$_POST['gsp_update_repo_root']), '/') : $update_cfg['repo_root'],
-'panel_path' => isset($_POST['gsp_update_panel_path']) ? rtrim(trim((string)$_POST['gsp_update_panel_path']), '/') : $update_cfg['panel_path'],
-'website_path' => isset($_POST['gsp_update_website_path']) ? rtrim(trim((string)$_POST['gsp_update_website_path']), '/') : $update_cfg['website_path'],
-'panel_source_path' => isset($_POST['gsp_update_panel_source_path']) ? trim((string)$_POST['gsp_update_panel_source_path'], '/') : $update_cfg['panel_source_path'],
-'linux_agent_source_path' => isset($_POST['gsp_update_linux_agent_source_path']) ? trim((string)$_POST['gsp_update_linux_agent_source_path'], '/') : $update_cfg['linux_agent_source_path'],
-'windows_agent_source_path' => isset($_POST['gsp_update_windows_agent_source_path']) ? trim((string)$_POST['gsp_update_windows_agent_source_path'], '/') : $update_cfg['windows_agent_source_path'],
-'website_source_path' => isset($_POST['gsp_update_website_source_path']) ? trim((string)$_POST['gsp_update_website_source_path'], '/') : $update_cfg['website_source_path'],
- 'git_path' => isset($_POST['gsp_update_git_path']) ? trim((string)$_POST['gsp_update_git_path']) : $update_cfg['git_path'],
- 'backup_path' => isset($_POST['gsp_update_backup_path']) ? rtrim(trim((string)$_POST['gsp_update_backup_path']), '/') : $update_cfg['backup_path'],
- 'backup_retention' => isset($_POST['gsp_update_backup_retention']) ? trim((string)$_POST['gsp_update_backup_retention']) : $update_cfg['backup_retention'],
- 'panel_post_update_command' => isset($_POST['gsp_update_panel_post_update_command']) ? trim((string)$_POST['gsp_update_panel_post_update_command']) : $update_cfg['panel_post_update_command'],
-'website_post_update_command' => isset($_POST['gsp_update_website_post_update_command']) ? trim((string)$_POST['gsp_update_website_post_update_command']) : $update_cfg['website_post_update_command'],
-'linux_agent_post_update_command' => isset($_POST['gsp_update_linux_agent_post_update_command']) ? trim((string)$_POST['gsp_update_linux_agent_post_update_command']) : $update_cfg['linux_agent_post_update_command'],
-'windows_agent_post_update_command' => isset($_POST['gsp_update_windows_agent_post_update_command']) ? trim((string)$_POST['gsp_update_windows_agent_post_update_command']) : $update_cfg['windows_agent_post_update_command'],
-'backup_before_update' => !empty($_POST['gsp_update_backup_before']) ? '1' : '0',
-];
-$errors = gsp_validate_update_settings($update_cfg);
-if (!empty($errors)) {
-print_failure('Update settings are invalid: ' . htmlspecialchars(implode(' | ', $errors)));
-} else {
-$requested_components = isset($_POST['gsp_update_components']) && is_array($_POST['gsp_update_components']) ? $_POST['gsp_update_components'] : [];
-$requested_components = array_values(array_intersect(array('panel', 'website', 'linux_agent', 'windows_agent'), array_map('strval', $requested_components)));
-$local_components = array_values(array_intersect(array('panel', 'website'), $requested_components));
-$agent_components = array_values(array_intersect(array('linux_agent', 'windows_agent'), $requested_components));
-$remote_ids = isset($_POST['gsp_update_remote_ids']) && is_array($_POST['gsp_update_remote_ids']) ? array_map('intval', $_POST['gsp_update_remote_ids']) : [];
-if (!empty($_POST['gsp_update_all_agents'])) {
-$remote_ids = array();
-foreach (gsp_get_remote_agent_rows() as $row) {
-$remote_ids[] = (int)$row['remote_server_id'];
-}
-}
-if (empty($requested_components)) {
-print_failure('Select at least one component to update.');
-} else {
-$messages = [];
-if (!empty($local_components)) {
-$local_result = gsp_do_local_component_update($update_cfg, $local_components);
-if (!$local_result['success']) {
-print_failure('Local component update failed: ' . htmlspecialchars($local_result['error']));
-} else {
-$messages[] = 'Local components updated, files copied: ' . intval($local_result['files_copied']);
-}
-}
-if (!empty($agent_components)) {
-$remote_result = gsp_do_remote_agents_update($update_cfg, $remote_ids, $agent_components);
-if (empty($remote_result['success']) && empty($remote_result['results'])) {
-print_failure('Remote agent update failed: ' . htmlspecialchars(isset($remote_result['message']) ? $remote_result['message'] : 'Unknown error.'));
-}
-if (!empty($remote_result['results'])) {
-echo "
| Remote ID | Status | Message |
|---|---|---|
| " . intval($rid) . " | " . htmlspecialchars($status) . " | " . htmlspecialchars($msg) . " |
git.\n"; echo " "; echo "\n"; echo "
\n"; -echo "Select the application components to update from the configured repository. Server homes, hosted game data, uploads, logs, cache, and agent configuration folders are protected.
\n"; -echo ""; -echo " "; -echo " "; -echo " "; -echo " "; -echo ""; -echo "
\n"; -$remote_rows = gsp_get_remote_agent_rows(); -if (!empty($remote_rows)) { -if (!class_exists('OGPRemoteLibrary') && function_exists('xmlrpc_encode_request') && function_exists('xmlrpc_decode') && file_exists(GSP_PANEL_DIR . '/includes/lib_remote.php')) { -require_once(GSP_PANEL_DIR . '/includes/lib_remote.php'); -} -echo "| Select | Name | Host | Status | Reported OS |
|---|---|---|---|---|
| "; -echo " | " . htmlspecialchars($remote_row['remote_server_name']) . " | "; -echo "" . htmlspecialchars($remote_row['agent_ip'] . ':' . $remote_row['agent_port']) . " | "; -echo "" . htmlspecialchars($status_text) . " | "; -echo "" . htmlspecialchars($os_text !== '' ? $os_text : gsp_infer_agent_os($remote_row, '')) . " | "; -echo "
No remote agents are configured.
\n"; -} -echo "\n"; echo "\n"; echo "\n";
-echo "Detected Layout\n"; -echo "
\n"; - -echo " Current Installation\n"; -echo "
\n"; - -echo " Updater Preflight & Patches\n"; -echo "
Preflight warnings: Preflight errors: Apache Configuration Status\n"; -echo "
Apache stale path issues: Planned replacements:
SSL certificate issues: SSL certificate issues are diagnostic only and do not block Panel updates. "; -} -echo "\n"; - -echo "Backup\n"; -echo "\n"; - -echo "Update Panel\n"; -if (is_array($releases) && !empty($releases)) { -echo "\n"; -} -echo "\n"; -echo "\n"; - -if (!empty($backups)) { -echo "Rollback\n"; -echo "\n"; -} - -echo " |