summaryrefslogtreecommitdiff
path: root/guix/ssh.scm
diff options
context:
space:
mode:
Diffstat (limited to 'guix/ssh.scm')
-rw-r--r--guix/ssh.scm85
1 files changed, 69 insertions, 16 deletions
diff --git a/guix/ssh.scm b/guix/ssh.scm
index 3548243839..4fb145230d 100644
--- a/guix/ssh.scm
+++ b/guix/ssh.scm
@@ -1,5 +1,5 @@
;;; GNU Guix --- Functional package management for GNU
-;;; Copyright © 2016 Ludovic Courtès <ludo@gnu.org>
+;;; Copyright © 2016, 2017 Ludovic Courtès <ludo@gnu.org>
;;;
;;; This file is part of GNU Guix.
;;;
@@ -18,7 +18,10 @@
(define-module (guix ssh)
#:use-module (guix store)
- #:autoload (guix ui) (N_)
+ #:use-module ((guix ui) #:select (G_ N_))
+ #:use-module (ssh session)
+ #:use-module (ssh auth)
+ #:use-module (ssh key)
#:use-module (ssh channel)
#:use-module (ssh popen)
#:use-module (ssh session)
@@ -29,7 +32,9 @@
#:use-module (srfi srfi-35)
#:use-module (ice-9 match)
#:use-module (ice-9 binary-ports)
- #:export (connect-to-remote-daemon
+ #:export (open-ssh-session
+ remote-daemon-channel
+ connect-to-remote-daemon
send-files
retrieve-files
remote-store-host
@@ -43,11 +48,52 @@
;;;
;;; Code:
-(define* (connect-to-remote-daemon session
- #:optional
- (socket-name "/var/guix/daemon-socket/socket"))
- "Connect to the remote build daemon listening on SOCKET-NAME over SESSION,
-an SSH session. Return a <nix-server> object."
+(define %compression
+ "zlib@openssh.com,zlib")
+
+(define* (open-ssh-session host #:key user port
+ (compression %compression))
+ "Open an SSH session for HOST and return it. When USER and PORT are #f, use
+default values or whatever '~/.ssh/config' specifies; otherwise use them.
+Throw an error on failure."
+ (let ((session (make-session #:user user
+ #:host host
+ #:port port
+ #:timeout 10 ;seconds
+ ;; #:log-verbosity 'protocol
+
+ ;; We need lightweight compression when
+ ;; exchanging full archives.
+ #:compression compression
+ #:compression-level 3)))
+
+ ;; Honor ~/.ssh/config.
+ (session-parse-config! session)
+
+ (match (connect! session)
+ ('ok
+ ;; Use public key authentication, via the SSH agent if it's available.
+ (match (userauth-public-key/auto! session)
+ ('success
+ session)
+ (x
+ (disconnect! session)
+ (raise (condition
+ (&message
+ (message (format #f (G_ "SSH authentication failed for '~a': ~a~%")
+ host (get-error session)))))))))
+ (x
+ ;; Connection failed or timeout expired.
+ (raise (condition
+ (&message
+ (message (format #f (G_ "SSH connection to '~a' failed: ~a~%")
+ host (get-error session))))))))))
+
+(define* (remote-daemon-channel session
+ #:optional
+ (socket-name
+ "/var/guix/daemon-socket/socket"))
+ "Return an input/output port (an SSH channel) to the daemon at SESSION."
(define redirect
;; Code run in SESSION to redirect the remote process' stdin/stdout to the
;; daemon's socket, à la socat. The SSH protocol supports forwarding to
@@ -82,13 +128,20 @@ an SSH session. Return a <nix-server> object."
(_
(primitive-exit 1)))))))
- (let ((channel
- (open-remote-pipe* session OPEN_BOTH
- ;; Sort-of shell-quote REDIRECT.
- "guile" "-c"
- (object->string
- (object->string redirect)))))
- (open-connection #:port channel)))
+ (open-remote-pipe* session OPEN_BOTH
+ ;; Sort-of shell-quote REDIRECT.
+ "guile" "-c"
+ (object->string
+ (object->string redirect))))
+
+(define* (connect-to-remote-daemon session
+ #:optional
+ (socket-name
+ "/var/guix/daemon-socket/socket"))
+ "Connect to the remote build daemon listening on SOCKET-NAME over SESSION,
+an SSH session. Return a <nix-server> object."
+ (open-connection #:port (remote-daemon-channel session)))
+
(define (store-import-channel session)
"Return an output port to which archives to be exported to SESSION's store
@@ -216,7 +269,7 @@ LOCAL. When RECURSIVE? is true, retrieve the closure of FILES."
(&message
(message
(format #f
- (_ "failed to retrieve store items from '~a'")
+ (G_ "failed to retrieve store items from '~a'")
(remote-store-host remote)))))))
(let ((result (import-paths local port)))