Compare commits

...

3 Commits

Author SHA1 Message Date
hdbg
ef7dc8ba07 houskeeping: linter run 2025-12-08 14:32:38 +01:00
hdbg
471f9129b4 refactor(controller): use state to find available port range 2025-12-08 14:32:13 +01:00
hdbg
570cec8b47 refactor(controller): simplify PostgreSQL DSN connection string output 2025-12-08 14:28:16 +01:00
8 changed files with 23 additions and 35 deletions

10
Cargo.lock generated
View File

@@ -409,15 +409,6 @@ dependencies = [
"litrs", "litrs",
] ]
[[package]]
name = "dsn"
version = "1.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a68ec86c8ab056c40c4d3f6a543ad0ad6a251d7d01dac251feed242aa44e754a"
dependencies = [
"percent-encoding",
]
[[package]] [[package]]
name = "dyn-clone" name = "dyn-clone"
version = "1.0.20" version = "1.0.20"
@@ -1103,7 +1094,6 @@ dependencies = [
"cliclack", "cliclack",
"colored", "colored",
"comfy-table", "comfy-table",
"dsn",
"futures", "futures",
"indicatif", "indicatif",
"miette", "miette",

View File

@@ -12,7 +12,6 @@ clap = { version = "4.5.53", features = ["derive"] }
cliclack = "0.3.7" cliclack = "0.3.7"
colored = "3.0.0" colored = "3.0.0"
comfy-table = "7.2.1" comfy-table = "7.2.1"
dsn = "1.2.1"
futures = "0.3.31" futures = "0.3.31"
indicatif = { version = "0.18.3", features = ["improved_unicode"] } indicatif = { version = "0.18.3", features = ["improved_unicode"] }
miette = { version = "7.6.0", features = ["fancy"] } miette = { version = "7.6.0", features = ["fancy"] }

View File

@@ -1,4 +1,3 @@
use dsn::DSN;
use miette::miette; use miette::miette;
use colored::Colorize; use colored::Colorize;
@@ -92,15 +91,10 @@ impl Controller {
match format { match format {
ConnectionFormat::DSN => { ConnectionFormat::DSN => {
let dsn = DSN::builder() println!(
.driver("postgres") "postgres://{}:{}@127.0.0.1:{}/{}",
.username(USERNAME) USERNAME, project.config.password, project.config.port, DATABASE
.password(project.config.password.clone()) );
.host("127.0.0.1")
.port(project.config.port)
.database(DATABASE)
.build();
println!("{}", dsn.to_string());
} }
ConnectionFormat::Human => { ConnectionFormat::Human => {
format_conn_human(project); format_conn_human(project);
@@ -128,13 +122,12 @@ impl Controller {
let config = PGDConfig { let config = PGDConfig {
version: *latest_version, version: *latest_version,
password: utils::generate_password(), password: utils::generate_password(),
port: utils::find_available_port()?, port: utils::find_available_port(&self.ctx.state)?,
}; };
let project = Project::new(config)?; let project = Project::new(config)?;
println!( println!(
"\n{} {}\n", "\nCreated pgd.toml in {}\n",
"Created pgd.toml in",
project.path.display().to_string().bright_white().bold() project.path.display().to_string().bright_white().bold()
); );

View File

@@ -1,5 +1,5 @@
use miette::{Diagnostic, miette}; use miette::{Diagnostic, miette};
use std::{io::Write, str::FromStr}; use std::str::FromStr;
use thiserror::Error; use thiserror::Error;
use bollard::{ use bollard::{
@@ -283,11 +283,11 @@ impl DockerController {
..Default::default() ..Default::default()
}); });
let logs = self
self
.daemon .daemon
.logs(container_id, options) .logs(container_id, options)
.map(|k| k.into_diagnostic().wrap_err("Failed streaming logs")); .map(|k| k.into_diagnostic().wrap_err("Failed streaming logs"))
logs
} }
} }

View File

@@ -8,7 +8,7 @@ use indicatif::{MultiProgress, ProgressBar, ProgressState, ProgressStyle};
fn new_download_pb(multi: &MultiProgress, layer_id: &str) -> ProgressBar { fn new_download_pb(multi: &MultiProgress, layer_id: &str) -> ProgressBar {
let pb = multi.add(ProgressBar::new(0)); let pb = multi.add(ProgressBar::new(0));
pb.set_style( pb.set_style(
ProgressStyle::with_template(&"{spinner:.green} [{elapsed_precise}] {msg} [{wide_bar:.cyan/blue}] {bytes}/{total_bytes} ({eta})".to_string()) ProgressStyle::with_template("{spinner:.green} [{elapsed_precise}] {msg} [{wide_bar:.cyan/blue}] {bytes}/{total_bytes} ({eta})")
.unwrap() .unwrap()
.with_key("eta", |state: &ProgressState, w: &mut dyn Write| { .with_key("eta", |state: &ProgressState, w: &mut dyn Write| {
write!(w, "{:.1}s", state.eta().as_secs_f64()).unwrap() write!(w, "{:.1}s", state.eta().as_secs_f64()).unwrap()

View File

@@ -146,7 +146,7 @@ impl<'a> Reconciler<'a> {
.is_container_running_by_id(container_id) .is_container_running_by_id(container_id)
.await? .await?
{ {
return Ok(()); Ok(())
} else { } else {
miette::bail!("Container stopped unexpectedly after start"); miette::bail!("Container stopped unexpectedly after start");
} }

View File

@@ -1,12 +1,18 @@
use miette::Result; use miette::Result;
use rand::{Rng, distr::Alphanumeric}; use rand::{Rng, distr::Alphanumeric};
use crate::state::StateManager;
const DEFAULT_POSTGRES_PORT: u16 = 5432; const DEFAULT_POSTGRES_PORT: u16 = 5432;
const PORT_SEARCH_RANGE: u16 = 100; const PORT_SEARCH_RANGE: u16 = 100;
pub fn find_available_port() -> Result<u16> { pub fn find_available_port(state: &StateManager) -> Result<u16> {
use std::net::TcpListener; use std::net::TcpListener;
for port in DEFAULT_POSTGRES_PORT..(DEFAULT_POSTGRES_PORT + PORT_SEARCH_RANGE) { let starting_port = state
.get_highest_used_port()
.unwrap_or(DEFAULT_POSTGRES_PORT);
for port in starting_port..(starting_port + PORT_SEARCH_RANGE) {
if TcpListener::bind(("127.0.0.1", port)).is_ok() { if TcpListener::bind(("127.0.0.1", port)).is_ok() {
return Ok(port); return Ok(port);
} }

View File

@@ -88,8 +88,8 @@ impl StateManager {
self.0.borrow_mut().instances.insert(project_name, state); self.0.borrow_mut().instances.insert(project_name, state);
} }
pub fn remove(&self, project_name: &str) -> Option<InstanceState> { pub fn get_highest_used_port(&self) -> Option<u16> {
self.0.borrow_mut().instances.remove(project_name) self.0.borrow().instances.values().map(|i| i.port).max()
} }
} }