mirror of
https://github.com/edera-dev/krata.git
synced 2025-08-03 05:10:55 +00:00
feature(krata): implement network reservation list
This commit is contained in:
@ -1,6 +1,7 @@
|
|||||||
pub mod device;
|
pub mod device;
|
||||||
pub mod host;
|
pub mod host;
|
||||||
pub mod image;
|
pub mod image;
|
||||||
|
pub mod network;
|
||||||
pub mod zone;
|
pub mod zone;
|
||||||
|
|
||||||
use crate::cli::device::DeviceCommand;
|
use crate::cli::device::DeviceCommand;
|
||||||
@ -14,6 +15,7 @@ use krata::{
|
|||||||
events::EventStream,
|
events::EventStream,
|
||||||
v1::control::{control_service_client::ControlServiceClient, ResolveZoneIdRequest},
|
v1::control::{control_service_client::ControlServiceClient, ResolveZoneIdRequest},
|
||||||
};
|
};
|
||||||
|
use network::NetworkCommand;
|
||||||
use tonic::{transport::Channel, Request};
|
use tonic::{transport::Channel, Request};
|
||||||
|
|
||||||
#[derive(Parser)]
|
#[derive(Parser)]
|
||||||
@ -36,6 +38,7 @@ pub struct ControlCommand {
|
|||||||
pub enum ControlCommands {
|
pub enum ControlCommands {
|
||||||
Zone(ZoneCommand),
|
Zone(ZoneCommand),
|
||||||
Image(ImageCommand),
|
Image(ImageCommand),
|
||||||
|
Network(NetworkCommand),
|
||||||
Device(DeviceCommand),
|
Device(DeviceCommand),
|
||||||
Host(HostCommand),
|
Host(HostCommand),
|
||||||
}
|
}
|
||||||
@ -57,6 +60,8 @@ impl ControlCommands {
|
|||||||
match self {
|
match self {
|
||||||
ControlCommands::Zone(zone) => zone.run(client, events).await,
|
ControlCommands::Zone(zone) => zone.run(client, events).await,
|
||||||
|
|
||||||
|
ControlCommands::Network(network) => network.run(client, events).await,
|
||||||
|
|
||||||
ControlCommands::Image(image) => image.run(client, events).await,
|
ControlCommands::Image(image) => image.run(client, events).await,
|
||||||
|
|
||||||
ControlCommands::Device(device) => device.run(client, events).await,
|
ControlCommands::Device(device) => device.run(client, events).await,
|
||||||
|
43
crates/ctl/src/cli/network/mod.rs
Normal file
43
crates/ctl/src/cli/network/mod.rs
Normal file
@ -0,0 +1,43 @@
|
|||||||
|
use anyhow::Result;
|
||||||
|
use clap::{Parser, Subcommand};
|
||||||
|
use reservation::NetworkReservationCommand;
|
||||||
|
use tonic::transport::Channel;
|
||||||
|
|
||||||
|
use krata::events::EventStream;
|
||||||
|
use krata::v1::control::control_service_client::ControlServiceClient;
|
||||||
|
|
||||||
|
pub mod reservation;
|
||||||
|
|
||||||
|
#[derive(Parser)]
|
||||||
|
#[command(about = "Manage the network on the isolation engine")]
|
||||||
|
pub struct NetworkCommand {
|
||||||
|
#[command(subcommand)]
|
||||||
|
subcommand: NetworkCommands,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl NetworkCommand {
|
||||||
|
pub async fn run(
|
||||||
|
self,
|
||||||
|
client: ControlServiceClient<Channel>,
|
||||||
|
events: EventStream,
|
||||||
|
) -> Result<()> {
|
||||||
|
self.subcommand.run(client, events).await
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Subcommand)]
|
||||||
|
pub enum NetworkCommands {
|
||||||
|
Reservation(NetworkReservationCommand),
|
||||||
|
}
|
||||||
|
|
||||||
|
impl NetworkCommands {
|
||||||
|
pub async fn run(
|
||||||
|
self,
|
||||||
|
client: ControlServiceClient<Channel>,
|
||||||
|
events: EventStream,
|
||||||
|
) -> Result<()> {
|
||||||
|
match self {
|
||||||
|
NetworkCommands::Reservation(reservation) => reservation.run(client, events).await,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
125
crates/ctl/src/cli/network/reservation/list.rs
Normal file
125
crates/ctl/src/cli/network/reservation/list.rs
Normal file
@ -0,0 +1,125 @@
|
|||||||
|
use anyhow::Result;
|
||||||
|
use clap::{Parser, ValueEnum};
|
||||||
|
use comfy_table::{presets::UTF8_FULL_CONDENSED, Cell, Table};
|
||||||
|
use krata::{
|
||||||
|
events::EventStream,
|
||||||
|
v1::{
|
||||||
|
common::NetworkReservation,
|
||||||
|
control::{control_service_client::ControlServiceClient, ListNetworkReservationsRequest},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
use serde_json::Value;
|
||||||
|
use tonic::transport::Channel;
|
||||||
|
|
||||||
|
use crate::format::{kv2line, proto2dynamic, proto2kv};
|
||||||
|
|
||||||
|
#[derive(ValueEnum, Clone, Debug, PartialEq, Eq)]
|
||||||
|
enum NetworkReservationListFormat {
|
||||||
|
Table,
|
||||||
|
Json,
|
||||||
|
JsonPretty,
|
||||||
|
Jsonl,
|
||||||
|
Yaml,
|
||||||
|
KeyValue,
|
||||||
|
Simple,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Parser)]
|
||||||
|
#[command(about = "List network reservation information")]
|
||||||
|
pub struct NetworkReservationListCommand {
|
||||||
|
#[arg(short, long, default_value = "table", help = "Output format")]
|
||||||
|
format: NetworkReservationListFormat,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl NetworkReservationListCommand {
|
||||||
|
pub async fn run(
|
||||||
|
self,
|
||||||
|
mut client: ControlServiceClient<Channel>,
|
||||||
|
_events: EventStream,
|
||||||
|
) -> Result<()> {
|
||||||
|
let reply = client
|
||||||
|
.list_network_reservations(ListNetworkReservationsRequest {})
|
||||||
|
.await?
|
||||||
|
.into_inner();
|
||||||
|
let mut reservations = reply.reservations;
|
||||||
|
|
||||||
|
reservations.sort_by(|a, b| a.uuid.cmp(&b.uuid));
|
||||||
|
|
||||||
|
match self.format {
|
||||||
|
NetworkReservationListFormat::Table => {
|
||||||
|
self.print_reservations_table(reservations)?;
|
||||||
|
}
|
||||||
|
|
||||||
|
NetworkReservationListFormat::Simple => {
|
||||||
|
for reservation in reservations {
|
||||||
|
println!(
|
||||||
|
"{}\t{}\t{}\t{}",
|
||||||
|
reservation.uuid, reservation.ipv4, reservation.ipv6, reservation.mac
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
NetworkReservationListFormat::Json
|
||||||
|
| NetworkReservationListFormat::JsonPretty
|
||||||
|
| NetworkReservationListFormat::Yaml => {
|
||||||
|
let mut values = Vec::new();
|
||||||
|
for device in reservations {
|
||||||
|
let message = proto2dynamic(device)?;
|
||||||
|
values.push(serde_json::to_value(message)?);
|
||||||
|
}
|
||||||
|
let value = Value::Array(values);
|
||||||
|
let encoded = if self.format == NetworkReservationListFormat::JsonPretty {
|
||||||
|
serde_json::to_string_pretty(&value)?
|
||||||
|
} else if self.format == NetworkReservationListFormat::Yaml {
|
||||||
|
serde_yaml::to_string(&value)?
|
||||||
|
} else {
|
||||||
|
serde_json::to_string(&value)?
|
||||||
|
};
|
||||||
|
println!("{}", encoded.trim());
|
||||||
|
}
|
||||||
|
|
||||||
|
NetworkReservationListFormat::Jsonl => {
|
||||||
|
for device in reservations {
|
||||||
|
let message = proto2dynamic(device)?;
|
||||||
|
println!("{}", serde_json::to_string(&message)?);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
NetworkReservationListFormat::KeyValue => {
|
||||||
|
self.print_key_value(reservations)?;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
fn print_reservations_table(&self, reservations: Vec<NetworkReservation>) -> Result<()> {
|
||||||
|
let mut table = Table::new();
|
||||||
|
table.load_preset(UTF8_FULL_CONDENSED);
|
||||||
|
table.set_content_arrangement(comfy_table::ContentArrangement::Dynamic);
|
||||||
|
table.set_header(vec!["uuid", "ipv4", "ipv6", "mac"]);
|
||||||
|
for reservation in reservations {
|
||||||
|
table.add_row(vec![
|
||||||
|
Cell::new(reservation.uuid),
|
||||||
|
Cell::new(reservation.ipv4),
|
||||||
|
Cell::new(reservation.ipv6),
|
||||||
|
Cell::new(reservation.mac),
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
if table.is_empty() {
|
||||||
|
println!("no network reservations found");
|
||||||
|
} else {
|
||||||
|
println!("{}", table);
|
||||||
|
}
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
fn print_key_value(&self, reservations: Vec<NetworkReservation>) -> Result<()> {
|
||||||
|
for reservation in reservations {
|
||||||
|
let kvs = proto2kv(reservation)?;
|
||||||
|
println!("{}", kv2line(kvs));
|
||||||
|
}
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
}
|
43
crates/ctl/src/cli/network/reservation/mod.rs
Normal file
43
crates/ctl/src/cli/network/reservation/mod.rs
Normal file
@ -0,0 +1,43 @@
|
|||||||
|
use anyhow::Result;
|
||||||
|
use clap::{Parser, Subcommand};
|
||||||
|
use list::NetworkReservationListCommand;
|
||||||
|
use tonic::transport::Channel;
|
||||||
|
|
||||||
|
use krata::events::EventStream;
|
||||||
|
use krata::v1::control::control_service_client::ControlServiceClient;
|
||||||
|
|
||||||
|
pub mod list;
|
||||||
|
|
||||||
|
#[derive(Parser)]
|
||||||
|
#[command(about = "Manage network reservations")]
|
||||||
|
pub struct NetworkReservationCommand {
|
||||||
|
#[command(subcommand)]
|
||||||
|
subcommand: NetworkReservationCommands,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl NetworkReservationCommand {
|
||||||
|
pub async fn run(
|
||||||
|
self,
|
||||||
|
client: ControlServiceClient<Channel>,
|
||||||
|
events: EventStream,
|
||||||
|
) -> Result<()> {
|
||||||
|
self.subcommand.run(client, events).await
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Subcommand)]
|
||||||
|
pub enum NetworkReservationCommands {
|
||||||
|
List(NetworkReservationListCommand),
|
||||||
|
}
|
||||||
|
|
||||||
|
impl NetworkReservationCommands {
|
||||||
|
pub async fn run(
|
||||||
|
self,
|
||||||
|
client: ControlServiceClient<Channel>,
|
||||||
|
events: EventStream,
|
||||||
|
) -> Result<()> {
|
||||||
|
match self {
|
||||||
|
NetworkReservationCommands::List(list) => list.run(client, events).await,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -1,21 +1,21 @@
|
|||||||
use crate::command::DaemonCommand;
|
use crate::command::DaemonCommand;
|
||||||
use crate::ip::assignment::IpAssignment;
|
use crate::network::assignment::NetworkAssignment;
|
||||||
use crate::zlt::ZoneLookupTable;
|
use crate::zlt::ZoneLookupTable;
|
||||||
use anyhow::Result;
|
use anyhow::Result;
|
||||||
use krata::v1::control::{GetHostStatusReply, GetHostStatusRequest};
|
use krata::v1::control::{GetHostStatusReply, GetHostStatusRequest};
|
||||||
|
|
||||||
pub struct GetHostStatusRpc {
|
pub struct GetHostStatusRpc {
|
||||||
ip: IpAssignment,
|
network: NetworkAssignment,
|
||||||
zlt: ZoneLookupTable,
|
zlt: ZoneLookupTable,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl GetHostStatusRpc {
|
impl GetHostStatusRpc {
|
||||||
pub fn new(ip: IpAssignment, zlt: ZoneLookupTable) -> Self {
|
pub fn new(ip: NetworkAssignment, zlt: ZoneLookupTable) -> Self {
|
||||||
Self { ip, zlt }
|
Self { network: ip, zlt }
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn process(self, _request: GetHostStatusRequest) -> Result<GetHostStatusReply> {
|
pub async fn process(self, _request: GetHostStatusRequest) -> Result<GetHostStatusReply> {
|
||||||
let host_reservation = self.ip.retrieve(self.zlt.host_uuid()).await?;
|
let host_reservation = self.network.retrieve(self.zlt.host_uuid()).await?;
|
||||||
Ok(GetHostStatusReply {
|
Ok(GetHostStatusReply {
|
||||||
host_domid: self.zlt.host_domid(),
|
host_domid: self.zlt.host_domid(),
|
||||||
host_uuid: self.zlt.host_uuid().to_string(),
|
host_uuid: self.zlt.host_uuid().to_string(),
|
||||||
|
28
crates/daemon/src/control/list_network_reservations.rs
Normal file
28
crates/daemon/src/control/list_network_reservations.rs
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
use anyhow::Result;
|
||||||
|
|
||||||
|
use krata::v1::{
|
||||||
|
common::NetworkReservation,
|
||||||
|
control::{ListNetworkReservationsReply, ListNetworkReservationsRequest},
|
||||||
|
};
|
||||||
|
|
||||||
|
use crate::network::assignment::NetworkAssignment;
|
||||||
|
|
||||||
|
pub struct ListNetworkReservationsRpc {
|
||||||
|
network: NetworkAssignment,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl ListNetworkReservationsRpc {
|
||||||
|
pub fn new(network: NetworkAssignment) -> Self {
|
||||||
|
Self { network }
|
||||||
|
}
|
||||||
|
|
||||||
|
pub async fn process(
|
||||||
|
self,
|
||||||
|
_request: ListNetworkReservationsRequest,
|
||||||
|
) -> Result<ListNetworkReservationsReply> {
|
||||||
|
let state = self.network.read_reservations().await?;
|
||||||
|
let reservations: Vec<NetworkReservation> =
|
||||||
|
state.into_values().map(|x| x.into()).collect::<Vec<_>>();
|
||||||
|
Ok(ListNetworkReservationsReply { reservations })
|
||||||
|
}
|
||||||
|
}
|
@ -2,6 +2,7 @@ use std::pin::Pin;
|
|||||||
|
|
||||||
use anyhow::Error;
|
use anyhow::Error;
|
||||||
use futures::Stream;
|
use futures::Stream;
|
||||||
|
use list_network_reservations::ListNetworkReservationsRpc;
|
||||||
use tokio::sync::mpsc::Sender;
|
use tokio::sync::mpsc::Sender;
|
||||||
use tonic::{Request, Response, Status, Streaming};
|
use tonic::{Request, Response, Status, Streaming};
|
||||||
use uuid::Uuid;
|
use uuid::Uuid;
|
||||||
@ -17,8 +18,8 @@ use krata::v1::control::{
|
|||||||
WatchEventsRequest, ZoneConsoleReply, ZoneConsoleRequest,
|
WatchEventsRequest, ZoneConsoleReply, ZoneConsoleRequest,
|
||||||
};
|
};
|
||||||
use krata::v1::control::{
|
use krata::v1::control::{
|
||||||
GetZoneReply, GetZoneRequest, SetHostPowerManagementPolicyReply,
|
GetZoneReply, GetZoneRequest, ListNetworkReservationsReply, ListNetworkReservationsRequest,
|
||||||
SetHostPowerManagementPolicyRequest,
|
SetHostPowerManagementPolicyReply, SetHostPowerManagementPolicyRequest,
|
||||||
};
|
};
|
||||||
use krataoci::packer::service::OciPackerService;
|
use krataoci::packer::service::OciPackerService;
|
||||||
use kratart::Runtime;
|
use kratart::Runtime;
|
||||||
@ -41,7 +42,7 @@ use crate::control::snoop_idm::SnoopIdmRpc;
|
|||||||
use crate::control::update_zone_resources::UpdateZoneResourcesRpc;
|
use crate::control::update_zone_resources::UpdateZoneResourcesRpc;
|
||||||
use crate::control::watch_events::WatchEventsRpc;
|
use crate::control::watch_events::WatchEventsRpc;
|
||||||
use crate::db::zone::ZoneStore;
|
use crate::db::zone::ZoneStore;
|
||||||
use crate::ip::assignment::IpAssignment;
|
use crate::network::assignment::NetworkAssignment;
|
||||||
use crate::{
|
use crate::{
|
||||||
console::DaemonConsoleHandle, devices::DaemonDeviceManager, event::DaemonEventContext,
|
console::DaemonConsoleHandle, devices::DaemonDeviceManager, event::DaemonEventContext,
|
||||||
idm::DaemonIdmHandle, zlt::ZoneLookupTable,
|
idm::DaemonIdmHandle, zlt::ZoneLookupTable,
|
||||||
@ -55,6 +56,7 @@ pub mod get_host_cpu_topology;
|
|||||||
pub mod get_host_status;
|
pub mod get_host_status;
|
||||||
pub mod get_zone;
|
pub mod get_zone;
|
||||||
pub mod list_devices;
|
pub mod list_devices;
|
||||||
|
pub mod list_network_reservations;
|
||||||
pub mod list_zones;
|
pub mod list_zones;
|
||||||
pub mod pull_image;
|
pub mod pull_image;
|
||||||
pub mod read_hypervisor_console;
|
pub mod read_hypervisor_console;
|
||||||
@ -91,7 +93,7 @@ pub struct DaemonControlService {
|
|||||||
console: DaemonConsoleHandle,
|
console: DaemonConsoleHandle,
|
||||||
idm: DaemonIdmHandle,
|
idm: DaemonIdmHandle,
|
||||||
zones: ZoneStore,
|
zones: ZoneStore,
|
||||||
ip: IpAssignment,
|
network: NetworkAssignment,
|
||||||
zone_reconciler_notify: Sender<Uuid>,
|
zone_reconciler_notify: Sender<Uuid>,
|
||||||
packer: OciPackerService,
|
packer: OciPackerService,
|
||||||
runtime: Runtime,
|
runtime: Runtime,
|
||||||
@ -106,7 +108,7 @@ impl DaemonControlService {
|
|||||||
console: DaemonConsoleHandle,
|
console: DaemonConsoleHandle,
|
||||||
idm: DaemonIdmHandle,
|
idm: DaemonIdmHandle,
|
||||||
zones: ZoneStore,
|
zones: ZoneStore,
|
||||||
ip: IpAssignment,
|
network: NetworkAssignment,
|
||||||
zone_reconciler_notify: Sender<Uuid>,
|
zone_reconciler_notify: Sender<Uuid>,
|
||||||
packer: OciPackerService,
|
packer: OciPackerService,
|
||||||
runtime: Runtime,
|
runtime: Runtime,
|
||||||
@ -118,7 +120,7 @@ impl DaemonControlService {
|
|||||||
console,
|
console,
|
||||||
idm,
|
idm,
|
||||||
zones,
|
zones,
|
||||||
ip,
|
network,
|
||||||
zone_reconciler_notify,
|
zone_reconciler_notify,
|
||||||
packer,
|
packer,
|
||||||
runtime,
|
runtime,
|
||||||
@ -134,7 +136,7 @@ impl ControlService for DaemonControlService {
|
|||||||
) -> Result<Response<GetHostStatusReply>, Status> {
|
) -> Result<Response<GetHostStatusReply>, Status> {
|
||||||
let request = request.into_inner();
|
let request = request.into_inner();
|
||||||
adapt(
|
adapt(
|
||||||
GetHostStatusRpc::new(self.ip.clone(), self.zlt.clone())
|
GetHostStatusRpc::new(self.network.clone(), self.zlt.clone())
|
||||||
.process(request)
|
.process(request)
|
||||||
.await,
|
.await,
|
||||||
)
|
)
|
||||||
@ -191,6 +193,18 @@ impl ControlService for DaemonControlService {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async fn list_network_reservations(
|
||||||
|
&self,
|
||||||
|
request: Request<ListNetworkReservationsRequest>,
|
||||||
|
) -> Result<Response<ListNetworkReservationsReply>, Status> {
|
||||||
|
let request = request.into_inner();
|
||||||
|
adapt(
|
||||||
|
ListNetworkReservationsRpc::new(self.network.clone())
|
||||||
|
.process(request)
|
||||||
|
.await,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
type PullImageStream =
|
type PullImageStream =
|
||||||
Pin<Box<dyn Stream<Item = Result<PullImageReply, Status>> + Send + 'static>>;
|
Pin<Box<dyn Stream<Item = Result<PullImageReply, Status>> + Send + 'static>>;
|
||||||
|
|
||||||
|
@ -3,7 +3,7 @@ use redb::Database;
|
|||||||
use std::path::Path;
|
use std::path::Path;
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
|
|
||||||
pub mod ip;
|
pub mod network;
|
||||||
pub mod zone;
|
pub mod zone;
|
||||||
|
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
use crate::db::KrataDatabase;
|
use crate::db::KrataDatabase;
|
||||||
use advmac::MacAddr6;
|
use advmac::MacAddr6;
|
||||||
use anyhow::Result;
|
use anyhow::Result;
|
||||||
|
use krata::v1::common::NetworkReservation as ApiNetworkReservation;
|
||||||
use log::error;
|
use log::error;
|
||||||
use redb::{ReadableTable, TableDefinition};
|
use redb::{ReadableTable, TableDefinition};
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
@ -8,24 +9,25 @@ use std::collections::HashMap;
|
|||||||
use std::net::{Ipv4Addr, Ipv6Addr};
|
use std::net::{Ipv4Addr, Ipv6Addr};
|
||||||
use uuid::Uuid;
|
use uuid::Uuid;
|
||||||
|
|
||||||
const IP_RESERVATION_TABLE: TableDefinition<u128, &[u8]> = TableDefinition::new("ip-reservation");
|
const NETWORK_RESERVATION_TABLE: TableDefinition<u128, &[u8]> =
|
||||||
|
TableDefinition::new("network-reservation");
|
||||||
|
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
pub struct IpReservationStore {
|
pub struct NetworkReservationStore {
|
||||||
db: KrataDatabase,
|
db: KrataDatabase,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl IpReservationStore {
|
impl NetworkReservationStore {
|
||||||
pub fn open(db: KrataDatabase) -> Result<Self> {
|
pub fn open(db: KrataDatabase) -> Result<Self> {
|
||||||
let write = db.database.begin_write()?;
|
let write = db.database.begin_write()?;
|
||||||
let _ = write.open_table(IP_RESERVATION_TABLE);
|
let _ = write.open_table(NETWORK_RESERVATION_TABLE);
|
||||||
write.commit()?;
|
write.commit()?;
|
||||||
Ok(IpReservationStore { db })
|
Ok(NetworkReservationStore { db })
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn read(&self, id: Uuid) -> Result<Option<IpReservation>> {
|
pub async fn read(&self, id: Uuid) -> Result<Option<NetworkReservation>> {
|
||||||
let read = self.db.database.begin_read()?;
|
let read = self.db.database.begin_read()?;
|
||||||
let table = read.open_table(IP_RESERVATION_TABLE)?;
|
let table = read.open_table(NETWORK_RESERVATION_TABLE)?;
|
||||||
let Some(entry) = table.get(id.to_u128_le())? else {
|
let Some(entry) = table.get(id.to_u128_le())? else {
|
||||||
return Ok(None);
|
return Ok(None);
|
||||||
};
|
};
|
||||||
@ -33,26 +35,26 @@ impl IpReservationStore {
|
|||||||
Ok(Some(serde_json::from_slice(bytes)?))
|
Ok(Some(serde_json::from_slice(bytes)?))
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn list(&self) -> Result<HashMap<Uuid, IpReservation>> {
|
pub async fn list(&self) -> Result<HashMap<Uuid, NetworkReservation>> {
|
||||||
enum ListEntry {
|
enum ListEntry {
|
||||||
Valid(Uuid, IpReservation),
|
Valid(Uuid, NetworkReservation),
|
||||||
Invalid(Uuid),
|
Invalid(Uuid),
|
||||||
}
|
}
|
||||||
let mut reservations: HashMap<Uuid, IpReservation> = HashMap::new();
|
let mut reservations: HashMap<Uuid, NetworkReservation> = HashMap::new();
|
||||||
|
|
||||||
let corruptions = {
|
let corruptions = {
|
||||||
let read = self.db.database.begin_read()?;
|
let read = self.db.database.begin_read()?;
|
||||||
let table = read.open_table(IP_RESERVATION_TABLE)?;
|
let table = read.open_table(NETWORK_RESERVATION_TABLE)?;
|
||||||
table
|
table
|
||||||
.iter()?
|
.iter()?
|
||||||
.flat_map(|result| {
|
.flat_map(|result| {
|
||||||
result.map(|(key, value)| {
|
result.map(|(key, value)| {
|
||||||
let uuid = Uuid::from_u128_le(key.value());
|
let uuid = Uuid::from_u128_le(key.value());
|
||||||
match serde_json::from_slice::<IpReservation>(value.value()) {
|
match serde_json::from_slice::<NetworkReservation>(value.value()) {
|
||||||
Ok(reservation) => ListEntry::Valid(uuid, reservation),
|
Ok(reservation) => ListEntry::Valid(uuid, reservation),
|
||||||
Err(error) => {
|
Err(error) => {
|
||||||
error!(
|
error!(
|
||||||
"found invalid ip reservation in database for uuid {}: {}",
|
"found invalid network reservation in database for uuid {}: {}",
|
||||||
uuid, error
|
uuid, error
|
||||||
);
|
);
|
||||||
ListEntry::Invalid(uuid)
|
ListEntry::Invalid(uuid)
|
||||||
@ -73,7 +75,7 @@ impl IpReservationStore {
|
|||||||
|
|
||||||
if !corruptions.is_empty() {
|
if !corruptions.is_empty() {
|
||||||
let write = self.db.database.begin_write()?;
|
let write = self.db.database.begin_write()?;
|
||||||
let mut table = write.open_table(IP_RESERVATION_TABLE)?;
|
let mut table = write.open_table(NETWORK_RESERVATION_TABLE)?;
|
||||||
for corruption in corruptions {
|
for corruption in corruptions {
|
||||||
table.remove(corruption.to_u128_le())?;
|
table.remove(corruption.to_u128_le())?;
|
||||||
}
|
}
|
||||||
@ -82,10 +84,10 @@ impl IpReservationStore {
|
|||||||
Ok(reservations)
|
Ok(reservations)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn update(&self, id: Uuid, entry: IpReservation) -> Result<()> {
|
pub async fn update(&self, id: Uuid, entry: NetworkReservation) -> Result<()> {
|
||||||
let write = self.db.database.begin_write()?;
|
let write = self.db.database.begin_write()?;
|
||||||
{
|
{
|
||||||
let mut table = write.open_table(IP_RESERVATION_TABLE)?;
|
let mut table = write.open_table(NETWORK_RESERVATION_TABLE)?;
|
||||||
let bytes = serde_json::to_vec(&entry)?;
|
let bytes = serde_json::to_vec(&entry)?;
|
||||||
table.insert(id.to_u128_le(), bytes.as_slice())?;
|
table.insert(id.to_u128_le(), bytes.as_slice())?;
|
||||||
}
|
}
|
||||||
@ -96,7 +98,7 @@ impl IpReservationStore {
|
|||||||
pub async fn remove(&self, id: Uuid) -> Result<()> {
|
pub async fn remove(&self, id: Uuid) -> Result<()> {
|
||||||
let write = self.db.database.begin_write()?;
|
let write = self.db.database.begin_write()?;
|
||||||
{
|
{
|
||||||
let mut table = write.open_table(IP_RESERVATION_TABLE)?;
|
let mut table = write.open_table(NETWORK_RESERVATION_TABLE)?;
|
||||||
table.remove(id.to_u128_le())?;
|
table.remove(id.to_u128_le())?;
|
||||||
}
|
}
|
||||||
write.commit()?;
|
write.commit()?;
|
||||||
@ -105,7 +107,7 @@ impl IpReservationStore {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Serialize, Deserialize, Clone, Debug)]
|
#[derive(Serialize, Deserialize, Clone, Debug)]
|
||||||
pub struct IpReservation {
|
pub struct NetworkReservation {
|
||||||
pub uuid: String,
|
pub uuid: String,
|
||||||
pub ipv4: Ipv4Addr,
|
pub ipv4: Ipv4Addr,
|
||||||
pub ipv6: Ipv6Addr,
|
pub ipv6: Ipv6Addr,
|
||||||
@ -116,3 +118,17 @@ pub struct IpReservation {
|
|||||||
pub gateway_ipv6: Ipv6Addr,
|
pub gateway_ipv6: Ipv6Addr,
|
||||||
pub gateway_mac: MacAddr6,
|
pub gateway_mac: MacAddr6,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl From<NetworkReservation> for ApiNetworkReservation {
|
||||||
|
fn from(val: NetworkReservation) -> Self {
|
||||||
|
ApiNetworkReservation {
|
||||||
|
uuid: val.uuid,
|
||||||
|
ipv4: format!("{}/{}", val.ipv4, val.ipv4_prefix),
|
||||||
|
ipv6: format!("{}/{}", val.ipv6, val.ipv6_prefix),
|
||||||
|
mac: val.mac.to_string().to_lowercase().replace('-', ":"),
|
||||||
|
gateway_ipv4: format!("{}/{}", val.gateway_ipv4, val.ipv4_prefix),
|
||||||
|
gateway_ipv6: format!("{}/{}", val.gateway_ipv6, val.ipv6_prefix),
|
||||||
|
gateway_mac: val.gateway_mac.to_string().to_lowercase().replace('-', ":"),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -1,7 +1,7 @@
|
|||||||
use crate::db::ip::IpReservationStore;
|
use crate::db::network::NetworkReservationStore;
|
||||||
use crate::db::zone::ZoneStore;
|
use crate::db::zone::ZoneStore;
|
||||||
use crate::db::KrataDatabase;
|
use crate::db::KrataDatabase;
|
||||||
use crate::ip::assignment::IpAssignment;
|
use crate::network::assignment::NetworkAssignment;
|
||||||
use anyhow::{anyhow, Result};
|
use anyhow::{anyhow, Result};
|
||||||
use config::DaemonConfig;
|
use config::DaemonConfig;
|
||||||
use console::{DaemonConsole, DaemonConsoleHandle};
|
use console::{DaemonConsole, DaemonConsoleHandle};
|
||||||
@ -37,18 +37,19 @@ pub mod db;
|
|||||||
pub mod devices;
|
pub mod devices;
|
||||||
pub mod event;
|
pub mod event;
|
||||||
pub mod idm;
|
pub mod idm;
|
||||||
pub mod ip;
|
|
||||||
pub mod metrics;
|
pub mod metrics;
|
||||||
|
pub mod network;
|
||||||
pub mod oci;
|
pub mod oci;
|
||||||
pub mod reconcile;
|
pub mod reconcile;
|
||||||
pub mod zlt;
|
pub mod zlt;
|
||||||
|
|
||||||
pub struct Daemon {
|
pub struct Daemon {
|
||||||
store: String,
|
store: String,
|
||||||
_config: Arc<DaemonConfig>,
|
_config: Arc<DaemonConfig>,
|
||||||
zlt: ZoneLookupTable,
|
zlt: ZoneLookupTable,
|
||||||
devices: DaemonDeviceManager,
|
devices: DaemonDeviceManager,
|
||||||
zones: ZoneStore,
|
zones: ZoneStore,
|
||||||
ip: IpAssignment,
|
network: NetworkAssignment,
|
||||||
events: DaemonEventContext,
|
events: DaemonEventContext,
|
||||||
zone_reconciler_task: JoinHandle<()>,
|
zone_reconciler_task: JoinHandle<()>,
|
||||||
zone_reconciler_notify: Sender<Uuid>,
|
zone_reconciler_notify: Sender<Uuid>,
|
||||||
@ -127,9 +128,14 @@ impl Daemon {
|
|||||||
let runtime_for_reconciler = runtime.dupe().await?;
|
let runtime_for_reconciler = runtime.dupe().await?;
|
||||||
let ipv4_network = Ipv4Network::from_str(&config.network.ipv4.subnet)?;
|
let ipv4_network = Ipv4Network::from_str(&config.network.ipv4.subnet)?;
|
||||||
let ipv6_network = Ipv6Network::from_str(&config.network.ipv6.subnet)?;
|
let ipv6_network = Ipv6Network::from_str(&config.network.ipv6.subnet)?;
|
||||||
let ip_reservation_store = IpReservationStore::open(database)?;
|
let network_reservation_store = NetworkReservationStore::open(database)?;
|
||||||
let ip =
|
let network = NetworkAssignment::new(
|
||||||
IpAssignment::new(host_uuid, ipv4_network, ipv6_network, ip_reservation_store).await?;
|
host_uuid,
|
||||||
|
ipv4_network,
|
||||||
|
ipv6_network,
|
||||||
|
network_reservation_store,
|
||||||
|
)
|
||||||
|
.await?;
|
||||||
debug!("initializing zone reconciler");
|
debug!("initializing zone reconciler");
|
||||||
let zone_reconciler = ZoneReconciler::new(
|
let zone_reconciler = ZoneReconciler::new(
|
||||||
devices.clone(),
|
devices.clone(),
|
||||||
@ -142,7 +148,7 @@ impl Daemon {
|
|||||||
kernel_path,
|
kernel_path,
|
||||||
initrd_path,
|
initrd_path,
|
||||||
addons_path,
|
addons_path,
|
||||||
ip.clone(),
|
network.clone(),
|
||||||
config.clone(),
|
config.clone(),
|
||||||
)?;
|
)?;
|
||||||
|
|
||||||
@ -165,7 +171,7 @@ impl Daemon {
|
|||||||
zlt,
|
zlt,
|
||||||
devices,
|
devices,
|
||||||
zones,
|
zones,
|
||||||
ip,
|
network,
|
||||||
events,
|
events,
|
||||||
zone_reconciler_task,
|
zone_reconciler_task,
|
||||||
zone_reconciler_notify,
|
zone_reconciler_notify,
|
||||||
@ -186,7 +192,7 @@ impl Daemon {
|
|||||||
self.console.clone(),
|
self.console.clone(),
|
||||||
self.idm.clone(),
|
self.idm.clone(),
|
||||||
self.zones.clone(),
|
self.zones.clone(),
|
||||||
self.ip.clone(),
|
self.network.clone(),
|
||||||
self.zone_reconciler_notify.clone(),
|
self.zone_reconciler_notify.clone(),
|
||||||
self.packer.clone(),
|
self.packer.clone(),
|
||||||
self.runtime.clone(),
|
self.runtime.clone(),
|
||||||
|
@ -9,37 +9,37 @@ use std::{
|
|||||||
use tokio::sync::RwLock;
|
use tokio::sync::RwLock;
|
||||||
use uuid::Uuid;
|
use uuid::Uuid;
|
||||||
|
|
||||||
use crate::db::ip::{IpReservation, IpReservationStore};
|
use crate::db::network::{NetworkReservation, NetworkReservationStore};
|
||||||
|
|
||||||
#[derive(Default, Clone)]
|
#[derive(Default, Clone)]
|
||||||
pub struct IpAssignmentState {
|
pub struct NetworkAssignmentState {
|
||||||
pub ipv4: HashMap<Ipv4Addr, IpReservation>,
|
pub ipv4: HashMap<Ipv4Addr, NetworkReservation>,
|
||||||
pub ipv6: HashMap<Ipv6Addr, IpReservation>,
|
pub ipv6: HashMap<Ipv6Addr, NetworkReservation>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
pub struct IpAssignment {
|
pub struct NetworkAssignment {
|
||||||
ipv4_network: Ipv4Network,
|
ipv4_network: Ipv4Network,
|
||||||
ipv6_network: Ipv6Network,
|
ipv6_network: Ipv6Network,
|
||||||
gateway_ipv4: Ipv4Addr,
|
gateway_ipv4: Ipv4Addr,
|
||||||
gateway_ipv6: Ipv6Addr,
|
gateway_ipv6: Ipv6Addr,
|
||||||
gateway_mac: MacAddr6,
|
gateway_mac: MacAddr6,
|
||||||
store: IpReservationStore,
|
store: NetworkReservationStore,
|
||||||
state: Arc<RwLock<IpAssignmentState>>,
|
state: Arc<RwLock<NetworkAssignmentState>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl IpAssignment {
|
impl NetworkAssignment {
|
||||||
pub async fn new(
|
pub async fn new(
|
||||||
host_uuid: Uuid,
|
host_uuid: Uuid,
|
||||||
ipv4_network: Ipv4Network,
|
ipv4_network: Ipv4Network,
|
||||||
ipv6_network: Ipv6Network,
|
ipv6_network: Ipv6Network,
|
||||||
store: IpReservationStore,
|
store: NetworkReservationStore,
|
||||||
) -> Result<Self> {
|
) -> Result<Self> {
|
||||||
let mut state = IpAssignment::fetch_current_state(&store).await?;
|
let mut state = NetworkAssignment::fetch_current_state(&store).await?;
|
||||||
let gateway_reservation = if let Some(reservation) = store.read(Uuid::nil()).await? {
|
let gateway_reservation = if let Some(reservation) = store.read(Uuid::nil()).await? {
|
||||||
reservation
|
reservation
|
||||||
} else {
|
} else {
|
||||||
IpAssignment::allocate(
|
NetworkAssignment::allocate(
|
||||||
&mut state,
|
&mut state,
|
||||||
&store,
|
&store,
|
||||||
Uuid::nil(),
|
Uuid::nil(),
|
||||||
@ -53,7 +53,7 @@ impl IpAssignment {
|
|||||||
};
|
};
|
||||||
|
|
||||||
if store.read(host_uuid).await?.is_none() {
|
if store.read(host_uuid).await?.is_none() {
|
||||||
let _ = IpAssignment::allocate(
|
let _ = NetworkAssignment::allocate(
|
||||||
&mut state,
|
&mut state,
|
||||||
&store,
|
&store,
|
||||||
host_uuid,
|
host_uuid,
|
||||||
@ -66,7 +66,7 @@ impl IpAssignment {
|
|||||||
.await?;
|
.await?;
|
||||||
}
|
}
|
||||||
|
|
||||||
let assignment = IpAssignment {
|
let assignment = NetworkAssignment {
|
||||||
ipv4_network,
|
ipv4_network,
|
||||||
ipv6_network,
|
ipv6_network,
|
||||||
gateway_ipv4: gateway_reservation.ipv4,
|
gateway_ipv4: gateway_reservation.ipv4,
|
||||||
@ -78,9 +78,11 @@ impl IpAssignment {
|
|||||||
Ok(assignment)
|
Ok(assignment)
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn fetch_current_state(store: &IpReservationStore) -> Result<IpAssignmentState> {
|
async fn fetch_current_state(
|
||||||
|
store: &NetworkReservationStore,
|
||||||
|
) -> Result<NetworkAssignmentState> {
|
||||||
let reservations = store.list().await?;
|
let reservations = store.list().await?;
|
||||||
let mut state = IpAssignmentState::default();
|
let mut state = NetworkAssignmentState::default();
|
||||||
for reservation in reservations.values() {
|
for reservation in reservations.values() {
|
||||||
state.ipv4.insert(reservation.ipv4, reservation.clone());
|
state.ipv4.insert(reservation.ipv4, reservation.clone());
|
||||||
state.ipv6.insert(reservation.ipv6, reservation.clone());
|
state.ipv6.insert(reservation.ipv6, reservation.clone());
|
||||||
@ -90,15 +92,15 @@ impl IpAssignment {
|
|||||||
|
|
||||||
#[allow(clippy::too_many_arguments)]
|
#[allow(clippy::too_many_arguments)]
|
||||||
async fn allocate(
|
async fn allocate(
|
||||||
state: &mut IpAssignmentState,
|
state: &mut NetworkAssignmentState,
|
||||||
store: &IpReservationStore,
|
store: &NetworkReservationStore,
|
||||||
uuid: Uuid,
|
uuid: Uuid,
|
||||||
ipv4_network: Ipv4Network,
|
ipv4_network: Ipv4Network,
|
||||||
ipv6_network: Ipv6Network,
|
ipv6_network: Ipv6Network,
|
||||||
gateway_ipv4: Option<Ipv4Addr>,
|
gateway_ipv4: Option<Ipv4Addr>,
|
||||||
gateway_ipv6: Option<Ipv6Addr>,
|
gateway_ipv6: Option<Ipv6Addr>,
|
||||||
gateway_mac: Option<MacAddr6>,
|
gateway_mac: Option<MacAddr6>,
|
||||||
) -> Result<IpReservation> {
|
) -> Result<NetworkReservation> {
|
||||||
let found_ipv4: Option<Ipv4Addr> = ipv4_network
|
let found_ipv4: Option<Ipv4Addr> = ipv4_network
|
||||||
.iter()
|
.iter()
|
||||||
.filter(|ip| {
|
.filter(|ip| {
|
||||||
@ -136,7 +138,7 @@ impl IpAssignment {
|
|||||||
mac.set_local(true);
|
mac.set_local(true);
|
||||||
mac.set_multicast(false);
|
mac.set_multicast(false);
|
||||||
|
|
||||||
let reservation = IpReservation {
|
let reservation = NetworkReservation {
|
||||||
uuid: uuid.to_string(),
|
uuid: uuid.to_string(),
|
||||||
ipv4,
|
ipv4,
|
||||||
ipv6,
|
ipv6,
|
||||||
@ -153,9 +155,9 @@ impl IpAssignment {
|
|||||||
Ok(reservation)
|
Ok(reservation)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn assign(&self, uuid: Uuid) -> Result<IpReservation> {
|
pub async fn assign(&self, uuid: Uuid) -> Result<NetworkReservation> {
|
||||||
let mut state = self.state.write().await;
|
let mut state = self.state.write().await;
|
||||||
let reservation = IpAssignment::allocate(
|
let reservation = NetworkAssignment::allocate(
|
||||||
&mut state,
|
&mut state,
|
||||||
&self.store,
|
&self.store,
|
||||||
uuid,
|
uuid,
|
||||||
@ -181,18 +183,22 @@ impl IpAssignment {
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn retrieve(&self, uuid: Uuid) -> Result<Option<IpReservation>> {
|
pub async fn retrieve(&self, uuid: Uuid) -> Result<Option<NetworkReservation>> {
|
||||||
self.store.read(uuid).await
|
self.store.read(uuid).await
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn reload(&self) -> Result<()> {
|
pub async fn reload(&self) -> Result<()> {
|
||||||
let mut state = self.state.write().await;
|
let mut state = self.state.write().await;
|
||||||
let intermediate = IpAssignment::fetch_current_state(&self.store).await?;
|
let intermediate = NetworkAssignment::fetch_current_state(&self.store).await?;
|
||||||
*state = intermediate;
|
*state = intermediate;
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn read(&self) -> Result<IpAssignmentState> {
|
pub async fn read(&self) -> Result<NetworkAssignmentState> {
|
||||||
Ok(self.state.read().await.clone())
|
Ok(self.state.read().await.clone())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub async fn read_reservations(&self) -> Result<HashMap<Uuid, NetworkReservation>> {
|
||||||
|
self.store.list().await
|
||||||
|
}
|
||||||
}
|
}
|
@ -14,8 +14,8 @@ use std::sync::atomic::{AtomicBool, Ordering};
|
|||||||
|
|
||||||
use crate::config::{DaemonConfig, DaemonPciDeviceRdmReservePolicy};
|
use crate::config::{DaemonConfig, DaemonPciDeviceRdmReservePolicy};
|
||||||
use crate::devices::DaemonDeviceManager;
|
use crate::devices::DaemonDeviceManager;
|
||||||
use crate::ip::assignment::IpAssignment;
|
use crate::network::assignment::NetworkAssignment;
|
||||||
use crate::reconcile::zone::ip_reservation_to_network_status;
|
use crate::reconcile::zone::network_reservation_to_network_status;
|
||||||
use crate::{reconcile::zone::ZoneReconcilerResult, zlt::ZoneLookupTable};
|
use crate::{reconcile::zone::ZoneReconcilerResult, zlt::ZoneLookupTable};
|
||||||
use krata::v1::common::zone_image_spec::Image;
|
use krata::v1::common::zone_image_spec::Image;
|
||||||
use tokio::fs::{self, File};
|
use tokio::fs::{self, File};
|
||||||
@ -29,7 +29,7 @@ pub struct ZoneCreator<'a> {
|
|||||||
pub initrd_path: &'a Path,
|
pub initrd_path: &'a Path,
|
||||||
pub addons_path: &'a Path,
|
pub addons_path: &'a Path,
|
||||||
pub packer: &'a OciPackerService,
|
pub packer: &'a OciPackerService,
|
||||||
pub ip_assignment: &'a IpAssignment,
|
pub network_assignment: &'a NetworkAssignment,
|
||||||
pub zlt: &'a ZoneLookupTable,
|
pub zlt: &'a ZoneLookupTable,
|
||||||
pub runtime: &'a Runtime,
|
pub runtime: &'a Runtime,
|
||||||
pub config: &'a DaemonConfig,
|
pub config: &'a DaemonConfig,
|
||||||
@ -174,7 +174,7 @@ impl ZoneCreator<'_> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let reservation = self.ip_assignment.assign(uuid).await?;
|
let reservation = self.network_assignment.assign(uuid).await?;
|
||||||
|
|
||||||
let mut initial_resources = spec.initial_resources.unwrap_or_default();
|
let mut initial_resources = spec.initial_resources.unwrap_or_default();
|
||||||
if initial_resources.target_cpus < 1 {
|
if initial_resources.target_cpus < 1 {
|
||||||
@ -236,7 +236,7 @@ impl ZoneCreator<'_> {
|
|||||||
info!("created zone {}", uuid);
|
info!("created zone {}", uuid);
|
||||||
zone.status = Some(ZoneStatus {
|
zone.status = Some(ZoneStatus {
|
||||||
state: ZoneState::Created.into(),
|
state: ZoneState::Created.into(),
|
||||||
network_status: Some(ip_reservation_to_network_status(&reservation)),
|
network_status: Some(network_reservation_to_network_status(&reservation)),
|
||||||
exit_status: None,
|
exit_status: None,
|
||||||
error_status: None,
|
error_status: None,
|
||||||
resource_status: Some(ZoneResourceStatus {
|
resource_status: Some(ZoneResourceStatus {
|
||||||
|
@ -7,8 +7,8 @@ use std::{
|
|||||||
|
|
||||||
use self::create::ZoneCreator;
|
use self::create::ZoneCreator;
|
||||||
use crate::config::DaemonConfig;
|
use crate::config::DaemonConfig;
|
||||||
use crate::db::ip::IpReservation;
|
use crate::db::network::NetworkReservation;
|
||||||
use crate::ip::assignment::IpAssignment;
|
use crate::network::assignment::NetworkAssignment;
|
||||||
use crate::{
|
use crate::{
|
||||||
db::zone::ZoneStore,
|
db::zone::ZoneStore,
|
||||||
devices::DaemonDeviceManager,
|
devices::DaemonDeviceManager,
|
||||||
@ -62,7 +62,7 @@ pub struct ZoneReconciler {
|
|||||||
tasks: Arc<RwLock<HashMap<Uuid, ZoneReconcilerEntry>>>,
|
tasks: Arc<RwLock<HashMap<Uuid, ZoneReconcilerEntry>>>,
|
||||||
zone_reconciler_notify: Sender<Uuid>,
|
zone_reconciler_notify: Sender<Uuid>,
|
||||||
zone_reconcile_lock: Arc<RwLock<()>>,
|
zone_reconcile_lock: Arc<RwLock<()>>,
|
||||||
ip_assignment: IpAssignment,
|
ip_assignment: NetworkAssignment,
|
||||||
config: Arc<DaemonConfig>,
|
config: Arc<DaemonConfig>,
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -79,7 +79,7 @@ impl ZoneReconciler {
|
|||||||
kernel_path: PathBuf,
|
kernel_path: PathBuf,
|
||||||
initrd_path: PathBuf,
|
initrd_path: PathBuf,
|
||||||
modules_path: PathBuf,
|
modules_path: PathBuf,
|
||||||
ip_assignment: IpAssignment,
|
ip_assignment: NetworkAssignment,
|
||||||
config: Arc<DaemonConfig>,
|
config: Arc<DaemonConfig>,
|
||||||
) -> Result<Self> {
|
) -> Result<Self> {
|
||||||
Ok(Self {
|
Ok(Self {
|
||||||
@ -195,7 +195,7 @@ impl ZoneReconciler {
|
|||||||
|
|
||||||
if let Some(reservation) = self.ip_assignment.retrieve(uuid).await? {
|
if let Some(reservation) = self.ip_assignment.retrieve(uuid).await? {
|
||||||
status.network_status =
|
status.network_status =
|
||||||
Some(ip_reservation_to_network_status(&reservation));
|
Some(network_reservation_to_network_status(&reservation));
|
||||||
}
|
}
|
||||||
stored_zone.status = Some(status);
|
stored_zone.status = Some(status);
|
||||||
}
|
}
|
||||||
@ -286,7 +286,7 @@ impl ZoneReconciler {
|
|||||||
initrd_path: &self.initrd_path,
|
initrd_path: &self.initrd_path,
|
||||||
addons_path: &self.addons_path,
|
addons_path: &self.addons_path,
|
||||||
packer: &self.packer,
|
packer: &self.packer,
|
||||||
ip_assignment: &self.ip_assignment,
|
network_assignment: &self.ip_assignment,
|
||||||
zlt: &self.zlt,
|
zlt: &self.zlt,
|
||||||
runtime: &self.runtime,
|
runtime: &self.runtime,
|
||||||
config: &self.config,
|
config: &self.config,
|
||||||
@ -369,7 +369,7 @@ impl ZoneReconciler {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn ip_reservation_to_network_status(ip: &IpReservation) -> ZoneNetworkStatus {
|
pub fn network_reservation_to_network_status(ip: &NetworkReservation) -> ZoneNetworkStatus {
|
||||||
ZoneNetworkStatus {
|
ZoneNetworkStatus {
|
||||||
zone_ipv4: format!("{}/{}", ip.ipv4, ip.ipv4_prefix),
|
zone_ipv4: format!("{}/{}", ip.ipv4, ip.ipv4_prefix),
|
||||||
zone_ipv6: format!("{}/{}", ip.ipv6, ip.ipv6_prefix),
|
zone_ipv6: format!("{}/{}", ip.ipv6, ip.ipv6_prefix),
|
||||||
|
@ -139,3 +139,13 @@ message TerminalSize {
|
|||||||
uint32 rows = 1;
|
uint32 rows = 1;
|
||||||
uint32 columns = 2;
|
uint32 columns = 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
message NetworkReservation {
|
||||||
|
string uuid = 1;
|
||||||
|
string ipv4 = 2;
|
||||||
|
string ipv6 = 3;
|
||||||
|
string mac = 4;
|
||||||
|
string gateway_ipv4 = 5;
|
||||||
|
string gateway_ipv6 = 6;
|
||||||
|
string gateway_mac = 7;
|
||||||
|
}
|
||||||
|
@ -17,6 +17,8 @@ service ControlService {
|
|||||||
|
|
||||||
rpc ListDevices(ListDevicesRequest) returns (ListDevicesReply);
|
rpc ListDevices(ListDevicesRequest) returns (ListDevicesReply);
|
||||||
|
|
||||||
|
rpc ListNetworkReservations(ListNetworkReservationsRequest) returns (ListNetworkReservationsReply);
|
||||||
|
|
||||||
rpc PullImage(PullImageRequest) returns (stream PullImageReply);
|
rpc PullImage(PullImageRequest) returns (stream PullImageReply);
|
||||||
|
|
||||||
rpc CreateZone(CreateZoneRequest) returns (CreateZoneReply);
|
rpc CreateZone(CreateZoneRequest) returns (CreateZoneReply);
|
||||||
@ -265,3 +267,9 @@ message ReadHypervisorConsoleRequest {}
|
|||||||
message ReadHypervisorConsoleReply {
|
message ReadHypervisorConsoleReply {
|
||||||
string data = 1;
|
string data = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
message ListNetworkReservationsRequest {}
|
||||||
|
|
||||||
|
message ListNetworkReservationsReply {
|
||||||
|
repeated krata.v1.common.NetworkReservation reservations = 1;
|
||||||
|
}
|
||||||
|
Reference in New Issue
Block a user