Skip to content
This repository was archived by the owner on Jan 27, 2026. It is now read-only.

Commit 1e0a4dc

Browse files
authored
Add software check for miner port (#240)
* add miner port check to ensure external port is available
1 parent b89c1ba commit 1e0a4dc

File tree

6 files changed

+73
-21
lines changed

6 files changed

+73
-21
lines changed

worker/src/checks/issue.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ pub enum IssueType {
1818
InsufficientCpu, // Minimum CPU cores needed
1919
NetworkConnectivityIssue, // Network performance issues
2020
NoStoragePath, // No storage path found
21+
PortUnavailable, // Port is unavailable
2122
}
2223

2324
impl IssueType {

worker/src/checks/software/mod.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,4 @@
11
pub mod docker;
2+
pub mod port;
23
pub mod software_check;
4+
pub use software_check::SoftwareChecker;

worker/src/checks/software/port.rs

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
use crate::checks::issue::{IssueReport, IssueType};
2+
use crate::console::Console;
3+
use anyhow::Result;
4+
use std::net::TcpListener;
5+
use std::sync::Arc;
6+
use tokio::sync::RwLock;
7+
8+
fn try_bind_port(port: u16) -> Result<()> {
9+
let addr = format!("0.0.0.0:{}", port);
10+
// If bind succeeds, port is available; if it fails, port is taken.
11+
let listener = TcpListener::bind(addr)?;
12+
drop(listener); // Release the port immediately.
13+
Ok(())
14+
}
15+
16+
pub async fn check_port_available(issues: &Arc<RwLock<IssueReport>>, port: u16) -> Result<()> {
17+
let issue_tracker = issues.read().await;
18+
19+
match try_bind_port(port) {
20+
Ok(_) => Console::success("Port is available"),
21+
Err(e) => {
22+
issue_tracker.add_issue(
23+
IssueType::PortUnavailable,
24+
format!("Port {} is not available: {}", port, e),
25+
);
26+
}
27+
}
28+
29+
Ok(())
30+
}
Lines changed: 26 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,33 @@
1-
use super::docker::check_docker_installed;
1+
use super::{docker::check_docker_installed, port::check_port_available};
22
use crate::checks::issue::IssueReport;
33
use crate::console::Console;
4+
use shared::models::node::Node;
45
use std::sync::Arc;
56
use tokio::sync::RwLock;
6-
pub async fn run_software_check(
7-
issues: Option<Arc<RwLock<IssueReport>>>,
8-
) -> Result<(), Box<dyn std::error::Error>> {
9-
Console::section("Software Checks");
10-
let issues = issues.unwrap_or_else(|| Arc::new(RwLock::new(IssueReport::new())));
117

12-
// Check Docker installation and connectivity
13-
Console::title("Docker:");
14-
check_docker_installed(&issues).await?;
8+
pub struct SoftwareChecker {
9+
issues: Arc<RwLock<IssueReport>>,
10+
}
11+
12+
impl SoftwareChecker {
13+
pub fn new(issues: Option<Arc<RwLock<IssueReport>>>) -> Self {
14+
Self {
15+
issues: issues.unwrap_or_else(|| Arc::new(RwLock::new(IssueReport::new()))),
16+
}
17+
}
18+
19+
pub async fn check_software(
20+
&self,
21+
node_config: &Node,
22+
) -> Result<(), Box<dyn std::error::Error>> {
23+
// Check Docker installation and connectivity
24+
Console::title("Docker:");
25+
check_docker_installed(&self.issues).await?;
26+
27+
// Check port availability
28+
Console::title("Port:");
29+
check_port_available(&self.issues, node_config.port).await?;
1530

16-
Ok(())
31+
Ok(())
32+
}
1733
}

worker/src/cli/command.rs

Lines changed: 13 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
use crate::api::server::start_server;
22
use crate::checks::hardware::HardwareChecker;
33
use crate::checks::issue::IssueReport;
4-
use crate::checks::software::software_check;
4+
use crate::checks::software::SoftwareChecker;
55
use crate::console::Console;
66
use crate::docker::taskbridge::TaskBridge;
77
use crate::docker::DockerService;
@@ -291,8 +291,8 @@ pub async fn execute_command(
291291
let issue_tracker = Arc::new(RwLock::new(IssueReport::new()));
292292
let mut hardware_check = HardwareChecker::new(Some(issue_tracker.clone()));
293293
let node_config = hardware_check.check_hardware(node_config).await.unwrap();
294-
if let Err(err) = software_check::run_software_check(Some(issue_tracker.clone())).await
295-
{
294+
let software_checker = SoftwareChecker::new(Some(issue_tracker.clone()));
295+
if let Err(err) = software_checker.check_software(&node_config).await {
296296
Console::user_error(&format!("❌ Software check failed: {}", err));
297297
std::process::exit(1);
298298
}
@@ -634,8 +634,9 @@ pub async fn execute_command(
634634
Console::section("🔍 PRIME WORKER SYSTEM CHECK");
635635
let issues = Arc::new(RwLock::new(IssueReport::new()));
636636

637-
// Run hardware checks
637+
// Run checks
638638
let mut hardware_checker = HardwareChecker::new(Some(issues.clone()));
639+
let software_checker = SoftwareChecker::new(Some(issues.clone()));
639640
let node_config = Node {
640641
id: String::new(),
641642
ip_address: String::new(),
@@ -645,12 +646,15 @@ pub async fn execute_command(
645646
compute_pool_id: 0,
646647
};
647648

648-
if let Err(err) = hardware_checker.check_hardware(node_config).await {
649-
Console::user_error(&format!("❌ Hardware check failed: {}", err));
650-
std::process::exit(1);
651-
}
649+
let node_config = match hardware_checker.check_hardware(node_config).await {
650+
Ok(node_config) => node_config,
651+
Err(err) => {
652+
Console::user_error(&format!("❌ Hardware check failed: {}", err));
653+
std::process::exit(1);
654+
}
655+
};
652656

653-
if let Err(err) = software_check::run_software_check(Some(issues.clone())).await {
657+
if let Err(err) = software_checker.check_software(&node_config).await {
654658
Console::user_error(&format!("❌ Software check failed: {}", err));
655659
std::process::exit(1);
656660
}

worker/src/docker/service.rs

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -109,8 +109,7 @@ impl DockerService {
109109
.filter(|c| {
110110
c.names.iter().any(|name| name.contains(TASK_PREFIX))
111111
&& task_id
112-
.as_ref()
113-
.map_or(true, |id| !c.names.iter().any(|name| name.contains(id)))
112+
.as_ref().is_none_or(|id| !c.names.iter().any(|name| name.contains(id)))
114113
})
115114
.cloned()
116115
.collect();

0 commit comments

Comments
 (0)