-
Notifications
You must be signed in to change notification settings - Fork 109
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add support for Docker runtime (#96)
* add support for docker runtime
- Loading branch information
1 parent
26c0dc7
commit e780e2e
Showing
10 changed files
with
215 additions
and
59 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,68 +1,65 @@ | ||
use std::{ | ||
fs::File, | ||
os::unix::io::{IntoRawFd, RawFd}, | ||
path::PathBuf, | ||
}; | ||
|
||
use anyhow::{anyhow, Result}; | ||
use bollard::{container::InspectContainerOptions, Docker}; | ||
use containerd_client::{ | ||
connect, | ||
services::v1::{containers_client::ContainersClient, GetContainerRequest}, | ||
services::v1::{tasks_client::TasksClient, GetRequest}, | ||
tonic::Request, | ||
with_namespace, | ||
}; | ||
use nix::sched::setns; | ||
use serde::{Deserialize, Serialize}; | ||
|
||
const CONTAINERD_SOCK_PATH: &str = "/run/containerd/containerd.sock"; | ||
const DEFAULT_CONTAINERD_NAMESPACE: &str = "k8s.io"; | ||
|
||
#[derive(Serialize, Deserialize, Debug)] | ||
struct Namespace { | ||
#[serde(rename = "type")] | ||
ns_type: String, | ||
path: Option<String>, | ||
pub async fn get_container_pid(container_id: &str, container_runtime: &str) -> Result<u64> { | ||
match container_runtime { | ||
"docker" => get_docker_container_pid(container_id.to_string()).await, | ||
"containerd" => get_containerd_container_pid(container_id.to_string()).await, | ||
_ => Err(anyhow!("Unsupported runtime: {}", container_runtime)), | ||
} | ||
} | ||
|
||
#[derive(Serialize, Deserialize, Debug)] | ||
struct LinuxInfo { | ||
namespaces: Vec<Namespace>, | ||
async fn get_docker_container_pid(container_id: String) -> Result<u64> { | ||
let client = Docker::connect_with_local_defaults()?; | ||
let inspect_options = Some(InspectContainerOptions { size: false }); | ||
let inspect_response = client | ||
.inspect_container(&container_id, inspect_options) | ||
.await?; | ||
|
||
let pid = inspect_response | ||
.state | ||
.and_then(|state| state.pid) | ||
.and_then(|pid| if pid > 0 { Some(pid as u64) } else { None }) | ||
.ok_or_else(|| anyhow!("No pid found"))?; | ||
Ok(pid) | ||
} | ||
|
||
#[derive(Serialize, Deserialize, Debug)] | ||
struct Spec { | ||
linux: LinuxInfo, | ||
async fn get_containerd_container_pid(container_id: String) -> Result<u64> { | ||
let channel = connect(CONTAINERD_SOCK_PATH).await?; | ||
let mut client = TasksClient::new(channel); | ||
let request = GetRequest { | ||
container_id, | ||
..Default::default() | ||
}; | ||
let request = with_namespace!(request, DEFAULT_CONTAINERD_NAMESPACE); | ||
let response = client.get(request).await?; | ||
let pid = response | ||
.into_inner() | ||
.process | ||
.ok_or_else(|| anyhow!("No pid found"))? | ||
.pid; | ||
|
||
Ok(pid as u64) | ||
} | ||
|
||
pub fn set_namespace(ns_path: &str) -> Result<()> { | ||
pub fn set_namespace(ns_path: PathBuf) -> Result<()> { | ||
let fd: RawFd = File::open(ns_path)?.into_raw_fd(); | ||
setns(fd, nix::sched::CloneFlags::CLONE_NEWNET)?; | ||
Ok(()) | ||
} | ||
|
||
pub async fn get_container_namespace(container_id: String) -> Result<String> { | ||
let channel = connect(CONTAINERD_SOCK_PATH).await?; | ||
let mut client = ContainersClient::new(channel); | ||
let request = GetContainerRequest { id: container_id }; | ||
let request = with_namespace!(request, DEFAULT_CONTAINERD_NAMESPACE); | ||
let resp = client.get(request).await?; | ||
let resp = resp.into_inner(); | ||
let container = resp | ||
.container | ||
.ok_or_else(|| anyhow!("container not found"))?; | ||
let spec: Spec = serde_json::from_slice( | ||
&container | ||
.spec | ||
.ok_or_else(|| anyhow!("invalid data from containerd"))? | ||
.value, | ||
)?; | ||
let ns_path = spec | ||
.linux | ||
.namespaces | ||
.iter() | ||
.find(|ns| ns.ns_type == "network") | ||
.ok_or_else(|| anyhow!("network namespace not found"))? | ||
.path | ||
.as_ref() | ||
.ok_or_else(|| anyhow!("no network namespace path"))?; | ||
Ok(ns_path.to_owned()) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.