Initial Commit
This commit is contained in:
Executable
+67
@@ -0,0 +1,67 @@
|
||||
#!/usr/bin/env python3
|
||||
"""Push a local script into the running maintenance guest and run it.
|
||||
|
||||
sudo owuivm-guest-run vm/images/ubuntu/by-hand.sh
|
||||
|
||||
WHY THIS EXISTS
|
||||
|
||||
Preparing a base image by hand means typing into a VNC console, and the
|
||||
list of things to do to it is a hundred lines long. Everything on that
|
||||
list is ordinary shell, so the only real problem is getting the text in
|
||||
there - and the machine already has a channel for exactly that, the same
|
||||
one every session uses.
|
||||
|
||||
It needs qemu-guest-agent inside the guest, which is also the one thing
|
||||
on that list that genuinely has to be typed by hand: it is what this
|
||||
speaks to. So the sequence is always "install the guest agent by hand,
|
||||
then push the rest".
|
||||
|
||||
Deliberately the maintenance socket only. A session's guest belongs to
|
||||
the agent, and a way to inject a script into it from the host is not
|
||||
something this host should own.
|
||||
"""
|
||||
from __future__ import annotations
|
||||
|
||||
import sys
|
||||
|
||||
sys.path.insert(0, "/usr/local/lib/owuivm")
|
||||
|
||||
from guest import Guest, GuestError # noqa: E402
|
||||
|
||||
SOCKET = "/run/owuivm/00000000000000000000000000000000/ga.sock"
|
||||
|
||||
|
||||
def main(argv: list[str]) -> int:
|
||||
if len(argv) != 2:
|
||||
print(f"usage: {argv[0]} <script>", file=sys.stderr)
|
||||
return 64
|
||||
with open(argv[1], "rb") as handle:
|
||||
body = handle.read()
|
||||
remote = "/root/" + argv[1].rsplit("/", 1)[-1]
|
||||
|
||||
try:
|
||||
with Guest(SOCKET, timeout=30.0) as agent:
|
||||
if not agent.ping(timeout=10.0):
|
||||
raise GuestError("the guest agent did not answer")
|
||||
agent.write_file(remote, body)
|
||||
print(f"pushed {len(body)} bytes to {remote}; running it\n", flush=True)
|
||||
# No timeout worth arguing about: this installs packages over
|
||||
# a link that is as fast as the host's, and a run that is
|
||||
# still going is not a run that has failed.
|
||||
result = agent.shell(f"bash {remote}", timeout_s=1800.0)
|
||||
except (GuestError, OSError) as exc:
|
||||
print(f"could not reach the machine: {exc}", file=sys.stderr)
|
||||
print("\nIs it running, and is qemu-guest-agent installed inside it?"
|
||||
"\n sudo apt install -y qemu-guest-agent"
|
||||
"\n sudo systemctl enable --now qemu-guest-agent", file=sys.stderr)
|
||||
return 69
|
||||
|
||||
sys.stdout.write(result["stdout"])
|
||||
if result["stderr"].strip():
|
||||
sys.stderr.write("\n-- stderr --\n" + result["stderr"])
|
||||
print(f"\nexit code: {result['exit_code']} ({result['seconds']}s)")
|
||||
return 0 if result["exit_code"] == 0 else 1
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
raise SystemExit(main(sys.argv))
|
||||
Reference in New Issue
Block a user