Wine в Docker — «reg add» сохраняет эффекты только временно
Я бился головой об стену из-за этого.
Я хочу добавить исполняемый файл в PATH под Wine в Ubuntu 20.04. Пытаюсь настроить это из файла docker, но возникла странная проблема. В частности, я пытаюсь установить Python под Wine, чтобы вы могли позвонитьwine python
. Я решил попробовать использовать встроенный Python и вручную установить pip черезget_pip.py
(Здесь не показано).
В Dockerfile у меня есть:
FROM ubuntu:20.04
RUN useradd --no-log-init -r --uid 1003 -G dialout -g 100 -s /bin/bash jenkins
# PULL /wine/winecfg from private server pre-configured
RUN dpkg --add-architecture i386 \
&& apt get update
&& apt get install -y \
libc6:i386 \
&& apt get install -y \
wine=5.0-3
RUN mkdir -p /wine/winecfg && chown -R jenkins:users /wine
# Add Embedded Python
ARG Python_Embedded_Archive=python-3.9.7-embed-win32.zip
RUN apt-get install -y unzip
COPY ${Python_Embedded_Archive} /temp/${Python_Embedded_Archive}
RUN unzip /temp/${Python_Embedded_Archive} -d /wine/python
RUN chmod +x /wine/python/python.exe
RUN chown jenkins:users /wine/python
# Switch to jenkins, which owns wine
USER jenkins:true
# Add Embedded Python to PATH in wine
COPY add_to_wine_path.sh /wine
RUN bash /wine/add_to_wine_path.sh /wine/python \
&& wine python --version
RUN wine python --version
Примечание. Это не полный файл докеры, а только соответствующие части.
Папка /wine/cfg находится в
Сadd_to_wine_path.sh
:
path_to_add=$1
echo "Adding '$path_to_add' to Wine's PATH variable"
# Get clean the current path values (generally empty, but script could be called a second time)
existing_path=$(wine reg QUERY 'HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Session Manager\Environment' -v PATH | grep -Po '(?<=\^%).*(?=\^%)')
# If the existing path value is empty
if [ -z $existing_path" ]
then
# Set the default path values (Windows paths)
existing_path="C:\windows\system32;C:\windows"
fi
wine reg add 'HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Session Manager\Environment' -v PATH /t REG_EXPAND_SZ /d ^%\;&path_to_add\;$existing_path^% /f
Что на самом деле происходит:
когда я создаю образ докера, первый вызов срабатывает, указывая, что PATH был обновлен. УРА!
Но когда второйwine python --version
работает в другомRUN
заблокировать, это не получается.
Мне кажется, что реестр необходимо принудительно обновить для всех пользователей в Wine, фактически перезагрузив.
Поэтому я попробовалwineboot
со всеми различными вариантами, и это все равно не помогло.
Кто-нибудь из гуру реестра Windows или Wine знает, что здесь происходит?
1 ответ
Я также пытался сохранить изменение реестра Wine в Docker и экспериментально обнаружил, что в моей среде для файла реестра требуется от 1 до 2 секунд (~/.wine/user.reg
), который будет изменен после вызоваwine reg add
.
Здесь есть похожий запрос . Надеюсь, есть способ синхронно сбросить реестр на диск; в противном случае проще всего будет выполнять цикл до тех пор, пока файл не будет изменен.
Вот как я это сделал в одной ситуации (это изменение реестра включает опцию «Показать точечные файлы»):
RUN before=$(stat -c '%Y' /home/xclient/.wine/user.reg) \
&& wine reg add 'HKEY_CURRENT_USER\Software\Wine' /v ShowDotFiles /d Y \
&& while [ $(stat -c '%Y' /home/xclient/.wine/user.reg) = $before ]; do sleep 1; done
Вероятно, это безопасно, поскольку это одно изменение в реестре по умолчанию (который не очень велик: по-видимому, всего 16 КБ), но в более сложных ситуациях все может пойти не так:
- Если вы внесете несколько изменений в реестр, они не могут быть сброшены на диск одновременно, поэтому просмотра даты изменения файла будет недостаточно.
- Возможно, можно выйти из цикла, пока файл все еще записывается на диск, поэтому в итоге вы получите поврежденный файл реестра.