Skip to content

Remove rpm depency from packagesystem! - #1130

Open
krolmiki2011 wants to merge 2 commits into
coreos:mainfrom
ImmutableLinux:no-rpm-anymore
Open

Remove rpm depency from packagesystem!#1130
krolmiki2011 wants to merge 2 commits into
coreos:mainfrom
ImmutableLinux:no-rpm-anymore

Conversation

@krolmiki2011

@krolmiki2011 krolmiki2011 commented Jul 27, 2026

Copy link
Copy Markdown

Thanks to these changes, it will be possible to eliminate the rpm dependency from bootupd and become more distribution-independent!

KEY CHANGES:
BIOS:
In the case of BIOS, ContentMetadata is created just as it is for UEFI; for BIOS, grub2-install --version and the mtime are used.
EFI (ostree-boot):
The situation is similar for ostree-boot in BIOS mode, except it iterates through files, and the version format is: legacy-ostree-boot-{mtime}

NOTE:
The old code, before the modification, is in the {bios, efi, packagesystem}_legacy.rs

Oh, and 'grub2-install --version' need package maintainers to patch grub2 upstream version to package version

This patch was inspired by issue: #468

@openshift-ci

openshift-ci Bot commented Jul 27, 2026

Copy link
Copy Markdown

Hi @krolmiki2011. Thanks for your PR.

I'm waiting for a coreos member to verify that this patch is reasonable to test. If it is, they should reply with /ok-to-test on its own line. Until that is done, I will not automatically test new commits in this PR, but the usual testing commands by org members will still work.

Regular contributors should join the org to skip this step.

Once the patch is verified, the new status will be reflected by the ok-to-test label.

I understand the commands that are listed here.

Details

Instructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the kubernetes-sigs/prow repository.

@krolmiki2011

Copy link
Copy Markdown
Author

hello can someone help me, because tests not working

@krolmiki2011

Copy link
Copy Markdown
Author

Hello, its anyone here?

@krolmiki2011

Copy link
Copy Markdown
Author

Hello?

@krolmiki2011

Copy link
Copy Markdown
Author

Is there anyone here?

@Rolv-Apneseth

Copy link
Copy Markdown
Member

Hi @krolmiki2011. We have reduced capacity for going through bootupd contributions at the moment, but when I get the chance I'll try to look this over.

From a very brief glance, why keep the legacy code files? Investigating the failing CI will take a more thorough investigation, but it does seem related to these changes. Are we maybe missing something to filter out only bootloader components here?

@Rolv-Apneseth

Copy link
Copy Markdown
Member

One more point, though again it may just require a deeper look from my part, but #468 (comment) would lead me to believe this should be possible without making changes to files other than packagesystem.rs. Could you give a brief explanation of why that wasn't possible for this approach?

@krolmiki2011

Copy link
Copy Markdown
Author

One more point, though again it may just require a deeper look from my part, but #468 (comment) would lead me to believe this should be possible without making changes to files other than packagesystem.rs. Could you give a brief explanation of why that wasn't possible for this approach?

Okay, so I view this notebook as a place to keep things in case the code turns into spaghetti, but also as something to delete once the code is stable.

Regarding your second question—a good point—I noticed that BIOS and Legacy EFI (OSTree boot) both use RPM; while BIOS is handled by query_bios_grub() in packagesystem.rs, Legacy EFI isn't. I could certainly implement a similar function in packagesystem if you'd like.

@Rolv-Apneseth

Copy link
Copy Markdown
Member

So, trying to understand this a bit better, as TBH I'm still learning about bootupd and how it works:

We want to make bootupd more distro-agnostic, so we want to remove the requirement for rpm. This is currently used to get the version+build time of the files tracked by bootupd (to know if an update is needed). And, this is only the case for legacy EFI and BIOS implementations, since the newer EFI path parses version info from the directory structure (/usr/lib/efi/<name>/<version>/EFI - only implemented on Fedora 44+ though). The version(s) returned by rpm for each package (e.g. grub2-tools-1:2.12-64.fc44.x86_64) is persisted on existing systems for later comparison. The timestamp also gets persisted but I don't actually see that being used anywhere.

Quick overview of the data that gets stored:

ContentMetadata struct
pub(crate) struct ContentMetadata {
    /// The timestamp, which is used to determine update availability
    pub(crate) timestamp: DateTime<Utc>,
    /// Human readable version number, like ostree it is not ever parsed, just displayed
    pub(crate) version: String,
    /// Transfer version into Module struct list
    pub(crate) versions: Option<Vec<Module>>,
    /// The default bootloader to install if at install time no bootloader option is
    /// provided
    #[cfg(efi_arch)]
    pub(crate) default_bootloader: Option<Bootloader>,
}

