use crate::config::Config;
use crate::utils::wait_for_http_service;
use docker_api::api::ContainerCreateOpts;
use docker_api::api::ContainerDetails;
use docker_api::volume::VolumeCreateOpts;
use docker_api::Docker;
use http::uri::Authority;
use unidecode::unidecode;
pub fn transliterate(s: impl AsRef<str>) -> String {
unidecode(s.as_ref())
.chars()
.map(|c| match c {
'@' => '_',
c => c,
})
.filter(|&c| c.is_alphanumeric() || "_.-".contains(c))
.collect()
}
fn get_host_port(details: &ContainerDetails) -> String {
details
.network_settings
.ports
.clone() .unwrap()
.get("3000/tcp")
.unwrap()
.as_ref()
.unwrap()[0]
.host_port
.clone() }
pub async fn start_rcs(email: &str, config: &Config) -> Authority {
let email = transliterate(email);
let docker = Docker::new(&config.socket_path).unwrap();
let volumes = docker.volumes();
let volume = volumes.get(&email);
let volume_opts = VolumeCreateOpts::builder().name(&email).build();
if volume.inspect().await.is_err() {
volumes.create(&volume_opts).await.unwrap();
println!("created volume {}", &email);
}
let containers = docker.containers();
let container = containers.get(&email);
let inspect = container.inspect().await;
let authority = if let Ok(details) = inspect {
let port = get_host_port(&details);
Authority::try_from(format!("127.0.0.1:{}", port)).unwrap()
} else {
let opts = ContainerCreateOpts::builder(&config.rcs_image)
.name(&email)
.publish_all_ports()
.volumes([format!("{}:/home/workspace", &email)])
.build();
let ctr = containers.create(&opts).await.unwrap();
println!("created container {}", &email);
ctr.start().await.unwrap();
let details = ctr.inspect().await.unwrap();
let port = get_host_port(&details);
Authority::try_from(format!("127.0.0.1:{}", port)).unwrap()
};
wait_for_http_service(authority.clone()).await;
authority
}