44
55use std:: ffi:: { CString , OsStr , OsString } ;
66use std:: io:: Seek ;
7- use std:: os:: fd:: RawFd ;
87use std:: os:: unix:: process:: CommandExt ;
98use std:: process:: Command ;
109
@@ -26,12 +25,35 @@ use serde::{Deserialize, Serialize};
2625
2726use crate :: deploy:: RequiredHostSpec ;
2827use crate :: lints;
29- use crate :: progress_jsonl;
30- use crate :: progress_jsonl:: ProgressWriter ;
28+ use crate :: progress_jsonl:: { ProgressWriter , RawProgressFd } ;
3129use crate :: spec:: Host ;
3230use crate :: spec:: ImageReference ;
3331use crate :: utils:: sigpolicy_from_opts;
3432
33+ /// Shared progress options
34+ #[ derive( Debug , Parser , PartialEq , Eq ) ]
35+ pub ( crate ) struct ProgressOptions {
36+ /// File descriptor number which must refer to an open pipe (anonymous or named).
37+ ///
38+ /// Interactive progress will be written to this file descriptor as "JSON lines"
39+ /// format, where each value is separated by a newline.
40+ #[ clap( long) ]
41+ pub ( crate ) json_fd : Option < RawProgressFd > ,
42+ }
43+
44+ impl TryFrom < ProgressOptions > for ProgressWriter {
45+ type Error = anyhow:: Error ;
46+
47+ fn try_from ( value : ProgressOptions ) -> Result < Self > {
48+ let r = value
49+ . json_fd
50+ . map ( TryInto :: try_into)
51+ . transpose ( ) ?
52+ . unwrap_or_default ( ) ;
53+ Ok ( r)
54+ }
55+ }
56+
3557/// Perform an upgrade operation
3658#[ derive( Debug , Parser , PartialEq , Eq ) ]
3759pub ( crate ) struct UpgradeOpts {
@@ -54,9 +76,8 @@ pub(crate) struct UpgradeOpts {
5476 #[ clap( long, conflicts_with = "check" ) ]
5577 pub ( crate ) apply : bool ,
5678
57- /// Pipe download progress to this fd in a jsonl format.
58- #[ clap( long) ]
59- pub ( crate ) json_fd : Option < RawFd > ,
79+ #[ clap( flatten) ]
80+ pub ( crate ) progress : ProgressOptions ,
6081}
6182
6283/// Perform an switch operation
@@ -107,9 +128,8 @@ pub(crate) struct SwitchOpts {
107128 /// Target image to use for the next boot.
108129 pub ( crate ) target : String ,
109130
110- /// Pipe download progress to this fd in a jsonl format.
111- #[ clap( long) ]
112- pub ( crate ) json_fd : Option < RawFd > ,
131+ #[ clap( flatten) ]
132+ pub ( crate ) progress : ProgressOptions ,
113133}
114134
115135/// Options controlling rollback
@@ -653,11 +673,7 @@ async fn upgrade(opts: UpgradeOpts) -> Result<()> {
653673 let ( booted_deployment, _deployments, host) =
654674 crate :: status:: get_status_require_booted ( sysroot) ?;
655675 let imgref = host. spec . image . as_ref ( ) ;
656- let prog = opts
657- . json_fd
658- . map ( progress_jsonl:: ProgressWriter :: from_raw_fd)
659- . transpose ( ) ?
660- . unwrap_or_default ( ) ;
676+ let prog: ProgressWriter = opts. progress . try_into ( ) ?;
661677
662678 // If there's no specified image, let's be nice and check if the booted system is using rpm-ostree
663679 if imgref. is_none ( ) {
@@ -774,11 +790,7 @@ async fn switch(opts: SwitchOpts) -> Result<()> {
774790 ) ;
775791 let target = ostree_container:: OstreeImageReference { sigverify, imgref } ;
776792 let target = ImageReference :: from ( target) ;
777- let prog = opts
778- . json_fd
779- . map ( progress_jsonl:: ProgressWriter :: from_raw_fd)
780- . transpose ( ) ?
781- . unwrap_or_default ( ) ;
793+ let prog: ProgressWriter = opts. progress . try_into ( ) ?;
782794
783795 // If we're doing an in-place mutation, we shortcut most of the rest of the work here
784796 if opts. mutate_in_place {
0 commit comments