Skip to content

Commit 67d0cbd

Browse files
authored
[sled-agent] Self assembling switch zone (#5593)
## Overview This PR migrates the switch zone to a self assembling format. There are a few bits of old code I'll be cleaning up, more logs I'll be adding and some documentation about how the switch zone flow works, but I'll do this in follow up PRs to keep this one as compact as possible. ## Caveats I've tested this in a local single node deployment and in the a4x2 testbed. Unfortunately, this is not enough testing to make sure all of the services play nice together on a real rack. We'll have to keep an eye on dogfood when this is deployed. The only services that depend on the [common networking](https://github.com/oxidecomputer/omicron/blob/30eb1ee38987201ac71f2115fdd89da4b08710c7/zone-setup/src/bin/zone-setup.rs#L578-L690) [service](https://github.com/oxidecomputer/omicron/blob/30eb1ee38987201ac71f2115fdd89da4b08710c7/smf/zone-network-setup/manifest.xml) are dendrite and MGS. While this makes sense on the a4x2 testbed, I'd like to verify that these dependencies make sense when running on a real rack. As several people have worked on different parts of this zone, I've tagged a whole bunch of people for review, sorry if this is overkill! Just want to make sure I've got the right eyes on each service of the zone. Related: #1898 Closes: #2884 TODO: - [x] Update Dendrite hashes after merging https://github.com/oxidecomputer/dendrite/pull/990
1 parent 2f57493 commit 67d0cbd

File tree

22 files changed

+1367
-606
lines changed

22 files changed

+1367
-606
lines changed

Cargo.lock

Lines changed: 3 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

illumos-utils/src/lib.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -36,8 +36,8 @@ pub const PFEXEC: &str = "/usr/bin/pfexec";
3636
pub struct CommandFailureInfo {
3737
command: String,
3838
status: std::process::ExitStatus,
39-
stdout: String,
40-
stderr: String,
39+
pub stdout: String,
40+
pub stderr: String,
4141
}
4242

4343
impl std::fmt::Display for CommandFailureInfo {

illumos-utils/src/route.rs

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -107,4 +107,23 @@ impl Route {
107107
};
108108
Ok(())
109109
}
110+
111+
pub fn add_bootstrap_route(
112+
bootstrap_prefix: u16,
113+
gz_bootstrap_addr: Ipv6Addr,
114+
zone_vnic_name: &str,
115+
) -> Result<(), ExecutionError> {
116+
let mut cmd = std::process::Command::new(PFEXEC);
117+
let cmd = cmd.args(&[
118+
ROUTE,
119+
"add",
120+
"-inet6",
121+
&format!("{bootstrap_prefix:x}::/16"),
122+
&gz_bootstrap_addr.to_string(),
123+
"-ifp",
124+
zone_vnic_name,
125+
]);
126+
execute(cmd)?;
127+
Ok(())
128+
}
110129
}

illumos-utils/src/running_zone.rs

