Compare commits
No commits in common. "ecc461a33f79649718260dbaf2c78825575bc6a1" and "be385dccff49303dd9159bccf8552d44fcc2e451" have entirely different histories.
ecc461a33f
...
be385dccff
@ -149,98 +149,6 @@ impl PhysicalHost {
|
|||||||
parts.join(" | ")
|
parts.join(" | ")
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn parts_list(&self) -> String {
|
|
||||||
let PhysicalHost {
|
|
||||||
id,
|
|
||||||
category,
|
|
||||||
network,
|
|
||||||
storage,
|
|
||||||
labels,
|
|
||||||
memory_modules,
|
|
||||||
cpus,
|
|
||||||
} = self;
|
|
||||||
|
|
||||||
let mut parts_list = String::new();
|
|
||||||
parts_list.push_str("\n\n=====================");
|
|
||||||
parts_list.push_str(&format!("\nHost ID {id}"));
|
|
||||||
parts_list.push_str("\n=====================");
|
|
||||||
parts_list.push_str("\n\n=====================");
|
|
||||||
parts_list.push_str(&format!("\nCPU count {}", cpus.len()));
|
|
||||||
parts_list.push_str("\n=====================");
|
|
||||||
cpus.iter().for_each(|c| {
|
|
||||||
let CPU {
|
|
||||||
model,
|
|
||||||
vendor,
|
|
||||||
cores,
|
|
||||||
threads,
|
|
||||||
frequency_mhz,
|
|
||||||
} = c;
|
|
||||||
parts_list.push_str(&format!(
|
|
||||||
"\n{vendor} {model}, {cores}/{threads} {}Ghz",
|
|
||||||
*frequency_mhz as f64 / 1000.0
|
|
||||||
));
|
|
||||||
});
|
|
||||||
|
|
||||||
parts_list.push_str("\n\n=====================");
|
|
||||||
parts_list.push_str(&format!("\nNetwork Interfaces count {}", network.len()));
|
|
||||||
parts_list.push_str("\n=====================");
|
|
||||||
network.iter().for_each(|nic| {
|
|
||||||
parts_list.push_str(&format!(
|
|
||||||
"\nNic({} {}Gbps mac({}) ipv4({}), ipv6({})",
|
|
||||||
nic.name,
|
|
||||||
nic.speed_mbps.unwrap_or(0) / 1000,
|
|
||||||
nic.mac_address,
|
|
||||||
nic.ipv4_addresses.join(","),
|
|
||||||
nic.ipv6_addresses.join(",")
|
|
||||||
));
|
|
||||||
});
|
|
||||||
|
|
||||||
parts_list.push_str("\n\n=====================");
|
|
||||||
parts_list.push_str(&format!("\nStorage drives count {}", storage.len()));
|
|
||||||
parts_list.push_str("\n=====================");
|
|
||||||
storage.iter().for_each(|drive| {
|
|
||||||
let StorageDrive {
|
|
||||||
name,
|
|
||||||
model,
|
|
||||||
serial,
|
|
||||||
size_bytes,
|
|
||||||
logical_block_size: _,
|
|
||||||
physical_block_size: _,
|
|
||||||
rotational: _,
|
|
||||||
wwn: _,
|
|
||||||
interface_type,
|
|
||||||
smart_status,
|
|
||||||
} = drive;
|
|
||||||
parts_list.push_str(&format!(
|
|
||||||
"\n{name} {}Gb {model} {interface_type} smart({smart_status:?}) {serial}",
|
|
||||||
size_bytes / 1000 / 1000 / 1000
|
|
||||||
));
|
|
||||||
});
|
|
||||||
|
|
||||||
parts_list.push_str("\n\n=====================");
|
|
||||||
parts_list.push_str(&format!("\nMemory modules count {}", memory_modules.len()));
|
|
||||||
parts_list.push_str("\n=====================");
|
|
||||||
memory_modules.iter().for_each(|mem| {
|
|
||||||
let MemoryModule {
|
|
||||||
size_bytes,
|
|
||||||
speed_mhz,
|
|
||||||
manufacturer,
|
|
||||||
part_number,
|
|
||||||
serial_number,
|
|
||||||
rank,
|
|
||||||
} = mem;
|
|
||||||
parts_list.push_str(&format!(
|
|
||||||
"\n{}Gb, {}Mhz, Manufacturer ({}), Part Number ({})",
|
|
||||||
size_bytes / 1000 / 1000 / 1000,
|
|
||||||
speed_mhz.unwrap_or(0),
|
|
||||||
manufacturer.as_ref().unwrap_or(&String::new()),
|
|
||||||
part_number.as_ref().unwrap_or(&String::new()),
|
|
||||||
));
|
|
||||||
});
|
|
||||||
|
|
||||||
parts_list
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn cluster_mac(&self) -> MacAddress {
|
pub fn cluster_mac(&self) -> MacAddress {
|
||||||
self.network
|
self.network
|
||||||
.first()
|
.first()
|
||||||
|
|||||||
@ -18,7 +18,6 @@ impl InventoryFilter {
|
|||||||
use derive_new::new;
|
use derive_new::new;
|
||||||
use log::info;
|
use log::info;
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
use strum::EnumIter;
|
|
||||||
|
|
||||||
use crate::hardware::{ManagementInterface, ManualManagementInterface};
|
use crate::hardware::{ManagementInterface, ManualManagementInterface};
|
||||||
|
|
||||||
@ -64,7 +63,7 @@ impl Inventory {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Serialize, Deserialize, sqlx::Type, Clone, EnumIter)]
|
#[derive(Debug, Serialize, Deserialize, sqlx::Type, Clone)]
|
||||||
pub enum HostRole {
|
pub enum HostRole {
|
||||||
Bootstrap,
|
Bootstrap,
|
||||||
ControlPlane,
|
ControlPlane,
|
||||||
|
|||||||
@ -29,7 +29,7 @@ pub trait InventoryRepository: Send + Sync + 'static {
|
|||||||
async fn save(&self, host: &PhysicalHost) -> Result<(), RepoError>;
|
async fn save(&self, host: &PhysicalHost) -> Result<(), RepoError>;
|
||||||
async fn get_latest_by_id(&self, host_id: &str) -> Result<Option<PhysicalHost>, RepoError>;
|
async fn get_latest_by_id(&self, host_id: &str) -> Result<Option<PhysicalHost>, RepoError>;
|
||||||
async fn get_all_hosts(&self) -> Result<Vec<PhysicalHost>, RepoError>;
|
async fn get_all_hosts(&self) -> Result<Vec<PhysicalHost>, RepoError>;
|
||||||
async fn get_host_for_role(&self, role: &HostRole) -> Result<Vec<PhysicalHost>, RepoError>;
|
async fn get_host_for_role(&self, role: HostRole) -> Result<Vec<PhysicalHost>, RepoError>;
|
||||||
async fn save_role_mapping(
|
async fn save_role_mapping(
|
||||||
&self,
|
&self,
|
||||||
role: &HostRole,
|
role: &HostRole,
|
||||||
|
|||||||
@ -109,7 +109,7 @@ impl InventoryRepository for SqliteInventoryRepository {
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn get_host_for_role(&self, role: &HostRole) -> Result<Vec<PhysicalHost>, RepoError> {
|
async fn get_host_for_role(&self, role: HostRole) -> Result<Vec<PhysicalHost>, RepoError> {
|
||||||
struct HostIdRow {
|
struct HostIdRow {
|
||||||
host_id: String,
|
host_id: String,
|
||||||
}
|
}
|
||||||
|
|||||||
@ -76,7 +76,7 @@ impl<T: Topology> Interpret<T> for DiscoverHostForRoleInterpret {
|
|||||||
Ok(choice) => {
|
Ok(choice) => {
|
||||||
info!("Selected {} as the bootstrap node.", choice.summary());
|
info!("Selected {} as the bootstrap node.", choice.summary());
|
||||||
host_repo
|
host_repo
|
||||||
.save_role_mapping(&self.score.role, &choice)
|
.save_role_mapping(&HostRole::Bootstrap, &choice)
|
||||||
.await?;
|
.await?;
|
||||||
host = choice;
|
host = choice;
|
||||||
break;
|
break;
|
||||||
|
|||||||
@ -1,72 +0,0 @@
|
|||||||
use async_trait::async_trait;
|
|
||||||
use harmony_types::id::Id;
|
|
||||||
use log::info;
|
|
||||||
use serde::{Deserialize, Serialize};
|
|
||||||
use strum::IntoEnumIterator;
|
|
||||||
|
|
||||||
use crate::{
|
|
||||||
data::Version,
|
|
||||||
infra::inventory::InventoryRepositoryFactory,
|
|
||||||
interpret::{Interpret, InterpretError, InterpretName, InterpretStatus, Outcome},
|
|
||||||
inventory::{HostRole, Inventory},
|
|
||||||
score::Score,
|
|
||||||
topology::Topology,
|
|
||||||
};
|
|
||||||
|
|
||||||
#[derive(Debug, Serialize, Deserialize, Clone)]
|
|
||||||
pub struct InspectInventoryScore {}
|
|
||||||
|
|
||||||
impl<T: Topology> Score<T> for InspectInventoryScore {
|
|
||||||
fn name(&self) -> String {
|
|
||||||
"InspectInventoryScore".to_string()
|
|
||||||
}
|
|
||||||
|
|
||||||
#[doc(hidden)]
|
|
||||||
fn create_interpret(&self) -> Box<dyn Interpret<T>> {
|
|
||||||
Box::new(InspectInventoryInterpret {})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Debug)]
|
|
||||||
pub struct InspectInventoryInterpret;
|
|
||||||
|
|
||||||
#[async_trait]
|
|
||||||
impl<T: Topology> Interpret<T> for InspectInventoryInterpret {
|
|
||||||
async fn execute(
|
|
||||||
&self,
|
|
||||||
_inventory: &Inventory,
|
|
||||||
_topology: &T,
|
|
||||||
) -> Result<Outcome, InterpretError> {
|
|
||||||
let repo = InventoryRepositoryFactory::build().await?;
|
|
||||||
for role in HostRole::iter() {
|
|
||||||
info!("Inspecting hosts for role {role:?}");
|
|
||||||
let hosts = repo.get_host_for_role(&role).await?;
|
|
||||||
info!("Hosts with role {role:?} : {}", hosts.len());
|
|
||||||
hosts.iter().enumerate().for_each(|(idx, h)| {
|
|
||||||
info!(
|
|
||||||
"Found host index {idx} with role {role:?} => \n{}\n{}",
|
|
||||||
h.summary(),
|
|
||||||
h.parts_list()
|
|
||||||
)
|
|
||||||
});
|
|
||||||
}
|
|
||||||
Ok(Outcome::success(
|
|
||||||
"Inventory inspection complete".to_string(),
|
|
||||||
))
|
|
||||||
}
|
|
||||||
fn get_name(&self) -> InterpretName {
|
|
||||||
InterpretName::Custom("InspectInventoryInterpret")
|
|
||||||
}
|
|
||||||
|
|
||||||
fn get_version(&self) -> Version {
|
|
||||||
todo!()
|
|
||||||
}
|
|
||||||
|
|
||||||
fn get_status(&self) -> InterpretStatus {
|
|
||||||
todo!()
|
|
||||||
}
|
|
||||||
|
|
||||||
fn get_children(&self) -> Vec<Id> {
|
|
||||||
todo!()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,5 +1,4 @@
|
|||||||
mod discovery;
|
mod discovery;
|
||||||
pub mod inspect;
|
|
||||||
pub use discovery::*;
|
pub use discovery::*;
|
||||||
|
|
||||||
use async_trait::async_trait;
|
use async_trait::async_trait;
|
||||||
|
|||||||
@ -100,7 +100,7 @@ When you can dig them, confirm to continue.
|
|||||||
let repo = InventoryRepositoryFactory::build().await?;
|
let repo = InventoryRepositoryFactory::build().await?;
|
||||||
|
|
||||||
while bootstrap_host.is_none() {
|
while bootstrap_host.is_none() {
|
||||||
let hosts = repo.get_host_for_role(&HostRole::Bootstrap).await?;
|
let hosts = repo.get_host_for_role(HostRole::Bootstrap).await?;
|
||||||
bootstrap_host = hosts.into_iter().next().to_owned();
|
bootstrap_host = hosts.into_iter().next().to_owned();
|
||||||
DiscoverHostForRoleScore {
|
DiscoverHostForRoleScore {
|
||||||
role: HostRole::Bootstrap,
|
role: HostRole::Bootstrap,
|
||||||
|
|||||||
@ -67,7 +67,7 @@ impl OKDSetup02BootstrapInterpret {
|
|||||||
async fn get_bootstrap_node(&self) -> Result<PhysicalHost, InterpretError> {
|
async fn get_bootstrap_node(&self) -> Result<PhysicalHost, InterpretError> {
|
||||||
let repo = InventoryRepositoryFactory::build().await?;
|
let repo = InventoryRepositoryFactory::build().await?;
|
||||||
match repo
|
match repo
|
||||||
.get_host_for_role(&HostRole::Bootstrap)
|
.get_host_for_role(HostRole::Bootstrap)
|
||||||
.await?
|
.await?
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.next()
|
.next()
|
||||||
|
|||||||
@ -66,7 +66,7 @@ impl OKDSetup03ControlPlaneInterpret {
|
|||||||
) -> Result<Vec<PhysicalHost>, InterpretError> {
|
) -> Result<Vec<PhysicalHost>, InterpretError> {
|
||||||
const REQUIRED_HOSTS: usize = 3;
|
const REQUIRED_HOSTS: usize = 3;
|
||||||
let repo = InventoryRepositoryFactory::build().await?;
|
let repo = InventoryRepositoryFactory::build().await?;
|
||||||
let mut control_plane_hosts = repo.get_host_for_role(&HostRole::ControlPlane).await?;
|
let mut control_plane_hosts = repo.get_host_for_role(HostRole::ControlPlane).await?;
|
||||||
|
|
||||||
while control_plane_hosts.len() < REQUIRED_HOSTS {
|
while control_plane_hosts.len() < REQUIRED_HOSTS {
|
||||||
info!(
|
info!(
|
||||||
@ -80,7 +80,7 @@ impl OKDSetup03ControlPlaneInterpret {
|
|||||||
}
|
}
|
||||||
.interpret(inventory, topology)
|
.interpret(inventory, topology)
|
||||||
.await?;
|
.await?;
|
||||||
control_plane_hosts = repo.get_host_for_role(&HostRole::ControlPlane).await?;
|
control_plane_hosts = repo.get_host_for_role(HostRole::ControlPlane).await?;
|
||||||
}
|
}
|
||||||
|
|
||||||
if control_plane_hosts.len() < REQUIRED_HOSTS {
|
if control_plane_hosts.len() < REQUIRED_HOSTS {
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user