Note that the descriptions for timestamp and version are out of date - timestamp appears unused, and version is used as a legacy fallback. versions is used when available.

Example bootupd-state.json
{
  "installed": {
    "BIOS": {
      "meta": {
        "timestamp": "2026-06-09T16:53:24Z",
        "version": "grub2-tools-1:2.12-60.fc44.x86_64",
        "versions": [
          {
            "name": "grub2",
            "rpm_evr": "1:2.12-60.fc44"
          }
        ]
      },
      "filetree": null,
      "adopted-from": null
    },
    "EFI": {
      "meta": {
        "timestamp": "2026-08-13T14:37:10.461466856Z",
        "version": "grub2-1:2.12-60.fc44,shim-16.1-5",
        "versions": [
          {
            "name": "grub2",
            "rpm_evr": "1:2.12-60.fc44"
          },
          {
            "name": "shim",
            "rpm_evr": "16.1-5"
          }
        ]
      },
      "filetree": {
        "children": {
          "BOOT/BOOTX64.EFI": {
            "source": "shim/16.1-5/EFI/BOOT/BOOTX64.EFI",
            "size": 1026520,
            "sha512": "sha512:0dc3725da36f3183b5cb5af0ba982caccc35019b35f8c80ee29545b7f9fa0672aa09aac4f5693f250ca603910aa4249538d45991595cae198f897ee2f406bb27"
          },
          "BOOT/fbx64.efi": {
            "source": "shim/16.1-5/EFI/BOOT/fbx64.efi",
            "size": 119280,
            "sha512": "sha512:46bf07b2212b2042f2c3eb44b0fc94527443ebd405204fd09014c55b4f3fd5d590007d78a5662f79570cfdb90e5c8ed5d794d7fa85ed8914d4c60b1d6ee9441d"
          },
          "fedora/BOOTX64.CSV": {
            "source": "shim/16.1-5/EFI/fedora/BOOTX64.CSV",
            "size": 110,
            "sha512": "sha512:0c29b8ae73171ef683ba690069c1bae711e130a084a81169af33a83dfbae4e07d909c2482dbe89a96ab26e171f17c53f1de8cb13d558bc1535412ff8accf253f"
          },
          "fedora/grubx64.efi": {
            "source": "grub2/1:2.12-60.fc44/EFI/fedora/grubx64.efi",
            "size": 4145576,
            "sha512": "sha512:1f86c5f4824cf292a9e36314186309977a8d92834c48b70ac128f7ec2289a544acddce16ea1b7d2457426cdd2fd5dfc65beab727f171c2fe443f8fc4ba19d684"
          },
          "fedora/mmx64.efi": {
            "source": "shim/16.1-5/EFI/fedora/mmx64.efi",
            "size": 874352,
            "sha512": "sha512:d63aafcab70aeedcf1e083fda32130d9ba997ad04f8466c0d058f5d364a48d554b7160c0a4f17441f19797d39dfd785516078d3bd841714df2c2aa3327f3fa9f"
          },
          "fedora/shim.efi": {
            "source": "shim/16.1-5/EFI/fedora/shim.efi",
            "size": 1026520,
            "sha512": "sha512:0dc3725da36f3183b5cb5af0ba982caccc35019b35f8c80ee29545b7f9fa0672aa09aac4f5693f250ca603910aa4249538d45991595cae198f897ee2f406bb27"
          },
          "fedora/shimx64.efi": {
            "source": "shim/16.1-5/EFI/fedora/shimx64.efi",
            "size": 1026520,
            "sha512": "sha512:0dc3725da36f3183b5cb5af0ba982caccc35019b35f8c80ee29545b7f9fa0672aa09aac4f5693f250ca603910aa4249538d45991595cae198f897ee2f406bb27"
          }
        }
      },
      "adopted-from": null
    }
  },
  "pending": null,
  "static-configs": {
    "timestamp": "1970-01-01T00:00:00Z",
    "version": "0.2.35",
    "versions": null
  }
}

Side note, but this also shows that the timestamps are inconsistent - BIOS is giving the build time of the RPM, whereas EFI (which I guess is using the filetree of /usr/lib/efi) is giving the time the state file was generated.


