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

Upgrading opam to 2.1.0 touches files in my CWD, but it shouldn't #4783

Closed
Kakadu opened this issue Aug 5, 2021 · 12 comments · Fixed by #4787
Closed

Upgrading opam to 2.1.0 touches files in my CWD, but it shouldn't #4783

Kakadu opened this issue Aug 5, 2021 · 12 comments · Fixed by #4787

Comments

@Kakadu
Copy link

Kakadu commented Aug 5, 2021

I'm trying to upgrade to opam 2.1 from 2.1~beta-something (I think it was beta4). It does something with bwrap and tries to create something in my current workdir (/home/kakadu/asp/typerex-lint): see "bwrap: Can't mkdir /home/kakadu/asp/typerex-lint: No such file or directory" in the output below. Why? Is it intended? Should I be worried?

$ bash -c "sh <(curl -fsSL https://raw.githubusercontent.com/ocaml/opam/master/shell/install.sh) --version 2.1.0"
## Downloading opam 2.1.0 for linux on x86_64...
## Downloaded.
## Where should it be installed ? [/home/kakadu/bin] 
## opam 2.1.0 installed to /home/kakadu/bin
## Converting the opam root format & updating
No configuration file found, using built-in defaults.
This version of opam requires an update to the layout of /media/work/.opam from version 2.1~alpha2 to version 2.1, which can't be reverted.
You may want to back it up before going further.

Perform the update and continue? [Y/n] Y
Format upgrade done.

<><> Rerunning init and update ><><><><><><><><><><><><><><><><><><><><><><><><>
Checking for available remotes: rsync and local, git.
  - you won't be able to use mercurial repositories unless you install the hg command on your system.
  - you won't be able to use darcs repositories unless you install the darcs command on your system.

[ERROR] Sandboxing is not working on your platform ubuntu:
        "/media/work/.opam/opam-init/hooks/sandbox.sh build sh -c echo SUCCESS >$TMPDIR/opam-sandbox-check-out && cat $TMPDIR/opam-sandbox-check-out; rm -f $TMPDIR/opam-sandbox-check-out"
        exited with code 1 "bwrap: Can't mkdir /home/kakadu/asp/typerex-lint: No such file or directory"
Do you want to disable it?  Note that this will result in less secure package builds, so please ensure that you have some other isolation mechanisms in place (such as running within a
container or virtual machine). [y/N] 

My config

$  cat ~/.opam/config
opam-version: "2.0"
opam-root-version: "2.1"
repositories: "default"
installed-switches: [
  "memtrace"
  "4.11.2+fp+flambda"
  "4.10.1+flambda"
  "4.11.2+32bit"
  "4.11.1+BER"
  "4.12.0+fp+flambda"
  "4.10.1+fp+flambda"
  "4.07.1+fp+flambda"
]
switch: "4.10.1+flambda"
jobs: 3
download-jobs: 3
eval-variables: [
  sys-ocaml-version
  ["ocamlc" "-vnum"]
  "OCaml version present on your system independently of opam, if any"
]
default-compiler: [
  "ocaml-system" {>= "4.01.0"}
  "ocaml-base-compiler"
]
depext: true
depext-run-installs: true
depext-cannot-install: false

The bwrap is installed system-wide, my CWD seems not to be pinned

@rjbou
Copy link
Collaborator

rjbou commented Aug 5, 2021

Do you have TMPDIR defined ?

@rjbou
Copy link
Collaborator

rjbou commented Aug 5, 2021

It's the sandbox checker that tries to write in a file in $TMPDIR/opam-sandbox-check-out

@Kakadu
Copy link
Author

Kakadu commented Aug 5, 2021

Do you have TMPDIR defined ?

No

@rjbou rjbou added this to the 2.1.1 milestone Aug 5, 2021
@rjbou rjbou added the KIND: BUG label Aug 5, 2021
@rjbou
Copy link
Collaborator

