Skip to content

Commit

Permalink
WIP-cli:expand lint to check if /var/run exists
Browse files Browse the repository at this point in the history
Broken lint just started framing

Co-authored-by: Joseph Marrero <[email protected]>
Co-authored-by: Huijing Hei <[email protected]>
Co-authored-by: Luke Yang <[email protected]>

Signed-off-by: Steven Presti <[email protected]>
  • Loading branch information
prestist committed May 30, 2024
1 parent 181411f commit 156150d
Show file tree
Hide file tree
Showing 2 changed files with 57 additions and 52 deletions.
73 changes: 56 additions & 17 deletions lib/src/cli.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ use anyhow::{Context, Result};
use camino::Utf8PathBuf;
use cap_std_ext::cap_std;
use cap_std_ext::cap_std::fs::Dir;
use cap_std_ext::dirext::CapStdExtDirExt;
use clap::Parser;
use fn_error_context::context;
use ostree::gio;
Expand Down Expand Up @@ -143,6 +144,12 @@ pub(crate) struct ManOpts {
pub(crate) directory: Utf8PathBuf,
}

#[derive(Debug, clap::Subcommand, PartialEq, Eq)]
pub(crate) enum ContainerOpts {
/// Lint the container
Lint,
}

/// Hidden, internal only options
#[derive(Debug, clap::Subcommand, PartialEq, Eq)]
pub(crate) enum InternalsOpts {
Expand All @@ -169,7 +176,9 @@ pub(crate) enum TestingOpts {
/// Execute integration tests that target a not-privileged ostree container
RunContainerIntegration {},
/// Block device setup for testing
PrepTestInstallFilesystem { blockdev: Utf8PathBuf },
PrepTestInstallFilesystem {
blockdev: Utf8PathBuf,
},
/// e2e test of install to-filesystem
TestInstallFilesystem {
image: String,
Expand Down Expand Up @@ -297,7 +306,10 @@ pub(crate) enum Opt {
#[cfg(feature = "install")]
Install(InstallOpts),
/// Validate non supported files are not present.
BuildLint,
/// make a subcommand like install called container
/// and add a lint subcommand to it.
#[clap(subcommand)]
Container(ContainerOpts),
/// Execute the given command in the host mount namespace
#[cfg(feature = "install")]
#[clap(hide = true)]
Expand Down Expand Up @@ -616,20 +628,36 @@ async fn usroverlay() -> Result<()> {
.into());
}

/// Implementation of `bootc build commit`
/// async fn lint() -> Result<()> {
/// 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.
#[context("linting")]
fn lint() -> Result<()> {
if !ostree_ext::container_utils::is_ostree_container()? {
anyhow::bail!(
"Not in a ostree container, this command only verifies ostree containers."
);
anyhow::bail!("Not in a ostree container, this command only verifies ostree containers.");
}

let lints = [check_var_run, check_kernel];
let root = cap_std::fs::Dir::open_ambient_dir("/", cap_std::ambient_authority())?;
let result = ostree_ext::bootabletree::find_kernel_dir_fs(&root)?;
tracing::debug!("Found kernel: {:?}", result);
return Ok(());
for lint in lints {
lint(&root)?;
}
Ok(())
}

fn check_var_run(root: &Dir) -> Result<()> {
if let Some(meta) = root.symlink_metadata_optional("var/run")? {
if !meta.is_symlink() {
anyhow::bail!("Not a symlink: var/run");
}
}
Ok(())
}

fn check_kernel(root: &Dir) -> Result<()> {
ostree_ext::bootabletree::find_kernel_dir_fs(&root)?;
Ok(())
}

/// Parse the provided arguments and execute.
Expand Down Expand Up @@ -678,7 +706,12 @@ async fn run_from_opt(opt: Opt) -> Result<()> {
Opt::Rollback(opts) => rollback(opts).await,
Opt::Edit(opts) => edit(opts).await,
Opt::UsrOverlay => usroverlay().await,
Opt::BuildLint => lint(),
Opt::Container(opts) => match opts{
ContainerOpts::Lint => {
lint()?;
Ok(())
}
},
#[cfg(feature = "install")]
Opt::Install(opts) => match opts {
InstallOpts::ToDisk(opts) => crate::install::install_to_disk(opts).await,
Expand Down Expand Up @@ -760,14 +793,20 @@ fn test_linting() {
match ostree_ext::container_utils::is_ostree_container() {
Ok(result) => {
if !result {
let expected_error_message = "Not in a ostree container, this command only verifies ostree containers.";
let expected_error_message =
"Not in a ostree container, this command only verifies ostree containers.";
let expected_context = "linting";

let result = lint();
assert_eq!(result.err().unwrap().to_string(), expected_error_message, "Error message mismatch");
}
let error_chain = vec![expected_context.to_string(), expected_error_message.to_string()];
assert_eq!(error_chain.len(), 2, "Expected two errors in chain");

},
Err(_) =>{
let context = error_chain[0].to_string();
let error_message = error_chain[1].to_string();

assert_eq!(context, expected_context, "Context mismatch");
assert_eq!(error_message, expected_error_message, "Error message mismatch");
}
}
Err(_) => {}
}
}
}
36 changes: 1 addition & 35 deletions lib/src/privtests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ use cap_std_ext::cap_std::fs::Dir;
use fn_error_context::context;
use rustix::fd::AsFd;
use xshell::{cmd, Shell};

use crate::blockdev::LoopbackDevice;
use crate::install::config::InstallConfiguration;

Expand Down Expand Up @@ -195,37 +196,6 @@ fn verify_selinux_recurse(root: &Dir, path: &mut PathBuf, warn: bool) -> Result<
Ok(())
}

#[context("Container tests")]
fn test_build_lint(image: &str) -> Result<()> {

let sh = Shell::new()?;

// Smoke test of build_lint
let _test_1_result = cmd!(sh, "podman run --rm --privileged --pid=host --env=RUST_LOG -v /usr/bin/bootc:/usr/bin/bootc {image} bootc build-lint").run();

// Setup for multiple kernels lint test
cmd!(sh, "podman run -dt --name test --privileged --pid=host --env=RUST_LOG -v /usr/bin/bootc:/usr/bin/bootc {image} bash").run()?;
let kernel_name = cmd!(sh, "podman exec test bash -c 'ls /usr/lib/modules | tail -n -1'" ).read()?;
Command::new("podman")
.arg("exec")
.arg("test")
.arg("bash")
.arg("-c")
.arg(format!("sudo cp -r /usr/lib/modules/{} /usr/lib/modules/delete-me", kernel_name))
.output()?;
let more_then_one_kernel_result = cmd!(sh, "podman exec test bash -c 'bootc build-lint'").read_stderr();
// Container Cleanup
cmd!(sh, "podman rm -f test").run()?;

_test_1_result?;
if let Err(e) = more_then_one_kernel_result {
assert!(e.to_string().contains("bootc build-lint"));
} else {
assert!(false, "Expected error, got none");
}
Ok(())
}

pub(crate) async fn run(opts: TestingOpts) -> Result<()> {
match opts {
TestingOpts::RunPrivilegedIntegration {} => {
Expand All @@ -251,9 +221,5 @@ pub(crate) async fn run(opts: TestingOpts) -> Result<()> {
tokio::task::spawn_blocking(move || verify_selinux_recurse(&rootfs, &mut path, warn))
.await?
}
TestingOpts::TestBuildLint { image } => {
tokio::task::spawn_blocking(move || test_build_lint(&image)).await?
}

}
}

0 comments on commit 156150d

Please sign in to comment.