use std::fs;
use std::os::unix::fs as unix_fs;
use std::path::Path;
use arcbox_helper::validate::SocketTarget;
const DOCKER_SOCK: &str = arcbox_constants::paths::privileged::DOCKER_SOCKET;
pub fn link(target: &SocketTarget) -> Result<(), String> {
let target_path = Path::new(target.as_str());
let link_path = Path::new(DOCKER_SOCK);
match fs::symlink_metadata(link_path) {
Ok(meta) if meta.file_type().is_symlink() => {
let existing = fs::read_link(link_path)
.map_err(|e| format!("failed to read symlink {DOCKER_SOCK}: {e}"))?;
if existing == target_path {
return Ok(());
}
fs::remove_file(link_path)
.map_err(|e| format!("failed to remove existing {DOCKER_SOCK}: {e}"))?;
}
Ok(_) => {
return Err(format!(
"{DOCKER_SOCK} exists but is not a symlink \
(is Docker Desktop running? stop it first)"
));
}
Err(e) if e.kind() == std::io::ErrorKind::NotFound => {}
Err(e) => {
return Err(format!("failed to stat {DOCKER_SOCK}: {e}"));
}
}
unix_fs::symlink(target_path, link_path)
.map_err(|e| format!("failed to create symlink {DOCKER_SOCK} -> {target}: {e}"))
}
pub fn unlink() -> Result<(), String> {
let link_path = Path::new(DOCKER_SOCK);
match fs::symlink_metadata(link_path) {
Ok(meta) if meta.file_type().is_symlink() => {
fs::remove_file(link_path).map_err(|e| format!("failed to remove {DOCKER_SOCK}: {e}"))
}
Ok(_) => Err(format!(
"{DOCKER_SOCK} exists but is not a symlink (owned by another Docker daemon?)"
)),
Err(e) if e.kind() == std::io::ErrorKind::NotFound => Ok(()),
Err(e) => Err(format!("failed to stat {DOCKER_SOCK}: {e}")),
}
}