diff --git a/001-bugfix-and-adapt-rollback-tasks.patch b/001-bugfix-and-adapt-rollback-tasks.patch
new file mode 100644
index 0000000..a389f0b
--- /dev/null
+++ b/001-bugfix-and-adapt-rollback-tasks.patch
@@ -0,0 +1,1025 @@
+From bba113a5899bb0b17916b2179e1f5594756dc58e Mon Sep 17 00:00:00 2001
+From: Hu gang <18768366022@163.com>
+Date: Wed, 13 Dec 2023 15:15:59 +0800
+Subject: [PATCH] feat: add host management status, adaptation rollback tsak
+
+---
+ src/api/assest.js | 1 +
+ src/api/leaks.js | 24 +--
+ src/config/router.config.js | 4 +
+ src/vendor/ant-design-pro/utils/request.js | 14 +-
+ src/views/assests/HostDetail.vue | 39 ++--
+ src/views/assests/HostManagement.vue | 82 ++++---
+ src/views/leaks/LeakTaskDetail.vue | 203 ++++++++++--------
+ src/views/leaks/LeakTaskList.vue | 4 +
+ src/views/leaks/TaskResultReport.vue | 76 +++++--
+ .../components/CreateRepairTaskDrawer.vue | 36 ++--
+ 10 files changed, 277 insertions(+), 206 deletions(-)
+
+diff --git a/src/api/assest.js b/src/api/assest.js
+index a0f70ec..94015d3 100644
+--- a/src/api/assest.js
++++ b/src/api/assest.js
+@@ -55,6 +55,7 @@ export function hostList({tableInfo, ...parameter}) {
+ ...parameter,
+ host_group_list: tableInfo.filters.host_group_name || [],
+ management,
++ search_key: tableInfo.filters.searchKey,
+ sort: tableInfo.sorter.field,
+ direction: directionMap[tableInfo.sorter.order],
+ page: tableInfo.pagination.current,
+diff --git a/src/api/leaks.js b/src/api/leaks.js
+index 8daf70d..c6f704b 100644
+--- a/src/api/leaks.js
++++ b/src/api/leaks.js
+@@ -44,15 +44,15 @@ const api = {
+ getRpmUnderCve: '/vulnerability/cve/packages/host/get', // 查询cve影响的rpm包的主机列表
+ getCvefixLeakRpm: '/vulnerability/task/cve/rpm/get', // 修复任务详情中cve列表的二级package
+ getCveRpmHostUnderLeak: '/vulnerability/task/cve/rpm/host/get', // 查询修复任务下的cve影响的rpm包的主机列表
+- getCveListInFixDetail: '/vulnerability/task/cve-fix/info/get', // 新接口取代api.getCveUnderCveTask 获取修复任务详情下的cve列表
+ getRpmListInFixDetail: '/vulnerability/task/cve-fix/rpm/get', // 新接口取代api.getCvefixLeakRpm,获取修复任务详情下指定主机和任务下的rpm列表
+ getCveFixReport: '/vulnerability/task/cve-fix/result/get', // 新接口取代api.getCveTaskResult ,获取修复任务的报告
+- getCveRollvackReport: ' /vulnerability/task/rollback/result/get', // 获取回滚任务报告
++ getCveRollvackReport: '/vulnerability/task/cve-rollback/result/get', // 获取回滚任务报告
+ generateHotPathRemoveTask: '/vulnerability/task/hotpatch-remove/generate', // 新接口取代api.generateRollbackTask ,生成热补丁移除任务
+- getRpmListInRollbackDetail: '/vulnerability/task/rollback/rpm/get', // 获取回滚任务详情列表下的rpm信息
+- getCveListInRollbackDetail: '/vulnerability/task/rollback/cve-info/get', // 获取回滚任务详情下的列表信息
++ getRpmListInRollbackDetail: '/vulnerability/task/cve-rollback/rpm/get', // 获取回滚任务详情列表下的rpm信息
+ generateRollbackTask: '/vulnerability/task/cve-rollback/generate', // 生成回滚任务
++ getCveListInRollbackDetail: '/vulnerability/task/cve-rollback/info/get', // 获取回滚任务详情下的列表信息
+ getCveHotpatchRemoveDetail: '/vulnerability/task/hotpatch-remove/info/get', // 获取热补丁移除任务详情
++ getCveListInFixDetail: '/vulnerability/task/cve-fix/info/get', // 新接口取代api.getCveUnderCveTask 获取修复任务详情下的cve列表
+ getHotpatchRemoveTaskReport: '/vulnerability/task/hotpatch-remove/result/get', // 获取热补丁移除任务报告
+ getAllHostInDetail: '/vulnerability/task/host/get' // 获取详情页面下所有的hostid
+ };
+@@ -132,6 +132,7 @@ export function getCveListInRollbackDetail({tableInfo, ...params}) {
+ task_id: params.taskId,
+ direction: sorterMap[tableInfo.sorter.order],
+ filter: {
++ search_key: tableInfo.filters.searchKey,
+ status: tableInfo.filters.status
+ },
+ page: tableInfo.pagination.current,
+@@ -140,7 +141,7 @@ export function getCveListInRollbackDetail({tableInfo, ...params}) {
+ });
+ }
+
+-// 创建热补丁回退任务
++// 创建热补丁移除任务
+ export function generateHotPatchRemoveTask(params) {
+ return request({
+ url: api.generateHotPathRemoveTask,
+@@ -196,6 +197,7 @@ export function getCveListInFixDetail({tableInfo, ...params}) {
+ task_id: params.taskId,
+ direction: sorterMap[tableInfo.sorter.order],
+ filter: {
++ search_key: tableInfo.filters.searchKey,
+ status: tableInfo.filters.status
+ },
+ page: tableInfo.pagination.current,
+@@ -267,18 +269,6 @@ export function getCveFixRpm(parameters) {
+ });
+ }
+
+-// export function generateRollbackTask(parameters) {
+-// return request({
+-// url: api.generateRollbackTask,
+-// method: 'post',
+-// data: {
+-// task_name: parameters.task_name,
+-// description: parameters.description,
+-// info: parameters.info || []
+-// }
+-// });
+-// }
+-
+ export function getCveExport(parameter) {
+ return request({
+ url: api.getCveExport,
+diff --git a/src/config/router.config.js b/src/config/router.config.js
+index b92011f..5f1d4df 100644
+--- a/src/config/router.config.js
++++ b/src/config/router.config.js
+@@ -575,6 +575,10 @@ export const asyncRouterMap = [
+ breadcrumbName: routeMap.leaks.children.leakTaskView.children.leakTaskList.title,
+ path: routeMap.leaks.children.leakTaskView.children.leakTaskList.path
+ },
++ {
++ breadcrumbName: routeMap.leaks.children.leakTaskView.children.leakTaskDetail.title,
++ path: routeMap.leaks.children.leakTaskView.children.leakTaskDetail.path
++ },
+ {
+ breadcrumbName: routeMap.leaks.children.leakTaskView.children.taskResultReport.title,
+ path: routeMap.leaks.children.leakTaskView.children.taskResultReport.path
+diff --git a/src/vendor/ant-design-pro/utils/request.js b/src/vendor/ant-design-pro/utils/request.js
+index d9320d8..661bfd0 100644
+--- a/src/vendor/ant-design-pro/utils/request.js
++++ b/src/vendor/ant-design-pro/utils/request.js
+@@ -101,7 +101,7 @@ request.interceptors.response.use((response) => {
+ const code = response.data.code || response.status;
+ // 不处理所有2xx的状态码
+ if (!code.toString().match(/^2[0-9]{2,2}$/)) {
+- let err = null;
++ // let err = null;
+ switch (code) {
+ case '1201':
+ if (!timestamp1 || timestamp1 + 1632252465 < new Date().getTime()) {
+@@ -166,10 +166,14 @@ request.interceptors.response.use((response) => {
+ });
+ return retryRequest;
+ default:
+- err = new Error(response.data.message);
+- err.data = response.data.data;
+- err.response = response.data;
+- throw err;
++ notification.error({
++ message: response.data.label,
++ description: response.data.message
++ });
++ // err = new Error(response.data.message);
++ // err.data = response.data.data;
++ // err.response = response.data;
++ // throw err;
+ }
+ }
+ if (response.headers['content-type'] === 'application/octet-stream') {
+diff --git a/src/views/assests/HostDetail.vue b/src/views/assests/HostDetail.vue
+index 8286caf..6eadb05 100644
+--- a/src/views/assests/HostDetail.vue
++++ b/src/views/assests/HostDetail.vue
+@@ -49,38 +49,37 @@ export default {
+ };
+ },
+ methods: {
+- fetchHostInfo(This) {
+- const _this = This;
+- This.basicHostInfoIsLoading = true;
+- getHostDetail(This.hostId, true)
+- .then(function (res) {
+- _this.basicHostInfo = res.data.host_infos[0];
+- _this.scene = This.basicHostInfo.scene;
++ fetchHostInfo() {
++ this.basicHostInfoIsLoading = true;
++ getHostDetail(Number(this.hostId), true)
++ .then((res) => {
++ this.basicHostInfo = res.data.host_infos[0];
++ this.scene = this.basicHostInfo.scene;
+ })
+- .catch(function (err) {
+- _this.$message.error(err.response.message);
++ .catch((err) => {
++ this.$message.error(err.response.message);
+ })
+ .finally(() => {
+- _this.basicHostInfoIsLoading = false;
++ this.basicHostInfoIsLoading = false;
+ });
+- This.basicInfoIsLoading = true;
+- getHostDetail(This.hostId, false)
+- .then(function (res) {
+- _this.basicInfo = res.data.host_infos[0];
++ this.basicInfoIsLoading = true;
++ getHostDetail(Number(this.hostId), false)
++ .then((res) => {
++ this.basicInfo = res.data.host_infos[0];
+ })
+- .catch(function (err) {
+- _this.$message.error(err.response.message);
++ .catch((err) => {
++ this.$message.error(err.response.message);
+ })
+ .finally(() => {
+- _this.basicInfoIsLoading = false;
++ this.basicInfoIsLoading = false;
+ });
+ },
+ reFetchHostInfo() {
+- this.$options.methods.fetchHostInfo(this);
++ this.fetchHostInfo();
+ }
+ },
+- mounted: function () {
+- this.$options.methods.fetchHostInfo(this);
++ mounted() {
++ this.fetchHostInfo();
+ }
+ };
+
+diff --git a/src/views/assests/HostManagement.vue b/src/views/assests/HostManagement.vue
+index aaa86a8..77e0ed8 100644
+--- a/src/views/assests/HostManagement.vue
++++ b/src/views/assests/HostManagement.vue
+@@ -17,7 +17,8 @@
+
+
+
+- 重置条件
++
++
+
+
+
+@@ -59,26 +60,19 @@
+ >{{ hostName }}
+ {{ isMana ? '是' : '否' }}
+- {{ hostStatusMap[status] }}
++
++
++ {{ hostStatusMap[status] }}
++
+ {{ scene ? (scene === 'normal' ? '通用' : scene) : '暂无' }}
+
+-
+ 编辑
+- |
+- 删除
++ >编辑
++
++ 删除
+
+-
+
+
+
+@@ -94,7 +88,7 @@ import MyPageHeaderWrapper from '@/views/utils/MyPageHeaderWrapper';
+ import {getSelectedRow} from '@/views/utils/getSelectedRow';
+ import HostDetailDrawer from './components/HostDetailDrawer';
+ // import HostTerminal from '@/views/assests/components/HostTerminal';
+-import {hostList, deleteHost, hostGroupList} from '@/api/assest';
++import {hostList, deleteHost, hostGroupList, getHostListWithStatus} from '@/api/assest';
+
+ const hostStatusMap = {
+ 0: '在线',
+@@ -214,6 +208,9 @@ export default {
+ }
+ },
+ methods: {
++ async getAllHostStatus() {
++ const res = await getHostListWithStatus();
++ },
+ handleTableChange(pagination, filters, sorter) {
+ // 存储翻页状态
+ this.pagination = pagination;
+@@ -230,14 +227,13 @@ export default {
+ this.selectedRowsAll = getSelectedRow(selectedRowKeys, this.selectedRowsAll, this.tableData, 'host_id');
+ },
+ // 获取列表数据
+- getHostList() {
+- const _this = this;
++ async getHostList() {
+ this.tableIsLoading = true;
+ const pagination = this.pagination || {};
+ const filters = this.filters || {};
+ const sorter = this.sorter || {};
+
+- hostList({
++ const hostListRes = await hostList({
+ tableInfo: {
+ pagination: {
+ current: pagination.current,
+@@ -249,22 +245,28 @@ export default {
+ order: sorter.order
+ }
+ }
+- })
+- .then(function (res) {
+- _this.tableData = res.data.host_infos || [];
+- _this.pagination = {
+- ..._this.pagination,
+- current: pagination.current,
+- pageSize: pagination.pageSize,
+- total: res.data.total_count || (res.data.total_count === 0 ? 0 : pagination.total)
+- };
+- })
+- .catch(function (err) {
+- _this.$message.error(err.response.message);
+- })
+- .finally(function () {
+- _this.tableIsLoading = false;
+- });
++ });
++ if (hostListRes) {
++ this.tableData = hostListRes.data.host_infos || [];
++ this.pagination = {
++ ...this.pagination,
++ current: pagination.current,
++ pageSize: pagination.pageSize,
++ total: hostListRes.data.total_count || (hostListRes.data.total_count === 0 ? 0 : pagination.total)
++ };
++ const hostIdList = this.tableData.map((item) => item.host_id);
++ this.tableIsLoading = false;
++ const res = await getHostListWithStatus(hostIdList);
++ if (res) {
++ this.tableData.forEach((item) => {
++ const s = res.data.find((s) => item.host_id === s.host_id);
++ if (s) {
++ item.status = s.status;
++ }
++ });
++ this.tableData = JSON.parse(JSON.stringify(this.tableData));
++ }
++ }
+ },
+ editHost(record) {
+ this.$message.success('连接到主机' + record.host_ip);
+@@ -384,6 +386,16 @@ export default {
+ duration: 5
+ });
+ },
++ handleSearch(text = '') {
++ this.pagination = defaultPagination;
++ this.sorter = null;
++ if (!this.filters) {
++ this.filters = {};
++ }
++ this.selectedRowKeys = [];
++ this.filters.searchKey = text !== '' ? text : undefined;
++ this.getHostList();
++ },
+ handleReset() {
+ this.pagination = defaultPagination;
+ this.sorter = null;
+diff --git a/src/views/leaks/LeakTaskDetail.vue b/src/views/leaks/LeakTaskDetail.vue
+index 27e919e..f7f7438 100644
+--- a/src/views/leaks/LeakTaskDetail.vue
++++ b/src/views/leaks/LeakTaskDetail.vue
+@@ -111,7 +111,9 @@
+
+
+
+- 生成回滚任务
++ 生成回滚任务
+
+
+
+@@ -236,12 +238,13 @@ import {
+ getTaskProgress,
+ generateRollbackTask,
+ getCveProgressUnderCveTask,
+- getAllHostInDetail
++ getAllHostInDetail,
++ getHostScanStatus
+ } from '@/api/leaks';
+ import configs from '@/config/defaultSettings';
+
+ const taskTypeMap = {
+- 'cve fix': '漏洞修复',
++ 'cve fix': 'cve修复',
+ 'repo set': 'REPO设置',
+ 'cve rollback': 'cve回滚',
+ 'hotpatch remove': '热补丁移除'
+@@ -307,6 +310,8 @@ export default {
+ },
+ data() {
+ return {
++ // 生成回滚任务按钮是否loading
++ isRollBackButtonLoading: false,
+ expandedRowKeys: [],
+ rpmrecord: {},
+ propType: '',
+@@ -379,7 +384,7 @@ export default {
+ {
+ dataIndex: 'host_name',
+ key: 'host_name',
+- title: '主机',
++ title: '主机名',
+ scopedSlots: {customRender: 'hostName'}
+ },
+ {
+@@ -391,7 +396,7 @@ export default {
+ {
+ dataIndex: 'cve_num',
+ key: 'cve_num',
+- title: '修复的CVE',
++ title: 'CVE数量',
+ scopedSlots: {customRender: 'cveNum'}
+ },
+ {
+@@ -405,26 +410,27 @@ export default {
+ {text: '修复成功', value: 'succeed'},
+ {text: '待修复', value: 'fail'},
+ {text: '运行中', value: 'running'},
+- {text: '未知', value: 'None'}
++ {text: '未知', value: 'unknown'}
+ ]
+ : [
+ {text: '回滚成功', value: 'succeed'},
+ {text: '待回滚', value: 'fail'},
+ {text: '运行中', value: 'running'},
+- {text: '未知', value: 'None'}
++ {text: '未知', value: 'unknown'}
+ ],
+ filteredValue: filters.status || null,
+ onFilter: (value, record) => record.status.includes(value)
+ }
+ ];
+ },
++
+ repoColumns() {
+ let {filters} = this;
+ filters = filters || {};
+ return [
+ {
+ dataIndex: 'host_name',
+- title: '主机名称',
++ title: '主机名',
+ scopedSlots: {customRender: 'host_name'}
+ },
+ {
+@@ -452,27 +458,28 @@ export default {
+ },
+ // 展开后的列表列号
+ innerColumns() {
++ const {taskType} = this;
+ return [
+ {
+ dataIndex: 'installed_rpm',
+ key: 'installed_rpm',
+- title: '受影响rpm'
++ title: taskType === 'cve fix' ? '受影响rpm' : '已安装rpm'
+ },
+ {
+- dataIndex: 'available_rpm',
+- key: 'available_rpm',
+- title: '待安装rpm',
+- scopedSlots: {customRender: 'available_rpm'}
++ dataIndex: taskType === 'cve fix' ? 'available_rpm' : 'target_rpm',
++ key: taskType === 'cve fix' ? 'available_rpm' : 'target_rpm',
++ title: taskType === 'cve fix' ? '待安装rpm' : '目标rpm',
++ scopedSlots: {customRender: 'rpm'}
+ },
+ {
+ dataIndex: 'cves',
+ key: 'cves',
+- title: '修复cve'
++ title: 'CVE'
+ },
+ {
+ dataIndex: 'status',
+ key: 'rpm_status',
+- title: '状态',
++ title: this.taskType === 'cve fix' ? '修复状态' : '回滚状态',
+ scopedSlots: {customRender: 'status'},
+ filter:
+ this.taskType === 'cve fix'
+@@ -480,13 +487,13 @@ export default {
+ {text: '修复成功', value: 'succeed'},
+ {text: '待修复', value: 'fail'},
+ {text: '运行中', value: 'running'},
+- {text: '未知', value: 'None'}
++ {text: '未知', value: 'unknown'}
+ ]
+ : [
+ {text: '回滚成功', value: 'succeed'},
+ {text: '待回滚', value: 'fail'},
+ {text: '运行中', value: 'running'},
+- {text: '未知', value: 'None'}
++ {text: '未知', value: 'unknown'}
+ ]
+ }
+ ];
+@@ -563,50 +570,43 @@ export default {
+ clearInterval(this.jumpModalInterval);
+ this.isRollbackModelvisible = false;
+ this.$router.push({
+- path: `/leaks/task/${this.taskType}/${this.rollbackTaskId}`,
++ path: `/leaks/task/cve rollback/${this.rollbackTaskId}`,
+ query: {
+ task_id: this.rollbackTaskId
+ }
+ });
++ this.expandedRowKeys = [];
++ this.taskType = 'cve rollback';
+ this.taskId = this.rollbackTaskId;
+ localStorage.setItem('taskId', this.taskId);
+ this.getInitalData();
+ },
+ async generateRollbackTask() {
++ this.isRollBackButtonLoading = true;
+ if (this.detail.statuses['running'] > 0) {
+ this.$warning({
+ title: '有任务正在运行,不能回滚。'
+ });
++ this.isRollBackButtonLoading = false;
+ return;
+ }
+- this.$confirm({
+- title: (
+-
+- 回滚后无法恢复
+-
+- 请确认回滚CVE修复任务:
+-
+- ),
+- icon: () => ,
+- onOk: async () => {
+- const res = await generateRollbackTask(this.taskId);
+- if (res) {
+- this.rollbackTaskId = res.data.task_id;
+- this.countDown = 5;
+- this.isRollbackModelvisible = true;
+- this.jumpModalInterval = setInterval(() => {
+- this.countDown = this.countDown - 1;
+- if (this.countDown === 0) {
+- clearInterval(this.jumpModalInterval);
+- this.isRollbackModelvisible = false;
+- }
+- }, 1000);
++ const res = await generateRollbackTask(this.taskId);
++ if (res) {
++ this.rollbackTaskId = res.data.task_id;
++ this.countDown = 5;
++ this.isRollbackModelvisible = true;
++ this.jumpModalInterval = setInterval(() => {
++ this.countDown = this.countDown - 1;
++ if (this.countDown === 0) {
++ clearInterval(this.jumpModalInterval);
++ this.isRollbackModelvisible = false;
+ }
+- }
+- });
++ }, 1000);
++ this.isRollBackButtonLoading = false;
++ } else {
++ }
+ },
+ dateFormat,
+-
+ jumptoResult(value) {
+ this.$router.push({
+ path: `/leaks/task-report/${this.taskType}/${this.taskId}`,
+@@ -633,7 +633,6 @@ export default {
+ });
+ return res || null;
+ },
+-
+ // 展开详情列表
+ async expand(expanded, record) {
+ if (!expanded) return;
+@@ -739,7 +738,7 @@ export default {
+ current: pagination.current,
+ pageSize: pagination.pageSize
+ },
+- filters: filters,
++ filters,
+ sorter: {
+ field: sorter.field,
+ order: sorter.order
+@@ -770,7 +769,7 @@ export default {
+ return res || null;
+ },
+ // 获取热补丁回退列表
+- async getCveListWithHotpathRemove() {
++ async getCveListWithHotpathRemove(needScan = false) {
+ this.tableIsLoading = true;
+ const pagination = this.pagination || {};
+ const filters = this.filters || {};
+@@ -800,12 +799,13 @@ export default {
+ this.tableIsLoading = false;
+ await this.updateCveProgress(
+ this.taskId,
+- res.data.result.map((cve) => cve.cve_id)
++ res.data.result.map((cve) => cve.cve_id),
++ needScan
+ );
+ }
+ },
+- // for cve task
+- async getCveList() {
++ // 获取cve列表(修复,回滚)
++ async getCveList(needScan = false) {
+ this.tableIsLoading = true;
+ const res = this.taskType === 'cve fix' ? await this.getCveListWithFix() : await this.getCveListWithRollback();
+ if (res) {
+@@ -814,34 +814,67 @@ export default {
+ rpms: []
+ }));
+ this.reportvisible = this.getReportVisible(res.data.result);
+- this.expandedRowKeys = [];
++ // this.expandedRowKeys = [];
+ this.pagination = {
+ ...this.pagination,
+ total: res.data.total_count || (res.data.total_count === 0 ? 0 : this.pagination.total)
+ };
+- await this.updateHostProgress();
++ !this.reportvisible && (await this.updateHostProgress(needScan));
+ this.tableIsLoading = false;
+ }
+ },
+ // 修复,回滚任务running时刷新列表状态
+- async updateHostProgress() {
++ async updateHostProgress(needScan = false) {
+ clearTimeout(this.CveScanStatueTimeout);
+ const res = this.taskType === 'cve fix' ? await this.getCveListWithFix() : await this.getCveListWithRollback();
+ const progressRes = res.data.result;
+- this.tableData = progressRes.map((item) => ({
+- ...item,
+- rpms: []
+- }));
++ progressRes.forEach((item) => {
++ const i = this.tableData.findIndex((t) => t.host_id === item.host_id);
++ if (i > -1 && this.tableData[i].status !== item.status) {
++ this.tableData[i].status = item.status;
++ if (this.expandedRowKeys.includes(this.tableData[i].host_id)) this.expand(true, this.tableData[i]);
++ }
++ });
++
+ const list = progressRes.filter((item) => item.status === 'running');
+ this.reportvisible = list.length === 0;
+ if (list.length > 0) {
+ this.CveScanStatueTimeout = setTimeout(() => {
+- this.updateHostProgress();
++ this.updateHostProgress(needScan);
+ }, configs.taskProgressUpdateInterval);
++ } else {
++ needScan && (await this.sacnHostAfterExcute());
+ }
+ },
+- // 更新热补丁回退的执行进度
+- async updateCveProgress(taskId, cveList) {
++
++ // 在任务执行完成之后进行主机扫描
++ async sacnHostAfterExcute() {
++ const hostList = await this.getAllHostId();
++ const res = await getHostScanStatus({hostList});
++ if (!res) return;
++ const hostStatusList = res.data.result;
++ const needScanList = Object.keys(hostStatusList).map((h) => {
++ if (hostStatusList[h] !== 3 && hostList.includes(Number(h))) return Number(h);
++ });
++ this.scanLeakAfterExecuteTask(needScanList);
++ },
++ // 返回扫描状态的主机
++ getScanningHost(scanMap, hostList) {
++ const arr = [];
++ hostList.forEach((host) => {
++ if (scanMap[host.host_id] === 3) {
++ arr.push(host);
++ }
++ });
++ return arr;
++ },
++ /**
++ * 更新热补丁回退的执行进度
++ * @param {*} taskId 任务id
++ * @param {*} cveList cve 列表
++ * @param {*} needScan 是否需要扫描主机
++ */
++ async updateCveProgress(taskId, cveList, needScan = false) {
+ clearTimeout(this.CveScanStatueTimeout);
+ const processRes = await getCveProgressUnderCveTask({
+ taskId,
+@@ -852,8 +885,10 @@ export default {
+ this.runningCveIds = this.getRunningCve(processRes.data.result);
+ if (this.runningCveIds.length > 0) {
+ this.CveScanStatueTimeout = setTimeout(() => {
+- this.updateCveProgress(taskId, cveList);
++ this.updateCveProgress(taskId, cveList, needScan);
+ }, configs.taskProgressUpdateInterval);
++ } else {
++ needScan && (await this.sacnHostAfterExcute());
+ }
+ },
+ // 将查询到的cve进度更新到表格数据中,用于数据展示
+@@ -954,26 +989,23 @@ export default {
+ title: `确定执行任务${this.detail.task_name}?`,
+ icon: () => ,
+ okText: '执行',
+- onOk: () => {
+- return executeTask(this.taskId)
+- .then((res) => {
+- this.$message.success(res.message);
+- this.scanLeakAfterExecuteTask();
+- // 执行任务成功后刷新
+- setTimeout(() => {
+- this.getInitalData();
+- this.expandedRowKeys = [];
+- }, 3000);
+- })
+- .catch((err) => {
+- this.$message.error(err.response.message);
+- });
++ onOk: async () => {
++ const excuteRes = await executeTask(this.taskId);
++ if (excuteRes) {
++ // 获取详情任务所有处理的hostid列表
++ this.$message.success(excuteRes.message);
++ // 执行任务成功后刷新
++ setTimeout(() => {
++ this.getInitalData(true);
++ this.expandedRowKeys = [];
++ }, 3000);
++ }
+ }
+ });
+ },
+- async scanLeakAfterExecuteTask() {
++ async scanLeakAfterExecuteTask(hostList) {
+ await scanHost({
+- hostList: this.hostList,
++ hostList,
+ filter: null
+ });
+ },
+@@ -981,7 +1013,7 @@ export default {
+ async getAllHostId() {
+ const res = await getAllHostInDetail(this.taskId);
+ if (res) {
+- this.hostList = res.data;
++ return res.data;
+ }
+ },
+ showHostListUnderCve(type, record) {
+@@ -992,16 +1024,17 @@ export default {
+ closeHostListUnderCve() {
+ this.hostListUnderCveVisible = false;
+ },
+- getInitalData() {
++ /**
++ * isFresh 是第一次初始化还是后续的刷新数据
++ */
++ getInitalData(isFresh = false) {
+ this.getInfo();
+- // 获取详情任务所有处理的hostid列表
+- this.getAllHostId();
+ if (this.taskType === 'repo set') {
+ this.getHostList();
+ } else if (this.taskType === 'hotpatch remove') {
+- this.getCveListWithHotpathRemove();
++ this.getCveListWithHotpathRemove(isFresh);
+ } else {
+- this.getCveList();
++ this.getCveList(isFresh);
+ }
+ },
+
+@@ -1023,9 +1056,9 @@ export default {
+ }
+ if (this.taskType === 'cve fix' || this.taskType === 'cve rollback') {
+ if (text !== '') {
+- this.filters.host_name = text;
++ this.filters.searchKey = text;
+ } else {
+- this.filters.host_name = undefined;
++ this.filters.searchKey = undefined;
+ }
+ this.getCveList();
+ } else {
+@@ -1065,7 +1098,7 @@ export default {
+ localStorage.setItem('taskId', this.taskId);
+ },
+ mounted() {
+- this.getInitalData();
++ this.getInitalData(false);
+ },
+ beforeDestroy() {
+ // 离开页面前,若当前存在轮询,清除轮询
+diff --git a/src/views/leaks/LeakTaskList.vue b/src/views/leaks/LeakTaskList.vue
+index be0ce82..08cb5e4 100644
+--- a/src/views/leaks/LeakTaskList.vue
++++ b/src/views/leaks/LeakTaskList.vue
+@@ -193,6 +193,10 @@ export default {
+ {
+ text: 'cve rollback',
+ value: 'cve rollback'
++ },
++ {
++ text: 'hotpatch remove',
++ value: 'hotpatch remove'
+ }
+ ]
+ },
+diff --git a/src/views/leaks/TaskResultReport.vue b/src/views/leaks/TaskResultReport.vue
+index ca8d031..e702b06 100644
+--- a/src/views/leaks/TaskResultReport.vue
++++ b/src/views/leaks/TaskResultReport.vue
+@@ -1,4 +1,3 @@
+-
+
+
+
+@@ -30,7 +29,7 @@
+ {{ cveStatusTextMap[resultItem.status] }}
+
+
+- {{ rollStatusTextMap[resultItem.status] }}
++ {{ rollStatusTextMap[resultItem.task_result.result] }}
+
+
+ {{ repoStatusTextMap[resultItem.task_result.status] }}
+@@ -39,8 +38,13 @@
+ {{ resultItem.task_result.repo }}
+
+
+- 检查项:
+-
++ 检查项:
++ 无
++
+
+
+
+
+
+-
+-
RPM回滚情况:
++
++
RPM回滚详情:
+
+
+-
+-
结果:
+- {{ rollStatusTextMap[rpm.result] }}
+-
+-
+-
++
++ 已安装rpm:
++ {{ rpm.installed_rpm }}
++
++
++ 目标rpm:
++ {{ rpm.target_rpm }}
++
++
+
+
+-
+-
Log:
+-
{{ resultItem.log }}
+-
++
Log:
++
+
+
+
+-
CVE修复情况:
++
热补丁移除情况:
+
+
+
+-
结果: {{ statusResultTextMap[cve.result] }}
++
结果: {{ removeStatusResult[cve.result] }}
+
+
+
Log:
+@@ -132,7 +134,16 @@
+
Log:
+
{{ resultItem.task_result.log }}
+
+-
++
+
+
+
+@@ -188,6 +199,13 @@ const statusResultTextMap = {
+ unknown: '未知'
+ };
+
++const removeStatusResult = {
++ succeed: '移除成功',
++ fail: '待移除',
++ running: '运行中',
++ unknown: '未知'
++};
++
+ const statusResultValueMap = {
+ succeed: 'success',
+ unfixed: 'error',
+@@ -210,6 +228,13 @@ export default {
+ props: {
+ routes,
+ itemRender: ({route, params, routes, paths, h}) => {
++ if (route.path === '/leaks/task/:taskType/:taskId') {
++ const path = {
++ path: `/leaks/task/${this.$route.query.taskType}/${this.$route.query.taskId}`,
++ query: {taskId: this.$route.query.taskId}
++ };
++ return
{route.breadcrumbName};
++ }
+ return
{route.breadcrumbName};
+ }
+ }
+@@ -218,6 +243,7 @@ export default {
+ },
+ data() {
+ return {
++ removeStatusResult,
+ taskId: this.$route.query.taskId,
+ taskType: this.$route.query.taskType,
+ latestExecuteTime: this.$route.query.latestExecuteTime,
+@@ -293,6 +319,10 @@ export default {
+ font-weight: 500;
+ color: rgba(0, 0, 0, 0.85);
+ }
++.title {
++ font-weight: bold;
++ margin-right: 5px;
++}
+ /deep/ .ant-descriptions-item {
+ .ant-descriptions-item-label {
+ font-weight: 500;
+diff --git a/src/views/leaks/components/CreateRepairTaskDrawer.vue b/src/views/leaks/components/CreateRepairTaskDrawer.vue
+index 5977bfb..b302439 100644
+--- a/src/views/leaks/components/CreateRepairTaskDrawer.vue
++++ b/src/views/leaks/components/CreateRepairTaskDrawer.vue
+@@ -4,7 +4,7 @@
+ {{ taskTypsbutton[taskType] }}
+
+
{
+- this.$message.success(res.message);
+- if (excuteASAP) {
+- const task = res.data.filter((item) => item.fix_way === 'hotpatch');
+- this.handleExcuteASAP(task[0].task_id, res.data);
+- } else {
+- this.visible = false;
+- this.handleGenerateSuccess(res.data, 'CVE修复', 'normal');
+- }
+- })
+- .catch((err) => {
+- this.$message.error(err.response.message);
+- })
+- .finally(() => {
+- if (!excuteASAP) {
+- this.submitLoading = false;
+- }
+- });
++ generateTask(params).then((res) => {
++ this.$message.success(res.message);
++ if (excuteASAP) {
++ // 如果同时存在冷热补丁两种任务,则选择热补丁任务立即执行,如果只有单个任务,则执行该任务
++ const task =
++ res.data.length > 1 ? res.data.filter((item) => item.fix_way === 'hotpatch') : res.data;
++ this.handleExcuteASAP(task[0].task_id, res.data);
++ } else {
++ this.visible = false;
++ this.handleGenerateSuccess(res.data, 'CVE修复', 'normal');
++ }
++ });
++ this.submitLoading = false;
+ break;
+ }
+ case 'repo set':
+--
+Gitee
diff --git a/002-fix-hotpatch-remove-filter.patch b/002-fix-hotpatch-remove-filter.patch
new file mode 100644
index 0000000..8f600eb
--- /dev/null
+++ b/002-fix-hotpatch-remove-filter.patch
@@ -0,0 +1,24 @@
+From a747433cfaf40104eb56d9d3dea6d86ed5d5b82d Mon Sep 17 00:00:00 2001
+From: Hu gang <18768366022@163.com>
+Date: Mon, 18 Dec 2023 10:27:00 +0800
+Subject: [PATCH] fix: fix hotpathch remove filter failed
+
+---
+ src/views/leaks/LeakTaskDetail.vue | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/src/views/leaks/LeakTaskDetail.vue b/src/views/leaks/LeakTaskDetail.vue
+index f7f7438..00438d7 100644
+--- a/src/views/leaks/LeakTaskDetail.vue
++++ b/src/views/leaks/LeakTaskDetail.vue
+@@ -661,6 +661,8 @@ export default {
+ // 出发排序、筛选、分页时,重新请求主机列表
+ if (this.taskType === 'cve fix' || this.taskType === 'cve rollback') {
+ this.getCveList();
++ } else if (this.taskType === 'hotpatch remove') {
++ this.getCveListWithHotpathRemove();
+ } else {
+ this.getHostList();
+ }
+--
+Gitee
diff --git a/003-change-search-placeholder.patch b/003-change-search-placeholder.patch
new file mode 100644
index 0000000..86caad3
--- /dev/null
+++ b/003-change-search-placeholder.patch
@@ -0,0 +1,24 @@
+From 2cc872cddbc8331941507167b23a977aa0b543ad Mon Sep 17 00:00:00 2001
+From: Hu gang <18768366022@163.com>
+Date: Mon, 18 Dec 2023 11:05:17 +0800
+Subject: [PATCH] chore: change search input palceholder
+
+---
+ src/views/leaks/LeakTaskDetail.vue | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/src/views/leaks/LeakTaskDetail.vue b/src/views/leaks/LeakTaskDetail.vue
+index 00438d7..766a1cf 100644
+--- a/src/views/leaks/LeakTaskDetail.vue
++++ b/src/views/leaks/LeakTaskDetail.vue
+@@ -103,7 +103,7 @@
+
+
+
+--
+Gitee
diff --git a/004-modify-search-key-for-hostlist.patch b/004-modify-search-key-for-hostlist.patch
new file mode 100644
index 0000000..e5585ec
--- /dev/null
+++ b/004-modify-search-key-for-hostlist.patch
@@ -0,0 +1,38 @@
+From 3289156212ecda06c35ace47af0a6033ff41ea1d Mon Sep 17 00:00:00 2001
+From: Hu gang <18768366022@163.com>
+Date: Mon, 18 Dec 2023 15:17:42 +0800
+Subject: [PATCH] chore: change search key
+
+---
+ src/views/assests/HostManagement.vue | 2 +-
+ src/views/leaks/LeakTaskDetail.vue | 2 +-
+ 2 files changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/src/views/assests/HostManagement.vue b/src/views/assests/HostManagement.vue
+index 77e0ed8..e3c1635 100644
+--- a/src/views/assests/HostManagement.vue
++++ b/src/views/assests/HostManagement.vue
+@@ -18,7 +18,7 @@
+
+
+
+-
++
+
+
+
+diff --git a/src/views/leaks/LeakTaskDetail.vue b/src/views/leaks/LeakTaskDetail.vue
+index 766a1cf..81f0a88 100644
+--- a/src/views/leaks/LeakTaskDetail.vue
++++ b/src/views/leaks/LeakTaskDetail.vue
+@@ -103,7 +103,7 @@
+
+
+
+--
+Gitee
diff --git a/aops-hermes-v1.4.0.tar.gz b/aops-hermes-v1.4.0.tar.gz
index 5965041..7b38de4 100644
Binary files a/aops-hermes-v1.4.0.tar.gz and b/aops-hermes-v1.4.0.tar.gz differ
diff --git a/aops-hermes.spec b/aops-hermes.spec
index 6e5f344..07b13dc 100644
--- a/aops-hermes.spec
+++ b/aops-hermes.spec
@@ -2,12 +2,16 @@
Name: aops-hermes
Version: v1.4.0
-Release: 1
+Release: 2
Summary: Web for an intelligent diagnose frame
License: MulanPSL2
URL: https://gitee.com/openeuler/%{name}
Source0: %{name}-%{version}.tar.gz
Source1: node_modules.tar.gz
+Patch001: 001-bugfix-and-adapt-rollback-tasks.patch
+Patch002: 002-fix-hotpatch-remove-filter.patch
+Patch003: 003-change-search-placeholder.patch
+Patch004: 004-modify-search-key-for-hostlist.patch
BuildRequires: nodejs node-gyp nodejs-yarn
@@ -19,7 +23,7 @@ Web for an intelligent diagnose frame
%prep
-%autosetup -n %{name}-%{version}
+%autosetup -n %{name}-%{version} -p1
%setup -T -D -a 1
@@ -43,8 +47,16 @@ cp -r deploy/aops-hermes.service %{buildroot}/usr/lib/systemd/system/
%changelog
+* Mon Dec 18 2023 Hu gang<18768366022@163.com> - v1.4.0-2
+- Added keyword search for host list
+- Fixed the problem of abnormal list rendering in task details task running state
+- Optimize some page copywriting
+- Adaptation rollback task related (creation, execution, detailed viewing, task report viewing, etc.)
+- Solve the problem of hot and cold patch execution tasks failing when creating a repair task.
+- Fix hotpatch remove list filter failed
+
* Tue Dec 12 2023 Hu gang<18768366022@163.com> - v1.4.0-1
-- adaptToNewRepairTasksIncludingDetailsCreationTaskReportsAndTaskExecution
+- adapt to NewRepair Tasks Including DetailsCreation TaskReports And TaskExecution
- Modify the original rollback task to hot patch rollback
- Added related rollback tasks