RSS Feed

Lisp Project of the Day

trivial-ssh

You can support this project by donating at:

Donate using PatreonDonate using Liberapay

trivial-sshsystemnetwork

Documentation🥺
Docstrings🤨
Tests 🤨
Examples😀
RepositoryActivity🥺
CI 😀

This system is a simple wrapper around cl-libssh2 which is binding to the libssh2. Trivial SSH provides a few macros to safely establish a connection, open and close streams.

In the next example we'll connect to the host and run two commands to get its hostname and OS description:

;; Make this before Quickloading the system:
;; brew upgrade libssh2

POFTHEDAY> (flet ((read-lines (s)
                    (loop for line = (read-line s nil nil)
                          while line
                          collect line)))

             (ssh:with-connection (conn "134.209.21.115" (ssh:agent "root"))
               (values
                (ssh:with-command (conn iostream "hostname -f")
                                  (read-lines iostream))
                (ssh:with-command (conn iostream "lsb_release --id --release --codename")
                                  (read-lines iostream)))))
("my-lovely-host.inter.net")
("Distributor ID:	Ubuntu"
 "Release:	18.04"
 "Codename:	bionic")

Also, there is are commands to upload and download files using SCP protocol. Here is how we can copy the bootstrap file to the host and execute it:

POFTHEDAY> (ssh:with-connection (conn "134.209.21.115" (ssh:agent "root"))
               (ssh:upload-file conn "install.sh" "/tmp/install.sh")
               (ssh:with-command (conn stream "chmod +x /tmp/install.sh"))
                 (ssh:with-command (conn stream "/tmp/install.sh")))

The cool part of with-command macro is that you have a communication stream and can read output during the command execution. Here we are installing Emacs on the remote host and can observe the process:

Here is the code from this sample:

POFTHEDAY> (flet ((-> (from to)
                    (loop for line = (read-line from nil nil)
                       while line
                       do (write-string line to)
                          (terpri))))
             (ssh:with-connection (conn "134.209.21.115"
                                        (ssh:agent "root"))
               (ssh:with-command
                   (conn stream "apt-get update &&
                                apt-get install -y emacs-nox")
                   (-> stream *standard-output*))))

Update

Found that cl-libssh2 does not support agent forwarding. Because of that, I'm not able to call git pull on the remote machine.

I tried to patch cl-libssh2 to support the latest libssh2 where agent forwarding was supported in August 2019, but this patch does not work yet.

If somebody is interested to help me with that, he might try this pull-request:

https://github.com/alxchk/cl-libssh2/pull/7


Brought to you by 40Ants under Creative Commons License