diff --git a/nixos/lib/test-driver/test-driver.py b/nixos/lib/test-driver/test-driver.py index 75f80df53f21..2b8dffec7d59 100644 --- a/nixos/lib/test-driver/test-driver.py +++ b/nixos/lib/test-driver/test-driver.py @@ -1,13 +1,17 @@ #! /somewhere/python3 from contextlib import contextmanager, _GeneratorContextManager +from queue import Queue, Empty +from typing import Tuple, Any, Callable, Dict, Iterator, Optional, List from xml.sax.saxutils import XMLGenerator import _thread import atexit +import base64 import os +import pathlib import ptpython.repl import pty -from queue import Queue, Empty import re +import shlex import shutil import socket import subprocess @@ -15,9 +19,6 @@ import sys import tempfile import time import unicodedata -from typing import Tuple, Any, Callable, Dict, Iterator, Optional, List -import shlex -import pathlib CHAR_TO_KEY = { "A": "shift-a", @@ -566,6 +567,41 @@ class Machine: if ret.returncode != 0: raise Exception("Cannot convert screenshot") + def copy_from_host_via_shell(self, source: str, target: str) -> None: + """Copy a file from the host into the guest by piping it over the + shell into the destination file. Works without host-guest shared folder. + Prefer copy_from_host for whenever possible. + """ + with open(source, "rb") as fh: + content_b64 = base64.b64encode(fh.read()).decode() + self.succeed( + f"mkdir -p $(dirname {target})", + f"echo -n {content_b64} | base64 -d > {target}", + ) + + def copy_from_host(self, source: str, target: str) -> None: + """Copy a file from the host into the guest via the `shared_dir` shared + among all the VMs (using a temporary directory). + """ + host_src = pathlib.Path(source) + vm_target = pathlib.Path(target) + with tempfile.TemporaryDirectory(dir=self.shared_dir) as shared_td: + shared_temp = pathlib.Path(shared_td) + host_intermediate = shared_temp / host_src.name + vm_shared_temp = pathlib.Path("/tmp/shared") / shared_temp.name + vm_intermediate = vm_shared_temp / host_src.name + + self.succeed(make_command(["mkdir", "-p", vm_shared_temp])) + if host_src.is_dir(): + shutil.copytree(host_src, host_intermediate) + else: + shutil.copy(host_src, host_intermediate) + self.succeed("sync") + self.succeed(make_command(["mkdir", "-p", vm_target.parent])) + self.succeed(make_command(["cp", "-r", vm_intermediate, vm_target])) + # Make sure the cleanup is synced into VM + self.succeed("sync") + def copy_from_vm(self, source: str, target_dir: str = "") -> None: """Copy a file from the VM (specified by an in-VM source path) to a path relative to `$out`. The file is copied via the `shared_dir` shared among