use std::env::{self, VarError};
use std::fs::{self, File};
use std::io::BufReader;
use std::path::PathBuf;
use serde::Deserialize;
use super::constants::{DOCKER_CONFIG_DIR_ENV_VAR, DOCKER_CONTEXTS_METADATA_DIR, DOCKER_DEFAULT_CONFIG_DIR};
use super::util::{encode_sha256_digest, get_home_dir, sha256_digest};
use crate::{DockerError, Result};
#[derive(Deserialize)]
pub struct DockerConfig {
#[serde(rename = "currentContext")]
pub current_context: Option<String>,
#[serde(skip, default)]
pub config_dir: PathBuf,
}
impl DockerConfig {
pub const FILENAME: &str = "config.json";
pub fn new() -> Result<Option<Self>> {
let mut config_dir = Self::get_dir()?;
config_dir.push(DockerConfig::FILENAME);
if !fs::exists(&config_dir).map_err(|e| {
DockerError::from_io_error_with_description(e, || "faild to check if a the Docker config exists".into())
})? {
return Ok(None);
}
let docker_config_file = File::open(&config_dir).map_err(|e| {
DockerError::from_io_error_with_description(e, || "failed to read the Docker config file".into())
})?;
let reader = BufReader::new(docker_config_file);
serde_json::from_reader::<_, DockerConfig>(reader)
.map_err(|e| DockerError::from_serde_error_with_description(e, || "docker config".into()))
.map(|mut config| {
config_dir.pop();
config.config_dir = config_dir;
Some(config)
})
}
pub fn get_current_context_metadata_dir(&self) -> Option<PathBuf> {
let current_context = self.current_context.as_ref()?;
let encoded_current_context_sha256_digest = encode_sha256_digest(sha256_digest(current_context));
let mut context_dir = self.config_dir.to_owned();
context_dir.push(DOCKER_CONTEXTS_METADATA_DIR);
context_dir.push(encoded_current_context_sha256_digest);
Some(context_dir)
}
fn get_dir() -> Result<PathBuf> {
match env::var(DOCKER_CONFIG_DIR_ENV_VAR) {
Ok(config_dir) => Ok(config_dir.into()),
Err(e @ VarError::NotUnicode(_)) => Err(DockerError::from_var_error_with_var_name(
e,
DOCKER_CONFIG_DIR_ENV_VAR.into(),
)),
Err(VarError::NotPresent) => {
let mut home_dir = get_home_dir()?;
home_dir.push(DOCKER_DEFAULT_CONFIG_DIR);
Ok(home_dir)
}
}
}
}