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

cli: Add new state wipe-ostree subcommand #777

Merged
merged 1 commit into from
Sep 6, 2024
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
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<()> {
omertuc marked this conversation as resolved.
Show resolved Hide resolved
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
32 changes: 20 additions & 12 deletions tests-integration/src/install.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
use std::path::Path;
use std::{os::fd::AsRawFd, path::PathBuf};
use std::{
os::fd::AsRawFd,
path::{Path, PathBuf},
};

use anyhow::Result;
use camino::Utf8Path;
Expand All @@ -23,18 +25,24 @@ 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() {
/// 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<()> {
if !Path::new("/ostree/deploy/").exists() {
return Ok(());
}

// 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 +84,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 +97,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 +136,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 +146,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