mirror of
https://codeberg.org/guix/guix.git
synced 2026-01-25 03:55:08 -06:00
This is to accomodate following situation:
- The proxy is up
- The substitute server is down
When that happens, 5xx is returned from the proxy, typically either Bad
Gateway or Gateway Timeout. This implies the substitute server is down.
Still, for checking if the user is online, we do not check the response code.
If there is a response, even 4xx, 5xx, it still means the user is online.
* gnu/installer/newt/network.scm
(url-alive?): Add optional argument to to check the response code.
(common-urls-alive?): Add the same argument, passing it to url-alive?
(check-substitute-availability): Assume offline when non-successful http code
returned.
Follow up of 9ea2174ba8.
Change-Id: I52ae8a49407009dd76ad5da3925355770bc25d0c
Change-Id: I99a77cb7332198bae84f28a00a6cc0409d5bf3b9
Signed-off-by: Rutherther <rutherther@ditigal.xyz>
Merges: #5217
252 lines
8.8 KiB
Scheme
252 lines
8.8 KiB
Scheme
;;; GNU Guix --- Functional package management for GNU
|
|
;;; Copyright © 2018 Mathieu Othacehe <m.othacehe@gmail.com>
|
|
;;; Copyright © 2019, 2020 Ludovic Courtès <ludo@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 newt network)
|
|
#:use-module (gnu installer connman)
|
|
#:use-module (gnu installer steps)
|
|
#:use-module (gnu installer utils)
|
|
#:use-module (gnu installer newt ethernet)
|
|
#:use-module (gnu installer newt page)
|
|
#:use-module (gnu installer newt wifi)
|
|
#:use-module (guix i18n)
|
|
#:use-module (srfi srfi-1)
|
|
#:use-module (srfi srfi-11)
|
|
#:use-module (srfi srfi-26)
|
|
#:use-module (srfi srfi-34)
|
|
#:use-module (srfi srfi-35)
|
|
#:use-module (ice-9 match)
|
|
#:use-module (web client)
|
|
#:use-module (web response)
|
|
#:use-module (newt)
|
|
#:export (run-network-page))
|
|
|
|
;; Maximum length of a technology name.
|
|
(define technology-name-max-length (make-parameter 20))
|
|
|
|
(define (technology->text technology)
|
|
"Return a string describing the given TECHNOLOGY."
|
|
(let* ((name (technology-name technology))
|
|
(padded-name (string-pad-right name
|
|
(technology-name-max-length))))
|
|
(format #f "~a~%" padded-name)))
|
|
|
|
(define (run-technology-page)
|
|
"Run a page to ask the user which technology shall be used to access
|
|
Internet and return the selected technology. For now, only technologies with
|
|
\"ethernet\" or \"wifi\" types are supported."
|
|
(define (technology-items)
|
|
(filter (lambda (technology)
|
|
(let ((type (technology-type technology)))
|
|
(or
|
|
(string=? type "ethernet")
|
|
(string=? type "wifi"))))
|
|
(connman-technologies)))
|
|
|
|
(match (technology-items)
|
|
(()
|
|
(case (choice-window
|
|
(G_ "Internet access")
|
|
(G_ "Continue")
|
|
(G_ "Exit")
|
|
(G_ "The install process requires Internet access but no \
|
|
network devices were found. Do you want to continue anyway?"))
|
|
((1) (abort-to-prompt 'installer-step 'break))
|
|
((2) (abort-to-prompt 'installer-step 'abort))))
|
|
((technology)
|
|
;; Since there's only one technology available, skip the selection
|
|
;; screen.
|
|
technology)
|
|
((items ...)
|
|
(run-listbox-selection-page
|
|
#:info-text (G_ "The install process requires Internet access.\
|
|
Please select a network device.")
|
|
#:title (G_ "Internet access")
|
|
#:listbox-items items
|
|
#:listbox-item->text technology->text
|
|
#:listbox-height (min (+ (length items) 2) 5)
|
|
#:button-text (G_ "Exit")
|
|
#:button-callback-procedure
|
|
(lambda _
|
|
(abort-to-prompt 'installer-step 'abort))))))
|
|
|
|
(define (find-technology-by-type technologies type)
|
|
"Find and return a technology with the given TYPE in TECHNOLOGIES list."
|
|
(find (lambda (technology)
|
|
(string=? (technology-type technology)
|
|
type))
|
|
technologies))
|
|
|
|
(define (wait-technology-powered technology)
|
|
"Wait and display a progress bar until the given TECHNOLOGY is powered."
|
|
(let ((name (technology-name technology))
|
|
(full-value 5))
|
|
(run-scale-page
|
|
#:title (G_ "Powering technology")
|
|
#:info-text (format #f (G_ "Waiting for technology ~a to be powered.")
|
|
name)
|
|
#:scale-full-value full-value
|
|
#:scale-update-proc
|
|
(lambda (value)
|
|
(let* ((technologies (connman-technologies))
|
|
(type (technology-type technology))
|
|
(updated-technology
|
|
(find-technology-by-type technologies type))
|
|
(technology-powered? updated-technology))
|
|
(sleep 1)
|
|
(if technology-powered?
|
|
full-value
|
|
(+ value 1)))))))
|
|
|
|
(define* (url-alive? url #:key (ensure-ok-status? #f))
|
|
(false-if-exception
|
|
(let ((response (http-request url)))
|
|
(or (not ensure-ok-status?)
|
|
(= (response-code response)
|
|
200)))))
|
|
|
|
(define* (common-urls-alive? urls #:key (ensure-ok-status? #f))
|
|
"Return #t if at least some of the given URLS are alive,
|
|
meaning that they do respond to a HTTP request. If ENSURE-OK-STATUS? is
|
|
#t, return #t only if the code is 200."
|
|
(dynamic-wind
|
|
(lambda ()
|
|
(sigaction SIGALRM
|
|
(lambda _ #f))
|
|
(alarm 3))
|
|
(lambda ()
|
|
(any (cut url-alive? <> #:ensure-ok-status? ensure-ok-status?)
|
|
urls))
|
|
(lambda ()
|
|
(alarm 0))))
|
|
|
|
(define (wait-service-online)
|
|
"Display a newt scale until connman detects an Internet access. Do
|
|
FULL-VALUE tentatives, spaced by 1 second."
|
|
(define (online?)
|
|
(or (and (connman-online?)
|
|
(common-urls-alive?
|
|
(list
|
|
"https://bordeaux.guix.gnu.org"
|
|
"https://ci.guix.gnu.org"
|
|
"https://guix.gnu.org"
|
|
"https://gnu.org")
|
|
;; Any HTTP response means the users is online.
|
|
#:ensure-ok-status? #f))
|
|
(file-exists? "/tmp/installer-assume-online")))
|
|
|
|
(let* ((full-value 5))
|
|
(run-scale-page
|
|
#:title (G_ "Checking connectivity")
|
|
#:info-text (G_ "Waiting for Internet access establishment...")
|
|
#:scale-full-value full-value
|
|
#:scale-update-proc
|
|
(lambda (value)
|
|
(sleep 1)
|
|
(if (online?)
|
|
full-value
|
|
(+ value 1))))
|
|
(unless (online?)
|
|
(case (choice-window
|
|
(G_ "Internet access")
|
|
(G_ "Continue")
|
|
(G_ "Try again?")
|
|
(G_ "
|
|
The selected network does not seem to provide access to the \
|
|
Internet. The install process requires Internet access. \
|
|
Do you want to continue anyway?"))
|
|
((2) (abort-to-prompt 'installer-step 'abort))))))
|
|
|
|
(define (check-substitute-availability)
|
|
"Check that at least one of the Guix substitute servers is available."
|
|
(define (substitutes-available?)
|
|
(or
|
|
(file-exists? "/tmp/installer-assume-online")
|
|
(common-urls-alive?
|
|
(list
|
|
"https://bordeaux.guix.gnu.org/nix-cache-info"
|
|
"https://ci.guix.gnu.org/nix-cache-info")
|
|
#:ensure-ok-status? #t)))
|
|
|
|
(let* ((full-value 5))
|
|
(run-scale-page
|
|
#:title (G_ "Checking substitutes")
|
|
#:info-text (G_ "Checking if Guix substitutes are available...")
|
|
#:scale-full-value full-value
|
|
#:scale-update-proc
|
|
(lambda (value)
|
|
(sleep 1)
|
|
(if (substitutes-available?)
|
|
full-value
|
|
(+ value 1))))
|
|
(unless (substitutes-available?)
|
|
(case (choice-window
|
|
(G_ "Substitute availability")
|
|
(G_ "Continue")
|
|
(G_ "Try again?")
|
|
(G_ "
|
|
None of the Guix substitute servers are available.
|
|
You can proceed with the install, but you will
|
|
have to build most of the packages you install locally."))
|
|
((2) (abort-to-prompt 'installer-step 'abort))))))
|
|
|
|
(define (run-network-page)
|
|
"Run a page to allow the user to configure connman so that it can access the
|
|
Internet."
|
|
(define network-steps
|
|
(list
|
|
;; Ask the user to choose between ethernet and wifi technologies.
|
|
(installer-step
|
|
(id 'select-technology)
|
|
(compute
|
|
(lambda _
|
|
(run-technology-page))))
|
|
;; Enable the previously selected technology.
|
|
(installer-step
|
|
(id 'power-technology)
|
|
(compute
|
|
(lambda (result _)
|
|
(let ((technology (result-step result 'select-technology)))
|
|
(connman-enable-technology technology)
|
|
(wait-technology-powered technology)))))
|
|
;; Propose the user to connect to one of the service available for the
|
|
;; previously selected technology.
|
|
(installer-step
|
|
(id 'connect-service)
|
|
(compute
|
|
(lambda (result _)
|
|
(let* ((technology (result-step result 'select-technology))
|
|
(type (technology-type technology)))
|
|
(cond
|
|
((string=? "wifi" type)
|
|
(run-wifi-page))
|
|
((string=? "ethernet" type)
|
|
(run-ethernet-page)))))))
|
|
;; Wait for connman status to switch to 'online, which means it can
|
|
;; access Internet.
|
|
(installer-step
|
|
(id 'wait-online)
|
|
(compute (lambda _
|
|
(wait-service-online))))
|
|
(installer-step
|
|
(id 'check-substitutes)
|
|
(compute (lambda _
|
|
(check-substitute-availability))))))
|
|
(run-installer-steps
|
|
#:steps network-steps
|
|
#:rewind-strategy 'start))
|