`libalternatives` в openSUSE: майбутнє управління альтернативами
Управління декількома версіями одного інструмента - правильний шлях для сучасних дистрибутивів.
Table of Contents
- Вступ: навіщо потрібен механізм альтернатив
- Чому
update-alternativesвже не задовольняє сучасні потреби - Що таке
libalternatives - Порівняння:
update-alternativesvslibalternatives - Команди
alts: довідник - Висновки
- Швидка шпаргалка
Вступ: навіщо потрібен механізм альтернатив
update-alternatives - це класичний Linux-інструмент для управління симлінками команд, що мають декілька встановлених реалізацій. Кожен пакет реєструє себе як альтернативу для певної ролі (editor, java, python тощо), а система зберігає симлінки в /etc/alternatives/, вказуючи на поточну альтернативу з найвищим пріоритетом.
Спочатку це була Debian-тулза, але її швидко підхопили всі популярні дистрибутиви. Проте, з розвитком сучасних файлових систем і архітектур дистрибутивів, classic approach почав виявляти свої обмеження.
Чому update-alternatives вже не задовольняє сучасні потреби
Насправді, для більшості дистрибутивів він працює добре. Всіх, крім одного. openSUSE, з його унікальною архітектурою на базі Btrfs та snapshots, зіткнувся з фундаментальною проблемою.
Проблема 1: лише одна активна альтернатива
Симлінк може вказувати тільки на одну ціль. Для простих випадків (наприклад, вибір між vim і nano) цього достатньо. Однак коли мова йде про розробку, де одночасно встановлені Node.js 18, 20 і 22, виникають проблеми.
Сценарій:
- Ви явно запускаєте програму через
node18 - Вона викликає дочірній процес через
#!/usr/bin/node - Дочірній процес запускається на Node.js 22 (бо симлінк
/usr/bin/nodeвказує на неї) - Результат: непередбачувана поведінка і важкі для діагностики помилки
Проблема 2: відсутність юзер-левел налаштувань
update-alternatives - це інструмент системного адміністратора. Звичайний користувач без прав root не може змінити налаштування для свого облікового запису. Єдиний обхідний шлях - ручні симлінки у ~/.local/bin, що не є універсальним рішенням.
Проблема 3: /var і снапшоти (головна проблема для openSUSE)
Ось де openSUSE зіткнувся з архітектурним обмеженням:
update-alternativesзберігає свій стан у/var/lib/alternatives/- У openSUSE коренева файлова система (
/) снапшотується через Btrfs /varнавмисно винесений в окремий btrfs-subvolume, який не входить до снапшоту
Наслідки: Коли ви встановлюєте пакет, RPM-скрипти викликають update-alternatives, який записує стан у /var/lib/alternatives/. Цей запис існує поза снапшотом. Якщо ви виконуєте rollback системи до попереднього снапшоту - /var залишається з новим станом, а стан пакетів у снапшоті розходиться зі станом alternatives. Система стає неконсистентною.
Для звичайного Tumbleweed-робочого столу це може бути неприємністю. Для MicroOS або будь-якої image-based системи - це концептуальна несумісність. Коли ОС побудована навколо атомарних оновлень і гарантованих rollback’ів, механізм, що зберігає стан за межами снапшотів, є архітектурним протиріччям.
Що таке libalternatives
libalternatives - це інноваційний підхід, запропонований Adam Majer у 2021 році в розсилці openSUSE Factory. Основна ідея: перенести логіку вибору версії з «магічного симлінка» в бібліотеку часу виконання.
Архітектура
| Компонент | update-alternatives | libalternatives |
|---|---|---|
| Тип | Інструмент часу встановлення | Бібліотека часу виконання |
| Модифікація стану | Так (під час встановлення пакета) | Ні (тільки читання під час виконання) |
| Збереження конфігурації | /var/lib/alternatives/ | /usr/share/libalternatives/ |
Технічна реалізація
Конфігураційні файли: Пакет розміщує в
/usr/share/libalternatives/<ім'я_програми>/<пріоритет>.confфайл з описом альтернативиБінарники: Самі бінарники (
/usr/bin/node,/usr/bin/javaтощо) стають симлінками на/usr/bin/altsМеханізм роботи: Коли ви запускаєте
java, насправді виконуєтьсяalts, який:- Через
argv[0]розуміє, яку програму викликали - Читає конфігураційні файли з
/usr/share/libalternatives/java/ - Враховує системні та користувацькі уподобання
- Передає виклик потрібному бінарнику через
exec()
- Через
Переваги архітектури
- Конфігурація у складі пакета: Файли в
/usr/share/є частиною пакета і входять до знімку файлової системи - Атомарність: Rollback повертає все в узгоджений стан, включно зі станом альтернатив
- Ніяких записів у
/var/: Уникнення проблеми з снапшотами
Ієрархія пріоритетів
libalternatives використовує прозору ієрархію:
юзер → адміністратор → пакет Юзерські налаштування (у ~/.config/libalternatives/) мають найвищий пріоритет. Системний адміністратор може встановити одне значення, пакет - запропонувати інше, але вибір користувача переважить обидва.
Порівняння: update-alternatives vs libalternatives
| Аспект | update-alternatives | libalternatives |
|---|---|---|
| Тип | Інструмент часу встановлення | Бібліотека часу виконання |
| Збереження стану | /var/lib/alternatives/ | /usr/share/libalternatives/ |
| Сумісність зі снапшотами | ❌ Ні (стан поза снапшотом) | ✅ Так (стан у складі снапшота) |
| Юзер-левел налаштування | ❌ Ні (потрібен root) | ✅ Так (~/.config/libalternatives/) |
| Overhead при запуску | ❌ Ні (прямий симлінк) | ⚠️ Так (читання конфігурації + exec()) |
| Сумісність з іншими дистрибутивами | ✅ Так (стандарт de-facto) | ❌ Ні (тільки openSUSE) |
| Управління slave links | ✅ Так (через --slave) | ✅ Так (через конфігураційні файли) |
| Рівень control | Системний | Системний + користувацький |
Команди alts: довідник
Управління libalternatives здійснюється через команду alts.
| Команда | Опис | Приклад |
|---|---|---|
alts --display <name> | Показує поточний стан для вказаної альтернативи | alts --display java |
alts --set <name> <path> | Встановлює альтернативу для поточного користувача | alts --set java /usr/lib/jvm/java-25-graalvm/bin/java |
sudo alts --set <name> <path> | Встановлює системний default | sudo alts --set java /usr/lib/jvm/java-21-openjdk/bin/java |
alts --reset <name> | Скидає до системного default | alts --reset java |
alts --list <name> | Показує всі доступні альтернативи | alts --list java |
Примітка: Юзерські налаштування живуть у
~/.config/libalternatives/і мають найвищий пріоритет.
Висновки
libalternatives - це символічний крок openSUSE у напрямку сучасної архітектури дистрибутивів. Він вирішує конкретну проблему сумісності зі снапшотами, яка критична для image-based систем типу MicroOS.
Поточний статус у openSUSE
Згідно з офіційною документацією, проекту пропонує три стратегії для мейнтейнерів пакетів:
- Міграція на
libalternatives- для ключових пакетів (Java, Node.js тощо) - Використання
Provides/Conflicts- для взаємовиключних пакетів - Залишити
update-alternatives- якщо альтернативи не підходять
На практиці пакети мігрують поступово. Java вже перейшла на libalternatives, інші знаходяться в процесі.
Важливо:
update-alternativesнікуди не зникне і залишиться доступним у openSUSE. Проте, для ключових пакетівlibalternativesпоступово стає стандартом.
Поширення поза openSUSE
Поза openSUSE ситуація стабільна. update-alternatives залишається де-факто стандартом:
- Вбудований у Debian Policy
- присутній у RHEL/CentOS
- Використовується у Fedora
Навряд чи інші дистрибутиви підуть шляхом SUSE в найближчому майбутньому.
Швидка шпаргалка
# Перегляд поточного стану для java
alts --display java
# Перегляд всіх доступних альтернатив
alts --list java
# Встановлення для поточного користувача
alts --set java /usr/lib/jvm/java-25-graalvm/bin/java
# Встановлення системного default (потрібен sudo)
sudo alts --set java /usr/lib/jvm/java-21-openjdk/bin/java
# Скидання до системного default
alts --reset java
# Перевірка, яка версія java насправді запускається
readlink -f /usr/bin/java
java -versionComments
Please ensure Giscus is configured with your correct Repository ID and Category ID at giscus.app to enable comments.