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 КБ), но в более сложных ситуациях все может пойти не так:

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