From: Daan De Meyer Date: Sun, 3 Mar 2024 10:07:58 +0000 (+0100) Subject: Add RuntimeNetwork= setting X-Git-Tag: v21~18 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=a8d1310158ea820f2f4d334e8867368fdfe7dd66;p=thirdparty%2Fmkosi.git Add RuntimeNetwork= setting Let's allow configuring exactly what networking is set up when booting the image. --- diff --git a/mkosi/__init__.py b/mkosi/__init__.py index c3567fae1..9340fc82b 100644 --- a/mkosi/__init__.py +++ b/mkosi/__init__.py @@ -34,6 +34,7 @@ from mkosi.config import ( DocFormat, JsonEncoder, ManifestFormat, + Network, OutputFormat, SecureBootSignTool, ShimBootloader, @@ -3314,6 +3315,16 @@ def run_shell(args: Args, config: Config) -> None: cmdline: list[PathString] = ["systemd-nspawn", "--quiet", "--link-journal=no"] + if config.runtime_network == Network.user: + cmdline += ["--resolv-conf=auto"] + elif config.runtime_network == Network.interface: + if os.getuid() != 0: + die("RuntimeNetwork=interface requires root privileges") + + cmdline += ["--private-network", "--network-veth"] + elif config.runtime_network == Network.none: + cmdline += ["--private-network"] + # If we copied in a .nspawn file, make sure it's actually honoured if config.nspawn_settings: cmdline += ["--settings=trusted"] diff --git a/mkosi/config.py b/mkosi/config.py index ec8bebce3..c3caedf3f 100644 --- a/mkosi/config.py +++ b/mkosi/config.py @@ -253,6 +253,12 @@ class QemuFirmware(StrEnum): bios = enum.auto() +class Network(StrEnum): + interface = enum.auto() + user = enum.auto() + none = enum.auto() + + class Architecture(StrEnum): alpha = enum.auto() arc = enum.auto() @@ -1311,6 +1317,7 @@ class Config: runtime_trees: list[ConfigTree] runtime_size: Optional[int] runtime_scratch: ConfigFeature + runtime_network: Network ssh_key: Optional[Path] ssh_certificate: Optional[Path] @@ -2517,6 +2524,13 @@ SETTINGS = ( parse=config_parse_feature, help="Mount extra scratch space to /var/tmp", ), + ConfigSetting( + dest="runtime_network", + metavar="NET", + section="Host", + parse=config_make_enum_parser(Network), + help="Set networking backend to use when booting the image", + ), ConfigSetting( dest="ssh_key", metavar="PATH", @@ -3619,6 +3633,7 @@ def summary(config: Config) -> str: Runtime Trees: {line_join_list(config.runtime_trees)} Runtime Size: {format_bytes_or_none(config.runtime_size)} Runtime Scratch: {config.runtime_scratch} + Runtime Network: {config.runtime_network} SSH Signing Key: {none_to_none(config.ssh_key)} SSH Certificate: {none_to_none(config.ssh_certificate)} @@ -3755,6 +3770,7 @@ def json_type_transformer(refcls: Union[type[Args], type[Config]]) -> Callable[[ list[QemuDrive]: config_drive_transformer, GenericVersion: generic_version_transformer, Cacheonly: enum_transformer, + Network: enum_transformer, } def json_transformer(key: str, val: Any) -> Any: diff --git a/mkosi/qemu.py b/mkosi/qemu.py index 6efcdff9d..be22721d4 100644 --- a/mkosi/qemu.py +++ b/mkosi/qemu.py @@ -26,6 +26,7 @@ from mkosi.config import ( Args, Config, ConfigFeature, + Network, OutputFormat, QemuFirmware, QemuVsockCID, @@ -597,7 +598,15 @@ def run_qemu(args: Args, config: Config) -> None: *shm, ] - cmdline += ["-nic", f"user,model={config.architecture.default_qemu_nic_model()}"] + if config.runtime_network == Network.user: + cmdline += ["-nic", f"user,model={config.architecture.default_qemu_nic_model()}"] + elif config.runtime_network == Network.interface: + if os.getuid() != 0: + die("RuntimeNetwork=interface requires root privileges") + + cmdline += ["-nic", "tap,script=no,model=virtio-net-pci"] + elif config.runtime_network == Network.none: + cmdline += ["-nic", "none"] if config.qemu_kvm != ConfigFeature.disabled and have_kvm and config.architecture.is_native(): accel = "kvm" diff --git a/mkosi/resources/mkosi.md b/mkosi/resources/mkosi.md index 95a968ee1..e0cc35706 100644 --- a/mkosi/resources/mkosi.md +++ b/mkosi/resources/mkosi.md @@ -1706,6 +1706,19 @@ boolean argument: either `1`, `yes`, or `true` to enable, or `0`, `no`, : Note that using this feature with `mkosi qemu` requires systemd v254 or newer in the guest. +`RuntimeNetwork=`: `--runtime-network=` + +: Takes one of `user`, `interface` or `none`. Specifies the networking + to set up when booting the image. `user` sets up usermode networking. + `interface` sets up a virtual network connection between the host and + the image. This translates to a veth interface for `mkosi shell` and + `mkosi boot` and a tap interface for `mkosi qemu` and `mkosi vmspawn`. + +: Note that when using `interface`, mkosi does not automatically + configure the host interface. It is expected that a recent version of + `systemd-networkd` is running on the host which will automatically + configure the host interface of the link. + `SshKey=`, `--ssh-key=` : Path to the X509 private key in PEM format to use to connect to a diff --git a/mkosi/vmspawn.py b/mkosi/vmspawn.py index 16312907d..8726183ac 100644 --- a/mkosi/vmspawn.py +++ b/mkosi/vmspawn.py @@ -8,6 +8,7 @@ from pathlib import Path from mkosi.config import ( Args, Config, + Network, OutputFormat, QemuFirmware, yes_no, @@ -56,6 +57,11 @@ def run_vmspawn(args: Args, config: Config) -> None: "--secure-boot", yes_no(config.secure_boot), ] + if config.runtime_network == Network.user: + cmdline += ["--network-user-mode"] + elif config.runtime_network == Network.interface: + cmdline += ["--network-tap"] + if config.qemu_gui: cmdline += ["--qemu-gui"] diff --git a/tests/test_json.py b/tests/test_json.py index 83f6bcade..001a116b4 100644 --- a/tests/test_json.py +++ b/tests/test_json.py @@ -20,6 +20,7 @@ from mkosi.config import ( ConfigTree, DocFormat, ManifestFormat, + Network, OutputFormat, QemuDrive, QemuFirmware, @@ -240,6 +241,7 @@ def test_config() -> None: false ], "RootShell": "/bin/tcsh", + "RuntimeNetwork": "interface", "RuntimeScratch": "enabled", "RuntimeSize": 8589934592, "RuntimeTrees": [ @@ -400,6 +402,7 @@ def test_config() -> None: repository_key_check = False, root_password = ("test1234", False), root_shell = "/bin/tcsh", + runtime_network = Network.interface, runtime_scratch = ConfigFeature.enabled, runtime_size = 8589934592, runtime_trees = [ConfigTree(Path("/foo/bar"), Path("/baz")), ConfigTree(Path("/bar/baz"), Path("/qux"))],