понедельник, 1 июня 2015 г.

Так ли нужны пакетам в Ubuntu права root?

В этом посте я расскажу о том, как, теоретически, может работать установка приложений для Linux прямо в HOME, без прав root и в обход системного пакетного менеджера.

Нам что, мало пакетного менеджера?

Не секрет, что в Ubuntu любые утилиты и приложения считаются частью системы, и «разрабатываются» вместе со всей системой. Вот печальные итоги такого подхода:
  • Приложения обновляются только с обновлением всей системы. Есть исключения браузер Firefox и сторонние приложения (Skype, Google Chrome) обновляются регулярно. Но в целом, Вам придётся постоянно обновляться до последней версии своего дистрибутива просто для того, чтобы открыть созданный коллегой в MySQL Workbench набросок базы данных, или  воспользоваться методом рефакторинга из недавно вышедшей версии QtCreator...
  • Попытки получить приложение из чьего-то PPA могут привести к установке множества ненужных Вам системных пакетов, от которых зависит новая версия приложения. Всё бы ничего, но в будущем при попытке обновить систему до следующего LTS Вы либо просто не сможете обновиться, либо приведёте систему в нерабочее состояние — всё из-за того, что система не смогла рассчитать зависимости пакетов, взятых из PPA.
  • Попытки установить C++ библиотеку из других версий Ubuntu, или собрать и установить через make install тоже имеют неплохой потенциал в плане разрушения Вашей системы
Наконец, установка программ требует прав root — что в теории должно защитить программу от неосторожных действий пользователя. К сожалению, от вредоносных действий самой программы пользователь защиты не имеет — при установке пакета может выполняться от имени root любой вредоносный код, заложенный автором пакета. Кроме того, классический Linux для десктопа всё равно использует X11, который позволяет любой программе читать содержимое окон любой другой программы и отправлять ей фальшивые события ввода, даже не имея прав root. Иными словами, Linux-дистрибутивы не умеют изолировать недоверенные программы и предотвращать вредоносные действия с их стороны.

Установка в $HOME

Представьте, что вы — разработчик кроссплатформенного приложения. Ваше приложение [проприетарное, малоизвестное, узкоспециальное, часто обновляется, на закрытом бета-тесте, предназначено для не-гиковских пользователей Ubuntu] (нужное подчеркнуть) и потому поместить его в официальные репозитории Ubuntu либо PPA нельзя. Что делать? Одно из решений — создать установщик с помощью Qt Install Framework или иным способом.

Сделать установщик несложно. Сложнее заставить систему нормально воспринимать такую программу. Посмотрим, что можно сделать:
  • Путь к домашнему каталогу пользователя в Linux можно получить подстановкой ~ в shell-скриптах или через переменную окружения $HOME
const std::string homeDir{getenv("HOME")};
std::cerr << homeDir << std::endl;
  • Текстовые файлы с расширением .desktop - это аналог ярлыков в Windows (имеющих, кстати, расширение .lnk).
  • В каталоге ~/.config/autostart находятся .desktop файлы и скрипты, предназначенные для запуска при логине в систему (т.е. при входе в Ваш Desktop Environment)
  • В каталоге ~/.local/share/applications находятся .desktop файлы приложений, причём любой аналог «Пуска» в KDE, Unity, XFCE и других окружениях сканирует этот каталог и «видит» расположенные там ярлыки программ. Вот пример ярлыка для запуска Skype через optirun на ноутбуках двумя видеокартами Intel+NVIDIA (при добавлении этого файла потребуется повторный логин в систему):
[Desktop Entry]
Type=Application
Name=Skype
Name[ru]=Skype
Icon=skype
TryExec=primusrun skype
Exec=primusrun skype
Terminal=false
Categories=Qt;Internet;
  • В каталоге ~/.local/share/icons находятся дополнительные иконки, которые тоже можно указывать в .desktop файлах в строке «Icon=...». Структура каталога аналогична каталогу /usr/share/icons
  • Библиотеки, необходимые для программы, можно поместить рядом с ней и затем в команде или скрипте запуска программы добавить в переменную LD_LIBRARY_PATH относительный путь к этим библиотекам, например, . или ./libs. Можно также добавить относительный путь к библиотекам при сборке программы с помощью флагов компоновщика ld; если вы используете QtCreator с qmake, достаточно добавить три строчки:
unix:!macx {
    QMAKE_LFLAGS += '-Wl,-rpath,\'\$$ORIGIN/libs\',-z,origin'
}
На этом с теорией покончено, а практика создания установщиков в HOME для Linux будет в следующем посте

Комментариев нет:

Отправить комментарий