CI: Better free port finding (#8780)

Replace our port-finding code with `portpicker` crate.

We expect that it'll greatly reduce possibility of race conditions, as the port will be picked at random, so they won't collide as easily when we use the routine more than once.
This commit is contained in:
Michał Wawrzyniec Urbańczyk 2024-01-17 08:54:37 +01:00 committed by GitHub
parent 318cc2d81b
commit 184128949e
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
4 changed files with 14 additions and 18 deletions

10
Cargo.lock generated
View File

@ -3910,6 +3910,7 @@ dependencies = [
"path-slash",
"pathdiff",
"platforms",
"portpicker",
"rand 0.8.5",
"regex",
"reqwest",
@ -5154,6 +5155,15 @@ version = "1.3.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "767eb9f07d4a5ebcb39bbf2d452058a93c011373abf6832e24194a1c3f004794"
[[package]]
name = "portpicker"
version = "0.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "be97d76faf1bfab666e1375477b23fde79eccf0276e9b63b92a39d676a889ba9"
dependencies = [
"rand 0.8.5",
]
[[package]]
name = "ppv-lite86"
version = "0.2.17"

View File

@ -91,6 +91,7 @@ octocrab = { git = "https://github.com/enso-org/octocrab", default-features = fa
"rustls",
] }
platforms = { version = "3.2.0", features = ["serde"] }
portpicker = { version = "0.1.1" }
regex = { version = "1.6.0" }
serde = { version = "1.0.130", features = ["derive", "rc"] }
serde_yaml = { version = "0.9.16" }

View File

@ -42,6 +42,7 @@ path-absolutize = "3.0.11"
pathdiff = "0.2.1"
path-slash = "0.2.1"
platforms = { workspace = true }
portpicker = { workspace = true }
rand = "0.8.4"
regex = { workspace = true }
reqwest = { workspace = true }

View File

@ -130,9 +130,6 @@ pub mod prelude {
}
use prelude::*;
use std::net::Ipv4Addr;
use std::net::SocketAddrV4;
use std::net::TcpListener;
use ::anyhow::Context;
@ -142,24 +139,11 @@ pub const EMPTY_REQUEST_BODY: Option<&()> = None;
/// The user agent string name used by our HTTP clients.
pub const USER_AGENT: &str = "enso-build";
pub const UNREGISTERED_PORTS: Range<u16> = 49152..65535;
pub const RECORD_SEPARATOR: &str = "\u{1E}";
/// Looks up a free port in the IANA private or dynamic port range.
/// Looks up a free port.
pub fn get_free_port() -> Result<u16> {
let port_range = UNREGISTERED_PORTS;
port_range
.into_iter()
.find(|port| {
// Note that we must use Ipv4Addr::UNSPECIFIED. Ipv4Addr::LOCALHOST would not be enough,
// as it misses e.g. services spawned by docker subnetworks.
// This also makes us write this by hand, rather than use a crate.
let ipv4 = SocketAddrV4::new(Ipv4Addr::UNSPECIFIED, *port);
// FIXME investigate? this can show firewall dialog on windows
TcpListener::bind(ipv4).is_ok()
})
.context("Failed to find a free local port.")
portpicker::pick_unused_port().context("Failed to find a free available port.")
}
pub fn ok_ready_boxed<'a, T: 'a + Send>(t: T) -> BoxFuture<'a, Result<T>> {