@@ -50,6 +50,7 @@ use crate::bootc_composefs::{
5050use crate :: deploy:: { MergeState , RequiredHostSpec } ;
5151use crate :: podstorage:: set_additional_image_store;
5252use crate :: progress_jsonl:: { ProgressWriter , RawProgressFd } ;
53+ use crate :: spec:: FilesystemOverlayAccessMode ;
5354use crate :: spec:: Host ;
5455use crate :: spec:: ImageReference ;
5556use 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 ) ]
269278pub ( 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