Archived
1
0
Fork 0

installer: Capture external commands output.

* gnu/installer/utils.scm (run-external-command-with-handler,
run-external-command-with-line-hooks): New variables.
(run-command): Use run-external-command-with-line-hooks.

Signed-off-by: Mathieu Othacehe <othacehe@gnu.org>
This commit is contained in:
Josselin Poiret 2022-01-15 14:50:00 +01:00 committed by Mathieu Othacehe
parent c57ec6ed1e
commit 0b9fbbb4dd
No known key found for this signature in database
GPG key ID: 8354763531769CA6

View file

@ -25,7 +25,9 @@
#:use-module (srfi srfi-1) #:use-module (srfi srfi-1)
#:use-module (srfi srfi-19) #:use-module (srfi srfi-19)
#:use-module (srfi srfi-34) #:use-module (srfi srfi-34)
#:use-module (ice-9 control)
#:use-module (ice-9 match) #:use-module (ice-9 match)
#:use-module (ice-9 popen)
#:use-module (ice-9 rdelim) #:use-module (ice-9 rdelim)
#:use-module (ice-9 regex) #:use-module (ice-9 regex)
#:use-module (ice-9 format) #:use-module (ice-9 format)
@ -34,6 +36,8 @@
read-all read-all
nearest-exact-integer nearest-exact-integer
read-percentage read-percentage
run-external-command-with-handler
run-external-command-with-line-hooks
run-command run-command
syslog-port syslog-port
@ -78,37 +82,91 @@ number. If no percentage is found, return #f"
(and result (and result
(string->number (match:substring result 1))))) (string->number (match:substring result 1)))))
(define* (run-external-command-with-handler handler command)
"Run command specified by the list COMMAND in a child with output handler
HANDLER. HANDLER is a procedure taking an input port, to which the command
will write its standard output and error. Returns the integer status value of
the child process as returned by waitpid."
(match-let (((input . output) (pipe)))
;; Hack to work around Guile bug 52835
(define dup-output (duplicate-port output "w"))
;; Void pipe, but holds the pid for close-pipe.
(define dummy-pipe
(with-input-from-file "/dev/null"
(lambda ()
(with-output-to-port output
(lambda ()
(with-error-to-port dup-output
(lambda ()
(apply open-pipe* (cons "" command)))))))))
(close-port output)
(close-port dup-output)
(handler input)
(close-port input)
(close-pipe dummy-pipe)))
(define (run-external-command-with-line-hooks line-hooks command)
"Run command specified by the list COMMAND in a child, processing each
output line with the procedures in LINE-HOOKS. Returns the integer status
value of the child process as returned by waitpid."
(define (handler input)
(and
(and=> (get-line input)
(lambda (line)
(if (eof-object? line)
#f
(begin (for-each (lambda (f) (f line))
(append line-hooks
%default-installer-line-hooks))
#t))))
(handler input)))
(run-external-command-with-handler handler command))
(define* (run-command command) (define* (run-command command)
"Run COMMAND, a list of strings. Return true if COMMAND exited "Run COMMAND, a list of strings. Return true if COMMAND exited
successfully, #f otherwise." successfully, #f otherwise."
(define env (environ))
(define (pause) (define (pause)
(format #t (G_ "Press Enter to continue.~%")) (format #t (G_ "Press Enter to continue.~%"))
(send-to-clients '(pause)) (send-to-clients '(pause))
(environ env) ;restore environment variables
(match (select (cons (current-input-port) (current-clients)) (match (select (cons (current-input-port) (current-clients))
'() '()) '() '())
(((port _ ...) _ _) (((port _ ...) _ _)
(read-line port)))) (read-line port))))
(setenv "PATH" "/run/current-system/profile/bin") (installer-log-line "running command ~s" command)
(define result (run-external-command-with-line-hooks
(guard (c ((invoke-error? c) (list %display-line-hook)
(newline) command))
(format (current-error-port) (define exit-val (status:exit-val result))
(G_ "Command failed with exit code ~a.~%") (define term-sig (status:term-sig result))
(invoke-error-exit-status c)) (define stop-sig (status:stop-sig result))
(installer-log-line "command ~s failed with exit code ~a" (define succeeded?
command (invoke-error-exit-status c)) (cond
(pause) ((and exit-val (not (zero? exit-val)))
#f)) (installer-log-line "command ~s exited with value ~a"
(installer-log-line "running command ~s" command) command exit-val)
(apply invoke command) (format #t (G_ "Command ~s exited with value ~a")
(installer-log-line "command ~s succeeded" command) command exit-val)
(newline) #f)
(pause) (term-sig
#t)) (installer-log-line "command ~s killed by signal ~a"
command term-sig)
(format #t (G_ "Command ~s killed by signal ~a")
command term-sig)
#f)
(stop-sig
(installer-log-line "command ~s stopped by signal ~a"
command stop-sig)
(format #t (G_ "Command ~s stopped by signal ~a")
command stop-sig)
#f)
(else
(installer-log-line "command ~s succeeded" command)
(format #t (G_ "Command ~s succeeded") command)
#t)))
(newline)
(pause)
succeeded?)
;;; ;;;