@@ -172,6 +172,7 @@ def __init__(self, image, dest, bmap=None, image_size=None):
172172 self ._progress_file = None
173173 self ._progress_format = None
174174 self .set_progress_indicator (None , None )
175+ self ._psplash_pipe = None
175176
176177 self ._f_image = image
177178 self ._image_path = image .name
@@ -211,6 +212,28 @@ def __init__(self, image, dest, bmap=None, image_size=None):
211212
212213 self ._batch_blocks = self ._batch_bytes // self .block_size
213214
215+ def set_psplash_pipe (self , path ):
216+ """
217+ Set the psplash named pipe file path to be used when updating the
218+ progress - best effort.
219+
220+ The 'path' argument is the named pipe used by the psplash process to get
221+ progress bar commands. When the path argument doesn't exist or is not a
222+ pipe, the function will ignore with a warning. This behavior is
223+ considered as such because the progress is considered a decoration
224+ functionality which might or might not be available even if requested.
225+ When used as a boot service, the unavailability of the psplash service
226+ (due to various reasons: no screen, racing issues etc.) should not
227+ break the writting process. This is why this implementation is done as
228+ a best effort.
229+ """
230+
231+ if os .path .exists (pipe ) and stat .S_ISFIFO (os .stat (pipe ).st_mode ):
232+ self ._psplash_pipe = pipe
233+ else :
234+ _log .warning ("'%s' is not a pipe, so psplash progress will not be "
235+ "updated" % pipe )
236+
214237 def set_progress_indicator (self , file_obj , format_string ):
215238 """
216239 Setup the progress indicator which shows how much data has been copied
@@ -404,6 +427,17 @@ def _update_progress(self, blocks_written):
404427 self ._progress_file .write (progress )
405428 self ._progress_file .flush ()
406429
430+ # Update psplash progress when configured. This is using a best effort
431+ # strategy to not affect the writing process when psplash breaks, is
432+ # not available early enough or screen is not available.
433+ if self ._psplash_pipe and self .mapped_cnt :
434+ try :
435+ mode = os .O_WRONLY | os .O_NONBLOCK
436+ with os .fdopen (os .open (self ._psplash_pipe , mode ), 'w' ) as p_fo :
437+ p_fo .write ("PROGRESS %d\n " % percent )
438+ except :
439+ pass
440+
407441 def _get_block_ranges (self ):
408442 """
409443 This is a helper generator that parses the bmap XML file and for each
0 commit comments