Проблемы бродячей файловой системы с npm

Я сталкивался с частой ошибкой на машинах Vagrant и npm, когда файловая система внезапно становится доступной только для чтения. Во всех случаях использовался синхронизированный каталог, содержащий репозиторий git.

Вот настройка подготовки, с которой я смог столкнуться с проблемой. Оба файла расположены в корне репозитория git, ориентированного на узлы, например этого. .

бродячий файл

# Vagrantfile API/syntax version. Don't touch unless you know what you're doing!
VAGRANTFILE_API_VERSION = "2"

Vagrant.configure(VAGRANTFILE_API_VERSION) do |config|
  # Use host's SSH keys
  config.ssh.forward_agent = true

  # Get current directory name (presumably, repo dirname)
  repo_dirname = File.basename(Dir.getwd)

  # Set US locale
  ENV['LC_ALL']="en_US.UTF-8"

  # Ensures virtualbox can create symlinks in shared folders
  config.vm.provider "virtualbox" do |vb|
    vb.customize ["setextradata", :id,
                  "VBoxInternal2/SharedFoldersEnableSymlinksCreate/vagrant", "1"]
  end

  # Forward usual dev port through to host machine
  config.vm.network :forwarded_port, guest: 3000, host: 3000
  # Also forward production port just in case
  config.vm.network :forwarded_port, guest: 80, host: 8080
  # Forward a folder for the repo so that code can be worked on from outside the
  # VM as usual
  config.vm.synced_folder ".", "/home/ubuntu/#{repo_dirname}", create: true

  config.vm.define "#{repo_dirname}-vm" do |repo_vm|
    repo_vm.vm.box = "ubuntu/xenial64"
    repo_vm.vm.host_name = "#{repo_dirname}-vm"
    repo_vm.vm.provision :shell do |sh|
      sh.path = "vagrant_provision.sh"
      sh.privileged = false
      sh.env = {
        REPO_DIR: repo_dirname
      }
    end
  end

end

vagrant_provision.sh

#!/usr/bin/env bash

function set_locale() {
    sudo locale-gen en.US
}

function get_builds() {
    sudo apt-get update &&
        sudo apt-get upgrade -y &&
        sudo apt-get install -y curl build-essential
}

function get_n_installer() {
    if [ -f n-install ]
    then
        echo "n installer already exists. Not downloading."
        return 0
    else
        echo "n installer not found. Downloading..."
        wget -L https://git.io/n-install
    fi
}

function install_n() {
    if [ -d "n" ]
    then
        echo "n install directory already exists. Not installing."
        return 0
    else
        echo "n install directory not found. Installing..."
        yes | bash n-install
    fi
}

function add_github_keys() {
    # Adds the github server key to known hosts
    ssh-keyscan github.com >> ~/.ssh/known_hosts &&
        return 0 || return 1
}

function add_n_to_path() {
    # Added by n-install, but ignored by vagrant
    export N_PREFIX="$HOME/n";
    [[ :$PATH: == *":$N_PREFIX/bin:"* ]] || PATH+=":$N_PREFIX/bin"
}

function get_repo() {
    if [ -d "$2" ]
    then
        echo "Destination directory $2 already exists. Deleting contents..."
        rm -rfv ./$2
    fi
    echo "Cloning $1 into $2..."
    git clone $1 $2
}

function install_npm_deps() {
    echo "Installing npm dependencies..."
    npm install
}

function rebuild_node_sass() {
    # Needed because of https://github.com/sass/node-sass/issues/1579
    npm rebuild node-sass
}

# . ~/.bashrc &&
set_locale &&
    add_github_keys &&
    get_builds &&
    get_n_installer &&
    install_n &&
    add_n_to_path &&
    cd $REPO_DIR &&
    install_npm_deps &&
    rebuild_node_sass &&
    echo "Provisioned user is: $USER" &&
    echo "Frontend provisioned. To run, type 'vagrant ssh'."

Основной шаг, который, кажется, вызывает проблему, — это выполнение npm install непривилегированным поставщиком. Иногда распаковка архива возникает ошибка, но в других случаях npm завершается с ошибкой ENOENT.

После входа в систему с vagrant ssh для завершения задания появляются ошибки файловой системы только для чтения. Несмотря на это, места в системе предостаточно (скажем, осталось 7 из 8 ГБ).

Ошибки файловой системы только для чтения также появляются, когда сервер веб-пакетов работает при тех же обстоятельствах.

Есть вопросы и тикеты, циркулирующие вокруг подобных ошибок, но я не видел никаких исследований того, что лежит в основе механизма. В чем дело?


person bright-star    schedule 11.01.2017    source источник


Ответы (2)


У меня были похожие проблемы с Vagrant 1.8.7 и Virtualbox 5.1.10. Мне удалось исправить проблему с файловой системой только для чтения, уменьшив количество ядер процессора до 1:

config.vm.provider "virtualbox" do |v|
  v.cpus = 1
end

У меня все еще возникают проблемы со сборкой (модули npm не найдены, ENOENT, ELIFECYCLE,...), но с меньшей частотой. К сожалению, мне не удалось найти основную причину этих ошибок.

В моей настройке npm не пишет в общий каталог. Если местом записи является общая папка, вы можете попробовать другой механизм синхронизации, который позволяет обойти некоторые ограничения реализации общей папки виртуального бокса.

person nmn    schedule 17.01.2017
comment
Переход на rsync был намного надежнее. Хорошая идея. - person bright-star; 13.02.2017

Мне удалось решить эту проблему, создав символическую ссылку node_modules за пределами общей папки /vagrant, т.е. /home/vagrant/node_modules:

mkdir /home/vagrant/node_modules
ln -sf /home/vagrant/node_modules /vagrant/

Недостатком этого является то, что вы больше не можете устанавливать npm снаружи vagrant, только изнутри (если вы не используете mkdir / vagrant на своем хост-компьютере).

person PHZ.fi-Pharazon    schedule 01.08.2017
comment
Я использовал этот подход, и он работал для меня до сих пор. Спасибо! - person manei_cc; 20.05.2020
comment
Спасибо за это! Немного грустно, что это все еще кажется необходимым в 2021 году с vagrant 2.2.6. Было бы неплохо узнать, в чем проблема на самом деле… предположительно, что-то связанное с бродячей fs? (Кроме того, странно, что у меня не было этой проблемы в 2014 году…) - person Reuben Thomas; 26.02.2021
comment
Это не ошибка Vagrant, а проблема с Oracle Virtualbox и вызовом sendfile -kernel. Может помочь переключение на другую виртуализацию (VMWare, но это стоит лицензии) или использование другого механизма синхронизации (NFS?) для общей папки, но я не пробовал. - person PHZ.fi-Pharazon; 13.04.2021