From 8884df5df3abe6457996d9daa43b240f8da25fbc Mon Sep 17 00:00:00 2001 From: Matt Culler Date: Wed, 15 Jan 2025 12:17:41 -0500 Subject: [PATCH 1/4] feat: mknod intercepts now configurable from LXDProvider --- craft_providers/lxd/lxd_instance.py | 14 ++++++++++++-- craft_providers/lxd/lxd_provider.py | 4 ++++ 2 files changed, 16 insertions(+), 2 deletions(-) diff --git a/craft_providers/lxd/lxd_instance.py b/craft_providers/lxd/lxd_instance.py index 7b4af3af..a46ab056 100644 --- a/craft_providers/lxd/lxd_instance.py +++ b/craft_providers/lxd/lxd_instance.py @@ -25,6 +25,7 @@ import subprocess import tempfile from typing import Any, Dict, List, Optional +import warnings from craft_providers.const import TIMEOUT_SIMPLE from craft_providers.errors import details_from_called_process_error @@ -54,6 +55,7 @@ def __init__( project: str = "default", remote: str = "local", lxc: Optional[LXC] = None, + intercept_mknod: bool = True, ) -> None: """Create an LXD executor. @@ -65,6 +67,7 @@ def __init__( :param project: The name of the LXD project. :param remote: The name of the LXD remote. :param lxc: The LXC wrapper to use. + :param intercept_mknod: If the host can, tell LXD instance to intercept mknod :raises LXDError: If the name is invalid. """ @@ -79,6 +82,7 @@ def __init__( self.instance_name = get_instance_name(name, LXDError) self.project = project self.remote = remote + self._intercept_mknod = intercept_mknod if lxc is None: self.lxc = LXC() @@ -363,8 +367,14 @@ def launch( uid = os.getuid() config_keys["raw.idmap"] = f"both {uid!s} 0" - if self._host_supports_mknod(): - config_keys["security.syscalls.intercept.mknod"] = "true" + if self._intercept_mknod: + if not self._host_supports_mknod(): + warnings.warn( + "Application configured to intercept guest mknod calls, " + "but the host OS does not support intercepting mknod." + ) + else: + config_keys["security.syscalls.intercept.mknod"] = "true" self.lxc.launch( config_keys=config_keys, diff --git a/craft_providers/lxd/lxd_provider.py b/craft_providers/lxd/lxd_provider.py index 13fde5f4..cbd532b5 100644 --- a/craft_providers/lxd/lxd_provider.py +++ b/craft_providers/lxd/lxd_provider.py @@ -45,6 +45,7 @@ class LXDProvider(Provider): :param lxc: Optional lxc client to use. :param lxd_project: LXD project to use (default is default). :param lxd_remote: LXD remote to use (default is local). + :param intercept_mknod: If the host can, tell LXD instance to intercept mknod """ def __init__( @@ -53,10 +54,12 @@ def __init__( lxc: LXC = LXC(), lxd_project: str = "default", lxd_remote: str = "local", + intercept_mknod: bool = True, ) -> None: self.lxc = lxc self.lxd_project = lxd_project self.lxd_remote = lxd_remote + self._intercept_mknod = intercept_mknod @property def name(self) -> str: @@ -98,6 +101,7 @@ def create_environment(self, *, instance_name: str) -> Executor: name=instance_name, project=self.lxd_project, remote=self.lxd_remote, + intercept_mknod=self._intercept_mknod, ) @contextlib.contextmanager From 8d50772bc70a8a8756bb381d614cee38c358bb65 Mon Sep 17 00:00:00 2001 From: Matt Culler Date: Thu, 16 Jan 2025 10:30:58 -0500 Subject: [PATCH 2/4] fix: unit test --- tests/unit/lxd/test_lxd_provider.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/unit/lxd/test_lxd_provider.py b/tests/unit/lxd/test_lxd_provider.py index db360fe6..199c8f89 100644 --- a/tests/unit/lxd/test_lxd_provider.py +++ b/tests/unit/lxd/test_lxd_provider.py @@ -121,7 +121,7 @@ def test_create_environment(mocker): provider.create_environment(instance_name="test-name") mock_lxd_instance.assert_called_once_with( - name="test-name", project="default", remote="local" + name="test-name", project="default", remote="local", intercept_mknod=True ) From c97ab108de71d6375a0c6c53a51b9cdda7a140b6 Mon Sep 17 00:00:00 2001 From: Matt Culler Date: Thu, 16 Jan 2025 10:31:46 -0500 Subject: [PATCH 3/4] fix: lint --- craft_providers/lxd/lxd_instance.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/craft_providers/lxd/lxd_instance.py b/craft_providers/lxd/lxd_instance.py index a46ab056..97e98a07 100644 --- a/craft_providers/lxd/lxd_instance.py +++ b/craft_providers/lxd/lxd_instance.py @@ -24,8 +24,8 @@ import shutil import subprocess import tempfile -from typing import Any, Dict, List, Optional import warnings +from typing import Any, Dict, List, Optional from craft_providers.const import TIMEOUT_SIMPLE from craft_providers.errors import details_from_called_process_error From 65e870626dfb55f40e71bfd5c23ec8dec7dc5617 Mon Sep 17 00:00:00 2001 From: Matt Culler Date: Thu, 16 Jan 2025 15:15:07 -0500 Subject: [PATCH 4/4] docs: update changelog (also includes item from #710) --- docs/reference/changelog.rst | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/docs/reference/changelog.rst b/docs/reference/changelog.rst index 0ee033e8..ac040935 100644 --- a/docs/reference/changelog.rst +++ b/docs/reference/changelog.rst @@ -4,6 +4,13 @@ Changelog See the `Releases page`_ on GitHub for a complete list of commits that are included in each version. +2.2.0 (2025-Jan-16) +------------------- +- ``hookutil.py`` now available for dependent projects to clean up lxd + instances. +- Dependent projects can now disable lxd ``mknod`` interception via + ``LXDProvider``'s ``__init__``. + 2.1.0 (2025-Jan-10) ------------------- - Require Multipass>=1.14.1