All of lore.kernel.org
 help / color / mirror / Atom feed
* [Buildroot] [PATCH v2 0/5] download: Add SFTP support and tests
@ 2020-04-15 16:48 Thomas Preston
  2020-04-15 16:48 ` [Buildroot] [PATCH v2 1/5] support/docker: Update to debian:buster-20200327 Thomas Preston
                   ` (5 more replies)
  0 siblings, 6 replies; 7+ messages in thread
From: Thomas Preston @ 2020-04-15 16:48 UTC (permalink / raw)
  To: buildroot

Hi,
Back in October 2019 I submitted a patch adding an SFTP download method
to Buildroot, however since there were no packages using SFTP the patch
was rejected.

Yann E. MORIN suggested that it was a valid change however it required
tests to avoid bitrot - since there was no way to verify the SFTP
download method did not break over time without any packages using it.

In this series I have re-added the SFTP download method and also some
test infrastructure which starts a local SSH server and uses SFTP to
download some test packages in a br2-external project. I've also added
tests for SCP! :D

For this, I had to update the Dockerfile from Debian Stretch to Buster
which I explain a bit further in the patch. I'm not sure how to test if
this breaks anything else. Will all the tests run in a clean container +
Buildroot project clone?

You can run the tests like so:

	support/testing/run-tests -o output -d dl \
		tests.download.test_ssh.TestSFTP \
		tests.download.test_ssh.TestSCP

Thanks!
Thomas

Thomas Preston (5):
  support/docker: Update to debian:buster-20200327
  support/docker: Add openssh-server
  testing/infra: Add docstrings to base test classes
  download: Add SFTP support (not FTPS)
  support/testing: Add download tests for SCP/SFTP

 .gitlab-ci.yml                                |   2 +
 Config.in                                     |   4 +
 package/pkg-download.mk                       |   1 +
 support/docker/Dockerfile                     |   3 +-
 support/docker/apt-sources.list               |   8 +-
 support/download/dl-wrapper                   |   2 +-
 support/download/sftp                         |  37 +++++
 support/testing/infra/basetest.py             |   2 +
 .../tests/download/br2-external/scp/Config.in |   0
 .../download/br2-external/scp/external.desc   |   1 +
 .../download/br2-external/scp/external.mk     |   4 +
 .../scp/package/scp-bad/scp-bad.hash          |   1 +
 .../scp/package/scp-bad/scp-bad.mk            |  17 +++
 .../scp/package/scp-good/scp-good.hash        |   1 +
 .../scp/package/scp-good/scp-good.mk          |  17 +++
 .../scp/package/scp-nohash/scp-nohash.mk      |  17 +++
 .../download/br2-external/sftp/Config.in      |   0
 .../download/br2-external/sftp/external.desc  |   1 +
 .../download/br2-external/sftp/external.mk    |   4 +
 .../sftp/package/sftp-bad/sftp-bad.hash       |   1 +
 .../sftp/package/sftp-bad/sftp-bad.mk         |  17 +++
 .../sftp/package/sftp-good/sftp-good.hash     |   1 +
 .../sftp/package/sftp-good/sftp-good.mk       |  17 +++
 .../sftp/package/sftp-nohash/sftp-nohash.mk   |  17 +++
 support/testing/tests/download/sshd.py        | 129 ++++++++++++++++++
 .../tests/download/sshd/ssh-test-1.0.tar.xz   | Bin 0 -> 232 bytes
 support/testing/tests/download/test_ssh.py    |  66 +++++++++
 27 files changed, 364 insertions(+), 6 deletions(-)
 create mode 100755 support/download/sftp
 create mode 100644 support/testing/tests/download/br2-external/scp/Config.in
 create mode 100644 support/testing/tests/download/br2-external/scp/external.desc
 create mode 100644 support/testing/tests/download/br2-external/scp/external.mk
 create mode 100644 support/testing/tests/download/br2-external/scp/package/scp-bad/scp-bad.hash
 create mode 100644 support/testing/tests/download/br2-external/scp/package/scp-bad/scp-bad.mk
 create mode 100644 support/testing/tests/download/br2-external/scp/package/scp-good/scp-good.hash
 create mode 100644 support/testing/tests/download/br2-external/scp/package/scp-good/scp-good.mk
 create mode 100644 support/testing/tests/download/br2-external/scp/package/scp-nohash/scp-nohash.mk
 create mode 100644 support/testing/tests/download/br2-external/sftp/Config.in
 create mode 100644 support/testing/tests/download/br2-external/sftp/external.desc
 create mode 100644 support/testing/tests/download/br2-external/sftp/external.mk
 create mode 100644 support/testing/tests/download/br2-external/sftp/package/sftp-bad/sftp-bad.hash
 create mode 100644 support/testing/tests/download/br2-external/sftp/package/sftp-bad/sftp-bad.mk
 create mode 100644 support/testing/tests/download/br2-external/sftp/package/sftp-good/sftp-good.hash
 create mode 100644 support/testing/tests/download/br2-external/sftp/package/sftp-good/sftp-good.mk
 create mode 100644 support/testing/tests/download/br2-external/sftp/package/sftp-nohash/sftp-nohash.mk
 create mode 100644 support/testing/tests/download/sshd.py
 create mode 100644 support/testing/tests/download/sshd/ssh-test-1.0.tar.xz
 create mode 100755 support/testing/tests/download/test_ssh.py

-- 
2.20.1

^ permalink raw reply	[flat|nested] 7+ messages in thread

* [Buildroot] [PATCH v2 1/5] support/docker: Update to debian:buster-20200327
  2020-04-15 16:48 [Buildroot] [PATCH v2 0/5] download: Add SFTP support and tests Thomas Preston
