mirror of
https://github.com/atmoz/sftp.git
synced 2024-12-22 13:14:42 -05:00
da53454b4b
Using regex to validate arguments. Remove readme and usage output from image (expecting people to read documentation online). Some cleanups.
280 lines
6.6 KiB
Bash
Executable file
280 lines
6.6 KiB
Bash
Executable file
#!/bin/bash
|
|
# See: https://github.com/djui/bashunit
|
|
|
|
skipAllTests=false
|
|
|
|
scriptDir="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
|
|
buildDir="$scriptDir/.."
|
|
tmpDir="/tmp/atmoz_sftp_test"
|
|
|
|
sudo="sudo"
|
|
cache="--no-cache"
|
|
|
|
build=${1:-"build"}
|
|
output=${2:-"quiet"}
|
|
cleanup=${3:-"cleanup"}
|
|
sftpImageName="atmoz/sftp_test"
|
|
sftpContainerName="atmoz_sftp_test"
|
|
|
|
if [ "$output" == "quiet" ]; then
|
|
redirect="/dev/null"
|
|
else
|
|
redirect="/dev/stdout"
|
|
fi
|
|
|
|
buildOptions="--tag $sftpImageName"
|
|
|
|
##############################################################################
|
|
|
|
function beforeTest() {
|
|
if [ "$build" == "build" ]; then
|
|
buildOptions="$buildOptions $cache --pull=true"
|
|
fi
|
|
|
|
$sudo docker build $buildOptions "$buildDir"
|
|
if [ $? -gt 0 ]; then
|
|
echo "Build failed"
|
|
exit 1
|
|
fi
|
|
|
|
# Private key can not be read by others
|
|
chmod go-rw "$scriptDir/id_rsa"
|
|
|
|
rm -rf "$tmpDir" # clean state
|
|
mkdir "$tmpDir"
|
|
|
|
echo "test::$(id -u):$(id -g):dir1,dir2" >> "$tmpDir/users"
|
|
echo "user.with.dot::$(id -u):$(id -g)" >> "$tmpDir/users"
|
|
$sudo docker run \
|
|
-v "$tmpDir/users:/etc/sftp/users.conf:ro" \
|
|
-v "$scriptDir/id_rsa.pub":/home/test/.ssh/keys/id_rsa.pub:ro \
|
|
-v "$scriptDir/id_rsa.pub":/home/user.with.dot/.ssh/keys/id_rsa.pub:ro \
|
|
-v "$tmpDir":/home/test/share \
|
|
--name "$sftpContainerName" \
|
|
--expose 22 \
|
|
-d "$sftpImageName" \
|
|
> "$redirect"
|
|
|
|
waitForServer $sftpContainerName
|
|
}
|
|
|
|
function afterTest() {
|
|
if [ "$output" != "quiet" ]; then
|
|
echo "Docker logs:"
|
|
$sudo docker logs "$sftpContainerName"
|
|
fi
|
|
|
|
if [ "$cleanup" == "cleanup" ]; then
|
|
$sudo docker rm -fv "$sftpContainerName" > "$redirect"
|
|
rm -rf "$tmpDir"
|
|
fi
|
|
}
|
|
|
|
function getSftpIp() {
|
|
$sudo docker inspect -f {{.NetworkSettings.IPAddress}} "$1"
|
|
}
|
|
|
|
function runSftpCommands() {
|
|
ip="$(getSftpIp $1)"
|
|
user="$2"
|
|
shift 2
|
|
|
|
commands=""
|
|
for cmd in "$@"; do
|
|
commands="$commands$cmd"$'\n'
|
|
done
|
|
|
|
echo "$commands" | sftp \
|
|
-i "$scriptDir/id_rsa" \
|
|
-oStrictHostKeyChecking=no \
|
|
-oUserKnownHostsFile=/dev/null \
|
|
-b - $user@$ip \
|
|
> "$redirect" 2>&1
|
|
|
|
status=$?
|
|
sleep 1 # wait for commands to finish
|
|
return $status
|
|
}
|
|
|
|
function waitForServer() {
|
|
containerName="$1"
|
|
echo -n "Waiting for $containerName to open port 22 ..."
|
|
|
|
for i in {1..30}; do
|
|
sleep 1
|
|
ip="$(getSftpIp $containerName)"
|
|
echo -n "."
|
|
if [ -n "$ip" ] && nc -z $ip 22; then
|
|
echo " OPEN"
|
|
return 0;
|
|
fi
|
|
done
|
|
|
|
echo " TIMEOUT"
|
|
return 1
|
|
}
|
|
|
|
##############################################################################
|
|
|
|
function testContainerIsRunning() {
|
|
$skipAllTests && skip && return 0
|
|
|
|
ps="$($sudo docker ps -q -f name="$sftpContainerName")"
|
|
assertNotEqual "$ps" ""
|
|
|
|
if [ -z "$ps" ]; then
|
|
skipAllTests=true
|
|
fi
|
|
}
|
|
|
|
function testLoginUsingSshKey() {
|
|
$skipAllTests && skip && return 0
|
|
|
|
runSftpCommands "$sftpContainerName" "test" "exit"
|
|
assertReturn $? 0
|
|
}
|
|
|
|
function testUserWithDotLogin() {
|
|
$skipAllTests && skip && return 0
|
|
|
|
runSftpCommands "$sftpContainerName" "user.with.dot" "exit"
|
|
assertReturn $? 0
|
|
}
|
|
|
|
function testWritePermission() {
|
|
$skipAllTests && skip && return 0
|
|
|
|
runSftpCommands "$sftpContainerName" "test" \
|
|
"cd share" \
|
|
"mkdir test" \
|
|
"exit"
|
|
test -d "$tmpDir/test"
|
|
assertReturn $? 0
|
|
}
|
|
|
|
function testDir() {
|
|
$skipAllTests && skip && return 0
|
|
|
|
runSftpCommands "$sftpContainerName" "test" \
|
|
"cd dir1" \
|
|
"mkdir test-dir1" \
|
|
"get -rf test-dir1 $tmpDir/" \
|
|
"cd ../dir2" \
|
|
"mkdir test-dir2" \
|
|
"get -rf test-dir2 $tmpDir/" \
|
|
"exit"
|
|
test -d "$tmpDir/test-dir1"
|
|
assertReturn $? 0
|
|
test -d "$tmpDir/test-dir2"
|
|
assertReturn $? 0
|
|
}
|
|
|
|
# Smallest user config possible
|
|
function testMinimalContainerStart() {
|
|
$skipAllTests && skip && return 0
|
|
|
|
tmpContainerName="$sftpContainerName""_minimal"
|
|
|
|
$sudo docker run \
|
|
--name "$tmpContainerName" \
|
|
-d "$sftpImageName" \
|
|
m: \
|
|
> "$redirect"
|
|
|
|
waitForServer $tmpContainerName
|
|
|
|
ps="$($sudo docker ps -q -f name="$tmpContainerName")"
|
|
assertNotEqual "$ps" ""
|
|
|
|
if [ -z "$ps" ]; then
|
|
skipAllTests=true
|
|
fi
|
|
|
|
if [ "$output" != "quiet" ]; then
|
|
$sudo docker logs "$tmpContainerName"
|
|
fi
|
|
|
|
if [ "$cleanup" == "cleanup" ]; then
|
|
$sudo docker rm -fv "$tmpContainerName" > "$redirect"
|
|
fi
|
|
}
|
|
|
|
function testLegacyConfigPath() {
|
|
$skipAllTests && skip && return 0
|
|
|
|
tmpContainerName="$sftpContainerName""_legacy"
|
|
|
|
echo "test::$(id -u):$(id -g)" >> "$tmpDir/legacy_users"
|
|
$sudo docker run \
|
|
-v "$tmpDir/legacy_users:/etc/sftp-users.conf:ro" \
|
|
--name "$tmpContainerName" \
|
|
--expose 22 \
|
|
-d "$sftpImageName" \
|
|
> "$redirect"
|
|
|
|
waitForServer $tmpContainerName
|
|
|
|
ps="$($sudo docker ps -q -f name="$tmpContainerName")"
|
|
assertNotEqual "$ps" ""
|
|
|
|
if [ "$output" != "quiet" ]; then
|
|
$sudo docker logs "$tmpContainerName"
|
|
fi
|
|
|
|
if [ "$cleanup" == "cleanup" ]; then
|
|
$sudo docker rm -fv "$tmpContainerName" > "$redirect"
|
|
fi
|
|
}
|
|
|
|
|
|
# Bind-mount folder using script in /etc/sftp.d/
|
|
function testCustomContainerStart() {
|
|
$skipAllTests && skip && return 0
|
|
|
|
tmpContainerName="$sftpContainerName""_custom"
|
|
|
|
mkdir -p "$tmpDir/custom/bindmount"
|
|
echo "mkdir -p /home/custom/bindmount && \
|
|
chown custom /home/custom/bindmount && \
|
|
mount --bind /custom /home/custom/bindmount" \
|
|
> "$tmpDir/mount.sh"
|
|
chmod +x "$tmpDir/mount.sh"
|
|
|
|
$sudo docker run \
|
|
--privileged=true \
|
|
--name "$tmpContainerName" \
|
|
-v "$scriptDir/id_rsa.pub":/home/custom/.ssh/keys/id_rsa.pub:ro \
|
|
-v "$tmpDir/custom/bindmount":/custom \
|
|
-v "$tmpDir/mount.sh":/etc/sftp.d/mount.sh \
|
|
--expose 22 \
|
|
-d "$sftpImageName" \
|
|
custom:123 \
|
|
> "$redirect"
|
|
|
|
waitForServer $tmpContainerName
|
|
|
|
ps="$($sudo docker ps -q -f name="$tmpContainerName")"
|
|
assertNotEqual "$ps" ""
|
|
|
|
runSftpCommands "$tmpContainerName" "custom" \
|
|
"cd bindmount" \
|
|
"mkdir test" \
|
|
"exit"
|
|
|
|
test -d "$tmpDir/custom/bindmount/test"
|
|
assertReturn $? 0
|
|
|
|
if [ "$output" != "quiet" ]; then
|
|
$sudo docker logs "$tmpContainerName"
|
|
fi
|
|
|
|
if [ "$cleanup" == "cleanup" ]; then
|
|
$sudo docker rm -fv "$tmpContainerName" > "$redirect"
|
|
fi
|
|
}
|
|
|
|
##############################################################################
|
|
|
|
# Run tests
|
|
source "$scriptDir/bashunit.bash"
|
|
# Nothing happens after this
|