summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLudovic Courtès <ludovic.courtes@inria.fr>2017-04-21 14:57:02 +0200
committerLudovic Courtès <ludo@gnu.org>2017-04-21 17:23:37 +0200
commit3dff90ce34448551bc82a6a7262837c0561a4691 (patch)
tree7eced926e6a28156e1694525b57e5d0982d0aa21
parent3b5cd17a975d18ec200fa8cb835bcb58d3a61af8 (diff)
downloadgnu-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.texi13
-rw-r--r--guix/store.scm41
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))