feat(enroll): opt-in IPvlan per-agent for Wi-Fi-bridged VMs

Wi-Fi APs bind one MAC per associated station, so VirtualBox/VMware
guests bridged over Wi-Fi rotate the VM's DHCP lease when Docker's
macvlan starts emitting container-MAC frames through the vNIC. Adds a
`use_ipvlan` toggle on the Agent Enrollment tab (mirrors the updater
daemon checkbox): flips the flag on SwarmHost, bakes `ipvlan=true` into
the agent's decnet.ini, and `_worker_config` forces ipvlan=True on the
per-host shard at dispatch. Safe no-op on wired/bare-metal agents.
This commit is contained in:
2026-04-19 17:57:45 -04:00
parent 6d7567b6bb
commit 5df995fda1
6 changed files with 109 additions and 6 deletions

View File

@@ -15,6 +15,7 @@ const AgentEnrollment: React.FC = () => {
const [masterHost, setMasterHost] = useState(window.location.hostname);
const [agentName, setAgentName] = useState('');
const [withUpdater, setWithUpdater] = useState(true);
const [useIpvlan, setUseIpvlan] = useState(false);
const [servicesIni, setServicesIni] = useState<string | null>(null);
const [servicesIniName, setServicesIniName] = useState<string | null>(null);
const [submitting, setSubmitting] = useState(false);
@@ -49,6 +50,7 @@ const AgentEnrollment: React.FC = () => {
setError(null);
setAgentName('');
setWithUpdater(true);
setUseIpvlan(false);
setServicesIni(null);
setServicesIniName(null);
setCopied(false);
@@ -64,6 +66,7 @@ const AgentEnrollment: React.FC = () => {
master_host: masterHost,
agent_name: agentName,
with_updater: withUpdater,
use_ipvlan: useIpvlan,
services_ini: servicesIni,
});
setResult(res.data);
@@ -130,6 +133,16 @@ const AgentEnrollment: React.FC = () => {
/>
<span>Install updater daemon (lets the master push code updates to this agent)</span>
</label>
<label className="form-inline">
<input
type="checkbox"
checked={useIpvlan}
onChange={(e) => setUseIpvlan(e.target.checked)}
/>
<span>
Use IPvlan instead of MACVLAN (required for VirtualBox/VMware guests bridged over Wi-Fi Wi-Fi APs bind one MAC per station, so MACVLAN rotates the VM's lease)
</span>
</label>
<label>
Services INI (optional)
<input ref={fileRef} type="file" accept=".ini,.conf,.txt" onChange={handleFile} />