@ 2020-04-15 16:48 ` Thomas Preston
  2020-04-15 16:48 ` [Buildroot] [PATCH v2 2/5] support/docker: Add openssh-server Thomas Preston
                   ` (4 subsequent siblings)
  5 siblings, 0 replies; 7+ messages in thread
From: Thomas Preston @ 2020-04-15 16:48 UTC (permalink / raw)
  To: buildroot

Update the test container to debian:buster-20200327, because it
contains the openssh-server package v7.9, which provides an updated
ssh-keygen (since v7.6).

Specifically, the host key generation function in openssh-server v7.6
onwards now accepts a flag that allows us to specify a host tree prefix,
instead of trying to create SSH host keys in /. This allows us to create
SSH host keys and therefore run an SSH server as a non-root user. For
example, to create host keys in `prefix/host/etc/ssh`:

	ssh-keygen -A -f prefix/host

Signed-off-by: Thomas Preston <thomas.preston@codethink.co.uk>
---
 support/docker/Dockerfile       | 2 +-
 support/docker/apt-sources.list | 8 ++++----
 2 files changed, 5 insertions(+), 5 deletions(-)

diff --git a/support/docker/Dockerfile b/support/docker/Dockerfile
index 03acde85d2..be795a18b4 100644
--- a/support/docker/Dockerfile
+++ b/support/docker/Dockerfile
@@ -6,7 +6,7 @@
 # We use a specific tag for the base image *and* the corresponding date
 # for the repository., so do not forget to update the apt-sources.list
 # file that is shipped next to this Dockerfile.
-FROM debian:stretch-20171210
+FROM debian:buster-20200327
 
 LABEL maintainer="Buildroot mailing list <buildroot@buildroot.org>" \
       vendor="Buildroot" \
diff --git a/support/docker/apt-sources.list b/support/docker/apt-sources.list
index 789fb8fc17..c13c4d03c4 100644
--- a/support/docker/apt-sources.list
+++ b/support/docker/apt-sources.list
@@ -1,4 +1,4 @@
-# Latest just before 20171210T000000Z:
-deb [check-valid-until=no] http://snapshot.debian.org/archive/debian/20171209T220346Z/ stretch main
-deb [check-valid-until=no] http://snapshot.debian.org/archive/debian/20171209T220346Z/ stretch-updates main
-deb [check-valid-until=no] http://snapshot.debian.org/archive/debian-security/20171209T224618Z/ stretch/updates main
+# Latest just before 20200327T000000Z:
+deb [check-valid-until=no] http://snapshot.debian.org/archive/debian/20200326T221821Z/ buster main
+deb [check-valid-until=no] http://snapshot.debian.org/archive/debian/20200326T221821Z/ buster-updates main
+deb [check-valid-until=no] http://snapshot.debian.org/archive/debian-security/20200316T220151Z/ buster/updates main
-- 
2.20.1

^ permalink raw reply related	[flat|nested] 7+ messages in thread

* [Buildroot] [PATCH v2 2/5] support/docker: Add openssh-server
  2020-04-15 16:48 [Buildroot] [PATCH v2 0/5] download: Add SFTP support and tests Thomas Preston
  2020-04-15 16:48 ` [Buildroot] [PATCH v2 1/5] support/docker: Update to debian:buster-20200327 Thomas Preston
@ 2020-04-15 16:48 ` Thomas Preston
  2020-04-15 16:48 ` [Buildroot] [PATCH v2 3/5] testing/infra: Add docstrings to base test classes Thomas Preston
                   ` (3 subsequent siblings)
  5 siblings, 0 replies; 7+ messages in thread
From: Thomas Preston @ 2020-04-15 16:48 UTC (permalink / raw)
  To: buildroot

Install the openssh-server package into the test container. This
package, as well as its dependency openssh-client, is required to test
SCP and SFTP download methods on the localhost, as if these tools were
already installed on the user's machine.

Signed-off-by: Thomas Preston <thomas.preston@codethink.co.uk>
---
 support/docker/Dockerfile | 1 +
 1 file changed, 1 insertion(+)

diff --git a/support/docker/Dockerfile b/support/docker/Dockerfile
index be795a18b4..f44be230e6 100644
--- a/support/docker/Dockerfile
+++ b/support/docker/Dockerfile
@@ -36,6 +36,7 @@ RUN apt-get install -y --no-install-recommends \
         libncurses5-dev \
         locales \
         mercurial \
+        openssh-server \
         python-flake8 \
         python-nose2 \
         python-pexpect \
-- 
2.20.1

^ permalink raw reply related	[flat|nested] 7+ messages in thread

* [Buildroot] [PATCH v2 3/5] testing/infra: Add docstrings to base test classes
  2020-04-15 16:48 [Buildroot] [PATCH v2 0/5] download: Add SFTP support and tests Thomas Preston
  2020-04-15 16:48 ` [Buildroot] [PATCH v2 1/5] support/docker: Update to debian:buster-20200327 Thomas Preston
  2020-04-15 16:48 ` [Buildroot] [PATCH v2 2/5] support/docker: Add openssh-server Thomas Preston
@ 2020-04-15 16:48 ` Thomas Preston
  2020-04-15 16:48 ` [Buildroot] [PATCH v2 4/5] download: Add SFTP support (not FTPS) Thomas Preston
                   ` (2 subsequent siblings)
  5 siblings, 0 replies; 7+ messages in thread
From: Thomas Preston @ 2020-04-15 16:48 UTC (permalink / raw)
  To: buildroot

It wasn't immediately obvious to me what the two Buildroot base test
classes were for, so add docstrings to explain the differences between
BRConfigTest and BRTest.

Signed-off-by: Thomas Preston <thomas.preston@codethink.co.uk>
---
 support/testing/infra/basetest.py | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/support/testing/infra/basetest.py b/support/testing/infra/basetest.py
index 5dc6034447..dec0ab7013 100644
--- a/support/testing/infra/basetest.py
+++ b/support/testing/infra/basetest.py
@@ -29,6 +29,7 @@ MINIMAL_CONFIG = \
 
 
 class BRConfigTest(unittest.TestCase):
+    """Test up to the configure stage."""
     config = None
     br2_external = list()
     downloaddir = None
@@ -66,6 +67,7 @@ class BRConfigTest(unittest.TestCase):
 
 
 class BRTest(BRConfigTest):
+    """Test up to the build stage and instantiate an emulator."""
     def __init__(self, names):
         super(BRTest, self).__init__(names)
         self.emulator = None
-- 
2.20.1

^ permalink raw reply related	[flat|nested] 7+ messages in thread

* [Buildroot] [PATCH v2 4/5] download: Add SFTP support (not FTPS)
  2020-04-15 16:48 [Buildroot] [PATCH v2 0/5] download: Add SFTP support and tests Thomas Preston
                   ` (2 preceding siblings ...)
  2020-04-15 16:48 ` [Buildroot] [PATCH v2 3/5] testing/infra: Add docstrings to base test classes Thomas Preston
