пятница, 7 сентября 2018 г.

Модифицикация стороннего rpm-пакета

Шпаргалка


  1. Исходная версия модифицируемого пакета установлена.
  2. Кладём файлы (если требуется добавить файлы) в необходимые места на своей системе.
  3. Вызываем rpmrebuild -e <package-name> 
  4. В vi-редакторе модифицируем spec-файл и сохрняем (:wq)
  5. Забираем пересобранный пакет из ~/rpmbuild/RPMS/<arch>/<package>

История


Потребовалось собрать Qt5 SQL драйвер для Oracle Database в виде отдельного пакета для Oracle Linux 7. По аналогии с имеющимися в public репозитории аналогичными пакетами аналогичных драйверов для других баз данных. Для сборки были скачаны rpm-ки oracle-instantclient18.3 c оффициального сайта и требуемый драйвер был собран. Все эти рпм-ки были помещены в локальный репозиторий. Но при запуске

sudo yum  install qt5-qtbase-oci

yum ругался следующим образом:


[grin@grinol7 ~]$ sudo yum install qt5-qtbase-oci
Loaded plugins: langpacks, ulninfo
Resolving Dependencies
--> Running transaction check
---> Package qt5-qtbase-oci.x86_64 0:5.9.2-3el7 will be installed
--> Processing Dependency: libclntsh.so.18.1()(64bit) for package: qt5-qtbase-oci-5.9.2-3el7.x86_64
--> Finished Dependency Resolution
Error: Package: qt5-qtbase-oci-5.9.2-3el7.x86_64 (topaz)
           Requires: libclntsh.so.18.1()(64bit)
 You could try using --skip-broken to work around the problem
 You could try running: rpm -Va --nofiles --nodigest


Проверка показала, что требуемая библиотека находится (как сам файл так и Provides запись к нему) в пакете oracle-instantclient18.3-basic.

[grin@grinol7 tmp]$ rpm -ql oracle-instantclient18.3-basic
/usr/lib/oracle/18.3/client64/bin/adrci
/usr/lib/oracle/18.3/client64/bin/genezi
/usr/lib/oracle/18.3/client64/lib/libclntsh.so.18.1
/usr/lib/oracle/18.3/client64/lib/libclntshcore.so.18.1
/usr/lib/oracle/18.3/client64/lib/libipc1.so
/usr/lib/oracle/18.3/client64/lib/libmql1.so
/usr/lib/oracle/18.3/client64/lib/libnnz18.so
/usr/lib/oracle/18.3/client64/lib/libocci.so.18.1
/usr/lib/oracle/18.3/client64/lib/libociei.so
/usr/lib/oracle/18.3/client64/lib/libocijdbc18.so
/usr/lib/oracle/18.3/client64/lib/libons.so
/usr/lib/oracle/18.3/client64/lib/liboramysql18.so
/usr/lib/oracle/18.3/client64/lib/network/admin/README
/usr/lib/oracle/18.3/client64/lib/ojdbc8.jar
/usr/lib/oracle/18.3/client64/lib/xstreams.jar
/usr/share/oracle/18.3/client64/doc/BASIC_README
[grin@grinol7 tmp]$ rpm -q --provides oracle-instantclient18.3-basic

libclntsh.so.18.1
oracle-instantclient18.3-basic = 18.3.0.0.0-1
oracle-instantclient18.3-basic(x86-64) = 18.3.0.0.0-1


Но если вчитаться в лог об ошибке, то qt5-qtbase-oci требует не просто libclntsh.so.18.1, а libclntsh.so.18.1()(64bit). Также видно, что oracle-instantclient18.3 в качестве "provides" дважды указывает сам себя, причём второй раз дополнительно в скобках пишет архитектуру.

oracle-instantclient18.3-basic = 18.3.0.0.0-1
oracle-instantclient18.3-basic(x86-64) = 18.3.0.0.0-1


Следовательно нужно пересобрать oracle-instantclient18.3-basic, с добавленной в spec-file "Provides" записью для libclntsh.so.18.1()(64bit).

Помимо этого можно добавить файл конфигурации для ld (например в моём случае /etc/ld.so.conf.d/oracle-instantclient18.3.conf).

Редактировать (пересобирать новую rpm) будем через утилиту rpmrebuild.
Предварительно создадим файл в своей файловой системе /etc/ld.so.conf.d/oracle-instantclient18.3.conf, в который запишем путь к библиотекам oracle

/usr/lib/oracle/18.3/client64/lib

Напоминаю,  что в моём случае oracle-instantclient18.3-basic уже был установлен. Далее выполняем команду

rpmrebuild -e oracle-instantclient18.3-basic

После этого в терминале откроется vi редактор spec-файла для нового пакета.

В моём случае необходимо было добавить строку 

Provides:      libclntsh.so.18.1()(64bit)
 

и строку

%attr(0644, root, root) "/etc/ld.so.conf.d/oracle-instantclient-18.3.conf"

в соответствующие им места spec-файла.
После этого закрываем редактор с сохранением изменений (:wq).
Возвращаемся в терминал, где на запрос rmprebuild

Do you want to continue ? (y/N) 

отвечаем утвердительно.

В моём случае новый пакет  был собран в течении секунд 20-ти (т.е. не сразу - у кого-то быстрее, у кого-то дольше). Если ошибок не пишет - то значит всё ок, просто работает. В конце rpmbuild уведомляет что пакет создан и указывает где:

