docker discovery working, updated rust to 1.90

This commit is contained in:
Maya
2025-10-13 07:47:22 -04:00
parent f183c3c7e6
commit 3ac7ce6fe8
13 changed files with 49 additions and 44 deletions
+5 -2
View File
@@ -1,4 +1,7 @@
use crate::{daemon::{discovery::handlers as discovery_handlers, runtime::{types::DaemonAppState}}, server::shared::types::api::{ApiResponse, ApiResult}};
use crate::{
daemon::{discovery::handlers as discovery_handlers, runtime::types::DaemonAppState},
server::shared::types::api::{ApiResponse, ApiResult},
};
use axum::{routing::get, Json, Router};
use std::sync::Arc;
@@ -14,4 +17,4 @@ async fn get_health() -> ApiResult<Json<ApiResponse<String>>> {
Ok(Json(ApiResponse::success(
"Netvisor Daemon Running".to_string(),
)))
}
}
@@ -90,10 +90,8 @@ impl ServiceDefinition for Box<dyn ServiceDefinition> {
impl ServiceDefinitionExt for Box<dyn ServiceDefinition> {
fn is_infra_service(&self) -> bool {
self.is_dns_resolver()
|| self.is_gateway()
|| self.is_reverse_proxy()
// || self.is_docker_daemon()
self.is_dns_resolver() || self.is_gateway() || self.is_reverse_proxy()
// || self.is_docker_daemon()
}
fn discovery_ports(&self) -> Vec<PortBase> {
+1 -2
View File
@@ -9,9 +9,9 @@ use axum::{
routing::{delete, get, post, put},
Router,
};
use validator::Validate;
use std::sync::Arc;
use uuid::Uuid;
use validator::Validate;
pub fn create_router() -> Router<Arc<AppState>> {
Router::new()
@@ -25,7 +25,6 @@ async fn create_subnet(
State(state): State<Arc<AppState>>,
Json(request): Json<Subnet>,
) -> ApiResult<Json<ApiResponse<Subnet>>> {
tracing::info!("Received subnet creation request: {:?}", request);
if let Err(validation_errors) = request.base.validate() {
+2 -1
View File
@@ -1,6 +1,7 @@
use crate::server::{
config::AppState,
shared::types::api::{ApiResponse, ApiResult}, topology::types::api::TopologyRequestOptions,
shared::types::api::{ApiResponse, ApiResult},
topology::types::api::TopologyRequestOptions,
};
use axum::{extract::State, response::Json, routing::post, Router};
use std::sync::Arc;
@@ -66,7 +66,7 @@ impl EdgeBuilder {
source_is_infra && source_needs_infra_constraint,
target_is_infra && target_needs_infra_constraint,
);
// Don't label edges if they are within a subnet (avoid clutter) or between subnets that have been
// consolidated (ie docker bridge subnets)
let label = if source_subnet == target_subnet
+9 -3
View File
@@ -40,7 +40,10 @@ impl TopologyService {
}
}
pub async fn build_graph(&self, options: TopologyRequestOptions) -> Result<Graph<Node, Edge>, Error> {
pub async fn build_graph(
&self,
options: TopologyRequestOptions,
) -> Result<Graph<Node, Edge>, Error> {
// Fetch all data
let hosts = self.host_service.get_all_hosts().await?;
let subnets = self.subnet_service.get_all_subnets().await?;
@@ -57,8 +60,11 @@ impl TopologyService {
// Create nodes with layout
let mut layout_planner = SubnetLayoutPlanner::new();
let (subnet_layouts, child_nodes) =
layout_planner.create_subnet_child_nodes(&ctx, &all_edges, options.group_docker_bridges_by_host);
let (subnet_layouts, child_nodes) = layout_planner.create_subnet_child_nodes(
&ctx,
&all_edges,
options.group_docker_bridges_by_host,
);
// Get relocation info from layout planner
let relocation_map = layout_planner.get_handle_relocation_map();
@@ -59,9 +59,10 @@ impl SubnetLayoutPlanner {
&mut self,
ctx: &TopologyContext,
all_edges: &[Edge],
group_docker_bridges_by_host: bool
group_docker_bridges_by_host: bool,
) -> (HashMap<Uuid, SubnetLayout>, Vec<Node>) {
let children_by_subnet = self.group_children_by_subnet(ctx, all_edges, group_docker_bridges_by_host);
let children_by_subnet =
self.group_children_by_subnet(ctx, all_edges, group_docker_bridges_by_host);
let mut child_nodes = Vec::new();
let subnet_sizes: HashMap<Uuid, SubnetLayout> = children_by_subnet
@@ -83,7 +84,7 @@ impl SubnetLayoutPlanner {
&mut self,
ctx: &TopologyContext,
all_edges: &[Edge],
group_docker_bridges_by_host: bool
group_docker_bridges_by_host: bool,
) -> HashMap<Uuid, Vec<SubnetChild>> {
let mut children_by_subnet: HashMap<Uuid, Vec<SubnetChild>> = HashMap::new();
@@ -363,7 +363,7 @@ impl SubnetPositioner {
fn calculate_median(values: &mut [f64]) -> f64 {
values.sort_by(|a, b| a.partial_cmp(b).unwrap());
if values.len() % 2 == 0 {
if values.len().is_multiple_of(2) {
let mid = values.len() / 2;
(values[mid - 1] + values[mid]) / 2.0
} else {
+3 -3
View File
@@ -1,6 +1,6 @@
use serde::{Serialize, Deserialize};
use serde::{Deserialize, Serialize};
#[derive(Serialize, Deserialize, Debug, Copy, Clone, Default)]
pub struct TopologyRequestOptions {
pub group_docker_bridges_by_host: bool
}
pub group_docker_bridges_by_host: bool,
}
+1 -1
View File
@@ -1,4 +1,4 @@
pub mod api;
pub mod base;
pub mod edges;
pub mod nodes;
pub mod api;
+14 -15
View File
@@ -10,7 +10,7 @@ use netvisor::server::shared::types::metadata::HasId;
use uuid::Uuid;
struct ContainerManager {
container_process: Option<Child>
container_process: Option<Child>,
}
/// Container lifecycle management
@@ -23,16 +23,18 @@ impl ContainerManager {
fn start(&mut self) -> Result<(), String> {
println!("Starting containers with docker compose...");
// Start containers and wait for them to be healthy
// Don't use -d, let docker compose wait for health before returning
let status = Command::new("docker")
.args([
"compose",
"-f", "docker-compose.yml",
"-f", "docker-compose.dev.yml",
"-f",
"docker-compose.yml",
"-f",
"docker-compose.dev.yml",
"up",
"--wait", // Wait for services to be healthy before returning
"--wait", // Wait for services to be healthy before returning
])
.current_dir("..")
.status()
@@ -45,7 +47,7 @@ impl ContainerManager {
println!("✅ Server and daemon are healthy!");
Ok(())
}
fn cleanup(&mut self) {
println!("\nCleaning up containers...");
@@ -190,10 +192,7 @@ async fn check_daemon_registered(client: &reqwest::Client) -> Result<Daemon, Str
}
/// Start discovery and wait for it to complete
async fn run_discovery_and_wait(
client: &reqwest::Client,
daemon_id: Uuid,
) -> Result<(), String> {
async fn run_discovery_and_wait(client: &reqwest::Client, daemon_id: Uuid) -> Result<(), String> {
// Initiate discovery
println!("\n=== Starting Discovery ===");
let response = client
@@ -212,8 +211,7 @@ async fn run_discovery_and_wait(
.unwrap_or_else(|_| "Could not read body".to_string());
return Err(format!(
"Discovery initiation failed with status {}: {}",
status,
body
status, body
));
}
@@ -293,7 +291,7 @@ async fn run_discovery_and_wait(
/// Check for Home Assistant service
async fn check_for_home_assistant_service(client: &reqwest::Client) -> Result<Service, String> {
println!("\n=== Checking for Home Assistant Service ===");
let services = retry_api_request("fetch services", 10, 2, || {
let client = client.clone();
async move {
@@ -339,7 +337,8 @@ async fn check_for_home_assistant_service(client: &reqwest::Client) -> Result<Se
.await?;
// Find Home Assistant service
let home_assistant_service = services.clone()
let home_assistant_service = services
.clone()
.into_iter()
.find(|s| s.base.service_definition.id() == HomeAssistant.id())
.ok_or_else(|| {
@@ -395,4 +394,4 @@ async fn test_container_daemon_server_integration() {
println!(" ✓ Home Assistant service discovered");
// Cleanup happens automatically via Drop trait
}
}
@@ -10,7 +10,7 @@
import { type Node, type Edge } from '@xyflow/svelte';
import '@xyflow/svelte/dist/style.css';
import { getDistanceToNode, getNextHandle, topology } from '../store';
import { edgeTypes, entities } from '$lib/shared/stores/metadata';
import { edgeTypes } from '$lib/shared/stores/metadata';
import { pushError } from '$lib/shared/stores/feedback';
// Import custom node components
@@ -77,7 +77,6 @@
const edgeLabel = edgeTypes.getName(edgeType);
let edgeMetadata = edgeTypes.getMetadata(edgeType);
let edgeColorHelper = edgeTypes.getColorHelper(edgeType);
let hostColorHelper = entities.getColorHelper('Host');
const dashArray = edgeMetadata.is_dashed ? 'stroke-dasharray: 5,5;' : '';
const markerStart = !edgeMetadata.has_start_marker
@@ -93,12 +92,11 @@
color: edgeColorHelper.rgb
} as EdgeMarkerType);
const labelStyle =
edgeMetadata.style_label_like_nodes
? `background: ${twColorToRgba(edgeColorHelper.bg)};
const labelStyle = edgeMetadata.style_label_like_nodes
? `background: ${twColorToRgba(edgeColorHelper.bg)};
color: ${edgeColorHelper.rgb};
border: 2px solid ${twColorToRgba(edgeColorHelper.border)};`
: 'background: #374151; color: #f3f4f6; border: 1px solid #4b5563;';
: 'background: #374151; color: #f3f4f6; border: 1px solid #4b5563;';
const data: CustomEdgeData = {
edgeType: edgeType,
+2 -2
View File
@@ -55,5 +55,5 @@ export interface CustomNodeData extends Record<string, unknown> {
}
export interface TopologyRequestOptions {
group_docker_bridges_by_host: boolean
}
group_docker_bridges_by_host: boolean;
}