@ 2020-04-15 16:48 ` Thomas Preston
  2020-04-15 16:48 ` [Buildroot] [PATCH v2 5/5] support/testing: Add download tests for SCP/SFTP Thomas Preston
  2022-01-06  8:43 ` [Buildroot] [PATCH v2 0/5] download: Add SFTP support and tests Arnout Vandecappelle
  5 siblings, 0 replies; 7+ messages in thread
From: Thomas Preston @ 2020-04-15 16:48 UTC (permalink / raw)
  To: buildroot

Add Secure File Transfer Program (SFTP) support using a simple wrapper.
SFTP is a common protocol used to transfer files securely between
enterprises, but it is not currently supported in Buildroot because all
of the packages are usually available via HTTP, git or some other
download method.

SFTP is similar to FTP but it preforms all operations over an encrypted
SSH transport.

Signed-off-by: Thomas Preston <thomas.preston@codethink.co.uk>
Signed-off-by: Michael Drake <michael.drake@codethink.co.uk>
---
 Config.in                   |  4 ++++
 package/pkg-download.mk     |  1 +
 support/download/dl-wrapper |  2 +-
 support/download/sftp       | 37 +++++++++++++++++++++++++++++++++++++
 4 files changed, 43 insertions(+), 1 deletion(-)
 create mode 100755 support/download/sftp

diff --git a/Config.in b/Config.in
index 48fd36ff98..2050dd7a03 100644
--- a/Config.in
+++ b/Config.in
@@ -114,6 +114,10 @@ config BR2_SCP
 	string "Secure copy (scp) command"
 	default "scp"
 
+config BR2_SFTP
+	string "Secure file transfer (sftp) command"
+	default "sftp"
+
 config BR2_HG
 	string "Mercurial (hg) command"
 	default "hg"
diff --git a/package/pkg-download.mk b/package/pkg-download.mk
index de619ba90a..88790fe46e 100644
--- a/package/pkg-download.mk
+++ b/package/pkg-download.mk
@@ -15,6 +15,7 @@ export BZR := $(call qstrip,$(BR2_BZR))
 export GIT := $(call qstrip,$(BR2_GIT))
 export HG := $(call qstrip,$(BR2_HG))
 export SCP := $(call qstrip,$(BR2_SCP))
+export SFTP := $(call qstrip,$(BR2_SFTP))
 export LOCALFILES := $(call qstrip,$(BR2_LOCALFILES))
 
 DL_WRAPPER = support/download/dl-wrapper
diff --git a/support/download/dl-wrapper b/support/download/dl-wrapper
index 3315bd410e..6cf0b89cba 100755
--- a/support/download/dl-wrapper
+++ b/support/download/dl-wrapper
@@ -88,7 +88,7 @@ main() {
         backend_urlencode="${uri%%+*}"
         backend="${backend_urlencode%|*}"
         case "${backend}" in
-            git|svn|cvs|bzr|file|scp|hg) ;;
+            git|svn|cvs|bzr|file|scp|hg|sftp) ;;
             *) backend="wget" ;;
         esac
         uri=${uri#*+}
diff --git a/support/download/sftp b/support/download/sftp
new file mode 100755
index 0000000000..8aeb91e0e8
--- /dev/null
+++ b/support/download/sftp
@@ -0,0 +1,37 @@
+#!/usr/bin/env bash
+
+# We want to catch any unexpected failure, and exit immediately
+set -e
+
+# Download helper for sftp, to be called from the download wrapper script
+#
+# Options:
+#   -q          Be quiet.
+#   -o FILE     Copy to local file FILE.
+#   -f FILE     Copy from remote file FILE.
+#   -u URI      Download file at URI.
+#
+# Environment:
+#   SFTP      : the sftp command to call
+
+verbose=
+while getopts "${BR_BACKEND_DL_GETOPTS}" OPT; do
+    case "${OPT}" in
+    q)  verbose=-q;;
+    o)  output="${OPTARG}";;
+    f)  filename="${OPTARG}";;
+    u)  uri="${OPTARG}";;
+    :)  printf "option '%s' expects a mandatory argument\n" "${OPTARG}"; exit 1;;
+    \?) printf "unknown option '%s'\n" "${OPTARG}" >&2; exit 1;;
+    esac
+done
+
+shift $((OPTIND-1)) # Get rid of our options
+
+# Caller needs to single-quote its arguments to prevent them from
+# being expanded a second time (in case there are spaces in them)
+_sftp() {
+    eval ${SFTP} "${@}"
+}
+
+_sftp ${verbose} "${@}" "'${uri}/${filename}'" "'${output}'"
-- 
2.20.1

^ permalink raw reply related	[flat|nested] 7+ messages in thread

* [Buildroot] [PATCH v2 5/5] support/testing: Add download tests for SCP/SFTP
  2020-04-15 16:48 [Buildroot] [PATCH v2 0/5] download: Add SFTP support and tests Thomas Preston
                   ` (3 preceding siblings ...)
  2020-04-15 16:48 ` [Buildroot] [PATCH v2 4/5] download: Add SFTP support (not FTPS) Thomas Preston
@ 2020-04-15 16:48 ` Thomas Preston
  2022-01-06  8:43 ` [Buildroot] [PATCH v2 0/5] download: Add SFTP support and tests Arnout Vandecappelle
  5 siblings, 0 replies; 7+ messages in thread
From: Thomas Preston @ 2020-04-15 16:48 UTC (permalink / raw)
  To: buildroot

Add download test infrastructure which starts an OpenSSH server using
the sshd binary installed on the Buildroot host. This server can then be
used to test the expected usage of the SCP and SFTP download methods.
The test creates new SSH keys for the server and client, so that the
server can be run as a non-root user.

A new test module has been added called `tests.download.sshd` which
contains helper methods to create the SSH keys and a class called
`OpenSSHDaemon` which handles the sshd server component.

The tests download example packages in the br2-external project `ssh`.
They check the following conditions for both SCP and SFTP download
methods:
- Correct hash.
- Incorrect hash.
- No hash file.

The SSH download test infrastructure is based on test_git.py.

Signed-off-by: Thomas Preston <thomas.preston@codethink.co.uk>
---
 .gitlab-ci.yml                                |   2 +
 .../tests/download/br2-external/scp/Config.in |   0
 .../download/br2-external/scp/external.desc   |   1 +
 .../download/br2-external/scp/external.mk     |   4 +
 .../scp/package/scp-bad/scp-bad.hash          |   1 +
 .../scp/package/scp-bad/scp-bad.mk            |  17 +++
 .../scp/package/scp-good/scp-good.hash        |   1 +
 .../scp/package/scp-good/scp-good.mk          |  17 +++
 .../scp/package/scp-nohash/scp-nohash.mk      |  17 +++
 .../download/br2-external/sftp/Config.in      |   0
 .../download/br2-external/sftp/external.desc  |   1 +
 .../download/br2-external/sftp/external.mk    |   4 +
 .../sftp/package/sftp-bad/sftp-bad.hash       |   1 +
 .../sftp/package/sftp-bad/sftp-bad.mk         |  17 +++
 .../sftp/package/sftp-good/sftp-good.hash     |   1 +
 .../sftp/package/sftp-good/sftp-good.mk       |  17 +++
 .../sftp/package/sftp-nohash/sftp-nohash.mk   |  17 +++
 support/testing/tests/download/sshd.py        | 129 ++++++++++++++++++
 .../tests/download/sshd/ssh-test-1.0.tar.xz   | Bin 0 -> 232 bytes
 support/testing/tests/download/test_ssh.py    |  66 +++++++++
 20 files changed, 313 insertions(+)
 create mode 100644 support/testing/tests/download/br2-external/scp/Config.in
 create mode 100644 support/testing/tests/download/br2-external/scp/external.desc
 create mode 100644 support/testing/tests/download/br2-external/scp/external.mk
 create mode 100644 support/testing/tests/download/br2-external/scp/package/scp-bad/scp-bad.hash
 create mode 100644 support/testing/tests/download/br2-external/scp/package/scp-bad/scp-bad.mk
 create mode 100644 support/testing/tests/download/br2-external/scp/package/scp-good/scp-good.hash
 create mode 100644 support/testing/tests/download/br2-external/scp/package/scp-good/scp-good.mk
 create mode 100644 support/testing/tests/download/br2-external/scp/package/scp-nohash/scp-nohash.mk
 create mode 100644 support/testing/tests/download/br2-external/sftp/Config.in
 create mode 100644 support/testing/tests/download/br2-external/sftp/external.desc
 create mode 100644 support/testing/tests/download/br2-external/sftp/external.mk
 create mode 100644 support/testing/tests/download/br2-external/sftp/package/sftp-bad/sftp-bad.hash
 create mode 100644 support/testing/tests/download/br2-external/sftp/package/sftp-bad/sftp-bad.mk
 create mode 100644 support/testing/tests/download/br2-external/sftp/package/sftp-good/sftp-good.hash
 create mode 100644 support/testing/tests/download/br2-external/sftp/package/sftp-good/sftp-good.mk
 create mode 100644 support/testing/tests/download/br2-external/sftp/package/sftp-nohash/sftp-nohash.mk
 create mode 100644 support/testing/tests/download/sshd.py
 create mode 100644 support/testing/tests/download/sshd/ssh-test-1.0.tar.xz
 create mode 100755 support/testing/tests/download/test_ssh.py

diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml
index 4b84a5b709..8061b50526 100644
--- a/.gitlab-ci.yml
+++ b/.gitlab-ci.yml
@@ -349,6 +349,8 @@ tests.core.test_timezone.TestGlibcNonDefaultLimitedTimezone: { extends: .runtime
 tests.core.test_timezone.TestNoTimezone: { extends: .runtime_test }
 tests.download.test_git.TestGitHash: { extends: .runtime_test }
 tests.download.test_git.TestGitRefs: { extends: .runtime_test }
+tests.download.test_ssh.TestSCP: { extends: .runtime_test }
+tests.download.test_ssh.TestSFTP: { extends: .runtime_test }
 tests.fs.test_ext.TestExt2: { extends: .runtime_test }
 tests.fs.test_ext.TestExt2r1: { extends: .runtime_test }
 tests.fs.test_ext.TestExt3: { extends: .runtime_test }
diff --git a/support/testing/tests/download/br2-external/scp/Config.in b/support/testing/tests/download/br2-external/scp/Config.in
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/support/testing/tests/download/br2-external/scp/external.desc b/support/testing/tests/download/br2-external/scp/external.desc
new file mode 100644
index 0000000000..0ca0389a32
--- /dev/null
+++ b/support/testing/tests/download/br2-external/scp/external.desc
@@ -0,0 +1 @@
+name: SCP
diff --git a/support/testing/tests/download/br2-external/scp/external.mk b/support/testing/tests/download/br2-external/scp/external.mk
new file mode 100644
index 0000000000..49408f2f22
--- /dev/null
+++ b/support/testing/tests/download/br2-external/scp/external.mk
@@ -0,0 +1,4 @@
+include $(sort $(wildcard $(BR2_EXTERNAL_SCP_PATH)/package/*/*.mk))
+
+# Get the openssh-server port number from the test infra
+SSHD_PORT_NUMBER ?= 2222
diff --git a/support/testing/tests/download/br2-external/scp/package/scp-bad/scp-bad.hash b/support/testing/tests/download/br2-external/scp/package/scp-bad/scp-bad.hash
new file mode 100644
index 0000000000..90b15b30c2
--- /dev/null
+++ b/support/testing/tests/download/br2-external/scp/package/scp-bad/scp-bad.hash
@@ -0,0 +1 @@
+sha256  0000000000000000000000000000000000000000000000000000000000000000  ssh-test-1.0.tar.xz
diff --git a/support/testing/tests/download/br2-external/scp/package/scp-bad/scp-bad.mk b/support/testing/tests/download/br2-external/scp/package/scp-bad/scp-bad.mk
new file mode 100644
index 0000000000..5f6d55d940
--- /dev/null
+++ b/support/testing/tests/download/br2-external/scp/package/scp-bad/scp-bad.mk
@@ -0,0 +1,17 @@
+################################################################################
+#
+# scp-bad
+#
+################################################################################
+
+SCP_BAD_VERSION = 1.0
+SCP_BAD_SOURCE = ssh-test-$(SCP_BAD_VERSION).tar.xz
+SCP_BAD_SITE = scp://localhost:$(SSHD_TEST_DIR)
+SCP_BAD_DL_OPTS = \
+	-P $(SSHD_PORT_NUMBER) \
+	-i $(SSH_IDENTITY) \
+	-o "UserKnownHostsFile=/dev/null" \
+	-o "StrictHostKeyChecking=no" \
+	-o "CheckHostIP=no"
+
+$(eval $(generic-package))
diff --git a/support/testing/tests/download/br2-external/scp/package/scp-good/scp-good.hash b/support/testing/tests/download/br2-external/scp/package/scp-good/scp-good.hash
new file mode 100644
index 0000000000..31353a88ba
--- /dev/null
+++ b/support/testing/tests/download/br2-external/scp/package/scp-good/scp-good.hash
@@ -0,0 +1 @@
+sha256  b457c1a37ba7405e8806b93f3d5cc82165db0b0cad25d203f112e32c7a30c0be  ssh-test-1.0.tar.xz
diff --git a/support/testing/tests/download/br2-external/scp/package/scp-good/scp-good.mk b/support/testing/tests/download/br2-external/scp/package/scp-good/scp-good.mk
new file mode 100644
index 0000000000..eff455a470
--- /dev/null
+++ b/support/testing/tests/download/br2-external/scp/package/scp-good/scp-good.mk
@@ -0,0 +1,17 @@
+################################################################################
+#
+# scp-good
+#
+################################################################################
+
+SCP_GOOD_VERSION = 1.0
+SCP_GOOD_SOURCE = ssh-test-$(SCP_GOOD_VERSION).tar.xz
+SCP_GOOD_SITE = scp://localhost:$(SSHD_TEST_DIR)
+SCP_GOOD_DL_OPTS = \
+	-P $(SSHD_PORT_NUMBER) \
+	-i $(SSH_IDENTITY) \
+	-o "UserKnownHostsFile=/dev/null" \
+	-o "StrictHostKeyChecking=no" \
+	-o "CheckHostIP=no" \
+
+$(eval $(generic-package))
diff --git a/support/testing/tests/download/br2-external/scp/package/scp-nohash/scp-nohash.mk b/support/testing/tests/download/br2-external/scp/package/scp-nohash/scp-nohash.mk
new file mode 100644
index 0000000000..f44c45fda3
--- /dev/null
+++ b/support/testing/tests/download/br2-external/scp/package/scp-nohash/scp-nohash.mk
@@ -0,0 +1,17 @@
+################################################################################
+#
+# scp-nohash
+#
+################################################################################
+
+SCP_NOHASH_VERSION = 1.0
+SCP_NOHASH_SOURCE = ssh-test-$(SCP_NOHASH_VERSION).tar.xz
+SCP_NOHASH_SITE = scp://localhost:$(SSHD_TEST_DIR)
+SCP_NOHASH_DL_OPTS = \
+	-P $(SSHD_PORT_NUMBER) \
+	-i $(SSH_IDENTITY) \
+	-o "UserKnownHostsFile=/dev/null" \
+	-o "StrictHostKeyChecking=no" \
+	-o "CheckHostIP=no" \
+
+$(eval $(generic-package))
diff --git a/support/testing/tests/download/br2-external/sftp/Config.in b/support/testing/tests/download/br2-external/sftp/Config.in
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/support/testing/tests/download/br2-external/sftp/external.desc b/support/testing/tests/download/br2-external/sftp/external.desc
new file mode 100644
index 0000000000..ae3a2860cd
--- /dev/null
+++ b/support/testing/tests/download/br2-external/sftp/external.desc
@@ -0,0 +1 @@
+name: SFTP
diff --git a/support/testing/tests/download/br2-external/sftp/external.mk b/support/testing/tests/download/br2-external/sftp/external.mk
new file mode 100644
index 0000000000..cd4a7c839e
--- /dev/null
+++ b/support/testing/tests/download/br2-external/sftp/external.mk
@@ -0,0 +1,4 @@
+include $(sort $(wildcard $(BR2_EXTERNAL_SFTP_PATH)/package/*/*.mk))
+
+# Get the openssh-server port number from the test infra
+SSHD_PORT_NUMBER ?= 2222
diff --git a/support/testing/tests/download/br2-external/sftp/package/sftp-bad/sftp-bad.hash b/support/testing/tests/download/br2-external/sftp/package/sftp-bad/sftp-bad.hash
new file mode 100644
index 0000000000..90b15b30c2
--- /dev/null
+++ b/support/testing/tests/download/br2-external/sftp/package/sftp-bad/sftp-bad.hash
@@ -0,0 +1 @@
+sha256  0000000000000000000000000000000000000000000000000000000000000000  ssh-test-1.0.tar.xz
diff --git a/support/testing/tests/download/br2-external/sftp/package/sftp-bad/sftp-bad.mk b/support/testing/tests/download/br2-external/sftp/package/sftp-bad/sftp-bad.mk
new file mode 100644
index 0000000000..fa83c2cd68
--- /dev/null
+++ b/support/testing/tests/download/br2-external/sftp/package/sftp-bad/sftp-bad.mk
@@ -0,0 +1,17 @@
+################################################################################
+#
+# sftp-bad
+#
+################################################################################
+
+SFTP_BAD_VERSION = 1.0
+SFTP_BAD_SOURCE = ssh-test-$(SFTP_BAD_VERSION).tar.xz
+SFTP_BAD_SITE = sftp://localhost/$(SSHD_TEST_DIR)
+SFTP_BAD_DL_OPTS = \
+	-P $(SSHD_PORT_NUMBER) \
+	-i $(SSH_IDENTITY) \
+	-o "UserKnownHostsFile=/dev/null" \
+	-o "StrictHostKeyChecking=no" \
+	-o "CheckHostIP=no" \
+
+$(eval $(generic-package))
diff --git a/support/testing/tests/download/br2-external/sftp/package/sftp-good/sftp-good.hash b/support/testing/tests/download/br2-external/sftp/package/sftp-good/sftp-good.hash
new file mode 100644
index 0000000000..31353a88ba
--- /dev/null
+++ b/support/testing/tests/download/br2-external/sftp/package/sftp-good/sftp-good.hash
@@ -0,0 +1 @@
+sha256  b457c1a37ba7405e8806b93f3d5cc82165db0b0cad25d203f112e32c7a30c0be  ssh-test-1.0.tar.xz
diff --git a/support/testing/tests/download/br2-external/sftp/package/sftp-good/sftp-good.mk b/support/testing/tests/download/br2-external/sftp/package/sftp-good/sftp-good.mk
new file mode 100644
index 0000000000..1cb5f22dbc
--- /dev/null
+++ b/support/testing/tests/download/br2-external/sftp/package/sftp-good/sftp-good.mk
@@ -0,0 +1,17 @@
+################################################################################
+#
+# sftp-good
+#
+################################################################################
+
+SFTP_GOOD_VERSION = 1.0
+SFTP_GOOD_SOURCE = ssh-test-$(SFTP_GOOD_VERSION).tar.xz
+SFTP_GOOD_SITE = sftp://localhost/$(SSHD_TEST_DIR)
+SFTP_GOOD_DL_OPTS = \
+	-P $(SSHD_PORT_NUMBER) \
+	-i $(SSH_IDENTITY) \
+	-o "UserKnownHostsFile=/dev/null" \
+	-o "StrictHostKeyChecking=no" \
+	-o "CheckHostIP=no" \
+
+$(eval $(generic-package))
diff --git a/support/testing/tests/download/br2-external/sftp/package/sftp-nohash/sftp-nohash.mk b/support/testing/tests/download/br2-external/sftp/package/sftp-nohash/sftp-nohash.mk
new file mode 100644
index 0000000000..62a2c3d864
--- /dev/null
+++ b/support/testing/tests/download/br2-external/sftp/package/sftp-nohash/sftp-nohash.mk
@@ -0,0 +1,17 @@
+################################################################################
+#
+# sftp-nohash
+#
+################################################################################
+
+SFTP_NOHASH_VERSION = 1.0
+SFTP_NOHASH_SOURCE = ssh-test-$(SFTP_NOHASH_VERSION).tar.xz
+SFTP_NOHASH_SITE = sftp://localhost/$(SSHD_TEST_DIR)
+SFTP_NOHASH_DL_OPTS = \
+	-P $(SSHD_PORT_NUMBER) \
+	-i $(SSH_IDENTITY) \
+	-o "UserKnownHostsFile=/dev/null" \
+	-o "StrictHostKeyChecking=no" \
+	-o "CheckHostIP=no" \
+
+$(eval $(generic-package))
diff --git a/support/testing/tests/download/sshd.py b/support/testing/tests/download/sshd.py
new file mode 100644
index 0000000000..ba5c2e053f
--- /dev/null
+++ b/support/testing/tests/download/sshd.py
@@ -0,0 +1,129 @@
+import os
+import shutil
+import subprocess
+
+# subprocess does not kill the child daemon when a test case fails by raising
+# an exception. So use pexpect instead.
+import pexpect
+
+import infra
+
+
+SSHD_PORT_INITIAL = 2222
+SSHD_PORT_LAST = SSHD_PORT_INITIAL + 99
+SSHD_PATH = "/usr/sbin/sshd"
+SSHD_HOST_DIR = "host"
+
+# SSHD_KEY_DIR is where the /etc/ss/ssh_host_*_key files go
+SSHD_KEY_DIR = os.path.join(SSHD_HOST_DIR, "etc/ssh")
+SSHD_KEY = os.path.join(SSHD_KEY_DIR, "ssh_host_ed25519_key")
+
+# SSH_CLIENT_KEY_DIR is where the client id_rsa key and authorized_keys files go
+SSH_CLIENT_KEY_DIR = os.path.join(SSHD_HOST_DIR, "home/br-user/ssh")
+SSH_CLIENT_KEY = os.path.join(SSH_CLIENT_KEY_DIR, "id_rsa")
+SSH_AUTH_KEYS_FILE = os.path.join(SSH_CLIENT_KEY_DIR, "authorized_keys")
+
+
+class OpenSSHDaemon():
+
+    def __init__(self, builddir, logtofile):
+        """
+        Start an OpenSSH SSH Daemon
+
+        In order to support test cases in parallel, select the port the
+        server will listen to in runtime. Since there is no reliable way
+        to allocate the port prior to starting the server (another
+        process in the host machine can use the port between it is
+        selected from a list and it is really allocated to the server)
+        try to start the server in a port and in the case it is already
+        in use, try the next one in the allowed range.
+        """
+        self.daemon = None
+        self.port = None
+
+        self.logfile = infra.open_log_file(builddir, "sshd", logtofile)
+
+        server_keyfile = os.path.join(builddir, SSHD_KEY)
+        auth_keys_file = os.path.join(builddir, SSH_AUTH_KEYS_FILE)
+        daemon_cmd = [SSHD_PATH,
+                      "-D", # or use -ddd to debug
+                      "-e",
+                      "-h", server_keyfile,
+                      "-o", "AuthorizedKeysFile={}".format(auth_keys_file)]
+        for port in range(SSHD_PORT_INITIAL, SSHD_PORT_LAST + 1):
+            cmd = daemon_cmd + ["-p", "{}".format(port)]
+            self.logfile.write(
+                "> starting sshd with '{}'\n".format(" ".join(cmd)))
+            self.daemon = pexpect.spawn(cmd[0], cmd[1:], logfile=self.logfile,
+                                        encoding='utf-8')
+            ret = self.daemon.expect([
+                # Success
+                "Server listening on :: port {}.".format(port),
+                # Failure
+                "Cannot bind any address."])
+            if ret == 0:
+                self.port = port
+                return
+        raise SystemError("Could not find a free port to run sshd")
+
+    def stop(self):
+        if self.daemon is None:
+            return
+        self.daemon.terminate(force=True)
+
+
+def generate_keys_server(builddir, logfile):
+    """Generate keys required to run an OpenSSH Daemon."""
+    keyfile = os.path.join(builddir, SSHD_KEY)
+    if os.path.exists(keyfile):
+        logfile.write("> SSH server key already exists '{}'".format(keyfile))
+        return
+
+    hostdir = os.path.join(builddir, SSHD_HOST_DIR)
+    keydir = os.path.join(builddir, SSHD_KEY_DIR)
+    infra.run_cmd_on_host(builddir, ["mkdir", "-p", hostdir, keydir])
+
+    cmd = ["ssh-keygen", "-A", "-f", hostdir]
+    logfile.write(
+        "> generating SSH server keys with '{}'\n".format(" ".join(cmd)))
+    # When ssh-keygen fails to create an SSH server key it doesn't return a
+    # useful error code. So use subprocess.getoutput to check for an error
+    # message instead.
+    out = subprocess.getoutput(" ".join(cmd))
+    logfile.write(out)
+    if "Could not save your public key" in out:
+        raise SystemError("Could not generate SSH server keys")
+
+
+def generate_keys_client(builddir, logfile):
+    """Generate keys required to log into an OpenSSH Daemon via SCP or SFTP."""
+    keyfile = os.path.join(builddir, SSH_CLIENT_KEY)
+    if os.path.exists(keyfile):
+        logfile.write("> SSH client key already exists '{}'".format(keyfile))
+        return
+
+    keydir = os.path.join(builddir, SSH_CLIENT_KEY_DIR)
+    infra.run_cmd_on_host(builddir, ["mkdir", "-p", keydir])
+
+    cmd = ["ssh-keygen",
+           "-f", keyfile,
+           "-b", "2048",
+           "-t", "rsa",
+           "-N", "",
+           "-q"]
+    logfile.write(
+        "> generating SSH client keys with '{}'\n".format(" ".join(cmd)))
+    ret = subprocess.call(cmd, stdout=logfile, stderr=logfile)
+    if ret > 0:
+        raise SystemError("Could not generate SSH client keys")
+
+    # Allow key-based login for this user (so that we can fetch from localhost)
+    pubkeyfile = os.path.join(keydir, "{}.pub".format(keyfile))
+    authfile = os.path.join(keydir, "authorized_keys")
+    shutil.copy(pubkeyfile, authfile)
+
+
+def generate_keys(builddir, logtofile):
+    logfile = infra.open_log_file(builddir, "ssh-keygen", logtofile)
+    generate_keys_server(builddir, logfile)
+    generate_keys_client(builddir, logfile)
diff --git a/support/testing/tests/download/sshd/ssh-test-1.0.tar.xz b/support/testing/tests/download/sshd/ssh-test-1.0.tar.xz
new file mode 100644
index 0000000000000000000000000000000000000000..bd83d0aff57569181d48e3c62ed24cf413349857
GIT binary patch
literal 232
zcmV<E02lxLH+ooF000E$*0e?f03iVu0001VFXf})C;tGaT>v at ZoLY1;=#rcYU!vo{
zY*d180V}vZPgp1s8F;=V2;UVkreiQmd@~S!C7Cz<muCq&y&rU=#0Mnb>Go}p<~MWy
zLlsZz<ezJHLQ+Zz;FM>Od$tuKG<#wIxTdaXt!(>CWqO6(9;!ET?+(Xp1W5kWc%A<b
zSztIv+|VVwQHZ*%f;jPjmxo8t{;$zGJ!I)lpxo`&x%+_rzrkKwYNz5s%Y8pC0001w
i;7sIpNoptn0mA`+Pyhh at 39RU`#Ao{g000001X)^l_h(@M

