Skip to content

Commit

Permalink
Update all {F,RH}CoreOS systems that have an aleph version
Browse files Browse the repository at this point in the history
Came up in review in coreos/fedora-coreos-docs#203
Basically it's confusing to users that they need to understand
the difference between `update` and `adopt-and-update`.

From bootupd's perspective these are quite different things;
the first case is a completely known quantity, the second isn't.

However...we can be pretty confident that we can update systems
that have a CoreOS aleph version (i.e. they were generated by coreos-assembler),
since we haven't changed how the bootloader is installed there
really much at all.

This means that for now RHCOS 4.{1,2} bootimages that were
generated via Anaconda will still require `adopt-and-update`,
but detecting and validating that can come as a second phase.

The high level logic here is that the status gains a new
`confident: bool` flag (which corresponds right now to
"have CoreOS aleph").  The client side looks at this
and automatically bridges the `update` CLI to
`adopt-and-update`.

Closes: #103
  • Loading branch information
cgwalters authored and openshift-merge-robot committed Nov 13, 2020
1 parent 481ae48 commit e00de4a
Show file tree
Hide file tree
Showing 5 changed files with 40 additions and 10 deletions.
22 changes: 19 additions & 3 deletions src/bootupd.rs
Original file line number Diff line number Diff line change
Expand Up @@ -243,8 +243,13 @@ pub(crate) fn print_status(status: &Status) -> Result<()> {
if status.adoptable.is_empty() {
println!("No components are adoptable.");
}
for (name, version) in status.adoptable.iter() {
println!("Adoptable: {}: {}", name, version.version);
for (name, adopt) in status.adoptable.iter() {
let ver = &adopt.version.version;
if adopt.confident {
println!("Detected: {}: {}", name, ver);
} else {
println!("Adoptable: {}: {}", name, ver);
}
}

if let Some(coreos_aleph) = coreos::get_aleph_version()? {
Expand All @@ -266,7 +271,7 @@ pub(crate) fn print_status(status: &Status) -> Result<()> {

pub(crate) fn client_run_update(c: &mut ipc::ClientToDaemonConnection) -> Result<()> {
let status: Status = c.send(&ClientRequest::Status)?;
if status.components.is_empty() {
if status.components.is_empty() && status.adoptable.is_empty() {
println!("No components installed.");
return Ok(());
}
Expand Down Expand Up @@ -303,6 +308,17 @@ pub(crate) fn client_run_update(c: &mut ipc::ClientToDaemonConnection) -> Result
}
updated = true;
}
for (name, adoptable) in status.adoptable.iter() {
if adoptable.confident {
let r: ContentMetadata = c.send(&ClientRequest::AdoptAndUpdate {
component: name.to_string(),
})?;
println!("Adopted and updated: {}: {}", name, r.version);
updated = true;
} else {
println!("Component {} requires explicit adopt-and-update", name);
}
}
if !updated {
println!("No update available for any component.");
}
Expand Down
2 changes: 1 addition & 1 deletion src/component.rs
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ pub(crate) trait Component {
/// In an operating system whose initially booted disk image is not
/// using bootupd, detect whether it looks like the component exists
/// and "synthesize" content metadata from it.
fn query_adopt(&self) -> Result<Option<ContentMetadata>>;
fn query_adopt(&self) -> Result<Option<Adoptable>>;

/// Given an adoptable system and an update, perform the update.
fn adopt_update(&self, update: &ContentMetadata) -> Result<InstalledContent>;
Expand Down
9 changes: 6 additions & 3 deletions src/efi.rs
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ impl Component for EFI {
"EFI"
}

fn query_adopt(&self) -> Result<Option<ContentMetadata>> {
fn query_adopt(&self) -> Result<Option<Adoptable>> {
let esp = self.open_esp_optional()?;
if esp.is_none() {
log::trace!("No ESP detected");
Expand All @@ -67,7 +67,10 @@ impl Component for EFI {
version: coreos_aleph.aleph.imgid,
};
log::trace!("EFI adoptable: {:?}", &meta);
Ok(Some(meta))
Ok(Some(Adoptable {
version: meta,
confident: true,
}))
}

/// Given an adoptable system and an update, perform the update.
Expand All @@ -90,7 +93,7 @@ impl Component for EFI {
Ok(InstalledContent {
meta: updatemeta.clone(),
filetree: Some(updatef),
adopted_from: Some(meta),
adopted_from: Some(meta.version),
})
}

Expand Down
12 changes: 11 additions & 1 deletion src/model.rs
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,16 @@ pub(crate) struct ComponentStatus {
pub(crate) adopted_from: Option<ContentMetadata>,
}

/// Information on a component that can be adopted
#[derive(Serialize, Deserialize, Debug)]
#[serde(rename_all = "kebab-case")]
pub(crate) struct Adoptable {
/// A synthetic version
pub(crate) version: ContentMetadata,
/// True if we are likely to be able to reliably update this system
pub(crate) confident: bool,
}

/// Representation of bootupd's worldview at a point in time.
/// This is intended to be a stable format that is output by `bootupctl status --json`
/// and parsed by higher level management tools. Transitively then
Expand All @@ -106,7 +116,7 @@ pub(crate) struct Status {
/// Maps a component name to status
pub(crate) components: BTreeMap<String, ComponentStatus>,
/// Components that appear to be installed, not via bootupd
pub(crate) adoptable: BTreeMap<String, ContentMetadata>,
pub(crate) adoptable: BTreeMap<String, Adoptable>,
}

#[cfg(test)]
Expand Down
5 changes: 3 additions & 2 deletions tests/e2e-adopt/e2e-adopt-in-vm.sh
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,7 @@ fi

bootupctl status | tee out.txt
assert_file_has_content_literal out.txt 'No components installed.'
assert_file_has_content out.txt 'Adoptable: EFI: .*coreos.*-qemu.*'
assert_file_has_content out.txt 'Detected: EFI: .*coreos.*-qemu.*'

bootupctl validate | tee out.txt
assert_file_has_content_literal out.txt 'No components installed.'
Expand All @@ -105,7 +105,8 @@ assert_not_file_has_content_literal out.txt "Validated"
assert_not_has_file /boot/bootupd-state.json
ok validate

bootupctl adopt-and-update | tee out.txt
# Explicitly testing https://github.com/coreos/bootupd/issues/103
bootupctl update | tee out.txt
assert_file_has_content out.txt 'Adopted and updated: EFI: grub2-efi-x64'
ok adoption

Expand Down

0 comments on commit e00de4a

Please sign in to comment.