Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
44 commits
Select commit Hold shift + click to select a range
94908e7
first brush at processing primary boot device selection in control plane
iximeow Sep 16, 2024
55c2fe2
actually set up crdb properly with new column
iximeow Sep 17, 2024
3e5ba81
rustfmt
iximeow Sep 17, 2024
1a70c9f
make boot_device uuid, constrain disk detach and boot_device assignment
iximeow Sep 20, 2024
60993d3
generalize {set,clear}_boot_device into other instance setting changes
iximeow Sep 21, 2024
097a961
setting boot device does not have the instance_attach_disk problem
iximeow Sep 21, 2024
5f8844c
cleanup, also figured out why rustfmt wasnt respecting 80col
iximeow Sep 21, 2024
7b7c290
rustfmt, line wrapping
iximeow Sep 21, 2024
a059312
first_async introduced some types issues, oops
iximeow Sep 21, 2024
b7833bf
unwind deteching if a boot disk is present and unattached vs nonexistant
iximeow Sep 21, 2024
53873aa
allow reconfiguration of instances in Creating
iximeow Sep 21, 2024
cae16ea
include the field rename...
iximeow Sep 21, 2024
662401d
line wrapping, update nexus_tags.txt
iximeow Sep 21, 2024
efb34a5
update endpoint is a PUT on the resource, add unauthorized coverage
iximeow Sep 21, 2024
4eb1ff5
s/boot_device/boot_disk/g
iximeow Sep 21, 2024
da9e29c
and the column gets a s/boot_disk/boot_disk_id/g
iximeow Sep 21, 2024
1b21005
how did that not rustfmt before???
iximeow Sep 21, 2024
1537af9
update openapi documents
iximeow Sep 24, 2024
31a1ba0
reconfigure_instance -> instance_reconfigure
iximeow Sep 24, 2024
bf36e98
a few more words on why set_boot_disk is weird
iximeow Sep 24, 2024
5a7863f
might as well assert on that error
iximeow Sep 24, 2024
73069f2
overzealous boot_disk_id in tests
iximeow Sep 24, 2024
60d7972
temp
iximeow Sep 24, 2024
a4688d8
use propolis-client's new BootSettings type
iximeow Sep 24, 2024
ed5f0e5
Merge branch 'main' into ixi/boot-order
iximeow Sep 25, 2024
e4e299a
update openapi documents post-merge
iximeow Sep 25, 2024
02e76de
clippy
iximeow Sep 25, 2024
6b65dfe
do update propolis...
iximeow Sep 25, 2024
35be25f
didnt even know that test was there..
iximeow Sep 25, 2024
d6b1e73
test merge fixup as well
iximeow Sep 25, 2024
93a0268
more clippy fixes (in tests! just run cargo xtask clippy.)
iximeow Sep 25, 2024
886f735
other half of the "boot_disk_id" migration + test that it migrates right
iximeow Sep 27, 2024
996687e
better API documentation on the `boot_disk` field
iximeow Sep 27, 2024
7d599b3
Merge remote-tracking branch 'origin/main' into ixi/boot-order-correc…
iximeow Sep 27, 2024
0bd0919
documentation for kinda-unsatisfying `add-instance-boot-disk`
iximeow Sep 27, 2024
e8c8554
not those though
iximeow Sep 27, 2024
9c04206
resolved schema change conflict incompletely
iximeow Sep 27, 2024
ef268bf
updating a wrong-state instance is conflict
iximeow Sep 27, 2024
70344ad
good to have boot disk listed in omdb
iximeow Sep 27, 2024
73882b5
speed limit 80
iximeow Sep 27, 2024
404801c
clippy/fmt
iximeow Sep 27, 2024
28cdc3d
Merge branch 'main' into ixi/boot-order
iximeow Sep 30, 2024
8b22d56
instance create API: boot disk name -> boot disk attachment
iximeow Sep 30, 2024
899f781
Merge branch 'main' into ixi/boot-order
iximeow Sep 30, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
37 changes: 29 additions & 8 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

