From 50692cd13a83e23f5a356733ee7bbe29760f132f Mon Sep 17 00:00:00 2001 From: klarkxy <278370456@qq.com> Date: Fri, 13 Mar 2026 15:50:14 +0800 Subject: [PATCH] feat(web): implement async git pull with real-time status updates - Replace synchronous git pull execution with background job system - Add AJAX endpoints for starting and monitoring git pull operations - Implement process tracking using PID files and exit code files - Add real-time log display with tail reading functionality - Improve user experience with non-blocking UI and status updates - Maintain backward compatibility with existing sudo permissions setup --- web/gitpull.php | 188 +++++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 169 insertions(+), 19 deletions(-) diff --git a/web/gitpull.php b/web/gitpull.php index 488d431..7d350d6 100644 --- a/web/gitpull.php +++ b/web/gitpull.php @@ -18,12 +18,91 @@ if (!isset($_SESSION[$OJ_NAME.'_'.'administrator'])) { // ==================================================== $src_path = '/home/judge/src'; -$output = []; -$return_code = -1; +$current_user = isset($_SESSION[$OJ_NAME.'_'.'user_id']) ? $_SESSION[$OJ_NAME.'_'.'user_id'] : 'admin'; +$job_key = preg_replace('/[^a-zA-Z0-9_\-]/', '_', $current_user); +$job_base = sys_get_temp_dir() . '/hustoj_gitpull_' . $job_key; +$log_file = $job_base . '.log'; +$pid_file = $job_base . '.pid'; +$code_file = $job_base . '.code'; -// 打开页面或点击重试按钮时均以 root 身份执行 git pull -$cmd = "sudo git -C " . escapeshellarg($src_path) . " pull 2>&1"; -exec($cmd, $output, $return_code); +function is_process_running($pid) { + $pid = intval($pid); + if ($pid <= 0) { + return false; + } + $out = []; + $ret = 1; + exec('ps -p ' . $pid . ' >/dev/null 2>&1', $out, $ret); + return $ret === 0; +} + +function read_tail($file, $maxBytes = 200000) { + if (!file_exists($file)) { + return ''; + } + $size = filesize($file); + if ($size === false || $size <= $maxBytes) { + return file_get_contents($file); + } + $fp = fopen($file, 'rb'); + if (!$fp) { + return ''; + } + fseek($fp, -$maxBytes, SEEK_END); + $data = fread($fp, $maxBytes); + fclose($fp); + return $data === false ? '' : $data; +} + +if (isset($_GET['ajax'])) { + header('Content-Type: application/json; charset=utf-8'); + $action = isset($_GET['action']) ? $_GET['action'] : ''; + + if ($action === 'start') { + $running = false; + if (file_exists($pid_file)) { + $pid_now = trim(file_get_contents($pid_file)); + $running = is_process_running($pid_now); + } + if (!$running) { + @unlink($code_file); + @unlink($log_file); + $script = 'sudo git -C ' . escapeshellarg($src_path) . ' pull > ' . escapeshellarg($log_file) . ' 2>&1; echo $? > ' . escapeshellarg($code_file); + $cmd = 'nohup sh -c ' . escapeshellarg($script) . ' >/dev/null 2>&1 & echo $!'; + $out = []; + $ret = 1; + exec($cmd, $out, $ret); + $pid = isset($out[0]) ? trim($out[0]) : ''; + if ($pid !== '') { + file_put_contents($pid_file, $pid); + } + } + echo json_encode(['ok' => true]); + exit; + } + + if ($action === 'status') { + $pid = file_exists($pid_file) ? trim(file_get_contents($pid_file)) : ''; + $running = is_process_running($pid); + $done = file_exists($code_file); + $exit_code = null; + if ($done) { + $exit_code = intval(trim(file_get_contents($code_file))); + } + $log = read_tail($log_file); + echo json_encode([ + 'ok' => true, + 'running' => $running, + 'done' => $done, + 'exit_code' => $exit_code, + 'log' => $log + ]); + exit; + } + + echo json_encode(['ok' => false, 'msg' => 'unknown action']); + exit; +} $show_title = "Git Pull - " . $OJ_NAME; require("template/".$OJ_TEMPLATE."/header.php"); @@ -35,26 +114,97 @@ require("template/".$OJ_TEMPLATE."/header.php");
服务器更新 (git pull )
-
-
-
- -
- 若提示 sudo 权限不足,请在服务器上执行以下命令(仅需一次):
- echo "www-data ALL=(ALL) NOPASSWD: /usr/bin/git" | sudo tee /etc/sudoers.d/www-data-git
- sudo chmod 440 /etc/sudoers.d/www-data-git -
- +
+
准备开始更新...
+

     
- - + 返回
+ +
+ 若提示 sudo 权限不足,请在服务器上执行以下命令(仅需一次):
+ echo "www-data ALL=(ALL) NOPASSWD: /usr/bin/git" | sudo tee /etc/sudoers.d/www-data-git
+ sudo chmod 440 /etc/sudoers.d/www-data-git +
+ +