#![allow(dead_code, unused_imports)]
use std::env;
use std::path::PathBuf;
pub use futures_util::{StreamExt, TryStreamExt};
pub use podman_api::{api, conn, models, opts, Podman};
pub use tempdir::TempDir;
pub const DEFAULT_IMAGE: &str = "ubuntu:latest";
pub const DEFAULT_CMD: &str = "sleep inf";
pub const DEFAULT_CMD_ARRAY: &[&str] = &["sleep", "inf"];
pub const TEST_IMAGE_PATH: &str = "/var/test123";
const URI_ENV_VAR: &str = "PODMAN_API_URI";
pub fn init_runtime() -> Podman {
let _ = env_logger::try_init();
if let Ok(uri) = env::var(URI_ENV_VAR) {
Podman::new(uri).unwrap()
} else {
#[cfg(unix)]
{
let uid = nix::unistd::Uid::effective();
let podman_dir = PathBuf::from(format!("/run/user/{uid}/podman"));
let podman_root_dir = PathBuf::from("/run/podman");
if podman_dir.exists() {
Podman::unix(podman_dir.join("podman.sock"))
} else if podman_root_dir.exists() {
Podman::unix(podman_root_dir.join("podman.sock"))
} else {
panic!(
"Podman socket not found. Tried {URI_ENV_VAR} env variable, {} and {}",
podman_dir.display(),
podman_root_dir.display()
);
}
}
#[cfg(not(unix))]
{
panic!("Podman socket not found. Try setting the {URI_ENV_VAR} env variable",);
}
}
}
pub async fn create_base_container(
podman: &Podman,
name: &str,
opts: Option<opts::ContainerCreateOpts>,
) -> api::Container {
cleanup_container(podman, name).await;
let opts = opts.unwrap_or_else(|| {
opts::ContainerCreateOpts::builder()
.name(name)
.image(DEFAULT_IMAGE)
.command(DEFAULT_CMD_ARRAY)
.build()
});
podman
.containers()
.create(&opts)
.await
.expect("created base container");
podman.containers().get(name)
}
pub async fn cleanup_container(podman: &Podman, name: &str) {
let _ = podman.containers().get(name).remove().await;
}
pub async fn get_container_full_id(podman: &Podman, name: &str) -> String {
podman
.containers()
.get(name)
.inspect()
.await
.map(|data| data.id)
.expect("container inspect data")
.expect("container full id")
}
pub fn tempdir_with_dockerfile(name: &str, content: Option<&str>) -> TempDir {
let tmp = TempDir::new(name).expect("temp dir for image");
let default_dockerfile = format!(
"FROM {DEFAULT_IMAGE}\nRUN echo 1234 > {TEST_IMAGE_PATH}\nRUN echo 321\nCMD sleep inf",
);
std::fs::write(
tmp.path().join("Dockerfile"),
content.unwrap_or(default_dockerfile.as_str()),
)
.expect("saved Dockerfile");
tmp
}
pub async fn create_base_image(
podman: &Podman,
tag: &str,
opts: Option<opts::ImageBuildOpts>,
) -> api::Image {
let images = podman.images();
let _ = images.get(tag).remove().await;
let tmp = tempdir_with_dockerfile(tag, None);
let opts = opts.unwrap_or_else(|| {
opts::ImageBuildOpts::builder(tmp.path().to_string_lossy())
.tag(tag)
.build()
});
let mut image_stream = images.build(&opts).expect("image build stream");
let mut last = None;
while let Some(chunk) = image_stream.next().await {
assert!(chunk.is_ok());
last = Some(chunk);
}
podman
.images()
.get(last.unwrap().unwrap().stream.trim_end().to_string())
}
pub async fn get_image_full_id(podman: &Podman, name: &str) -> String {
podman
.images()
.get(name)
.inspect()
.await
.map(|data| data.id)
.expect("image inspect data")
.expect("image full id")
}
pub async fn create_base_volume(
podman: &Podman,
name: &str,
opts: Option<opts::VolumeCreateOpts>,
) -> api::Volume {
cleanup_volume(podman, name).await;
let opts = opts.unwrap_or_else(|| opts::VolumeCreateOpts::builder().name(name).build());
podman
.volumes()
.create(&opts)
.await
.expect("created base volume");
podman.volumes().get(name)
}
pub async fn cleanup_volume(podman: &Podman, name: &str) {
let _ = podman.volumes().get(name).remove().await;
}
pub async fn create_base_network(
podman: &Podman,
name: &str,
opts: Option<opts::NetworkCreateOpts>,
) -> api::Network {
cleanup_network(podman, name).await;
let opts = opts.unwrap_or_else(|| opts::NetworkCreateOpts::builder().name(name).build());
podman
.networks()
.create(&opts)
.await
.expect("created base network");
podman.networks().get(name)
}
pub async fn cleanup_network(podman: &Podman, name: &str) {
let _ = podman.networks().get(name).remove().await;
}