четверг, 14 декабря 2017 г.

Памятка: удаление подмодулей в Git

Взято отсюда: https://gist.github.com/kyleturner/1563153

1. В файле .gitmodules удаляем строки, относящиеся к удаляемому подмодулю
2. В файле .git/config удаляем строки, относящиеся к удаляемому подмодулю
3. Выполняем команду: git rm --cached <path_to_submodule>
4. Удаляем папку, куда примонтирован подмодуль.
5. Коммитим изменения.

вторник, 20 декабря 2016 г.

Шпаргалка по rpmbuild

Пересборка src.rpm:

    rpmbuild --rebuild xxx.src.rpm

Распковка src.rpm:

    rpm2cpio xxx.src.rpm | cpio --extract --make-directories --verbose

Частичная сборка:

    rpmbuild --short-circuit -b<id> --target $(uname -m) ~/rpmbuild/SPECS/xxx.spec

Где id - идентификатор секции в spec-файле:
%prep - p ( -bp )
%build - c ( -bc )
%install - i ( -bi )
%files - l ( -bl )

Полная сборка:

Выполняется после того, как последовательно прошлись по всем шагам:
    rpmbuild -ba --target $(uname -m) --clean ~/rpmbuild/SPECS/xxx.spec

Генерация gpg-ключа для подписывания пакетов:

gpg --gen-key

Добавление подписи к пакету: 

rpm --add-sign xxx.rpm

Автоматическое добавление подписи к пакету:

Сначала необходимо посмотреть список сгенерённых ключей:
$ gpg --fingerprint
/home/grin/.gnupg/pubring.gpg
-----------------------------
pub   2048R/8EF3B046 2015-01-26
      Key fingerprint = EBBC 7265 2A5E B117 E397  E63E FE30 9913 8EF3 B046
uid                  Rinat Gadelshin <rgadelsh@gmail.com>
sub   2048R/97A7AD93 2015-01-26

pub   2048R/52D7329A 2015-01-26
      Key fingerprint = 565C 5622 BD66 F17B DDB0  0378 CBF8 F0C1 52D7 329A
uid                  Rinat Gadelshin (grin) <rgadelsh@gmail.com>
sub   2048R/A394DD73 2015-01-26

Далее в файл ~/.rpmmacros необходимо добавить следующие строки:
%_signature gpg
%_gpg_name Rinat Gadelshin (grin) <rgadelsh@gmail.com>
 

По сути, мы прописываем строку uid, относящуюся к выбранному ключу (52D7329A из вывода команды gpg --fingerprint). Видно что для нашего ключа строка содержит комментарий (grin), а для другого ключа ( 8EF3B046 ) комментарий не содержится.


четверг, 10 ноября 2016 г.

Поиск библиотеки, содержащей определение функции

Переодически при компиляции сторонних продуктов возникает ошибка
 undefined reference to <function>
для какой либо функции. Обычно я гуглил имя функции и искал, что кто-нибудь скажет какую библиотеку надо прилинковать к проекту.
Вчера, в очередной раз столкнувшись с подобной проблемой написал, в терминале команду, которая ищет данную функцию.