literal 0
HcmV?d00001

diff --git a/support/testing/tests/download/test_ssh.py b/support/testing/tests/download/test_ssh.py
new file mode 100755
index 0000000000..4fc4fd552a
--- /dev/null
+++ b/support/testing/tests/download/test_ssh.py
@@ -0,0 +1,66 @@
+import os
+import shutil
+
+import tests.download.sshd
+
+import infra
+
+
+class SSHTestBase(infra.basetest.BRConfigTest):
+    config = infra.basetest.MINIMAL_CONFIG
+    sshd_test_dir = infra.filepath("tests/download/sshd")
+    sshd = None
+
+    def setUp(self):
+        super(SSHTestBase, self).setUp()
+
+        self.show_msg("Generating keys")
+        tests.download.sshd.generate_keys(self.builddir, self.logtofile)
+
+        self.show_msg("Starting sshd")
+        self.sshd = tests.download.sshd.OpenSSHDaemon(self.builddir,
+                                                      self.logtofile)
+
+    def tearDown(self):
+        self.show_msg("Stopping sshd")
+        if self.sshd:
+            self.sshd.stop()
+        super(SSHTestBase, self).tearDown()
+
+    def download_package(self, package):
+        self.show_msg("Downloading {}".format(package))
+        # store downloaded tarball inside the output dir so the test infra
+        # cleans it up@the end
+        dl_dir = os.path.join(self.builddir, "dl")
+        ssh_identity = os.path.join(self.builddir,
+                                    tests.download.sshd.SSH_CLIENT_KEY)
+        # enforce that we test the download
+        if os.path.exists(dl_dir):
+            shutil.rmtree(dl_dir)
+        env = {"BR2_DL_DIR": dl_dir,
+               "SSHD_PORT_NUMBER": str(self.sshd.port),
+               "SSHD_TEST_DIR": self.sshd_test_dir,
+               "SSH_IDENTITY": ssh_identity}
+        self.b.build(["{}-dirclean".format(package),
+                      "{}-source".format(package)],
+                     env)
+
+
+class TestSCP(SSHTestBase):
+    br2_external = [infra.filepath("tests/download/br2-external/scp")]
+
+    def test_run(self):
+        with self.assertRaises(SystemError):
+            self.download_package("scp-bad")
+        self.download_package("scp-good")
+        self.download_package("scp-nohash")
+
+
+class TestSFTP(SSHTestBase):
+    br2_external = [infra.filepath("tests/download/br2-external/sftp")]
+
+    def test_run(self):
+        with self.assertRaises(SystemError):
+            self.download_package("sftp-bad")
+        self.download_package("sftp-good")
+        self.download_package("sftp-nohash")
-- 
2.20.1

