Skip to content

Commit c9b42c3

Browse files
evan-goodecgwalters
authored andcommitted
usroverlay: Add --read-only flag
Signed-off-by: Evan Goode <mail@evangoo.de>
1 parent d55be0e commit c9b42c3

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
@@ -21,6 +21,7 @@ use ostree_ext::container::deploy::ORIGIN_CONTAINER;
2121
use rustix::{
2222
fd::AsFd,
2323
fs::{Mode, OFlags, StatVfsMountFlags, open},
24+
mount::MountAttrFlags,
2425
path::Arg,
2526
};
2627

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

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

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

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

351357
Ok(())

crates/lib/src/cli.rs

Lines changed: 26 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,7 @@ use crate::bootc_composefs::{
5050
use crate::deploy::{MergeState, RequiredHostSpec};
5151
use crate::podstorage::set_additional_image_store;
5252
use crate::progress_jsonl::{ProgressWriter, RawProgressFd};
53+
use crate::spec::FilesystemOverlayAccessMode;
5354
use crate::spec::Host;
5455
use crate::spec::ImageReference;
5556
use crate::status::get_host;
@@ -265,6 +266,14 @@ pub(crate) struct StatusOpts {
265266
pub(crate) verbose: bool,
266267
}
267268

269+
/// Add a transient overlayfs on /usr
270+
#[derive(Debug, Parser, PartialEq, Eq)]
271+
pub(crate) struct UsrOverlayOpts {
272+
/// Mount the overlayfs as read-only.
273+
#[clap(long)]
274+
pub(crate) read_only: bool,
275+
}
276+
268277
#[derive(Debug, clap::Subcommand, PartialEq, Eq)]
269278
pub(crate) enum InstallOpts {
270279
/// Install to the target block device.
@@ -788,7 +797,7 @@ pub(crate) enum Opt {
788797
///
789798
/// Allows temporary package installation that will be discarded on reboot.
790799
#[clap(alias = "usroverlay")]
791-
UsrOverlay,
800+
UsrOverlay(UsrOverlayOpts),
792801
/// Install the running container to a target.
793802
///
794803
/// Takes a container image and installs it to disk in a bootable format.
@@ -1445,13 +1454,16 @@ async fn edit(opts: EditOpts) -> Result<()> {
14451454
}
14461455

14471456
/// Implementation of `bootc usroverlay`
1448-
async fn usroverlay() -> Result<()> {
1457+
async fn usroverlay(access_mode: FilesystemOverlayAccessMode) -> Result<()> {
14491458
// This is just a pass-through today. At some point we may make this a libostree API
14501459
// or even oxidize it.
1451-
Err(Command::new("ostree")
1452-
.args(["admin", "unlock"])
1453-
.exec()
1454-
.into())
1460+
let args = match access_mode {
1461+
// In this context, "--transient" means "read-only overlay"
1462+
FilesystemOverlayAccessMode::ReadOnly => ["admin", "unlock", "--transient"].as_slice(),
1463+
1464+
FilesystemOverlayAccessMode::ReadWrite => ["admin", "unlock"].as_slice(),
1465+
};
1466+
Err(Command::new("ostree").args(args).exec().into())
14551467
}
14561468

14571469
/// Perform process global initialization. This should be called as early as possible
@@ -1562,12 +1574,17 @@ async fn run_from_opt(opt: Opt) -> Result<()> {
15621574
Ok(())
15631575
}
15641576
Opt::Edit(opts) => edit(opts).await,
1565-
Opt::UsrOverlay => {
1577+
Opt::UsrOverlay(opts) => {
15661578
use crate::store::Environment;
15671579
let env = Environment::detect()?;
1580+
let access_mode = if opts.read_only {
1581+
FilesystemOverlayAccessMode::ReadOnly
1582+
} else {
1583+
FilesystemOverlayAccessMode::ReadWrite
1584+
};
15681585
match env {
1569-
Environment::OstreeBooted => usroverlay().await,
1570-
Environment::ComposefsBooted(_) => composefs_usr_overlay(),
1586+
Environment::OstreeBooted => usroverlay(access_mode).await,
1587+
Environment::ComposefsBooted(_) => composefs_usr_overlay(access_mode),
15711588
_ => anyhow::bail!("usroverlay only applies on booted hosts"),
15721589
}
15731590
}

0 commit comments

Comments
 (0)