You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Today hostfwd is baked at QEMU launch: buildHostfwdString(state.ports) → -netdev user,id=net0,hostfwd=… in src/lib/qemu.ts:189, persisted in machine.json (portBase, extraPorts, ports). Adding a port to a running machine today requires a restart — stop()/start() — there is no live path.
Agent use case: chr.start() → chr.rest("/something") that needs a new host→guest port (e.g. btest UDP range 2000–2010, a user-added /ip service, container port) — the agent wants chr.addHostFwd({host:28282, guest:80, proto:"udp"}) without bouncing the VM.
What QEMU already does
QEMU human monitor (HMP) on the user netdev supports hostfwd_add / hostfwd_remove at runtime (hostfwd_add [netdev:] [tcp|udp]:[host_ip]:host_port-[guest_ip]:guest_port). quickchr already drives HMP via src/lib/channels.ts:monitorCommand (used for quit, savevm, info snapshots, etc.), so the transport exists — there is just no hostfwd_add barrel.
grep -R hostfwd_add src/ is empty today. src/lib/forward-spec.ts:21 notes QEMU has no native range — btest:9200-9210:2000-2010/udp expands to one hostfwd per port, which the live path would mirror.
Scope / current behavior
--forward / extraPorts and the range expansion (expandForwardSpec) are start-time only.
MachineState.ports is treated as immutable after spawn.
Proposed enhancement
Expose a ChrInstance method (e.g. addHostFwd / `addForwar
Context
Today
hostfwdis baked at QEMU launch:buildHostfwdString(state.ports)→-netdev user,id=net0,hostfwd=…insrc/lib/qemu.ts:189, persisted inmachine.json(portBase,extraPorts,ports). Adding a port to a running machine today requires a restart —stop()/start()— there is no live path.Agent use case:
chr.start()→chr.rest("/something")that needs a new host→guest port (e.g.btestUDP range2000–2010, a user-added/ip service, container port) — the agent wantschr.addHostFwd({host:28282, guest:80, proto:"udp"})without bouncing the VM.What QEMU already does
QEMU human monitor (HMP) on the
usernetdev supportshostfwd_add/hostfwd_removeat runtime (hostfwd_add [netdev:] [tcp|udp]:[host_ip]:host_port-[guest_ip]:guest_port). quickchr already drives HMP viasrc/lib/channels.ts:monitorCommand(used forquit,savevm,info snapshots, etc.), so the transport exists — there is just nohostfwd_addbarrel.grep -R hostfwd_add src/is empty today.src/lib/forward-spec.ts:21notes QEMU has no native range —btest:9200-9210:2000-2010/udpexpands to onehostfwdper port, which the live path would mirror.Scope / current behavior
--forward/extraPortsand the range expansion (expandForwardSpec) are start-time only.MachineState.portsis treated as immutable after spawn.Proposed enhancement
Expose a
ChrInstancemethod (e.g.addHostFwd/ `addForwarvalidateExplicitExtraPorts()+ `isPortAvai checks, including concurrency against port allocator: concurrent auto starts select the same block and one QEMU fails #140's allocatorreservation,hostfwd_addviamonitorCommand()perPortMappingd byFORWARD_RANGE_MAX = 64`),machine.jsonso the nextstart()replays them, with typed errors (PORT_CONFLICT/MACHINE_STOPPED/ monitorerror),
user-NIC only —vmnet-shared/bridged/tap/sockethave nohostfwdto extend (typed error if nousernetdev),removeHostFwdviahostfwd_remove.Done-when
stop()/start()(persisted) and are(concurrent callers reuse port allocator: concurrent auto starts select the same block and one QEMU fails #140 reservation).MANUAL.md+routeros-quickchrskill document live vs reusernetdev is a typed error, not silent no-op.Relation to other port work