Lines changed: 14 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@ pub enum ServiceError {
4646
pub struct RunCommandError {
4747
zone: String,
4848
#[source]
49-
err: crate::ExecutionError,
49+
pub err: crate::ExecutionError,
5050
}
5151

5252
/// Errors returned from [`RunningZone::boot`].
@@ -462,7 +462,7 @@ impl RunningZone {
462462
/// Note that the zone must already be configured to be booted.
463463
pub async fn boot(zone: InstalledZone) -> Result<Self, BootError> {
464464
// Boot the zone.
465-
info!(zone.log, "Zone booting");
465+
info!(zone.log, "Booting {} zone", zone.name);
466466

467467
Zones::boot(&zone.name).await?;
468468

@@ -480,6 +480,9 @@ impl RunningZone {
480480
zone: zone.name.to_string(),
481481
})?;
482482

483+
// TODO https://github.com/oxidecomputer/omicron/issues/1898:
484+
// Remove all non-self assembling code
485+
483486
// If the zone is self-assembling, then SMF service(s) inside the zone
484487
// will be creating the listen address for the zone's service(s),
485488
// setting the appropriate ifprop MTU, and so on. The idea behind
@@ -575,7 +578,6 @@ impl RunningZone {
575578
&self,
576579
address: Ipv6Addr,
577580
) -> Result<(), EnsureAddressError> {
578-
info!(self.inner.log, "Adding bootstrap address");
579581
let vnic = self.inner.bootstrap_vnic.as_ref().ok_or_else(|| {
580582
EnsureAddressError::MissingBootstrapVnic {
581583
address: address.to_string(),
@@ -735,15 +737,16 @@ impl RunningZone {
735737
gz_bootstrap_addr: Ipv6Addr,
736738
zone_vnic_name: &str,
737739
) -> Result<(), RunCommandError> {
738-
self.run_cmd([
740+
let args = [
739741
"/usr/sbin/route",
740742
"add",
741743
"-inet6",
742744
&format!("{bootstrap_prefix:x}::/16"),
743745
&gz_bootstrap_addr.to_string(),
744746
"-ifp",
745747
zone_vnic_name,
746-
])?;
748+
];
749+
self.run_cmd(args)?;
747750
Ok(())
748751
}
749752

@@ -775,7 +778,7 @@ impl RunningZone {
775778

776779
/// Return a reference to the links for this zone.
777780
pub fn links(&self) -> &Vec<Link> {
778-
&self.inner.links
781+
&self.inner.links()
779782
}
780783

781784
/// Return a mutable reference to the links for this zone.
@@ -1010,6 +1013,11 @@ impl InstalledZone {
10101013
pub fn root(&self) -> Utf8PathBuf {
10111014
self.zonepath.path.join(Self::ROOT_FS_PATH)
10121015
}
1016+
1017+
/// Return a reference to the links for this zone.
1018+
pub fn links(&self) -> &Vec<Link> {
1019+
&self.links
1020+
}
10131021
}
10141022

10151023
#[derive(Clone)]

illumos-utils/src/zone.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -640,7 +640,7 @@ impl Zones {
640640
//
641641
// Does NOT check if the address already exists.
642642
#[allow(clippy::needless_lifetimes)]
643-
fn create_address_internal<'a>(
643+
pub fn create_address_internal<'a>(
644644
zone: Option<&'a str>,
645645
addrobj: &AddrObject,
646646
addrtype: AddressRequest,

package-manifest.toml

Lines changed: 12 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -439,7 +439,6 @@ service_name = "switch_zone_setup"
439439
source.type = "local"
440440
source.paths = [
441441
{ from = "smf/switch_zone_setup/manifest.xml", to = "/var/svc/manifest/site/switch_zone_setup/manifest.xml" },
442-
{ from = "smf/switch_zone_setup/switch_zone_setup", to = "/opt/oxide/bin/switch_zone_setup" },
443442
{ from = "smf/switch_zone_setup/support_authorized_keys", to = "/opt/oxide/support/authorized_keys" },
444443
{ from = "/opt/ooce/pgsql-13/lib/amd64", to = "/opt/ooce/pgsql-13/lib/amd64" },
445444
]
@@ -645,8 +644,8 @@ only_for_targets.image = "standard"
645644
# the other `source.*` keys.
646645
source.type = "prebuilt"
647646
source.repo = "dendrite"
648-
source.commit = "e83f4f164fd3dbb2100989a399a4fa087232ac36"
649-
source.sha256 = "b28247df4d301540b0a46e4d9fdf410ee6fbdb23d18c80acbd36c016a084e30e"
647+
source.commit = "fb571dc6512b24a777c5a9b2927a50501f6be297"
648+
source.sha256 = "c7971efca6500cee8edf2696ec6b38014af82bacfe88a0e583bb9bb3a591bc8d"
650649
output.type = "zone"
651650
output.intermediate_only = true
652651

@@ -672,8 +671,8 @@ only_for_targets.image = "standard"
672671
# the other `source.*` keys.
673672
source.type = "prebuilt"
674673
source.repo = "dendrite"
675-
source.commit = "e83f4f164fd3dbb2100989a399a4fa087232ac36"
676-
source.sha256 = "caf988e39d800bdccb1b9423568a19ba10a79aa2b07f74bf7eb65589fd81f8b1"
674+
source.commit = "fb571dc6512b24a777c5a9b2927a50501f6be297"
675+
source.sha256 = "0a96670ce203bce7bed6a0e40842d319c2b4b8ee1a2e9210d3713423f8bd00b1"
677676
output.type = "zone"
678677
output.intermediate_only = true
679678

@@ -692,8 +691,8 @@ only_for_targets.image = "standard"
692691
# the other `source.*` keys.
693692
source.type = "prebuilt"
694693
source.repo = "dendrite"
695-
source.commit = "e83f4f164fd3dbb2100989a399a4fa087232ac36"
696-
source.sha256 = "378a2f32c1850a5a62fa9b320813e342a647647d2f014ab5eced7c2d1d4f9c95"
694+
source.commit = "fb571dc6512b24a777c5a9b2927a50501f6be297"
695+
source.sha256 = "a5bda6b899bff23fccd4dd74224fd1bc44703741054b50552921efa7470cb11a"
697696
output.type = "zone"
698697
output.intermediate_only = true
699698

@@ -740,6 +739,8 @@ source.packages = [
740739
"switch_zone_setup.tar.gz",
741740
"xcvradm.tar.gz",
742741
"omicron-omdb.tar.gz",
742+
"zone-setup.tar.gz",
743+
"zone-network-install.tar.gz"
743744
]
744745
output.type = "zone"
745746

@@ -764,6 +765,8 @@ source.packages = [
764765
"switch_zone_setup.tar.gz",
765766
"sp-sim-stub.tar.gz",
766767
"omicron-omdb.tar.gz",
768+
"zone-setup.tar.gz",
769+
"zone-network-install.tar.gz"
767770
]
768771
output.type = "zone"
769772

@@ -788,6 +791,8 @@ source.packages = [
788791
"switch_zone_setup.tar.gz",
789792
"sp-sim-softnpu.tar.gz",
790793
"omicron-omdb.tar.gz",
794+
"zone-setup.tar.gz",
795+
"zone-network-install.tar.gz"
791796
]
792797
output.type = "zone"
793798

sled-agent/src/params.rs

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -597,9 +597,6 @@ impl crate::smf_helper::Service for OmicronZoneType {
597597
fn smf_name(&self) -> String {
598598
format!("svc:/oxide/{}", self.service_name())
599599
}
600-
fn should_import(&self) -> bool {
601-
true
602-
}
603600
}
604601

605602
impl From<OmicronZoneType> for sled_agent_client::types::OmicronZoneType {

sled-agent/src/profile.rs

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -163,6 +163,7 @@ impl Display for ServiceInstanceBuilder {
163163
}
164164
}
165165

166+
#[derive(Clone)]
166167
pub struct PropertyGroupBuilder {
167168
name: String,
168169
/// names of the properties that were added, in the order they were added
@@ -233,7 +234,7 @@ impl Display for PropertyGroupBuilder {
233234
if values.len() == 1 {
234235
write!(
235236
f,
236-
r#" <propval type="{ty}" name="{name}" value="{value}"/>
237+
r#" <propval type="{ty}" name="{name}" value='{value}'/>
237238
"#,
238239
name = property_name,
239240
value = &values[0],
@@ -302,7 +303,7 @@ mod tests {
302303
<service_bundle type="profile" name="myprofile">
303304
<service version="1" type="service" name="myservice">
304305
<property_group type="application" name="mypg">
305-
<propval type="astring" name="myprop" value="myvalue"/>
306+
<propval type="astring" name="myprop" value='myvalue'/>
306307
</property_group>
307308
</service>
308309
</service_bundle>"#,
@@ -384,7 +385,7 @@ mod tests {
384385
<service version="1" type="service" name="myservice">
385386
<instance enabled="true" name="default">
386387
<property_group type="application" name="mypg">
387-
<propval type="type" name="prop" value="value"/>
388+
<propval type="type" name="prop" value='value'/>
388389
</property_group>
389390
</instance>
390391
</service>
@@ -429,11 +430,11 @@ mod tests {
429430
</property_group>
430431
<instance enabled="true" name="default">
431432
<property_group type="application" name="mypg">
432-
<propval type="type" name="prop" value="value"/>
433-
<propval type="type" name="prop2" value="value2"/>
433+
<propval type="type" name="prop" value='value'/>
434+
<propval type="type" name="prop2" value='value2'/>
434435
</property_group>
435436
<property_group type="application" name="mypg2">
436-
<propval type="type" name="prop3" value="value3"/>
437+
<propval type="type" name="prop3" value='value3'/>
437438
</property_group>
438439
</instance>
439440
</service>

0 commit comments

Comments
 (0)