Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

update_agent: support rebase to OCI pullspec #1241

Open
wants to merge 14 commits into
base: main
Choose a base branch
from

Conversation

jbtrystram
Copy link

Add a configuration knob in update to optionnaly use OCI pullspec instead of ostree checksums.

This will default to false.
Requires coreos/fedora-coreos-cincinnati#99 and coreos/rpm-ostree#5120

@jbtrystram jbtrystram force-pushed the oci_scheme branch 2 times, most recently from f0713e1 to 1ca8a87 Compare December 4, 2024 14:18
@jbtrystram jbtrystram changed the title update_agent: support rebaseing to OCI pullspec update_agent: support rebase to OCI pullspec Dec 4, 2024
Copy link
Member

@travier travier left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Very quick look but looks good 👍🏻

Copy link
Member

@jlebon jlebon left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's cross-link to coreos/fedora-coreos-tracker#1823 in the commit message for the larger context.

tests/fixtures/00-config-sample.toml Outdated Show resolved Hide resolved
src/cincinnati/mod.rs Outdated Show resolved Hide resolved
src/cincinnati/mod.rs Outdated Show resolved Hide resolved
src/rpm_ostree/cli_deploy.rs Outdated Show resolved Hide resolved
@jbtrystram jbtrystram force-pushed the oci_scheme branch 3 times, most recently from 4b9c09b to 11aa880 Compare December 16, 2024 10:45
Parse rpm-ostree status to detect if the current booted deployment
is an OCI image. If so, query the OCI graph for cincinnati and
rebase to the correct OCI image.

Requires coreos/fedora-coreos-cincinnati#99
and coreos/rpm-ostree#5120

Part of: coreos/fedora-coreos-tracker#1823
Copy link
Author

@jbtrystram jbtrystram left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I updated this to use ostree-remote-image so we validate the ostree signatures, as suggested in coreos/fedora-coreos-tracker#1823 (comment)

I think this is ready for review now. I will clean up and sqash commits once the design is agreed

src/rpm_ostree/cli_status.rs Outdated Show resolved Hide resolved
src/rpm_ostree/cli_deploy.rs Outdated Show resolved Hide resolved
Comment on lines 93 to 102
pub fn base_revision(&self) -> String {
self.base_checksum
self.container_image_reference
.clone()
.map(|pullspec| {
pullspec
.strip_prefix("ostree-remote-image:fedora:docker://")
.map(|s| s.to_string())
})
.flatten()
.or(self.base_checksum.clone())
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe it would make more sense to add an Option<String> to the Deployement struct to be able to have both the pullspec and the base commit ?
However the cincinnati graph does not contains checksum in the OCI case so we can't compare ostree commits when doing rebase later anyway.

Copy link
Author

@jbtrystram jbtrystram Feb 5, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

haven't had the need for it in the Zincati context, except maybe if we want Zincati to do OCI -> OSTree ? (in that case, after calling rpm-ostree deploy zincati will fail as the checksum won't match

@jbtrystram
Copy link
Author

OK, had some more discussion with Jlebon and travier today and there are some more things to flesh out

@jbtrystram jbtrystram marked this pull request as draft January 13, 2025 14:36
src/rpm_ostree/mod.rs Outdated Show resolved Hide resolved
@jbtrystram
Copy link
Author

jbtrystram commented Jan 15, 2025

Allright, I think this is ready for review now. I highlighted a couple of things I am unsure of.
I will squash the commits after addressing review comments

@jbtrystram jbtrystram marked this pull request as ready for review January 15, 2025 17:20
Some(params) => params,
None => HashMap::new(),
};
let query_params = self.query_params.unwrap_or_default();
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Minor: clippy fix I'm guessing? This could be its own separate commit.

Comment on lines 239 to 242
log::warn!(
"booted deployment {} not found in the update graph",
&booted_depl.checksum
);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Minor: this could be its own separate commit.

