Skip to content
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

Difficulty with rspm when working with renv #24

Open
IanVermes opened this issue May 13, 2024 · 7 comments
Open

Difficulty with rspm when working with renv #24

IanVermes opened this issue May 13, 2024 · 7 comments

Comments

@IanVermes
Copy link

I've been having a little trouble trying to get your package to work for me in a Docker context, and suspect it's my own misunderstanding.

Without renv
I know that working without renv works well, as this minimal Dockerfile works perfectly:

FROM rocker/r-base:4.2.2

RUN apt-get update -yq \
    && apt-get install -yq \
    apt-file

WORKDIR /opt/example

RUN Rscript -e 'install.packages("rspm"); rspm::enable(); install.packages("units")'

With renv

But with renv I'm doing something wrong but can't see what.

I have a small reproducible example where I try to install the units package with rspm and renv.

## Dockerfile
FROM rocker/r-base:4.2.2

RUN apt-get update -yq \
    && apt-get install -yq \
    apt-file

WORKDIR /opt/example

RUN Rscript -e 'install.packages("renv"); renv::init(); renv::install("rspm"); rspm::install_sysreqs()'

RUN Rscript -e 'rspm::renv_init(); renv::install("units")'

Then I run it as follows (Docker version 24.0.5) but fails to build:

docker build --progress plain --no-cache . > build.log 2>&1

And the logs yield the following (complete build.log attached)

...
#8 [5/5] RUN Rscript -e 'rspm::renv_init(); renv::install("units")'
#8 1.484 # Downloading packages -------------------------------------------------------
#8 1.487 - Downloading units from CRAN ...               OK [242.2 Kb]
#8 1.668 - Downloading Rcpp from CRAN ...                OK [3.3 Mb]
#8 1.865 Successfully downloaded 2 packages in 0.57 seconds.
#8 1.865 
#8 1.866 The following package(s) will be installed:
#8 1.866 - Rcpp  [1.0.12]
#8 1.866 - units [0.8-5]
#8 1.866 These packages will be installed into "/opt/example/renv/library/R-4.2/x86_64-pc-linux-gnu".
#8 1.866 
#8 1.866 # Installing packages --------------------------------------------------------
#8 1.931 - Installing Rcpp ...                           OK [built from source and cached in 32s]
#8 34.16 - Installing units ...                          FAILED
#8 35.94 Error: Error installing package 'units':
#8 35.94 =================================
#8 35.94 
#8 35.94 * installing *source* package ‘units’ ...
#8 35.94 ** package ‘units’ successfully unpacked and MD5 sums checked
#8 35.94 ** using staged installation
#8 35.94 configure: units: 0.8-5
#8 35.94 checking whether the C++ compiler works... yes
#8 35.94 checking for C++ compiler default output file name... a.out
#8 35.94 checking for suffix of executables... 
#8 35.94 checking whether we are cross compiling... no
#8 35.94 checking for suffix of object files... o
#8 35.94 checking whether the compiler supports GNU C++... yes
#8 35.94 checking whether g++ -std=gnu++14 accepts -g... yes
#8 35.94 checking for g++ -std=gnu++14 option to enable C++11 features... none needed
#8 35.94 checking for stdio.h... yes
#8 35.94 checking for stdlib.h... yes
#8 35.94 checking for string.h... yes
#8 35.94 checking for inttypes.h... yes
#8 35.94 checking for stdint.h... yes
#8 35.94 checking for strings.h... yes
#8 35.94 checking for sys/stat.h... yes
#8 35.94 checking for sys/types.h... yes
#8 35.94 checking for unistd.h... yes
#8 35.94 checking for _Bool... no
#8 35.94 checking for stdbool.h that conforms to C99... yes
#8 35.94 checking for error_at_line... yes
#8 35.94 checking for gcc... gcc
#8 35.94 checking whether the compiler supports GNU C... yes
#8 35.94 checking whether gcc accepts -g... yes
#8 35.94 checking for gcc option to enable C11 features... none needed
#8 35.94 checking for XML_ParserCreate in -lexpat... no
#8 35.94 checking for udunits2.h... no
#8 35.94 checking for udunits2/udunits2.h... no
#8 35.94 checking for ut_read_xml in -ludunits2... no
#8 35.94 configure: error: in `/tmp/Rtmpt7NwwG/R.INSTALLcbdc56a2a/units':
#8 35.94 configure: error: 
#8 35.94 --------------------------------------------------------------------------------
#8 35.94   Configuration failed because libudunits2.so was not found. Try installing:
#8 35.94     * deb: libudunits2-dev (Debian, Ubuntu, ...)
#8 35.94     * rpm: udunits2-devel (Fedora, EPEL, ...)
#8 35.94     * brew: udunits (OSX)
#8 35.94   If udunits2 is already installed in a non-standard location, use:
#8 35.94     --configure-args='--with-udunits2-lib=/usr/local/lib'
#8 35.94   if the library was not found, and/or:
#8 35.94     --configure-args='--with-udunits2-include=/usr/include/udunits2'
#8 35.94   if the header was not found, replacing paths with appropriate values.
#8 35.94   You can alternatively set UDUNITS2_INCLUDE and UDUNITS2_LIBS manually.
#8 35.94 --------------------------------------------------------------------------------
#8 35.94 
#8 35.94 See `config.log' for more details
#8 35.94 ERROR: configuration failed for package ‘units’
#8 35.94 * removing ‘/opt/example/renv/staging/1/units’
#8 35.94 install of package 'units' failed [error code 1]
...

