-
Notifications
You must be signed in to change notification settings - Fork 103
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
internals: Add new (experimental) bootc internals fsck
#1178
Open
cgwalters
wants to merge
1
commit into
bootc-dev:main
Choose a base branch
from
cgwalters:add-fsck
base: main
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
+155
−0
Open
Changes from all commits
Commits
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
# bootc internals fsck | ||
|
||
Experimental features are subject to change or removal. Please | ||
do provide feedback on them. | ||
|
||
## Using `bootc internals fsck` | ||
|
||
This command expects a booted system, and performs consistency checks | ||
in a read-only fashion. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,128 @@ | ||
//! # Write deployments merging image with configmap | ||
//! | ||
//! Create a merged filesystem tree with the image and mounted configmaps. | ||
|
||
// Unfortunately needed here to work with linkme | ||
#![allow(unsafe_code)] | ||
|
||
use std::process::Command; | ||
|
||
use cap_std_ext::cap_std; | ||
use cap_std_ext::cap_std::fs::{Dir, MetadataExt as _}; | ||
use cap_std_ext::dirext::CapStdExtDirExt; | ||
use linkme::distributed_slice; | ||
|
||
use crate::store::Storage; | ||
|
||
/// A lint check has failed. | ||
#[derive(thiserror::Error, Debug)] | ||
struct FsckError(String); | ||
|
||
/// The outer error is for unexpected fatal runtime problems; the | ||
/// inner error is for the check failing in an expected way. | ||
type FsckResult = anyhow::Result<std::result::Result<(), FsckError>>; | ||
|
||
/// Everything is OK - we didn't encounter a runtime error, and | ||
/// the targeted check passed. | ||
fn fsck_ok() -> FsckResult { | ||
Ok(Ok(())) | ||
} | ||
|
||
/// We successfully found a failure. | ||
fn fsck_err(msg: impl AsRef<str>) -> FsckResult { | ||
Ok(Err(FsckError::new(msg))) | ||
} | ||
|
||
impl std::fmt::Display for FsckError { | ||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { | ||
f.write_str(&self.0) | ||
} | ||
} | ||
|
||
impl FsckError { | ||
fn new(msg: impl AsRef<str>) -> Self { | ||
Self(msg.as_ref().to_owned()) | ||
} | ||
} | ||
|
||
#[derive(Debug)] | ||
struct FsckCheck { | ||
name: &'static str, | ||
ordering: u16, | ||
f: FsckFn, | ||
} | ||
|
||
type FsckFn = fn(&Storage) -> FsckResult; | ||
#[distributed_slice] | ||
pub(crate) static FSCK_CHECKS: [FsckCheck]; | ||
|
||
impl FsckCheck { | ||
pub(crate) const fn new(name: &'static str, ordering: u16, f: FsckFn) -> Self { | ||
FsckCheck { name, ordering, f } | ||
} | ||
} | ||
|
||
#[distributed_slice(FSCK_CHECKS)] | ||
static CHECK_RESOLVCONF: FsckCheck = FsckCheck::new("etc-resolvconf", 5, check_resolvconf); | ||
/// See https://github.com/containers/bootc/pull/1096 and https://github.com/containers/bootc/pull/1167 | ||
/// Basically verify that if /usr/etc/resolv.conf exists, it is not a zero-sized file that was | ||
/// probably injected by buildah and that bootc should have removed. | ||
/// | ||
/// Note that this fsck check can fail for systems upgraded from old bootc right now, as | ||
/// we need the *new* bootc to fix it. | ||
/// | ||
/// But at the current time fsck is an experimental feature that we should only be running | ||
/// in our CI. | ||
fn check_resolvconf(storage: &Storage) -> FsckResult { | ||
// For now we only check the booted deployment. | ||
if storage.booted_deployment().is_none() { | ||
return fsck_ok(); | ||
} | ||
// Read usr/etc/resolv.conf directly. | ||
let usr = Dir::open_ambient_dir("/usr", cap_std::ambient_authority())?; | ||
let Some(meta) = usr.symlink_metadata_optional("etc/resolv.conf")? else { | ||
return fsck_ok(); | ||
}; | ||
if meta.is_file() && meta.size() == 0 { | ||
return fsck_err("Found usr/etc/resolv.conf as zero-sized file"); | ||
} | ||
fsck_ok() | ||
} | ||
|
||
pub(crate) fn fsck(storage: &Storage, mut output: impl std::io::Write) -> anyhow::Result<()> { | ||
let mut checks = FSCK_CHECKS.static_slice().iter().collect::<Vec<_>>(); | ||
checks.sort_by(|a, b| a.ordering.cmp(&b.ordering)); | ||
|
||
let mut errors = false; | ||
for check in checks.iter() { | ||
let name = check.name; | ||
// SAFETY: Shouldn't fail to join a thread | ||
match (check.f)(&storage) { | ||
Ok(Ok(())) => {} | ||
Ok(Err(e)) => { | ||
errors = true; | ||
writeln!(output, "Failed check \"{name}\": {e}")?; | ||
} | ||
Err(e) => { | ||
errors = true; | ||
writeln!(output, "Unexpected runtime error in check \"{name}\": {e}")?; | ||
} | ||
} | ||
println!("ok: {name}"); | ||
} | ||
if errors { | ||
anyhow::bail!("Encountered errors") | ||
} | ||
|
||
// Run an `ostree fsck` (yes, ostree exposes enough APIs | ||
// that we could reimplement this in Rust, but eh) | ||
let st = Command::new("ostree") | ||
.arg("fsck") | ||
.stdin(std::process::Stdio::inherit()) | ||
.status()?; | ||
if !st.success() { | ||
anyhow::bail!("ostree fsck failed"); | ||
} | ||
|
||
Ok(()) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
use std assert | ||
use tap.nu | ||
|
||
tap begin "Run fsck" | ||
|
||
# That's it, just ensure we've run a fsck on our basic install. | ||
bootc internals fsck | ||
|
||
tap ok |
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
copy/paste header leftover from deploy.rs