function="dbus_watch_set_data"; \
for library in $(ls /usr/lib/*.so); do \
    res=$(readelf -s ${library} 2> /dev/null | grep ${function} | grep -v 00000000); \
    if [ ! -z "$res" ]; then \
        echo "${library}: $res"; \
        break; \
    fi; \
done; \
if [ -z "$res" ]; then \
    echo "function '${function}' not found"; \
fi

Соответственно вместо dbus_watch_set_data нужно подставлять имя искомой функции.
Также можно вместо /usr/lib/ вставлять другие директории, например /usr/local/lib.

Пример удачного поика:
[grin@grinvbox-ol65-x86 ~]$ function="dbus_watch_set_data"; for library in $(ls /usr/lib/*.so); do res=$(readelf -s ${library} 2> /dev/null | grep ${function} | grep -v 00000000); if [ ! -z "$res" ]; then echo "${library}: $res"; break; fi; done; if [ -z "$res" ]; then echo "function '${function}' not found"; fi
/usr/lib/libdbus-1.so:    473: 0002bdd0   111 FUNC    GLOBAL DEFAULT   12 dbus_watch_set_data@@LIBDBUS_1_3
  1410: 0002bdd0   111 FUNC    GLOBAL DEFAULT   12 dbus_watch_set_data

Функция dbus_watch_set_data найдена (2 раза) в библиотеке /usr/lib/libdbus-1.so


Пример неудачного поиска:
[grin@grinvbox-ol65-x86 ~]$ function="dbusx_watch_set_data"; for library in $(ls /usr/lib/*.so); do res=$(readelf -s ${library} 2> /dev/null | grep ${function} | grep -v 00000000); if [ ! -z "$res" ]; then echo "${library}: $res"; break; fi; done; if [ -z "$res" ]; then echo "function '${function}' not found"; fi
function 'dbusx_watch_set_data' not found

Функция dbusx_watch_set_data не найдена (нет такой функции).


P.S. для более детального понимания, рекомендую man readelf.

четверг, 29 января 2015 г.

Квота на размер папки в Linux

Предыстория
Для ftp сервера на Linux-е потребовалось установить ограничение на размер папки Upload.
В итоге был выбран следующий вариант ( оригинал был прочитан тут: forum.ubuntu.ru ).

Суть метода в следующем:
Создаём файл фиксированного размера (2 GiB - 512 блоков по 4 MiB).
dd if=/dev/zero of=/opt/ftp_upload_fs bs=4M count=512
Чем больше размер блока, тем быстрее будет создаваться, но блок полностью размещается в оперативной памяти, так что не задавайте размер блока в 1 GB, если в системе у вас всего 512 MB =)

Создаём внутри этого файла файловую систему.
mke2fs -F /opt/ftp_upload_fs

Создаём папку, куда будет примонтирован данный файл.
mkdir -p /srv/ftp/upload

Теперь можно вручную примонтировать файл к папке, и задать владельца для данной папки (т.к. после примонтирования владельцем папки станет root:root).
sudo mount -o loop /opt/ftp_upload_fs /srv/ftp/upload
sudo chown ftp:ftp /srv/ftp/upload

Что бы после перезагрузки файл автоматически монтировался к папке, пропишем в /etc/fstab соответствующую инструкцию.
sudo echo "/opt/ftp_upload_fs /srv/ftp/upload auto defaults 0 1" >> /etc/fstab

После перезагрузки файл будет подмонтирован в папку, но владельцем папки будет root. Сам файл монтируется как /dev/loop устройство, для которого не поддерживается опция uid. Поэтому в /etc/rc.local прописываем владельцем данной папки пользователя ftp.
echo "chown ftp:ftp /srv/ftp/upload" >> /etc/rc.local

пятница, 23 января 2015 г.

Упаковка своего ПО в rpm-пакет

Детально описание rpm-пакетов, и особенности их создания описаны тут (оригиналперевод).
В данной статье будет дана краткая справка для ленивых =).

среда, 21 января 2015 г.

Развёртывание своего YUM-репозитория

Мотивация

Для управления набором ПО в диспетчерском центре, который должен быть отключен от Internet, предлагается развернуть свой YUM-репозиторий. Программное обеспечение, необходимое для организации работы диспетчерского центра хранится в этом репозитории в виде rpm-пакетов.

Плюсы данного подхода видятся следующие:

  • легко отслеживать версию установленного ПО ( от разработчиков не требуется встраивать механизм поддержки версий в само ПО - версия в обязательном порядке указывается для RPM-пакета ).
  • легко обновлять ПО до новой версии ( делается одной командой с клиентской машины, на которую можно зайти удалённо по ssh ).
  • легко откатить ПО к старой версии, если с обновлённой версией заметны проблемы.
  • легко устанавливать ПО на ЗИП-машину, в соответствии с той ролью, для которой её настраивают.

пятница, 16 января 2015 г.

Тонкости создания rpm-пакетов

Внимательное отношение к эпохе пакета

При разрешении зависимостей, эпоха (Epoch) имеет более важное значение чем версия пакета.
Например если в пакете указать зависимость без эпохи

Requires: qt >= 4.7.4

А в системе установлена версия 4.6.3 первой эпохи

[grin@grinvb i686]$ yum info qt
Loaded plugins: refresh-packagekit, security
Installed Packages
Name        : qt
Arch        : i686
Epoch       : 1
Version     : 4.6.3
Release     : 1.el6
Size        : 35 M
Repo        : installed

То, при установки нашего пакета, rpm решит, что 4.6.3 более новая, чем требуемая 4.7.4, следовательно зависимость удовлетворена и можно ставить пакет, что является ошибкой.