Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Shell out to local SSH client as alternative to a paramiko connection #2680

Merged
merged 1 commit into from Oct 16, 2020

Conversation

aiordache
Copy link
Collaborator

We have several issues raised for failures of the paramiko SSH connection, support for SSH config option etc. Shelling out to the local ssh client may provide a better experience and it mirrors the behaviour of docker cli. We keep the paramiko connection as the default one.

To use the local ssh client instead of paramiko, we must set the parameter use_ssh_client when creating the docker client as below:

def test_ssh_client():
    client = APIClient(base_url='ssh://remote', use_ssh_client=True)

    containers = client.containers()
    print("Running container IDs:")
    for c in containers:
        print("\t{}".format(c['Id']))

Make sure we have configured key-based ssh login to the target docker host:

Host remote
	Hostname 192.168.0.10
	User root
	IdentityFile ~/test/id_rsa
	Port 22

Output

Running container IDs:
        bd07c66651afc84f4223df96f59c4ffb3ba4ebb425feb6a6e0365e1a8987a024
        8625e8663fcaaa512d54444c08d99057ca893c806e05dd702cbd1dc86764065e

Closes #2659

@aiordache aiordache marked this pull request as draft October 5, 2020 17:38
Dockerfile Outdated
@@ -13,3 +13,11 @@ RUN pip install -r test-requirements.txt

COPY . /src
RUN pip install .

# install SSHD
RUN apt-get install -y openssh-client
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This might be included in the python:3.x image

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

better to move this to the top of this stage, so that it doesn't re-install with every code change.

Also needs a apt-get update, --no-install-recommends, and cleaning up after

Dockerfile-py3 Outdated
# Add the keys and set permissions
COPY tests/ssh-keys /root/.ssh
RUN chmod 600 /root/.ssh/id_rsa && \
chmod 600 /root/.ssh/id_rsa.pub
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: \n

Makefile Show resolved Hide resolved
docker/api/client.py Show resolved Hide resolved
tests/Dockerfile Outdated
# Add the keys and set permissions
COPY tests/ssh-keys /root/.ssh
RUN chmod 600 /root/.ssh/id_rsa && \
chmod 600 /root/.ssh/id_rsa.pub
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: \n

@aiordache aiordache force-pushed the replace_paramiko branch 7 times, most recently from f21a36a to 19e8141 Compare October 7, 2020 18:49
@aiordache aiordache marked this pull request as ready for review October 7, 2020 18:56
Copy link
Member

@chris-crone chris-crone left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks @aiordache! I think we're nearly there

Makefile Outdated
@@ -1,3 +1,6 @@
TEST_API_VERSION ?= 1.39
TEST_ENGINE_VERSION ?= 19.03.12
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: 19.03.13 is out now

docker/transport/sshconn.py Outdated Show resolved Hide resolved
self.timeout = timeout
self.host = host

# self.base_url = six.moves.urllib_parse.urlparse(host)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we remove this? Do we know why it was added originally?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Re-ping on this as I see it's still here

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Undid it by mistake.

tests/Dockerfile Outdated
gnupg2 \
pass \
curl
curl \
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think that curl and ssh are already in the Python 3.7 Debian image:

docker run --rm python:3.7 sh -c "which curl && which ssh"
/usr/bin/curl
/usr/bin/ssh

If there's another reason you need them, I prefer having lists like this sorted so that it's easy to check if something's being installed.

@aiordache aiordache force-pushed the replace_paramiko branch 2 times, most recently from 041e654 to 072215b Compare October 8, 2020 12:40
Dockerfile Outdated
Comment on lines 6 to 7
RUN chmod 600 /root/.ssh/id_rsa && \
chmod 600 /root/.ssh/id_rsa.pub
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think with engine 20.x, we'll be able to use COPY --chmod moby/buildkit#1492

would a chmod -R work for this?

Suggested change
RUN chmod 600 /root/.ssh/id_rsa && \
chmod 600 /root/.ssh/id_rsa.pub
RUN chmod -R 600 /root/.ssh/

tests/Dockerfile Outdated
Comment on lines 17 to 18
RUN chmod 600 /root/.ssh/id_rsa && \
chmod 600 /root/.ssh/id_rsa.pub
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
RUN chmod 600 /root/.ssh/id_rsa && \
chmod 600 /root/.ssh/id_rsa.pub
RUN chmod -R 600 /root/.ssh

@aiordache aiordache force-pushed the replace_paramiko branch 2 times, most recently from f931f46 to 515b23c Compare October 8, 2020 12:55
Copy link
Member

@chris-crone chris-crone left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Once my comments are addressed, this LGTM! Thanks @aiordache!

Comment on lines 86 to 94
if not self.proc or self.proc.stdin.closed:
raise Exception('SSH subprocess not initiated.'
'connect() must be called first.')
self.proc.stdin.write(msg)
self.proc.stdin.flush()

def send(self, msg):
self.sendall(msg)
return len(msg)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: To avoid having to compute the message length separately, I would call send from sendall and use the byte count from the write() function's return.

Suggested change
if not self.proc or self.proc.stdin.closed:
raise Exception('SSH subprocess not initiated.'
'connect() must be called first.')
self.proc.stdin.write(msg)
self.proc.stdin.flush()
def send(self, msg):
self.sendall(msg)
return len(msg)
self.send(msg)
def send(self, msg):
if not self.proc or self.proc.stdin.closed:
raise Exception('SSH subprocess not initiated.'
'connect() must be called first.')
written = self.proc.stdin.write(msg)
self.proc.stdin.flush()
return written

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Py2.7 request library seems to have a problem if we call send from sendall. Moved the logic intro a private method to be called in these two.

self.timeout = timeout
self.host = host

# self.base_url = six.moves.urllib_parse.urlparse(host)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Re-ping on this as I see it's still here

@@ -339,7 +339,6 @@ def test_build_with_extra_hosts(self):

assert self.client.inspect_image(img_name)
ctnr = self.run_container(img_name, 'cat /hosts-file')
self.tmp_containers.append(ctnr)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I haven't dived into the code but why this change?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The self.run_container already appends it to the list so there is no need to do it after.

@aiordache aiordache force-pushed the replace_paramiko branch 3 times, most recently from 66fa566 to a54e94f Compare October 13, 2020 08:34
Signed-off-by: aiordache <anca.iordache@docker.com>
@aiordache aiordache merged commit e09b070 into docker:master Oct 16, 2020
@aiordache aiordache added this to the 4.4.0 milestone Nov 23, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Replace paramiko with the local ssh client
3 participants