Skip to content

Commit fd3b99a

Browse files
cli: Add option to current vs default /etc
Signed-off-by: Pragyan Poudyal <[email protected]>
1 parent dcc5db5 commit fd3b99a

File tree

3 files changed

+61
-16
lines changed

3 files changed

+61
-16
lines changed

crates/etc-merge/src/lib.rs

Lines changed: 21 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -305,16 +305,16 @@ fn get_modifications(
305305
/// [`anyhow::Result`] containing a tuple of directory trees in the order:
306306
///
307307
/// 1. `pristine_etc_files` – Dirtree of the pristine etc state
308-
/// 2. `current_etc_files` – Dirtree of the current etc state
309-
/// 3. `new_etc_files` – Dirtree of the new etc state
308+
/// 2. `current_etc_files` – Dirtree of the current etc state
309+
/// 3. `new_etc_files` – Dirtree of the new etc state (if new_etc directory is passed)
310310
pub fn traverse_etc(
311311
pristine_etc: &CapStdDir,
312312
current_etc: &CapStdDir,
313-
new_etc: &CapStdDir,
313+
new_etc: Option<&CapStdDir>,
314314
) -> anyhow::Result<(
315315
Directory<CustomMetadata>,
316316
Directory<CustomMetadata>,
317-
Directory<CustomMetadata>,
317+
Option<Directory<CustomMetadata>>,
318318
)> {
319319
let mut pristine_etc_files = Directory::default();
320320
recurse_dir(pristine_etc, &mut pristine_etc_files)
@@ -324,8 +324,16 @@ pub fn traverse_etc(
324324
recurse_dir(current_etc, &mut current_etc_files)
325325
.context(format!("Recursing {current_etc:?}"))?;
326326

327-
let mut new_etc_files = Directory::default();
328-
recurse_dir(new_etc, &mut new_etc_files).context(format!("Recursing {new_etc:?}"))?;
327+
let new_etc_files = match new_etc {
328+
Some(new_etc) => {
329+
let mut new_etc_files = Directory::default();
330+
recurse_dir(new_etc, &mut new_etc_files).context(format!("Recursing {new_etc:?}"))?;
331+
332+
Some(new_etc_files)
333+
}
334+
335+
None => None,
336+
};
329337

330338
return Ok((pristine_etc_files, current_etc_files, new_etc_files));
331339
}
@@ -826,7 +834,7 @@ mod tests {
826834
c.remove_file(deleted_files[0])?;
827835
c.remove_file(deleted_files[1])?;
828836

829-
let (pristine_etc_files, current_etc_files, _) = traverse_etc(&p, &c, &n)?;
837+
let (pristine_etc_files, current_etc_files, _) = traverse_etc(&p, &c, Some(&n))?;
830838
let res = compute_diff(&pristine_etc_files, &current_etc_files)?;
831839

832840
// Test added files
@@ -1010,9 +1018,10 @@ mod tests {
10101018
n.create_dir_all("dir/perms")?;
10111019
n.write("dir/perms/some-file", "Some-file")?;
10121020

1013-
let (pristine_etc_files, current_etc_files, new_etc_files) = traverse_etc(&p, &c, &n)?;
1021+
let (pristine_etc_files, current_etc_files, new_etc_files) =
1022+
traverse_etc(&p, &c, Some(&n))?;
10141023
let diff = compute_diff(&pristine_etc_files, &current_etc_files)?;
1015-
merge(&c, &current_etc_files, &n, &new_etc_files, diff)?;
1024+
merge(&c, &current_etc_files, &n, &new_etc_files.unwrap(), diff)?;
10161025

10171026
assert!(files_eq(&c, &n, "new_file.txt")?);
10181027
assert!(files_eq(&c, &n, "a/new_file.txt")?);
@@ -1082,10 +1091,11 @@ mod tests {
10821091

10831092
n.create_dir_all("file-to-dir")?;
10841093

1085-
let (pristine_etc_files, current_etc_files, new_etc_files) = traverse_etc(&p, &c, &n)?;
1094+
let (pristine_etc_files, current_etc_files, new_etc_files) =
1095+
traverse_etc(&p, &c, Some(&n))?;
10861096
let diff = compute_diff(&pristine_etc_files, &current_etc_files)?;
10871097

1088-
let merge_res = merge(&c, &current_etc_files, &n, &new_etc_files, diff);
1098+
let merge_res = merge(&c, &current_etc_files, &n, &new_etc_files.unwrap(), diff);
10891099

10901100
assert!(merge_res.is_err());
10911101
assert_eq!(

crates/lib/src/bootc_composefs/finalize.rs

Lines changed: 26 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,12 +11,34 @@ use bootc_initramfs_setup::{mount_composefs_image, open_dir};
1111
use bootc_mount::tempmount::TempMount;
1212
use cap_std_ext::cap_std::{ambient_authority, fs::Dir};
1313
use cap_std_ext::dirext::CapStdExtDirExt;
14-
use etc_merge::{compute_diff, merge, traverse_etc};
14+
use etc_merge::{compute_diff, merge, print_diff, traverse_etc};
1515
use rustix::fs::{fsync, renameat, CWD};
1616
use rustix::path::Arg;
1717

1818
use fn_error_context::context;
1919

20+
pub(crate) async fn get_etc_diff() -> Result<()> {
21+
let host = composefs_deployment_status().await?;
22+
let booted_composefs = host.require_composefs_booted()?;
23+
24+
// Mount the booted EROFS image to get pristine etc
25+
let sysroot = open_dir(CWD, "/sysroot").context("Opening /sysroot")?;
26+
let composefs_fd = mount_composefs_image(&sysroot, &booted_composefs.verity, false)?;
27+
28+
let erofs_tmp_mnt = TempMount::mount_fd(&composefs_fd)?;
29+
30+
let pristine_etc =
31+
Dir::open_ambient_dir(erofs_tmp_mnt.dir.path().join("etc"), ambient_authority())?;
32+
let current_etc = Dir::open_ambient_dir("/etc", ambient_authority())?;
33+
34+
let (pristine_files, current_files, _) = traverse_etc(&pristine_etc, &current_etc, None)?;
35+
let diff = compute_diff(&pristine_files, &current_files)?;
36+
37+
print_diff(&diff, &mut std::io::stdout());
38+
39+
Ok(())
40+
}
41+
2042
pub(crate) async fn composefs_native_finalize() -> Result<()> {
2143
let host = composefs_deployment_status().await?;
2244

@@ -49,7 +71,9 @@ pub(crate) async fn composefs_native_finalize() -> Result<()> {
4971
let new_etc = Dir::open_ambient_dir(new_etc_path, ambient_authority())?;
5072

5173
let (pristine_files, current_files, new_files) =
52-
traverse_etc(&pristine_etc, &current_etc, &new_etc)?;
74+
traverse_etc(&pristine_etc, &current_etc, Some(&new_etc))?;
75+
76+
let new_files = new_files.ok_or(anyhow::anyhow!("Failed to get dirtree for new etc"))?;
5377

5478
let diff = compute_diff(&pristine_files, &current_files)?;
5579
merge(&current_etc, &current_files, &new_etc, &new_files, diff)?;

crates/lib/src/cli.rs

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -31,8 +31,11 @@ use serde::{Deserialize, Serialize};
3131

3232
#[cfg(feature = "composefs-backend")]
3333
use crate::bootc_composefs::{
34-
finalize::composefs_native_finalize, rollback::composefs_rollback, status::composefs_booted,
35-
switch::switch_composefs, update::upgrade_composefs,
34+
finalize::{composefs_native_finalize, get_etc_diff},
35+
rollback::composefs_rollback,
36+
status::composefs_booted,
37+
switch::switch_composefs,
38+
update::upgrade_composefs,
3639
};
3740
use crate::deploy::RequiredHostSpec;
3841
use crate::lints;
@@ -653,6 +656,9 @@ pub(crate) enum Opt {
653656
Internals(InternalsOpts),
654657
#[cfg(feature = "composefs-backend")]
655658
ComposefsFinalizeStaged,
659+
#[cfg(feature = "composefs-backend")]
660+
/// Diff current /etc configuration versus default
661+
ConfigDiff,
656662
}
657663

658664
/// Ensure we've entered a mount namespace, so that we can remount
@@ -1502,12 +1508,14 @@ async fn run_from_opt(opt: Opt) -> Result<()> {
15021508
let current_etc = Dir::open_ambient_dir(current_etc, cap_std::ambient_authority())?;
15031509
let new_etc = Dir::open_ambient_dir(new_etc, cap_std::ambient_authority())?;
15041510

1505-
let (p, c, n) = etc_merge::traverse_etc(&pristine_etc, &current_etc, &new_etc)?;
1511+
let (p, c, n) =
1512+
etc_merge::traverse_etc(&pristine_etc, &current_etc, Some(&new_etc))?;
15061513

15071514
let diff = compute_diff(&p, &c)?;
15081515
print_diff(&diff, &mut std::io::stdout());
15091516

15101517
if merge {
1518+
let n = n.ok_or(anyhow::anyhow!("Failed to get dirtree for new etc"))?;
15111519
etc_merge::merge(&current_etc, &c, &new_etc, &n, diff)?;
15121520
}
15131521

@@ -1525,6 +1533,9 @@ async fn run_from_opt(opt: Opt) -> Result<()> {
15251533

15261534
#[cfg(feature = "composefs-backend")]
15271535
Opt::ComposefsFinalizeStaged => composefs_native_finalize().await,
1536+
1537+
#[cfg(feature = "composefs-backend")]
1538+
Opt::ConfigDiff => get_etc_diff().await,
15281539
}
15291540
}
15301541

0 commit comments

Comments
 (0)