use super::BuildahError;
use super::execute_buildah_command;
use crate::process::CommandResult;
use serde::{Deserialize, Serialize};
use serde_json::{self, Value};
use std::collections::HashMap;
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct Image {
pub id: String,
pub names: Vec<String>,
pub size: String,
pub created: String,
}
pub fn images() -> Result<Vec<Image>, BuildahError> {
let result = execute_buildah_command(&["images", "--json"])?;
match serde_json::from_str::<serde_json::Value>(&result.stdout) {
Ok(json) => {
if let Value::Array(images_json) = json {
let mut images = Vec::new();
for image_json in images_json {
let id = match image_json.get("id").and_then(|v| v.as_str()) {
Some(id) => id.to_string(),
None => {
return Err(BuildahError::ConversionError(
"Missing image ID".to_string(),
))
}
};
let names = match image_json.get("names").and_then(|v| v.as_array()) {
Some(names_array) => {
let mut names_vec = Vec::new();
for name_value in names_array {
if let Some(name_str) = name_value.as_str() {
names_vec.push(name_str.to_string());
}
}
names_vec
}
None => Vec::new(), };
let size = match image_json.get("size").and_then(|v| v.as_str()) {
Some(size) => size.to_string(),
None => "Unknown".to_string(), };
let created = match image_json.get("created").and_then(|v| v.as_str()) {
Some(created) => created.to_string(),
None => "Unknown".to_string(), };
images.push(Image {
id,
names,
size,
created,
});
}
Ok(images)
} else {
Err(BuildahError::JsonParseError(
"Expected JSON array".to_string(),
))
}
}
Err(e) => Err(BuildahError::JsonParseError(format!(
"Failed to parse image list JSON: {}",
e
))),
}
}
pub fn image_remove(image: &str) -> Result<CommandResult, BuildahError> {
execute_buildah_command(&["rmi", image])
}
pub fn image_push(
image: &str,
destination: &str,
tls_verify: bool,
) -> Result<CommandResult, BuildahError> {
let mut args = vec!["push"];
if !tls_verify {
args.push("--tls-verify=false");
}
args.push(image);
args.push(destination);
execute_buildah_command(&args)
}
pub fn image_tag(image: &str, new_name: &str) -> Result<CommandResult, BuildahError> {
execute_buildah_command(&["tag", image, new_name])
}
pub fn image_pull(image: &str, tls_verify: bool) -> Result<CommandResult, BuildahError> {
let mut args = vec!["pull"];
if !tls_verify {
args.push("--tls-verify=false");
}
args.push(image);
execute_buildah_command(&args)
}
pub fn image_commit(
container: &str,
image_name: &str,
format: Option<&str>,
squash: bool,
rm: bool,
) -> Result<CommandResult, BuildahError> {
let mut args = vec!["commit"];
if let Some(format_str) = format {
args.push("--format");
args.push(format_str);
}
if squash {
args.push("--squash");
}
if rm {
args.push("--rm");
}
args.push(container);
args.push(image_name);
execute_buildah_command(&args)
}
pub fn bah_config(
container: &str,
options: HashMap<String, String>,
) -> Result<CommandResult, BuildahError> {
let mut args_owned: Vec<String> = Vec::new();
args_owned.push("config".to_string());
for (key, value) in options.iter() {
let option_name = format!("--{}", key);
args_owned.push(option_name);
args_owned.push(value.clone());
}
args_owned.push(container.to_string());
let args: Vec<&str> = args_owned.iter().map(|s| s.as_str()).collect();
execute_buildah_command(&args)
}