Skip to content

Commit

Permalink
Improve compatibility with jenkins docker-plugin (#63)
Browse files Browse the repository at this point in the history
* Add some logging for parameter transparency

* Output windows sshd logs in container logs

this is more consistent with how the linux script
outputs ssh activity via non-detatched sshd

* Ignore docker-plugin default sshd command

* Move envvar export before potentially running arbitrary command

even if you do want to run an arbitrary command, making
environment variables available is probably good or
atleast doesn't hurt.  Especially if that command happens
to be some uncaught variant of sshd

* Add windows tests for env pubkey and docker-plugin default arg

* Add linux test for docker-plugin default arg

* Handle quoted and unquoted forms of docker-plugin command

Co-authored-by: Barrett Lewis <barrett@mitsi.com>
  • Loading branch information
GunArm and Barrett Lewis committed Mar 1, 2021
1 parent 217f589 commit 825b242
Show file tree
Hide file tree
Showing 4 changed files with 100 additions and 11 deletions.
21 changes: 17 additions & 4 deletions setup-sshd
Original file line number Diff line number Diff line change
Expand Up @@ -49,19 +49,32 @@ fi
if [[ ${JENKINS_SLAVE_SSH_PUBKEY} == ssh-* ]]; then
write_key "${JENKINS_SLAVE_SSH_PUBKEY}"
fi

# ensure variables passed to docker container are also exposed to ssh sessions
env | grep _ >> /etc/environment

if [[ $# -gt 0 ]]; then
echo "${0##*/} params: $@"

if [[ $1 == ssh-* ]]; then
echo "Authorizing ssh pubkey found in params."
write_key "$1"
shift 1
elif [[ "$@" == "/usr/sbin/sshd -D -p 22" ]]; then
# neutralize default jenkins docker-plugin command
# we will run sshd at the end anyway
echo "Ignoring provided sshd command."

# if unquoted (4 tokens) shift extra 3
[[ "$2" == "-D" ]] && shift 3

shift 1
else
echo "Executing params: '$@'"
exec "$@"
fi
fi


# ensure variables passed to docker container are also exposed to ssh sessions
env | grep _ >> /etc/environment

# generate host keys if not present
ssh-keygen -A

Expand Down
19 changes: 12 additions & 7 deletions setup-sshd.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -81,25 +81,30 @@ while($null -ne $knownHostKeyVar) {
$knownHostKeyVar = Get-ChildItem env: -Name "JENKINS_AGENT_SSH_KNOWNHOST_$index"
}

# ensure variables passed to docker container are also exposed to ssh sessions
Get-ChildItem env: | ForEach-Object { setx /m $_.Name $_.Value | Out-Null }

if(![System.String]::IsNullOrWhiteSpace($Cmd)) {
Write-Host "$($MyInvocation.MyCommand.Name) param: '$Cmd'"
if($Cmd -match "^ssh-.*") {
Write-Host "Authorizing ssh pubkey found in params."
Write-Key $Cmd
} elseif($Cmd -match "^/usr/sbin/sshd") {
# neutralize default jenkins docker-plugin command
# we will run sshd at the end anyway
Write-Host "Ignoring provided (linux) sshd command."
} else {
Write-Host "Executing param: $Cmd"
& $Cmd
exit
}
}

# ensure variables passed to docker container are also exposed to ssh sessions
Get-ChildItem env: | ForEach-Object { setx /m $_.Name $_.Value | Out-Null }

Start-Service sshd

# dump network information
ipconfig
netstat -a

while($true) {
# if we don't do this endless loop, the container exits
Start-Sleep -Seconds 60
}
# aside from forwarding ssh logs, this keeps the container open
Get-Content -Path "C:\ProgramData\ssh\logs\sshd.log" -Wait
36 changes: 36 additions & 0 deletions tests/sshAgent.Tests.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -148,6 +148,42 @@ Describe "[$JDK $FLAVOR] create agent container with pubkey as argument" {
}
}

Describe "[$JDK $FLAVOR] create agent container with pubkey as envvar" {
BeforeAll {
$exitCode, $stdout, $stderr = Run-Program 'docker.exe' "run -dit -e `"JENKINS_AGENT_SSH_PUBKEY=$PUBLIC_SSH_KEY`" --name $AGENT_CONTAINER -P $AGENT_IMAGE"
Is-ContainerRunning $AGENT_CONTAINER | Should -BeTrue
}

It 'runs commands via ssh' {
$exitCode, $stdout, $stderr = Run-ThruSSH $AGENT_CONTAINER "$PRIVATE_SSH_KEY" "$SHELL -NoLogo -C `"Write-Host 'f00'`""
$exitCode | Should -Be 0
$stdout | Should -Match "f00"
}

AfterAll {
Cleanup($AGENT_CONTAINER)
}
}

$DOCKER_PLUGIN_DEFAULT_ARG="/usr/sbin/sshd -D -p 22"
Describe "[$JDK $FLAVOR] create agent container like docker-plugin with '$DOCKER_PLUGIN_DEFAULT_ARG' as argument" {
BeforeAll {
[string]::IsNullOrWhiteSpace($DOCKER_PLUGIN_DEFAULT_ARG) | Should -BeFalse
$exitCode, $stdout, $stderr = Run-Program 'docker.exe' "run -dit -e `"JENKINS_AGENT_SSH_PUBKEY=$PUBLIC_SSH_KEY`" --name $AGENT_CONTAINER -P $AGENT_IMAGE `"$DOCKER_PLUGIN_DEFAULT_ARG`""
Is-ContainerRunning $AGENT_CONTAINER | Should -BeTrue
}

It 'runs commands via ssh' {
$exitCode, $stdout, $stderr = Run-ThruSSH $AGENT_CONTAINER "$PRIVATE_SSH_KEY" "$SHELL -NoLogo -C `"Write-Host 'f00'`""
$exitCode | Should -Be 0
$stdout | Should -Match "f00"
}

AfterAll {
Cleanup($AGENT_CONTAINER)
}
}

Describe "[$JDK $FLAVOR] build args" {
BeforeAll {
Push-Location -StackName 'agent' -Path "$PSScriptRoot/.."
Expand Down
35 changes: 35 additions & 0 deletions tests/tests.bats
Original file line number Diff line number Diff line change
Expand Up @@ -127,6 +127,41 @@ function teardown () {
)
}

DOCKER_PLUGIN_DEFAULT_ARG="/usr/sbin/sshd -D -p 22"
@test "[${JDK} ${FLAVOR}] create agent container like docker-plugin with '${DOCKER_PLUGIN_DEFAULT_ARG}' (unquoted) as argument" {
[ ! -z "$DOCKER_PLUGIN_DEFAULT_ARG" ]

docker run -e "JENKINS_AGENT_SSH_PUBKEY=${PUBLIC_SSH_KEY}" -d --name "${AGENT_CONTAINER}" -P "${AGENT_IMAGE}" ${DOCKER_PLUGIN_DEFAULT_ARG}

is_agent_container_running

run_through_ssh echo f00

[ "$status" = "0" ] && [ "$output" = "f00" ] \
|| (\
echo "status: $status"; \
echo "output: $output"; \
false \
)
}

@test "[${JDK} ${FLAVOR}] create agent container with '${DOCKER_PLUGIN_DEFAULT_ARG}' (quoted) as argument" {
[ ! -z "$DOCKER_PLUGIN_DEFAULT_ARG" ]

docker run -e "JENKINS_AGENT_SSH_PUBKEY=${PUBLIC_SSH_KEY}" -d --name "${AGENT_CONTAINER}" -P "${AGENT_IMAGE}" "${DOCKER_PLUGIN_DEFAULT_ARG}"

is_agent_container_running

run_through_ssh echo f00

[ "$status" = "0" ] && [ "$output" = "f00" ] \
|| (\
echo "status: $status"; \
echo "output: $output"; \
false \
)
}

@test "[${JDK} ${FLAVOR}] use build args correctly" {
cd "${BATS_TEST_DIRNAME}"/.. || false

Expand Down

0 comments on commit 825b242

Please sign in to comment.