mirror of
https://github.com/whyour/qinglong.git
synced 2025-05-22 22:36:06 +08:00
依赖管理增加直接强制删除
This commit is contained in:
parent
5be421b4ea
commit
1b893f35ba
|
@ -94,7 +94,7 @@ export default (app: Router) => {
|
||||||
const logger: Logger = Container.get('logger');
|
const logger: Logger = Container.get('logger');
|
||||||
try {
|
try {
|
||||||
const dependenceService = Container.get(DependenceService);
|
const dependenceService = Container.get(DependenceService);
|
||||||
const data = await dependenceService.removeDb(req.body);
|
const data = await dependenceService.remove(req.body, true);
|
||||||
return res.send({ code: 200, data });
|
return res.send({ code: 200, data });
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
logger.error('🔥 error: %o', e);
|
logger.error('🔥 error: %o', e);
|
||||||
|
|
|
@ -37,13 +37,13 @@ export enum DependenceTypes {
|
||||||
}
|
}
|
||||||
|
|
||||||
export enum InstallDependenceCommandTypes {
|
export enum InstallDependenceCommandTypes {
|
||||||
'npm i -g --force',
|
'npm i -g -f --loglevel warn',
|
||||||
'pip3 install',
|
'pip3 install',
|
||||||
'apk add --no-cache -f',
|
'apk add --no-cache -f',
|
||||||
}
|
}
|
||||||
|
|
||||||
export enum unInstallDependenceCommandTypes {
|
export enum unInstallDependenceCommandTypes {
|
||||||
'npm uninstall -g --force',
|
'npm uninstall -g -f --loglevel warn',
|
||||||
'pip3 uninstall -y',
|
'pip3 uninstall -y',
|
||||||
'apk del -f',
|
'apk del -f',
|
||||||
}
|
}
|
||||||
|
|
|
@ -13,5 +13,6 @@ export class SockMessage {
|
||||||
export type SockMessageType =
|
export type SockMessageType =
|
||||||
| 'ping'
|
| 'ping'
|
||||||
| 'installDependence'
|
| 'installDependence'
|
||||||
|
| 'uninstallDependence'
|
||||||
| 'updateSystemVersion'
|
| 'updateSystemVersion'
|
||||||
| 'manuallyRunScript';
|
| 'manuallyRunScript';
|
||||||
|
|
|
@ -56,13 +56,13 @@ export default class DependenceService {
|
||||||
return await this.getDb({ id: payload.id });
|
return await this.getDb({ id: payload.id });
|
||||||
}
|
}
|
||||||
|
|
||||||
public async remove(ids: number[]) {
|
public async remove(ids: number[], force = false): Promise<Dependence[]> {
|
||||||
await DependenceModel.update(
|
await DependenceModel.update(
|
||||||
{ status: DependenceStatus.removing, log: [] },
|
{ status: DependenceStatus.removing, log: [] },
|
||||||
{ where: { id: ids } },
|
{ where: { id: ids } },
|
||||||
);
|
);
|
||||||
const docs = await DependenceModel.findAll({ where: { id: ids } });
|
const docs = await DependenceModel.findAll({ where: { id: ids } });
|
||||||
this.installOrUninstallDependencies(docs, false);
|
this.installOrUninstallDependencies(docs, false, force);
|
||||||
return docs;
|
return docs;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -128,12 +128,16 @@ export default class DependenceService {
|
||||||
public installOrUninstallDependencies(
|
public installOrUninstallDependencies(
|
||||||
dependencies: Dependence[],
|
dependencies: Dependence[],
|
||||||
isInstall: boolean = true,
|
isInstall: boolean = true,
|
||||||
|
force: boolean = false,
|
||||||
) {
|
) {
|
||||||
return new Promise(async (resolve) => {
|
return new Promise(async (resolve) => {
|
||||||
if (dependencies.length === 0) {
|
if (dependencies.length === 0) {
|
||||||
resolve(null);
|
resolve(null);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
const socketMessageType = !force
|
||||||
|
? 'installDependence'
|
||||||
|
: 'uninstallDependence';
|
||||||
const depNames = dependencies.map((x) => x.name).join(' ');
|
const depNames = dependencies.map((x) => x.name).join(' ');
|
||||||
const depRunCommand = (
|
const depRunCommand = (
|
||||||
isInstall
|
isInstall
|
||||||
|
@ -145,21 +149,21 @@ export default class DependenceService {
|
||||||
const cp = spawn(`${depRunCommand} ${depNames}`, { shell: '/bin/bash' });
|
const cp = spawn(`${depRunCommand} ${depNames}`, { shell: '/bin/bash' });
|
||||||
const startTime = Date.now();
|
const startTime = Date.now();
|
||||||
this.sockService.sendMessage({
|
this.sockService.sendMessage({
|
||||||
type: 'installDependence',
|
type: socketMessageType,
|
||||||
message: `开始${actionText}依赖 ${depNames},开始时间 ${new Date(
|
message: `开始${actionText}依赖 ${depNames},开始时间 ${new Date(
|
||||||
startTime,
|
startTime,
|
||||||
).toLocaleString()}`,
|
).toLocaleString()}\n\n`,
|
||||||
references: depIds,
|
references: depIds,
|
||||||
});
|
});
|
||||||
await this.updateLog(
|
await this.updateLog(
|
||||||
depIds,
|
depIds,
|
||||||
`开始${actionText}依赖 ${depNames},开始时间 ${new Date(
|
`开始${actionText}依赖 ${depNames},开始时间 ${new Date(
|
||||||
startTime,
|
startTime,
|
||||||
).toLocaleString()}\n`,
|
).toLocaleString()}\n\n`,
|
||||||
);
|
);
|
||||||
cp.stdout.on('data', async (data) => {
|
cp.stdout.on('data', async (data) => {
|
||||||
this.sockService.sendMessage({
|
this.sockService.sendMessage({
|
||||||
type: 'installDependence',
|
type: socketMessageType,
|
||||||
message: data.toString(),
|
message: data.toString(),
|
||||||
references: depIds,
|
references: depIds,
|
||||||
});
|
});
|
||||||
|
@ -168,7 +172,7 @@ export default class DependenceService {
|
||||||
|
|
||||||
cp.stderr.on('data', async (data) => {
|
cp.stderr.on('data', async (data) => {
|
||||||
this.sockService.sendMessage({
|
this.sockService.sendMessage({
|
||||||
type: 'installDependence',
|
type: socketMessageType,
|
||||||
message: data.toString(),
|
message: data.toString(),
|
||||||
references: depIds,
|
references: depIds,
|
||||||
});
|
});
|
||||||
|
@ -177,7 +181,7 @@ export default class DependenceService {
|
||||||
|
|
||||||
cp.on('error', async (err) => {
|
cp.on('error', async (err) => {
|
||||||
this.sockService.sendMessage({
|
this.sockService.sendMessage({
|
||||||
type: 'installDependence',
|
type: socketMessageType,
|
||||||
message: JSON.stringify(err),
|
message: JSON.stringify(err),
|
||||||
references: depIds,
|
references: depIds,
|
||||||
});
|
});
|
||||||
|
@ -191,15 +195,15 @@ export default class DependenceService {
|
||||||
const resultText = isSucceed ? '成功' : '失败';
|
const resultText = isSucceed ? '成功' : '失败';
|
||||||
|
|
||||||
this.sockService.sendMessage({
|
this.sockService.sendMessage({
|
||||||
type: 'installDependence',
|
type: socketMessageType,
|
||||||
message: `依赖${actionText}${resultText},结束时间 ${new Date(
|
message: `\n依赖${actionText}${resultText},结束时间 ${new Date(
|
||||||
endTime,
|
endTime,
|
||||||
).toLocaleString()},耗时 ${(endTime - startTime) / 1000} 秒`,
|
).toLocaleString()},耗时 ${(endTime - startTime) / 1000} 秒`,
|
||||||
references: depIds,
|
references: depIds,
|
||||||
});
|
});
|
||||||
await this.updateLog(
|
await this.updateLog(
|
||||||
depIds,
|
depIds,
|
||||||
`依赖${actionText}${resultText},结束时间 ${new Date(
|
`\n依赖${actionText}${resultText},结束时间 ${new Date(
|
||||||
endTime,
|
endTime,
|
||||||
).toLocaleString()},耗时 ${(endTime - startTime) / 1000} 秒`,
|
).toLocaleString()},耗时 ${(endTime - startTime) / 1000} 秒`,
|
||||||
);
|
);
|
||||||
|
@ -216,11 +220,9 @@ export default class DependenceService {
|
||||||
}
|
}
|
||||||
await DependenceModel.update({ status }, { where: { id: depIds } });
|
await DependenceModel.update({ status }, { where: { id: depIds } });
|
||||||
|
|
||||||
// 如果删除依赖成功,3秒后删除数据库记录
|
// 如果删除依赖成功或者强制删除
|
||||||
if (isSucceed && !isInstall) {
|
if ((isSucceed || force) && !isInstall) {
|
||||||
setTimeout(() => {
|
this.removeDb(depIds);
|
||||||
this.removeDb(depIds);
|
|
||||||
}, 5000);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
resolve(null);
|
resolve(null);
|
||||||
|
|
|
@ -16,7 +16,7 @@ import {
|
||||||
DeleteOutlined,
|
DeleteOutlined,
|
||||||
SyncOutlined,
|
SyncOutlined,
|
||||||
CheckCircleOutlined,
|
CheckCircleOutlined,
|
||||||
StopOutlined,
|
DeleteFilled,
|
||||||
BugOutlined,
|
BugOutlined,
|
||||||
FileTextOutlined,
|
FileTextOutlined,
|
||||||
} from '@ant-design/icons';
|
} from '@ant-design/icons';
|
||||||
|
@ -120,6 +120,15 @@ const Dependence = ({ headerStyle, isPhone, socketMessage }: any) => {
|
||||||
const isPc = !isPhone;
|
const isPc = !isPhone;
|
||||||
return (
|
return (
|
||||||
<Space size="middle">
|
<Space size="middle">
|
||||||
|
<Tooltip title={isPc ? '日志' : ''}>
|
||||||
|
<a
|
||||||
|
onClick={() => {
|
||||||
|
setLogDependence({ ...record, timestamp: Date.now() });
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<FileTextOutlined />
|
||||||
|
</a>
|
||||||
|
</Tooltip>
|
||||||
{record.status !== Status.安装中 &&
|
{record.status !== Status.安装中 &&
|
||||||
record.status !== Status.删除中 && (
|
record.status !== Status.删除中 && (
|
||||||
<>
|
<>
|
||||||
|
@ -133,17 +142,13 @@ const Dependence = ({ headerStyle, isPhone, socketMessage }: any) => {
|
||||||
<DeleteOutlined />
|
<DeleteOutlined />
|
||||||
</a>
|
</a>
|
||||||
</Tooltip>
|
</Tooltip>
|
||||||
|
<Tooltip title={isPc ? '强制删除' : ''}>
|
||||||
|
<a onClick={() => deleteDependence(record, index, true)}>
|
||||||
|
<DeleteFilled />
|
||||||
|
</a>
|
||||||
|
</Tooltip>
|
||||||
</>
|
</>
|
||||||
)}
|
)}
|
||||||
<Tooltip title={isPc ? '日志' : ''}>
|
|
||||||
<a
|
|
||||||
onClick={() => {
|
|
||||||
setLogDependence({ ...record, timestamp: Date.now() });
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
<FileTextOutlined />
|
|
||||||
</a>
|
|
||||||
</Tooltip>
|
|
||||||
</Space>
|
</Space>
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
|
@ -182,7 +187,11 @@ const Dependence = ({ headerStyle, isPhone, socketMessage }: any) => {
|
||||||
setIsModalVisible(true);
|
setIsModalVisible(true);
|
||||||
};
|
};
|
||||||
|
|
||||||
const deleteDependence = (record: any, index: number) => {
|
const deleteDependence = (
|
||||||
|
record: any,
|
||||||
|
index: number,
|
||||||
|
force: boolean = false,
|
||||||
|
) => {
|
||||||
Modal.confirm({
|
Modal.confirm({
|
||||||
title: '确认删除',
|
title: '确认删除',
|
||||||
content: (
|
content: (
|
||||||
|
@ -196,10 +205,19 @@ const Dependence = ({ headerStyle, isPhone, socketMessage }: any) => {
|
||||||
),
|
),
|
||||||
onOk() {
|
onOk() {
|
||||||
request
|
request
|
||||||
.delete(`${config.apiPrefix}dependencies`, { data: [record.id] })
|
.delete(`${config.apiPrefix}dependencies${force ? '/force' : ''}`, {
|
||||||
|
data: [record.id],
|
||||||
|
})
|
||||||
.then((data: any) => {
|
.then((data: any) => {
|
||||||
if (data.code === 200) {
|
if (data.code === 200) {
|
||||||
handleDependence(data.data[0]);
|
if (force) {
|
||||||
|
const i = value.findIndex((x) => x.id === data.data[0].id);
|
||||||
|
if (i !== -1) {
|
||||||
|
const result = [...value];
|
||||||
|
result.splice(i, 1);
|
||||||
|
setValue(result);
|
||||||
|
}
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
message.error(data);
|
message.error(data);
|
||||||
}
|
}
|
||||||
|
@ -275,13 +293,16 @@ const Dependence = ({ headerStyle, isPhone, socketMessage }: any) => {
|
||||||
onChange: onSelectChange,
|
onChange: onSelectChange,
|
||||||
};
|
};
|
||||||
|
|
||||||
const delDependencies = () => {
|
const delDependencies = (force: boolean) => {
|
||||||
|
const forceUrl = force ? '/force' : '';
|
||||||
Modal.confirm({
|
Modal.confirm({
|
||||||
title: '确认删除',
|
title: '确认删除',
|
||||||
content: <>确认删除选中的依赖吗</>,
|
content: <>确认删除选中的依赖吗</>,
|
||||||
onOk() {
|
onOk() {
|
||||||
request
|
request
|
||||||
.delete(`${config.apiPrefix}dependencies`, { data: selectedRowIds })
|
.delete(`${config.apiPrefix}dependencies${forceUrl}`, {
|
||||||
|
data: selectedRowIds,
|
||||||
|
})
|
||||||
.then((data: any) => {
|
.then((data: any) => {
|
||||||
if (data.code === 200) {
|
if (data.code === 200) {
|
||||||
setSelectedRowIds([]);
|
setSelectedRowIds([]);
|
||||||
|
@ -377,10 +398,17 @@ const Dependence = ({ headerStyle, isPhone, socketMessage }: any) => {
|
||||||
<Button
|
<Button
|
||||||
type="primary"
|
type="primary"
|
||||||
style={{ marginBottom: 5, marginLeft: 8 }}
|
style={{ marginBottom: 5, marginLeft: 8 }}
|
||||||
onClick={delDependencies}
|
onClick={() => delDependencies(false)}
|
||||||
>
|
>
|
||||||
批量删除
|
批量删除
|
||||||
</Button>
|
</Button>
|
||||||
|
<Button
|
||||||
|
type="primary"
|
||||||
|
style={{ marginBottom: 5, marginLeft: 8 }}
|
||||||
|
onClick={() => delDependencies(true)}
|
||||||
|
>
|
||||||
|
批量强制删除
|
||||||
|
</Button>
|
||||||
<span style={{ marginLeft: 8 }}>
|
<span style={{ marginLeft: 8 }}>
|
||||||
已选择
|
已选择
|
||||||
<a>{selectedRowIds?.length}</a>项
|
<a>{selectedRowIds?.length}</a>项
|
||||||
|
|
Loading…
Reference in New Issue
Block a user