Skip to content

Commit 7770294

Browse files
committed
usroverlay: Add --read-only flag
1 parent 38c1579 commit 7770294

2 files changed

Lines changed: 35 additions & 12 deletions

File tree

crates/lib/src/bootc_composefs/state.rs

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ use ostree_ext::container::deploy::ORIGIN_CONTAINER;
2020
use rustix::{
2121
fd::AsFd,
2222
fs::{Mode, OFlags, StatVfsMountFlags, open},
23+
mount::MountAttrFlags,
2324
path::Arg,
2425
};
2526

@@ -329,7 +330,7 @@ pub(crate) async fn write_composefs_state(
329330
Ok(())
330331
}
331332

332-
pub(crate) fn composefs_usr_overlay() -> Result<()> {
333+
pub(crate) fn composefs_usr_overlay(access_mode: FilesystemOverlayAccessMode) -> Result<()> {
333334
let status = get_composefs_usr_overlay_status()?;
334335
if status.is_some() {
335336
println!("An overlayfs is already mounted on /usr");
@@ -342,9 +343,14 @@ pub(crate) fn composefs_usr_overlay() -> Result<()> {
342343
let usr_metadata = usr.metadata(".").context("Getting /usr metadata")?;
343344
let usr_mode = Mode::from_raw_mode(usr_metadata.permissions().mode());
344345

345-
overlay_transient(usr, Some(usr_mode))?;
346+
let mount_attr_flags = match access_mode {
347+
FilesystemOverlayAccessMode::ReadOnly => Some(MountAttrFlags::MOUNT_ATTR_RDONLY),
348+
FilesystemOverlayAccessMode::ReadWrite => None,
349+
};
346350

347-
println!("A writeable overlayfs is now mounted on /usr");
351+
overlay_transient(usr, Some(usr_mode), mount_attr_flags)?;
352+
353+
println!("A {} overlayfs is now mounted on /usr", access_mode);
348354
println!("All changes there will be discarded on reboot.");
349355

350356
Ok(())

crates/lib/src/cli.rs

Lines changed: 26 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@ use crate::bootc_composefs::{
4646
use crate::deploy::{MergeState, RequiredHostSpec};
4747
use crate::podstorage::set_additional_image_store;
4848
use crate::progress_jsonl::{ProgressWriter, RawProgressFd};
49+
use crate::spec::FilesystemOverlayAccessMode;
4950
use crate::spec::Host;
5051
use crate::spec::ImageReference;
5152
use crate::status::get_host;
@@ -261,6 +262,14 @@ pub(crate) struct StatusOpts {
261262
pub(crate) verbose: bool,
262263
}
263264

265+
/// Add a transient overlayfs on /usr
266+
#[derive(Debug, Parser, PartialEq, Eq)]
267+
pub(crate) struct UsrOverlayOpts {
268+
/// Mount the overlayfs as read-only.
269+
#[clap(long)]
270+
pub(crate) read_only: bool,
271+
}
272+
264273
#[derive(Debug, clap::Subcommand, PartialEq, Eq)]
265274
pub(crate) enum InstallOpts {
266275
/// Install to the target block device.
@@ -745,7 +754,7 @@ pub(crate) enum Opt {
745754
///
746755
/// Allows temporary package installation that will be discarded on reboot.
747756
#[clap(alias = "usroverlay")]
748-
UsrOverlay,
757+
UsrOverlay(UsrOverlayOpts),
749758
/// Install the running container to a target.
750759
///
751760
/// Takes a container image and installs it to disk in a bootable format.
@@ -1402,13 +1411,16 @@ async fn edit(opts: EditOpts) -> Result<()> {
14021411
}
14031412

14041413
/// Implementation of `bootc usroverlay`
1405-
async fn usroverlay() -> Result<()> {
1414+
async fn usroverlay(access_mode: FilesystemOverlayAccessMode) -> Result<()> {
14061415
// This is just a pass-through today. At some point we may make this a libostree API
14071416
// or even oxidize it.
1408-
Err(Command::new("ostree")
1409-
.args(["admin", "unlock"])
1410-
.exec()
1411-
.into())
1417+
let args = match access_mode {
1418+
// In this context, "--transient" means "read-only overlay"
1419+
FilesystemOverlayAccessMode::ReadOnly => ["admin", "unlock", "--transient"].as_slice(),
1420+
1421+
FilesystemOverlayAccessMode::ReadWrite => ["admin", "unlock"].as_slice(),
1422+
};
1423+
Err(Command::new("ostree").args(args).exec().into())
14121424
}
14131425

14141426
/// Perform process global initialization. This should be called as early as possible
@@ -1519,12 +1531,17 @@ async fn run_from_opt(opt: Opt) -> Result<()> {
15191531
Ok(())
15201532
}
15211533
Opt::Edit(opts) => edit(opts).await,
1522-
Opt::UsrOverlay => {
1534+
Opt::UsrOverlay(opts) => {
15231535
use crate::store::Environment;
15241536
let env = Environment::detect()?;
1537+
let access_mode = if opts.read_only {
1538+
FilesystemOverlayAccessMode::ReadOnly
1539+
} else {
1540+
FilesystemOverlayAccessMode::ReadWrite
1541+
};
15251542
match env {
1526-
Environment::OstreeBooted => usroverlay().await,
1527-
Environment::ComposefsBooted(_) => composefs_usr_overlay(),
1543+
Environment::OstreeBooted => usroverlay(access_mode).await,
1544+
Environment::ComposefsBooted(_) => composefs_usr_overlay(access_mode),
15281545
_ => anyhow::bail!("usroverlay only applies on booted hosts"),
15291546
}
15301547
}

0 commit comments

Comments
 (0)