network.scm 6.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199
  1. ;;; GNU Guix --- Functional package management for GNU
  2. ;;; Copyright © 2018 Mathieu Othacehe <m.othacehe@gmail.com>
  3. ;;; Copyright © 2019, 2020 Ludovic Courtès <ludo@gnu.org>
  4. ;;;
  5. ;;; This file is part of GNU Guix.
  6. ;;;
  7. ;;; GNU Guix is free software; you can redistribute it and/or modify it
  8. ;;; under the terms of the GNU General Public License as published by
  9. ;;; the Free Software Foundation; either version 3 of the License, or (at
  10. ;;; your option) any later version.
  11. ;;;
  12. ;;; GNU Guix is distributed in the hope that it will be useful, but
  13. ;;; WITHOUT ANY WARRANTY; without even the implied warranty of
  14. ;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  15. ;;; GNU General Public License for more details.
  16. ;;;
  17. ;;; You should have received a copy of the GNU General Public License
  18. ;;; along with GNU Guix. If not, see <http://www.gnu.org/licenses/>.
  19. (define-module (gnu installer newt network)
  20. #:use-module (gnu installer connman)
  21. #:use-module (gnu installer steps)
  22. #:use-module (gnu installer utils)
  23. #:use-module (gnu installer newt ethernet)
  24. #:use-module (gnu installer newt page)
  25. #:use-module (gnu installer newt wifi)
  26. #:use-module (guix i18n)
  27. #:use-module (srfi srfi-1)
  28. #:use-module (srfi srfi-11)
  29. #:use-module (srfi srfi-34)
  30. #:use-module (srfi srfi-35)
  31. #:use-module (ice-9 match)
  32. #:use-module (web client)
  33. #:use-module (web response)
  34. #:use-module (newt)
  35. #:export (run-network-page))
  36. ;; Maximum length of a technology name.
  37. (define technology-name-max-length (make-parameter 20))
  38. (define (technology->text technology)
  39. "Return a string describing the given TECHNOLOGY."
  40. (let* ((name (technology-name technology))
  41. (padded-name (string-pad-right name
  42. (technology-name-max-length))))
  43. (format #f "~a~%" padded-name)))
  44. (define (run-technology-page)
  45. "Run a page to ask the user which technology shall be used to access
  46. Internet and return the selected technology. For now, only technologies with
  47. \"ethernet\" or \"wifi\" types are supported."
  48. (define (technology-items)
  49. (filter (lambda (technology)
  50. (let ((type (technology-type technology)))
  51. (or
  52. (string=? type "ethernet")
  53. (string=? type "wifi"))))
  54. (connman-technologies)))
  55. (match (technology-items)
  56. (()
  57. (case (choice-window
  58. (G_ "Internet access")
  59. (G_ "Continue")
  60. (G_ "Exit")
  61. (G_ "The install process requires Internet access but no \
  62. network devices were found. Do you want to continue anyway?"))
  63. ((1) (abort-to-prompt 'installer-step 'break))
  64. ((2) (abort-to-prompt 'installer-step 'abort))))
  65. ((technology)
  66. ;; Since there's only one technology available, skip the selection
  67. ;; screen.
  68. technology)
  69. ((items ...)
  70. (run-listbox-selection-page
  71. #:info-text (G_ "The install process requires Internet access.\
  72. Please select a network device.")
  73. #:title (G_ "Internet access")
  74. #:listbox-items items
  75. #:listbox-item->text technology->text
  76. #:listbox-height (min (+ (length items) 2) 5)
  77. #:button-text (G_ "Exit")
  78. #:button-callback-procedure
  79. (lambda _
  80. (abort-to-prompt 'installer-step 'abort))))))
  81. (define (find-technology-by-type technologies type)
  82. "Find and return a technology with the given TYPE in TECHNOLOGIES list."
  83. (find (lambda (technology)
  84. (string=? (technology-type technology)
  85. type))
  86. technologies))
  87. (define (wait-technology-powered technology)
  88. "Wait and display a progress bar until the given TECHNOLOGY is powered."
  89. (let ((name (technology-name technology))
  90. (full-value 5))
  91. (run-scale-page
  92. #:title (G_ "Powering technology")
  93. #:info-text (format #f (G_ "Waiting for technology ~a to be powered.")
  94. name)
  95. #:scale-full-value full-value
  96. #:scale-update-proc
  97. (lambda (value)
  98. (let* ((technologies (connman-technologies))
  99. (type (technology-type technology))
  100. (updated-technology
  101. (find-technology-by-type technologies type))
  102. (technology-powered? updated-technology))
  103. (sleep 1)
  104. (if technology-powered?
  105. full-value
  106. (+ value 1)))))))
  107. (define (wait-service-online)
  108. "Display a newt scale until connman detects an Internet access. Do
  109. FULL-VALUE tentatives, spaced by 1 second."
  110. (define (url-alive? url)
  111. (false-if-exception
  112. (= (response-code (http-request url))
  113. 200)))
  114. (define (ci-available?)
  115. (dynamic-wind
  116. (lambda ()
  117. (sigaction SIGALRM
  118. (lambda _ #f))
  119. (alarm 3))
  120. (lambda ()
  121. (or (url-alive? "https://ci.guix.gnu.org")
  122. (url-alive? "https://bordeaux.guix.gnu.org")))
  123. (lambda ()
  124. (alarm 0))))
  125. (define (online?)
  126. (or (and (connman-online?)
  127. (ci-available?))
  128. (file-exists? "/tmp/installer-assume-online")))
  129. (let* ((full-value 5))
  130. (run-scale-page
  131. #:title (G_ "Checking connectivity")
  132. #:info-text (G_ "Waiting for Internet access establishment...")
  133. #:scale-full-value full-value
  134. #:scale-update-proc
  135. (lambda (value)
  136. (sleep 1)
  137. (if (online?)
  138. full-value
  139. (+ value 1))))
  140. (unless (online?)
  141. (run-error-page
  142. (G_ "The selected network does not provide access to the \
  143. Internet and the Guix substitute server, please try again.")
  144. (G_ "Connection error"))
  145. (abort-to-prompt 'installer-step 'abort))))
  146. (define (run-network-page)
  147. "Run a page to allow the user to configure connman so that it can access the
  148. Internet."
  149. (define network-steps
  150. (list
  151. ;; Ask the user to choose between ethernet and wifi technologies.
  152. (installer-step
  153. (id 'select-technology)
  154. (compute
  155. (lambda _
  156. (run-technology-page))))
  157. ;; Enable the previously selected technology.
  158. (installer-step
  159. (id 'power-technology)
  160. (compute
  161. (lambda (result _)
  162. (let ((technology (result-step result 'select-technology)))
  163. (connman-enable-technology technology)
  164. (wait-technology-powered technology)))))
  165. ;; Propose the user to connect to one of the service available for the
  166. ;; previously selected technology.
  167. (installer-step
  168. (id 'connect-service)
  169. (compute
  170. (lambda (result _)
  171. (let* ((technology (result-step result 'select-technology))
  172. (type (technology-type technology)))
  173. (cond
  174. ((string=? "wifi" type)
  175. (run-wifi-page))
  176. ((string=? "ethernet" type)
  177. (run-ethernet-page)))))))
  178. ;; Wait for connman status to switch to 'online, which means it can
  179. ;; access Internet.
  180. (installer-step
  181. (id 'wait-online)
  182. (compute (lambda _
  183. (wait-service-online))))))
  184. (run-installer-steps
  185. #:steps network-steps
  186. #:rewind-strategy 'start))