Skip to content

Commit

Permalink
cli: Add new state wipe-ostree subcommand
Browse files Browse the repository at this point in the history
Solves containers#776

Right now the integration tests have some hacky code to clear out
`ostree` stateroots  (see `reset_root` function), it would be better if
they could rely on a bootc command to take care of that for them instead

This commit adds a new `state wipe-ostree` subcommand to the CLI that
removes all `ostree` deployments from the system using native ostree
bindings. This makes it easier to later rm -rf the stateroots and have a
clean slate for the next test.
  • Loading branch information
omertuc committed Sep 5, 2024
1 parent f668b80 commit d07af39
Show file tree
Hide file tree
Showing 3 changed files with 42 additions and 14 deletions.
19 changes: 19 additions & 0 deletions lib/src/cli.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ use ostree_ext::keyfileext::KeyFileExt;
use ostree_ext::ostree;
use schemars::schema_for;

use crate::deploy::wipe_ostree;
use crate::deploy::RequiredHostSpec;
use crate::lints;
use crate::spec::Host;
Expand Down Expand Up @@ -294,6 +295,12 @@ pub(crate) enum InternalsOpts {
Cleanup,
}

#[derive(Debug, clap::Subcommand, PartialEq, Eq)]
pub(crate) enum StateOpts {
/// Remove all ostree deployments from this system
WipeOstree,
}

impl InternalsOpts {
/// The name of the binary we inject into /usr/lib/systemd/system-generators
const GENERATOR_BIN: &'static str = "bootc-systemd-generator";
Expand Down Expand Up @@ -424,6 +431,10 @@ pub(crate) enum Opt {
#[clap(trailing_var_arg = true, allow_hyphen_values = true)]
args: Vec<OsString>,
},
/// Modify the state of the system
#[clap(hide = true)]
#[clap(subcommand)]
State(StateOpts),
#[clap(subcommand)]
#[clap(hide = true)]
Internals(InternalsOpts),
Expand Down Expand Up @@ -914,6 +925,14 @@ async fn run_from_opt(opt: Opt) -> Result<()> {
},
#[cfg(feature = "docgen")]
Opt::Man(manopts) => crate::docgen::generate_manpages(&manopts.directory),
Opt::State(opts) => match opts {
StateOpts::WipeOstree => {
let sysroot = ostree::Sysroot::new_default();
sysroot.load(gio::Cancellable::NONE)?;
wipe_ostree(&sysroot).await?;
Ok(())
}
},
}
}

Expand Down
10 changes: 9 additions & 1 deletion lib/src/deploy.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,8 @@ use ostree_container::OstreeImageReference;
use ostree_ext::container as ostree_container;
use ostree_ext::container::store::{ImportProgress, PrepareResult};
use ostree_ext::oci_spec::image::Descriptor;
use ostree_ext::ostree;
use ostree_ext::ostree::Deployment;
use ostree_ext::ostree::{self, Sysroot};
use ostree_ext::sysroot::SysrootLock;

use crate::spec::ImageReference;
Expand Down Expand Up @@ -288,6 +288,14 @@ pub(crate) async fn prune_container_store(sysroot: &Storage) -> Result<()> {
Ok(())
}

pub(crate) async fn wipe_ostree(sysroot: &Sysroot) -> Result<()> {
sysroot
.write_deployments(&[], gio::Cancellable::NONE)
.context("removing deployments")?;

Ok(())
}

pub(crate) async fn cleanup(sysroot: &Storage) -> Result<()> {
let bound_prune = prune_container_store(sysroot);

Expand Down
27 changes: 14 additions & 13 deletions tests-integration/src/install.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
use std::path::Path;
use std::{os::fd::AsRawFd, path::PathBuf};

use anyhow::Result;
Expand All @@ -23,18 +22,20 @@ pub(crate) const BASE_ARGS: &[&str] = &[
"label=disable",
];

// Clear out and delete any ostree roots
fn reset_root(sh: &Shell) -> Result<()> {
// TODO fix https://github.com/containers/bootc/pull/137
if !Path::new("/ostree/deploy/default").exists() {
return Ok(());
}
/// Clear out and delete any ostree roots, leverage bootc hidden wipe-ostree command to get rid of
/// otherwise hard to delete deployment files
fn reset_root(sh: &Shell, image: &str) -> Result<()> {
// Without /boot ostree will not delete anything
let mounts = &["-v", "/ostree:/ostree", "-v", "/boot:/boot"];

cmd!(
sh,
"sudo /bin/sh -c 'chattr -i /ostree/deploy/default/deploy/*'"
"sudo {BASE_ARGS...} {mounts...} {image} bootc state wipe-ostree"
)
.run()?;
cmd!(sh, "sudo rm /ostree/deploy/default -rf").run()?;

// Now that the hard to delete files are gone, we can just rm -rf the rest
cmd!(sh, "sudo /bin/sh -c 'rm -rf /ostree/deploy/*'").run()?;
Ok(())
}

Expand Down Expand Up @@ -76,7 +77,7 @@ pub(crate) fn run_alongside(image: &str, mut testargs: libtest_mimic::Arguments)
let tests = [
Trial::test("loopback install", move || {
let sh = &xshell::Shell::new()?;
reset_root(sh)?;
reset_root(sh, image)?;
let size = 10 * 1000 * 1000 * 1000;
let mut tmpdisk = tempfile::NamedTempFile::new_in("/var/tmp")?;
tmpdisk.as_file_mut().set_len(size)?;
Expand All @@ -89,7 +90,7 @@ pub(crate) fn run_alongside(image: &str, mut testargs: libtest_mimic::Arguments)
"replace=alongside with ssh keys and a karg, and SELinux disabled",
move || {
let sh = &xshell::Shell::new()?;
reset_root(sh)?;
reset_root(sh, image)?;
let tmpd = &sh.create_temp_dir()?;
let tmp_keys = tmpd.path().join("test_authorized_keys");
let tmp_keys = tmp_keys.to_str().unwrap();
Expand Down Expand Up @@ -128,7 +129,7 @@ pub(crate) fn run_alongside(image: &str, mut testargs: libtest_mimic::Arguments)
),
Trial::test("Install and verify selinux state", move || {
let sh = &xshell::Shell::new()?;
reset_root(sh)?;
reset_root(sh, image)?;
cmd!(sh, "sudo {BASE_ARGS...} {target_args...} {image} bootc install to-existing-root --acknowledge-destructive {generic_inst_args...}").run()?;
generic_post_install_verification()?;
let root = &Dir::open_ambient_dir("/ostree", cap_std::ambient_authority()).unwrap();
Expand All @@ -138,7 +139,7 @@ pub(crate) fn run_alongside(image: &str, mut testargs: libtest_mimic::Arguments)
}),
Trial::test("without an install config", move || {
let sh = &xshell::Shell::new()?;
reset_root(sh)?;
reset_root(sh, image)?;
let empty = sh.create_temp_dir()?;
let empty = empty.path().to_str().unwrap();
cmd!(sh, "sudo {BASE_ARGS...} {target_args...} -v {empty}:/usr/lib/bootc/install {image} bootc install to-existing-root {generic_inst_args...}").run()?;
Expand Down

0 comments on commit d07af39

Please sign in to comment.