Skip to content

Commit

Permalink
Merge pull request #1067 from cgwalters/lint-list
Browse files Browse the repository at this point in the history
lints: Add description and `--list`
  • Loading branch information
jmarrero authored Jan 31, 2025
2 parents 29f9ecb + 1433aa4 commit 455e168
Show file tree
Hide file tree
Showing 8 changed files with 81 additions and 27 deletions.
14 changes: 13 additions & 1 deletion docs/src/man/bootc-container-lint.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,8 @@ checks as part of a container build

# SYNOPSIS

**bootc container lint** \[**\--rootfs**\] \[**-h**\|**\--help**\]
**bootc container lint** \[**\--rootfs**\] \[**\--fatal-warnings**\]
\[**\--list**\] \[**-h**\|**\--help**\]

# DESCRIPTION

Expand All @@ -21,6 +22,17 @@ part of a build process; it will error if any problems are detected.

: Operate on the provided rootfs

**\--fatal-warnings**

: Make warnings fatal

**\--list**

: Instead of executing the lints, just print all available lints. At
the current time, this will output in YAML format because its
reasonably human friendly. However, there is no commitment to
maintaining this exact format; do not parse it via code or scripts

**-h**, **\--help**

: Print help (see a summary with -h)
Expand Down
8 changes: 2 additions & 6 deletions docs/src/man/bootc-install-to-disk.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,8 @@ bootc-install-to-disk - Install to the target block device
**bootc install to-disk** \[**\--wipe**\] \[**\--block-setup**\]
\[**\--filesystem**\] \[**\--root-size**\] \[**\--source-imgref**\]
\[**\--target-transport**\] \[**\--target-imgref**\]
\[**\--enforce-container-sigpolicy**\] \[**\--target-ostree-remote**\]
\[**\--skip-fetch-check**\] \[**\--disable-selinux**\] \[**\--karg**\]
\[**\--enforce-container-sigpolicy**\] \[**\--skip-fetch-check**\]
\[**\--disable-selinux**\] \[**\--karg**\]
\[**\--root-ssh-authorized-keys**\] \[**\--generic-image**\]
\[**\--bound-images**\] \[**\--stateroot**\] \[**\--via-loopback**\]
\[**-h**\|**\--help**\] \<*DEVICE*\>
Expand Down Expand Up @@ -83,10 +83,6 @@ more complex such as RAID, LVM, LUKS etc.
Enabling this option enforces that \`/etc/containers/policy.json\`
includes a default policy which requires signatures

**\--target-ostree-remote**=*TARGET_OSTREE_REMOTE*

: Enable verification via an ostree remote

**\--skip-fetch-check**

: By default, the accessiblity of the target image will be verified
Expand Down
7 changes: 1 addition & 6 deletions docs/src/man/bootc-install-to-existing-root.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,7 @@ bootc-install-to-existing-root - Install to the host root filesystem
**bootc install to-existing-root** \[**\--replace**\]
\[**\--source-imgref**\] \[**\--target-transport**\]
\[**\--target-imgref**\] \[**\--enforce-container-sigpolicy**\]
\[**\--target-ostree-remote**\] \[**\--skip-fetch-check**\]
\[**\--disable-selinux**\] \[**\--karg**\]
\[**\--skip-fetch-check**\] \[**\--disable-selinux**\] \[**\--karg**\]
\[**\--root-ssh-authorized-keys**\] \[**\--generic-image**\]
\[**\--bound-images**\] \[**\--stateroot**\]
\[**\--acknowledge-destructive**\] \[**-h**\|**\--help**\]
Expand Down Expand Up @@ -69,10 +68,6 @@ cleaned up if desired when rebooted into the new root.
Enabling this option enforces that \`/etc/containers/policy.json\`
includes a default policy which requires signatures

**\--target-ostree-remote**=*TARGET_OSTREE_REMOTE*

: Enable verification via an ostree remote

**\--skip-fetch-check**

: By default, the accessiblity of the target image will be verified
Expand Down
7 changes: 1 addition & 6 deletions docs/src/man/bootc-install-to-filesystem.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,7 @@ filesystem structure
\[**\--acknowledge-destructive**\] \[**\--skip-finalize**\]
\[**\--source-imgref**\] \[**\--target-transport**\]
\[**\--target-imgref**\] \[**\--enforce-container-sigpolicy**\]
\[**\--target-ostree-remote**\] \[**\--skip-fetch-check**\]
\[**\--disable-selinux**\] \[**\--karg**\]
\[**\--skip-fetch-check**\] \[**\--disable-selinux**\] \[**\--karg**\]
\[**\--root-ssh-authorized-keys**\] \[**\--generic-image**\]
\[**\--bound-images**\] \[**\--stateroot**\] \[**-h**\|**\--help**\]
\<*ROOT_PATH*\>
Expand Down Expand Up @@ -98,10 +97,6 @@ is currently expected to be empty by default.
Enabling this option enforces that \`/etc/containers/policy.json\`
includes a default policy which requires signatures

**\--target-ostree-remote**=*TARGET_OSTREE_REMOTE*

: Enable verification via an ostree remote

**\--skip-fetch-check**

: By default, the accessiblity of the target image will be verified
Expand Down
8 changes: 2 additions & 6 deletions docs/src/man/bootc-switch.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,8 @@ bootc-switch - Target a new container image reference to boot
# SYNOPSIS

**bootc switch** \[**\--quiet**\] \[**\--apply**\] \[**\--transport**\]
\[**\--enforce-container-sigpolicy**\] \[**\--ostree-remote**\]
\[**\--retain**\] \[**-h**\|**\--help**\] \<*TARGET*\>
\[**\--enforce-container-sigpolicy**\] \[**\--retain**\]
\[**-h**\|**\--help**\] \<*TARGET*\>

# DESCRIPTION

Expand Down Expand Up @@ -51,10 +51,6 @@ updates via container image tags; for example,
Enabling this option enforces that \`/etc/containers/policy.json\`
includes a default policy which requires signatures.

**\--ostree-remote**=*OSTREE_REMOTE*

: Enable verification via an ostree remote

**\--retain**

: Retain reference to currently booted image
Expand Down
2 changes: 1 addition & 1 deletion lib/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ cap-std-ext = { workspace = true, features = ["fs_utf8"] }
hex = { workspace = true }
fn-error-context = { workspace = true }
indicatif = { workspace = true }
indoc = { workspace = true }
libc = { workspace = true }
liboverdrop = "0.1.0"
libsystemd = "0.7"
Expand All @@ -50,7 +51,6 @@ comfy-table = "7.1.1"
thiserror = "2.0.11"

[dev-dependencies]
indoc = { workspace = true }
similar-asserts = { workspace = true }
static_assertions = { workspace = true }

Expand Down
11 changes: 11 additions & 0 deletions lib/src/cli.rs
Original file line number Diff line number Diff line change
Expand Up @@ -249,6 +249,13 @@ pub(crate) enum ContainerOpts {
/// Make warnings fatal.
#[clap(long)]
fatal_warnings: bool,

/// Instead of executing the lints, just print all available lints.
/// At the current time, this will output in YAML format because it's
/// reasonably human friendly. However, there is no commitment to
/// maintaining this exact format; do not parse it via code or scripts.
#[clap(long)]
list: bool,
},
}

Expand Down Expand Up @@ -1018,7 +1025,11 @@ async fn run_from_opt(opt: Opt) -> Result<()> {
ContainerOpts::Lint {
rootfs,
fatal_warnings,
list,
} => {
if list {
return lints::lint_list(std::io::stdout().lock());
}
if !ostree_ext::container_utils::is_ostree_container()? {
anyhow::bail!(
"Not in a ostree container, this command only verifies ostree containers."
Expand Down
51 changes: 50 additions & 1 deletion lib/src/lints.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@ use cap_std_ext::cap_std;
use cap_std_ext::cap_std::fs::MetadataExt;
use cap_std_ext::dirext::CapStdExtDirExt as _;
use fn_error_context::context;
use indoc::indoc;
use serde::Serialize;

/// Reference to embedded default baseimage content that should exist.
const BASEIMAGE_REF: &str = "usr/share/doc/bootc/baseimage/base";
Expand Down Expand Up @@ -51,7 +53,8 @@ impl LintError {
type LintFn = fn(&Dir) -> LintResult;

/// The classification of a lint type.
#[derive(Debug)]
#[derive(Debug, Serialize)]
#[serde(rename_all = "kebab-case")]
enum LintType {
/// If this fails, it is known to be fatal - the system will not install or
/// is effectively guaranteed to fail at runtime.
Expand All @@ -60,51 +63,89 @@ enum LintType {
Warning,
}

#[derive(Debug, Serialize)]
#[serde(rename_all = "kebab-case")]
struct Lint {
name: &'static str,
#[serde(rename = "type")]
ty: LintType,
#[serde(skip)]
f: LintFn,
description: &'static str,
}

const LINTS: &[Lint] = &[
Lint {
name: "var-run",
ty: LintType::Fatal,
f: check_var_run,
description: "Check for /var/run being a physical directory; this is always a bug.",
},
Lint {
name: "kernel",
ty: LintType::Fatal,
f: check_kernel,
description: indoc! { r#"
Check for multiple kernels, i.e. multiple directories of the form /usr/lib/modules/$kver.
Only one kernel is supported in an image.
"# },
},
Lint {
name: "bootc-kargs",
ty: LintType::Fatal,
f: check_parse_kargs,
description: "Verify syntax of /usr/lib/bootc/kargs.d.",
},
Lint {
name: "etc-usretc",
ty: LintType::Fatal,
f: check_usretc,
description: indoc! { r#"
Verify that only one of /etc or /usr/etc exist. You should only have /etc
in a container image. It will cause undefined behavior to have both /etc
and /usr/etc.
"#},
},
Lint {
// This one can be lifted in the future, see https://github.com/containers/bootc/issues/975
name: "utf8",
ty: LintType::Fatal,
f: check_utf8,
description: indoc! { r#"
Check for non-UTF8 filenames. Currently, the ostree backend of bootc only supports
UTF-8 filenames. Non-UTF8 filenames will cause a fatal error.
"#},
},
Lint {
name: "baseimage-root",
ty: LintType::Fatal,
f: check_baseimage_root,
description: indoc! { r#"
Check that expected files are present in the root of the filesystem; such
as /sysroot and a composefs configuration for ostree. More in
<https://containers.github.io/bootc/bootc-images.html#standard-image-content>.
"#},
},
Lint {
name: "var-log",
ty: LintType::Warning,
f: check_varlog,
description: indoc! { r#"
Check for non-empty regular files in `/var/log`. It is often undesired
to ship log files in container images. Log files in general are usually
per-machine state in `/var`. Additionally, log files often include
timestamps, causing unreproducible container images, and may contain
sensitive build system information.
"#},
},
];

pub(crate) fn lint_list(output: impl std::io::Write) -> Result<()> {
// Dump in yaml format by default, it's readable enough
serde_yaml::to_writer(output, LINTS)?;
Ok(())
}

/// check for the existence of the /var/run directory
/// if it exists we need to check that it links to /run if not error
/// if it does not exist error.
Expand Down Expand Up @@ -522,4 +563,12 @@ mod tests {
check_baseimage_root(&td).unwrap().unwrap();
Ok(())
}

#[test]
fn test_list() {
let mut r = Vec::new();
lint_list(&mut r).unwrap();
let lints: Vec<serde_yaml::Value> = serde_yaml::from_slice(&r).unwrap();
assert_eq!(lints.len(), LINTS.len());
}
}

0 comments on commit 455e168

Please sign in to comment.