mirror of
https://github.com/kata-containers/kata-containers.git
synced 2025-04-30 04:34:27 +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:
parent
4f62a7618c
commit
5b89c1df2f
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"));
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user