dvc: DVC push hangs when pushing via SSH

DVC version: dvc[ssh]==2.3.0 (I have also tried to downgrade to 2.2.0 and 2.1.0, same result unfortunately) OS: Windows 10 Python version: 3.9.5

I am trying to set up a data registry on a SFTP server. I have dvc added all my files, set up the remote:

dvc remote add -d myremote ssh://user@example.com

and set up the password of this user on this server:

dvc remote modify --local myremote password mypassword

However, when I push, I see it’s checking my local cache (this works), but eventually it gets stuck here:

0% Querying cache in ssh://user@example.com|                                                   |0.00/180k [00:00<?,     ?file/s]

I let it run for about 10 minutes, but still no progress. I then tried to ssh to the server using PowerShell, which also kept hanging after I entered the password. But when I stopped the terminal that dvc push was running in, the ssh in PowerShell stopped hanging and I was in the server.

About this issue

  • Original URL
  • State: closed
  • Created 3 years ago
  • Comments: 21 (16 by maintainers)

Most upvoted comments

@gcoter this seems like something related to the server itself. Do you know if there are any changed limits in regards to maximum number of sessions? Or can you try to run the following script with filling the options necessary to authenticate and paste the output?

import asyncio
import asyncssh
from contextlib import AsyncExitStack

async def main():
    async with asyncssh.connect(
        host=<INSERT_HOST>,
        username=<INSERT_USERNAME>,
        password=<INSERT_PASSWORD>,
        client_keys=[<INSERT_CLIENT_KEY>]
        known_hosts=None
    ) as client:
        print('connected')
        stack = AsyncExitStack()
        for n in range(25):
            print(f'Opening channel {n}')
            channel = await stack.enter_async_context(client.start_sftp_client())
            await channel.stat("/tmp")

asyncio.run(main())

Did some further tests. One of them was to let a colleague set up part of the data registry on their laptop and try to push it to the same server. He failed at the same point.

Something that I also find strange is that DVC opens up 4 connections when executing dvc push -j 1. Shouldn’t this mean that there should only be one connection?

We also found out that when I close the terminal window (the only way I can stop the hanging process), 3 connections are closed on the server, but 1 always stays alive for some reason. Even though I don’t kill the push command in the nicest way, I think it’s strange that this 1 process is not cleaned up properly.