rjbou commented Aug 5, 2021

You can define it and relaunch an opam init --reinit -ni.

@rjbou
Copy link
Collaborator

rjbou commented Aug 5, 2021

PR opened! Thank for the quick try & report :)

@kit-ty-kate
Copy link
Member

The fix doesn't seem right to me.

@Kakadu could you share the content of /media/work/.opam/opam-init/hooks/sandbox.sh ?

@Kakadu
Copy link
Author

Kakadu commented Aug 5, 2021

/media/work/.opam/opam-init/hooks/sandbox.sh

After saying yes above the files looks like:

➜  ~ cat /media/work/.opam/opam-init/hooks/sandbox.sh
#!/usr/bin/env bash

set -ue

if ! command -v bwrap >/dev/null; then
    echo "The 'bwrap' command was not found. Install 'bubblewrap' on your system, or" >&2
    echo "disable sandboxing in ${OPAMROOT:-~/.opam}/config at your own risk." >&2
    echo "See https://github.com/projectatomic/bubblewrap for bwrap details." >&2
    echo "For 'bwrap' use in opam, see the FAQ:" >&2
    echo "  https://opam.ocaml.org/doc/FAQ.html#Why-does-opam-require-bwrap" >&2
    exit 10
fi

# --new-session requires bubblewrap 0.1.7
# --die-with-parent requires bubblewrap 0.1.8
ARGS=(--unshare-net --new-session --die-with-parent)
ARGS=("${ARGS[@]}" --proc /proc --dev /dev)
ARGS=("${ARGS[@]}" --setenv TMPDIR /opam-tmp --setenv TMP /opam-tmp --setenv TEMPDIR /opam-tmp --setenv TEMP /opam-tmp)
ARGS=("${ARGS[@]}" --tmpfs /opam-tmp)
ARGS=("${ARGS[@]}" --tmpfs /run)

add_mount() {
    case "$1" in
        ro) B="--ro-bind";;
        rw) B="--bind";;
        sym) B="--symlink";;
    esac
    ARGS=("${ARGS[@]}" "$B" "$2" "$3")
}

add_mounts() {
    local flag="$1"; shift
    for dir in "$@"; do
      if [ -d "$dir" ]; then
        add_mount "$flag" "$dir" "$dir"
      fi
    done
}

# Mounts the standard system paths. Maintains symlinks, to handle cases
# like `/bin` -> `usr/bin`, where `/bin/../foo` resolves to `/usr/foo`,
# not `/foo`. We handle symlinks here but not in `add_mounts` because
# system paths are pretty much guaranteed not to accidentally escape into
# off-limits directories.
add_sys_mounts() {
    for dir in "$@"; do
        if [ -L "$dir" ]; then
            local src=$(readlink -f "$dir")
            add_mount sym "$src" "$dir"
        else
            add_mounts ro "$dir"
        fi
    done
}

# remove some unusual paths (/nix/stored and /rw/usrlocal )
# use OPAM_USER_PATH_RO variable to add them
# the OPAM_USER_PATH_RO format is the same as PATH
# ie: export OPAM_USER_PATH_RO=/nix/store:/rw/usrlocal
add_sys_mounts /usr /bin /lib /lib32 /lib64 /etc /opt /home /var /tmp

# C compilers using `ccache` will write to a shared cache directory
# that remain writeable. ccache seems widespread in some Fedora systems.
add_ccache_mount() {
  if command -v ccache > /dev/null; then
      ccache_dir_regex='cache_dir = (.*)$'
      local IFS=$'\n'
      for f in $(ccache -p 2>/dev/null); do
        if [[ $f =~ $ccache_dir_regex ]]; then
          ccache_dir=${BASH_REMATCH[1]}
          break
        fi
      done
      CCACHE_DIR=${CCACHE_DIR-$HOME/.ccache}
      ccache_dir=${ccache_dir-$CCACHE_DIR}
      add_mounts rw "$ccache_dir"
  fi
}

