dump.scm 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119
  1. ;;; GNU Guix --- Functional package management for GNU
  2. ;;; Copyright © 2021 Mathieu Othacehe <othacehe@gnu.org>
  3. ;;;
  4. ;;; This file is part of GNU Guix.
  5. ;;;
  6. ;;; GNU Guix is free software; you can redistribute it and/or modify it
  7. ;;; under the terms of the GNU General Public License as published by
  8. ;;; the Free Software Foundation; either version 3 of the License, or (at
  9. ;;; your option) any later version.
  10. ;;;
  11. ;;; GNU Guix is distributed in the hope that it will be useful, but
  12. ;;; WITHOUT ANY WARRANTY; without even the implied warranty of
  13. ;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  14. ;;; GNU General Public License for more details.
  15. ;;;
  16. ;;; You should have received a copy of the GNU General Public License
  17. ;;; along with GNU Guix. If not, see <http://www.gnu.org/licenses/>.
  18. (define-module (gnu installer dump)
  19. #:use-module (gnu installer utils)
  20. #:use-module (guix build utils)
  21. #:use-module (srfi srfi-11)
  22. #:use-module (ice-9 iconv)
  23. #:use-module (ice-9 match)
  24. #:use-module (ice-9 popen)
  25. #:use-module (ice-9 textual-ports)
  26. #:use-module (web client)
  27. #:use-module (web http)
  28. #:use-module (web response)
  29. #:use-module (webutils multipart)
  30. #:export (prepare-dump
  31. make-dump
  32. send-dump-report))
  33. ;; The installer crash dump type.
  34. (define %dump-type "installer-dump")
  35. (define (result->list result)
  36. "Return the alist for the given RESULT."
  37. (hash-map->list (lambda (k v)
  38. (cons k v))
  39. result))
  40. (define* (prepare-dump key args #:key result)
  41. "Create a crash dump directory. KEY and ARGS represent the thrown error.
  42. RESULT is the installer result hash table. Returns the created directory path."
  43. (define now (localtime (current-time)))
  44. (define dump-dir
  45. (format #f "/tmp/dump.~a"
  46. (strftime "%F.%H.%M.%S" now)))
  47. (mkdir-p dump-dir)
  48. (with-directory-excursion dump-dir
  49. ;; backtrace
  50. (call-with-output-file "installer-backtrace"
  51. (lambda (port)
  52. (display-backtrace (make-stack #t) port)
  53. (print-exception port
  54. (stack-ref (make-stack #t) 1)
  55. key args)))
  56. ;; installer result
  57. (call-with-output-file "installer-result"
  58. (lambda (port)
  59. (write (result->list result) port)))
  60. ;; syslog
  61. (copy-file "/var/log/messages" "syslog")
  62. ;; dmesg
  63. (let ((pipe (open-pipe* OPEN_READ "dmesg")))
  64. (call-with-output-file "dmesg"
  65. (lambda (port)
  66. (dump-port pipe port)
  67. (close-pipe pipe)))))
  68. dump-dir)
  69. (define* (make-dump dump-dir file-choices)
  70. "Create a crash dump archive from DUMP-DIR containing FILE-CHOICES.
  71. Returns the archive path."
  72. (define output (string-append (basename dump-dir) ".tar.gz"))
  73. (with-directory-excursion (dirname dump-dir)
  74. (apply system* "tar" "-zcf" output
  75. (map (lambda (f)
  76. (string-append (basename dump-dir) "/" f))
  77. file-choices)))
  78. (canonicalize-path (string-append (dirname dump-dir) "/" output)))
  79. (define* (send-dump-report dump
  80. #:key
  81. (url "https://dump.guix.gnu.org"))
  82. "Turn the DUMP archive into a multipart body and send it to the Guix crash
  83. dump server at URL."
  84. (define (match-boundary kont)
  85. (match-lambda
  86. (('boundary . (? string? b))
  87. (kont b))
  88. (x #f)))
  89. (define (response->string response)
  90. (bytevector->string
  91. (read-response-body response)
  92. "UTF-8"))
  93. (let-values (((body boundary)
  94. (call-with-input-file dump
  95. (lambda (port)
  96. (format-multipart-body
  97. `((,%dump-type . ,port)))))))
  98. (false-if-exception
  99. (response->string
  100. (http-post
  101. (string-append url "/upload")
  102. #:keep-alive? #t
  103. #:streaming? #t
  104. #:headers `((content-type
  105. . (multipart/form-data
  106. (boundary . ,boundary))))
  107. #:body body)))))