* gnu/installer.scm (installer-program): Let the installer customize the dump archive. * gnu/installer/dump.scm (prepare-dump, make-dump): Split make-dump in prepare-dump, which copies the files necessary for the dump, and make-dump which creates the archive. * gnu/installer/record.scm (installer): Add report-page field. Change documented return value of exit-error. * gnu/installer/newt.scm (exit-error): Change arguments to be a string containing the error. Let the user choose between exiting and initiating a dump. (report-page): Add new variable. * gnu/installer/newt/page.scm (run-dump-page): New variable. * gnu/installer/newt/dump.scm: Delete it. Signed-off-by: Mathieu Othacehe <othacehe@gnu.org>
		
			
				
	
	
		
			118 lines
		
	
	
	
		
			3.9 KiB
		
	
	
	
		
			Scheme
		
	
	
	
	
	
			
		
		
	
	
			118 lines
		
	
	
	
		
			3.9 KiB
		
	
	
	
		
			Scheme
		
	
	
	
	
	
| ;;; GNU Guix --- Functional package management for GNU
 | |
| ;;; Copyright © 2021 Mathieu Othacehe <othacehe@gnu.org>
 | |
| ;;;
 | |
| ;;; This file is part of GNU Guix.
 | |
| ;;;
 | |
| ;;; GNU Guix is free software; you can redistribute it and/or modify it
 | |
| ;;; under the terms of the GNU General Public License as published by
 | |
| ;;; the Free Software Foundation; either version 3 of the License, or (at
 | |
| ;;; your option) any later version.
 | |
| ;;;
 | |
| ;;; GNU Guix is distributed in the hope that it will be useful, but
 | |
| ;;; WITHOUT ANY WARRANTY; without even the implied warranty of
 | |
| ;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | |
| ;;; GNU General Public License for more details.
 | |
| ;;;
 | |
| ;;; You should have received a copy of the GNU General Public License
 | |
| ;;; along with GNU Guix.  If not, see <http://www.gnu.org/licenses/>.
 | |
| 
 | |
| (define-module (gnu installer dump)
 | |
|   #:use-module (gnu installer utils)
 | |
|   #:use-module (guix build utils)
 | |
|   #:use-module (srfi srfi-11)
 | |
|   #:use-module (ice-9 iconv)
 | |
|   #:use-module (ice-9 match)
 | |
|   #:use-module (ice-9 popen)
 | |
|   #:use-module (ice-9 textual-ports)
 | |
|   #:use-module (web client)
 | |
|   #:use-module (web http)
 | |
|   #:use-module (web response)
 | |
|   #:use-module (webutils multipart)
 | |
|   #:export (prepare-dump
 | |
|             make-dump
 | |
|             send-dump-report))
 | |
| 
 | |
| ;; The installer crash dump type.
 | |
| (define %dump-type "installer-dump")
 | |
| 
 | |
| (define (result->list result)
 | |
|   "Return the alist for the given RESULT."
 | |
|   (hash-map->list (lambda (k v)
 | |
|                     (cons k v))
 | |
|                   result))
 | |
| 
 | |
| (define* (prepare-dump key args #:key result)
 | |
|   "Create a crash dump directory.  KEY and ARGS represent the thrown error.
 | |
| RESULT is the installer result hash table.  Returns the created directory path."
 | |
|   (define now (localtime (current-time)))
 | |
|   (define dump-dir
 | |
|     (format #f "/tmp/dump.~a"
 | |
|             (strftime "%F.%H.%M.%S" now)))
 | |
|   (mkdir-p dump-dir)
 | |
|   (with-directory-excursion dump-dir
 | |
|     ;; backtrace
 | |
|     (call-with-output-file "installer-backtrace"
 | |
|       (lambda (port)
 | |
|         (display-backtrace (make-stack #t) port)
 | |
|         (print-exception port
 | |
|                          (stack-ref (make-stack #t) 1)
 | |
|                          key args)))
 | |
| 
 | |
|     ;; installer result
 | |
|     (call-with-output-file "installer-result"
 | |
|       (lambda (port)
 | |
|         (write (result->list result) port)))
 | |
| 
 | |
|     ;; syslog
 | |
|     (copy-file "/var/log/messages" "syslog")
 | |
| 
 | |
|     ;; dmesg
 | |
|     (let ((pipe (open-pipe* OPEN_READ "dmesg")))
 | |
|       (call-with-output-file "dmesg"
 | |
|         (lambda (port)
 | |
|           (dump-port pipe port)
 | |
|           (close-pipe pipe)))))
 | |
|   dump-dir)
 | |
| 
 | |
| (define* (make-dump dump-dir file-choices)
 | |
|   "Create a crash dump archive from DUMP-DIR containing FILE-CHOICES.
 | |
| Returns the archive path."
 | |
|   (define output (string-append (basename dump-dir) ".tar.gz"))
 | |
|   (with-directory-excursion (dirname dump-dir)
 | |
|     (apply system* "tar" "-zcf" output
 | |
|            (map (lambda (f)
 | |
|                   (string-append (basename dump-dir) "/" f))
 | |
|                 file-choices)))
 | |
|   (canonicalize-path (string-append (dirname dump-dir) "/" output)))
 | |
| 
 | |
| (define* (send-dump-report dump
 | |
|                            #:key
 | |
|                            (url "https://dump.guix.gnu.org"))
 | |
|   "Turn the DUMP archive into a multipart body and send it to the Guix crash
 | |
| dump server at URL."
 | |
|   (define (match-boundary kont)
 | |
|     (match-lambda
 | |
|       (('boundary . (? string? b))
 | |
|        (kont b))
 | |
|       (x #f)))
 | |
| 
 | |
|   (define (response->string response)
 | |
|     (bytevector->string
 | |
|      (read-response-body response)
 | |
|      "UTF-8"))
 | |
| 
 | |
|   (let-values (((body boundary)
 | |
|                 (call-with-input-file dump
 | |
|                   (lambda (port)
 | |
|                     (format-multipart-body
 | |
|                      `((,%dump-type . ,port)))))))
 | |
|     (false-if-exception
 | |
|      (response->string
 | |
|       (http-post
 | |
|        (string-append url "/upload")
 | |
|        #:keep-alive? #t
 | |
|        #:streaming? #t
 | |
|        #:headers `((content-type
 | |
|                     . (multipart/form-data
 | |
|                        (boundary . ,boundary))))
 | |
|        #:body body)))))
 |