It is really weird since I can’t reproduce this locally. Config parameters always take precedence over the remote url ones (e.g ssh://username@host.com will be overriden if the config specifies another username). Can you a new issue @sjawhar?

I’m running into the same “Can’t create any SFTP connections” error. Ran the debug script from @isidentical and get the same output as @gcoter (error after 10). Tried --jobs 1, still error.

Update I’ve been using a local config that sets the remote user in config.local. I switched that to overriding the entire SSH url with the user included (e.g. ssh://username@host.com) and now it works. @gcoter are you also using any kind of config override to set the SSH username?

Hi @isidentical, thanks for your answer 🙂 I ran your script and here is the output:

connected
Opening channel 0
Opening channel 1
Opening channel 2
Opening channel 3
Opening channel 4
Opening channel 5
Opening channel 6
Opening channel 7
Opening channel 8
Opening channel 9
Opening channel 10
Traceback (most recent call last):
  File "test_dvc.py", line 20, in <module>
    asyncio.run(main())
  File "/usr/lib/python3.8/asyncio/runners.py", line 44, in run
    return loop.run_until_complete(main)
  File "/usr/lib/python3.8/asyncio/base_events.py", line 616, in run_until_complete
    return future.result()
  File "test_dvc.py", line 17, in main
    channel = await stack.enter_async_context(client.start_sftp_client())
  File "/usr/lib/python3.8/contextlib.py", line 568, in enter_async_context
    result = await _cm_type.__aenter__(cm)
  File "/home/gcoter/.cache/pypoetry/virtualenvs/music-generation-v2-7Nqe6-3y-py3.8/lib/python3.8/site-packages/asyncssh/misc.py", line 220, in __aenter__
    self._result = await self._coro
  File "/home/gcoter/.cache/pypoetry/virtualenvs/music-generation-v2-7Nqe6-3y-py3.8/lib/python3.8/site-packages/asyncssh/connection.py", line 4302, in start_sftp_client
    writer, reader, _ = await self.open_session(subsystem='sftp',
  File "/home/gcoter/.cache/pypoetry/virtualenvs/music-generation-v2-7Nqe6-3y-py3.8/lib/python3.8/site-packages/asyncssh/connection.py", line 3469, in open_session
    chan, session = await self.create_session(SSHClientStreamSession,
  File "/home/gcoter/.cache/pypoetry/virtualenvs/music-generation-v2-7Nqe6-3y-py3.8/lib/python3.8/site-packages/asyncssh/connection.py", line 3445, in create_session
    session = await chan.create(session_factory, command, subsystem,
  File "/home/gcoter/.cache/pypoetry/virtualenvs/music-generation-v2-7Nqe6-3y-py3.8/lib/python3.8/site-packages/asyncssh/channel.py", line 1015, in create
    packet = await self._open(b'session')
  File "/home/gcoter/.cache/pypoetry/virtualenvs/music-generation-v2-7Nqe6-3y-py3.8/lib/python3.8/site-packages/asyncssh/channel.py", line 635, in _open
    return await self._open_waiter
asyncssh.misc.ChannelOpenError: open failed

I had to replace “/tmp” with another folder name (because tmp does not exist on this sftp server). Apart from that, I did not change your script.

Regarding the server, I did not make any change myself for a while. Of course, it had some updates, but I don’t remember that anything related to the number of sessions was modified.

When we look at the output, it seems like there is a limit of 10 sessions apparently?

@efiop I tried version 2.7.4, I still have the same error:

$ dvc push -v -a -j 1
2021-10-03 14:11:11,126 DEBUG: Preparing to transfer data from '.dvc/cache' to 'ssh://<REMOTE URL>/gcoter/music-generation-v2.dvc'
2021-10-03 14:11:11,127 DEBUG: Preparing to collect status from 'ssh://<REMOTE URL>/gcoter/music-generation-v2.dvc'
2021-10-03 14:11:11,144 DEBUG: Collecting status from 'ssh://<REMOTE URL>/gcoter/music-generation-v2.dvc'
2021-10-03 14:11:11,748 DEBUG: Querying 38 hashes via object_exists
2021-10-03 14:11:40,840 ERROR: unexpected error - Can't create any SFTP connections!                                                     
------------------------------------------------------------
Traceback (most recent call last):
  File "/home/gcoter/.cache/pypoetry/virtualenvs/music-generation-v2-7Nqe6-3y-py3.8/lib/python3.8/site-packages/dvc/main.py", line 55, in main
    ret = cmd.do_run()
  File "/home/gcoter/.cache/pypoetry/virtualenvs/music-generation-v2-7Nqe6-3y-py3.8/lib/python3.8/site-packages/dvc/command/base.py", line 45, in do_run
    return self.run()
  File "/home/gcoter/.cache/pypoetry/virtualenvs/music-generation-v2-7Nqe6-3y-py3.8/lib/python3.8/site-packages/dvc/command/data_sync.py", line 57, in run
    processed_files_count = self.repo.push(
  File "/home/gcoter/.cache/pypoetry/virtualenvs/music-generation-v2-7Nqe6-3y-py3.8/lib/python3.8/site-packages/dvc/repo/__init__.py", line 50, in wrapper
    return f(repo, *args, **kwargs)
  File "/home/gcoter/.cache/pypoetry/virtualenvs/music-generation-v2-7Nqe6-3y-py3.8/lib/python3.8/site-packages/dvc/repo/push.py", line 48, in push
    pushed += self.cloud.push(obj_ids, jobs, remote=remote, odb=odb)
  File "/home/gcoter/.cache/pypoetry/virtualenvs/music-generation-v2-7Nqe6-3y-py3.8/lib/python3.8/site-packages/dvc/data_cloud.py", line 85, in push
    return transfer(
  File "/home/gcoter/.cache/pypoetry/virtualenvs/music-generation-v2-7Nqe6-3y-py3.8/lib/python3.8/site-packages/dvc/objects/transfer.py", line 153, in transfer
    status = compare_status(src, dest, obj_ids, check_deleted=False, **kwargs)
  File "/home/gcoter/.cache/pypoetry/virtualenvs/music-generation-v2-7Nqe6-3y-py3.8/lib/python3.8/site-packages/dvc/objects/status.py", line 160, in compare_status
    dest_exists, dest_missing = status(
  File "/home/gcoter/.cache/pypoetry/virtualenvs/music-generation-v2-7Nqe6-3y-py3.8/lib/python3.8/site-packages/dvc/objects/status.py", line 122, in status
    exists = hashes.intersection(
  File "/home/gcoter/.cache/pypoetry/virtualenvs/music-generation-v2-7Nqe6-3y-py3.8/lib/python3.8/site-packages/dvc/objects/status.py", line 36, in _indexed_dir_hashes
    indexed_dir_exists.update(odb.list_hashes_exists(indexed_dirs))
  File "/home/gcoter/.cache/pypoetry/virtualenvs/music-generation-v2-7Nqe6-3y-py3.8/lib/python3.8/site-packages/dvc/objects/db/base.py", line 415, in list_hashes_exists
    ret = list(itertools.compress(hashes, in_remote))
  File "/usr/lib/python3.8/concurrent/futures/_base.py", line 619, in result_iterator
    yield fs.pop().result()
  File "/usr/lib/python3.8/concurrent/futures/_base.py", line 437, in result
    return self.__get_result()
  File "/usr/lib/python3.8/concurrent/futures/_base.py", line 389, in __get_result
    raise self._exception
  File "/usr/lib/python3.8/concurrent/futures/thread.py", line 57, in run
    result = self.fn(*self.args, **self.kwargs)
  File "/home/gcoter/.cache/pypoetry/virtualenvs/music-generation-v2-7Nqe6-3y-py3.8/lib/python3.8/site-packages/dvc/objects/db/base.py", line 406, in exists_with_progress
    ret = self.fs.exists(path_info)
  File "/home/gcoter/.cache/pypoetry/virtualenvs/music-generation-v2-7Nqe6-3y-py3.8/lib/python3.8/site-packages/dvc/fs/fsspec_wrapper.py", line 97, in exists
    return self.fs.exists(self._with_bucket(path_info))
  File "/home/gcoter/.cache/pypoetry/virtualenvs/music-generation-v2-7Nqe6-3y-py3.8/lib/python3.8/site-packages/fsspec/asyn.py", line 91, in wrapper
    return sync(self.loop, func, *args, **kwargs)
  File "/home/gcoter/.cache/pypoetry/virtualenvs/music-generation-v2-7Nqe6-3y-py3.8/lib/python3.8/site-packages/fsspec/asyn.py", line 71, in sync
    raise return_result
  File "/home/gcoter/.cache/pypoetry/virtualenvs/music-generation-v2-7Nqe6-3y-py3.8/lib/python3.8/site-packages/fsspec/asyn.py", line 25, in _runner
    result[0] = await coro
  File "/home/gcoter/.cache/pypoetry/virtualenvs/music-generation-v2-7Nqe6-3y-py3.8/lib/python3.8/site-packages/fsspec/asyn.py", line 480, in _exists
    await self._info(path)
  File "/home/gcoter/.cache/pypoetry/virtualenvs/music-generation-v2-7Nqe6-3y-py3.8/lib/python3.8/site-packages/sshfs/utils.py", line 27, in wrapper
    return await func(*args, **kwargs)
  File "/home/gcoter/.cache/pypoetry/virtualenvs/music-generation-v2-7Nqe6-3y-py3.8/lib/python3.8/site-packages/sshfs/spec.py", line 135, in _info
    async with self._pool.get() as channel:
  File "/usr/lib/python3.8/contextlib.py", line 171, in __aenter__
    return await self.gen.__anext__()
  File "/home/gcoter/.cache/pypoetry/virtualenvs/music-generation-v2-7Nqe6-3y-py3.8/lib/python3.8/site-packages/sshfs/pools/soft.py", line 38, in get
    raise ValueError("Can't create any SFTP connections!")
ValueError: Can't create any SFTP connections!
------------------------------------------------------------
2021-10-03 14:11:41,203 DEBUG: Version info for developers:
DVC version: 2.7.4 (pip)
---------------------------------
Platform: Python 3.8.10 on Linux-5.4.0-88-generic-x86_64-with-glibc2.29
Supports:
	http (aiohttp = 3.7.4.post0, aiohttp-retry = 2.4.5),
	https (aiohttp = 3.7.4.post0, aiohttp-retry = 2.4.5),
	ssh (sshfs = 2021.9.0)
Cache types: hardlink, symlink
Cache directory: ext4 on /dev/sda5
Caches: local
Remotes: ssh
Workspace directory: ext4 on /dev/sda5
Repo: dvc, git

Having any troubles? Hit us up at https://dvc.org/support, we are always happy to help!
2021-10-03 14:11:41,205 DEBUG: Analytics is enabled.
2021-10-03 14:11:41,267 DEBUG: Trying to spawn '['daemon', '-q', 'analytics', '/tmp/tmp8qood5j9']'
2021-10-03 14:11:41,269 DEBUG: Spawned '['daemon', '-q', 'analytics', '/tmp/tmp8qood5j9']'

@efiop Yes, SSH and SFTP CLI work. I tried with -j 1, I have the same error

Hi! Since we couldnt get the SSH remote working, we switched to another remote type, so I’m not sure if I still have access to that particular server. I’m willing to give it a shot though. How can I install it with the ssh dependency from master branch on Windows?

Something like this? pip install git+git://github.com/iterative/dvc[ssh]