use std::env;
use std::path::{Path, PathBuf};
use crate::apis::configuration::Configuration;
use reqwest::ClientBuilder;
use nix::unistd::access;
use nix::unistd::geteuid;
use nix::unistd::AccessFlags;
pub const UNIX_BASE_PATH: &str = "http://unix.socket";
pub fn unix_socket_configuration() -> reqwest::Result<Configuration> {
let (unix_socket_path,_) = resolve_socket_path(None);
let unix_socket = ClientBuilder::new()
.unix_socket(unix_socket_path)
.connection_verbose(true)
.build()?;
let configuration = Configuration {
base_path: "http://unix.socket".to_string(),
user_agent: None,
client: unix_socket,
basic_auth: None,
oauth_access_token: None,
bearer_access_token: None,
api_key: None,
};
Ok(configuration)
}
pub fn resolve_socket_path(path: Option<&str>) -> (PathBuf, Option<String>) {
if let Some(p) = path.filter(|p| !p.is_empty()) {
return (PathBuf::from(p), None);
}
if let Ok(p) = env::var("INCUS_SOCKET") {
if !p.is_empty() {
return (PathBuf::from(p), None);
}
}
let incus_dir_from_env = env::var("INCUS_DIR");
let incus_dir = if incus_dir_from_env.as_ref().is_ok_and(|d| !d.is_empty()){
PathBuf::from(incus_dir_from_env.unwrap())
} else if Path::new("/run/incus/unix.socket").exists() {
PathBuf::from("/run/incus")
} else {
PathBuf::from("/var/lib/incus")
};
let socket = incus_dir.join("unix.socket");
let user_socket = incus_dir.join("unix.socket.user");
if !is_writable(&socket) && is_writable(&user_socket) {
return (user_socket, Some(format!("user-{}", geteuid())));
}
(socket, None)
}
fn is_writable(path: &Path) -> bool {
access(path, AccessFlags::W_OK).is_ok()
}