mirror of
https://codeberg.org/icewind/haze.git
synced 2026-06-03 09:04:12 +02:00
default proxy to last
This commit is contained in:
parent
6f78480b48
commit
7910b9d034
2 changed files with 55 additions and 9 deletions
|
|
@ -6,7 +6,6 @@ use crate::config::HazeConfig;
|
|||
use crate::exec::container_logs;
|
||||
use crate::git::checkout_all;
|
||||
use crate::network::clear_networks;
|
||||
use crate::php::PhpVersion;
|
||||
use crate::proxy::proxy;
|
||||
use crate::service::Service;
|
||||
use crate::service::ServiceTrait;
|
||||
|
|
|
|||
63
src/proxy.rs
63
src/proxy.rs
|
|
@ -11,9 +11,13 @@ use std::os::unix::fs::PermissionsExt;
|
|||
use std::path::PathBuf;
|
||||
use std::str::FromStr;
|
||||
use std::sync::{Arc, Mutex};
|
||||
use std::time::Duration;
|
||||
use tokio::net::UnixListener;
|
||||
use tokio::signal::ctrl_c;
|
||||
use tokio::spawn;
|
||||
use tokio::time::sleep;
|
||||
use tokio_stream::wrappers::UnixListenerStream;
|
||||
use tracing::info;
|
||||
use warp::host::Authority;
|
||||
use warp::http::{HeaderMap, HeaderValue, Method};
|
||||
use warp::hyper::body::Bytes;
|
||||
|
|
@ -25,6 +29,7 @@ use warp_reverse_proxy::{
|
|||
|
||||
struct ActiveInstances {
|
||||
known: Mutex<HashMap<String, SocketAddr>>,
|
||||
last: Mutex<Option<SocketAddr>>,
|
||||
docker: Docker,
|
||||
config: HazeConfig,
|
||||
}
|
||||
|
|
@ -33,6 +38,7 @@ impl ActiveInstances {
|
|||
pub fn new(docker: Docker, config: HazeConfig) -> Self {
|
||||
ActiveInstances {
|
||||
known: Mutex::default(),
|
||||
last: Mutex::default(),
|
||||
docker,
|
||||
config,
|
||||
}
|
||||
|
|
@ -72,6 +78,22 @@ impl ActiveInstances {
|
|||
self.known.lock().unwrap().insert(name.into(), addr);
|
||||
Some(addr)
|
||||
}
|
||||
|
||||
pub fn last(&self) -> Option<SocketAddr> {
|
||||
self.last.lock().unwrap().clone()
|
||||
}
|
||||
|
||||
async fn update_last(&self) {
|
||||
let last = Cloud::get_by_filter(&self.docker, None, &self.config)
|
||||
.await
|
||||
.ok()
|
||||
.and_then(|cloud| Some(SocketAddr::new(cloud.ip?, 80)));
|
||||
let mut old = self.last.lock().unwrap();
|
||||
if old.as_ref() != last.as_ref() {
|
||||
info!(instance = ?last, "Found new instance");
|
||||
*old = last;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub async fn proxy(docker: Docker, config: HazeConfig) -> Result<()> {
|
||||
|
|
@ -80,29 +102,54 @@ pub async fn proxy(docker: Docker, config: HazeConfig) -> Result<()> {
|
|||
}
|
||||
let listen = config.proxy.listen.clone();
|
||||
|
||||
let base_address = config.proxy.address.clone();
|
||||
let instances = ActiveInstances::new(docker, config);
|
||||
serve(instances, listen).await
|
||||
serve(instances, listen, base_address).await
|
||||
}
|
||||
|
||||
async fn serve(instances: ActiveInstances, listen: String) -> Result<()> {
|
||||
async fn serve(instances: ActiveInstances, listen: String, base_address: String) -> Result<()> {
|
||||
let instances = Arc::new(instances);
|
||||
let base_address = Arc::new(base_address);
|
||||
let last_instances = instances.clone();
|
||||
let instances = warp::any().map(move || instances.clone());
|
||||
let base_address = warp::any().map(move || base_address.clone());
|
||||
|
||||
spawn(async move {
|
||||
loop {
|
||||
sleep(Duration::from_secs(1)).await;
|
||||
last_instances.update_last().await;
|
||||
}
|
||||
});
|
||||
|
||||
let proxy = warp::any()
|
||||
.and(warp::filters::host::optional())
|
||||
.and(instances)
|
||||
.and(base_address)
|
||||
.and_then(
|
||||
move |host: Option<Authority>, instances: Arc<ActiveInstances>| async move {
|
||||
move |host: Option<Authority>,
|
||||
instances: Arc<ActiveInstances>,
|
||||
base_address: Arc<String>| async move {
|
||||
let host = match host {
|
||||
Some(host) => host,
|
||||
None => return Err(warp::reject::not_found()),
|
||||
};
|
||||
let requested_instance = host.as_str().split('.').next().unwrap();
|
||||
if let Some(ip) = instances.get(requested_instance).await {
|
||||
Ok((format!("http://{}", ip), host.to_string()))
|
||||
let ip = if host.as_str() == base_address.as_str() {
|
||||
instances
|
||||
.last()
|
||||
.ok_or_else(|| String::from("No running instance known"))
|
||||
} else {
|
||||
eprintln!("Error {} has no known ip", requested_instance);
|
||||
Err(warp::reject::not_found())
|
||||
let requested_instance = host.as_str().split('.').next().unwrap();
|
||||
instances
|
||||
.get(requested_instance)
|
||||
.await
|
||||
.ok_or_else(|| format!("Error {} has no known ip", requested_instance))
|
||||
};
|
||||
match ip {
|
||||
Ok(ip) => Ok((format!("http://{}", ip), host.to_string())),
|
||||
Err(e) => {
|
||||
eprintln!("{}", e);
|
||||
Err(warp::reject::not_found())
|
||||
}
|
||||
}
|
||||
},
|
||||
)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue