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

Error: <callr_remote_error: Failed to move installed package at '/usr/local/lib/R/site-library/ps'> #251

Open
mskyttner opened this issue Dec 13, 2020 · 16 comments
Labels
bug an unexpected problem or unintended behavior

Comments

@mskyttner
Copy link

Reproducible steps

Make a build with docker build . using the Dockerfile below:

FROM rocker/geospatial:4.0.3
RUN R -e 'install.packages("pak", repos = "https://r-lib.github.io/p/pak/dev/")'
RUN R -e 'pak::pkg_install("ps", ask = FALSE)'

Log

Stack trace:

  1. (function (...) ...
  2. base:::withCallingHandlers(cli_message = function(msg) { ...
  3. get("pkg_install_do_plan", asNamespace("pak"))(...)
  4. pkgdepends::install_package_plan(plan = plan, lib = lib, num_workers = num_ ...
  5. base:::withCallingHandlers({ ...
  6. pkgdepends:::handle_events(state, events)
  7. pkgdepends:::handle_event(state, i)
  8. proc$get_result()
  9. processx:::process_get_result(self, private)
  10. private$post_process()
  11. pkgdepends:::install_extracted_binary(filename, lib_cache, pkg_cache, ...
  12. base:::throw(new_fs_error("Failed to move installed package at {installed_p ...
  13. base:::signalCondition(cond)
  14. (function (e) ...
  15. base:::stop(e)
  16. (function (e) ...

Related issue

#175

@gaborcsardi
Copy link
Member

For the record, #175 is not a related issue, that is a download error, this one is an installation error.

I am not sure why it happens, but it has to do something with the permissions of the library directory on that Docker image. E.g. this is successful:

> dir.create(lib <- tempfile())
> pak::pak("ps", lib = lib)

→ Will install 1 package.Will download 1 CRAN package (115.13 kB).
+ ps   1.5.0 [bld][cmp][dl] (115.13 kB)
ℹ Getting 1 pkg (115.13 kB)
✔ Got ps 1.5.0 (source) (350.08 kB)
✔ Downloaded 1 package (350.08 kB) in 1.4sBuilding ps 1.5.0Built ps 1.5.0 (478ms)
✔ Installed ps 1.5.0  (37ms)
✔ 1 + 0 pkgs | kept 0, updated 0, new 1 | downloaded 1 (350.08 kB) 2.6s

@gaborcsardi
Copy link
Member

It is more clear when running the underlying pkgdepends commands:

> p <- pkgdepends::new_pkg_installation_proposal("ps")
> p$solve()
✔ Loading global cached package metadata ... done
> p$download()
ℹ Getting 1 pkg (115.13 kB)
✔ Cached copy of ps 1.5.0 (source) is the latest buildNo downloads needed, all packages are cached
> p$install()
ℹ Building ps 1.5.0Built ps 1.5.0 (441ms)
⸨▒▒▒▒▒▒▒▒▒▒▒▒▒⸩ | 📦  1/1     |0/11 | installing ps
Error: <install_filesystem_error in install_extracted_binary(filename, lib_cache, pkg_cache, lib,  ...:
 Failed to move installed package at '/usr/local/lib/R/site-library/ps'>

See `.Last.error.trace` for a stack trace.
Warning message:
In file.rename(installed_path, move_to) :
  cannot rename file '/usr/local/lib/R/site-library/ps' to '/usr/local/lib/R/site-library/_cache/ps/file3c256916315', reason 'Invalid cross-device link'

@mskyttner
Copy link
Author

The permissions for that directory in the container:

drwxrwsr-x  1 root staff 4.0K Dec 13 19:33 site-library

Could it be a "staged install" thing where ps already is loaded and used by pak and some lock during a staged install phase prevents it from be "replaced"?

@gaborcsardi
Copy link
Member

Could it be a "staged install" thing where ps already is loaded and used by pak and some lock during a staged install phase prevents it from be "replaced"?

No, locking is advisory on Linux.

It seems like it is not the permissions, but a Docker issue. We can try to work around it.

@gaborcsardi
Copy link
Member

I am fairly sure that the issue is that the package (e.g. ps) is already installed on the parent image, and pak tries to move/rename its directory before the installation. For Docker this is a move/rename between devices. We can try to copy + delete if the move fails.

@gaborcsardi gaborcsardi added the bug an unexpected problem or unintended behavior label Jan 30, 2021
@ColinFay
Copy link

I also stumbled upon this issue when trying to update my R install scripts from {remotes} to {pak}.

Has there been any workaround for this?

So far I've been doing

packs <- as.data.frame(installed.packages())
if (!pak %in% packs$Package) {
	pak::pkg_install(
      pak
	)
  }

But that feels like a hack :)

@mjkanji
Copy link

mjkanji commented Feb 2, 2022

@gaborcsardi Any updates on this or solutions that we can use to circumvent the problem? The above "hack" by ColinFay is only relevant for packages themselves and not their dependencies (e.g., if pkg depends on pkgY and pkgY is the one creating the issue, it's not particularly easy to conditionally exclude it using installed.packages() unless we look at the underlying solution from pkgdepends itself.

@mjkanji
Copy link

mjkanji commented Feb 2, 2022

A (hopefully) more "resilient" version of the hack from @ColinFay that also excludes dependencies:

new_pkgs = c("tibble", "rlang", "fansi")
p <- pkgdepends::new_pkg_installation_proposal(new_pkgs)
p$solve()
sol <- p$get_solution()
sol_pkgs <- s$data$package
installed_pkgs <- installed.packages()[, "Package"]

# Remove any packages suggested by the solution which are already installed (regardless of version)
to_install <- setdiff(sol_pkgs, installed_pkgs )
pak::pkg_install(to_install, dependencies = FALSE)

An obvious disadvantage of this approach is that if one of the packages you have already installed is super old, pak might suggest updating it, but this approach overrides pak's suggestion and keeps the older version, which could potentially lead to its own set of problems...

mskyttner pushed a commit to KTH-Library/kthcorpus that referenced this issue Mar 8, 2022
@pat-s
Copy link

pat-s commented Mar 13, 2022

I also get biten by this in a docker setting.

The comment to try copy + delete was from the end of 2020. I would be interested to know if there have been some attempts to troubleshoot this or if it's possibly a dead end?

@schloerke
Copy link

My current work around...

Add a local library to your docker's Rprofile. Install your packages there.

# Use custom lib location
RUN mkdir -p '/custom/R/library' && echo ".libPaths('/custom/R/library')" >> `Rscript -e "cat(R.home())"`/etc/Rprofile.site

# Install pak
RUN R --quiet -e 'install.packages("pak", repos = sprintf("https://r-lib.github.io/p/pak/stable/%s/%s/%s", .Platform[["pkgType"]], R.Version()[["os"]], R.Version()[["arch"]]))'

# Install all pkgs
RUN R --quiet -e "pak::pkg_install('networkD3')"

By using a local lib:

  • it doesn't match the parent R library, making it mutable
  • packages within this lib be used first when running R

@telegott
Copy link

telegott commented Jul 27, 2022

@schloerke I tried this workaround but I still get the error


Error: <callr_remote_error: Failed to move installed package at '/app/pak-library/classInt'>
 in process 30 
-->
<install_filesystem_error in install_extracted_binary(filename, lib_cache, pkg_cache, lib,  ...:
 Failed to move installed package at '/app/pak-library/classInt'>
 in process 

 Stack trace:

 12. (function (...)  ...
 13. base:::withCallingHandlers(cli_message = function(msg) { ...
 14. get("local_install_dev_deps_do_plan", asNamespace("pak"))(...)
 15. pak:::pkg_install_do_plan(proposal = NULL, lib = lib)
 16. pkgdepends::install_package_plan(plan = plan, lib = lib, num_workers = num_ ...
 17. base:::withCallingHandlers({ ...
 18. pkgdepends:::handle_events(state, events)
 19. pkgdepends:::handle_event(state, i)
 20. proc$get_result()
 21. processx:::process_get_result(self, private)
 22. private$post_process()
 23. pkgdepends:::install_extracted_binary(filename, lib_cache, pkg_cache,  ...
 24. base:::throw(new_fs_error("Failed to move installed package at {installed_p ...
 25. base:::signalCondition(cond)
 26. (function (e)  ...
 27. base:::stop(e)
 28. (function (e)  ...

 x Failed to move installed package at '/app/pak-library/classInt' 

The goal is to have a common base image, add test dependencies in a test layer and later deploy the base image with minimal changes as deploy so I don't have to rebuild the production libraries

Snippet from Dockerfile (.Rprofile is in the .dockerignore)

WORKDIR app
RUN mkdir -p pak-library
RUN echo ".libPaths('/app/pak-library')" > .Rprofile
COPY DESCRIPTION DESCRIPTION
COPY scripts/tool scripts/tool

RUN R -e "print(.libPaths())"
RUN set -xe \
    && Rscript -e 'install.packages("pak")' \
    && Rscript -e 'pak::local_install_deps()'
COPY . .

FROM base AS test
RUN Rscript -e "print(.libPaths())"
RUN set -xe \
    && Rscript -e 'pak::local_install_dev_deps()'

FROM base AS deploy
...

Do you have an idea what could be wrong here?

@gaborcsardi
Copy link
Member

I guess the second pak call is trying to update a package that was installed in the first pak call.

@telegott
Copy link

@gaborcsardi this also happens with a minimal DESCRIPTION:

Imports: 
    sf
Suggests:
    lintr

and classInt does not seem to be a reverse dependency of lintr, but on the pak::install_local_dev_deps it indeed does try to update classInt, to the same version:

ℹ Loading metadata database
✔ Loading metadata database ... done

 
→ Will install 27 packages.
→ Will update 1 package.
→ Will download 28 CRAN packages (15.16 MB).
→ Will download 1 package with unknown size.
+ backports            1.4.1  [bld][cmp][dl] (26.20 kB)
+ callr                3.7.0  [bld][dl] (90.47 kB)
+ classInt     0.4-7 → 0.4-7  [bld][cmp][dl] (437.80 kB)
+ cli                  3.3.0  [bld][cmp][dl] (495.82 kB)
+ crayon               1.5.1  [bld][dl] (40.18 kB)
+ cyclocomp            1.1.0  [bld][dl] (8.41 kB)
+ desc                 1.4.1  [bld][dl] (80.67 kB)
+ digest               0.6.29 [bld][cmp][dl] (162.78 kB)
+ evaluate             0.15   [bld][dl] (25.62 kB)
+ glue                 1.6.2  [bld][cmp][dl] (106.51 kB)
+ highr                0.9    [bld][dl] (15.19 kB)
+ jsonlite             1.8.0  [bld][cmp][dl] (1.05 MB)
+ knitr                1.39   [bld][dl] (898.42 kB)
+ lazyeval             0.2.2  [bld][cmp][dl] (83.48 kB)
+ lintr                3.0.0  [bld][dl] (2.19 MB)
+ processx             3.6.1  [bld][cmp][dl] (161.75 kB)
+ ps                   1.7.1  [bld][cmp][dl] (128.66 kB)
+ R6                   2.5.1  [bld][dl] (63.42 kB)
+ remotes              2.4.2  [bld][dl] (152.54 kB)
+ rex                  1.2.1  [bld][dl] (93.58 kB)
+ rprojroot            2.0.3  [bld][dl] (59.94 kB)
+ stringi              1.7.6  [bld][cmp][dl] (8.03 MB)
+ stringr              1.4.0  [bld][dl] (135.78 kB)
+ withr                2.5.0  [bld][dl] (102.09 kB)
+ xfun                 0.31   [bld][cmp][dl] (126.06 kB)
+ xml2                 1.3.3  [bld][cmp][dl] (283.96 kB)
+ xmlparsedata         1.0.5  [bld][dl] (8.99 kB)
+ yaml                 2.3.5  [bld][cmp][dl] (94.53 kB)

I thought that workaround with a custom library path might fix this permission (?) issue as described. Is there another way to install only Suggests packages (of course there could be the same reverse dependency between a package in Imports and Suggests ...)

@gaborcsardi
Copy link
Member

I am going to try to fix this now. A small reprex Dockerfile:

FROM rhub/r-minimal

WORKDIR /root

RUN installr -c -p
RUN Rscript -e 'pak::pkg_install("rlang")'

RUN Rscript -e 'pak::pkg_install("r-lib/rlang")'

@gaborcsardi
Copy link
Member

gaborcsardi commented Jul 27, 2022

OK, this is now fixed in pkgdepends, and the nightly devel Linux builds of pak. So this works now:

FROM rhub/r-minimal

WORKDIR /root

RUN installr -c

RUN Rscript -e 'install.packages("pak", repos = sprintf("https://r-lib.github.io/p/pak/devel/%s/%s/%s", .Platform$pkgType, R.Version()$os, R.Version()$arch))'

RUN Rscript -e 'pak::pkg_install("rlang")'

RUN Rscript -e 'pak::pkg_install("r-lib/rlang")'

@telegott
Copy link

@gaborcsardi awesome, thanks so much!

eitsupi added a commit to eitsupi/rocker-devcontainer-features that referenced this issue Oct 9, 2022
netbsd-srcmastr pushed a commit to NetBSD/pkgsrc that referenced this issue Feb 19, 2023
# pak 0.4.0

* pak has much improved and more informative error messages now.
  This work is not yet finished, so if you find an unclear error message,
  please open an issue. Thank you!

* The solver is now more robust for non-canonical input (e.g. `DESCRIPTION`
  files) (r-lib/pak#423).

* Better installation output. Standard output and error are now
  collected together (r-lib/pkgdepends@0669f0f8c).

* The solver is now doing a better job when multiple versions of the
  same package are present in the same repository
  (r-lib/actions#559).

* `pkg_name_check()` now works again, it needed a fix after changes at
  https://crandb.r-pkg.org.

* Explicit package names in local and URL package sources, as in
  `package=local::...` or `package=url::...` are now parsed correctly in
  dependencies.

* pak is now more robust to `Archs` fields missing from the CRAN
  metadata for packages with compiled code
  (r-lib/pak#448).

* `url::` packages now always work correctly, even if the digest package is
  not installed (r-lib/pak#433).

* pak is now more robust when installing packages from subdirectories
  of GitHub repositories (r-lib/pak#431,
  @paleolimbot).

* Parameters `?reinstall`, `?source` and `?ignore` now work correctly when
  specified in the `package=?parameter` format (#294).

* The `?ignore` parameter works correctly now.

* Dependency resolution now does not fail if a package is not found.

* pak can now install `url::` remotes from GitHub.

* pak now does not fail when the package of a `.tar.gz` GitHub
  snapshot is in a subdirectory, or in a subdirectory of a subdirectory.

* pak now errors early if it cannot deduce the name of the package
  from a `Remotes` or `Config/Needs/*` entry.

* Solver failures now include details in some cases where previously they
  did not.

* pak can now update packages in Docker containers where the
  old version was installed in the different Docker later
  (r-lib/pak#251)

* Update R version -> Bioconductor version mapping. R 4.2.x now maps to
  Bioconductor 3.16.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug an unexpected problem or unintended behavior
Projects
None yet
Development

No branches or pull requests

7 participants