diff --git a/app/Config/Routes.php b/app/Config/Routes.php index 67d02ca..9677e49 100644 --- a/app/Config/Routes.php +++ b/app/Config/Routes.php @@ -1217,7 +1217,6 @@ $routes->group('setting', static function($routes) { $routes->get('admin/system-ops', 'SystemOps::index', ['filter' => $settingsAdminFilter]); $routes->get('admin/system-ops/panel', 'SystemOps::panel', ['filter' => $settingsAdminFilter]); $routes->get('admin/system-ops/diagnose', 'SystemOps::diagnose', ['filter' => $settingsAdminFilter]); - $routes->post('admin/system-ops/update', 'SystemOps::update', ['filter' => $settingsAdminFilter]); $routes->post('admin/system-ops/updateDirect', 'SystemOps::updateDirect', ['filter' => $settingsAdminFilter]); $routes->post('admin/system-ops/action', 'SystemOps::action', ['filter' => $settingsAdminFilter]); $routes->post('admin/hospital-profile/save', 'Setting\\HospitalProfile::save'); diff --git a/app/Controllers/SystemOps.php b/app/Controllers/SystemOps.php index b0f6ca5..225f1a8 100644 --- a/app/Controllers/SystemOps.php +++ b/app/Controllers/SystemOps.php @@ -29,14 +29,6 @@ class SystemOps extends BaseController return view('Setting/Admin/system_ops_panel', $data); } - public function update() - { - $ops = new SystemOperations(); - $result = $ops->runUpdate(); - - return $this->response->setJSON($result); - } - public function updateDirect() { $ops = new SystemOperations(); diff --git a/app/Libraries/SystemOperations.php b/app/Libraries/SystemOperations.php index a7b39de..7926c16 100644 --- a/app/Libraries/SystemOperations.php +++ b/app/Libraries/SystemOperations.php @@ -195,156 +195,6 @@ class SystemOperations @rmdir($dir); } - public function runUpdate(): array - { - $repoPath = ROOTPATH; - $logFile = WRITEPATH . 'system_update.log'; - $startedAt = date('Y-m-d H:i:s'); - - $entry = [ - 'timestamp' => $startedAt, - 'type' => 'update', - 'status' => 'running', - 'message' => 'HMS update started (git pull)', - ]; - $this->appendHistory($entry); - - // Pre-check: Verify .git directory exists - if (!is_dir($repoPath . '/.git')) { - $errorMsg = 'Git repository not found. .git directory missing.'; - $this->appendHistory([ - 'timestamp' => date('Y-m-d H:i:s'), - 'type' => 'update', - 'status' => 'failed', - 'message' => 'HMS update failed', - 'detail' => $errorMsg, - ]); - file_put_contents($logFile, 'FAILED: ' . $errorMsg . PHP_EOL, FILE_APPEND); - return ['ok' => false, 'message' => $errorMsg]; - } - - // Find git command location (try common paths) - $gitPath = $this->findGitCommand(); - if (!$gitPath) { - $errorMsg = 'Git command not found. Tried: /usr/bin/git, /bin/git, /usr/local/bin/git. Ensure git is installed on the system.'; - $this->appendHistory([ - 'timestamp' => date('Y-m-d H:i:s'), - 'type' => 'update', - 'status' => 'failed', - 'message' => 'HMS update failed', - 'detail' => $errorMsg, - ]); - file_put_contents($logFile, 'FAILED: ' . $errorMsg . PHP_EOL, FILE_APPEND); - return ['ok' => false, 'message' => $errorMsg]; - } - - // Run git status first to check connectivity and permissions - $statusCmd = 'cd ' . escapeshellarg($repoPath) . ' && ' . escapeshellarg($gitPath) . ' status 2>&1'; - $statusResult = $this->runCommand($statusCmd); - if ($statusResult['exit_code'] !== 0) { - $statusError = trim($statusResult['output']); - $errorMsg = ''; - - // Get diagnostics first - $diagnostics = $this->getGitDiagnostics($gitPath, $repoPath); - - // Build detailed diagnostic summary - $diagSummary = 'DIAGNOSTICS: ' . - 'Version=' . $diagnostics['git_version'] . '; ' . - 'User=' . $diagnostics['git_config_user_name'] . '; ' . - 'Email=' . $diagnostics['git_config_user_email'] . '; ' . - 'Remote=' . $diagnostics['remote_url'] . '; ' . - 'Branch=' . $diagnostics['current_branch'] . '; ' . - '.git=' . $diagnostics['git_dir_exists'] . '; ' . - 'Config=' . $diagnostics['git_config_exists']; - - // Parse error message - if (strpos($statusError, 'Permission denied') !== false) { - $errorMsg = 'PERMISSION ERROR: Git directory may not be writable by www-data user. Check directory ownership.'; - } elseif (strpos($statusError, 'fatal: Not a git repository') !== false) { - $errorMsg = 'REPO ERROR: Not a valid git repository. .git directory corrupted.'; - } elseif (strpos($statusError, 'user.email') !== false || strpos($statusError, 'user.name') !== false) { - $errorMsg = 'CONFIG ERROR: Git user not configured. RUN: git config user.name "www-data" && git config user.email "deploy@example.com"'; - } elseif (strpos($statusError, 'SSL certificate problem') !== false) { - $errorMsg = 'SSL ERROR: Certificate verification failed. RUN: git config http.sslVerify false'; - } elseif (strpos($statusError, 'Could not resolve host') !== false || strpos($statusError, 'Connection refused') !== false) { - $errorMsg = 'NETWORK ERROR: Cannot connect to GitHub. Check network/firewall.'; - } elseif (trim($statusError) === '') { - $errorMsg = 'GIT ERROR: Command returned no output. Possible permission or file system issue.'; - } else { - $errorMsg = 'GIT ERROR: ' . substr($statusError, 0, 150); - } - - $fullMsg = $errorMsg . ' | ' . $diagSummary; - - $this->appendHistory([ - 'timestamp' => date('Y-m-d H:i:s'), - 'type' => 'update', - 'status' => 'failed', - 'message' => 'HMS update failed', - 'detail' => $fullMsg, - ]); - file_put_contents($logFile, 'FAILED: ' . $fullMsg . ' (Raw error: ' . $statusError . ')' . PHP_EOL, FILE_APPEND); - return ['ok' => false, 'message' => $fullMsg]; - } - - // Run git pull with timeout protection - $command = 'cd ' . escapeshellarg($repoPath) . ' && timeout 60 ' . escapeshellarg($gitPath) . ' pull origin main 2>&1'; - $result = $this->runCommand($command); - $output = $result['output']; - - // Check for timeout - if (str_contains($output, 'Terminated') || $result['exit_code'] === 124) { - $errorMsg = 'Update timed out after 60 seconds. Network connectivity or server response issue.'; - $this->appendHistory([ - 'timestamp' => date('Y-m-d H:i:s'), - 'type' => 'update', - 'status' => 'timeout', - 'message' => 'HMS update timed out (60 seconds)', - 'detail' => $errorMsg, - ]); - file_put_contents($logFile, 'TIMEOUT: ' . $output . PHP_EOL, FILE_APPEND); - return ['ok' => false, 'message' => $errorMsg]; - } - - if ($result['exit_code'] !== 0) { - // Parse error message for user-friendly output - $errorMsg = $output; - if (strpos($output, 'Permission denied') !== false) { - $errorMsg = 'Permission denied. Check SSH key setup and permissions.'; - } elseif (strpos($output, 'Authentication failed') !== false || strpos($output, 'fatal: could not read') !== false) { - $errorMsg = 'Authentication failed. SSH keys may not be configured for www-data user.'; - } elseif (strpos($output, 'Connection refused') !== false) { - $errorMsg = 'Connection refused. GitHub server may be unreachable.'; - } elseif (strpos($output, 'fatal: remote origin does not appear to be a git repository') !== false) { - $errorMsg = 'Remote origin not configured correctly.'; - } - - $this->appendHistory([ - 'timestamp' => date('Y-m-d H:i:s'), - 'type' => 'update', - 'status' => 'failed', - 'message' => 'HMS update failed', - 'detail' => $errorMsg, - ]); - file_put_contents($logFile, 'FAILED: ' . $output . PHP_EOL, FILE_APPEND); - - return ['ok' => false, 'message' => $errorMsg, 'output' => $output]; - } - - // Success - $this->appendHistory([ - 'timestamp' => date('Y-m-d H:i:s'), - 'type' => 'update', - 'status' => 'success', - 'message' => 'HMS update completed', - 'detail' => $output, - ]); - file_put_contents($logFile, 'SUCCESS: ' . $output . PHP_EOL, FILE_APPEND); - - return ['ok' => true, 'message' => 'HMS update completed successfully', 'output' => $output]; - } - private function findGitCommand(): ?string { // Try common git installation paths diff --git a/app/Views/Setting/Admin/system_ops.php b/app/Views/Setting/Admin/system_ops.php index 5db046c..9ad2153 100644 --- a/app/Views/Setting/Admin/system_ops.php +++ b/app/Views/Setting/Admin/system_ops.php @@ -88,9 +88,8 @@ setHealthState('healthy'); setInterval(function(){ refreshPanel(); }, 30000); - $(document).off('click', '#btnUpdateSystem, #btnUpdateDirectGithub, #btnRestartWeb, #btnRestartPhp, #btnReboot, #btnShutdown') - .on('click', '#btnUpdateSystem', function(){ if (!confirm('Pull latest HMS code from repository?\n\nThis method requires git to be configured on the server.')) return; postAction('= base_url('setting/admin/system-ops/update') ?>', {}, this); }) - .on('click', '#btnUpdateDirectGithub', function(){ if (!confirm('Deploy latest HMS code from GitHub?\n\nThis will download the latest code and update files.\nThis method is more reliable if git is not available.')) return; postAction('= base_url('setting/admin/system-ops/updateDirect') ?>', {}, this); }) + $(document).off('click', '#btnUpdateDirectGithub, #btnRestartWeb, #btnRestartPhp, #btnReboot, #btnShutdown') + .on('click', '#btnUpdateDirectGithub', function(){ if (!confirm('Deploy latest HMS code from GitHub?\n\nThis will download the latest code and update all files.')) return; postAction('= base_url('setting/admin/system-ops/updateDirect') ?>', {}, this); }) .on('click', '#btnRestartWeb', function(){ if (!confirm('Restart the web server now?')) return; postAction('= base_url('setting/admin/system-ops/action') ?>', {action: 'restart_web'}, this); }) .on('click', '#btnRestartPhp', function(){ if (!confirm('Restart PHP-FPM now?')) return; postAction('= base_url('setting/admin/system-ops/action') ?>', {action: 'restart_php'}, this); }) .on('click', '#btnReboot', function(){ if (!confirm('Reboot the server now?')) return; postAction('= base_url('setting/admin/system-ops/action') ?>', {action: 'reboot'}, this); }) diff --git a/app/Views/Setting/Admin/system_ops_panel.php b/app/Views/Setting/Admin/system_ops_panel.php index 5d36e84..e5cb41d 100644 --- a/app/Views/Setting/Admin/system_ops_panel.php +++ b/app/Views/Setting/Admin/system_ops_panel.php @@ -44,10 +44,7 @@