While it is a very helpful error message and I could resolve the installation manually, but was hoping from the documentation that renv::install("[email protected]") followed by rspm::install_sysreqs() would work.

Please let me know what I've missed.

Our workflow revolves around renv and renv::install - so moving back to install.packages wouldn't be desirable.

@IanVermes IanVermes changed the title Difficulty with rspm in Difficulty with rspm when working renv May 13, 2024
@IanVermes IanVermes changed the title Difficulty with rspm when working renv Difficulty with rspm when working with renv May 13, 2024
@Enchufa2
Copy link
Member

rspm::renv_init() is meant to be run instead of renv::init().

@IanVermes
Copy link
Author

IanVermes commented May 13, 2024

Thanks @Enchufa2 for the help.

I tried that, but unfortunately an error appears during the build, as before. The error message is identical next build.log

## Dockerfile
FROM rocker/r-base:4.2.2

RUN apt-get update -yq \
    && apt-get install -yq \
    apt-file

WORKDIR /opt/example

RUN Rscript -e 'install.packages("renv"); install.packages("rspm"); rspm::renv_init(); rspm::install_sysreqs(); renv::install("units")'

Just incase there is something session based that I might be missing, I've tried to reproduce the docs https://rdrr.io/cran/rspm/man/renv_init.html, and its not possible for me.

## Dockerfile
FROM rocker/r-base:4.2.2

RUN apt-get update -yq \
    && apt-get install -yq \
    apt-file

WORKDIR /opt/example

RUN Rscript -e 'install.packages("renv"); install.packages("rspm")'
docker build --progress plain -t minimal:example .
docker run --rm -it minimal:example R

Within the same R session:

rspm::renv_init()
renv::install("[email protected]")      # <--- fails here again (same error as log)
rspm::install_sysreqs()           ## never run, as previous step fails
install.packages("units")         # <--- runs perfectly, rspm shims working as expected

@IanVermes
Copy link
Author

Also, just for reference

> packageVersion("rspm")
[1] ‘0.5.2> packageVersion("renv")
[1] ‘1.0.7

@Enchufa2
Copy link
Member

Mmmh... this is supposed to work:

## Dockerfile
FROM rocker/r-base:4.2.2

RUN apt-get update -yq \
    && apt-get install -yq \
    apt-file

WORKDIR /opt/example

RUN Rscript -e 'install.packages(c("renv", "rspm")); rspm::renv_init()'
RUN Rscript -e 'install.packages("units")'

At least it worked at some point. But it seems that now renv is trying to load the package after installing it? So it fails and rspm has no chance of installing the library. I don't see any option in renv to avoid this behavior. Maybe you could ask there?

@IanVermes
Copy link
Author

Thank you for taking a look. This does work.

...
RUN Rscript -e 'install.packages(c("renv", "rspm")); rspm::renv_init()'
RUN Rscript -e 'install.packages("units")'

But tragically for long running scientific projects or for deterministically building docker images, version pinning of dependencies is crucial.

Pinning is not possible with install.packages -- the use case of specifying [email protected], bioc::[email protected] or from github VanLoo-lab/ascat/[email protected] is very strong and why renv::install is preferred to install.packages.

rspm is such a good package and renv is good toolkit.

@Enchufa2
Copy link
Member

That is why rspm::install_sysreqs() is exported. You can call this function manually after any package installation. BTW, normally in a docker workflow with renv one would call restore with a lockfile, instead of calling install for individual packages. See this thread for reference: #17

@IanVermes
Copy link
Author

Thanks @Enchufa2 - I'll test it going via the restore route first. I'm on leave but will let you know in about 10 days.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants