mirror of
https://gitlab.com/veilid/veilid.git
synced 2025-01-25 22:15:59 -05:00
machine state work
This commit is contained in:
parent
1af7050632
commit
c361dce995
@ -139,7 +139,7 @@ impl MachineRegistryInner {
|
||||
}
|
||||
};
|
||||
|
||||
break Ok(machine_state_id.0);
|
||||
break Ok(machine_state_id.external_id());
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1,60 +1,69 @@
|
||||
use super::*;
|
||||
|
||||
#[derive(Debug)]
|
||||
struct MachineStateInner {
|
||||
/// The template generating this machine
|
||||
generating_template: Option<TemplateStateId>,
|
||||
#[derive(Debug, Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Hash)]
|
||||
pub enum MachineOrigin {
|
||||
InitialConfig,
|
||||
Direct,
|
||||
Template(TemplateStateId),
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
struct MachineStateFields {
|
||||
/// The current network interfaces definition
|
||||
interfaces: HashMap<String, MachineStateInterface>,
|
||||
interfaces: imbl::HashMap<Arc<String>, MachineStateInterface>,
|
||||
/// Capabilities to disable on this machine
|
||||
disable_capabilities: Vec<String>,
|
||||
disable_capabilities: imbl::Vector<String>,
|
||||
/// If this machine is a bootstrap
|
||||
bootstrap: bool,
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct MachineStateInterface {
|
||||
/// The network this interface belongs to
|
||||
pub network_id: Option<NetworkStateId>,
|
||||
/// The veilid NetworkInterface state
|
||||
pub network_interface: NetworkInterface,
|
||||
pub network_interface: Arc<NetworkInterface>,
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
struct MachineStateUnlockedInner {
|
||||
struct MachineStateImmutable {
|
||||
/// The id of this machine
|
||||
id: MachineStateId,
|
||||
/// The name of this machine if it is named
|
||||
opt_name: Option<String>,
|
||||
/// Where this machine came for housekeeping purposes
|
||||
origin: MachineOrigin,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct MachineState {
|
||||
xxx convert to immutable state
|
||||
unlocked_inner: Arc<MachineStateUnlockedInner>,
|
||||
inner: Arc<Mutex<MachineStateInner>>,
|
||||
immutable: Arc<MachineStateImmutable>,
|
||||
fields: Arc<MachineStateFields>,
|
||||
}
|
||||
|
||||
pub type MachineStateId = StateId<MachineState>;
|
||||
|
||||
impl MachineState {
|
||||
pub fn new(id: MachineStateId, opt_name: Option<String>) -> Self {
|
||||
pub fn new(id: MachineStateId, opt_name: Option<String>, origin: MachineOrigin) -> Self {
|
||||
// Create a localhost interface for this machine
|
||||
Self {
|
||||
unlocked_inner: Arc::new(MachineStateUnlockedInner { id, opt_name }),
|
||||
inner: Arc::new(Mutex::new(MachineStateInner {
|
||||
generating_template: None,
|
||||
interfaces: HashMap::new(),
|
||||
disable_capabilities: Vec::new(),
|
||||
immutable: Arc::new(MachineStateImmutable {
|
||||
id,
|
||||
opt_name,
|
||||
origin,
|
||||
}),
|
||||
fields: Arc::new(MachineStateFields {
|
||||
interfaces: imbl::HashMap::new(),
|
||||
disable_capabilities: imbl::Vector::new(),
|
||||
bootstrap: false,
|
||||
})),
|
||||
}),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn release(&self, machine_registry_inner: &mut MachineRegistryInner) {
|
||||
pub fn release(mut self, machine_registry_inner: &mut MachineRegistryInner) {
|
||||
self.release_all_interfaces(machine_registry_inner);
|
||||
let inner = self.inner.lock();
|
||||
if let Some(generating_template) = inner.generating_template {
|
||||
|
||||
if let MachineOrigin::Template(generating_template) = self.immutable.origin {
|
||||
let template_state = machine_registry_inner
|
||||
.template_states_mut()
|
||||
.get_state(generating_template)
|
||||
@ -63,44 +72,40 @@ impl MachineState {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn external_id(&self) -> MachineId {
|
||||
self.unlocked_inner.id.0
|
||||
pub fn set_disable_capabilities(&mut self, disable_capabilities: Vec<String>) {
|
||||
self.fields = Arc::new(MachineStateFields {
|
||||
disable_capabilities: disable_capabilities.into(),
|
||||
..(*self.fields).clone()
|
||||
});
|
||||
}
|
||||
|
||||
pub fn set_generating_template(&self, generating_template: TemplateStateId) {
|
||||
let mut inner = self.inner.lock();
|
||||
inner.generating_template = Some(generating_template);
|
||||
pub fn set_bootstrap(&mut self, bootstrap: bool) {
|
||||
self.fields = Arc::new(MachineStateFields {
|
||||
bootstrap,
|
||||
..(*self.fields).clone()
|
||||
});
|
||||
}
|
||||
|
||||
pub fn set_disable_capabilities(&self, disable_capabilities: Vec<String>) {
|
||||
let mut inner = self.inner.lock();
|
||||
inner.disable_capabilities = disable_capabilities;
|
||||
}
|
||||
|
||||
pub fn set_bootstrap(&self, bootstrap: bool) {
|
||||
let mut inner = self.inner.lock();
|
||||
inner.bootstrap = bootstrap
|
||||
}
|
||||
|
||||
fn next_free_interface_name_inner(inner: &MachineStateInner) -> String {
|
||||
fn next_free_interface_key(&self) -> Arc<String> {
|
||||
let mut inum = 0usize;
|
||||
loop {
|
||||
let name = format!("vin{}", inum);
|
||||
if !inner.interfaces.contains_key(&name) {
|
||||
return name;
|
||||
if !self.fields.interfaces.contains_key(&name) {
|
||||
return Arc::new(name);
|
||||
}
|
||||
inum += 1;
|
||||
}
|
||||
}
|
||||
|
||||
pub fn allocate_interface(
|
||||
&self,
|
||||
opt_name: Option<String>,
|
||||
&mut self,
|
||||
interface_name: Option<String>,
|
||||
opt_interface_flags: Option<InterfaceFlags>,
|
||||
) -> MachineRegistryResult<String> {
|
||||
let mut inner = self.inner.lock();
|
||||
let name = opt_name.unwrap_or_else(|| Self::next_free_interface_name_inner(&*inner));
|
||||
if inner.interfaces.contains_key(&name) {
|
||||
) -> MachineRegistryResult<Arc<String>> {
|
||||
let interface_key = interface_name
|
||||
.map(Arc::new)
|
||||
.unwrap_or_else(|| self.next_free_interface_key());
|
||||
if self.fields.interfaces.contains_key(&interface_key) {
|
||||
return Err(MachineRegistryError::DuplicateName);
|
||||
}
|
||||
let flags = opt_interface_flags.unwrap_or_else(|| InterfaceFlags {
|
||||
@ -109,44 +114,50 @@ impl MachineState {
|
||||
is_point_to_point: false,
|
||||
has_default_route: true,
|
||||
});
|
||||
inner.interfaces.insert(
|
||||
name.clone(),
|
||||
let interfaces = self.fields.interfaces.update(
|
||||
interface_key.clone(),
|
||||
MachineStateInterface {
|
||||
network_id: None,
|
||||
network_interface: NetworkInterface {
|
||||
name: name.clone(),
|
||||
network_interface: Arc::new(NetworkInterface {
|
||||
name: (*interface_key).clone(),
|
||||
flags,
|
||||
addrs: Vec::new(),
|
||||
},
|
||||
}),
|
||||
},
|
||||
);
|
||||
|
||||
Ok(name)
|
||||
self.fields = Arc::new(MachineStateFields {
|
||||
interfaces,
|
||||
..(*self.fields).clone()
|
||||
});
|
||||
|
||||
Ok(interface_key)
|
||||
}
|
||||
|
||||
pub fn interfaces(&self) -> Vec<String> {
|
||||
let mut intfs: Vec<String> = self.inner.lock().interfaces.keys().cloned().collect();
|
||||
pub fn interfaces(&self) -> Vec<Arc<String>> {
|
||||
let mut intfs: Vec<_> = self.fields.interfaces.keys().cloned().collect();
|
||||
intfs.sort();
|
||||
intfs
|
||||
}
|
||||
|
||||
pub fn allocate_address_ipv4(
|
||||
&self,
|
||||
&mut self,
|
||||
machine_registry_inner: &mut MachineRegistryInner,
|
||||
interface: &str,
|
||||
interface_name: &str,
|
||||
opt_address: Option<Ipv4Addr>,
|
||||
opt_address_flags: Option<AddressFlags>,
|
||||
) -> MachineRegistryResult<Ifv4Addr> {
|
||||
let mut inner = self.inner.lock();
|
||||
let Some(intf) = inner.interfaces.get_mut(interface) else {
|
||||
let interface_key = Arc::new(interface_name.to_string());
|
||||
let Some(mut machine_state_interface) = self.fields.interfaces.get(&interface_key).cloned()
|
||||
else {
|
||||
return Err(MachineRegistryError::InvalidName);
|
||||
};
|
||||
|
||||
// Get the network state
|
||||
let Some(network_id) = intf.network_id else {
|
||||
let Some(network_id) = machine_state_interface.network_id else {
|
||||
return Err(MachineRegistryError::NetworkNotFound);
|
||||
};
|
||||
let network_state = machine_registry_inner
|
||||
let mut network_state = machine_registry_inner
|
||||
.network_states()
|
||||
.get_state(network_id)?;
|
||||
|
||||
@ -158,6 +169,11 @@ impl MachineState {
|
||||
opt_address,
|
||||
)?;
|
||||
|
||||
// Update the network state
|
||||
machine_registry_inner
|
||||
.network_states_mut()
|
||||
.set_state(network_state);
|
||||
|
||||
// Get address flags
|
||||
let flags = opt_address_flags.unwrap_or_else(|| AddressFlags {
|
||||
is_dynamic,
|
||||
@ -165,31 +181,49 @@ impl MachineState {
|
||||
is_preferred: true,
|
||||
});
|
||||
|
||||
intf.network_interface.addrs.push(InterfaceAddress {
|
||||
// Update interface addresses
|
||||
let mut new_intf = (*machine_state_interface.network_interface).clone();
|
||||
new_intf.addrs.push(InterfaceAddress {
|
||||
if_addr: IfAddr::V4(ifv4_addr.clone()),
|
||||
flags,
|
||||
});
|
||||
|
||||
// Update interface
|
||||
machine_state_interface.network_interface = Arc::new(new_intf);
|
||||
|
||||
// Update interfaces map
|
||||
let interfaces = self
|
||||
.fields
|
||||
.interfaces
|
||||
.update(interface_key, machine_state_interface);
|
||||
|
||||
// Update fields
|
||||
self.fields = Arc::new(MachineStateFields {
|
||||
interfaces,
|
||||
..(*self.fields).clone()
|
||||
});
|
||||
|
||||
Ok(ifv4_addr)
|
||||
}
|
||||
|
||||
pub fn allocate_address_ipv6(
|
||||
&self,
|
||||
&mut self,
|
||||
machine_registry_inner: &mut MachineRegistryInner,
|
||||
interface: &str,
|
||||
interface_name: &str,
|
||||
opt_address: Option<Ipv6Addr>,
|
||||
opt_address_flags: Option<AddressFlags>,
|
||||
) -> MachineRegistryResult<Ifv6Addr> {
|
||||
let mut inner = self.inner.lock();
|
||||
let Some(intf) = inner.interfaces.get_mut(interface) else {
|
||||
let interface_key = Arc::new(interface_name.to_string());
|
||||
let Some(mut machine_state_interface) = self.fields.interfaces.get(&interface_key).cloned()
|
||||
else {
|
||||
return Err(MachineRegistryError::InvalidName);
|
||||
};
|
||||
|
||||
// Get the network state
|
||||
let Some(network_id) = intf.network_id else {
|
||||
let Some(network_id) = machine_state_interface.network_id else {
|
||||
return Err(MachineRegistryError::NetworkNotFound);
|
||||
};
|
||||
let network_state = machine_registry_inner
|
||||
let mut network_state = machine_registry_inner
|
||||
.network_states()
|
||||
.get_state(network_id)?;
|
||||
|
||||
@ -200,6 +234,10 @@ impl MachineState {
|
||||
OwnerTag::Machine(self.id()),
|
||||
opt_address,
|
||||
)?;
|
||||
// Update the network state
|
||||
machine_registry_inner
|
||||
.network_states_mut()
|
||||
.set_state(network_state);
|
||||
|
||||
// Get address flags
|
||||
let flags = opt_address_flags.unwrap_or_else(|| AddressFlags {
|
||||
@ -208,48 +246,98 @@ impl MachineState {
|
||||
is_preferred: true,
|
||||
});
|
||||
|
||||
intf.network_interface.addrs.push(InterfaceAddress {
|
||||
// Update interface addresses
|
||||
let mut new_intf = (*machine_state_interface.network_interface).clone();
|
||||
new_intf.addrs.push(InterfaceAddress {
|
||||
if_addr: IfAddr::V6(ifv6_addr.clone()),
|
||||
flags,
|
||||
});
|
||||
|
||||
// Update interface
|
||||
machine_state_interface.network_interface = Arc::new(new_intf);
|
||||
|
||||
// Update interfaces map
|
||||
let interfaces = self
|
||||
.fields
|
||||
.interfaces
|
||||
.update(interface_key, machine_state_interface);
|
||||
|
||||
// Update fields
|
||||
self.fields = Arc::new(MachineStateFields {
|
||||
interfaces,
|
||||
..(*self.fields).clone()
|
||||
});
|
||||
|
||||
Ok(ifv6_addr)
|
||||
}
|
||||
|
||||
pub fn attach_network(
|
||||
&self,
|
||||
&mut self,
|
||||
machine_registry_inner: &mut MachineRegistryInner,
|
||||
interface: &str,
|
||||
interface_name: &str,
|
||||
network_id: NetworkStateId,
|
||||
) -> MachineRegistryResult<()> {
|
||||
let mut inner = self.inner.lock();
|
||||
let Some(intf) = inner.interfaces.get_mut(interface) else {
|
||||
let interface_key = Arc::new(interface_name.to_string());
|
||||
let Some(mut machine_state_interface) = self.fields.interfaces.get(&interface_key).cloned()
|
||||
else {
|
||||
return Err(MachineRegistryError::InvalidName);
|
||||
};
|
||||
if intf.network_id.is_some() {
|
||||
self.detach_network(machine_registry_inner, interface);
|
||||
|
||||
if machine_state_interface.network_id.is_some() {
|
||||
Self::detach_network_inner(machine_registry_inner, &mut machine_state_interface)?;
|
||||
}
|
||||
intf.network_id = Some(network_id);
|
||||
|
||||
machine_state_interface.network_id = Some(network_id);
|
||||
|
||||
// Update interfaces map
|
||||
let interfaces = self
|
||||
.fields
|
||||
.interfaces
|
||||
.update(interface_key, machine_state_interface);
|
||||
|
||||
// Update fields
|
||||
self.fields = Arc::new(MachineStateFields {
|
||||
interfaces,
|
||||
..(*self.fields).clone()
|
||||
});
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn detach_network(
|
||||
&self,
|
||||
&mut self,
|
||||
machine_registry_inner: &mut MachineRegistryInner,
|
||||
interface: &str,
|
||||
interface_name: &str,
|
||||
) -> MachineRegistryResult<()> {
|
||||
let mut inner = self.inner.lock();
|
||||
Self::detach_network_inner(&mut *inner, machine_registry_inner, interface)
|
||||
let interface_key = Arc::new(interface_name.to_string());
|
||||
let Some(mut machine_state_interface) = self.fields.interfaces.get(&interface_key).cloned()
|
||||
else {
|
||||
return Err(MachineRegistryError::InvalidName);
|
||||
};
|
||||
|
||||
Self::detach_network_inner(machine_registry_inner, &mut machine_state_interface)?;
|
||||
|
||||
// Update interfaces map
|
||||
let interfaces = self
|
||||
.fields
|
||||
.interfaces
|
||||
.update(interface_key, machine_state_interface);
|
||||
|
||||
// Update fields
|
||||
self.fields = Arc::new(MachineStateFields {
|
||||
interfaces,
|
||||
..(*self.fields).clone()
|
||||
});
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn attached_network_interfaces(
|
||||
&self,
|
||||
network_id: NetworkStateId,
|
||||
) -> MachineRegistryResult<Vec<String>> {
|
||||
) -> MachineRegistryResult<Vec<Arc<String>>> {
|
||||
let mut out = Vec::new();
|
||||
let inner = self.inner.lock();
|
||||
for intf in &inner.interfaces {
|
||||
for intf in &self.fields.interfaces {
|
||||
if intf.1.network_id == Some(network_id) {
|
||||
out.push(intf.0.clone());
|
||||
}
|
||||
@ -258,22 +346,23 @@ impl MachineState {
|
||||
}
|
||||
|
||||
pub fn release_address(
|
||||
&self,
|
||||
&mut self,
|
||||
machine_registry_inner: &mut MachineRegistryInner,
|
||||
interface: &str,
|
||||
interface_name: &str,
|
||||
address: IpAddr,
|
||||
) -> MachineRegistryResult<()> {
|
||||
let mut inner = self.inner.lock();
|
||||
let Some(intf) = inner.interfaces.get_mut(interface) else {
|
||||
let interface_key = Arc::new(interface_name.to_owned());
|
||||
let Some(mut machine_state_interface) = self.fields.interfaces.get(&interface_key).cloned()
|
||||
else {
|
||||
return Err(MachineRegistryError::InvalidName);
|
||||
};
|
||||
|
||||
let Some(network_id) = intf.network_id else {
|
||||
let Some(network_id) = machine_state_interface.network_id else {
|
||||
return Err(MachineRegistryError::NetworkNotFound);
|
||||
};
|
||||
|
||||
// Get the network state
|
||||
let network_state = machine_registry_inner
|
||||
let mut network_state = machine_registry_inner
|
||||
.network_states()
|
||||
.get_state(network_id)?;
|
||||
|
||||
@ -283,92 +372,168 @@ impl MachineState {
|
||||
IpAddr::V6(ipv6_addr) => network_state.release_address_v6(ipv6_addr)?,
|
||||
};
|
||||
|
||||
// Update the network state
|
||||
machine_registry_inner
|
||||
.network_states_mut()
|
||||
.set_state(network_state);
|
||||
|
||||
// Remove the address from the interface
|
||||
intf.network_interface
|
||||
let addrs: Vec<_> = machine_state_interface
|
||||
.network_interface
|
||||
.addrs
|
||||
.retain(|x| x.if_addr().ip() != address);
|
||||
.iter()
|
||||
.filter(|x| x.if_addr().ip() != address)
|
||||
.cloned()
|
||||
.collect();
|
||||
|
||||
// Update network interface
|
||||
machine_state_interface.network_interface = Arc::new(NetworkInterface {
|
||||
addrs,
|
||||
..(*machine_state_interface.network_interface).clone()
|
||||
});
|
||||
|
||||
// Update interfaces map
|
||||
let interfaces = self
|
||||
.fields
|
||||
.interfaces
|
||||
.update(interface_key, machine_state_interface);
|
||||
|
||||
// Update fields
|
||||
self.fields = Arc::new(MachineStateFields {
|
||||
interfaces,
|
||||
..(*self.fields).clone()
|
||||
});
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn release_all_addresses(
|
||||
&self,
|
||||
&mut self,
|
||||
machine_registry_inner: &mut MachineRegistryInner,
|
||||
interface: &str,
|
||||
interface_name: &str,
|
||||
) -> MachineRegistryResult<()> {
|
||||
let mut inner = self.inner.lock();
|
||||
Self::release_all_addresses_inner(&mut *inner, machine_registry_inner, interface)
|
||||
}
|
||||
|
||||
fn detach_network_inner(
|
||||
inner: &mut MachineStateInner,
|
||||
machine_registry_inner: &mut MachineRegistryInner,
|
||||
interface: &str,
|
||||
) -> MachineRegistryResult<()> {
|
||||
Self::release_all_addresses_inner(inner, machine_registry_inner, interface)?;
|
||||
let Some(intf) = inner.interfaces.get_mut(interface) else {
|
||||
let interface_key = Arc::new(interface_name.to_string());
|
||||
let Some(mut machine_state_interface) = self.fields.interfaces.get(&interface_key).cloned()
|
||||
else {
|
||||
return Err(MachineRegistryError::InvalidName);
|
||||
};
|
||||
intf.network_id = None;
|
||||
|
||||
Self::release_all_addresses_inner(machine_registry_inner, &mut machine_state_interface)?;
|
||||
|
||||
// Update interfaces map
|
||||
let interfaces = self
|
||||
.fields
|
||||
.interfaces
|
||||
.update(interface_key, machine_state_interface);
|
||||
|
||||
// Update fields
|
||||
self.fields = Arc::new(MachineStateFields {
|
||||
interfaces,
|
||||
..(*self.fields).clone()
|
||||
});
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
fn detach_network_inner(
|
||||
machine_registry_inner: &mut MachineRegistryInner,
|
||||
machine_state_interface: &mut MachineStateInterface,
|
||||
) -> MachineRegistryResult<()> {
|
||||
Self::release_all_addresses_inner(machine_registry_inner, machine_state_interface)?;
|
||||
machine_state_interface.network_id = None;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn release_all_addresses_inner(
|
||||
inner: &mut MachineStateInner,
|
||||
machine_registry_inner: &mut MachineRegistryInner,
|
||||
interface: &str,
|
||||
machine_state_interface: &mut MachineStateInterface,
|
||||
) -> MachineRegistryResult<()> {
|
||||
let Some(intf) = inner.interfaces.get_mut(interface) else {
|
||||
return Err(MachineRegistryError::InvalidName);
|
||||
};
|
||||
|
||||
let Some(network_id) = intf.network_id else {
|
||||
let Some(network_id) = machine_state_interface.network_id else {
|
||||
return Ok(());
|
||||
};
|
||||
|
||||
// Get the network state
|
||||
let network_state = machine_registry_inner
|
||||
let mut network_state = machine_registry_inner
|
||||
.network_states()
|
||||
.get_state(network_id)?;
|
||||
|
||||
// Release the addresses from the network
|
||||
for addr in &intf.network_interface.addrs {
|
||||
for addr in &machine_state_interface.network_interface.addrs {
|
||||
match addr.if_addr.ip() {
|
||||
IpAddr::V4(ipv4_addr) => network_state.release_address_v4(ipv4_addr)?,
|
||||
IpAddr::V6(ipv6_addr) => network_state.release_address_v6(ipv6_addr)?,
|
||||
};
|
||||
}
|
||||
|
||||
// Update the network state
|
||||
machine_registry_inner
|
||||
.network_states_mut()
|
||||
.set_state(network_state);
|
||||
|
||||
// Remove the addresses from the interface
|
||||
intf.network_interface.addrs.clear();
|
||||
let mut new_intf = (*machine_state_interface.network_interface).clone();
|
||||
new_intf.addrs.clear();
|
||||
|
||||
// Update interface
|
||||
machine_state_interface.network_interface = Arc::new(new_intf);
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn release_interface(
|
||||
&self,
|
||||
&mut self,
|
||||
machine_registry_inner: &mut MachineRegistryInner,
|
||||
interface: &str,
|
||||
interface_name: &str,
|
||||
) -> MachineRegistryResult<()> {
|
||||
let mut inner = self.inner.lock();
|
||||
Self::detach_network_inner(&mut *inner, machine_registry_inner, interface)?;
|
||||
inner
|
||||
.interfaces
|
||||
.remove(interface)
|
||||
.expect("interface must exist");
|
||||
let interface_key = Arc::new(interface_name.to_string());
|
||||
let Some(mut machine_state_interface) = self.fields.interfaces.get(&interface_key).cloned()
|
||||
else {
|
||||
return Err(MachineRegistryError::InvalidName);
|
||||
};
|
||||
|
||||
Self::detach_network_inner(machine_registry_inner, &mut machine_state_interface)?;
|
||||
|
||||
// Update interfaces map
|
||||
let interfaces = self.fields.interfaces.without(&interface_key);
|
||||
|
||||
// Update fields
|
||||
self.fields = Arc::new(MachineStateFields {
|
||||
interfaces,
|
||||
..(*self.fields).clone()
|
||||
});
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn release_all_interfaces(
|
||||
&self,
|
||||
&mut self,
|
||||
machine_registry_inner: &mut MachineRegistryInner,
|
||||
) -> MachineRegistryResult<()> {
|
||||
let mut inner = self.inner.lock();
|
||||
let interfaces: Vec<String> = inner.interfaces.keys().cloned().collect();
|
||||
for interface in interfaces {
|
||||
Self::release_all_addresses_inner(&mut *inner, machine_registry_inner, &interface)?;
|
||||
let interface_names: Vec<String> = self
|
||||
.fields
|
||||
.interfaces
|
||||
.keys()
|
||||
.map(|x| (**x).clone())
|
||||
.collect();
|
||||
for interface_name in interface_names {
|
||||
let interface_key = Arc::new(interface_name);
|
||||
let Some(mut machine_state_interface) =
|
||||
self.fields.interfaces.get(&interface_key).cloned()
|
||||
else {
|
||||
return Err(MachineRegistryError::InvalidName);
|
||||
};
|
||||
|
||||
Self::detach_network_inner(machine_registry_inner, &mut machine_state_interface)?;
|
||||
}
|
||||
inner.interfaces.clear();
|
||||
|
||||
// Update fields
|
||||
self.fields = Arc::new(MachineStateFields {
|
||||
interfaces: imbl::HashMap::new(),
|
||||
..(*self.fields).clone()
|
||||
});
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
@ -467,10 +632,10 @@ impl MachineState {
|
||||
|
||||
impl State for MachineState {
|
||||
fn id(&self) -> StateId<Self> {
|
||||
self.unlocked_inner.id.clone()
|
||||
self.immutable.id.clone()
|
||||
}
|
||||
|
||||
fn name(&self) -> Option<String> {
|
||||
self.unlocked_inner.opt_name.clone()
|
||||
self.immutable.opt_name.clone()
|
||||
}
|
||||
}
|
||||
|
@ -148,18 +148,11 @@ impl NetworkState {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn with_model(
|
||||
self,
|
||||
machine_registry_inner: &mut MachineRegistryInner,
|
||||
params: NetworkStateModelParams,
|
||||
) -> Self {
|
||||
Self {
|
||||
fields: Arc::new(NetworkStateFields {
|
||||
model: NetworkStateModel { params },
|
||||
..(*self.fields).clone()
|
||||
}),
|
||||
..self.clone()
|
||||
}
|
||||
pub fn set_model(&mut self, params: NetworkStateModelParams) {
|
||||
self.fields = Arc::new(NetworkStateFields {
|
||||
model: NetworkStateModel { params },
|
||||
..(*self.fields).clone()
|
||||
});
|
||||
}
|
||||
|
||||
pub fn clear_ipv4(
|
||||
@ -365,10 +358,6 @@ impl NetworkState {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn set_generating_blueprint(&self, generating_blueprint: BlueprintStateId) {
|
||||
inner.generating_blueprint = Some(generating_blueprint);
|
||||
}
|
||||
|
||||
pub fn is_ipv4(&self) -> bool {
|
||||
self.fields.lock().ipv4.is_some()
|
||||
}
|
||||
@ -396,7 +385,7 @@ impl NetworkState {
|
||||
}
|
||||
|
||||
pub fn allocate_address_v4(
|
||||
&self,
|
||||
&mut self,
|
||||
machine_registry_inner: &mut MachineRegistryInner,
|
||||
owner_tag: OwnerTag,
|
||||
opt_address: Option<Ipv4Addr>,
|
||||
@ -447,16 +436,19 @@ impl NetworkState {
|
||||
Self::can_allocate_net_v4_inner(&*inner, opt_address, prefix)
|
||||
}
|
||||
|
||||
pub fn release_address_v4(&self, addr: Ipv4Addr) -> MachineRegistryResult<Option<OwnerTag>> {
|
||||
pub fn release_address_v4(
|
||||
&mut self,
|
||||
addr: Ipv4Addr,
|
||||
) -> MachineRegistryResult<Option<OwnerTag>> {
|
||||
Self::release_subnet_v4_inner(&mut *inner, Ipv4Net::new(addr, 32).expect("must succeed"))
|
||||
}
|
||||
|
||||
pub fn release_subnet_v4(&self, net: Ipv4Net) -> MachineRegistryResult<Option<OwnerTag>> {
|
||||
pub fn release_subnet_v4(&mut self, net: Ipv4Net) -> MachineRegistryResult<Option<OwnerTag>> {
|
||||
Self::release_subnet_v4_inner(&mut *inner, net)
|
||||
}
|
||||
|
||||
pub fn allocate_address_v6(
|
||||
&self,
|
||||
&mut self,
|
||||
machine_registry_inner: &mut MachineRegistryInner,
|
||||
owner_tag: OwnerTag,
|
||||
opt_address: Option<Ipv6Addr>,
|
||||
|
@ -14,6 +14,10 @@ impl<S: State> StateId<S> {
|
||||
pub fn new(external_id: u64) -> Self {
|
||||
Self(external_id, PhantomData {})
|
||||
}
|
||||
|
||||
pub fn external_id(&self) -> u64 {
|
||||
self.0
|
||||
}
|
||||
}
|
||||
|
||||
impl<S: State> Copy for StateId<S> {}
|
||||
|
Loading…
x
Reference in New Issue
Block a user