question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

passsing named 'options' argument to asyncssh.connect seems broken

See original GitHub issue

I had some working code with asyncssh==2.4.2, now I upgraded to asyncssh==2.9.0 and asyncssh.connect() began to fail. The code looks like this:

opts = asyncssh.SSHClientConnectionOptions(
	keepalive_interval = 10,
	username = user,
	client_keys = keys,
	kex_algs = ...
	#and so on
)
async with asyncssh.connect(host, options = opts, config = None) as conn:
	#...

After the upgrade I began to get immediately asyncssh.misc.ConnectionLost: Connection lost, turned on debug logging and saw a Proxy command there (the one that I use in ~/.ssh/config), which means that neither config = None nor options = opts are applied now (or just config = None? I don’t know actually because the ignored config prevents the further connection). Now, if I call it like this - async with asyncssh.connect(host, config = None, **opts) as conn: - it works again. So the problems are:

  • either docs are out-of-date or named options passing got broken, probably affecting config
  • would be great to see in info/debug logging that some ssh config file was loaded and used (it was very confusing too see that Proxy command)

Issue Analytics

  • State:closed
  • Created 2 years ago
  • Comments:9 (8 by maintainers)

github_iconTop GitHub Comments

1reaction
ronfcommented, Aug 2, 2022

My pleasure - this was an interesting one. Let me know if you have any trouble with the change!

1reaction
ronfcommented, Feb 6, 2022

Ok - I’ve managed to change the model as I described above.

Previously, if an options object was passed in on the connect() and no config argument was specified when creating that object, the default SSH config file would be loaded at the time the options object was created. To avoid this, “config=None” had to be specified when creating the options. Loading the config early prevented some conditionals from being evaluated properly, since information to match those conditionals against wasn’t available yet. Also, leaving “config” unset when creating the options object meant that “config=None” in the connect() call could not be honored since the default config was already loaded before connect() was called.

With this change, the decision about whether to load the default config or not is deferred until the connect() call when config is not specified in either the options object creating or in the connect() call. This delay also means that specifying “config=None” on the connect() call now properly prevents the default config file from being loaded.

Here’s a more detailed summary of the old/new behavior:

When options is not specified at all on connect() call:

  • When config is specified in connect(): Attempt to load specified config (UNCHANGED)
  • When config is not specified on connect(): Attempt to load default config, if present (UNCHANGED)
  • When config is explicitly set to None on connect(): Don’t load any config (UNCHANGED)

When options is specified on connect(), but no config was specified when creating options:

  • When config is specified in connect(): Attempt to load specified config (CHANGED)
    • Previously, this would attempt to load the default config when options was created and then add the specified config later in connect(), but any settings from the default config would take precedence.
  • When config is not specified on connect(): Attempt to load default config at connect() time, if present (CHANGED)
    • Previously this would attempt to load the default config earlier, when options was created. This meant that some conditionals in the config might not be evaluated correctly, as the information wasn’t available yet.
  • When config is explicitly set to None on connect(): Don’t load any config (CHANGED)
    • Previously, the default config was already loaded when options was created and setting None here couldn’t prevent this.

When options is specified on connect() and config is specified when creating options:

  • When config is specified in connect(): Attempt to load both config in options and config on connect() (UNCHANGED)
    • As before, there are limitations on this, as many config settings will get “locked in” at the time the options was created and not be affected by the additional config file loaded on the connect().
  • When config is not specified on connect(): Load only the config specified in options (UNCHANGED)
  • When config is explicitly set to None on connect(): Load only the config specified in options (UNCHANGED)

The documentation under connect(), listen_reverse(), and get_server_host_key() has also been updated to describe the new behavior.

This change is now available as commit 2809f70 in the “develop” branch. Feedback is welcome!

Read more comments on GitHub >

github_iconTop Results From Across the Web

AsyncSSH: Asynchronous SSH for Python — AsyncSSH 2.12 ...
The following code shows an example of a simple SSH client which logs into localhost and lists files in a directory named 'abc'...
Read more >
Cannot run simple client · Issue #418 · ronf/asyncssh - GitHub
This doesn't run at all. import asyncio, asyncssh, sys async def run_client(): async with asyncssh.connect('192.168.1.2', username="root", ...
Read more >
asyncssh - Bountysource
AsyncSSH is a Python package which provides an asynchronous client and server implementation of the SSHv2 protocol on top of the Python asyncio...
Read more >
asyncssh - PyPI
import asyncio, asyncssh, sys async def run_client(): async with asyncssh.connect('localhost') as conn: result = await conn.run('echo "Hello!
Read more >
Mastering Python for Networking and Security - EBIN.PUB
It supports both argument flags (either present or not) and arguments with values. • It supports different formats of passing arguments.
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found