# Panel Update Module ## Scope This document covers the admin Panel updater implemented through: - `Panel/modules/update/update.php` - `Panel/modules/administration/panel_update.php` - `Panel/includes/lib_remote.php` for remote agent component updates ## Current Workflow ```text Admin opens home.php?m=update -> update.php loads panel_update.php -> gsp_panel_update_section() renders UI Configured Git update: -> load saved settings -> validate repo/branch/paths/retention -> preflight path and write checks -> create backup when enabled -> git clone configured branch to temp checkout -> resolve source layout -> self-update updater files first if needed -> apply patches -> sync Panel and Website files -> preserve config.inc.php and protected paths -> write LAST_UPDATE.txt and version metadata -> clear cache / fix permissions -> prune backups by retention ``` ## Backup Workflow Backup helpers: - `gsp_get_backup_base()` - `gsp_get_backup_retention()` - `gsp_create_full_backup()` - `gsp_safe_component_backup()` - `gsp_get_available_backups()` - `gsp_get_managed_backup_entries()` - `gsp_prune_old_backups()` Behavior: - full updater backups use the configured `gsp_update_backup_path` - component-only backups also use the configured backup path - missing parent directories are created recursively - failures are logged to `logs/update_trace.log` with path diagnostics - retention is enforced after full backups and component backups Managed backup directory names: - full backups: `YYYY-MM-DD_HH-MM-SS` - component backups: `component__YYYY-MM-DD_HH-MM-SS` Rollback uses only full backups. Component backups are retained and pruned, but are not shown in the rollback selector. ## Retention Workflow Retention setting: - `gsp_update_backup_retention` - default: `5` Behavior: 1. Create backup. 2. Scan all updater-managed backup directories under the configured backup path. 3. Sort newest to oldest. 4. Delete entries beyond retention. 5. Log deleted backup directories to `logs/update_trace.log`. This applies to both: - full updater backups - component backups created by local component updates ## Required Folders And Permissions Minimum writable locations: - configured repository root - configured Panel path - configured backup path - `logs/` under repository root for `update_trace.log` Required tools when used: - `git` - `tar` - `mysqldump` for database backup - `mysql` for restore ## Error Handling The update page should not white-screen for routine helper/runtime failures. Current protections: - `update.php` checks that `gsp_panel_update_section()` exists before calling it - `update.php` catches `Throwable` and logs unexpected failures - `gsp_panel_update_section()` catches action-time `Throwable` and keeps rendering the UI - backup directory creation logs detailed path diagnostics - missing helper regressions are surfaced as user-visible failures instead of fatal white screens where possible Log file: - `GSP_ROOT/logs/update_trace.log` ## Helper Scope Warnings These helpers must remain top-level: - `gsp_update_settings()` - `gsp_validate_update_settings()` - `gsp_checkout_update_source()` - `gsp_do_configured_git_update()` - `gsp_disable_ssl_vhost()` If any of these are accidentally nested inside another function, the update page can pass `php -l` but still fail at runtime with `Call to undefined function ...`. ## Scheduler Audit Current finding: - the existing `cron` scheduler is game-server oriented - it schedules `gamemanager` and `server_content` actions through `ogp_api.php` - it does **not** currently expose a first-class scheduled self-update path for: - Panel updates - Website updates - remote Linux agent code updates - remote Windows agent code updates Result: - backup/retention integration for scheduled self-updates is currently not applicable because those scheduled self-update jobs do not exist in the current codebase - game-server Steam/content scheduler jobs are separate and do not use this updater module ## Remote Agent Update Flow Remote component updates use: - `lib_remote.php::component_update()` - agent-side `component_update` RPC The Panel: 1. validates configured repo and source folder 2. selects Linux or Windows agent source folder 3. builds an encoded payload 4. sends the payload over XML-RPC 5. shows queued/failed results per remote host ## Troubleshooting ### Undefined function crash Check: - `php -l Panel/modules/administration/panel_update.php` - `php -r 'require "Panel/modules/administration/panel_update.php"; var_dump(function_exists("gsp_checkout_update_source"));'` If `php -l` passes but `function_exists(...)` is false, a helper was nested inside another function. ### Backup directory creation fails Check: - configured `gsp_update_backup_path` - parent directory existence - web server write access - `logs/update_trace.log` for the exact `mkdir` failure ### Retention appears wrong Remember: - rollback list shows only full backups - managed backup count includes full backups and component backups - pruning applies to all updater-managed backup directories ### Update page loads but remote agent updates fail Check: - PHP XML-RPC extension on the Panel host - agent reachability and encryption key - agent-side `component_update` support ## Validation Commands ```bash php -l Panel/modules/administration/panel_update.php php -l Panel/modules/update/update.php php Panel/modules/update/tests/update_config_smoke.php php -r 'require "Panel/modules/administration/panel_update.php"; foreach (["gsp_checkout_update_source","gsp_do_configured_git_update","gsp_disable_ssl_vhost"] as $f) echo $f,":",function_exists($f)?"yes":"no",PHP_EOL;' ```