feat: 脚本/定时任务真实执行+输出捕获+执行历史 — 替换pending空壳为本地执行,采集stdout/stderr,更新统计;修复CronJobManager/Automation字段名不匹配(status→enabled,cron→cron_expr,command→content,language→type)

This commit is contained in:
attacker committed 2026-06-14 22:11:18 +08:00
1 parent 85bc2a8e05
commit a4fd5fc178
19 files changed
+2715 -114

No files matched your search

@@ -0,0 +1,173 @@
import { useState } from 'react';
import { toast } from 'sonner';
import { useUserStore } from '@/store';
import {
Dialog,
DialogContent,
DialogDescription,
DialogHeader,
DialogTitle,
} from '@/components/ui/dialog';
import { Tabs, TabsContent, TabsList, TabsTrigger } from '@/components/ui/tabs';
import { Button } from '@/components/ui/button';
import { Copy, Check, Terminal, Download, Settings, Play, Cpu } from 'lucide-react';
interface AgentWizardProps {
open: boolean;
onOpenChange: (open: boolean) => void;
}
/** 自动检测服务器地址:使用当前浏览器访问的主机名,端口固定 8080 */
function detectServerAddress(): string {
if (typeof window !== 'undefined' && window.location) {
const host = window.location.hostname;
return host ? `http://${host}:8080` : 'http://127.0.0.1:8080';
}
return 'http://127.0.0.1:8080';
}
export function AgentWizard({ open, onOpenChange }: AgentWizardProps) {
const token = useUserStore((s) => s.token) || '<YOUR_TOKEN>';
const serverUrl = detectServerAddress();
const [copied, setCopied] = useState(false);
const installCommand = `curl -fsSL ${serverUrl.replace(/^http:/, 'http:')}/agent/install.sh | bash -s -- --server ${serverUrl} --token ${token}`;
const handleCopy = async () => {
try {
await navigator.clipboard.writeText(installCommand);
setCopied(true);
toast.success('安装命令已复制');
setTimeout(() => setCopied(false), 2000);
} catch {
toast.error('复制失败,请手动复制');
}
};
const binaryUrl = `${serverUrl}/agent/aiops-agent-linux-amd64`;
const manualSteps = [
{
icon: Download,
title: '1. 下载二进制',
commands: [
`curl -fsSL ${binaryUrl} -o /usr/local/bin/aiops-agent`,
],
},
{
icon: Settings,
title: '2. 赋予执行权限',
commands: ['chmod +x /usr/local/bin/aiops-agent'],
},
{
icon: Cpu,
title: '3. 创建 systemd 服务',
commands: [
`cat > /etc/systemd/system/aiops-agent.service << 'EOF'`,
`[Unit]`,
`Description=AIOps Agent`,
`After=network.target`,
``,
`[Service]`,
`Type=simple`,
`ExecStart=/usr/local/bin/aiops-agent --server ${serverUrl} --token ${token}`,
`Restart=always`,
`RestartSec=5`,
``,
`[Install]`,
`WantedBy=multi-user.target`,
`EOF`,
],
},
{
icon: Play,
title: '4. 启动并设置开机自启',
commands: [
'systemctl daemon-reload',
'systemctl enable --now aiops-agent',
'systemctl status aiops-agent',
],
},
];
return (
<Dialog open={open} onOpenChange={onOpenChange}>
<DialogContent className="max-w-2xl bg-slate-900 border-slate-800 text-slate-100">
<DialogHeader>
<DialogTitle className="text-slate-100">部署 Agent</DialogTitle>
<DialogDescription className="text-slate-400">
在目标主机上执行以下命令即可完成 Agent 安装与注册
</DialogDescription>
</DialogHeader>
<Tabs defaultValue="auto" className="w-full">
<TabsList className="bg-slate-800 border border-slate-700">
<TabsTrigger value="auto" className="data-[state=active]:bg-slate-700">
<Terminal className="h-4 w-4 mr-1.5" />
安装Agent
</TabsTrigger>
<TabsTrigger value="manual" className="data-[state=active]:bg-slate-700">
手动安装
</TabsTrigger>
</TabsList>
{/* 自动安装 */}
<TabsContent value="auto" className="mt-4 space-y-3">
<p className="text-sm text-slate-400">
在目标主机执行以下命令,Agent 将自动下载、安装并启动:
</p>
<div className="relative rounded-lg bg-slate-950 border border-slate-800 p-4">
<pre className="text-xs text-emerald-400 font-mono whitespace-pre-wrap break-all pr-10">
{installCommand}
</pre>
<Button
size="icon"
variant="ghost"
onClick={handleCopy}
className="absolute top-2 right-2 h-8 w-8 text-slate-400 hover:text-slate-100 hover:bg-slate-800"
title="复制"
>
{copied ? <Check className="h-4 w-4 text-emerald-400" /> : <Copy className="h-4 w-4" />}
</Button>
</div>
<div className="flex items-start gap-2 text-xs text-slate-500">
<Terminal className="h-3.5 w-3.5 mt-0.5 shrink-0" />
<span>
服务器地址已自动检测为当前访问地址({serverUrl})。Agent 安装成功后将自动连接并开始上报指标。
</span>
</div>
</TabsContent>
{/* 手动安装 */}
<TabsContent value="manual" className="mt-4 space-y-4">
<div className="max-h-[420px] overflow-y-auto space-y-3 pr-1">
{manualSteps.map((step) => (
<div key={step.title} className="rounded-lg bg-slate-950 border border-slate-800 overflow-hidden">
<div className="flex items-center gap-2 px-4 py-2.5 bg-slate-800/50">
<step.icon className="h-4 w-4 text-blue-400" />
<span className="text-sm font-medium text-slate-200">{step.title}</span>
</div>
<div className="p-3 space-y-1">
{step.commands.map((cmd, idx) => (
<div key={idx} className="flex items-start gap-2">
<span className="text-slate-600 font-mono text-xs select-none mt-0.5">$</span>
<code className="text-xs text-slate-300 font-mono whitespace-pre-wrap break-all flex-1">
{cmd}
</code>
</div>
))}
</div>
</div>
))}
</div>
<p className="text-xs text-slate-500">
完成上述步骤后,Agent 将作为 systemd 服务运行并自动上报指标。
</p>
</TabsContent>
</Tabs>
</DialogContent>
</Dialog>
);
}
export default AgentWizard;