Спецификация RPM Как указать в пакете, чтобы предыдущий RPM был удалён

Вопрос или проблема

Вопрос:

Что мне нужно указать в файле foo.spec, чтобы RPM удалял предыдущий RPM перед установкой?

Описание:

Я создал файл спецификаций, который создает RPM для нескольких пакетов, использующих один и тот же источник и предоставляющих одну и ту же услугу, каждый с немного другой конфигурацией. Например, они все предоставляют одну и ту же “возможность”.

Вот пример основных элементов моего .spec файла:

%define version     1234
%define name        foo
%define release     1
%define pkgname     %{name}-%{version}-%{release}

Name:               %{name}
Version:            %{version}
Release:            %{release}
Provides:           %{name}

%package one
Summary:            Резюме для foo-one
Group:              %{group}
Obsoletes:          %{name} <= %{version}
Provides:           %{name} = %{version}

%description one
Бла бла бла

%package two
Summary:            Резюме для foo-two
Group:              %{group}
Obsoletes:          %{name} <= %{version}
Provides:           %{name} = %{version}

%description two
Бла бла бла

# %prep, %install, %build и %clean довольно просты 
# и опущены здесь ради краткости

%files one
%defattr(-,root,root,-)
%{_prefix}/%{pkgname}

%files two
%defattr(-,root,root,-)
%{_prefix}/%{pkgname}

Когда я устанавливаю первый, он устанавливается нормально. Затем я удаляю первый, а затем устанавливаю второй, это тоже работает нормально.

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

Пример сеанса:

# rpmbuild foo и копирование rpm в yum репозиторий

$ yum install foo-one
...
$ yum list installed|grep foo
foo-one.noarch           1234-1                @myrepo

$ yum install foo-two
...[Должно сказать, что он удаляет foo-one, но не говорит]...

$ yum list installed|grep foo
foo-one.noarch           1234-1                @myrepo
foo-two.noarch           1234-1                @myrepo

$ rpm -q --provides foo-one
foo = 1234
foo-one = 1234-1

$ rpm -q --provides foo-two
foo = 1234
foo-two = 1234-1

Что мне нужно указать в файле foo.spec, чтобы RPM удалял предыдущий RPM перед установкой?

Вы хотите сделать так, чтобы эти пакеты конфликтовали друг с другом, чтобы yum знал, что их нельзя устанавливать одновременно.

%package one
Summary:            Резюме для foo-one
Group:              %{group}
Obsoletes:          %{name} <= %{version}
Provides:           %{name} = %{version}
Conflicts:          %{name}-two

Ответ или решение

Чтобы обеспечить удаление предыдущего RPM перед установкой нового пакета в вашем проекте, необходимо использовать директиву Conflicts в вашем файле спецификации .spec. Эта директива сообщает менеджеру пакетов, что указанные пакеты не могут существовать одновременно.

Ниже описывается, как это сделать на практике, используя ваш пример:

Обновленная структура spec-файла

Ваш текущий foo.spec файл может быть модифицирован следующим образом:

%define version     1234
%define name        foo
%define release     1
%define pkgname     %{name}-%{version}-%{release}

Name:               %{name}
Version:            %{version}
Release:            %{release}
Provides:           %{name}

%package one
Summary:            Summary for foo-one
Group:              %{group}
Obsoletes:          %{name} < %{version}
Provides:           %{name} = %{version}
Conflicts:          %{name} two

%description one
Blah blah blah

%package two
Summary:            Summary for foo-two
Group:              %{group}
Obsoletes:          %{name} < %{version}
Provides:           %{name} = %{version}
Conflicts:          %{name} one

%description two
Blah blah blah

# %prep, %install, %build и %clean опущены для краткости

%files one
%defattr(-,root,root,-)
%{_prefix}/%{pkgname}

%files two
%defattr(-,root,root,-)
%{_prefix}/%{pkgname}

Пояснение изменений

  1. Директива Conflicts:

    • Для каждого пакета (one и two) добавьте директиву Conflicts, которая указывает на противоположный пакет. Это позволяет системе установки (например, yum) выяснить, что оба пакета не могут быть установлены одновременно.
    • Conflicts: %{name} two означает, что если установлен foo-two, то перед установкой foo-one, foo-two будет удалён.
  2. Директива Obsoletes:

    • Использование директивы Obsoletes позволяет удостовериться, что при установке нового пакета системы могу удалять более старые версии или пакеты, которые предоставляют аналогичную функциональность.

Пример установки

Теперь, когда вы установите foo-one, а затем попытаетесь установить foo-two, система сообщит вам, что foo-one будет удалён, что соответствует желаемой логике:

$ yum install foo-one
...
$ yum install foo-two
...
Removing foo-one because it conflicts with foo-two

Заключение

С помощью директив Conflicts и Obsoletes вы сможете контролировать порядок установки и обеспечивать, чтобы только одна версия пакета была установлена в любой момент времени. Эти изменения сделают ваши RPM-пакеты более управляемыми и предотвратят множественные установки, что также уменьшит потенциальные конфликты конфигураций и зависимостей на стороне конечного пользователя.

Оцените материал
Добавить комментарий

Капча загружается...