Skip to content

Commit 1ba8d1e

Browse files
authored
Merge pull request bootc-dev#777 from omertuc/wipeos
cli: Add new `state wipe-ostree` subcommand
2 parents f668b80 + 16b194e commit 1ba8d1e

File tree

3 files changed

+48
-13
lines changed

3 files changed

+48
-13
lines changed

lib/src/cli.rs

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ use ostree_ext::keyfileext::KeyFileExt;
2121
use ostree_ext::ostree;
2222
use schemars::schema_for;
2323

24+
use crate::deploy::wipe_ostree;
2425
use crate::deploy::RequiredHostSpec;
2526
use crate::lints;
2627
use crate::spec::Host;
@@ -294,6 +295,12 @@ pub(crate) enum InternalsOpts {
294295
Cleanup,
295296
}
296297

298+
#[derive(Debug, clap::Subcommand, PartialEq, Eq)]
299+
pub(crate) enum StateOpts {
300+
/// Remove all ostree deployments from this system
301+
WipeOstree,
302+
}
303+
297304
impl InternalsOpts {
298305
/// The name of the binary we inject into /usr/lib/systemd/system-generators
299306
const GENERATOR_BIN: &'static str = "bootc-systemd-generator";
@@ -424,6 +431,10 @@ pub(crate) enum Opt {
424431
#[clap(trailing_var_arg = true, allow_hyphen_values = true)]
425432
args: Vec<OsString>,
426433
},
434+
/// Modify the state of the system
435+
#[clap(hide = true)]
436+
#[clap(subcommand)]
437+
State(StateOpts),
427438
#[clap(subcommand)]
428439
#[clap(hide = true)]
429440
Internals(InternalsOpts),
@@ -914,6 +925,14 @@ async fn run_from_opt(opt: Opt) -> Result<()> {
914925
},
915926
#[cfg(feature = "docgen")]
916927
Opt::Man(manopts) => crate::docgen::generate_manpages(&manopts.directory),
928+
Opt::State(opts) => match opts {
929+
StateOpts::WipeOstree => {
930+
let sysroot = ostree::Sysroot::new_default();
931+
sysroot.load(gio::Cancellable::NONE)?;
932+
wipe_ostree(&sysroot).await?;
933+
Ok(())
934+
}
935+
},
917936
}
918937
}
919938

lib/src/deploy.rs

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,8 +16,8 @@ use ostree_container::OstreeImageReference;
1616
use ostree_ext::container as ostree_container;
1717
use ostree_ext::container::store::{ImportProgress, PrepareResult};
1818
use ostree_ext::oci_spec::image::Descriptor;
19-
use ostree_ext::ostree;
2019
use ostree_ext::ostree::Deployment;
20+
use ostree_ext::ostree::{self, Sysroot};
2121
use ostree_ext::sysroot::SysrootLock;
2222

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

291+
pub(crate) async fn wipe_ostree(sysroot: &Sysroot) -> Result<()> {
292+
sysroot
293+
.write_deployments(&[], gio::Cancellable::NONE)
294+
.context("removing deployments")?;
295+
296+
Ok(())
297+
}
298+
291299
pub(crate) async fn cleanup(sysroot: &Storage) -> Result<()> {
292300
let bound_prune = prune_container_store(sysroot);
293301

tests-integration/src/install.rs

Lines changed: 20 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
1-
use std::path::Path;
2-
use std::{os::fd::AsRawFd, path::PathBuf};
1+
use std::{
2+
os::fd::AsRawFd,
3+
path::{Path, PathBuf},
4+
};
35

46
use anyhow::Result;
57
use camino::Utf8Path;
@@ -23,18 +25,24 @@ pub(crate) const BASE_ARGS: &[&str] = &[
2325
"label=disable",
2426
];
2527

26-
// Clear out and delete any ostree roots
27-
fn reset_root(sh: &Shell) -> Result<()> {
28-
// TODO fix https://github.com/containers/bootc/pull/137
29-
if !Path::new("/ostree/deploy/default").exists() {
28+
/// Clear out and delete any ostree roots, leverage bootc hidden wipe-ostree command to get rid of
29+
/// otherwise hard to delete deployment files
30+
fn reset_root(sh: &Shell, image: &str) -> Result<()> {
31+
if !Path::new("/ostree/deploy/").exists() {
3032
return Ok(());
3133
}
34+
35+
// Without /boot ostree will not delete anything
36+
let mounts = &["-v", "/ostree:/ostree", "-v", "/boot:/boot"];
37+
3238
cmd!(
3339
sh,
34-
"sudo /bin/sh -c 'chattr -i /ostree/deploy/default/deploy/*'"
40+
"sudo {BASE_ARGS...} {mounts...} {image} bootc state wipe-ostree"
3541
)
3642
.run()?;
37-
cmd!(sh, "sudo rm /ostree/deploy/default -rf").run()?;
43+
44+
// Now that the hard to delete files are gone, we can just rm -rf the rest
45+
cmd!(sh, "sudo /bin/sh -c 'rm -rf /ostree/deploy/*'").run()?;
3846
Ok(())
3947
}
4048

@@ -76,7 +84,7 @@ pub(crate) fn run_alongside(image: &str, mut testargs: libtest_mimic::Arguments)
7684
let tests = [
7785
Trial::test("loopback install", move || {
7886
let sh = &xshell::Shell::new()?;
79-
reset_root(sh)?;
87+
reset_root(sh, image)?;
8088
let size = 10 * 1000 * 1000 * 1000;
8189
let mut tmpdisk = tempfile::NamedTempFile::new_in("/var/tmp")?;
8290
tmpdisk.as_file_mut().set_len(size)?;
@@ -89,7 +97,7 @@ pub(crate) fn run_alongside(image: &str, mut testargs: libtest_mimic::Arguments)
8997
"replace=alongside with ssh keys and a karg, and SELinux disabled",
9098
move || {
9199
let sh = &xshell::Shell::new()?;
92-
reset_root(sh)?;
100+
reset_root(sh, image)?;
93101
let tmpd = &sh.create_temp_dir()?;
94102
let tmp_keys = tmpd.path().join("test_authorized_keys");
95103
let tmp_keys = tmp_keys.to_str().unwrap();
@@ -128,7 +136,7 @@ pub(crate) fn run_alongside(image: &str, mut testargs: libtest_mimic::Arguments)
128136
),
129137
Trial::test("Install and verify selinux state", move || {
130138
let sh = &xshell::Shell::new()?;
131-
reset_root(sh)?;
139+
reset_root(sh, image)?;
132140
cmd!(sh, "sudo {BASE_ARGS...} {target_args...} {image} bootc install to-existing-root --acknowledge-destructive {generic_inst_args...}").run()?;
133141
generic_post_install_verification()?;
134142
let root = &Dir::open_ambient_dir("/ostree", cap_std::ambient_authority()).unwrap();
@@ -138,7 +146,7 @@ pub(crate) fn run_alongside(image: &str, mut testargs: libtest_mimic::Arguments)
138146
}),
139147
Trial::test("without an install config", move || {
140148
let sh = &xshell::Shell::new()?;
141-
reset_root(sh)?;
149+
reset_root(sh, image)?;
142150
let empty = sh.create_temp_dir()?;
143151
let empty = empty.path().to_str().unwrap();
144152
cmd!(sh, "sudo {BASE_ARGS...} {target_args...} -v {empty}:/usr/lib/bootc/install {image} bootc install to-existing-root {generic_inst_args...}").run()?;

0 commit comments

Comments
 (0)