add_dune_cache_mount() {
  local u_cache=${XDG_CACHE_HOME:-$HOME/.cache}
  local u_dune_cache=$u_cache/dune
  local cache=$(readlink -m "$u_cache")
  local dune_cache=$cache/dune
  local dune_cache=$(readlink -m "$u_dune_cache")
  mkdir -p "${dune_cache}"
  add_mount rw "$u_dune_cache" "$dune_cache"
}

# mount unusual path in ro
if  [ -n "${OPAM_USER_PATH_RO-}" ]; then
   add_mounts ro $(echo "${OPAM_USER_PATH_RO}" | sed 's|:| |g')
fi

# When using opam variable that must be defined at action time, add them also
# at init check in OpamAuxCommands.check_and_revert_sandboxing (like
# OPAM_SWITCH_PREFIX).
# This case-switch should remain identical between the different sandbox implems
COMMAND="$1"; shift
case "$COMMAND" in
    build)
        add_mounts ro "$OPAM_SWITCH_PREFIX"
        add_mounts rw "$PWD"
        add_ccache_mount
        add_dune_cache_mount
        ;;
    install)
        add_mounts rw "$OPAM_SWITCH_PREFIX"
        add_mounts ro "$OPAM_SWITCH_PREFIX/.opam-switch"
        add_mounts rw "$PWD"
        ;;
    remove)
        add_mounts rw "$OPAM_SWITCH_PREFIX"
        add_mounts ro "$OPAM_SWITCH_PREFIX/.opam-switch"
        if [ "X${PWD#$OPAM_SWITCH_PREFIX/.opam-switch/}" != "X${PWD}" ]; then
          add_mounts rw "$PWD"
        fi
        ;;
    *)
        echo "$0: unknown command $COMMAND, must be one of 'build', 'install' or 'remove'" >&2
        exit 2
esac

# Note: we assume $1 can be trusted, see https://github.com/projectatomic/bubblewrap/issues/259
# As of now we are compatible up to 0.1.8, '--' can be added here when we require >= 0.3.0
exec bwrap "${ARGS[@]}" "$@"

@kit-ty-kate
Copy link
Member

kit-ty-kate commented Aug 5, 2021

I can't reproduce the issue locally when upgrading from 2.1.0~beta4 to 2.1.0.
Could you also paste some of the environment variable that you have set? I'm guessing, given your root is in /mnt/work/.opam you at least have OPAMROOT=/mnt/work/.opam but I wonder if you have anything else set that could play a role.

In a somewhat similar issue (#4751), the user seem to have used a symlink instead of setting OPAMROOT. Is that the case here too?
Either way i couldn't reproduce it with a symlink either so I'm really not sure what to do to reproduce.

@dra27
Copy link
Member

dra27 commented Aug 5, 2021

@Kakadu - is some part of /home/kakadu/asp/typerex-lint itself a symlink or mount-point?

@Kakadu
Copy link
Author

Kakadu commented Aug 5, 2021

yes @dra27

~ $ ll ~/asp ~/.opam
lrwxrwxrwx 1 kakadu kakadu  8 июн 13 18:30 /home/kakadu/asp -> work/asp
lrwxrwxrwx 1 kakadu kakadu 10 авг  4 20:17 /home/kakadu/.opam -> work/.opam

P.S.
It looks like if current working dir has followed a symlink then issue appears even on downgrade to 2.1.0~beta4. If CWD has no symlink then it's fine. If CWD has a mount point inside path, then it is fine too.

@dra27 dra27 linked a pull request Aug 6, 2021 that will close this issue
@dra27
Copy link
Member

dra27 commented Aug 6, 2021

Thanks, @Kakadu! Fix proposed in #4787

@kit-ty-kate
Copy link
Member

Alternative fix (for opam 2.2.0 most likely) in #4795. Feel free to test it.

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

Successfully merging a pull request may close this issue.

4 participants