Skip to content

Commit

Permalink
download correct arch packages (#173)
Browse files Browse the repository at this point in the history
for repos that use $basearch, we may download the package of the wrong architecture.
fix by selecting the package with correct checksum, rather than the first with the correct name/evr
  • Loading branch information
tofay authored Nov 21, 2024
1 parent 2cb19ea commit 7e1685c
Show file tree
Hide file tree
Showing 5 changed files with 57 additions and 11 deletions.
5 changes: 3 additions & 2 deletions Cargo.lock

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

1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ xattr = "1.0.1"
ocidir = "0.3.1"

[dev-dependencies]
libc = "0.2.164"
test-temp-dir = "0.3.0"
testcontainers = { version = "0.23.1", features = ["blocking"] }
testcontainers-modules = { version = "0.11.2", features = [
Expand Down
5 changes: 5 additions & 0 deletions src/lockfile/download.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
"""RPM downloader module."""

# Copyright (C) Microsoft Corporation.
#
# This program is free software: you can redistribute it and/or modify
Expand Down Expand Up @@ -37,6 +38,10 @@ def download(base, packages, directory):
def get_package(base, name, evr, checksum):
"""Find packages matching given spec."""
pkgs = base.sack.query().filter(name=name, evr=evr).run()
# Filter by checksum manually as hawkey does not support it
# This also ensures that we get the package for the correct arch
# in case $basearch is used in the URL.
pkgs = [p for p in pkgs if p.chksum and p.chksum[1].hex() == checksum]

if not pkgs:
msg = (
Expand Down
7 changes: 7 additions & 0 deletions tests/fixtures/basearch/rpmoci.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
[contents]
packages = ["basesystem"]

[[contents.repositories]]
url = "https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/$basearch/baseos/os"
id = "ubi"
options = { gpgcheck = "false" }
50 changes: 41 additions & 9 deletions tests/it.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,12 +16,18 @@ use testcontainers_modules::cncf_distribution::CncfDistribution;
const EXE: &str = env!("CARGO_BIN_EXE_rpmoci");

fn rpmoci() -> Command {
// if running as root
let mut cmd = Command::new("unshare");
// Don't use --map-auto here as that doesn't work on Azure Linux 2.0's unshare
// This will cause failures if tests install RPMs which create users
cmd.arg("--map-root-user").arg("--user").arg(EXE);
cmd
// if running as root, don't unshare
let is_root = unsafe { libc::geteuid() == 0 };
if is_root {
Command::new(EXE)
} else {
// Run in user namespace
let mut cmd = Command::new("unshare");
// Don't use --map-auto here as that doesn't work on Azure Linux 2.0's unshare
// This will cause failures if tests install RPMs which create users
cmd.arg("--map-root-user").arg("--user").arg(EXE);
cmd
}
}

fn setup_test(fixture: &str) -> (TestTempDir, PathBuf) {
Expand Down Expand Up @@ -250,20 +256,46 @@ fn test_explicit_etc_os_release() {
let output = rpmoci().arg("update").current_dir(&root).output().unwrap();
let stderr = std::str::from_utf8(&output.stderr).unwrap();
eprintln!("stderr: {}. {}. {}", stderr, root.display(), EXE);
assert!(output.status.success());
// Open the lockfile and verify /etc/os-release was added as a dependency
let lockfile_path = root.join("rpmoci.lock");
eprintln!("lockfile_path: {}", lockfile_path.display());
let lockfile: Lockfile = toml::from_str(&fs::read_to_string(lockfile_path).unwrap()).unwrap();
assert_eq!(
lockfile
.iter_packages()
.filter(|p| p.name == "mariner-release")
.count(),
1
);
}

#[test]
fn test_weak_deps() {
// Verify a build without weak dependencies succeeds
let (_tmp_dir, root) = setup_test("weakdeps");
let output = rpmoci()
let status = rpmoci()
.arg("build")
.arg("--image=weak")
.arg("--tag=deps")
.current_dir(&root)
.output()
.status()
.unwrap();
assert!(output.status.success());
assert!(status.success());
}

#[test]
fn test_base_arch() {
// Verify a build using a repo with a $basearch variable in the URL succeeds
let (_tmp_dir, root) = setup_test("basearch");
let status = rpmoci()
.arg("build")
.arg("--image=base")
.arg("--tag=arch")
.current_dir(&root)
.status()
.unwrap();
assert!(status.success());
}

#[cfg(feature = "test-docker")]
Expand Down

0 comments on commit 7e1685c

Please sign in to comment.