Merge pull request #1285 from minrk/rmmran

Microsoft killed MRAN, stop relying on it
pull/1288/head
Min RK 2023-06-12 10:20:18 +02:00 zatwierdzone przez GitHub
commit 0ea6f7d85e
Nie znaleziono w bazie danych klucza dla tego podpisu
ID klucza GPG: 4AEE18F83AFDEB23
12 zmienionych plików z 31 dodań i 83 usunięć

Wyświetl plik

@ -118,7 +118,7 @@ with ``REQUIRE`` and ``environment.yml``, visit
================================================
This is used to install R libraries pinned to a specific snapshot on
`MRAN <https://mran.microsoft.com/documents/rro/reproducibility>`_.
`Posit Package Manager <https://packagemanager.posit.co/>`_.
To set the date of the snapshot add a runtime.txt_.
For an example ``install.R`` file, visit our `example install.R file <https://github.com/binder-examples/r/blob/HEAD/install.R>`_.
@ -207,7 +207,7 @@ For these cases, we have a special file, ``runtime.txt``.
Have ``python-x.y`` in ``runtime.txt`` to run the repository with Python version x.y.
See our `Python2 example repository <https://github.com/binder-examples/python2_runtime/blob/HEAD/runtime.txt>`_.
Have ``r-<RVERSION>-<YYYY>-<MM>-<DD>`` in ``runtime.txt`` to run the repository with R version RVERSION and libraries from a YYYY-MM-DD snapshot of `MRAN <https://mran.microsoft.com/documents/rro/reproducibility>`_.
Have ``r-<RVERSION>-<YYYY>-<MM>-<DD>`` in ``runtime.txt`` to run the repository with R version RVERSION and libraries from a YYYY-MM-DD snapshot of `Posit Package Manager <https://packagemanager.posit.co/client/#/repos/2/overview>`__.
RVERSION can be set to 3.4, 3.5, 3.6, or to patch releases for the 3.5 and 3.6 series.
If you do not specify a version, the latest release will be used (currently R 3.6).
See our `R example repository <https://github.com/binder-examples/r/blob/HEAD/runtime.txt>`_.

Wyświetl plik

@ -65,17 +65,14 @@ to install libraries from on the given date. You can install more R packages fro
by adding a :ref:`install.R<install.R>` file to your repo. RStudio and IRKernel are
installed by default for all R versions.
If you request R 4.1 or later, or specify a snapshot date newer than
``2022-01-01``, `packagemanager.posit.co <https://packagemanager.posit.co/client/#/>`_
`packagemanager.posit.co <https://packagemanager.posit.co/client/#/>`_
will be used to provide much faster installations via `binary packages <https://www.rstudio.com/blog/package-manager-v1-1-no-interruptions/>`_.
For *some* packages, this might require you install underlying system libraries
using :ref:`apt.txt` - look at the page for the CRAN package you are interested in at
`packagemanager.posit.co <https://packagemanager.posit.co/client/#/>`_ to find
a list.
For older R versions with an older snapshot date, `MRAN <https://mran.microsoft.com/>`_
is used as source of packages. This purely provides source packages, and you should
migrate away from this if possible.
repo2docker stopped using the Microsoft mirror MRAN for older R versions after its shutdown in July, 2023.
Julia

Wyświetl plik

