From c5693d534f34b74ebdfdaaf6f81c840818ec450d Mon Sep 17 00:00:00 2001 From: Johannes Leupolz Date: Tue, 14 Apr 2026 20:21:21 +0000 Subject: [PATCH] Work on injection for container engine "incus" --- .../container_runtime/injection_strategy.rs | 68 +++++++++++++++++++ vuinputd/src/container_runtime/mod.rs | 5 +- 2 files changed, 70 insertions(+), 3 deletions(-) diff --git a/vuinputd/src/container_runtime/injection_strategy.rs b/vuinputd/src/container_runtime/injection_strategy.rs index 9645e9c..a244663 100644 --- a/vuinputd/src/container_runtime/injection_strategy.rs +++ b/vuinputd/src/container_runtime/injection_strategy.rs @@ -13,6 +13,7 @@ use crate::{ pub static PLACEMENT_IN_CONTAINER: GenericPlacementInContainer = GenericPlacementInContainer {}; pub static PLACEMENT_ON_HOST: GenericPlacementOnHost = GenericPlacementOnHost {}; pub static SEND_NETLINK_ONLY: GenericSendNetlinkMessageOnly = GenericSendNetlinkMessageOnly {}; +pub static INCUS: Incus = Incus {}; #[async_trait] pub trait InjectionStrategy { @@ -60,6 +61,7 @@ pub trait InjectionStrategy { pub struct GenericPlacementInContainer {} pub struct GenericPlacementOnHost {} pub struct GenericSendNetlinkMessageOnly {} +pub struct Incus {} #[async_trait] impl InjectionStrategy for GenericPlacementInContainer { @@ -253,3 +255,69 @@ impl InjectionStrategy for GenericSendNetlinkMessageOnly { Ok(()) } } + +#[async_trait] +impl InjectionStrategy for Incus { + async fn mknod_device_node( + &self, + _requesting_process: &RequestingProcess, + devname: &str, + _major: u64, + _minor: u64, + ) -> anyhow::Result<()> { + let hostpath = format!("path=/dev/input/{}", devname); + let incuspath = format!("path=/dev/input/{}", devname); + let child = std::process::Command::new("/proc/self/exe") + .args([ + "incus", + "config", + "device", + "add", + "first", + devname, + "unix-char", + &incuspath, + &hostpath, + "mode=\"666\"", + ]) + .spawn()?; + let output = child.wait_with_output()?; + let stdout = String::from_utf8_lossy(&output.stdout); + let stderr = String::from_utf8_lossy(&output.stderr); + println!("incus\n {}\n{}\n", stdout, stderr); + Ok(()) + } + + async fn remove_device_node( + &self, + _requesting_process: &RequestingProcess, + _devname: &str, + _major: u64, + _minor: u64, + ) -> anyhow::Result<()> { + Ok(()) + } + + async fn write_udev_runtime_data( + &self, + requesting_process: &RequestingProcess, + runtime_data: &str, + major: u64, + minor: u64, + ) -> anyhow::Result<()> { + PLACEMENT_IN_CONTAINER + .write_udev_runtime_data(requesting_process, runtime_data, major, minor) + .await + } + + async fn remove_udev_runtime_data( + &self, + requesting_process: &RequestingProcess, + major: u64, + minor: u64, + ) -> anyhow::Result<()> { + PLACEMENT_IN_CONTAINER + .remove_udev_runtime_data(requesting_process, major, minor) + .await + } +} diff --git a/vuinputd/src/container_runtime/mod.rs b/vuinputd/src/container_runtime/mod.rs index 3d4de8c..43e4497 100644 --- a/vuinputd/src/container_runtime/mod.rs +++ b/vuinputd/src/container_runtime/mod.rs @@ -4,8 +4,7 @@ use crate::{ container_runtime::injection_strategy::{ - GenericPlacementInContainer, GenericPlacementOnHost, GenericSendNetlinkMessageOnly, - InjectionStrategy, PLACEMENT_IN_CONTAINER, PLACEMENT_ON_HOST, SEND_NETLINK_ONLY, + GenericPlacementInContainer, GenericPlacementOnHost, GenericSendNetlinkMessageOnly, INCUS, InjectionStrategy, PLACEMENT_IN_CONTAINER, PLACEMENT_ON_HOST, SEND_NETLINK_ONLY }, global_config::get_vudevname, }; @@ -67,7 +66,7 @@ impl ContainerRuntime { ContainerRuntime::GenericPlacementInContainer => &PLACEMENT_IN_CONTAINER, ContainerRuntime::GenericPlacementOnHost => &PLACEMENT_ON_HOST, ContainerRuntime::GenericSendNetlinkMessageOnly => &SEND_NETLINK_ONLY, - ContainerRuntime::Incus => todo!("not implemented yet"), + ContainerRuntime::Incus => &INCUS, ContainerRuntime::Docker => &PLACEMENT_IN_CONTAINER, ContainerRuntime::Podman => &PLACEMENT_IN_CONTAINER, ContainerRuntime::Nspawn => &PLACEMENT_IN_CONTAINER,