Exemple #1
0
 /**
  * [runTask 运行任务]
  * @param  [type] $taskId  [description]
  * @param  [type] $ipList  [description]
  * @param  [type] $cmd     [description]
  * @param  [type] $timeout [description]
  * @return [array]          [ip:ok, failed, overtime]
  */
 public function runTask($taskId, $ipList, $cmd, $timeout = null)
 {
     $this->logger->info("START RUN TASK:{$taskId}");
     if (empty($timeout)) {
         $timeout = $this->timeout;
     }
     //执行命令
     $shellCmd = 'mkdir -p /tmp/pkg_tools_v3/;' . 'rsync -a #rsyncd_svr#::pkg_home/pkg_tools/ /tmp/pkg_tools_v3/;' . 'cd /tmp/pkg_tools_v3/;' . "{$cmd};" . 'cd scan_pkg;' . './scan_packages_info.sh >/dev/null 2>&1 & ';
     $this->logger->info("command:{$shellCmd}");
     $shellRun = new ShellExec();
     $taskList = $shellRun->runCmd($shellCmd, $ipList);
     $this->logger->info('TASK LIST:' . json_encode($taskList));
     //初始化任务状态 已启动
     foreach ($taskList as $shellTaskId => $taskInfo) {
         foreach ($taskInfo['ip_status'] as $ip => $info) {
             $status = 'started';
             $msg = 'task type:' . $taskInfo['type'] . ';' . 'shell taskid:' . $shellTaskId;
             $this->logger->info("ip:{$ip}, msg:{$msg}, status:{$status}");
             $this->updateStatus($ip, $taskId, $status, $msg, $msg);
         }
     }
     $startTime = time();
     $ipStatus = array();
     $done = array();
     $overtime = false;
     while (true) {
         $useTime = time() - $startTime;
         if ($useTime >= $timeout) {
             $overtime = true;
             break;
         }
         //获取任务执行情况
         $taskList = $shellRun->getTaskInfo($taskList);
         $this->logger->info("taskList info" . json_encode($taskList));
         $finished = true;
         foreach ($taskList as $shellTaskId => $taskInfo) {
             if ($taskInfo['status'] != 'ok') {
                 $finished = false;
             }
             foreach ($taskInfo['ip_status'] as $ip => $info) {
                 if (array_key_exists($ip, $done) && $done[$ip] == true) {
                     continue;
                 }
                 if (strpos($info['status'], 'fail') !== false) {
                     //失败的
                     $done[$ip] = true;
                     $status = 'failed';
                     $msg = $info['msg'];
                     $this->logger->info("ip:{$ip}, taskid:{$taskId}, status:{$status}, msg:{$msg}");
                     $this->updateStatus($ip, $taskId, $status, $msg, $msg);
                 } elseif ($info['status'] == 'ok') {
                     //成功的则获取命令输出并更新到数据库
                     $done[$ip] = true;
                     //匹配成功的输出 两种:result 或 resultLine
                     $matchCount = preg_match_all('/result%%(\\w+)%%(.*)%%/', $info['msg'], $matches);
                     if ($matchCount > 0) {
                         $result = end($matches[1]);
                         $msg = end($matches[2]);
                     }
                     if ($result == 'success') {
                         $status = 'ok';
                     } else {
                         $status = 'failed';
                     }
                     $matchCount = preg_match_all('/%%resultLine%%([^%]*)%%([^%]*)%%([^%]*)%%([^%]*)%%([^%]*)%%([^%]*)%%([^%]*)%%/', $info['msg'], $matches);
                     if ($matchCount > 0) {
                         $result = end($matches[6]);
                         $start = end($matches[7]);
                         if ($result == 'success') {
                             if (empty($start)) {
                                 $status = 'ok';
                             } else {
                                 $status = 'failed';
                                 $msg = $start;
                             }
                         } else {
                             $status = 'failed';
                         }
                     }
                     $this->logger->info("ip:{$ip}, taskid:{$taskId}, status:{$status}, msg:{$msg}");
                     $this->updateStatus($ip, $taskId, $status, $msg, $info['msg']);
                 }
             }
         }
         if ($finished == true) {
             break;
         }
         sleep(3);
     }
     $this->logger->info('task list:' . json_encode($taskList));
     $resultArray = array();
     //因为超时退出时, 将未结束的ip设置为fail
     if ($overtime == true) {
         $this->logger->info('overtime, set undone ip failed');
         foreach ($ipList as $ip) {
             $toSelect = array('task_id' => $taskId, 'ip' => $ip);
             $dbRes = $this->database->selectValue($toSelect, Conf::get('mysqlTaskResultTableName'));
             $status = 'ok';
             foreach ($dbRes as $index => $ipTaskInfo) {
                 if ($ipTaskInfo['status'] != 'ok' && $ipTaskInfo['status'] != 'failed') {
                     $ip = $ipTaskInfo['ip'];
                     $status = 'failed';
                     $msg = 'shell run timeout';
                     $resultArray[$ip] = 'overtime';
                     $this->logger->info("ip:{$ip}, taskid:{$taskId}, status:{$status}, msg:{$msg}");
                     $this->updateStatus($ip, $taskId, $status, $msg, $msg);
                 } else {
                     $resultArray[$ip] = $ipTaskInfo['status'];
                 }
             }
         }
     }
     $this->updateTaskStatus($taskId);
     return $resultArray;
 }