use std::collections::HashMap;
use tokio::io::{AsyncRead, AsyncSeek};
use tokio::sync::RwLock;
use tracing::{debug, error, info};
use crate::container::{
ContainerKey, ContainerMapByName, Handle as ContainerHandle, HandleMap as ContainerHandleMap,
};
use crate::handle::StopHandler;
use crate::log::{HandleFactory, Sender};
use crate::pod::Pod;
use crate::provider::ProviderError;
use crate::volume::Ref;
pub struct Handle<H, F> {
container_handles: RwLock<ContainerHandleMap<H, F>>,
pod: Pod,
_volumes: HashMap<String, Ref>,
}
impl<H, F> std::fmt::Debug for Handle<H, F> {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
f.debug_struct("Handle")
.field("pod", &self.pod.name())
.finish()
}
}
impl<H: StopHandler, F> Handle<H, F> {
pub fn new(
container_handles: ContainerHandleMap<H, F>,
pod: Pod,
volumes: Option<HashMap<String, Ref>>,
) -> Self {
Self {
container_handles: RwLock::new(container_handles),
pod,
_volumes: volumes.unwrap_or_default(),
}
}
pub async fn insert_container_handle(&self, key: ContainerKey, value: ContainerHandle<H, F>) {
let mut map = self.container_handles.write().await;
map.insert(key, value);
}
pub async fn output<R>(&self, container_name: &str, sender: Sender) -> anyhow::Result<()>
where
R: AsyncRead + AsyncSeek + Unpin + Send + 'static,
F: HandleFactory<R>,
{
let mut handles = self.container_handles.write().await;
let handle = handles
.get_mut_by_name(container_name.to_owned())
.ok_or_else(|| ProviderError::ContainerNotFound {
pod_name: self.pod.name().to_owned(),
container_name: container_name.to_owned(),
})?;
handle.output(sender).await
}
pub async fn stop(&self) -> anyhow::Result<()> {
{
let mut handles = self.container_handles.write().await;
for (key, handle) in handles.iter_mut() {
info!("Stopping container: {}", key);
match handle.stop().await {
Ok(_) => debug!("Successfully stopped container {}", key),
Err(e) => error!("Error while trying to stop pod {}: {:?}", key, e),
}
}
}
Ok(())
}
pub async fn wait(&mut self) -> anyhow::Result<()> {
let mut handles = self.container_handles.write().await;
for (_, handle) in handles.iter_mut() {
handle.wait().await?;
}
Ok(())
}
}
#[deprecated(
since = "0.6.0",
note = "Please use the new kubelet::pod::PodKey type. This function will be removed in 0.7"
)]
pub fn key_from_pod(pod: &Pod) -> String {
#[allow(deprecated)]
pod_key(pod.namespace(), pod.name())
}
#[deprecated(
since = "0.6.0",
note = "Please use the new kubelet::pod::PodKey type. This function will be removed in 0.7"
)]
pub fn pod_key<N: AsRef<str>, T: AsRef<str>>(namespace: N, pod_name: T) -> String {
format!("{}:{}", namespace.as_ref(), pod_name.as_ref())
}