Skip to content

Commit

Permalink
probe launching working!
Browse files Browse the repository at this point in the history
  • Loading branch information
rcgoodfellow committed Dec 13, 2023
1 parent a951832 commit 23b96d9
Show file tree
Hide file tree
Showing 6 changed files with 126 additions and 11 deletions.
4 changes: 4 additions & 0 deletions illumos-utils/src/running_zone.rs
Original file line number Diff line number Diff line change
Expand Up @@ -915,6 +915,10 @@ impl RunningZone {
&self.inner.links
}

pub fn links_mut(&mut self) -> &mut Vec<Link> {
&mut self.inner.links
}

/// Return the running processes associated with all the SMF services this
/// zone is intended to run.
pub fn service_processes(
Expand Down
34 changes: 34 additions & 0 deletions nexus/db-model/src/external_ip.rs
Original file line number Diff line number Diff line change
Expand Up @@ -130,6 +130,7 @@ pub struct IncompleteExternalIp {
time_created: DateTime<Utc>,
kind: IpKind,
is_service: bool,
is_probe: bool,
parent_id: Option<Uuid>,
pool_id: Uuid,
project_id: Option<Uuid>,
Expand All @@ -152,6 +153,7 @@ impl IncompleteExternalIp {
time_created: Utc::now(),
kind: IpKind::SNat,
is_service: false,
is_probe: false,
parent_id: Some(instance_id),
pool_id,
project_id: None,
Expand All @@ -168,6 +170,28 @@ impl IncompleteExternalIp {
time_created: Utc::now(),
kind: IpKind::Ephemeral,
is_service: false,
is_probe: false,
parent_id: Some(instance_id),
pool_id,
project_id: None,
explicit_ip: None,
explicit_port_range: None,
}
}

pub fn for_ephemeral_probe(
id: Uuid,
instance_id: Uuid,
pool_id: Uuid,
) -> Self {
Self {
id,
name: None,
description: None,
time_created: Utc::now(),
kind: IpKind::Ephemeral,
is_service: false,
is_probe: true,
parent_id: Some(instance_id),
pool_id,
project_id: None,
Expand All @@ -190,6 +214,7 @@ impl IncompleteExternalIp {
time_created: Utc::now(),
kind: IpKind::Floating,
is_service: false,
is_probe: false,
parent_id: None,
pool_id,
project_id: Some(project_id),
Expand All @@ -213,6 +238,7 @@ impl IncompleteExternalIp {
time_created: Utc::now(),
kind: IpKind::Floating,
is_service: false,
is_probe: false,
parent_id: None,
pool_id,
project_id: Some(project_id),
Expand All @@ -236,6 +262,7 @@ impl IncompleteExternalIp {
time_created: Utc::now(),
kind: IpKind::Floating,
is_service: true,
is_probe: false,
parent_id: Some(service_id),
pool_id,
project_id: None,
Expand Down Expand Up @@ -265,6 +292,7 @@ impl IncompleteExternalIp {
time_created: Utc::now(),
kind: IpKind::SNat,
is_service: true,
is_probe: false,
parent_id: Some(service_id),
pool_id,
project_id: None,
Expand All @@ -287,6 +315,7 @@ impl IncompleteExternalIp {
time_created: Utc::now(),
kind: IpKind::Floating,
is_service: true,
is_probe: false,
parent_id: Some(service_id),
pool_id,
project_id: None,
Expand All @@ -303,6 +332,7 @@ impl IncompleteExternalIp {
time_created: Utc::now(),
kind: IpKind::SNat,
is_service: true,
is_probe: false,
parent_id: Some(service_id),
pool_id,
project_id: None,
Expand Down Expand Up @@ -335,6 +365,10 @@ impl IncompleteExternalIp {
&self.is_service
}

pub fn is_probe(&self) -> &bool {
&self.is_probe
}

pub fn parent_id(&self) -> &Option<Uuid> {
&self.parent_id
}
Expand Down
28 changes: 27 additions & 1 deletion nexus/db-model/src/network_interface.rs
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,33 @@ impl Into<omicron_common::api::internal::shared::NetworkInterface>
for NetworkInterface
{
fn into(self) -> omicron_common::api::internal::shared::NetworkInterface {
todo!()
omicron_common::api::internal::shared::NetworkInterface {
id: self.id(),
kind: match self.kind {
NetworkInterfaceKind::Instance =>
omicron_common::api::internal::shared::NetworkInterfaceKind::Instance {
id: self.parent_id
},
NetworkInterfaceKind::Service =>
omicron_common::api::internal::shared::NetworkInterfaceKind::Service {
id: self.parent_id
},
NetworkInterfaceKind::Probe =>
omicron_common::api::internal::shared::NetworkInterfaceKind::Probe {
id: self.parent_id
},
},
name: self.name().clone(),
ip: self.ip.ip(),
mac: self.mac.into(),
subnet: ipnetwork::IpNetwork::new(
self.ip.network(),
24, //TODO
).unwrap().into(),
vni: omicron_common::api::external::Vni::try_from(0).unwrap(), //TODO
primary: self.primary,
slot: self.slot.try_into().unwrap(),
}
}
}

Expand Down
2 changes: 1 addition & 1 deletion nexus/db-queries/src/db/datastore/external_ip.rs
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,7 @@ impl DataStore {

let pool_id = pool.identity.id;
let data =
IncompleteExternalIp::for_ephemeral(ip_id, probe_id, pool_id);
IncompleteExternalIp::for_ephemeral_probe(ip_id, probe_id, pool_id);
self.allocate_external_ip(opctx, data).await
}

Expand Down
6 changes: 6 additions & 0 deletions nexus/db-queries/src/db/queries/external_ip.rs
Original file line number Diff line number Diff line change
Expand Up @@ -378,6 +378,12 @@ impl NextExternalIp {
out.push_bind_param::<sql_types::Nullable<sql_types::Uuid>, Option<Uuid>>(self.ip.project_id())?;
out.push_sql(" AS ");
out.push_identifier(dsl::project_id::NAME)?;
out.push_sql(", ");

// is_probe flag
out.push_bind_param::<sql_types::Bool, bool>(self.ip.is_probe())?;
out.push_sql(" AS ");
out.push_identifier(dsl::is_probe::NAME)?;

out.push_sql(" FROM (");
self.push_address_sequence_subquery(out.reborrow())?;
Expand Down
63 changes: 54 additions & 9 deletions sled-agent/src/probe_manager.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ use rand::SeedableRng;
use sled_storage::dataset::ZONE_DATASET;
use sled_storage::manager::StorageHandle;
use slog::{error, warn, Logger};
use std::collections::HashSet;
use std::collections::{HashMap, HashSet};
use std::hash::{Hash, Hasher};
use std::sync::Arc;
use std::time::Duration;
Expand All @@ -41,6 +41,7 @@ pub struct ProbeManagerInner {
vnic_allocator: VnicAllocator<Etherstub>,
storage: StorageHandle,
port_manager: PortManager,
running_probes: Mutex<HashMap<Uuid, RunningZone>>,
}

impl ProbeManager {
Expand All @@ -56,6 +57,7 @@ impl ProbeManager {
inner: Arc::new(ProbeManagerInner {
join_handle: Mutex::new(None),
vnic_allocator: VnicAllocator::new("probe", etherstub),
running_probes: Mutex::new(HashMap::new()),
nexus_client,
log,
sled_id,
Expand All @@ -70,7 +72,7 @@ impl ProbeManager {
}
}

#[derive(Debug)]
#[derive(Debug, Clone)]
struct ProbeState {
id: Uuid,
status: zone::State,
Expand Down Expand Up @@ -109,7 +111,7 @@ impl TryFrom<Zone> for ProbeState {
Ok(Self {
id: value
.name()
.strip_prefix(PROBE_ZONE_PREFIX)
.strip_prefix(&format!("{PROBE_ZONE_PREFIX}_"))
.ok_or(String::from("not a probe prefix"))?
.parse()
.map_err(|e| format!("invalid uuid: {e}"))?,
Expand Down Expand Up @@ -161,6 +163,7 @@ impl ProbeManagerInner {
I: Iterator<Item = &'a ProbeState>,
{
for probe in probes {
info!(self.log, "adding probe {}", probe.id);
if let Err(e) = self.add_probe(probe).await {
error!(self.log, "add probe: {e}");
}
Expand Down Expand Up @@ -228,9 +231,12 @@ impl ProbeManagerInner {

//TODO(ry) SMF properties?

RunningZone::boot(installed_zone).await?;
let rz = RunningZone::boot(installed_zone).await?;
rz.ensure_address_for_port("overlay", 0).await?;
info!(self.log, "started probe {}", probe.id);

self.running_probes.lock().await.insert(probe.id, rz);

Ok(())
}

Expand All @@ -239,16 +245,27 @@ impl ProbeManagerInner {
I: Iterator<Item = &'a ProbeState>,
{
for probe in probes {
info!(self.log, "removing probe {}", probe.id);
self.remove_probe(probe.id).await;
}
}

async fn remove_probe(self: &Arc<Self>, id: Uuid) {
if let Err(e) =
Zones::halt_and_remove(&format!("{}_{}", PROBE_ZONE_PREFIX, id))
.await
{
error!(self.log, "remove zone {e}")
match self.running_probes.lock().await.remove(&id) {
Some(mut running_zone) => {
for l in running_zone.links_mut() {
if let Err(e) = l.delete() {
error!(self.log, "delete probe link {}: {e}", l.name());
}
}
running_zone.release_opte_ports();
if let Err(e) = running_zone.stop().await {
error!(self.log, "stop probe: {e}")
}
}
None => {
warn!(self.log, "attempt to stop non-running probe: {id}")
}
}
}

Expand Down Expand Up @@ -295,3 +312,31 @@ impl ProbeManagerInner {
.collect())
}
}

#[cfg(test)]
mod test {
use super::*;
use uuid::Uuid;

#[test]
fn probe_state_set_ops() {
let a = ProbeState {
id: Uuid::new_v4(),
status: zone::State::Configured,
external_ips: Vec::new(),
interface: None,
};

let mut b = a.clone();
b.status = zone::State::Running;

let target = HashSet::from([a]);
let current = HashSet::from([b]);

let to_add = target.difference(&current);
let to_remove = current.difference(&target);

assert_eq!(to_add.count(), 0);
assert_eq!(to_remove.count(), 0);
}
}

0 comments on commit 23b96d9

Please sign in to comment.