diff options
author | Ludovic Courtès <ludovic.courtes@inria.fr> | 2017-04-21 14:57:02 +0200 |
---|---|---|
committer | Ludovic Courtès <ludo@gnu.org> | 2017-04-21 17:23:37 +0200 |
commit | 3dff90ce34448551bc82a6a7262837c0561a4691 (patch) | |
tree | 7eced926e6a28156e1694525b57e5d0982d0aa21 | |
parent | 3b5cd17a975d18ec200fa8cb835bcb58d3a61af8 (diff) | |
download | gnu-guix-3dff90ce34448551bc82a6a7262837c0561a4691.tar gnu-guix-3dff90ce34448551bc82a6a7262837c0561a4691.tar.gz |
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.
-rw-r--r-- | doc/guix.texi | 13 | ||||
-rw-r--r-- | guix/store.scm | 41 |
2 files changed, 54 insertions, 0 deletions
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)) |