@ -9,6 +9,10 @@ from ..semver import parse_version as V
from ._r_base import rstudio_base_scripts
from .python import PythonBuildPack
# Aproximately the first snapshot on RSPM (Posit package manager)
# that seems to have a working IRKernel.
RSPM_CUTOFF_DATE = datetime.date(2018, 12, 7)
class RBuildPack(PythonBuildPack):
"""
@ -22,8 +26,7 @@ class RBuildPack(PythonBuildPack):
Where 'year', 'month' and 'date' refer to a specific
date whose CRAN snapshot we will use to fetch packages.
Uses https://packagemanager.posit.co, or MRAN if no snapshot
is found on packagemanager.posit.co
Uses https://packagemanager.posit.co.
2. A `DESCRIPTION` file signaling an R package
@ -229,31 +232,6 @@ class RBuildPack(PythonBuildPack):
)
)
@lru_cache()
def get_mran_snapshot_url(self, snapshot_date, max_days_prior=7):
for i in range(max_days_prior):
try_date = snapshot_date - datetime.timedelta(days=i)
# Fall back to MRAN if packagemanager.posit.co doesn't have it
url = f"https://mran.microsoft.com/snapshot/{try_date.isoformat()}"
r = requests.head(url)
if r.ok:
return url
raise ValueError(
"No snapshot found for {} or {} days prior in mran.microsoft.com".format(
snapshot_date.strftime("%Y-%m-%d"), max_days_prior
)
)
@lru_cache()
def get_cran_mirror_url(self, snapshot_date):
# Date after which we will use rspm + binary packages instead of MRAN + source packages
rspm_cutoff_date = datetime.date(2022, 1, 1)
if snapshot_date >= rspm_cutoff_date or self.r_version >= V("4.1"):
return self.get_rspm_snapshot_url(snapshot_date)
else:
return self.get_mran_snapshot_url(snapshot_date)
@lru_cache()
def get_devtools_snapshot_url(self):
"""
@ -291,8 +269,14 @@ class RBuildPack(PythonBuildPack):
We set the snapshot date used to install R libraries from based on the
contents of runtime.txt.
"""
if self.checkpoint_date < RSPM_CUTOFF_DATE:
raise RuntimeError(
f'Microsoft killed MRAN, the source of R package snapshots before {RSPM_CUTOFF_DATE.strftime("%Y-%m-%d")}. '
f'This repo has a snapshot date of {self.checkpoint_date.strftime("%Y-%m-%d")} specified in runtime.txt. '
"Please use a newer snapshot date"
)
cran_mirror_url = self.get_cran_mirror_url(self.checkpoint_date)
cran_mirror_url = self.get_rspm_snapshot_url(self.checkpoint_date)
if self.platform != "linux/amd64":
raise RuntimeError(

Wyświetl plik

@ -24,18 +24,6 @@
`runtime.txt` is omitted and a recent enough snapshot date is assumed a RSPM
snapshot of CRAN to be used.
### r3.6-mran
- Test setup of a R 3.6 environment by specifying `r-3.6-...` in `runtime.txt`,
where the date provided in `runtime.txt` is old enough for a MRAN snapshot of
CRAN to be used.
### r4.0-mran
- Test setup of a R 4.0 environment by specifying `r-4.0-...` in `runtime.txt`,
where the date provided in `runtime.txt` is old enough for a MRAN snapshot of
CRAN to be used.
### r4.0-rspm
- Test setup of a R 4.0 environment by specifying `r-4.0-...` in `runtime.txt`,

Wyświetl plik

@ -1 +0,0 @@
r-3.6-2016-01-03

Wyświetl plik

@ -0,0 +1 @@
r-3.6-2018-12-07

Wyświetl plik

@ -7,7 +7,7 @@ if (!(version$major == "3" && as.double(version$minor) >= 6 && as.double(version
quit("yes", 1)
}
# Fail if MRAN isn't the configured CRAN mirror
if (!(startsWith(options()$repos["CRAN"], "https://mran.microsoft.com"))) {
# Fail if RSPM isn't the configured CRAN mirror
if (!(startsWith(options()$repos["CRAN"], "https://packagemanager.posit.co"))) {
quit("yes", 1)
}

Wyświetl plik

@ -1 +0,0 @@
install.packages("digest")

Wyświetl plik

@ -1 +0,0 @@
r-4.0-2021-07-07

Wyświetl plik

@ -1,13 +0,0 @@
#!/usr/bin/env Rscript
library('digest')
# Fail if version is not 4.0
print(version)
if (!(version$major == "4" && as.double(version$minor) >= 0 && as.double(version$minor) < 1)) {
quit("yes", 1)
}
# The date we have chosen should give us an MRAN mirror
if (!(startsWith(options()$repos["CRAN"], "https://mran.microsoft.com"))) {
quit("yes", 1)
}

Wyświetl plik

@ -40,7 +40,7 @@ def test_version_completion(tmpdir, base_image):
("r-3.5-2019-01-01", (2019, 1, 1)),
],
)
def test_mran_date(tmpdir, runtime, expected, base_image):
def test_cran_date(tmpdir, runtime, expected, base_image):
tmpdir.chdir()
with open("runtime.txt", "w") as f:
@ -74,21 +74,15 @@ def test_snapshot_rspm_date(base_image):
r.get_rspm_snapshot_url(date(1691, 9, 5))
@pytest.mark.parametrize("expected", [date(2019, 12, 29), date(2019, 12, 26)])
@pytest.mark.parametrize("requested", [date(2019, 12, 31)])
def test_snapshot_mran_date(requested, expected, base_image):
def mock_request_head(url):
r = Response()
if url == "https://mran.microsoft.com/snapshot/" + expected.isoformat():
r.status_code = 200
else:
r.status_code = 404
r.reason = "Mock MRAN no snapshot"
return r
def test_mran_dead(tmpdir, base_image):
tmpdir.chdir()
with patch("requests.head", side_effect=mock_request_head):
r = buildpacks.RBuildPack(base_image)
assert (
r.get_mran_snapshot_url(requested)
== f"https://mran.microsoft.com/snapshot/{expected.isoformat()}"
)
with open("runtime.txt", "w") as f:
f.write("r-3.6-2017-06-04")
r = buildpacks.RBuildPack(base_image)
with pytest.raises(
RuntimeError,
match=r"^Microsoft killed MRAN, the source of R package snapshots before 2018-12-07.*",
):
r.get_build_scripts()