@@ -46,6 +46,7 @@ use crate::bootc_composefs::{
4646use crate :: deploy:: { MergeState , RequiredHostSpec } ;
4747use crate :: podstorage:: set_additional_image_store;
4848use crate :: progress_jsonl:: { ProgressWriter , RawProgressFd } ;
49+ use crate :: spec:: FilesystemOverlayAccessMode ;
4950use crate :: spec:: Host ;
5051use crate :: spec:: ImageReference ;
5152use 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 ) ]
265274pub ( 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