From d30dbd50bc3a5db59061db14df26bf98135bc807 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Saugat=20Pachhai=20=28=E0=A4=B8=E0=A5=8C=E0=A4=97=E0=A4=BE?= =?UTF-8?q?=E0=A4=A4=29?= Date: Fri, 10 Jun 2022 19:29:03 +0545 Subject: [PATCH] run-cache: http: stage cache uploads in http remotes Currently, there is no way to find run-cache in HTTP remotes. In the future, we could use directory-listings from supported webservers to find files. Temporarily, we are restricting the run-cache uploads. This is a bit strict, we could have only restricted the downloads, but it might be more confusing to the users, so I went to categorically restrict stage cache uploads and downloads for http filesystems. --- dvc/stage/cache.py | 19 ++++++++++++++++++- dvc/testing/test_remote.py | 4 ++++ 2 files changed, 22 insertions(+), 1 deletion(-) diff --git a/dvc/stage/cache.py b/dvc/stage/cache.py index 2027b10c9..7a0f4518c 100644 --- a/dvc/stage/cache.py +++ b/dvc/stage/cache.py @@ -22,6 +22,10 @@ class RunCacheNotFoundError(DvcException): super().__init__(f"No run-cache for {stage.addressing}") +class RunCacheNotSupported(DvcException): + pass + + def _get_cache_hash(cache, key=False): from dvc_objects.meta import Meta @@ -213,7 +217,7 @@ class StageCache: cached_stage.checkout() def transfer(self, from_odb, to_odb): - from dvc.fs import LocalFileSystem + from dvc.fs import HTTPFileSystem, LocalFileSystem from dvc.fs.callbacks import Callback from_fs = from_odb.fs @@ -221,6 +225,19 @@ class StageCache: func = _log_exceptions(fs.generic.copy) runs = from_fs.path.join(from_odb.fs_path, "runs") + http_odb = next( + ( + odb + for odb in (from_odb, to_odb) + if isinstance(odb.fs, HTTPFileSystem) + ), + None, + ) + if http_odb: + path = http_odb.fs_path + message = f"run-cache is not supported for http filesystem: {path}" + raise RunCacheNotSupported(message) + ret = [] if not from_fs.exists(runs): return ret diff --git a/dvc/testing/test_remote.py b/dvc/testing/test_remote.py index aefcc288f..c9c869a8f 100644 --- a/dvc/testing/test_remote.py +++ b/dvc/testing/test_remote.py @@ -1,6 +1,9 @@ import os import shutil +import pytest + +from dvc.stage.cache import RunCacheNotSupported from dvc.utils.fs import remove @@ -92,6 +95,7 @@ class TestRemote: status_dir = dvc.cloud.status(dir_hashes) _check_status(status_dir, ok=dir_hashes) + @pytest.mark.xfail(raises=RunCacheNotSupported, strict=False) def test_stage_cache_push_pull(self, tmp_dir, dvc, remote): tmp_dir.gen("foo", "foo") stage = dvc.stage.add(