Вместо долгой лирики, вопросов «зачем это нужно» и истории моей жизни — сразу нырнем в технические координаты.

Задача: собрать свежую Mesa3D в изолированном окружении, не скачивая на хост-систему миллион dev-пакетов, и протестировать сборку.

Для того чтобы установить Podman, на примере Debian, нужны следующие пакеты:

apt install -y podman uidmap passt catatonit

Чтобы проверить, правильно ли все работает, достаточно запустить:

podman run --rm hello-world

Если вы увидели в терминале приветствие и нарисованных «подмонят» (маскотов Podman), то вас можно даже поздравить со входом в DevOps! (Шутка)
Если вы увидели в терминале приветствие и нарисованных «подмонят» (маскотов Podman), то вас можно даже поздравить со входом в DevOps! (Шутка)

Podman можно использовать как аналог докера с его Dockerfile, но есть и второй путь — использовать подманский аналог, Containerfile, и его манифесты k8s подов. Не сетевые сервисы разворачиваем, но, на мой взгляд, разделение на рантайм и сам контейнер проще для понимания. Все, это все лирика, приступим к запуску контейнеров.

Чтобы не выкачивать кучу пакетов постоянно, мы создадим golden image контейнер, напоминающий коробку с инструментами. В нем будут все зависимости, необходимые для сборки драйверов Mesa3D на свой вкус и цвет.

FROM debian:stable