This patch is currently changing the approach for BIOS to directly query and parse /usr/sbin/grub2-install --version, which you admit would require extra work to actually return the output we're looking for (and not ignore patch-level version bumps):

Oh, and 'grub2-install --version' need package maintainers to patch grub2 upstream version to package version

Since currently this returns something like grub2-install (GRUB) 2.12 and we parse out 2.12 by splitting white space. However, I don't think that's a realistic expectation from package maintainers, and maybe I'm wrong but I feel like it doesn't make much sense to change a tool's output like that.

For the ostree-boot EFI path, which used to query all files under /usr/lib/ostree-boot/efi/EFI with rpm to find grub and shim versions, this patch instead creates a synthetic version with "rpm_evr": "legacy-ostree-boot-{SystemTime::now()}", which 1. loses per-package breakdowns and 2. AFAICT would always then be considered update-able.

Worth also noting that the ostree-boot EFI path is what any system that doesn't have the usr/lib/efi/<name>/<version>/EFI layout would use, so that seems like the important one to do well. Currently, any system without /usr/lib/ostree-boot or /usr/lib/efi will fail, so some work would still be needed to support other distros that don't use ostree (if that's planned).


I think the first approach I would have thought of for this is to just parse version outputs from the main package managers (e.g. rpm, apt, pacman), finding whatever is installed on the system, and use those for versioning. But I believe the suggestion from @cgwalters (correct me if I'm wrong) was to not have this done in Rust, but rather have the base image provide a common script (e.g. get-package-version) which we could just call, shifting the burden of figuring out what package manager command is required out of bootupd.

Another approach that pops to mind is to use something like file hashes for versioning instead. So equal hashes of the file content means no update, not equal means update. That loses downgrade detection, but maybe that's fine for a bootloader updater. The EFI filetree already has hashes for each file, and for BIOS we could just hash the grub binary instead? I'm sure there's issues that I'm not foreseeing with this though.

The script approach probably means the least amount of work and changes for bootupd, and it could probably also be used when actually building the path layouts in /usr/lib/efi for the images that implement it. I don't have the context on whether we expect other distros to implement https://fedoraproject.org/wiki/Changes/BootLoaderUpdatesPhase1.


And thanks for working on this @krolmiki2011. I'd say let's decide on a solution first before we continue iterating. I'll try to follow up with others to see how to proceed, and maybe bring it up in a community meeting.

@krolmiki2011

krolmiki2011 commented Aug 18, 2026

Copy link
Copy Markdown
Author

@Rolv-Apneseth thanks for the reply and comment, and i kinda noticed, that grub2-install --version in fedora is 2.12, so less of topic i made pull request: https://src.fedoraproject.org/rpms/grub2/pull-request/246 to fix version

@krolmiki2011

Copy link
Copy Markdown
Author

Oh, and i open for another solutions

Comment thread src/packagesystem.rs Outdated
@krolmiki2011

Copy link
Copy Markdown
Author

@Rolv-Apneseth I made a script to begin with script is in packagesystem/query_file_owner

@krolmiki2011

Copy link
Copy Markdown
Author

@Rolv-Apneseth i think i replace rpm with script, what do you think?

@krolmiki2011

Copy link
Copy Markdown
Author

@Rolv-Apneseth i guess my code is ready to test

@krolmiki2011

Copy link
Copy Markdown
Author

Test needs to be fixed btw!

@Rolv-Apneseth Rolv-Apneseth left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Thanks for moving to the script approach. I have a couple of notes but WDYT @cgwalters

Comment thread packagesystem/query-file-owner Outdated
Comment thread packagesystem/query-file-owner Outdated
Comment thread src/packagesystem.rs Outdated
Comment thread src/packagesystem.rs Outdated
Comment thread Cargo.toml Outdated
Comment thread Makefile Outdated
@krolmiki2011

krolmiki2011 commented Aug 25, 2026

Copy link
Copy Markdown
Author

I made changes, but i have a question @Rolv-Apneseth , should EFI timestamp be: Utc::now() ?

@Rolv-Apneseth

Copy link
Copy Markdown
Member

I made changes, but i have a question @Rolv-Apneseth , should EFI timestamp be: Utc::now() ?

I think it should match whatever's being done for the /usr/lib/efi path, but it's not too important either way

@krolmiki2011

Copy link
Copy Markdown
Author

@Rolv-Apneseth yea, btw i made changes you proposed

@Rolv-Apneseth

Copy link
Copy Markdown
Member

I made changes, but i have a question @Rolv-Apneseth , should EFI timestamp be: Utc::now() ?

I think it should match whatever's being done for the /usr/lib/efi path, but it's not too important either way

@krolmiki2011 Ok, I wasn't aware of #1075 and https://reproducible-builds.org/docs/source-date-epoch. Please restore get_metadata_timestamp and use it in both locations.

@krolmiki2011

krolmiki2011 commented Aug 25, 2026

Copy link
Copy Markdown
Author

I made changes, but i have a question @Rolv-Apneseth , should EFI timestamp be: Utc::now() ?

I think it should match whatever's being done for the /usr/lib/efi path, but it's not too important either way

@krolmiki2011 Ok, I wasn't aware of #1075 and https://reproducible-builds.org/docs/source-date-epoch. Please restore get_metadata_timestamp and use it in both locations.

Wait, and bios too? @Rolv-Apneseth

@Rolv-Apneseth

Copy link
Copy Markdown
Member

Wait, and bios too? @Rolv-Apneseth

Just have get_metadata_timestamp handle all paths, yeah (so call it in parse_package_metadata). Internally it'll get the current timestamp if SOURCE_DATE_EPOCH isn't defined.

Comment thread packagesystem/query-file-owner Outdated
Comment thread src/packagesystem.rs Outdated
Comment thread src/packagesystem.rs Outdated
Comment thread .cci.jenkinsfile
Comment thread Cargo.toml
Comment thread Makefile Outdated
Comment thread README-devel.md Outdated
Comment thread README-devel.md Outdated
Comment thread packagesystem/query-file-owner Outdated
Comment thread packagesystem/query-file-owner Outdated
Comment thread packagesystem/query-file-owner-apk Outdated
Comment thread src/packagesystem.rs Outdated
Comment thread src/util.rs Outdated
@Rolv-Apneseth

Copy link
Copy Markdown
Member

CI failure is just cause the jenkins job is run from the jenkinsfile in main, not this branch.

08:08:21  + cargo test --features rpm
08:08:21  error: the package 'bootupd' does not contain this feature: rpm

And before that, the failures in that job are because there's a couple places in tests/e2e-update/e2e-update-in-vm.sh we need to change to expect space-separated output.


The bootc-e2e CI failed with:

error: generating metadata failed: query-file-owner failed
  1. I think we should include the stderr from the script in this error message
  2. The issue (I believe) is with checking the existence of files ([ ! -e "$FILE" ]). Leave that check out since (at least) RPM doesn't require a file to actually exist and just checks its database to see who has a claim over that path. This is used in the legacy EFI handling, since files are moved from their original paths ( transfer_ostree_boot_to_bootupd_updates).

Comment thread src/packagesystem.rs Outdated
@Rolv-Apneseth

Copy link
Copy Markdown
Member

Maybe just add the empty rpm feature back so we can see where we stand with CI @krolmiki2011

@krolmiki2011

Copy link
Copy Markdown
Author

Maybe just add the empty rpm feature back so we can see where we stand with CI @krolmiki2011

Thats why i added earlier

@Rolv-Apneseth

Copy link
Copy Markdown
Member

Thats why i added earlier

Fair enough, didn't realise that was why

@krolmiki2011

krolmiki2011 commented Aug 26, 2026

Copy link
Copy Markdown
Author

Now lets see is this gonna work

@krolmiki2011

Copy link
Copy Markdown
Author

Query File Script works in test

@krolmiki2011

Copy link
Copy Markdown
Author

@Rolv-Apneseth i think i mess up in e2e test scripts

@krolmiki2011

Copy link
Copy Markdown
Author

and i mess up

@krolmiki2011

Copy link
Copy Markdown
Author

At lleast bootc worked

@Rolv-Apneseth

Copy link
Copy Markdown
Member

Not sure it's your fault, though I'm not sure why it doesn't already happen on main, but it seems like some kind of race condition:

[2026-08-26T12:23:12.251Z] # Starting /run/bootupd-source/tests/e2e-update//e2e-update-in-vm.sh
[2026-08-26T12:23:12.251Z] # Skipped: BIOS
[2026-08-26T12:23:12.251Z] # Validated: EFI
[2026-08-26T12:23:12.251Z] # ok validate
[2026-08-26T12:23:12.251Z] # Component BIOS
[2026-08-26T12:23:12.251Z] #   Installed: grub2-tools 1:2.12-56.fc44
[2026-08-26T12:23:12.251Z] #   Update: Available: grub2-tools 1:2.12-58.fc44
[2026-08-26T12:23:12.251Z] # Component EFI
[2026-08-26T12:23:12.251Z] #   Installed: grub2 1:2.12-56.fc44,shim 16.1-5
[2026-08-26T12:23:12.251Z] #   Update: Available: grub2 1:2.12-58.fc44,shim 16.1-5,test_bootupd_payload 1.0
[2026-08-26T12:23:12.251Z] # No components are adoptable.
[2026-08-26T12:23:12.251Z] # Aleph version: 44.20260826.20.dev1
[2026-08-26T12:23:12.251Z] # Boot method: EFI
[2026-08-26T12:23:12.251Z] # ok update avail
[2026-08-26T12:23:12.251Z] # Previous BIOS: grub2-tools 1:2.12-56.fc44
[2026-08-26T12:23:12.251Z] # Updated BIOS: grub2-tools 1:2.12-58.fc44
[2026-08-26T12:23:12.251Z] # [TRACE bootupd] executing cli
[2026-08-26T12:23:12.251Z] # [DEBUG bootupd::aleph] Found aleph version in sysroot/.coreos-aleph-version.json
[2026-08-26T12:23:12.251Z] # [TRACE bootupd::bootupd] Gathering status for installed component: BIOS
[2026-08-26T12:23:12.251Z] # [TRACE bootupd::bootupd] Gathering status for installed component: EFI
[2026-08-26T12:23:12.251Z] # [DEBUG bootupd::efi] Unmounting RefCell { value: None }
[2026-08-26T12:23:12.251Z] # [TRACE bootupd::bootupd] Remaining known components: 0
[2026-08-26T12:23:12.251Z] # No update available for any component.
[2026-08-26T12:23:12.251Z] # -rw-r--r--. 1 root root 39 Aug 26 12:23 out.txt
[2026-08-26T12:23:12.251Z] # # No update available for any component.
[2026-08-26T12:23:12.251Z] # error: File 'out.txt' doesn't match regexp 'Previous EFI: .*'
[2026-08-26T12:23:12.251Z] + fatal 'test failed'
[2026-08-26T12:23:12.251Z] + echo error: test failed

Could you try apply this patch and we'll see if that prevents it:

diff --git a/tests/e2e-update/e2e-update.sh b/tests/e2e-update/e2e-update.sh
index 07c6da00..9efa583c 100755
--- a/tests/e2e-update/e2e-update.sh
+++ b/tests/e2e-update/e2e-update.sh
@@ -93,6 +93,7 @@ systemd:
       enabled: true
       contents: |
         [Unit]
+        Before=bootloader-update.service
         RequiresMountsFor=/run/testtmp
         [Service]
         Type=oneshot

@krolmiki2011

Copy link
Copy Markdown
Author

Okay i applied

@krolmiki2011

Copy link
Copy Markdown
Author

@Rolv-Apneseth it failed again

@krolmiki2011

Copy link
Copy Markdown
Author

I find the issue

@krolmiki2011

Copy link
Copy Markdown
Author

E2E PASSED

@krolmiki2011

Copy link
Copy Markdown
Author

Kola left

@krolmiki2011

Copy link
Copy Markdown
Author

@Rolv-Apneseth tests works

Comment thread packagesystem/query-file-owner-apk Outdated
Comment thread Cargo.toml Outdated
Comment thread README-devel.md Outdated
Comment thread README-devel.md Outdated
@Rolv-Apneseth

Copy link
Copy Markdown
Member

@Rolv-Apneseth tests works

Fantastic. From my point of view the only (major) thing left would be cleaning up all commits into 1 or maybe 2 commits since we don't use squash commits (don't have the context on why).

I would really like at least 1 other review on here though (@Johan-Liebert1 maybe) since this is a big PR. There may be some concerns about making the name+version space-separated, but I think it's the way to go as otherwise we can't (AFAICT) reliably determine where package name ends and version starts when parsing something like grub2-efi-x64-1:2.06-95.fc38.x86_64. Other than that, we agreed a script is the way to go, and with #1137 we'll be moving away from using versions for comparisons anyway.

Worth noting that this also addresses one of the fixes mentioned in #1073

truncation of hyphenated RPM names (e.g. bcm2711-firmware becomes bcm2711)

Comment thread Cargo.toml Outdated
Signed-off-by: krolmiki2011 <mikolajziolkowski504@gmail.com>
Signed-off-by: krolmiki2011 <mikolajziolkowski504@gmail.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants