diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 26d5ce4..7c23636 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -46,13 +46,13 @@ jobs: test-fedora: runs-on: ubuntu-24.04 container: - image: fedora:40 + image: fedora:44 options: --privileged steps: - name: Install dependencies run: | dnf install -y openssl-devel python3-devel sqlite-devel dnf-plugins-core util-linux rust cargo skopeo - dnf config-manager --add-repo https://download.docker.com/linux/fedora/docker-ce.repo + dnf config-manager addrepo --from-repofile=https://download.docker.com/linux/fedora/docker-ce.repo dnf install -y docker-ce-cli - uses: actions/checkout@v4 - name: Run tests diff --git a/src/lib.rs b/src/lib.rs index 3338e20..4b31a98 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -158,21 +158,45 @@ pub fn main(command: Command) -> anyhow::Result<()> { }; if changed { - lockfile.write_to_file(lockfile_path)?; + lockfile.write_to_file(&lockfile_path)?; } - lockfile + match lockfile .build( &cfg, &image, &tag, vendor_dir.as_deref(), - label.into_iter().collect(), + label.clone().into_iter().collect(), ) .context( "If packages in the lock file are no longer available in the configured \ repositories, run `rpmoci update` to regenerate it", - )?; + ) { + Ok(()) => (), + Err(e) => { + // running unlocked with a compatible lockfile: packages may have been + // removed from the rolling repo, so attempt an auto-update and retry. + if lockfile.is_compatible_including_local_rpms(&cfg)? && !locked { + log::debug!( + "Build failed with a compatible lockfile, attempting auto-update and rebuild." + ); + let lockfile = Lockfile::resolve_from_config(&cfg)?; + lockfile.write_to_file(&lockfile_path)?; + lockfile.build( + &cfg, + &image, + &tag, + vendor_dir.as_deref(), + label.into_iter().collect(), + )?; + } else { + // locked or lockfile no longer matches config – bail with the + // hint already included in the error context. + bail!("Failed to build image: {e}."); + } + } + }; let elapsed_time = now.elapsed(); write::ok( "Success", diff --git a/tests/fixtures/ubi9/foo/oci-layout b/tests/fixtures/ubi9/foo/oci-layout new file mode 100644 index 0000000..1343d37 --- /dev/null +++ b/tests/fixtures/ubi9/foo/oci-layout @@ -0,0 +1 @@ +{"imageLayoutVersion":"1.0.0"} \ No newline at end of file diff --git a/tests/fixtures/ubi9/rpmoci.toml b/tests/fixtures/ubi9/rpmoci.toml new file mode 100644 index 0000000..64b46a8 --- /dev/null +++ b/tests/fixtures/ubi9/rpmoci.toml @@ -0,0 +1,10 @@ +[contents] +packages = ["glibc"] + +[[contents.repositories]] +url = "https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/$basearch/baseos/os" +id = "ubi9-test" +options = { gpgcheck = "false" } + +[image] +cmd = ["/bin/bash"] diff --git a/tests/it.rs b/tests/it.rs index ac0d1df..75d2191 100644 --- a/tests/it.rs +++ b/tests/it.rs @@ -385,6 +385,12 @@ fn test_exclude() { build_and_run("exclude", false); } +#[cfg(feature = "test-docker")] +#[test] +fn test_auto_update_missing_package() { + build_and_run("ubi9", true); +} + fn build_and_run(image: &str, should_succeed: bool) -> std::process::Output { let (_tmp_dir, root) = setup_test(image); let status = rpmoci()