^ permalink raw reply related	[flat|nested] 7+ messages in thread

* Re: [Buildroot] [PATCH v2 0/5] download: Add SFTP support and tests
  2020-04-15 16:48 [Buildroot] [PATCH v2 0/5] download: Add SFTP support and tests Thomas Preston
                   ` (4 preceding siblings ...)
  2020-04-15 16:48 ` [Buildroot] [PATCH v2 5/5] support/testing: Add download tests for SCP/SFTP Thomas Preston
@ 2022-01-06  8:43 ` Arnout Vandecappelle
  5 siblings, 0 replies; 7+ messages in thread
From: Arnout Vandecappelle @ 2022-01-06  8:43 UTC (permalink / raw)
  To: buildroot; +Cc: michael.drake, yann.morin.1998

  Hi all,

  I finally applied this series. Since Thomas is no longer with CodeThink this 
is more for the others in Cc.

On 15/04/2020 18:48, Thomas Preston wrote:
> Hi,
> Back in October 2019 I submitted a patch adding an SFTP download method
> to Buildroot, however since there were no packages using SFTP the patch
> was rejected.
> 
> Yann E. MORIN suggested that it was a valid change however it required
> tests to avoid bitrot - since there was no way to verify the SFTP
> download method did not break over time without any packages using it.
> 
> In this series I have re-added the SFTP download method and also some
> test infrastructure which starts a local SSH server and uses SFTP to
> download some test packages in a br2-external project. I've also added
> tests for SCP! :D
> 
> For this, I had to update the Dockerfile from Debian Stretch to Buster
> which I explain a bit further in the patch. I'm not sure how to test if
> this breaks anything else. Will all the tests run in a clean container +
> Buildroot project clone?
> 
> You can run the tests like so:
> 
> 	support/testing/run-tests -o output -d dl \
> 		tests.download.test_ssh.TestSFTP \
> 		tests.download.test_ssh.TestSCP
> 
> Thanks!
> Thomas
> 
> Thomas Preston (5):
>    support/docker: Update to debian:buster-20200327

  I skipped this one because in the meanwhile we already updated to a more 
recent Debian.

>    support/docker: Add openssh-server
>    testing/infra: Add docstrings to base test classes
>    download: Add SFTP support (not FTPS)

     [Arnout:
      - update documentation with sftp everywhere scp is mentioned;
      - rename "verbose" variable to "quiet";
      - print the sftp command, similar to wget and scp helpers.
     ]

>    support/testing: Add download tests for SCP/SFTP

     [Arnout:
      - remove spurious end-of-line backslash;
      - remove unnecessary executable bit;
      - skip test instead of failing if sshd, ssh-keygen, scp or sftp are not
        found;
      - decode the output of subprocess;
      - use subprocess.check_output instead of subprocess.get_output;
      - use subprocess.check_call instead of manually checking return code;
      - don't set always-overridden SSHD_PORT_NUMBER in .mk file;
      - explicitly set sshd options on commandline instead of relying on host
        /etc/sshd/sshd_config;
      - let sshd listen only on localhost;
      - user internal sftp server;
      - disable BACKUP_SITE, no network is supposed to be accessed;
      - remove the -bad and -nohash versions;
      - rename {sftp,scp}-good to plain {sftp,scp};
      - move the sftp and scp packages into a single "ssh" external.
     ]

> 
>   .gitlab-ci.yml                                |   2 +
>   Config.in                                     |   4 +
>   package/pkg-download.mk                       |   1 +
>   support/docker/Dockerfile                     |   3 +-
>   support/docker/apt-sources.list               |   8 +-
>   support/download/dl-wrapper                   |   2 +-
>   support/download/sftp                         |  37 +++++
>   support/testing/infra/basetest.py             |   2 +
>   .../tests/download/br2-external/scp/Config.in |   0
>   .../download/br2-external/scp/external.desc   |   1 +
>   .../download/br2-external/scp/external.mk     |   4 +
>   .../scp/package/scp-bad/scp-bad.hash          |   1 +
>   .../scp/package/scp-bad/scp-bad.mk            |  17 +++
>   .../scp/package/scp-good/scp-good.hash        |   1 +
>   .../scp/package/scp-good/scp-good.mk          |  17 +++
>   .../scp/package/scp-nohash/scp-nohash.mk      |  17 +++
>   .../download/br2-external/sftp/Config.in      |   0
>   .../download/br2-external/sftp/external.desc  |   1 +
>   .../download/br2-external/sftp/external.mk    |   4 +
>   .../sftp/package/sftp-bad/sftp-bad.hash       |   1 +
>   .../sftp/package/sftp-bad/sftp-bad.mk         |  17 +++
>   .../sftp/package/sftp-good/sftp-good.hash     |   1 +
>   .../sftp/package/sftp-good/sftp-good.mk       |  17 +++
>   .../sftp/package/sftp-nohash/sftp-nohash.mk   |  17 +++
>   support/testing/tests/download/sshd.py        | 129 ++++++++++++++++++
>   .../tests/download/sshd/ssh-test-1.0.tar.xz   | Bin 0 -> 232 bytes
>   support/testing/tests/download/test_ssh.py    |  66 +++++++++
>   27 files changed, 364 insertions(+), 6 deletions(-)
>   create mode 100755 support/download/sftp
>   create mode 100644 support/testing/tests/download/br2-external/scp/Config.in
>   create mode 100644 support/testing/tests/download/br2-external/scp/external.desc
>   create mode 100644 support/testing/tests/download/br2-external/scp/external.mk
>   create mode 100644 support/testing/tests/download/br2-external/scp/package/scp-bad/scp-bad.hash
>   create mode 100644 support/testing/tests/download/br2-external/scp/package/scp-bad/scp-bad.mk
>   create mode 100644 support/testing/tests/download/br2-external/scp/package/scp-good/scp-good.hash
>   create mode 100644 support/testing/tests/download/br2-external/scp/package/scp-good/scp-good.mk
>   create mode 100644 support/testing/tests/download/br2-external/scp/package/scp-nohash/scp-nohash.mk
>   create mode 100644 support/testing/tests/download/br2-external/sftp/Config.in
>   create mode 100644 support/testing/tests/download/br2-external/sftp/external.desc
>   create mode 100644 support/testing/tests/download/br2-external/sftp/external.mk
>   create mode 100644 support/testing/tests/download/br2-external/sftp/package/sftp-bad/sftp-bad.hash
>   create mode 100644 support/testing/tests/download/br2-external/sftp/package/sftp-bad/sftp-bad.mk
>   create mode 100644 support/testing/tests/download/br2-external/sftp/package/sftp-good/sftp-good.hash
>   create mode 100644 support/testing/tests/download/br2-external/sftp/package/sftp-good/sftp-good.mk
>   create mode 100644 support/testing/tests/download/br2-external/sftp/package/sftp-nohash/sftp-nohash.mk
>   create mode 100644 support/testing/tests/download/sshd.py
>   create mode 100644 support/testing/tests/download/sshd/ssh-test-1.0.tar.xz
>   create mode 100755 support/testing/tests/download/test_ssh.py
> 
_______________________________________________
buildroot mailing list
buildroot@buildroot.org
https://lists.buildroot.org/mailman/listinfo/buildroot

^ permalink raw reply	[flat|nested] 7+ messages in thread

end of thread, other threads:[~2022-01-06  8:43 UTC | newest]

Thread overview: 7+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-04-15 16:48 [Buildroot] [PATCH v2 0/5] download: Add SFTP support and tests Thomas Preston
2020-04-15 16:48 ` [Buildroot] [PATCH v2 1/5] support/docker: Update to debian:buster-20200327 Thomas Preston
2020-04-15 16:48 ` [Buildroot] [PATCH v2 2/5] support/docker: Add openssh-server Thomas Preston
2020-04-15 16:48 ` [Buildroot] [PATCH v2 3/5] testing/infra: Add docstrings to base test classes Thomas Preston
2020-04-15 16:48 ` [Buildroot] [PATCH v2 4/5] download: Add SFTP support (not FTPS) Thomas Preston
2020-04-15 16:48 ` [Buildroot] [PATCH v2 5/5] support/testing: Add download tests for SCP/SFTP Thomas Preston
2022-01-06  8:43 ` [Buildroot] [PATCH v2 0/5] download: Add SFTP support and tests Arnout Vandecappelle

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.