# Включаем deb-src и обновляем индексы
RUN <<EOF 
rm -rf /etc/apt/sources.list.d/*
cat << 'SOURCES' > /etc/apt/sources.list.d/debianscr.sources
Types: deb deb-src
URIs: http://deb.debian.org/debian/
Suites: stable
Components: main
Signed-By: /usr/share/keyrings/debian-archive-keyring.gpg
SOURCES

apt-get update
EOF

RUN apt-get build-dep -y mesa

Пройдемся по главному: # syntax=docker/dockerfile:1 дает возможность использовать heredoc в описи. FROM debian:stable — базовый докерский образ, slim не рекомендую для целей компиляции, в нем только libc + apt, он может неправильно поставить пакеты или не доставить их. RUN — запуск команды в контейнере, тут создается файл, разрешающий apt строить зависимости по -dev пакетам, дальше — обновление apt индексов и постройка древа зависимостей для сборки mesa пакета: RUN apt-get build-dep -y mesa.

Контейнер описан, и пора его собрать командой: podman build -f Containerfile -t mesa-compiling . (предварительно сделав cd, где лежит файл описи, или просто запустив терминал в этой папке). После сборки проверьте все установленые образы: podman images. Если есть localhost/mesa-compiling latest, значит, все собралось правильно.

Дальше переходим к k8sманифесту, который и будет нашим рантаймом: Note: чтобы никто не запутался, формат описи у k8s .yml — штука страшная, с отступами, но для наших целей без упования по ключам и хешам подойдет. Если лень писать, возьмите example ниже, для любой компиляции подойдет, нужно лишь заменить значения. Если и брать лень, можете AI сгенерировать.

kind: Pod
metadata:
  name: mesa-compilie
spec:
  restartPolicy: Never
  containers:
  - name: mesa-sands
    image: localhost/mesa-compiling:latest
    command: ["/bin/bash", "-c"]
    args:
      - |
        cd /xcv0
        mkdir ./sysbins
        meson setup builded/ -D prefix=/usr -D android-libbacktrace=disabled -D b_ndebug=true -D b_lto=false -D egl=enabled -D gallium-drivers=r300,r600,radeonsi,i915,iris,crocus -D gallium-va=enabled -D gbm=enabled -D glvnd=enabled -D glx=dri -D lmsensors=enabled -D microsoft-clc=disabled -D platforms=x11,wayland -D video-codecs=all -D vulkan-drivers=amd,intel,intel_hasvk -D buildtype=plain
        meson compile -C builded/
        meson install -C builded/ --destdir /xcv0/sysbins
        tar --owner=1000 --group=1000 -czf /xcv0/mesa3d-drivers.tar.gz -C /xcv0/sysbins .
        echo "end of compilation"
    resources:
      limits:
        cpu: "5000m"
        memory: "2048Mi"
    # Монтируем том внутрь контейнера
    volumeMounts:
    - name: host-storage
      mountPath: /xcv0                # название взял случайное
   
  # Описываем сам том hostPath
  volumes:
  - name: host-storage
    hostPath:
      path: /home/username/path/to/mesa_source_code  # Поддерживаются относительные пути
      type: DirectoryOrCreate # Если папки нет, Podman создаст её сам

Для понимания весь манифест знать не обязательно, нам нужны лишь кнопки, за которые нужно крутить. image: localhost/mesa-compiling:latest — берем наш золотой образ со всеми инструментами. Args: вот это самая интересная команда, это сборщик проекта, в данном случае meson, перечислены опции компиляции, сама компиляция и установка библиотек в /sysbins с соблюдением структуры Debian FHS, tar просто снимает рута и пакует в удобный тарболл для распространения.

Установку описали, дальше идут немаловажные вещи, никому же не хочется подвесить систему на фриз в 10 минут, так что крутим resources: цпу меряется по ядрам, в нашем случае 5000m — доступен эквивалент загрузки пяти ядрам процессора (note: подман загрузит все потоки процессора, но занятость будет как у 5 ядер на 100%, т.е. на 8 ядрах это 60-80% на все 8 потоков, имейте ввиду). Memory: "2048Mi" — ограничение в два гига всей памяти на контейнер.

Последние пункты volumeMounts: и volumes: отвечают за монтирование хостовой папки внутрь контейнера (проброс). MountPath: /xcv0 — это папка в самом контейнере, откуда будут доступны исходники. Path: /home/username/path/to/mesa_source_code в volumes: — это папка на хосте, которую нужно смонтировать внутрь контейнера в /xcv0. В итоге контейнер видит /xcv0, но на самом деле читает /home/username/path/to/mesa_source_code, вот так просто. Note: имена в - name: host-storage должны быть одинаковыми, иначе точка не будет найдена, + папки с пробелами рекомендую переименовать без пробелов, например, mesascr.

Дальше дело техники или мышечной памяти, у кого как:

podman play kube /path/to/mesapod.yml

И после отработки контейнера:

podman kube down /path/to/mesapod.yml

рекомендую смотреть в htop, чтобы понять, когда контейнер закончил работу.
рекомендую смотреть в htop, чтобы понять, когда контейнер закончил работу.

Все. Время забрать свои первые артефакты из /sysbins или скопировать себе тарбол и распаковать его себе в хомяка! (~/home то бишь)

Чтобы запустить новый драйвер в неродной для него папке, его достаточно загрузить командой export LD_LIBRARY_PATH="/path/to/your/mesa3d" в терминале, в папке, где находится большой бинарь libgallium-X.X.X.so. Папки /dri, /gbm трогать не обязательно, если вы не ставите в систему на постоянной основе.

Для проверки можно запустить glxinfo в том же окне, что и прописана переменная, промотать до строчки и найти: OpenGL core profile version string: 4.6 (Core Profile). Если версия после прописи изменилась, у вас подключился новый драйвер.

OpenGL часть взята не из системы
OpenGL часть взята не из системы

Note: для пользователей Steam будет попроще, в поле аргументов к запуску добавьте: LD_LIBRARY_PATH="/home/user/path_to_mesa:$LD_LIBRARY_PATH" %command%. В Стиме не тестировал, не пользуюсь им.

Vulkan драйвера также подтянутся за счет LD_LIBRARY_PATH="/home/user/path_to_mesa", заменив таким образом системные версии. Если это не сработает, есть более сложный, но на 100% рабочий: Скопируйте файлы vendorname_icd.x86_64.json в ~/home/user/.local/share/vulkan/icd.d и поменяйте в скопированных файлах строчку "library_path": "/usr/lib/x86_64-linux-gnu/libvulkan_radeon.so", прописав свой путь к драйверу в ~/home.

vulkan часть работает
vulkan часть работает

Итого: Статья была написана с целью обойти сложности связаные со старыми графическими драйверами mesa из коробки, заполучить radeon anti-lag и поддержку новых gpu на Debian stable не ломая штатный пакетный менеджер ppa репозиториями ubuntu