依赖管理增加直接强制删除

This commit is contained in:
whyour 2022-04-23 15:02:54 +08:00
parent 5be421b4ea
commit 1b893f35ba
5 changed files with 66 additions and 35 deletions

View File

@ -94,7 +94,7 @@ export default (app: Router) => {
const logger: Logger = Container.get('logger');
try {
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 });
} catch (e) {
logger.error('🔥 error: %o', e);

View File

@ -37,13 +37,13 @@ export enum DependenceTypes {
}
export enum InstallDependenceCommandTypes {
'npm i -g --force',
'npm i -g -f --loglevel warn',
'pip3 install',
'apk add --no-cache -f',
}
export enum unInstallDependenceCommandTypes {
'npm uninstall -g --force',
'npm uninstall -g -f --loglevel warn',
'pip3 uninstall -y',
'apk del -f',
}

View File

@ -13,5 +13,6 @@ export class SockMessage {
export type SockMessageType =
| 'ping'
| 'installDependence'
| 'uninstallDependence'
| 'updateSystemVersion'
| 'manuallyRunScript';

View File

@ -56,13 +56,13 @@ export default class DependenceService {
return await this.getDb({ id: payload.id });
}
public async remove(ids: number[]) {
public async remove(ids: number[], force = false): Promise<Dependence[]> {
await DependenceModel.update(
{ status: DependenceStatus.removing, log: [] },
{ where: { id: ids } },
);
const docs = await DependenceModel.findAll({ where: { id: ids } });
this.installOrUninstallDependencies(docs, false);
this.installOrUninstallDependencies(docs, false, force);
return docs;
}
@ -128,12 +128,16 @@ export default class DependenceService {
public installOrUninstallDependencies(
dependencies: Dependence[],
isInstall: boolean = true,
force: boolean = false,
) {
return new Promise(async (resolve) => {
if (dependencies.length === 0) {
resolve(null);
return;
}
const socketMessageType = !force
? 'installDependence'
: 'uninstallDependence';
const depNames = dependencies.map((x) => x.name).join(' ');
const depRunCommand = (
isInstall
@ -145,21 +149,21 @@ export default class DependenceService {
const cp = spawn(`${depRunCommand} ${depNames}`, { shell: '/bin/bash' });
const startTime = Date.now();
this.sockService.sendMessage({
type: 'installDependence',
type: socketMessageType,
message: `开始${actionText}依赖 ${depNames},开始时间 ${new Date(
startTime,
).toLocaleString()}`,
).toLocaleString()}\n\n`,
references: depIds,
});
await this.updateLog(
depIds,
`开始${actionText}依赖 ${depNames},开始时间 ${new Date(
startTime,
).toLocaleString()}\n`,
).toLocaleString()}\n\n`,
);
cp.stdout.on('data', async (data) => {
this.sockService.sendMessage({
type: 'installDependence',
type: socketMessageType,
message: data.toString(),
references: depIds,
});
@ -168,7 +172,7 @@ export default class DependenceService {
cp.stderr.on('data', async (data) => {
this.sockService.sendMessage({
type: 'installDependence',
type: socketMessageType,
message: data.toString(),
references: depIds,
});
@ -177,7 +181,7 @@ export default class DependenceService {
cp.on('error', async (err) => {
this.sockService.sendMessage({
type: 'installDependence',
type: socketMessageType,
message: JSON.stringify(err),
references: depIds,
});
@ -191,15 +195,15 @@ export default class DependenceService {
const resultText = isSucceed ? '成功' : '失败';
this.sockService.sendMessage({
type: 'installDependence',
message: `依赖${actionText}${resultText},结束时间 ${new Date(
type: socketMessageType,
message: `\n依赖${actionText}${resultText},结束时间 ${new Date(
endTime,
).toLocaleString()} ${(endTime - startTime) / 1000} `,
references: depIds,
});
await this.updateLog(
depIds,
`依赖${actionText}${resultText},结束时间 ${new Date(
`\n依赖${actionText}${resultText},结束时间 ${new Date(
endTime,
).toLocaleString()} ${(endTime - startTime) / 1000} `,
);
@ -216,11 +220,9 @@ export default class DependenceService {
}
await DependenceModel.update({ status }, { where: { id: depIds } });
// 如果删除依赖成功3秒后删除数据库记录
if (isSucceed && !isInstall) {
setTimeout(() => {
// 如果删除依赖成功或者强制删除
if ((isSucceed || force) && !isInstall) {
this.removeDb(depIds);
}, 5000);
}
resolve(null);

View File

@ -16,7 +16,7 @@ import {
DeleteOutlined,
SyncOutlined,
CheckCircleOutlined,
StopOutlined,
DeleteFilled,
BugOutlined,
FileTextOutlined,
} from '@ant-design/icons';
@ -120,6 +120,15 @@ const Dependence = ({ headerStyle, isPhone, socketMessage }: any) => {
const isPc = !isPhone;
return (
<Space size="middle">
<Tooltip title={isPc ? '日志' : ''}>
<a
onClick={() => {
setLogDependence({ ...record, timestamp: Date.now() });
}}
>
<FileTextOutlined />
</a>
</Tooltip>
{record.status !== Status. &&
record.status !== Status. && (
<>
@ -133,17 +142,13 @@ const Dependence = ({ headerStyle, isPhone, socketMessage }: any) => {
<DeleteOutlined />
</a>
</Tooltip>
</>
)}
<Tooltip title={isPc ? '日志' : ''}>
<a
onClick={() => {
setLogDependence({ ...record, timestamp: Date.now() });
}}
>
<FileTextOutlined />
<Tooltip title={isPc ? '强制删除' : ''}>
<a onClick={() => deleteDependence(record, index, true)}>
<DeleteFilled />
</a>
</Tooltip>
</>
)}
</Space>
);
},
@ -182,7 +187,11 @@ const Dependence = ({ headerStyle, isPhone, socketMessage }: any) => {
setIsModalVisible(true);
};
const deleteDependence = (record: any, index: number) => {
const deleteDependence = (
record: any,
index: number,
force: boolean = false,
) => {
Modal.confirm({
title: '确认删除',
content: (
@ -196,10 +205,19 @@ const Dependence = ({ headerStyle, isPhone, socketMessage }: any) => {
),
onOk() {
request
.delete(`${config.apiPrefix}dependencies`, { data: [record.id] })
.delete(`${config.apiPrefix}dependencies${force ? '/force' : ''}`, {
data: [record.id],
})
.then((data: any) => {
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 {
message.error(data);
}
@ -275,13 +293,16 @@ const Dependence = ({ headerStyle, isPhone, socketMessage }: any) => {
onChange: onSelectChange,
};
const delDependencies = () => {
const delDependencies = (force: boolean) => {
const forceUrl = force ? '/force' : '';
Modal.confirm({
title: '确认删除',
content: <></>,
onOk() {
request
.delete(`${config.apiPrefix}dependencies`, { data: selectedRowIds })
.delete(`${config.apiPrefix}dependencies${forceUrl}`, {
data: selectedRowIds,
})
.then((data: any) => {
if (data.code === 200) {
setSelectedRowIds([]);
@ -377,10 +398,17 @@ const Dependence = ({ headerStyle, isPhone, socketMessage }: any) => {
<Button
type="primary"
style={{ marginBottom: 5, marginLeft: 8 }}
onClick={delDependencies}
onClick={() => delDependencies(false)}
>
</Button>
<Button
type="primary"
style={{ marginBottom: 5, marginLeft: 8 }}
onClick={() => delDependencies(true)}
>
</Button>
<span style={{ marginLeft: 8 }}>
<a>{selectedRowIds?.length}</a>