~ruther/guix-local

3dff90ce34448551bc82a6a7262837c0561a4691 — Ludovic Courtès 9 years ago 3b5cd17
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.
2 files changed, 54 insertions(+), 0 deletions(-)

M doc/guix.texi
M guix/store.scm
M doc/guix.texi => doc/guix.texi +13 -0
@@ 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.

M guix/store.scm => guix/store.scm +41 -0
@@ 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))