-
Notifications
You must be signed in to change notification settings - Fork 1.2k
remote: add support for WebDAV #3647
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
Closed
Closed
Changes from all commits
Commits
Show all changes
16 commits
Select commit
Hold shift + click to select a range
12a0a7a
remote: add support for WebDAV
9e8a97b
remote: WebDav Fix deepsource error
5dc4dd8
remote: WebDav Fix: base to the original state. Add WebdavURLInfo. Cr…
4d0d7bb
remote: WebDav Fix build error
441e9f4
remote: WebDav Fix deepsource error
74e8f53
remote: WebDav Fix deepseource error (webdavs)
a997811
remote: WebDav Fix codeclimat
a057c1a
remote: WebDav Fix black code style
87b2d23
remote: WebDav Add tests
0908005
remote: WebDav Fix deepsource
df3dd7b
remote: WebDav Fix tests - delete parametrization
4110f0e
remote: WebDav miss, add scheme in config file
52e8d5a
remote: WebDav If MKCOL returned an error and the path already exists…
3411f34
remote WebDav: add to DEFAULT_PORTS
0d3424e
remote WebDav: add gc
64b5129
remote WebDav: Drop method get_collection in favor parents
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,65 @@ | ||
import os.path | ||
|
||
from .http import RemoteHTTP | ||
from dvc.scheme import Schemes | ||
from dvc.progress import Tqdm | ||
from dvc.exceptions import HTTPError | ||
from dvc.path_info import WebdavURLInfo | ||
|
||
|
||
class RemoteWEBDAV(RemoteHTTP): | ||
scheme = Schemes.WEBDAV | ||
path_cls = WebdavURLInfo | ||
REQUEST_TIMEOUT = 20 | ||
|
||
def _upload(self, from_file, to_info, name=None, no_progress_bar=False): | ||
def chunks(): | ||
with open(from_file, "rb") as fd: | ||
with Tqdm.wrapattr( | ||
fd, | ||
"read", | ||
total=None | ||
if no_progress_bar | ||
else os.path.getsize(from_file), | ||
leave=False, | ||
desc=to_info.url if name is None else name, | ||
disable=no_progress_bar, | ||
) as fd_wrapped: | ||
while True: | ||
chunk = fd_wrapped.read(self.CHUNK_SIZE) | ||
if not chunk: | ||
break | ||
yield chunk | ||
|
||
self._create_collections(to_info) | ||
response = self._request("PUT", to_info.url, data=chunks()) | ||
shizacat marked this conversation as resolved.
Show resolved
Hide resolved
|
||
if response.status_code not in (200, 201): | ||
raise HTTPError(response.status_code, response.reason) | ||
|
||
def _create_collections(self, to_info): | ||
url_cols = [x.url + "/" for x in to_info.parents][:-1] | ||
from_idx = 0 | ||
for idx, url in enumerate(url_cols): | ||
from_idx = idx | ||
if bool(self._request("HEAD", url)): | ||
break | ||
for url in reversed(url_cols[:from_idx]): | ||
response = self._request("MKCOL", url) | ||
if response.status_code not in (200, 201): | ||
if bool(self._request("HEAD", url)): | ||
continue | ||
raise HTTPError(response.status_code, response.reason) | ||
|
||
def remove(self, path_info): | ||
response = self._request("DELETE", path_info.url) | ||
if response.status_code not in (200, 201, 204): | ||
raise HTTPError(response.status_code, response.reason) | ||
|
||
def gc(self): | ||
return super(RemoteHTTP, self).gc() | ||
|
||
def list_cache_paths(self, prefix=None, progress_callback=None): | ||
raise NotImplementedError | ||
|
||
def walk_files(self, path_info): | ||
raise NotImplementedError |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
from .webdav import RemoteWEBDAV | ||
from dvc.scheme import Schemes | ||
|
||
|
||
class RemoteWEBDAVS(RemoteWEBDAV): | ||
scheme = Schemes.WEBDAVS | ||
|
||
def gc(self): | ||
raise NotImplementedError | ||
shcheklein marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
||
def list_cache_paths(self, prefix=None, progress_callback=None): | ||
pmrowla marked this conversation as resolved.
Show resolved
Hide resolved
|
||
raise NotImplementedError | ||
|
||
def walk_files(self, path_info): | ||
raise NotImplementedError |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -9,3 +9,5 @@ class Schemes: | |
GDRIVE = "gdrive" | ||
LOCAL = "local" | ||
OSS = "oss" | ||
WEBDAV = "webdav" | ||
WEBDAVS = "webdavs" |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
import pytest | ||
|
||
from dvc.exceptions import HTTPError | ||
from dvc.path_info import WebdavURLInfo | ||
from dvc.remote.webdav import RemoteWEBDAV | ||
from tests.utils.httpd import StaticFileServer, WebDavSimpleHandler | ||
|
||
|
||
def test_create_collections(dvc): | ||
with StaticFileServer(handler_class=WebDavSimpleHandler) as httpd: | ||
url0 = "webdav://localhost:{}/a/b/file.txt".format(httpd.server_port) | ||
url1 = "webdav://localhost:{}/a/c/file.txt".format(httpd.server_port) | ||
config = {"url": url0} | ||
|
||
remote = RemoteWEBDAV(dvc, config) | ||
|
||
remote._create_collections(WebdavURLInfo(url0)) | ||
|
||
with pytest.raises(HTTPError): | ||
remote._create_collections(WebdavURLInfo(url1)) |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
what about https? webdavs?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If replace in "webdavS" webdav on http will be "httpS"
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
yep, 🤦 sorry :)
Ok, a few concerns still:
url
like this means loosing information. E.g. when we write in logs we will be getting http instead. In general feels like not a good idea creating a discrepancy between what we have inside class and what we return here.Feels like we should be doing it on the Remote class level, or there should be some separate method - access url or something?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It seems to me to do a separate method is over head. It will be necessary to rewrite the entire code from HTTP with one fix, and at the same time, there will still be the possibility use in logs the wrong URL.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, it was merely a random suggestion. The whole approach with overriding
url
feels like a hack and can hit us somewhere down the road. There should be a better way of doing this - e.g. RemoteWebDav class should understand how to deal with those URLs (translate them if needed and pass to HTTPRemote), etc.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actually, makes me think if we should tackle it the other way around by simply adding some flag that will tell HTTP(s) remote to use webdav to access this remote that would otherwise have a normal HTTP(s) URL. Something like
and then
or
or something else. Not sure if this makes sense. It kinda goes against current conventions, but also I'm not sure if webdav is unique enough for a separate remote, maybe it is better to handle it as HTTP with some special tweaks. 🤔
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hack - not sure. The same DEFAULT_PORTS also change the state of the object without notice. The same S3 is HTTP.
Leaving url unchanged - then the purpose of the _BasePath class is not very clear. It seemed to me that he should return the ready-made address format for working with him.
As for - as an extension of http. The more I work with him, the more he is everyday. The same gc. I don’t know how it works, but if only the remote method is needed for it, it’s easy to add and now a big difference from HTTP is already obtained.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Default ports logic is part of the protocols ... e.g. we want to detect that
example.com:80
is the same asexample.com
. In your case you create an object that provides an inconsistent interface - some methods (and some logic internally) might still rely onwebdav
, while url hashttp
. It can be very confusing - you ask and object to print its name - it prints Duck but then behave like Dog.not sure I got this point, could you clarify, please?
Again, not sure I understood this. Btw, we can jump on Discord - dvc.org/chat and discuss this with me and Ruslan (ivan and ruslan there). Please, feel free to ping me/us.