src/rpm_ostree/cli_deploy.rs Outdated Show resolved Hide resolved
src/rpm_ostree/cli_status.rs Outdated Show resolved Hide resolved
src/cincinnati/mod.rs Outdated Show resolved Hide resolved
src/rpm_ostree/actor.rs Outdated Show resolved Hide resolved
tests/fixtures/rpm-ostree-oci-status.json Outdated Show resolved Hide resolved
// get the latest commit but that would be racy, so let's finalize the latest
// commit.
if release.is_oci {
cmd.arg("--allow-missing-checksum")
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think probably the cleaner thing is to have rpm-ostree accept a digested pullspec the way it accepts commit checksums and it can verify that it matches the digested pullspec that was staged. Then we can drop this.

src/rpm_ostree/mod.rs Outdated Show resolved Hide resolved
Comment on lines 481 to 494
bail!(
log::error!(
"expected pending deployment '{}', but found '{}' instead",
release.version,
pending.version
);
return Ok(false);
}
if pending.checksum != release.checksum {
bail!(
log::error!(
"detected checksum mismatch for pending deployment '{}', got unexpected value '{}'",
release.version,
release.checksum,
);
return Ok(false);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hmm, why do we need this?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The rest of the function was built that way, and the bail error text was swallowed so I just aligned all the checks to use the same syntax

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This changes the semantics of the function. I think those differences might be on purpose.

In the OSTree case, if the checksum doesn't match, then something went really wrong because we expicitly deployed by checksum. Whereas the stream check below this line is done here because it can't be done before deploying; it's part of the commit metadata. (Though I guess we could pull it before deploying.)

We can't exactly transpose this to the OCI case, because there while we do deploy by digest, that digest doesn't actually mean much within the object store. That said, here I think checksum is actually the pullspec in the OCI path as this PR is written (right?), so we do also expect it to be always true. It's basically checking that the custom origin URL we've set has correctly been set. I think then we do still want to keep this a hard error?

For the version check, I think the change to not make it a hard error makes sense.

@jbtrystram
Copy link
Author

Allright, I reworked this PR a bunch following the review comments, that ended up being pretty substantial changes.

Overview :

  • A local deployment is now unserialized with an enum containing either a Checksum or a Pullspec. Both are simply strings, but I use that to match my way around, rather than a is_oci boolean.
  • custom-origin fields are now purely cosmetic : Zincati will cue from the container-image-reference.
  • Now properly parses the OCI manifest output from rpm-ostree --json and get the fedora-coreos.stream key from that. This is working around rpm-ostree status --json does not properly serialize ostree.manifest for OCI deployments rpm-ostree#5196
  • imported a couple of new crates : oci-spec for the above issue and ostree-rs to properly parse ostree image references and containers pull specs. I removed the hacky split(':') and split(":sha256")` in favor of that.

Testing

Here are my notes to test this out it case someone wants to experiment:

Start a VM with Zincati disabled : cosa run --qemu-image fedora-coreos-41.20241215.2.0-qemu.x86_64.qcow2 --add-ignition noautoupdate

Rebase to an OCI image in graph (recent enough to get rpm-ostree-2024.9) :

    sudo rpm-ostree rebase ostree-remote-image:fedora:registry:quay.io/fedora/fedora-coreos@sha256:74448159fae255797012a12eaf9089ea3c1018ffb0b3e76e03483cba59b50bb2 \
     --custom-origin-url=quay.io/fedora/fedora-coreos@sha256:74448159fae255797012a12eaf9089ea3c1018ffb0b3e76e03483cba59b50bb2 \
     --custom-origin-description="Fedora CoreOS testing stream"
     sudo reboot

Now import Zincati build with this PR then:

    sudo rm /etc/zincati/config.d/90-disable-auto-updates.toml
    sudo systemctl restart zincati

Zincati should now pick up an OCI update through the OCI graph

Getting zincati custom build in the COSA VM

While we can make a custom FCOS build with an override to get our Zincati build inside, it will be erased by the content of the OCI image with a rebase, so here is how I did, after building zincati and copy the binary into $COSA_DIR/tmp

rpm-ostree usroverlay
cp /mnt/workdir-tmp/zincati /usr/libexec/zincati
cp /mnt/workdir-tmp/zincati.rules /usr/share/polkit-1/rules.d/zincati.rules

# restart polkit
systemctl restart polkit.service

# re enable updates
rm /etc/zincati/config.d/90-disable-auto-updates.toml

# restart zincati
systemctl restart zincati.service

# Show the update
journalctl --no-pager -o cat -u zincati --follow

In the meantime, I'll squash this and try to make commits that make sense :)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants