#shell #docker-desktop
#оболочка #docker-рабочий стол
Вопрос:
Мой скрипт отлично работает на устройствах коллег (MacOSX с Docker Desktop, таким же, как у меня), но каждый раз выдает мне одну и ту же ошибку, и он не перемещает или только половину библиотек в deps
каталоге:
OSError: [Errno 18] Invalid cross-device link: '/tmp/pip-target-dzwe_2kc/lib/python/numpy' ->
'/foo/python/numpy'
Мой сценарий :
#!/bin/bash
export PKG_DIR='python'
export SIDE_DEPS_DIR='deps'
rm -rf ${PKG_DIR} amp;amp; mkdir -p ${PKG_DIR}
rm -rf ${SIDE_DEPS_DIR} amp;amp; mkdir -p ${SIDE_DEPS_DIR}
docker run --rm -v $(pwd):/foo -w /foo lambci/lambda:build-python3.8
pip3 install -r requirements.txt -t ${PKG_DIR}
# move stuff to deps
find /${PKG_DIR} -maxdepth 1 -type d
( -name "pandas*" -o -name "numpy*" -o -name "numpy.libs*" -o -name "scipy*" -o -name "scipy.libs*" ) -exec mv '{}' ${SIDE_DEPS_DIR} ;
# zip side dependencies
zip -r ge_deps.zip deps
# zip layer
zip -r layers-python38-great-expectations.zip python
Это скрипт, который использует общедоступный образ lambda docker для создания слоя lambda (в основном zip, содержащий библиотеки) и который удаляет ненужные библиотеки, чтобы поместить их в другую папку deps
.
Приведенный выше код будет использовать общедоступный образ Docker lambci / lambda и установит в пустой python
каталог библиотеки, которые поступают из пакета python, который называется «большие ожидания» и который помогает тестировать конвейеры данных (что указано в requirements.txt и есть great-expectations==0.12.7
)
Я некоторое время сталкивался с этой проблемой и не нашел решения.
Комментарии:
1. кажется, у вас могут возникнуть некоторые проблемы с жесткими ссылками: unix.stackexchange.com/questions/79132 /…
2. Случайно ли вы какую-
ln
либо из папок, упомянутых в ошибке? И забыли-s
флаг?3. Я не связывал ни одну папку
4. Если источник и место назначения находятся в разных файловых системах, это ошибка, которую вы получите, если попытаетесь использовать
rename(2)
для ее перемещения, но AFAIKmv(1)
должен вернуться к копированию, а затем удалению в этом случае. Есть ли у ваших коллег/tmp
и/foo
в той же файловой системе?5. Я видел, что если я создаю новый каталог в / Users / random_name , он работает нормально. но если я запускаю скрипт несколько раз в одном и том же каталоге, он больше не работает, или если я создаю новый каталог в Users / random_name / Desktop, он не работает. И каталоги имеют права доступа
Ответ №1:
Только что возникла эта точная проблема.
/tmp и / foo — это разные устройства — / tmp находится в ОС docker, а / foo сопоставлен с вашей локальной ОС.
похоже, что pip использует shutil.rename() для перемещения созданного пакета из tmp в конечное местоположение вывода (/foo ). Это сбой, потому что это разные устройства. В идеале pip вместо этого использовал бы shutil.move() , который будет иметь дело с перемещением между устройствами.
В качестве обходного пути вы можете изменить временную папку, используемую PIP, установив TMPDIR перед вызовом команды pip. т. е. export TMPDIR=/foo/tmp
Перед вызовом pip в образе docker. Итак, вся команда может быть примерно такой
docker run --rm -v $(pwd):/foo -w /foo lambci/lambda:build-python3.8
/bin/bash -c "export TMPDIR=/foo/tmp amp;amp; pip3 install -r requirements.txt -t ${PKG_DIR}"
(несколько команд взяты из https://www.edureka.co/community/10736/how-to-run-multiple-commands-in-docker-at-once — открыт для лучших предложений!)
Вероятно, это будет медленнее, потому что для временных файлов используется локальная ОС, но это позволяет избежать попытки «переименования» между устройствами из папки temp в конечную выходную папку.