racket / racket

The Racket repository
https://racket-lang.org/
Other
4.8k stars 662 forks source link

Installing `rival` errors trying to find shared libraries when using `-MCR` #4324

Closed samth closed 2 years ago

samth commented 2 years ago

Currently the rival package has the following error when run on https://pkg-build.racket-lang.org (saved at archived):

raco setup: 1 running: <pkgs>/rival/main.scrbl
current-directory: `exists' access denied for /home/root/racket/
  context...:
   /home/root/racket/collects/racket/private/config.rkt:30:4: exe-relative-path->complete-path
   /home/root/racket/collects/setup/private/dirs.rkt:24:2: get-config-table
   /home/root/racket/collects/racket/promise.rkt:65:10
   /home/root/racket/collects/racket/promise.rkt:45:2
   /home/root/racket/collects/setup/dirs.rkt:261:2: host-lib-search-dirs
   /home/root/racket/collects/racket/promise.rkt:65:10
   /home/root/racket/collects/racket/promise.rkt:45:2
   /home/root/racket/collects/racket/private/so-search.rkt:28:0: so-find
   /home/root/racket/collects/racket/runtime-path.rkt:88:9
   .../private/map.rkt:40:19: loop
   body of "/home/root/racket/share/pkgs/math-lib/math/private/bigfloat/gmp.rkt"
   body of top-level
   /home/root/racket/share/pkgs/sandbox-lib/racket/sandbox.rkt:740:9: ns
   /home/root/racket/share/pkgs/sandbox-lib/racket/sandbox.rkt:754:18

  context...:
   /home/root/racket/collects/setup/parallel-do.rkt:332:4: work-done method in list-queue%
   /home/root/racket/collects/setup/parallel-do.rkt:282:17
   /home/root/racket/collects/setup/parallel-do.rkt:236:4
   /home/root/racket/share/pkgs/racket-index/setup/scribble.rkt:139:0: setup-scribblings
   /home/root/racket/collects/setup/setup.rkt:78:3
   /home/root/racket/collects/pkg/main.rkt:17:0: setup
   body of (submod "/home/root/racket/collects/pkg/main.rkt" main)
   /home/root/racket/collects/raco/raco.rkt:41:0
   body of "/home/root/racket/collects/raco/raco.rkt"
   body of "/home/root/racket/collects/raco/main.rkt"

To reproduce (on my machine, with a regular install of Racket, more details below):

racket -MCR /home/samth/zo: -l- raco pkg install rival
To reproduce on a clean image: ``` % docker run -it mflatt/pkg-build-deps # mkdir /home/root # cd /home/root # wget https://download.racket-lang.org/releases/8.5/installers/racket-8.5-x86_64-linux-natipkg-cs.sh # sh racket... --dest racket # racket/bin/racket -MCR /home/root/zo: -l- raco pkg install rival ``` Complete transcript: ``` [samth@huor:~/.../service-conf/pkg-builder/pkg-build (master) plt] docker run --name ci-test3 -it mflatt/pkg-build-deps root@f2fe15ae6740:/# cd /home/ root@f2fe15ae6740:/home# mkdir root root@f2fe15ae6740:/home# cd root root@f2fe15ae6740:/home/root# apt install wget ... output snipped ... root@f2fe15ae6740:/home/root# wget --no-check-certificate https://download.racket-lang.org/releases/8.5/installers/racket-8.5-x86_64-linux-natipkg-cs.sh ... output snipped ... root@f2fe15ae6740:/home/root# sh racket-8.5-x86_64-linux-natipkg-cs.sh This program will extract and install Racket v8.5. Note: the required diskspace for this installation is 695M. Do you want a Unix-style distribution? In this distribution mode files go into different directories according to Unix conventions. A "racket-uninstall" script will be generated to be used when you want to remove the installation. If you say 'no', the whole Racket directory is kept in a single installation directory (movable and erasable), possibly with external links into it -- this is often more convenient, especially if you want to install multiple versions or keep it in your home directory. Enter yes/no (default: no) > Where do you want to install the "racket" directory tree? 1 - /usr/racket [default] 2 - /usr/local/racket 3 - ~/racket (/root/racket) 4 - ./racket (here) Or enter a different "racket" directory to install in. > 4 Checking the integrity of the binary archive... ok. Unpacking into "/home/root/racket" (Ctrl+C to abort)... Done. If you want to install new system links within the "bin", "man" and "share/applications" subdirectories of a common directory prefix (for example, "/usr/local") then enter the prefix of an existing directory that you want to use. This might overwrite existing symlinks, but not files. (default: skip links) > Installation complete. root@f2fe15ae6740:/home/root# /usr/bin/env "DISPLAY=:1 PLT_PKG_BUILD_SERVICE=1 PLTUSERHOME=/home/root//user PLT_PKG_BUILD_SERVICE=1 CI=true PLTSTDERR=debug@pkg error PLT_INFO_ALLOW_VARS=;PLT_PKG_BUILD_SERVICE PLTCOMPILEDROOTS=/home/root//zo:" /usr/bin/xvfb-run -n 1 /bin/sh -c 'cd "/home/root/"/racket && bin/racket -MCR "/home/root/"/zo: -l- raco pkg install --jobs 2 -u --auto rival' Resolving "rival" via https://download.racket-lang.org/releases/8.5/catalog/ Resolving "rival" via https://pkgs.racket-lang.org Downloading repository https://github.com/herbie-fp/rival.git commit dd4197014eccf9799cb80d3ad86b88fe4daf25c9 raco setup: version: 8.5 raco setup: platform: x86_64-linux-natipkg [cs] raco setup: target machine: ta6le raco setup: cross-installation: yes raco setup: installation name: 8.5 raco setup: variants: cs raco setup: main collects: /home/root/racket/collects/ raco setup: collects paths: raco setup: /root/.local/share/racket/8.5/collects raco setup: /home/root/racket/collects/ raco setup: main pkgs: /home/root/racket/share/pkgs raco setup: pkgs paths: raco setup: /home/root/racket/share/pkgs raco setup: /root/.local/share/racket/8.5/pkgs raco setup: links files: raco setup: /home/root/racket/share/links.rktd raco setup: /root/.local/share/racket/8.5/links.rktd raco setup: compiled-file roots: raco setup: /home/root//zo raco setup: same raco setup: main docs: /home/root/racket/doc raco setup: --- updating info-domain tables --- [20:56:35] raco setup: updating: /root/.local/share/racket/8.5/share/info-cache.rktd raco setup: --- pre-installing collections --- [20:56:35] raco setup: --- installing foreign libraries --- [20:56:35] raco setup: --- installing shared files --- [20:56:35] raco setup: --- compiling collections --- [20:56:35] raco setup: --- parallel build using 2 jobs --- [20:56:35] raco setup: 1 making: /rival raco setup: --- creating launchers --- [20:56:40] raco setup: --- installing man pages --- [20:56:40] raco setup: --- building documentation --- [20:56:40] raco setup: 1 running: /racket-index/scribblings/main/user/local-redirect.scrbl raco setup: 0 running: /rival/main.scrbl current-directory: `exists' access denied for /home/root/racket/ context...: /home/root/racket/collects/racket/private/config.rkt:30:4: exe-relative-path->complete-path /home/root/racket/collects/setup/private/dirs.rkt:24:2: get-config-table /home/root/racket/collects/racket/promise.rkt:65:10 /home/root/racket/collects/racket/promise.rkt:45:2 /home/root/racket/collects/setup/dirs.rkt:261:2: host-lib-search-dirs /home/root/racket/collects/racket/promise.rkt:65:10 /home/root/racket/collects/racket/promise.rkt:45:2 /home/root/racket/collects/racket/private/so-search.rkt:28:0: so-find /home/root/racket/collects/racket/runtime-path.rkt:88:9 .../private/map.rkt:40:19: loop body of "/home/root/racket/share/pkgs/math-lib/math/private/bigfloat/gmp.rkt" body of top-level /home/root/racket/share/pkgs/sandbox-lib/racket/sandbox.rkt:740:9: ns /home/root/racket/share/pkgs/sandbox-lib/racket/sandbox.rkt:754:18 context...: /home/root/racket/collects/setup/parallel-do.rkt:332:4: work-done method in list-queue% /home/root/racket/collects/setup/parallel-do.rkt:282:17 /home/root/racket/collects/setup/parallel-do.rkt:236:4 /home/root/racket/share/pkgs/racket-index/setup/scribble.rkt:139:0: setup-scribblings /home/root/racket/collects/setup/setup.rkt:78:3 /home/root/racket/collects/pkg/main.rkt:17:0: setup body of (submod "/home/root/racket/collects/pkg/main.rkt" main) /home/root/racket/collects/raco/raco.rkt:41:0 body of "/home/root/racket/collects/raco/raco.rkt" body of "/home/root/racket/collects/raco/main.rkt" raco setup: 0 running: /racket-index/scribblings/main/user/release.scrbl raco setup: 0 running: /racket-index/scribblings/main/user/search.scrbl raco setup: 0 running: /racket-index/scribblings/main/user/start.scrbl raco setup: 1 rendering: /racket-index/scribblings/main/user/local-redirect.scrbl raco setup: 0 rendering: /racket-index/scribblings/main/user/release.scrbl raco setup: 0 rendering: /racket-index/scribblings/main/user/search.scrbl raco setup: 1 rendering: /racket-index/scribblings/main/user/start.scrbl raco setup: --- installing collections --- [20:56:47] raco setup: --- post-installing collections --- [20:56:47] raco setup: --- summary of errors --- [20:56:47] raco setup: error: during building docs for /rival/main.scrbl raco setup: current-directory: `exists' access denied for /home/root/racket/ raco setup: context...: raco setup: /home/root/racket/collects/racket/private/config.rkt:30:4: exe-relative-path->complete-path raco setup: /home/root/racket/collects/setup/private/dirs.rkt:24:2: get-config-table raco setup: /home/root/racket/collects/racket/promise.rkt:65:10 raco setup: /home/root/racket/collects/racket/promise.rkt:45:2 raco setup: /home/root/racket/collects/setup/dirs.rkt:261:2: host-lib-search-dirs raco setup: /home/root/racket/collects/racket/promise.rkt:65:10 raco setup: /home/root/racket/collects/racket/promise.rkt:45:2 raco setup: /home/root/racket/collects/racket/private/so-search.rkt:28:0: so-find raco setup: /home/root/racket/collects/racket/runtime-path.rkt:88:9 raco setup: .../private/map.rkt:40:19: loop raco setup: body of "/home/root/racket/share/pkgs/math-lib/math/private/bigfloat/gmp.rkt" raco setup: body of top-level raco setup: /home/root/racket/share/pkgs/sandbox-lib/racket/sandbox.rkt:740:9: ns raco setup: /home/root/racket/share/pkgs/sandbox-lib/racket/sandbox.rkt:754:18 raco setup: racket pkg install: packages installed, although setup reported errors root@f2fe15ae6740:/home/root# ```
samth commented 2 years ago

Just -R works correctly.

mflatt commented 2 years ago

It looks like the issue is that cross-build mode (as triggered by -MCR) performs an executable-relative directory lookup that isn't cached in the same way as the non-cross directories. I can add caching.

samth commented 2 years ago

Caching feels odd as a fix here. If the code doesn't have permission to do this operation, then why is it ok to get the results of it from a cache?

mflatt commented 2 years ago

Finding the collects directory means a search starting with the name used to launch Racket, possibly using the PATH environment variable and inspecting those directories, possibly following soft links, and all the while appending a multi-element relative path to check whether we've found it, yet. It's a complex search and can touch a lot of things, but the end result is simple — typically some path right next to the executable. The intent is that this end path is accessible within a sandbox, but not necessarily everything that goes into finding that directory.

You may wonder why the implementation doesn't just compute the path at startup time and record it, as opposed to "caching" sometime later. There's an interplay of things written in Racket and built into the kernel, and this "caching" approach is the way I found to do it once upon a time. The exact mechanism might be a little different starting from scratch (now that it's easier to write startup tasks in Racket). But the underlying problem and repair would be about the same: a cross-compilation path would need to be computed and registered in addition to the two paths already registered.