aboutsummaryrefslogtreecommitdiff
path: root/gnu/installer/utils.scm
blob: 5f8fe8ca01974b149f6b4bfd7574b5c65ad0ecd3 (about) (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
;;; GNU Guix --- Functional package management for GNU
;;; Copyright © 2018, 2020 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 utils)
  #:use-module (guix utils)
  #:use-module (guix build utils)
  #:use-module (guix i18n)
  #:use-module (srfi srfi-1)
  #:use-module (srfi srfi-34)
  #:use-module (ice-9 match)
  #:use-module (ice-9 rdelim)
  #:use-module (ice-9 regex)
  #:use-module (ice-9 format)
  #:use-module (ice-9 textual-ports)
  #:export (read-lines
            read-all
            nearest-exact-integer
            read-percentage
            run-command

            syslog-port
            syslog

            with-server-socket
            current-server-socket
            current-clients
            send-to-clients))

(define* (read-lines #:optional (port (current-input-port)))
  "Read lines from PORT and return them as a list."
  (let loop ((line (read-line port))
             (lines '()))
    (if (eof-object? line)
        (reverse lines)
        (loop (read-line port)
              (cons line lines)))))

(define (read-all file)
  "Return the content of the given FILE as a string."
  (call-with-input-file file
    get-string-all))

(define (nearest-exact-integer x)
  "Given a real number X, return the nearest exact integer, with ties going to
the nearest exact even integer."
  (inexact->exact (round x)))

(define (read-percentage percentage)
  "Read PERCENTAGE string and return the corresponding percentage as a
number. If no percentage is found, return #f"
  (let ((result (string-match "^([0-9]+)%$" percentage)))
    (and result
         (string->number (match:substring result 1)))))

(define* (run-command command #:key locale)
  "Run COMMAND, a list of strings, in the given LOCALE.  Return true if
COMMAND exited successfully, #f otherwise."
  (define env (environ))

  (define (pause)
    (format #t (G_ "Press Enter to continue.~%"))
    (send-to-clients '(pause))
    (environ env)                               ;restore environment variables
    (match (select (cons (current-input-port) (current-clients))
             '() '())
      (((port _ ...) _ _)
       (read-line port))))

  (setenv "PATH" "/run/current-system/profile/bin")

  (when locale
    (let ((supported? (false-if-exception
                       (setlocale LC_ALL locale))))
      ;; If LOCALE is not supported, then set LANGUAGE, which might at
      ;; least give us translated messages.
      (if supported?
          (setenv "LC_ALL" locale)
          (setenv "LANGUAGE"
                  (string-take locale
                               (or (string-index locale #\_)
                                   (string-length locale)))))))

  (guard (c ((invoke-error? c)
             (newline)
             (format (current-error-port)
                     (G_ "Command failed with exit code ~a.~%")
                     (invoke-error-exit-status c))
             (syslog "command ~s failed with exit code ~a"
                     command (invoke-error-exit-status c))
             (pause)
             #f))
    (syslog "running command ~s~%" command)
    (apply invoke command)
    (syslog "command ~s succeeded~%" command)
    (newline)
    (pause)
    #t))


;;;
;;; Logging.
;;;

(define (open-syslog-port)
  "Return an open port (a socket) to /dev/log or #f if that wasn't possible."
  (let ((sock (socket AF_UNIX SOCK_DGRAM 0)))
    (catch 'system-error
      (lambda ()
        (connect sock AF_UNIX "/dev/log")
        (setvbuf sock 'line)
        sock)
      (lambda args
        (close-port sock)
        #f))))

(define syslog-port
  (let ((port #f))
    (lambda ()
      "Return an output port to syslog."
      (unless port
        (set! port (open-syslog-port)))
      (or port (%make-void-port "w")))))

(define-syntax syslog
  (lambda (s)
    "Like 'format', but write to syslog."
    (syntax-case s ()
      ((_ fmt args ...)
       (string? (syntax->datum #'fmt))
       (with-syntax ((fmt (string-append "installer[~d]: "
                                         (syntax->datum #'fmt))))
         #'(format (syslog-port) fmt (getpid) args ...))))))


;;;
;;; Client protocol.
;;;

(define %client-socket-file
  ;; Unix-domain socket where the installer accepts connections.
  "/var/guix/installer-socket")

(define current-server-socket
  ;; Socket on which the installer is currently accepting connections, or #f.
  (make-parameter #f))

(define current-clients
  ;; List of currently connected clients.
  (make-parameter '()))

(define* (open-server-socket
          #:optional (socket-file %client-socket-file))
  "Open SOCKET-FILE as a Unix-domain socket to accept incoming connections and
return it."
  (mkdir-p (dirname socket-file))
  (when (file-exists? socket-file)
    (delete-file socket-file))
  (let ((sock (socket AF_UNIX SOCK_STREAM 0)))
    (bind sock AF_UNIX socket-file)
    (listen sock 0)
    sock))

(define (call-with-server-socket thunk)
  (if (current-server-socket)
      (thunk)
      (let ((socket (open-server-socket)))
        (dynamic-wind
          (const #t)
          (lambda ()
            (parameterize ((current-server-socket socket))
              (thunk)))
          (lambda ()
            (close-port socket))))))

(define-syntax-rule (with-server-socket exp ...)
  "Evaluate EXP with 'current-server-socket' parameterized to a currently
accepting socket."
  (call-with-server-socket (lambda () exp ...)))

(define* (send-to-clients exp)
  "Send EXP to all the current clients."
  (define remainder
    (fold (lambda (client remainder)
            (catch 'system-error
              (lambda ()
                (write exp client)
                (newline client)
                (force-output client)
                (cons client remainder))
              (lambda args
                ;; We might get EPIPE if the client disconnects; when that
                ;; happens, remove CLIENT from the set of available clients.
                (let ((errno (system-error-errno args)))
                  (if (memv errno (list EPIPE ECONNRESET ECONNABORTED))
                      (begin
                        (syslog "removing client ~s due to ~s while replying~%"
                                (fileno client) (strerror errno))
                        (false-if-exception (close-port client))
                        remainder)
                      (cons client remainder))))))
          '()
          (current-clients)))

  (current-clients (reverse remainder))
  exp)
d30dfd4602 2024-07-18gnu: kwindowsystem: Update to 6.3.0.Zheng Junjie * gnu/packages/kde-frameworks.scm (kwindowsystem): Update to 6.3.0. [inputs]: Remove libxrender, qtbase-5, and qtx11extras; add qtbase, qtdeclarative, qtwayland, wayland-protocols, plasma-wayland-protocols, libxkbcommon, and wayland. [native-inputs]: Remove qttools-5; add wayland and qttools. [arguments]: Adjust check phase. Change-Id: Iad2482d91f037a2a178c5d257c140b904425f84b 2024-07-18gnu: kdnssd: Update to 6.3.0.Zheng Junjie * gnu/packages/kde-frameworks.scm (kdnssd): Update to 6.3.0. [inputs]: Remove qtbase-5; add qtbase. [native-inputs]: Remove qttools-5; add qttools. Change-Id: I2ab53069391f90c43e4ba0bd3176daa132f2a974 2024-07-18gnu: kdbusaddons: Update to 6.3.0.Zheng Junjie * gnu/packages/kde-frameworks.scm (kdbusaddons): Update to 6.3.0. [build-system]: Switch to qt-build-system. [arguments]: Remove patch-source phase; Adjust check phase. [inputs]: Remove qtbase-5, qtx11extras, and kinit-bootstrap; add libxkbcommon. [native-inputs]: Remove qttools-5; add qttools. Change-Id: I57fccc3693997cce92f5c42bb04525dd5a4beb4a 2024-07-18gnu: kcoreaddons: Update to 6.3.0.Zheng Junjie * gnu/packages/kde-frameworks.scm (kcoreaddons): Update to 6.3.0. [arguments]: Set #:qtbase to qtbase. [inputs]: Remove qtbase-5; add qtdeclarative. [native-inputs]: Remove qttools-5; add qttools. Change-Id: I0de3532e4401ec0cdf06dd9b36f5988820497547 2024-07-18gnu: kconfig: Update to 6.3.0.Zheng Junjie * gnu/packages/kde-frameworks.scm (kconfig): Update to 6.3.0. [build-system]: Switch qt-build-system. [arguments]: Set #:qtbase to qtbase; Stop replace check phase; Add check-setup phase. [inputs]: Remove qtbase-5 and qtdeclarative-5. [propagated-inputs]: Add qtdeclarative. [native-inputs]: Remove qttools-5 and xorg-server-for-tests; add qttools. Change-Id: I261f331083b1303387716d681de538e1b2943ef7 2024-07-18gnu: ksyntaxhighlighting: Update to 6.3.0.Zheng Junjie * gnu/packages/kde-frameworks.scm (ksyntaxhighlighting): Update to 6.3.0. [inputs]: Remove qtbase-5; add qtbase and qtdeclarative. [native-inputs]: Remove qttools-5 and qtxmlpatterns; add qttools. [arguments]: Use Gexps. Change-Id: Ica428e212c8f53125eb68abb234fc84459923a63 2024-07-18gnu: kplotting: Update to 6.3.0.Zheng Junjie * gnu/packages/kde-frameworks.scm (kplotting): Update to 6.3.0. [arguments]: Set #:qtbase to qtbase. [inputs]: Remove qtbase-5. [native-inputs]: Remove qttools-5; add qttools. Change-Id: I23f74f78bfce980164cefcf57eafe7e767e51968 2024-07-18gnu: kitemviews: Update to 6.3.0.Zheng Junjie * gnu/packages/kde-frameworks.scm (kitemviews): Update to 6.3.0. [arguments]: Set #:qtbase to qtbase. [inputs]: Remove qtbase-5. [native-inputs]: Remove qttools-5; add qttools. Change-Id: I595c2af5256a408856eb95208a1891ec7efd9619 2024-07-18gnu: kitemmodels: Update to 6.3.0.Zheng Junjie * gnu/packages/kde-frameworks.scm (kitemmodels): Update to 6.3.0. [arguments]: Set #:qtbase to qtbase. [inputs]: Remove qtbase-5 and qtdeclarative-5; add qtdeclarative. Change-Id: I9d97e80f4121b8ed628ae6d8eb5b66baf87203f0 2024-07-18gnu: kidletime: Update to 6.3.0.Zheng Junjie * gnu/packages/kde-frameworks.scm (kidletime): Update to 6.3.0. [inputs]: Remove libxscrnsaver, qtbase-5, and qtx11extras; add qtbase, qtwayland, wayland, plasma-wayland-protocols, wayland-protocols, and libxkbcommon. [native-inputs]: Add wayland. Change-Id: Iee27d9f4845e0275c9cd0e6194e83e650fb7208a 2024-07-18gnu: ki18n: Update to 6.3.0.Zheng Junjie * gnu/packages/kde-frameworks.scm (ki18n): Update to 6.3.0. [inputs]: Remove qtbase-5, qtdeclarative-5, and qtscript; add qtbase and qtdeclarative. [propagated-inputs]: Remove python. [native-inputs]: Add python-minimal and tzdata-for-tests. Change-Id: I9f56cf8ce339a55b48e3ebbde439e096d0a6c01d 2024-07-18gnu: kholidays: Update to 6.3.0.Zheng Junjie * gnu/packages/kde-frameworks.scm (kholidays): Update to 6.3.0. [inputs]: Remove qtbase-5 and qtdeclarative-5; add qtbase and qtdeclarative. [native-inputs]: Remove qttools-5; add qttools. Change-Id: I0ecf1de7d90390add08354467c6f1d7fb0c286f5 2024-07-18gnu: kwidgetsaddons: Update to 6.3.0.Zheng Junjie * gnu/packages/kde-frameworks.scm (kwidgetsaddons): Update to 6.3.0. [inputs]: Remove qtbase-5. [native-inputs]: Remove qttools-5 and xorg-server-for-tests; add qttools. [arguments]: Set #:qtbase to qtbase; Adjust check phase. Change-Id: Iae4756899cb52008b9306cf6b8b1dae3368532d3 2024-07-18gnu: kguiaddons: Update to 6.3.0.Zheng Junjie * gnu/packages/kde-frameworks.scm (kguiaddons): Update to 6.3.0. [arguments]: Set #:qtbase to qtbase. [inputs]: Remove qtbase-5, qtwayland-5, and qtx11extras; add libxkbcommon, and qtwayland. Change-Id: I5aea035983536fa10bd5333323bbbc8e56b3ae8d 2024-07-18gnu: plasma-wayland-protocols: Update to 1.13.0.Zheng Junjie * gnu/packages/kde-frameworks.scm (plasma-wayland-protocols): Update to 1.13.0. Change-Id: I7b70beee48d15b3802cd81eba3bc885ab9bc4a9d 2024-07-18gnu: kcodecs: Update to 6.3.0.Zheng Junjie * gnu/packages/kde-frameworks.scm (kcodecs): Update to 6.3.0. [inputs]: Remove qtbase-5; add qtbase. [native-inputs]: Remove qttools-5; add qttools. Change-Id: I8444feaa9510d313c769b766c1d22e4e6b735467 2024-07-18gnu: kcalendarcore: Update to 6.3.0.Zheng Junjie * gnu/packages/kde-frameworks.scm (kcalendarcore): Update to 6.3.0. [arguments]: Remove 'disable-failing-test phase. [inputs]: Remove qtbase-5; add qtbase. Change-Id: I34f2bfaefef5e709e69779af41c532fd61adcdf9 2024-07-18gnu: karchive: Update to 6.3.0.Zheng Junjie * gnu/packages/kde-frameworks.scm (karchive): Update to 6.3.0. [inputs]: Remove qtbase-5; add qtbase. [native-inputs]: Remove qttools-5; add qttools. [synopsis]: Adjust it. Change-Id: I159efc5f824b2aac034b8f34cec0c1e339580591 2024-07-18gnu: breeze-icons: Update to 6.3.0.Zheng Junjie * gnu/packages/kde-frameworks.scm (breeze-icons): Update to 6.3.0. [inputs]: Remove qtbase-5; add qtbase. [synopsis]: Adjust it. [description]: Adjust it. Change-Id: I5b6110f2c689c7328f98936cbbcc268a64554e04 2024-07-18gnu: bluez-qt: Update to 6.3.0.Zheng Junjie * gnu/packages/kde-frameworks.scm (bluez-qt): Update to 6.3.0. [inputs]: Remove qtdeclarative-5 and qtbase-5; add qtdeclarative and qtbase. Change-Id: Ic1e492d30e42c0bf460667a41a3ccd84e36ef698 2024-07-18gnu: attica: Update to 6.3.0.Zheng Junjie * gnu/packages/kde-frameworks.scm (attica): Update to 6.3.0. [inputs]: Remove qtbase-5; add qtbase. Change-Id: I9ad66984147838b748e45a8f64db6a045aec70a5 2024-07-18gnu: phonon: Enable qt6.Zheng Junjie * gnu/packages/kde-frameworks.scm (phonon): Enable qt6. [arguments]: Remove "-DPHONON_BUILD_QT6=OFF". <#:phases>: Remove patch-installdir phase. [inputs]: Add qtbase and qt5compat. [native-inputs]: Remove qttools-5; add qttools. Change-Id: Ie9421f5d1f8191fe1d600bc71fdb8a318fa92ca1 2024-07-18gnu: kquickcharts: Update to 6.3.0.Zheng Junjie * gnu/packages/kde-frameworks.scm (kquickcharts): Update to 6.3.0. [arguments]: Stop replace check phase; Set #:qtbase to qtbase. [inputs]: Remove qtbase-5, qtdeclarative-5, qtquickcontrols2-5, and xorg-server-for-tests; add qtdeclarative and qtshadertools. Change-Id: I37389d7e7944e3a7e46bd1b58165dd63c046249d 2024-07-18gnu: extra-cmake-modules: Update to 6.3.0.Zheng Junjie * gnu/packages/kde-frameworks.scm (extra-cmake-modules): Update to 6.3.0. [arguments]<#:phases>: Adjust fix-test phase. Change-Id: I61fbd6814a740a3596d64443bcde0a5af903e5c8 2024-05-01gnu: Add phonon-backend-vlc.Sughosha via Guix-patches via * gnu/packages/kde-frameworks.scm (phonon-plugin-vlc): New variable. Change-Id: I5a680d55782cbfcd6349efc64cce36457f456377 Signed-off-by: Zheng Junjie <zhengjunjie@iscas.ac.cn>