1
0
Fork 0
mirror of https://codeberg.org/icewind/haze.git synced 2026-06-03 17:14:08 +02:00

allow pinning instances

This commit is contained in:
Robin Appelman 2022-07-21 14:46:39 +02:00
commit 81695aee4b
6 changed files with 93 additions and 14 deletions

View file

@ -54,6 +54,12 @@ pub enum HazeArgs {
options: CloudOptions,
command: Vec<String>,
},
Pin {
filter: Option<String>,
},
Unpin {
filter: Option<String>,
},
}
#[derive(Debug, Clone, Eq, PartialEq)]
@ -202,6 +208,8 @@ impl HazeArgs {
let command = args.map(S::into).collect();
Ok(HazeArgs::Shell { options, command })
}
HazeCommand::Pin => Ok(HazeArgs::Pin { filter }),
HazeCommand::Unpin => Ok(HazeArgs::Unpin { filter }),
}
}
}
@ -221,6 +229,8 @@ pub enum HazeCommand {
Fmt,
Integration,
Shell,
Pin,
Unpin,
}
impl FromStr for HazeCommand {
@ -242,6 +252,8 @@ impl FromStr for HazeCommand {
"format" => Ok(HazeCommand::Fmt),
"integration" => Ok(HazeCommand::Integration),
"shell" => Ok(HazeCommand::Shell),
"pin" => Ok(HazeCommand::Pin),
"unpin" => Ok(HazeCommand::Unpin),
_ => Err(Report::msg(format!("Unknown command: {}", s))),
}
}
@ -263,6 +275,8 @@ impl HazeCommand {
HazeCommand::Fmt => false,
HazeCommand::Integration => false,
HazeCommand::Shell => false,
HazeCommand::Pin => true,
HazeCommand::Unpin => true,
}
}
}

View file