result: /home/grin/rpmbuild/RPMS/x86_64/oracle-instantclient18.3-basic-18.3.0.0.0-1.x86_64.rpm
Дальше я положил пакет  в свой локальный репозиторий (выполнил createrepo на сервере где расположен репозитори) и переустановил его

sudo yum clean expire-cache
sudo yum reinstall oracle-instantclient18.3-basic

После этого qt5-qtbase-oci успешно установился.

вторник, 30 января 2018 г.

Памятка: замена одного RPM пакета, другим в одной операции

Суть:
    Требуется использовать (в Red Hat based линуксах) команду yum shell
  • yum shell
  • remove <old_package>
  • install <new_package>
  • run
  • ....
  • exit

 Предистория
     Требовалось установить свою реализацию NTP-сервера/клиента вместо стандартного для Oracle Linux пакета ntp. В своём пакете (tssd) прописано, что он предоставляет функционал ntp (Provides: ntp внутри spec-файла). Помимо этого указано, что он конфликтует с ntp (что бы они сразу хором время не подводили). Итого: если попытаться установить сначала tssd - то получим конфликт, что сначала надо удалить ntp. Если сначала удалить ntp - то  зависимые от него системные пакеты тоже удалятся, а они могут быть важны и удалять их не стоит.

Пример выполнения
   Ниже приведён лог замены ntp на tssd.

[root@grinVMOL6x86 ~]# yum shell
Loaded plugins: security
Setting up Yum Shell
> remove ntp
Setting up Remove Process
> install tssd
Setting up Install Process
> run
--> Running transaction check
---> Package ntp.i686 0:4.2.6p5-12.0.1.el6_9.2 will be erased
---> Package tssd.i686 0:1.4-75 will be installed
--> Finished Dependency Resolution

================================================================
 Package Arch  Version                 Repository          Size
================================================================
Installing:
 tssd    i686  1.4-75                  topaz               118 k
Removing:
 ntp     i686  4.2.6p5-12.0.1.el6_9.2  @public_ol6_latest  1.6 M

Transaction Summary
================================================================
Install       1 Package(s)
Remove        1 Package(s)

Total download size: 118 k
Is this ok [y/N]: y
Downloading Packages:
tssd-1.4-75.i686.rpm                                                                                                                                                                                            | 118 kB     00:00     
Running rpm_check_debug
Running Transaction Test
Transaction Test Succeeded
Running Transaction
  Installing : tssd-1.4-75.i686                              1/2 
tssd start/running, process 7303
  Erasing    : ntp-4.2.6p5-12.0.1.el6_9.2.i686               2/2 
  Verifying  : tssd-1.4-75.i686                              1/2 
  Verifying  : ntp-4.2.6p5-12.0.1.el6_9.2.i686               2/2 

Removed:
  ntp.i686 0:4.2.6p5-12.0.1.el6_9.2                                                                                                                                                                                                    

Installed:
  tssd.i686 0:1.4-75                                                                                                                                                                                                                   

Finished Transaction
> exit
Leaving Shell
[root@grinVMOL6x86 ~]#

среда, 17 января 2018 г.

Памятка: конвертация исходников CP-1251 в UTF-8 (Linux)

В долгоживущем проекте, который уже перенесли на линукс малая часть исходников была в кодировке CP-1251 (Windows 1251). А основная часть в кодировке UTF-8. Требовалось без затей перекодировать в UTF-8 указанную малую часть.

Выполнили следующим скриптом:

for incorrect_file in $(for file in $(find $(pwd) -type f | grep -E "*\.h$|*\.c$|*\.hpp$|*\.cpp$"); do file -i ${file}; done | grep charset=iso-8859-1 | awk 'BEGIN{FS=":"}{print $1}'); do echo ${incorrect_file}; iconv -f cp1251 -t utf-8 ${incorrect_file} -o ${incorrect_file}; done

Более читаемая форма:

files=$(find $(pwd) -type f | grep -E "*\.h$|*\.c$|*\.hpp$|*\.cpp$"); \
incorrect_files=$( for_ file in ${files}; do \
                                  file -i ${_file}; \
                              done | \
                              grep charset=iso-8859-1 | \
                              awk 'BEGIN{FS=":"}{print $1}'); \
for incorrect_file in ${incorrect_files} do \
    echo ${incorrect_file}; \
    iconv -f cp1251 -t utf-8 ${incorrect_file} -o ${incorrect_file}; \
done

Разбор:
  • find $(pwd) -type f - ищет рекурсивно все файлы вглубь относительно текущей директории
  • grep -E "\.h$|\.c$|\.hpp$|.\cpp$" - фильтр - выводит в stdout только файлы с раширениями: .h .c .hpp .cpp
  • file -i ${file} - выдаёт информацию о файле, включая его кодировку
  • grep charset=iso-8859-1 - фильтр - выводит в stdout только информацию по файлам, имеющим указанную кодировку. Суть в том, что для файла с фактической кодировкой CP1251 команда file  -i выводит информацию, что кодировка iso-8859-1.
  • awk 'BEGIN {FS=":"}{print $1}' из отфильтрованной строки команды file -i выводит только имя файла.
  • iconv -f cp1251 -t utf-8 ${incorrect_file} -o ${incorrect_file} - собственно перекодирует файл из кодировки CP1251 в UTF-8.