6 changes: 3 additions & 3 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -511,9 +511,9 @@ prettyplease = { version = "0.2.22", features = ["verbatim"] }
proc-macro2 = "1.0"
progenitor = "0.8.0"
progenitor-client = "0.8.0"
bhyve_api = { git = "https://github.com/oxidecomputer/propolis", rev = "fae5334bcad5e864794332c6fed5e6bb9ec88831" }
propolis-client = { git = "https://github.com/oxidecomputer/propolis", rev = "fae5334bcad5e864794332c6fed5e6bb9ec88831" }
propolis-mock-server = { git = "https://github.com/oxidecomputer/propolis", rev = "fae5334bcad5e864794332c6fed5e6bb9ec88831" }
bhyve_api = { git = "https://github.com/oxidecomputer/propolis", rev = "11371b0f3743f8df5b047dc0edc2699f4bdf3927" }
propolis-client = { git = "https://github.com/oxidecomputer/propolis", rev = "11371b0f3743f8df5b047dc0edc2699f4bdf3927" }
propolis-mock-server = { git = "https://github.com/oxidecomputer/propolis", rev = "11371b0f3743f8df5b047dc0edc2699f4bdf3927" }
proptest = "1.5.0"
qorb = { git = "https://github.com/oxidecomputer/qorb", branch = "master" }
quote = "1.0"
Expand Down
13 changes: 13 additions & 0 deletions common/src/api/external/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -348,6 +348,16 @@ impl TryFrom<String> for NameOrId {
}
}

impl FromStr for NameOrId {
// TODO: We should have better error types here.
// See https://github.com/oxidecomputer/omicron/issues/347
type Err = String;

fn from_str(value: &str) -> Result<Self, Self::Err> {
NameOrId::try_from(String::from(value))
}
}

