feat(fleet): auto-swarm deploy — shard across enrolled workers when master
POST /deckies/deploy now branches on DECNET_MODE + enrolled host presence: when the caller is a master with at least one reachable swarm host, round- robin host_uuids are assigned over new deckies and the config is dispatched via AgentClient. Falls back to local docker-compose otherwise. Extracts the dispatch loop from api_deploy_swarm into dispatch_decnet_config so both endpoints share the same shard/dispatch/persist path. Adds GET /system/deployment-mode for the UI to show 'will shard across N hosts' vs 'will deploy locally' before the operator clicks deploy.
This commit is contained in:
@@ -23,6 +23,7 @@ const DeckyFleet: React.FC = () => {
|
||||
const [iniContent, setIniContent] = useState('');
|
||||
const [deploying, setDeploying] = useState(false);
|
||||
const [isAdmin, setIsAdmin] = useState(false);
|
||||
const [deployMode, setDeployMode] = useState<{ mode: string; swarm_host_count: number } | null>(null);
|
||||
|
||||
const fetchDeckies = async () => {
|
||||
try {
|
||||
@@ -102,9 +103,19 @@ const DeckyFleet: React.FC = () => {
|
||||
reader.readAsText(file);
|
||||
};
|
||||
|
||||
const fetchDeployMode = async () => {
|
||||
try {
|
||||
const res = await api.get('/system/deployment-mode');
|
||||
setDeployMode({ mode: res.data.mode, swarm_host_count: res.data.swarm_host_count });
|
||||
} catch {
|
||||
setDeployMode(null);
|
||||
}
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
fetchDeckies();
|
||||
fetchRole();
|
||||
fetchDeployMode();
|
||||
const _interval = setInterval(fetchDeckies, 10000); // Fleet state updates less frequently than logs
|
||||
return () => clearInterval(_interval);
|
||||
}, []);
|
||||
@@ -131,7 +142,16 @@ const DeckyFleet: React.FC = () => {
|
||||
{showDeploy && (
|
||||
<div style={{ marginBottom: '24px', padding: '24px', backgroundColor: 'var(--secondary-color)', border: '1px solid var(--accent-color)', display: 'flex', flexDirection: 'column', gap: '16px' }}>
|
||||
<div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center' }}>
|
||||
<h3 style={{ fontSize: '1rem', color: 'var(--text-color)' }}>Deploy via INI Configuration</h3>
|
||||
<h3 style={{ fontSize: '1rem', color: 'var(--text-color)' }}>
|
||||
Deploy via INI Configuration
|
||||
{deployMode && (
|
||||
<span style={{ marginLeft: 12, fontSize: '0.75rem', color: 'var(--dim-color)', fontWeight: 'normal' }}>
|
||||
{deployMode.mode === 'swarm'
|
||||
? `→ will shard across ${deployMode.swarm_host_count} SWARM host(s)`
|
||||
: '→ will deploy locally (UNIHOST)'}
|
||||
</span>
|
||||
)}
|
||||
</h3>
|
||||
<div>
|
||||
<input
|
||||
type="file"
|
||||
|
||||
Reference in New Issue
Block a user