mirror of
https://codeberg.org/guix/guix.git
synced 2026-01-25 03:55:08 -06:00
services: secret-service: Fiberize ‘secret-service-send-secrets’.
The previous code was tentatively written to run either in a Fibers context or in a non-Fibers context. Drop the non-Fibers code since this always runs within ‘shepherd’, which is fiberized. * gnu/build/secret-service.scm (with-modules): Remove. (wait-for-readable-fd): Rewrite using regular Fibers operations. (secret-service-send-secrets): Use ‘SOCK_NONBLOCK’. Simplify ‘sleep’ binding. Change-Id: Ic05d0bc54e6d2df89b6602bc716402067c845792
This commit is contained in:
parent
9db8fe9779
commit
9de6ed0a7e
1 changed files with 19 additions and 48 deletions
|
|
@ -1,5 +1,5 @@
|
|||
;;; GNU Guix --- Functional package management for GNU
|
||||
;;; Copyright © 2020-2023 Ludovic Courtès <ludo@gnu.org>
|
||||
;;; Copyright © 2020-2023, 2025 Ludovic Courtès <ludo@gnu.org>
|
||||
;;; Copyright © 2020 Jan (janneke) Nieuwenhuizen <janneke@gnu.org>
|
||||
;;;
|
||||
;;; This file is part of GNU Guix.
|
||||
|
|
@ -18,8 +18,12 @@
|
|||
;;; along with GNU Guix. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
(define-module (gnu build secret-service)
|
||||
#:autoload (fibers io-wakeup) (wait-until-port-readable-operation)
|
||||
#:autoload (fibers operations) (perform-operation
|
||||
choice-operation
|
||||
wrap-operation)
|
||||
#:autoload (fibers timers) (sleep-operation)
|
||||
#:use-module (guix build utils)
|
||||
|
||||
#:use-module (srfi srfi-26)
|
||||
#:use-module (rnrs bytevectors)
|
||||
#:use-module (ice-9 binary-ports)
|
||||
|
|
@ -33,6 +37,9 @@
|
|||
;;;
|
||||
;;; Utility procedures for copying secrets into a VM.
|
||||
;;;
|
||||
;;; Note: This code runs within the 'shepherd' process, hence the use of
|
||||
;;; Fibers.
|
||||
;;;
|
||||
;;; Code:
|
||||
|
||||
(define-syntax log
|
||||
|
|
@ -47,51 +54,15 @@
|
|||
;; to syslog.
|
||||
#'(format (current-output-port) fmt args ...))))))
|
||||
|
||||
(define-syntax with-modules
|
||||
(syntax-rules ()
|
||||
"Dynamically load the given MODULEs at run time, making the chosen
|
||||
bindings available within the lexical scope of BODY."
|
||||
((_ ((module #:select (bindings ...)) rest ...) body ...)
|
||||
(let* ((iface (resolve-interface 'module))
|
||||
(bindings (module-ref iface 'bindings))
|
||||
...)
|
||||
(with-modules (rest ...) body ...)))
|
||||
((_ () body ...)
|
||||
(begin body ...))))
|
||||
|
||||
(define (wait-for-readable-fd port timeout)
|
||||
"Wait until PORT has data available for reading or TIMEOUT has expired.
|
||||
Return #t in the former case and #f in the latter case."
|
||||
(match (resolve-module '(fibers) #f #:ensure #f) ;using Fibers?
|
||||
(#f
|
||||
(log "blocking on socket...~%")
|
||||
(match (select (list port) '() '() timeout)
|
||||
(((_) () ()) #t)
|
||||
((() () ()) #f)))
|
||||
(fibers
|
||||
;; We're running on the Shepherd 0.9+ with Fibers. Arrange to make a
|
||||
;; non-blocking wait so that other fibers can be scheduled in while we
|
||||
;; wait for PORT.
|
||||
(with-modules (((fibers) #:select (spawn-fiber sleep))
|
||||
((fibers channels)
|
||||
#:select (make-channel put-message get-message)))
|
||||
;; Make PORT non-blocking.
|
||||
(let ((flags (fcntl port F_GETFL)))
|
||||
(fcntl port F_SETFL (logior O_NONBLOCK flags)))
|
||||
|
||||
(let ((channel (make-channel)))
|
||||
(spawn-fiber
|
||||
(lambda ()
|
||||
(sleep timeout) ;suspends the fiber
|
||||
(put-message channel 'timeout)))
|
||||
(spawn-fiber
|
||||
(lambda ()
|
||||
(lookahead-u8 port) ;suspends the fiber
|
||||
(put-message channel 'readable)))
|
||||
(log "suspending fiber on socket...~%")
|
||||
(match (get-message channel)
|
||||
('readable #t)
|
||||
('timeout #f)))))))
|
||||
(perform-operation
|
||||
(choice-operation
|
||||
(wrap-operation (wait-until-port-readable-operation port)
|
||||
(const #t))
|
||||
(wrap-operation (sleep-operation timeout)
|
||||
(const #f)))))
|
||||
|
||||
(define (socket-address->string address)
|
||||
"Return a human-readable representation of ADDRESS, an object as returned by
|
||||
|
|
@ -135,10 +106,10 @@ HANDSHAKE-TIMEOUT seconds for handshake to complete. Return #f on failure."
|
|||
|
||||
(log "sending secrets to ~a~%" (socket-address->string address))
|
||||
|
||||
(let ((sock (socket AF_INET (logior SOCK_CLOEXEC SOCK_STREAM) 0))
|
||||
(sleep (if (resolve-module '(fibers) #f)
|
||||
(module-ref (resolve-interface '(fibers)) 'sleep)
|
||||
sleep)))
|
||||
(let ((sock (socket AF_INET
|
||||
(logior SOCK_CLOEXEC SOCK_NONBLOCK SOCK_STREAM)
|
||||
0))
|
||||
(sleep (module-ref (resolve-interface '(fibers)) 'sleep)))
|
||||
;; Connect to QEMU on the forwarded port. The 'connect' call succeeds as
|
||||
;; soon as QEMU is ready, even if there's no server listening on the
|
||||
;; forward port inside the guest.
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue