From 3dff90ce34448551bc82a6a7262837c0561a4691 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ludovic=20Court=C3=A8s?= Date: Fri, 21 Apr 2017 14:57:02 +0200 Subject: [PATCH] store: Add support for remote connections via 'guix://' URIs. * guix/store.scm (open-inet-socket): New procedure. (connect-to-daemon): Support the 'guix' URI scheme. * doc/guix.texi (The Store): Document it. --- doc/guix.texi | 13 +++++++++++++ guix/store.scm | 41 +++++++++++++++++++++++++++++++++++++++++ 2 files changed, 54 insertions(+) diff --git a/doc/guix.texi b/doc/guix.texi index 5f973e2fe1..8f646475e9 100644 --- a/doc/guix.texi +++ b/doc/guix.texi @@ -3683,6 +3683,19 @@ supported URI schemes are: These are for Unix-domain sockets. @code{file:///var/guix/daemon-socket/socket} is equivalent to @file{/var/guix/daemon-socket/socket}. + +@item guix +These URIs denote connections over TCP/IP, without encryption nor +authentication of the remote host. The URI must always specify both the +host name and port number: + +@example +guix://master.guix.example.org:1234 +@end example + +This setup is suitable on local networks, such as clusters, where only +trusted nodes may connect to the build daemon at +@code{master.guix.example.org}. @end table Additional URI schemes may be supported in the future. diff --git a/guix/store.scm b/guix/store.scm index 9eac22052e..752da98e37 100644 --- a/guix/store.scm +++ b/guix/store.scm @@ -375,6 +375,39 @@ (connect s a) s))) +(define (open-inet-socket host port) + "Connect to the Unix-domain socket at HOST:PORT and return it. Raise a +'&nix-connection-error' upon error." + (let ((sock (with-fluids ((%default-port-encoding #f)) + ;; This trick allows use of the `scm_c_read' optimization. + (socket PF_UNIX SOCK_STREAM 0)))) + (define addresses + (getaddrinfo host + (if (number? port) (number->string port) port) + (if (number? port) + (logior AI_ADDRCONFIG AI_NUMERICSERV) + AI_ADDRCONFIG))) + + (let loop ((addresses addresses)) + (match addresses + ((ai rest ...) + (let ((s (socket (addrinfo:fam ai) + ;; TCP/IP only + SOCK_STREAM IPPROTO_IP))) + + (catch 'system-error + (lambda () + (connect s (addrinfo:addr ai)) + s) + (lambda args + ;; Connection failed, so try one of the other addresses. + (close s) + (if (null? rest) + (raise (condition (&nix-connection-error + (file host) + (errno (system-error-errno args))))) + (loop rest)))))))))) + (define (connect-to-daemon uri) "Connect to the daemon at URI, a string that may be an actual URI or a file name." @@ -387,6 +420,14 @@ name." ((or #f 'file 'unix) (lambda (_) (open-unix-domain-socket (uri-path uri)))) + ('guix + (lambda (_) + (unless (uri-port uri) + (raise (condition (&nix-connection-error + (file (uri->string uri)) + (errno EBADR))))) ;bah! + + (open-inet-socket (uri-host uri) (uri-port uri)))) (x (raise (condition (&nix-connection-error (file (uri->string uri))