feat: add verified QEMU soft reset
This commit is contained in:
@@ -44,6 +44,8 @@ def main() -> int:
|
|||||||
commands.add_parser(name)
|
commands.add_parser(name)
|
||||||
reset = commands.add_parser("reset")
|
reset = commands.add_parser("reset")
|
||||||
reset.add_argument("--timeout", type=int, default=45)
|
reset.add_argument("--timeout", type=int, default=45)
|
||||||
|
soft_reset = commands.add_parser("soft-reset")
|
||||||
|
soft_reset.add_argument("--timeout", type=int, default=45)
|
||||||
execute = commands.add_parser("exec")
|
execute = commands.add_parser("exec")
|
||||||
execute.add_argument("command")
|
execute.add_argument("command")
|
||||||
put = commands.add_parser("put")
|
put = commands.add_parser("put")
|
||||||
@@ -63,10 +65,13 @@ def main() -> int:
|
|||||||
recognized = RapidOCR()(result["path"])
|
recognized = RapidOCR()(result["path"])
|
||||||
print("\n".join(recognized.txts or ()))
|
print("\n".join(recognized.txts or ()))
|
||||||
return 0
|
return 0
|
||||||
|
if args.op in ("reset", "soft-reset"):
|
||||||
if args.op == "reset":
|
if args.op == "reset":
|
||||||
rpc({"op": "stop"}, start_daemon=True)
|
rpc({"op": "stop"}, start_daemon=True)
|
||||||
time.sleep(.5)
|
time.sleep(.5)
|
||||||
rpc({"op": "start"}, start_daemon=True)
|
rpc({"op": "start"}, start_daemon=True)
|
||||||
|
else:
|
||||||
|
rpc({"op": "soft-reset"})
|
||||||
# FreeDOS displays its default boot menu before FDAUTO.BAT starts
|
# FreeDOS displays its default boot menu before FDAUTO.BAT starts
|
||||||
# TCPAGENT. This is input, not a readiness delay.
|
# TCPAGENT. This is input, not a readiness delay.
|
||||||
time.sleep(2)
|
time.sleep(2)
|
||||||
@@ -75,7 +80,7 @@ def main() -> int:
|
|||||||
while time.monotonic() < deadline:
|
while time.monotonic() < deadline:
|
||||||
try:
|
try:
|
||||||
if str(rpc({"op": "ping"})["response"]).startswith("OK 504F4E47"):
|
if str(rpc({"op": "ping"})["response"]).startswith("OK 504F4E47"):
|
||||||
print(json.dumps({"reset": True, "agent": "PONG"}))
|
print(json.dumps({"reset": args.op, "agent": "PONG"}))
|
||||||
return 0
|
return 0
|
||||||
except RuntimeError:
|
except RuntimeError:
|
||||||
time.sleep(.5)
|
time.sleep(.5)
|
||||||
|
|||||||
@@ -232,6 +232,10 @@ class Host:
|
|||||||
return {"agent_connected": self.agent_ready.is_set(), "qemu_running": running, "log": str(LOG_PATH)}
|
return {"agent_connected": self.agent_ready.is_set(), "qemu_running": running, "log": str(LOG_PATH)}
|
||||||
if op == "start": return self.start()
|
if op == "start": return self.start()
|
||||||
if op == "stop": return self.stop()
|
if op == "stop": return self.stop()
|
||||||
|
if op == "soft-reset":
|
||||||
|
self.monitor("system_reset")
|
||||||
|
log_event(logging.INFO, "qemu soft reset requested")
|
||||||
|
return {"reset": "requested"}
|
||||||
if op == "ping": return self.ping()
|
if op == "ping": return self.ping()
|
||||||
if op == "exec": return self.exec(str(request["command"]))
|
if op == "exec": return self.exec(str(request["command"]))
|
||||||
if op == "put": return self.put(str(request["source"]), str(request["destination"]))
|
if op == "put": return self.put(str(request["source"]), str(request["destination"]))
|
||||||
|
|||||||
+5
-2
@@ -26,6 +26,8 @@ lnav .qemu/ferro-vm.log
|
|||||||
Commands:
|
Commands:
|
||||||
|
|
||||||
```powershell
|
```powershell
|
||||||
|
uv run ferro-vm reset # clean QEMU quit and restart
|
||||||
|
uv run ferro-vm soft-reset # QEMU system_reset
|
||||||
uv run ferro-vm ping
|
uv run ferro-vm ping
|
||||||
uv run ferro-vm exec 'dir C:\FEC'
|
uv run ferro-vm exec 'dir C:\FEC'
|
||||||
uv run ferro-vm put fec/src/check.c 'C:\FEC\SRC\CHECK.C'
|
uv run ferro-vm put fec/src/check.c 'C:\FEC\SRC\CHECK.C'
|
||||||
@@ -35,8 +37,9 @@ uv run ferro-vm ocr
|
|||||||
uv run ferro-vm stop
|
uv run ferro-vm stop
|
||||||
```
|
```
|
||||||
|
|
||||||
The daemon logs command metadata, DOS output, exit status, transfers, and
|
Both reset modes wait for FreeDOS to boot, submit the default boot-menu Enter,
|
||||||
agent lifecycle events as UTF-8 lines. It deliberately never logs raw binary
|
and require TCPAGENT `PING`/`PONG` before succeeding. The daemon logs command
|
||||||
|
metadata, DOS output, exit status, transfers, and agent lifecycle events as UTF-8 lines. It deliberately never logs raw binary
|
||||||
payloads or protocol hex.
|
payloads or protocol hex.
|
||||||
|
|
||||||
## Standalone OCR
|
## Standalone OCR
|
||||||
|
|||||||
Reference in New Issue
Block a user