mirror of
				https://github.com/kata-containers/kata-containers.git
				synced 2025-10-31 09:26:52 +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" | source = "registry+https://github.com/rust-lang/crates.io-index" | ||||||
| checksum = "1aab8fc367588b89dcee83ab0fd66b72b50b72fa1904d7095045ace2b0c81c35" | checksum = "1aab8fc367588b89dcee83ab0fd66b72b50b72fa1904d7095045ace2b0c81c35" | ||||||
|  |  | ||||||
|  | [[package]] | ||||||
|  | name = "kata-types" | ||||||
|  | version = "0.1.0" | ||||||
|  | dependencies = [ | ||||||
|  |  "oci", | ||||||
|  |  "serde", | ||||||
|  |  "thiserror", | ||||||
|  | ] | ||||||
|  |  | ||||||
| [[package]] | [[package]] | ||||||
| name = "lazy_static" | name = "lazy_static" | ||||||
| version = "1.4.0" | version = "1.4.0" | ||||||
| @@ -414,6 +423,16 @@ dependencies = [ | |||||||
|  "autocfg", |  "autocfg", | ||||||
| ] | ] | ||||||
|  |  | ||||||
|  | [[package]] | ||||||
|  | name = "oci" | ||||||
|  | version = "0.1.0" | ||||||
|  | dependencies = [ | ||||||
|  |  "libc", | ||||||
|  |  "serde", | ||||||
|  |  "serde_derive", | ||||||
|  |  "serde_json", | ||||||
|  | ] | ||||||
|  |  | ||||||
| [[package]] | [[package]] | ||||||
| name = "once_cell" | name = "once_cell" | ||||||
| version = "1.9.0" | version = "1.9.0" | ||||||
|   | |||||||
| @@ -1,7 +1,9 @@ | |||||||
| [workspace] | [workspace] | ||||||
| members = [ | members = [ | ||||||
|     "logging", |     "logging", | ||||||
|  |     "kata-types", | ||||||
|     "safe-path", |     "safe-path", | ||||||
|     "protocols", |     "protocols", | ||||||
|  |     "oci", | ||||||
| ] | ] | ||||||
| resolver = "2" | resolver = "2" | ||||||
|   | |||||||
| @@ -5,6 +5,7 @@ or published to [`crates.io`](https://crates.io/index.html). | |||||||
| Currently it provides following library crates: | Currently it provides following library crates: | ||||||
|  |  | ||||||
| | Library | Description | | | 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. | | | [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