@ -2,10 +2,10 @@ use crate::config::{HazeConfig, HazeVolumeConfig};
use crate::database::Database;
use crate::exec::{exec, exec_tty, ExitCode};
use crate::mapping::{default_mappings, Mapping};
use crate::php::PhpVersion;
use crate::php::{PhpVersion, PHP_MEMORY_LIMIT};
use crate::service::Service;
use crate::service::ServiceTrait;
use bollard::container::{ListContainersOptions, RemoveContainerOptions};
use bollard::container::{ListContainersOptions, RemoveContainerOptions, UpdateContainerOptions};
use bollard::models::ContainerState;
use bollard::network::CreateNetworkOptions;
use bollard::Docker;
@ -157,6 +157,7 @@ pub struct Cloud {
pub ip: Option<IpAddr>,
pub workdir: Utf8PathBuf,
pub services: Vec<Service>,
pub pinned: bool,
}
impl Cloud {
@ -167,6 +168,7 @@ impl Cloud {
) -> Result<Self> {
let id = options
.name
.map(|name| format!("haze-{}", name))
.unwrap_or_else(|| format!("haze-{}", petname(2, "-")));
let workdir = config.work_dir.join(&id);
@ -380,6 +382,7 @@ impl Cloud {
ip: Some(ip),
workdir,
services: options.services,
pinned: false,
})
}
@ -459,7 +462,7 @@ impl Cloud {
}))
.await
.into_diagnostic()?;
let mut containers_by_id: HashMap<String, (Option<_>, Vec<_>)> = HashMap::new();
let mut containers_by_id: HashMap<String, (Option<_>, Option<_>, Vec<_>)> = HashMap::new();
for container in containers {
let labels = container.labels.clone().unwrap_or_default();
if let Some(cloud_id) = labels.get("haze-cloud-id") {
@ -469,9 +472,11 @@ impl Cloud {
} {
let mut entry = containers_by_id.entry(cloud_id.to_string()).or_default();
if labels.get("haze-type").map(String::as_str) == Some("cloud") {
let info = docker.inspect_container(cloud_id, None).await.ok();
entry.0 = Some(container);
entry.1 = info;
} else {
entry.1.push(container)
entry.2.push(container)
}
}
}
@ -479,7 +484,7 @@ impl Cloud {
let mut sortable_containers: Vec<_> = containers_by_id
.into_iter()
.filter_map(|(id, (cloud, services))| {
.filter_map(|(id, (cloud, info, services))| {
let cloud = cloud?;
let network = id.clone();
let networks = cloud.network_settings?.networks?;
@ -501,6 +506,14 @@ impl Cloud {
.iter()
.filter_map(|service| service.names.as_ref()?.first().map(String::clone))
.collect();
let pinned = (info
.and_then(|info| info.host_config)
.and_then(|host| host.memory)
.unwrap()
% 2)
== 1;
service_ids.push(id.clone());
Some((
cloud.created.unwrap_or_default(),
@ -513,6 +526,7 @@ impl Cloud {
ip: network_info.ip_address.as_ref()?.parse().ok(),
workdir,
services: found_services,
pinned,
},
))
})
@ -571,4 +585,32 @@ impl Cloud {
.await?;
Ok(())
}
pub async fn pin(&self, docker: &mut Docker) -> Result<()> {
// abuse memory limits as editable label
docker
.update_container(
&self.id,
UpdateContainerOptions::<String> {
memory: Some(PHP_MEMORY_LIMIT + 1),
..UpdateContainerOptions::default()
},
)
.await
.into_diagnostic()
}
pub async fn unpin(&self, docker: &mut Docker) -> Result<()> {
// abuse memory limits as editable label
docker
.update_container(
&self.id,
UpdateContainerOptions::<String> {
memory: Some(PHP_MEMORY_LIMIT),
..UpdateContainerOptions::default()
},
)
.await
.into_diagnostic()
}
}

View file

@ -35,7 +35,7 @@ async fn main() -> Result<()> {
match args {
HazeArgs::Clean => {
let list = Cloud::list(&mut docker, None, &config).await?;
for cloud in list {
for cloud in list.into_iter().filter(|cloud| !cloud.pinned) {
if let Err(e) = cloud.destroy(&mut docker).await {
eprintln!("Error while removing cloud: {:#}", e);
}
@ -48,17 +48,20 @@ async fn main() -> Result<()> {
let mut services: Vec<_> = cloud.services.iter().map(Service::name).collect();
services.push(cloud.db.name());
let services = services.join(", ");
let pin = if cloud.pinned { "*" } else { "" };
match cloud.ip {
Some(ip) => println!(
"Cloud {}, {}, {}, running on http://{}",
"Cloud {}{}, {}, {}, running on http://{}",
cloud.id,
pin,
cloud.php.name(),
services,
ip
),
None => println!(
"Cloud {}, {}, {}, not running",
"Cloud {}{}, {}, {}, not running",
cloud.id,
pin,
cloud.php.name(),
services
),
@ -283,6 +286,14 @@ async fn main() -> Result<()> {
.await?;
cloud.destroy(&mut docker).await?;
}
HazeArgs::Pin { filter } => {
let cloud = Cloud::get_by_filter(&mut docker, filter, &config).await?;
cloud.pin(&mut docker).await?;
}
HazeArgs::Unpin { filter } => {
let cloud = Cloud::get_by_filter(&mut docker, filter, &config).await?;
cloud.unpin(&mut docker).await?;
}
};
Ok(())

View file

@ -11,11 +11,7 @@ pub async fn clear_networks(docker: &Docker) -> Result<()> {
for network in networks {
match network.name.as_deref() {
Some(name) if name.starts_with("haze-") => {
docker
.remove_network(name)
.await
.into_diagnostic()
.wrap_err("Failed to remove docker network")?;
docker.remove_network(name).await.ok();
}
_ => {}
}

View file

@ -26,6 +26,8 @@ pub enum PhpVersion {
Php73Dbg,
}
pub const PHP_MEMORY_LIMIT: i64 = 2 * 1024 * 1024 * 1024;
impl FromStr for PhpVersion {
type Err = ();
@ -98,7 +100,7 @@ impl PhpVersion {
network_mode: Some(network.to_string()),
binds: Some(volumes),
extra_hosts: Some(vec![format!("hazehost:{}", host)]),
memory: Some(2 * 1024 * 1024 * 1024),
memory: Some(PHP_MEMORY_LIMIT),
nano_cpus: Some(2_000_000_000),
..Default::default()
}),