impl From<Name> for NameOrId {
fn from(name: Name) -> Self {
NameOrId::Name(name)
Expand Down Expand Up @@ -1183,6 +1193,9 @@ pub struct Instance {
/// RFC1035-compliant hostname for the Instance.
pub hostname: String,

/// the ID of the disk used to boot this Instance, if a specific one is assigned.
pub boot_disk_id: Option<Uuid>,

#[serde(flatten)]
pub runtime: InstanceRuntimeState,

Expand Down
3 changes: 3 additions & 0 deletions dev-tools/omdb/src/bin/omdb/db.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2941,6 +2941,7 @@ async fn cmd_db_instance_info(
const VCPUS: &'static str = "vCPUs";
const MEMORY: &'static str = "memory";
const HOSTNAME: &'static str = "hostname";
const BOOT_DISK: &'static str = "boot disk";
const AUTO_RESTART: &'static str = "auto-restart";
const STATE: &'static str = "nexus state";
const LAST_MODIFIED: &'static str = "last modified at";
Expand All @@ -2963,6 +2964,7 @@ async fn cmd_db_instance_info(
DELETED,
VCPUS,
MEMORY,
BOOT_DISK,
HOSTNAME,
AUTO_RESTART,
STATE,
Expand Down Expand Up @@ -3006,6 +3008,7 @@ async fn cmd_db_instance_info(
println!(" {VCPUS:>WIDTH$}: {}", instance.ncpus.0 .0);
println!(" {MEMORY:>WIDTH$}: {}", instance.memory.0);
println!(" {HOSTNAME:>WIDTH$}: {}", instance.hostname);
println!(" {BOOT_DISK:>WIDTH$}: {:?}", instance.boot_disk_id);
print_multiline_debug(AUTO_RESTART, &instance.auto_restart);
println!("\n{:=<80}", "== RUNTIME STATE ");
let InstanceRuntimeState {
Expand Down
5 changes: 3 additions & 2 deletions end-to-end-tests/src/instance_launch.rs
Original file line number Diff line number Diff line change
Expand Up @@ -66,9 +66,10 @@ async fn instance_launch() -> Result<()> {
hostname: "localshark".parse().unwrap(), // 🦈
memory: ByteCount(1024 * 1024 * 1024),
ncpus: InstanceCpuCount(2),
disks: vec![InstanceDiskAttachment::Attach {
boot_disk: Some(InstanceDiskAttachment::Attach {
name: disk_name.clone(),
}],
}),
disks: Vec::new(),
network_interfaces: InstanceNetworkInterfaceAttachment::Default,
external_ips: vec![ExternalIpCreate::Ephemeral { pool: None }],
user_data: String::new(),
Expand Down
15 changes: 15 additions & 0 deletions nexus/db-model/src/instance.rs
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,10 @@ pub struct Instance {
#[diesel(embed)]
pub auto_restart: InstanceAutoRestart,

/// The primary boot disk for this instance.
#[diesel(column_name = boot_disk_id)]
pub boot_disk_id: Option<Uuid>,

#[diesel(embed)]
pub runtime_state: InstanceRuntimeState,

Expand Down Expand Up @@ -115,6 +119,9 @@ impl Instance {
memory: params.memory.into(),
hostname: params.hostname.to_string(),
auto_restart,
// Intentionally ignore `params.boot_disk_id` here: we can't set
// `boot_disk_id` until the referenced disk is attached.
boot_disk_id: None,

runtime_state,

Expand Down Expand Up @@ -520,3 +527,11 @@ mod optional_time_delta {
.serialize(serializer)
}
}

/// The parts of an Instance that can be directly updated after creation.
#[derive(Clone, Debug, AsChangeset, Serialize, Deserialize)]
#[diesel(table_name = instance, treat_none_as_null = true)]
pub struct InstanceUpdate {
#[diesel(column_name = boot_disk_id)]
pub boot_disk_id: Option<Uuid>,
}
1 change: 1 addition & 0 deletions nexus/db-model/src/schema.rs
Original file line number Diff line number Diff line change
Expand Up @@ -409,6 +409,7 @@ table! {
hostname -> Text,
auto_restart_policy -> Nullable<crate::InstanceAutoRestartPolicyEnum>,
auto_restart_cooldown -> Nullable<Interval>,
boot_disk_id -> Nullable<Uuid>,
time_state_updated -> Timestamptz,
state_generation -> Int8,
active_propolis_id -> Nullable<Uuid>,
Expand Down
3 changes: 2 additions & 1 deletion nexus/db-model/src/schema_versions.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ use std::collections::BTreeMap;
///
/// This must be updated when you change the database schema. Refer to
/// schema/crdb/README.adoc in the root of this repository for details.
pub const SCHEMA_VERSION: SemverVersion = SemverVersion::new(106, 0, 0);
pub const SCHEMA_VERSION: SemverVersion = SemverVersion::new(107, 0, 0);

/// List of all past database schema versions, in *reverse* order
///
Expand All @@ -29,6 +29,7 @@ static KNOWN_VERSIONS: Lazy<Vec<KnownVersion>> = Lazy::new(|| {
// | leaving the first copy as an example for the next person.
// v
// KnownVersion::new(next_int, "unique-dirname-with-the-sql-files"),
KnownVersion::new(107, "add-instance-boot-disk"),
KnownVersion::new(106, "dataset-kinds-update"),
KnownVersion::new(105, "inventory-nvme-firmware"),
KnownVersion::new(104, "lookup-bgp-config-indexes"),
Expand Down
12 changes: 11 additions & 1 deletion nexus/db-queries/src/db/datastore/disk.rs
Original file line number Diff line number Diff line change
Expand Up @@ -335,7 +335,11 @@ impl DataStore {
.into_boxed()
.filter(instance::dsl::state
.eq_any(ok_to_detach_instance_states)
.and(instance::dsl::active_propolis_id.is_null())),
.and(instance::dsl::active_propolis_id.is_null())
.and(
instance::dsl::boot_disk_id.ne(authz_disk.id())
.or(instance::dsl::boot_disk_id.is_null())
)),
disk::table
.into_boxed()
.filter(disk::dsl::disk_state.eq_any(ok_to_detach_disk_state_labels)),
Expand Down Expand Up @@ -388,6 +392,12 @@ impl DataStore {
// Ok-to-be-detached instance states:
api::external::InstanceState::Creating |
api::external::InstanceState::Stopped => {
if collection.boot_disk_id == Some(authz_disk.id()) {
return Err(Error::conflict(
"boot disk cannot be detached"
));
}

// We can't detach, but the error hasn't
// helped us infer why.
return Err(Error::internal_error(
Expand Down
Loading
Loading