config:url_fetch_method: allow curl args (#49712)
Signed-off-by: Gregory Becker <becker33@llnl.gov>
This commit is contained in:
parent
91b3afac88
commit
ca64050f6a
@ -155,7 +155,8 @@ to use the same syntax used by many other applications that automatically
|
|||||||
detect custom certificates.
|
detect custom certificates.
|
||||||
When ``url_fetch_method:curl`` the ``config:ssl_certs`` should resolve to
|
When ``url_fetch_method:curl`` the ``config:ssl_certs`` should resolve to
|
||||||
a single file. Spack will then set the environment variable ``CURL_CA_BUNDLE``
|
a single file. Spack will then set the environment variable ``CURL_CA_BUNDLE``
|
||||||
in the subprocess calling ``curl``.
|
in the subprocess calling ``curl``. If additional ``curl`` arguments are required,
|
||||||
|
they can be set in the config, e.g. ``url_fetch_method:'curl -k -q'``.
|
||||||
If ``url_fetch_method:urllib`` then files and directories are supported i.e.
|
If ``url_fetch_method:urllib`` then files and directories are supported i.e.
|
||||||
``config:ssl_certs:$SSL_CERT_FILE`` or ``config:ssl_certs:$SSL_CERT_DIR``
|
``config:ssl_certs:$SSL_CERT_FILE`` or ``config:ssl_certs:$SSL_CERT_DIR``
|
||||||
will work.
|
will work.
|
||||||
|
@ -295,8 +295,9 @@ def fetch(self):
|
|||||||
)
|
)
|
||||||
|
|
||||||
def _fetch_from_url(self, url):
|
def _fetch_from_url(self, url):
|
||||||
if spack.config.get("config:url_fetch_method") == "curl":
|
fetch_method = spack.config.get("config:url_fetch_method", "urllib")
|
||||||
return self._fetch_curl(url)
|
if fetch_method.startswith("curl"):
|
||||||
|
return self._fetch_curl(url, config_args=fetch_method.split()[1:])
|
||||||
else:
|
else:
|
||||||
return self._fetch_urllib(url)
|
return self._fetch_urllib(url)
|
||||||
|
|
||||||
@ -345,7 +346,7 @@ def _fetch_urllib(self, url):
|
|||||||
self._check_headers(str(response.headers))
|
self._check_headers(str(response.headers))
|
||||||
|
|
||||||
@_needs_stage
|
@_needs_stage
|
||||||
def _fetch_curl(self, url):
|
def _fetch_curl(self, url, config_args=[]):
|
||||||
save_file = None
|
save_file = None
|
||||||
partial_file = None
|
partial_file = None
|
||||||
if self.stage.save_filename:
|
if self.stage.save_filename:
|
||||||
@ -374,7 +375,7 @@ def _fetch_curl(self, url):
|
|||||||
timeout = self.extra_options.get("timeout")
|
timeout = self.extra_options.get("timeout")
|
||||||
|
|
||||||
base_args = web_util.base_curl_fetch_args(url, timeout)
|
base_args = web_util.base_curl_fetch_args(url, timeout)
|
||||||
curl_args = save_args + base_args + cookie_args
|
curl_args = config_args + save_args + base_args + cookie_args
|
||||||
|
|
||||||
# Run curl but grab the mime type from the http headers
|
# Run curl but grab the mime type from the http headers
|
||||||
curl = self.curl
|
curl = self.curl
|
||||||
|
@ -100,7 +100,7 @@
|
|||||||
"allow_sgid": {"type": "boolean"},
|
"allow_sgid": {"type": "boolean"},
|
||||||
"install_status": {"type": "boolean"},
|
"install_status": {"type": "boolean"},
|
||||||
"binary_index_root": {"type": "string"},
|
"binary_index_root": {"type": "string"},
|
||||||
"url_fetch_method": {"type": "string", "enum": ["urllib", "curl"]},
|
"url_fetch_method": {"type": "string", "pattern": r"^urllib$|^curl( .*)*"},
|
||||||
"additional_external_search_paths": {"type": "array", "items": {"type": "string"}},
|
"additional_external_search_paths": {"type": "array", "items": {"type": "string"}},
|
||||||
"binary_index_ttl": {"type": "integer", "minimum": 0},
|
"binary_index_ttl": {"type": "integer", "minimum": 0},
|
||||||
"aliases": {"type": "object", "patternProperties": {r"\w[\w-]*": {"type": "string"}}},
|
"aliases": {"type": "object", "patternProperties": {r"\w[\w-]*": {"type": "string"}}},
|
||||||
|
@ -109,6 +109,26 @@ def test_fetch_options(tmp_path, mock_archive):
|
|||||||
assert filecmp.cmp(fetcher.archive_file, mock_archive.archive_file)
|
assert filecmp.cmp(fetcher.archive_file, mock_archive.archive_file)
|
||||||
|
|
||||||
|
|
||||||
|
def test_fetch_curl_options(tmp_path, mock_archive, monkeypatch):
|
||||||
|
with spack.config.override("config:url_fetch_method", "curl -k -q"):
|
||||||
|
fetcher = fs.URLFetchStrategy(
|
||||||
|
url=mock_archive.url, fetch_options={"cookie": "True", "timeout": 10}
|
||||||
|
)
|
||||||
|
|
||||||
|
def check_args(*args, **kwargs):
|
||||||
|
# Raise StopIteration to avoid running the rest of the fetch method
|
||||||
|
# args[0] is `which curl`, next two are our config options
|
||||||
|
assert args[1:3] == ("-k", "-q")
|
||||||
|
raise StopIteration
|
||||||
|
|
||||||
|
monkeypatch.setattr(type(fetcher.curl), "__call__", check_args)
|
||||||
|
|
||||||
|
with Stage(fetcher, path=str(tmp_path)):
|
||||||
|
assert fetcher.archive_file is None
|
||||||
|
with pytest.raises(StopIteration):
|
||||||
|
fetcher.fetch()
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.parametrize("_fetch_method", ["curl", "urllib"])
|
@pytest.mark.parametrize("_fetch_method", ["curl", "urllib"])
|
||||||
def test_archive_file_errors(tmp_path, mutable_config, mock_archive, _fetch_method):
|
def test_archive_file_errors(tmp_path, mutable_config, mock_archive, _fetch_method):
|
||||||
"""Ensure FetchStrategy commands may only be used as intended"""
|
"""Ensure FetchStrategy commands may only be used as intended"""
|
||||||
|
@ -388,9 +388,9 @@ def fetch_url_text(url, curl: Optional[Executable] = None, dest_dir="."):
|
|||||||
|
|
||||||
fetch_method = spack.config.get("config:url_fetch_method")
|
fetch_method = spack.config.get("config:url_fetch_method")
|
||||||
tty.debug("Using '{0}' to fetch {1} into {2}".format(fetch_method, url, path))
|
tty.debug("Using '{0}' to fetch {1} into {2}".format(fetch_method, url, path))
|
||||||
if fetch_method == "curl":
|
if fetch_method.startswith("curl"):
|
||||||
curl_exe = curl or require_curl()
|
curl_exe = curl or require_curl()
|
||||||
curl_args = ["-O"]
|
curl_args = fetch_method.split()[1:] + ["-O"]
|
||||||
curl_args.extend(base_curl_fetch_args(url))
|
curl_args.extend(base_curl_fetch_args(url))
|
||||||
|
|
||||||
# Curl automatically downloads file contents as filename
|
# Curl automatically downloads file contents as filename
|
||||||
@ -436,15 +436,14 @@ def url_exists(url, curl=None):
|
|||||||
url_result = urllib.parse.urlparse(url)
|
url_result = urllib.parse.urlparse(url)
|
||||||
|
|
||||||
# Use curl if configured to do so
|
# Use curl if configured to do so
|
||||||
use_curl = spack.config.get(
|
fetch_method = spack.config.get("config:url_fetch_method", "urllib")
|
||||||
"config:url_fetch_method", "urllib"
|
use_curl = fetch_method.startswith("curl") and url_result.scheme not in ("gs", "s3")
|
||||||
) == "curl" and url_result.scheme not in ("gs", "s3")
|
|
||||||
if use_curl:
|
if use_curl:
|
||||||
curl_exe = curl or require_curl()
|
curl_exe = curl or require_curl()
|
||||||
|
|
||||||
# Telling curl to fetch the first byte (-r 0-0) is supposed to be
|
# Telling curl to fetch the first byte (-r 0-0) is supposed to be
|
||||||
# portable.
|
# portable.
|
||||||
curl_args = ["--stderr", "-", "-s", "-f", "-r", "0-0", url]
|
curl_args = fetch_method.split()[1:] + ["--stderr", "-", "-s", "-f", "-r", "0-0", url]
|
||||||
if not spack.config.get("config:verify_ssl"):
|
if not spack.config.get("config:verify_ssl"):
|
||||||
curl_args.append("-k")
|
curl_args.append("-k")
|
||||||
_ = curl_exe(*curl_args, fail_on_error=False, output=os.devnull)
|
_ = curl_exe(*curl_args, fail_on_error=False, output=os.devnull)
|
||||||
|
Loading…
Reference in New Issue
Block a user