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

store: Really remove empty /etc/resolv.conf and /etc/hostname #1167

Merged
merged 1 commit into from
Mar 5, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
32 changes: 17 additions & 15 deletions ostree-ext/src/container/store.rs
Original file line number Diff line number Diff line change
Expand Up @@ -466,7 +466,7 @@ fn timestamp_of_manifest_or_config(
/// Automatically clean up files that may have been injected by container
/// builds. xref https://github.com/containers/buildah/issues/4242
fn cleanup_root(root: &Dir) -> Result<()> {
const RUNTIME_INJECTED: &[&str] = &["etc/hostname", "etc/resolv.conf"];
const RUNTIME_INJECTED: &[&str] = &["usr/etc/hostname", "usr/etc/resolv.conf"];
for ent in RUNTIME_INJECTED {
if let Some(meta) = root.symlink_metadata_optional(ent)? {
if meta.is_file() && meta.size() == 0 {
Expand Down Expand Up @@ -1055,15 +1055,16 @@ impl ImageImporter {
.with_context(|| format!("Checking out layer {commit}"))?;
}

let root_dir = td.open_dir(rootpath)?;

let modifier =
ostree::RepoCommitModifier::new(ostree::RepoCommitModifierFlags::CONSUME, None);
modifier.set_devino_cache(&devino);
// If we have derived layers, then we need to handle the case where
// the derived layers include custom policy. Just relabel everything
// in this case.
if have_derived_layers {
let rootpath = td.open_dir(rootpath)?;
let sepolicy = ostree::SePolicy::new_at(rootpath.as_raw_fd(), cancellable)?;
let sepolicy = ostree::SePolicy::new_at(root_dir.as_raw_fd(), cancellable)?;
tracing::debug!("labeling from merged tree");
modifier.set_sepolicy(Some(&sepolicy));
} else if let Some(base) = base_commit.as_ref() {
Expand All @@ -1074,7 +1075,7 @@ impl ImageImporter {
unreachable!()
}

cleanup_root(&td)?;
cleanup_root(&root_dir)?;

let mt = ostree::MutableTree::new();
repo.write_dfd_to_mtree(
Expand Down Expand Up @@ -1965,23 +1966,24 @@ mod tests {
#[test]
fn test_cleanup_root() -> Result<()> {
let td = cap_tempfile::TempDir::new(cap_std::ambient_authority())?;

let usretc = "usr/etc";
cleanup_root(&td).unwrap();
td.create_dir("etc")?;
td.write("etc/hostname", b"hostname")?;
td.create_dir_all(usretc)?;
let usretc = &td.open_dir(usretc)?;
usretc.write("hostname", b"hostname")?;
cleanup_root(&td).unwrap();
assert!(td.try_exists("etc/hostname")?);
td.write("etc/hostname", b"")?;
assert!(usretc.try_exists("hostname")?);
usretc.write("hostname", b"")?;
cleanup_root(&td).unwrap();
assert!(!td.try_exists("etc/hostname")?);
assert!(!td.try_exists("hostname")?);

td.symlink_contents("../run/systemd/stub-resolv.conf", "etc/resolv.conf")?;
usretc.symlink_contents("../run/systemd/stub-resolv.conf", "resolv.conf")?;
cleanup_root(&td).unwrap();
assert!(td.symlink_metadata("etc/resolv.conf")?.is_symlink());
td.remove_file("etc/resolv.conf")?;
td.write("etc/resolv.conf", b"")?;
assert!(usretc.symlink_metadata("resolv.conf")?.is_symlink());
usretc.remove_file("resolv.conf")?;
usretc.write("resolv.conf", b"")?;
cleanup_root(&td).unwrap();
assert!(!td.try_exists("etc/resolv.conf")?);
assert!(!usretc.try_exists("resolv.conf")?);

Ok(())
}
Expand Down
23 changes: 23 additions & 0 deletions tests/booted/readonly/011-test-resolvconf.nu
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
use std assert
use tap.nu

tap begin "verify there's not an empty /etc/resolv.conf in the image"

let st = bootc status --json | from json

let booted_ostree = $st.status.booted.ostree.checksum;

# ostree ls should probably have --json and a clean way to not error on ENOENT
let resolvconf = ostree ls $booted_ostree /usr/etc | split row (char newline) | find resolv.conf
if ($resolvconf | length) > 0 {
let parts = $resolvconf | first | split row -r '\s+'
let ty = $parts | first | split chars | first
# If resolv.conf exists in the image, currently require it in our
# test suite to be a symlink (which is hopefully to the systemd/stub-resolv.conf)
assert equal $ty 'l'
print "resolv.conf is a symlink"
} else {
print "No resolv.conf found in commit"
}

tap ok