mirror of
				https://github.com/kata-containers/kata-containers.git
				synced 2025-10-31 01:13:02 +00:00 
			
		
		
		
	libs/types: add kata-types crate under src/libs
Add kata-types crate to host constants and data types shared by multiple Kata Containers components. Fixes: #3305 Signed-off-by: Liu Jiang <gerry@linux.alibaba.com> Signed-off-by: Fupan Li <lifupan@gmail.com> Signed-off-by: Huamin Tang <huamin.thm@alibaba-inc.com> Signed-off-by: Lei Wang <wllenyj@linux.alibaba.com> Signed-off-by: yanlei <yl.on.the.way@gmail.com>
This commit is contained in:
		
							
								
								
									
										19
									
								
								src/libs/Cargo.lock
									
									
									
										generated
									
									
									
								
							
							
						
						
									
										19
									
								
								src/libs/Cargo.lock
									
									
									
										generated
									
									
									
								
							| @@ -283,6 +283,15 @@ version = "1.0.1" | ||||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||||
| checksum = "1aab8fc367588b89dcee83ab0fd66b72b50b72fa1904d7095045ace2b0c81c35" | ||||
|  | ||||
| [[package]] | ||||
| name = "kata-types" | ||||
| version = "0.1.0" | ||||
| dependencies = [ | ||||
|  "oci", | ||||
|  "serde", | ||||
|  "thiserror", | ||||
| ] | ||||
|  | ||||
| [[package]] | ||||
| name = "lazy_static" | ||||
| version = "1.4.0" | ||||
| @@ -414,6 +423,16 @@ dependencies = [ | ||||
|  "autocfg", | ||||
| ] | ||||
|  | ||||
| [[package]] | ||||
| name = "oci" | ||||
| version = "0.1.0" | ||||
| dependencies = [ | ||||
|  "libc", | ||||
|  "serde", | ||||
|  "serde_derive", | ||||
|  "serde_json", | ||||
| ] | ||||
|  | ||||
| [[package]] | ||||
| name = "once_cell" | ||||
| version = "1.9.0" | ||||
|   | ||||
| @@ -1,7 +1,9 @@ | ||||
| [workspace] | ||||
| members = [ | ||||
|     "logging", | ||||
|     "kata-types", | ||||
|     "safe-path", | ||||
|     "protocols", | ||||
|     "oci", | ||||
| ] | ||||
| resolver = "2" | ||||
|   | ||||
| @@ -5,6 +5,7 @@ or published to [`crates.io`](https://crates.io/index.html). | ||||
| Currently it provides following library crates: | ||||
|  | ||||
| | Library | Description | | ||||
| |-|-|-| | ||||
| | [logging](logging/) | Facilities to setup logging subsystem based slog. | | ||||
| |-|-| | ||||
| | [logging](logging/) | Facilities to setup logging subsystem based on slog. | | ||||
| | [types](kata-types/) | Collection of constants and data types shared by multiple Kata Containers components. | | ||||
| | [safe-path](safe-path/) | Utilities to safely resolve filesystem paths. | | ||||
|   | ||||
							
								
								
									
										19
									
								
								src/libs/kata-types/Cargo.toml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										19
									
								
								src/libs/kata-types/Cargo.toml
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,19 @@ | ||||
| [package] | ||||
| name = "kata-types" | ||||
| version = "0.1.0" | ||||
| description = "Constants and data types shared by Kata Containers components" | ||||
| keywords = ["kata", "container", "runtime"] | ||||
| authors = ["The Kata Containers community <kata-dev@lists.katacontainers.io>"] | ||||
| repository = "https://github.com/kata-containers/kata-containers.git" | ||||
| homepage = "https://katacontainers.io/" | ||||
| readme = "README.md" | ||||
| license = "Apache-2.0" | ||||
| edition = "2018" | ||||
|  | ||||
| [dependencies] | ||||
| serde = { version = "1.0.100", features = ["derive"] } | ||||
| thiserror = "1.0" | ||||
|  | ||||
| oci = { path = "../oci" } | ||||
|  | ||||
| [dev-dependencies] | ||||
							
								
								
									
										18
									
								
								src/libs/kata-types/README.md
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										18
									
								
								src/libs/kata-types/README.md
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,18 @@ | ||||
| # kata-types | ||||
|  | ||||
| This crate is a collection of constants and data types shared by multiple | ||||
| [Kata Containers](https://github.com/kata-containers/kata-containers/) components. | ||||
|  | ||||
| It defines constants and data types used by multiple Kata Containers components. Those constants | ||||
| and data types may be defined by Kata Containers or by other projects/specifications, such as: | ||||
| - [Containerd](https://github.com/containerd/containerd) | ||||
| - [Kubelet](https://github.com/kubernetes/kubelet) | ||||
|  | ||||
| ## Support | ||||
|  | ||||
| **Operating Systems**: | ||||
| - Linux | ||||
|  | ||||
| ## License | ||||
|  | ||||
| This code is licensed under [Apache-2.0](../../../LICENSE). | ||||
							
								
								
									
										13
									
								
								src/libs/kata-types/src/annotations/cri_containerd.rs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										13
									
								
								src/libs/kata-types/src/annotations/cri_containerd.rs
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,13 @@ | ||||
| // Copyright (c) 2019 Alibaba Cloud | ||||
| // Copyright (c) 2019 Ant Group | ||||
| // | ||||
| // SPDX-License-Identifier: Apache-2.0 | ||||
| // | ||||
|  | ||||
| #![allow(missing_docs)] | ||||
|  | ||||
| pub const CONTAINER_TYPE_LABEL_KEY: &str = "io.kubernetes.cri.container-type"; | ||||
| pub const SANDBOX: &str = "sandbox"; | ||||
| pub const CONTAINER: &str = "container"; | ||||
|  | ||||
| pub const SANDBOX_ID_LABEL_KEY: &str = "io.kubernetes.cri.sandbox-id"; | ||||
							
								
								
									
										13
									
								
								src/libs/kata-types/src/annotations/crio.rs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										13
									
								
								src/libs/kata-types/src/annotations/crio.rs
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,13 @@ | ||||
| // Copyright (c) 2019 Alibaba Cloud | ||||
| // Copyright (c) 2019 Ant Group | ||||
| // | ||||
| // SPDX-License-Identifier: Apache-2.0 | ||||
| // | ||||
|  | ||||
| #![allow(missing_docs)] | ||||
|  | ||||
| pub const CONTAINER_TYPE_LABEL_KEY: &str = "io.kubernetes.cri.container-type"; | ||||
| pub const SANDBOX: &str = "sandbox"; | ||||
| pub const CONTAINER: &str = "container"; | ||||
|  | ||||
| pub const SANDBOX_ID_LABEL_KEY: &str = "io.kubernetes.cri-o.SandboxID"; | ||||
							
								
								
									
										13
									
								
								src/libs/kata-types/src/annotations/dockershim.rs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										13
									
								
								src/libs/kata-types/src/annotations/dockershim.rs
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,13 @@ | ||||
| // Copyright (c) 2019 Alibaba Cloud | ||||
| // Copyright (c) 2019 Ant Group | ||||
| // | ||||
| // SPDX-License-Identifier: Apache-2.0 | ||||
| // | ||||
|  | ||||
| #![allow(missing_docs)] | ||||
|  | ||||
| pub const CONTAINER_TYPE_LABEL_KEY: &str = "io.kubernetes.docker.type"; | ||||
| pub const SANDBOX: &str = "podsandbox"; | ||||
| pub const CONTAINER: &str = "container"; | ||||
|  | ||||
| pub const SANDBOX_ID_LABEL_KEY: &str = "io.kubernetes.sandbox.id"; | ||||
							
								
								
									
										14
									
								
								src/libs/kata-types/src/annotations/mod.rs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										14
									
								
								src/libs/kata-types/src/annotations/mod.rs
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,14 @@ | ||||
| // Copyright (c) 2019 Alibaba Cloud | ||||
| // Copyright (c) 2019 Ant Group | ||||
| // | ||||
| // SPDX-License-Identifier: Apache-2.0 | ||||
| // | ||||
|  | ||||
| /// CRI-containerd specific annotations. | ||||
| pub mod cri_containerd; | ||||
|  | ||||
| /// CRI-O specific annotations. | ||||
| pub mod crio; | ||||
|  | ||||
| /// Dockershim specific annotations. | ||||
| pub mod dockershim; | ||||
							
								
								
									
										203
									
								
								src/libs/kata-types/src/container.rs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										203
									
								
								src/libs/kata-types/src/container.rs
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,203 @@ | ||||
| // Copyright (c) 2019-2021 Alibaba Cloud | ||||
| // Copyright (c) 2019-2021 Ant Group | ||||
| // | ||||
| // SPDX-License-Identifier: Apache-2.0 | ||||
| // | ||||
|  | ||||
| use std::fmt::{Display, Formatter}; | ||||
| use std::str::FromStr; | ||||
|  | ||||
| const CONTAINER: &str = "container"; | ||||
| const SANDBOX: &str = "sandbox"; | ||||
| const POD_CONTAINER: &str = "pod_container"; | ||||
| const POD_SANDBOX: &str = "pod_sandbox"; | ||||
| const POD_SANDBOX2: &str = "podsandbox"; | ||||
|  | ||||
| const STATE_READY: &str = "ready"; | ||||
| const STATE_RUNNING: &str = "running"; | ||||
| const STATE_STOPPED: &str = "stopped"; | ||||
| const STATE_PAUSED: &str = "paused"; | ||||
|  | ||||
| /// Error codes for container related operations. | ||||
| #[derive(thiserror::Error, Debug)] | ||||
| pub enum Error { | ||||
|     /// Invalid container type | ||||
|     #[error("Invalid container type {0}")] | ||||
|     InvalidContainerType(String), | ||||
|     /// Invalid container state | ||||
|     #[error("Invalid sandbox state {0}")] | ||||
|     InvalidState(String), | ||||
|     /// Invalid container state transition | ||||
|     #[error("Can not transit from {0} to {1}")] | ||||
|     InvalidStateTransition(State, State), | ||||
| } | ||||
|  | ||||
| /// Types of pod containers: container or sandbox. | ||||
| #[derive(PartialEq, Debug, Clone)] | ||||
| pub enum ContainerType { | ||||
|     /// A pod container. | ||||
|     PodContainer, | ||||
|     /// A pod sandbox. | ||||
|     PodSandbox, | ||||
| } | ||||
|  | ||||
| impl ContainerType { | ||||
|     /// Check whether it's a pod container. | ||||
|     pub fn is_pod_container(&self) -> bool { | ||||
|         matches!(self, ContainerType::PodContainer) | ||||
|     } | ||||
|  | ||||
|     /// Check whether it's a pod container. | ||||
|     pub fn is_pod_sandbox(&self) -> bool { | ||||
|         matches!(self, ContainerType::PodSandbox) | ||||
|     } | ||||
| } | ||||
|  | ||||
| impl Display for ContainerType { | ||||
|     fn fmt(&self, f: &mut Formatter) -> std::fmt::Result { | ||||
|         match self { | ||||
|             ContainerType::PodContainer => write!(f, "{}", POD_CONTAINER), | ||||
|             ContainerType::PodSandbox => write!(f, "{}", POD_SANDBOX), | ||||
|         } | ||||
|     } | ||||
| } | ||||
|  | ||||
| impl FromStr for ContainerType { | ||||
|     type Err = Error; | ||||
|  | ||||
|     fn from_str(value: &str) -> Result<Self, Self::Err> { | ||||
|         match value { | ||||
|             POD_CONTAINER | CONTAINER => Ok(ContainerType::PodContainer), | ||||
|             POD_SANDBOX | POD_SANDBOX2 | SANDBOX => Ok(ContainerType::PodSandbox), | ||||
|             _ => Err(Error::InvalidContainerType(value.to_owned())), | ||||
|         } | ||||
|     } | ||||
| } | ||||
|  | ||||
| /// Process states. | ||||
| #[derive(Clone, Copy, PartialEq, Debug)] | ||||
| pub enum State { | ||||
|     /// The container is ready to run. | ||||
|     Ready, | ||||
|     /// The container executed the user-specified program but has not exited | ||||
|     Running, | ||||
|     /// The container has exited | ||||
|     Stopped, | ||||
|     /// The container has been paused. | ||||
|     Paused, | ||||
| } | ||||
|  | ||||
| impl Display for State { | ||||
|     fn fmt(&self, f: &mut Formatter) -> std::fmt::Result { | ||||
|         match self { | ||||
|             State::Ready => write!(f, "{}", STATE_READY), | ||||
|             State::Running => write!(f, "{}", STATE_RUNNING), | ||||
|             State::Stopped => write!(f, "{}", STATE_STOPPED), | ||||
|             State::Paused => write!(f, "{}", STATE_PAUSED), | ||||
|         } | ||||
|     } | ||||
| } | ||||
|  | ||||
| impl FromStr for State { | ||||
|     type Err = Error; | ||||
|  | ||||
|     fn from_str(value: &str) -> Result<Self, Self::Err> { | ||||
|         match value { | ||||
|             STATE_READY => Ok(State::Ready), | ||||
|             STATE_RUNNING => Ok(State::Running), | ||||
|             STATE_STOPPED => Ok(State::Stopped), | ||||
|             STATE_PAUSED => Ok(State::Paused), | ||||
|             _ => Err(Error::InvalidState(value.to_owned())), | ||||
|         } | ||||
|     } | ||||
| } | ||||
|  | ||||
| impl State { | ||||
|     /// Check whether it's a valid state transition from self to the `new_state`. | ||||
|     pub fn check_transition(self, new_state: State) -> Result<(), Error> { | ||||
|         match self { | ||||
|             State::Ready if new_state == State::Running || new_state == State::Stopped => Ok(()), | ||||
|             State::Running if new_state == State::Stopped => Ok(()), | ||||
|             State::Stopped if new_state == State::Running => Ok(()), | ||||
|             State::Paused if new_state == State::Paused => Ok(()), | ||||
|             _ => Err(Error::InvalidStateTransition(self, new_state)), | ||||
|         } | ||||
|     } | ||||
| } | ||||
|  | ||||
| #[cfg(test)] | ||||
| mod tests { | ||||
|     use super::*; | ||||
|  | ||||
|     #[test] | ||||
|     fn test_container_type() { | ||||
|         assert!(ContainerType::PodContainer.is_pod_container()); | ||||
|         assert!(!ContainerType::PodContainer.is_pod_sandbox()); | ||||
|  | ||||
|         assert!(ContainerType::PodSandbox.is_pod_sandbox()); | ||||
|         assert!(!ContainerType::PodSandbox.is_pod_container()); | ||||
|     } | ||||
|  | ||||
|     #[test] | ||||
|     fn test_container_type_display() { | ||||
|         assert_eq!(format!("{}", ContainerType::PodContainer), POD_CONTAINER); | ||||
|         assert_eq!(format!("{}", ContainerType::PodSandbox), POD_SANDBOX); | ||||
|     } | ||||
|  | ||||
|     #[test] | ||||
|     fn test_container_type_from_str() { | ||||
|         assert_eq!( | ||||
|             ContainerType::from_str("pod_container").unwrap(), | ||||
|             ContainerType::PodContainer | ||||
|         ); | ||||
|         assert_eq!( | ||||
|             ContainerType::from_str("container").unwrap(), | ||||
|             ContainerType::PodContainer | ||||
|         ); | ||||
|         assert_eq!( | ||||
|             ContainerType::from_str("pod_sandbox").unwrap(), | ||||
|             ContainerType::PodSandbox | ||||
|         ); | ||||
|         assert_eq!( | ||||
|             ContainerType::from_str("podsandbox").unwrap(), | ||||
|             ContainerType::PodSandbox | ||||
|         ); | ||||
|         assert_eq!( | ||||
|             ContainerType::from_str("sandbox").unwrap(), | ||||
|             ContainerType::PodSandbox | ||||
|         ); | ||||
|         ContainerType::from_str("test").unwrap_err(); | ||||
|     } | ||||
|  | ||||
|     #[test] | ||||
|     fn test_valid() { | ||||
|         let mut state = State::from_str("invalid_state"); | ||||
|         assert!(state.is_err()); | ||||
|  | ||||
|         state = State::from_str("ready"); | ||||
|         assert!(state.is_ok()); | ||||
|  | ||||
|         state = State::from_str("running"); | ||||
|         assert!(state.is_ok()); | ||||
|  | ||||
|         state = State::from_str("stopped"); | ||||
|         assert!(state.is_ok()); | ||||
|     } | ||||
|  | ||||
|     #[test] | ||||
|     fn test_valid_transition() { | ||||
|         use State::*; | ||||
|  | ||||
|         assert!(Ready.check_transition(Ready).is_err()); | ||||
|         assert!(Ready.check_transition(Running).is_ok()); | ||||
|         assert!(Ready.check_transition(Stopped).is_ok()); | ||||
|  | ||||
|         assert!(Running.check_transition(Ready).is_err()); | ||||
|         assert!(Running.check_transition(Running).is_err()); | ||||
|         assert!(Running.check_transition(Stopped).is_ok()); | ||||
|  | ||||
|         assert!(Stopped.check_transition(Ready).is_err()); | ||||
|         assert!(Stopped.check_transition(Running).is_ok()); | ||||
|         assert!(Stopped.check_transition(Stopped).is_err()); | ||||
|     } | ||||
| } | ||||
							
								
								
									
										102
									
								
								src/libs/kata-types/src/k8s.rs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										102
									
								
								src/libs/kata-types/src/k8s.rs
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,102 @@ | ||||
| // Copyright (c) 2019-2021 Alibaba Cloud | ||||
| // Copyright (c) 2019-2021 Ant Group | ||||
| // | ||||
| // SPDX-License-Identifier: Apache-2.0 | ||||
| // | ||||
|  | ||||
| use std::path::Path; | ||||
|  | ||||
| use crate::annotations; | ||||
| use crate::container::ContainerType; | ||||
| use std::str::FromStr; | ||||
|  | ||||
| // K8S_EMPTY_DIR is the k8s specific path for `empty-dir` volumes | ||||
| const K8S_EMPTY_DIR: &str = "kubernetes.io~empty-dir"; | ||||
|  | ||||
| /// Check whether the path is a K8S empty directory. | ||||
| /// | ||||
| /// For a K8S EmptyDir, Kubernetes mounts | ||||
| /// "/var/lib/kubelet/pods/<id>/volumes/kubernetes.io~empty-dir/<volumeMount name>" | ||||
| /// to "/<mount-point>". | ||||
| pub fn is_empty_dir<P: AsRef<Path>>(path: P) -> bool { | ||||
|     let path = path.as_ref(); | ||||
|  | ||||
|     if let Some(parent) = path.parent() { | ||||
|         if let Some(pname) = parent.file_name() { | ||||
|             if pname == K8S_EMPTY_DIR && parent.parent().is_some() { | ||||
|                 return true; | ||||
|             } | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     false | ||||
| } | ||||
|  | ||||
| /// Get K8S container type from OCI annotations. | ||||
| pub fn container_type(spec: &oci::Spec) -> ContainerType { | ||||
|     // PodSandbox:  "sandbox" (Containerd & CRI-O), "podsandbox" (dockershim) | ||||
|     // PodContainer: "container" (Containerd & CRI-O & dockershim) | ||||
|     for k in [ | ||||
|         annotations::crio::CONTAINER_TYPE_LABEL_KEY, | ||||
|         annotations::cri_containerd::CONTAINER_TYPE_LABEL_KEY, | ||||
|         annotations::dockershim::CONTAINER_TYPE_LABEL_KEY, | ||||
|     ] | ||||
|     .iter() | ||||
|     { | ||||
|         if let Some(v) = spec.annotations.get(k.to_owned()) { | ||||
|             if let Ok(t) = ContainerType::from_str(v) { | ||||
|                 return t; | ||||
|             } | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     ContainerType::PodSandbox | ||||
| } | ||||
|  | ||||
| /// Determine the k8s sandbox ID from OCI annotations. | ||||
| /// | ||||
| /// This function is expected to be called only when the container type is "PodContainer". | ||||
| pub fn sandbox_id(spec: &oci::Spec) -> Result<Option<String>, String> { | ||||
|     if container_type(spec) != ContainerType::PodSandbox { | ||||
|         return Err("Not a sandbox container".to_string()); | ||||
|     } | ||||
|     for k in [ | ||||
|         annotations::crio::SANDBOX_ID_LABEL_KEY, | ||||
|         annotations::cri_containerd::SANDBOX_ID_LABEL_KEY, | ||||
|         annotations::dockershim::SANDBOX_ID_LABEL_KEY, | ||||
|     ] | ||||
|     .iter() | ||||
|     { | ||||
|         if let Some(id) = spec.annotations.get(k.to_owned()) { | ||||
|             return Ok(Some(id.to_string())); | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     Ok(None) | ||||
| } | ||||
|  | ||||
| #[cfg(test)] | ||||
| mod tests { | ||||
|     use super::*; | ||||
|  | ||||
|     #[test] | ||||
|     fn test_is_empty_dir() { | ||||
|         let empty_dir = "/volumes/kubernetes.io~empty-dir/shm"; | ||||
|         assert!(is_empty_dir(empty_dir)); | ||||
|  | ||||
|         let empty_dir = "/volumes/kubernetes.io~empty-dir//shm"; | ||||
|         assert!(is_empty_dir(empty_dir)); | ||||
|  | ||||
|         let empty_dir = "/volumes/kubernetes.io~empty-dir-test/shm"; | ||||
|         assert!(!is_empty_dir(empty_dir)); | ||||
|  | ||||
|         let empty_dir = "/volumes/kubernetes.io~empty-dir"; | ||||
|         assert!(!is_empty_dir(empty_dir)); | ||||
|  | ||||
|         let empty_dir = "kubernetes.io~empty-dir"; | ||||
|         assert!(!is_empty_dir(empty_dir)); | ||||
|  | ||||
|         let empty_dir = "/kubernetes.io~empty-dir/shm"; | ||||
|         assert!(is_empty_dir(empty_dir)); | ||||
|     } | ||||
| } | ||||
							
								
								
									
										20
									
								
								src/libs/kata-types/src/lib.rs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										20
									
								
								src/libs/kata-types/src/lib.rs
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,20 @@ | ||||
| // Copyright (c) 2021 Alibaba Cloud | ||||
| // | ||||
| // SPDX-License-Identifier: Apache-2.0 | ||||
| // | ||||
|  | ||||
| //! Constants and Data Types shared by Kata Containers components. | ||||
|  | ||||
| #[deny(missing_docs)] | ||||
|  | ||||
| /// Constants and data types annotations. | ||||
| pub mod annotations; | ||||
|  | ||||
| /// Constants and data types related to container. | ||||
| pub mod container; | ||||
|  | ||||
| /// Constants and data types related to Kubernetes/kubelet. | ||||
| pub mod k8s; | ||||
|  | ||||
| /// Constants and data types related to mount point. | ||||
| pub mod mount; | ||||
							
								
								
									
										88
									
								
								src/libs/kata-types/src/mount.rs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										88
									
								
								src/libs/kata-types/src/mount.rs
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,88 @@ | ||||
| // Copyright (c) 2019-2021 Alibaba Cloud | ||||
| // Copyright (c) 2019-2021 Ant Group | ||||
| // | ||||
| // SPDX-License-Identifier: Apache-2.0 | ||||
| // | ||||
|  | ||||
| use std::path::PathBuf; | ||||
|  | ||||
| /// Prefix to mark a volume as Kata special. | ||||
| pub const KATA_VOLUME_TYPE_PREFIX: &str = "kata:"; | ||||
|  | ||||
| /// The Mount should be ignored by the host and handled by the guest. | ||||
| pub const KATA_GUEST_MOUNT_PREFIX: &str = "kata:guest-mount:"; | ||||
|  | ||||
| /// KATA_EPHEMERAL_DEV_TYPE creates a tmpfs backed volume for sharing files between containers. | ||||
| pub const KATA_EPHEMERAL_VOLUME_TYPE: &str = "kata:ephemeral"; | ||||
|  | ||||
| /// KATA_HOST_DIR_TYPE use for host empty dir | ||||
| pub const KATA_HOST_DIR_VOLUME_TYPE: &str = "kata:hostdir"; | ||||
|  | ||||
| /// Information about a mount. | ||||
| #[derive(Debug, Clone, Default, serde::Serialize, serde::Deserialize)] | ||||
| pub struct Mount { | ||||
|     /// A device name, but can also be a file or directory name for bind mounts or a dummy. | ||||
|     /// Path values for bind mounts are either absolute or relative to the bundle. A mount is a | ||||
|     /// bind mount if it has either bind or rbind in the options. | ||||
|     pub source: String, | ||||
|     /// Destination of mount point: path inside container. This value MUST be an absolute path. | ||||
|     pub destination: PathBuf, | ||||
|     /// The type of filesystem for the mountpoint. | ||||
|     pub fs_type: String, | ||||
|     /// Mount options for the mountpoint. | ||||
|     pub options: Vec<String>, | ||||
|     /// Optional device id for the block device when: | ||||
|     /// - the source is a block device or a mountpoint for a block device | ||||
|     /// - block device direct assignment is enabled | ||||
|     pub device_id: Option<String>, | ||||
|     /// Intermediate path to mount the source on host side and then passthrough to vm by shared fs. | ||||
|     pub host_shared_fs_path: Option<PathBuf>, | ||||
|     /// Whether to mount the mountpoint in readonly mode | ||||
|     pub read_only: bool, | ||||
| } | ||||
|  | ||||
| impl Mount { | ||||
|     /// Get size of mount options. | ||||
|     pub fn option_size(&self) -> usize { | ||||
|         self.options.iter().map(|v| v.len() + 1).sum() | ||||
|     } | ||||
| } | ||||
|  | ||||
| /// Check whether a mount type is a marker for Kata specific volume. | ||||
| pub fn is_kata_special_volume(ty: &str) -> bool { | ||||
|     ty.len() > KATA_VOLUME_TYPE_PREFIX.len() && ty.starts_with(KATA_VOLUME_TYPE_PREFIX) | ||||
| } | ||||
|  | ||||
| /// Check whether a mount type is a marker for Kata guest mount volume. | ||||
| pub fn is_kata_guest_mount_volume(ty: &str) -> bool { | ||||
|     ty.len() > KATA_GUEST_MOUNT_PREFIX.len() && ty.starts_with(KATA_GUEST_MOUNT_PREFIX) | ||||
| } | ||||
|  | ||||
| /// Check whether a mount type is a marker for Kata ephemeral volume. | ||||
| pub fn is_kata_ephemeral_volume(ty: &str) -> bool { | ||||
|     ty == KATA_EPHEMERAL_VOLUME_TYPE | ||||
| } | ||||
|  | ||||
| /// Check whether a mount type is a marker for Kata hostdir volume. | ||||
| pub fn is_kata_host_dir_volume(ty: &str) -> bool { | ||||
|     ty == KATA_HOST_DIR_VOLUME_TYPE | ||||
| } | ||||
|  | ||||
| #[cfg(test)] | ||||
| mod tests { | ||||
|     use super::*; | ||||
|  | ||||
|     #[test] | ||||
|     fn test_is_kata_special_volume() { | ||||
|         assert!(is_kata_special_volume("kata:guest-mount:nfs")); | ||||
|         assert!(!is_kata_special_volume("kata:")); | ||||
|     } | ||||
|  | ||||
|     #[test] | ||||
|     fn test_is_kata_guest_mount_volume() { | ||||
|         assert!(is_kata_guest_mount_volume("kata:guest-mount:nfs")); | ||||
|         assert!(!is_kata_guest_mount_volume("kata:guest-mount")); | ||||
|         assert!(!is_kata_guest_mount_volume("kata:guest-moun")); | ||||
|         assert!(!is_kata_guest_mount_volume("Kata:guest-mount:nfs")); | ||||
|     } | ||||
| } | ||||
		Reference in New Issue
	
	Block a user