Skip to content

article2

Inho Oh edited this page Aug 8, 2024 · 4 revisions

Fedora Linux에 RPM 패키지 배포하기

Fedora는 Red Hat이 후원하는 커뮤니티 기반의 오픈소스 운영 체제로, 6개월마다 새로운 버전을 출시하여 최신 소프트웨어와 혁신적인 기능을 빠르게 도입하는 것을 목표로 합니다. RPM(Red Hat Package Manager)은 이러한 소프트웨어를 관리하기 위해 사용되는 패키지 관리 시스템으로, 패키지의 설치, 업그레이드, 제거, 확인 등을 쉽게 수행할 수 있습니다.

또한, RPM 패키지를 네트워크를 통해 사용할 수 있도록 YUM(Yellowdog Updater, Modified)과 DNF(Dandified YUM) 도구도 함께 사용됩니다.

이번 글에서는 이전에 소개한 ALN(Amazing Lucky Numbers) 라이브러리를 Fedora Linux용 RPM 패키지로 만드는 과정을 다루겠습니다. 패키지 생성에 필요한 파일 구조, 제어 파일 작성, 빌드 과정, 그리고 최종적으로 패키지를 생성하고 배포하는 방법에 대해 설명하겠습니다.

패키지 파일

Fedora에서 패키지 설치 시 사용되는 파일은 .rpm 확장자를 사용합니다. 아래에서 이 파일의 형식과 구성에 대해 자세히 알아보겠습니다.

RPM 파일 구성

.rpm 파일은 cpio 아카이브 형식으로 되어 있으며, rpm2cpiocpio 도구를 통해 내부의 데이터를 추출할 수 있습니다. 패키지 파일은 바이너리 패키지인 .rpm 파일과 소스 패키지(SRPM)인 .src.rpm 파일이 있습니다. 바이너리 패키지는 시스템에 설치할 파일들을 담고 있고, 소스 패키지는 소스 아카이브와 스펙 파일(.spec), 패치 등을 담고 있습니다.

참고로, 스펙 파일은 패키지의 빌드와 설치를 정의하는 파일로, 패키지명, 버전, 릴리즈, 설명, 라이선스, 소스 URL, 빌드 의존성, 설치 파일 목록 등을 포함하고 있습니다.

RPM 파일 내용 확인 방법

네트워크 설치를 지원하는 dnf 도구를 이용해 패키지 설치, 삭제 뿐만 아니라 RPM 파일을 직접 다운로드 받을 수도 있습니다. dnf download 명령이 이 때 사용되는데, 먼저 dnf-plugins-core 패키지를 설치해야 사용 가능합니다.

아래와 같이 패키지를 설치하고 임의로 glib2 패키지를 다운로드 받습니다. 바이너리 패키지 외에도 --source 옵션을 추가하면 소스 패키지를 받을 수 있습니다.

# dnf-plugins-core 설치
$ sudo dnf install -y dnf-plugins-core

# glib2 패키지 다운로드 - x86_64 architecture에 해당하는 RPM만 다운로드함
$ dnf download glib2.x86_64

# glib2의 소스 패키지 다운로드
$ dnf download --source glib2

$ ls
glib2-2.80.3-1.fc40.src.rpm
glib2-2.80.3-1.fc40.x86_64.rpm

rpm -qp(--query, --package) 명령을 통해 다운로드 받은 .rpm 파일의 정보를 조회할 수 있습니다.

# 패키지 정보 조회
rpm -qpi glib2-2.80.3-1.fc40.x86_64.rpm

# 패키지에 포함된 파일 목록 조회
rpm -qpl glib2-2.80.3-1.fc40.x86_64.rpm

파일을 추출하고 싶을 경우 아래와 같이 rpm2cpiocpio 명령을 조합해서 사용할 수 있습니다.

# cpio 설치
$ sudo dnf install -y cpio

# 파일 추출 - 소스 패키지
$ rpm2cpio glib2-2.80.3-1.fc40.src.rpm | cpio -idmv
glib-2.80.3.tar.xz
glib2.spec
gnutls-hmac.patch
gspawn-eperm.patch

# 파일 추출 - 바이너리 패키지
$ rpm2cpio glib2-2.80.3-1.fc40.x86_64.rpm | cpio -idmv
./usr/bin/gapplication
./usr/bin/gdbus
./usr/bin/gio
...
./usr/lib64/libgio-2.0.so.0
./usr/lib64/libgio-2.0.so.0.8000.3
...
./usr/share/licenses/glib2
./usr/share/licenses/glib2/LGPL-2.1-or-later.txt
...
./usr/share/man/man1/gio.1.gz

cpio 명령에 사용된 옵션은 아래와 같습니다.

  • -i: 아카이브에서 파일을 추출
  • -d: 필요한 디렉토리를 생성
  • -m: 파일의 수정 시간을 유지
  • -v: verbose

패키지 이름 규칙

RPM 패키지 이름은 일반적으로 다음과 같은 형식을 따릅니다.

{name}-{version}-{release}.{architecture}.rpm
{name}-{version}-{release}.src.rpm

위의 glib2 패키지명(glib2-2.80.3-1.fc40.x86_64.rpm) 기준으로 확인해 보겠습니다.

  • name: glib2
  • version: 2.80.3
  • release: 1.fc40 (release 1, fc40: Fedora core 40)
  • architecture: x86_64

이전 글에서 설명한 Debian의 deb 패키지와 비교해보면 아래와 같은 차이점이 있습니다.

  • 아키텍쳐 이름: DEB는 amd64를 사용하고 RPM은 x86_64를 사용합니다.
  • 구분자: 이름과 버전, 아키텍쳐를 구분할 때 DEB는 _-를 사용하는데, RPM은 -.을 사용합니다.
    • DEB: libglib2.0-0_2.72.4-0ubuntu2.3_arm64.deb
    • RPM: glib2-2.80.3-1.fc40.x86_64.rpm
  • 개발용 패키지 이름: deb의 경우 이름 뒤에 -dev를 사용하는데, RPM은 -devel을 일반적으로 사용합니다.
    • DEB: libglib2.0-dev_2.72.4-0ubuntu2.3_amd64.deb
    • RPM: glib2-devel-2.80.3-1.fc40.x86_64.rpm

패키지 정의하기

RPM 패키지를 정의하고 빌드하기 위해서는 스펙(.spec) 파일이 필요합니다. 스펙 파일은 패키지의 메타데이터, 빌드 및 설치 지침을 포함하는 파일로, RPM 패키지를 구성하는 핵심 요소입니다

스펙 파일의 구조

스펙 파일은 여러 섹션으로 구성됩니다. 각 섹션은 패키지를 빌드하고 설치하는 데 필요한 정보를 제공합니다. 주요 섹션은 다음과 같습니다:

  • Header: 패키지의 기본 정보를 포함합니다.
  • Description: 패키지에 대한 상세 설명을 제공합니다.
  • Package: 단일 스펙 파일에서 여러 개의 패키지를 정의할 때 사용합니다.
  • Prep: 소스를 준비하는 단계입니다.
  • Build: 소프트웨어를 컴파일하는 단계입니다.
  • Install: 소프트웨어를 설치하는 단계입니다.
  • Check: 빌드 후 테스트를 실행하는 단계입니다.
  • Files: 패키지에 포함될 파일 목록을 지정합니다.
  • Changelog: 패키지의 변경 내역을 기록합니다.

ALN 기준으로 실제로 작성해 보겠습니다.

Header

ALN에 대한 패키지 이름, 버전과 같은 기본 정보와 라이센스, 빌드 의존성 등을 명시합니다.

Name:           aln
Version:        0.1.1
Release:        1%{?dist}
Summary:        Amazing Lucky Numbers - A library and tool for generating lucky numbers

License:        Apache-2.0
URL:            https://github.com/webispy/aln
Source0:        %{name}.tar.gz

BuildRequires:  cmake
BuildRequires:  gcc
BuildRequires:  gcc-c++
BuildRequires:  glib2-devel
BuildRequires:  doxygen

Release 항목에 1%{?dist}와 같은 값이 사용되었는데, 배포판 태그에 대한 매크로를 같이 사용한 표현입니다. 최종적으로 1.fc40과 같은 값이 반영됩니다. 쉘에서 아래와 같이 직접 값을 확인해 볼 수 있습니다.

$ rpm --eval 1%{?dist}
1.fc40

소스 파일에 대해 지정할 때 Source가 아닌 Source0이 사용되었는데, 이 둘은 동일합니다. 만약 소스가 여러개라면 Source1 등의 형식으로 추가 소스 파일을 지정합니다.

또한, Source에는 URL 기반 주소를 사용할 수 있습니다. 이 경우 패키징 과정에서 소스가 자동으로 다운로드됩니다. ALN의 경우 여러가지 패키징 방법에 대해 설명하기 위해 소스와 패키지 파일들이 같이 존재하므로 URL 없이 로컬 파일을 사용하도록 설정했습니다.

Description

패키지에 대한 상세 설명을 제공합니다. 이 섹션은 %description 키워드로 시작하며, 패키지의 기능과 용도를 자세히 기술합니다:

%description
Amazing Lucky Numbers (aln) is a library and tool for generating amazing lucky numbers.

Package

단일 SPEC 파일에서 여러 개의 패키지를 정의할 때 사용되는데, 라이브러리, 실행 파일, 개발 파일 등을 별도의 패키지로 분리하여 관리할 때 유용합니다.

%package libs
Summary:        Amazing Lucky Numbers Library
%description libs
A library for generating amazing lucky numbers.

%package devel
Summary:        Development files for the Amazing Lucky Numbers Library
Requires:       %{name}-libs = %{version}-%{release}
%description devel
Development files for the Amazing Lucky Numbers Library.

위의 예제처럼 %package <sub-package-name> 형태로 지정할 수 있으며, 서브 패키지 이름에 기본 패키지 이름이 접두사로 추가됩니다. 이와 같이 설정할 경우, 기본 aln 패키지 외에도 aln-libsaln-devel 두개의 패키지가 추가로 생성됩니다.

각 패키지에 포함할 파일들은 Files 섹션(%files)에서 정의할 수 있습니다.

Prep

패키지를 빌드하기 위한 준비 작업을 수행합니다. 이 단계에서는 미리 정의된 %setup%patch 매크로를 사용할 수 있고 필요에 따라 직접 쉘 명령어를 사용할 수도 있습니다.

%prep
%setup -q -n %{name}

%setup 매크로는 소스 파일을 추출하고, 작업 디렉토리를 설정하는 데 사용하는데, 다음과 같은 옵션을 같이 사용할 수 있습니다.

  • -q: 출력 최소화
  • -n <name>: 빌드 디렉토리 이름을 지정. 소스 압축을 해제했을 때 기대되는 디렉토리 이름(%{name}-%{version})과 실제 이름이 다를 경우 설정합니다.

보다 자세한 설명은 https://rpm-packaging-guide.github.io/#setup에서 확인할 수 있습니다.

Build

빌드 단계를 정의합니다. Debian의 rules 파일에서 다양한 빌드 시스템을 지원했던 것과 마찬가지로 RPM도 CMake, meson과 같은 빌드 툴을 지원합니다.

%build
%cmake
%cmake_build

# Generate man pages using Doxygen
doxygen
find doc/man/man3 -type f ! -name 'aln*' -exec rm -f {} \;

%cmake는 Configure 단계(cmake -DCMAKE_INSTALL_PREFIX=...)를 수행하고, %cmake_build는 실제 빌드(cmake --build ...)를 진행하는 매크로입니다. 빌드가 끝나면 수동으로 Doxygen을 통해 문서를 만들고 불필요한 문서 파일을 삭제하는 쉘 스크립트를 실행합니다.

보다 자세한 설명은 https://docs.fedoraproject.org/en-US/packaging-guidelines/CMake/를 참고 바랍니다.

Install

소프트웨어를 설치하는 단계를 정의합니다.

%install
%cmake_install

# Install man pages
mkdir -p %{buildroot}%{_mandir}/{man1,man3}
install -m 644 tool/aln.1 %{buildroot}%{_mandir}/man1/
install -m 644 doc/man/man3/* %{buildroot}%{_mandir}/man3/

%cmake_install은 CMake를 통한 설치 명령(cmake --install ...)을 수행하는 매크로입니다. 설치가 끝나면 Build 단계에서 수동으로 생성했던 Doxygen 문서 설치 스크립트를 실행합니다.

Check

빌드 후 테스트를 실행하는 단계입니다.

%check
%ctest

%ctest는 CMake 스크립트에서 add_test()로 정의한 테스트 항목들에 대해 실행시키는 매크로입니다.

Files

패키지에 포함될 파일 목록을 지정합니다. ALN의 경우 기본 aln 패키지 외에 aln-libs, aln-devel 패키지를 생성하기 때문에 각 서브 패키지에 포함할 파일들을 추가로 지정해야 합니다.

aln 패키지: aln 실행 파일과 실행 파일에 대한 man 페이지

%files
%license LICENSE
%{_bindir}/aln
%{_mandir}/man1/aln.1*

aln-libs 패키지: 라이브러리 파일

%files libs
%{_libdir}/libaln.so.*

aln-devel 패키지: 헤더 파일, 빌드를 위한 라이브러리 파일, pkg-config, API man 페이지

%files devel
%{_includedir}/aln/
%{_libdir}/libaln.so
%{_libdir}/pkgconfig/aln.pc
%{_mandir}/man3/aln.h.3*
%{_mandir}/man3/aln_*.3*

Changelog

패키지의 변경 내역을 기록합니다. DEB 패키징에 사용했던 debian/changelog 파일과 같은 역할인데 형식만 다르다고 생각하면 됩니다.

%changelog
* Thu Jul 11 2024 Inho Oh <webispy@gmail.com> - 0.1.1
- fix aln.pc.in
- fix packaging
* Tue Jul 02 2024 Inho Oh <webispy@gmail.com> - 0.1.0-1
- Initial package

두번의 버전 업데이트가 있었는데, 첫번째에는 0.1.0-1 처럼 릴리즈 번호를 포함시켰고, 두번째에는 0.1.1로 릴리즈 버전 없이 사용했습니다. 둘 다 패키징에는 문제가 없지만 버전명에 릴리즈 번호를 포함 사용하는 것이 일반적입니다.

패키지 도구

앞에서 RPM 패키지 구성과 패키지를 정의하는 방법에 대해 알아보았습니다. 이제 패키지 도구를 이용해서 실제로 패키지를 만드는 방법에 대해 알아보겠습니다.

RPM 패키지 도구는 DEB 패키지 도구와 유사하게 두 가지 주요 방식을 제공합니다. 하나는 현재 환경에서 빠르게 패키지를 빌드할 수 있는 도구이고, 다른 하나는 chroot를 통해 격리된 환경에서 패키지를 생성하는 도구입니다.

  • 현재 환경에서 빠르게 패키지 만들기
    • DEB: dpkg-buildpackage
    • RPM: rpm-build
  • chroot를 통해 격리된 환경에서 패키지 만들기
    • DEB: sbuild
    • RPM: mock

rpm

RPM(Red Hat Package Manager) 패키지는 rpm 도구를 이용해 설치, 제거할 수 있으며, 설치된 패키지 목록도 확인할 수 있습니다. yum 또는 dnf 명령어를 사용해 패키지를 설치할 때, 내부적으로는 rpm 명령을 통해 실제로 패키지를 설치하게 됩니다.

rpm -ivh package.rpm     : 패키지 설치
rpm -Uvh package.rpm     : 패키지 설치 (업그레이드 설치)
rpm -e package           : 패키지 제거
rpm -qa                  : 설치된 전체 패키지 목록 확인
rpm -qi package          : 패키지 정보 확인 (설치된 패키지 이름 기반)
rpm -qip package.rpm     : 패키지 정보 확인 (패키지 파일명 기반)
rpm -ql package          : 패키지에 포함된 파일 목록 확인 (설치된 패키지 이름 기반)
rpm -qlp package.rpm     : 패키지에 포함된 파일 목록 확인 (패키지 파일명 기반)

rpm-build

rpm-build는 rpm 패키지를 빌드하기 위한 기본 도구입니다. 주로 개발 환경에서 직접 빌드할 때 많이 사용되는데, 현재 시스템 환경에서 바로 패키지를 빌드하기 때문에 빠르게 패키지를 만들 수 있습니다.

하지만, 내 시스템에서는 정상적으로 패키지 빌드에 성공했어도 다른 사람의 시스템 환경에서 똑같이 빌드가 성공한다고 보장할 수 없습니다. 각 시스템마다 설치된 패키지들이 다르기 때문입니다. 따라서, 정식으로 패키징 작업을 진행하기 전에 빠르게 패키징을 테스트할 목적으로 사용하기에 적합한 도구입니다.

ALN 기준으로 패키지 빌드하는 방법은 아래와 같습니다.

# 소스 다운로드
git clone https://github.com/webispy/aln.git
cd aln

# rpm-build 도구 설치
dnf install -y rpm-build

# ALN의 의존성 패키지 모두 설치
#  - aln.spec에 정의한 BuildRequires의 항목들을 builddep 옵션으로 모두 설치할 수 있습니다.
#  - builddep 옵션을 사용하려면 dnf-plugins-core를 설치해야 합니다.
dnf install -y dnf-plugins-core
dnf builddep -y packaging/aln.spec

# 패키지 빌드
#  -bb: build binary package only from <specfile>
#  --build-in-place: run build in current directory
rpmbuild -bb --build-in-place packaging/aln.spec

rpmbuild 명령 사용시 --build-in-place 옵션을 사용하지 않으면, 소스 파일이 $HOME/rpmbuild/SOURCES 디렉토리에 있어야 합니다. 매번 소스를 압축하여 복사하는 과정은 번거로울 수 있으므로, 이 옵션을 추가하여 빌드를 간편하게 할 수 있습니다.

빌드 후 패키지들은 $HOME/rpmbuild/RPMS/x86_64 디렉토리에 생성됩니다.

$ cd $HOME/rpmbuild/RPMS/x86_64
$ ls
aln-0.1.1-1.fc40.x86_64.rpm
aln-devel-0.1.1-1.fc40.x86_64.rpm
aln-libs-0.1.1-1.fc40.x86_64.rpm

이제 rpm 명령으로 ALN 패키지를 시스템에 설치 및 삭제할 수 있습니다. 단, rpm 명령은 의존성 패키지에 대해 자동으로 해결해주지 않기 때문에 설치 시 의존성 패키지 파일들도 같이 나열해 주어야 정상적으로 설치됩니다.

# 설치
sudo rpm -ivh aln-0.1.1-1.fc40.x86_64.rpm aln-libs-0.1.1-1.fc40.x86_64.rpm

# 삭제
sudo rpm -e aln aln-libs

mock

RPM 빌드 시스템에서 사용되는 강력한 빌드 도구로 rpm-build와 다르게 현재 시스템 환경을 이용하지 않고 chroot 환경(change root의 약자로 격리된 파일 시스템 환경을 제공)에서 빌드합니다.

Fedora의 필수 패키지만 설치된 깨끗한 가상 환경에서 빌드가 진행되기 때문에, 빌드하려는 패키지의 의존성을 확실하게 점검할 수 있고 격리된 환경이기 때문에 현재 시스템에 영향을 주지 않아 안전하게 패키징 작업을 진행할 수 있습니다.

또한, chroot를 사용하기 때문에 현재 시스템에 설치된 Fedora 배포판 버전과 다른 버전용 패키지를 생성할 수 있습니다.

mock를 통해 패키징을 수행하면 아래 과정이 매번 수행됩니다.

  • dnf update
  • 스펙 파일에 명시한 의존성 패키지 설치
  • 빌드(rpmbuild)

이후 mock 명령이 종료되면 패키징 과정 중 설치/생성된 모든 파일들이 제거됩니다. 따라서, 다시 패키징을 수행해도 매번 깨끗한 환경에서 위 과정이 새로 수행됩니다. 이는 docker에서 주로 사용하는 overlayfs와 유사한 방식을 사용하기 때문입니다.

mock 설정

mock 설치는 아래와 같이 dnf 명령으로 가능합니다.

sudo dnf install -y mock

다음으로 chroot 환경을 만들어야 합니다. 패키징 하려는 배포판 버전별로 아래 명령을 통해 생성합니다.

mock -r fedora-40-x86_64 --init
mock -r fedora-39-x86_64 --init

생성된 chroot 환경은 /var/lib/mock/ 디렉토리에서 찾을 수 있습니다.

각 배포판 목록과 배포판에 대한 설정은 /etc/mock/ 디렉토리 또는 mock --list-chroots 명령을 참고 바랍니다.

mock을 이용한 패키지

위에서 mock을 위한 chroot 준비가 모두 끝났으면, 이제 mock 명령으로 rpm 패키지를 만들 수 있습니다.

먼저 소스를 다운로드 후 스펙파일에서 지정한 Source0 파일 이름인 aln.tar.gz로 압축합니다.

git clone https://github.com/webispy/aln.git
tar cvfz aln.tar.gz aln

이제 다음 옵션들을 사용하여 SRPM(.src.rpm) 패키지를 생성합니다.

  • --spec: SRPM을 빌드하는 데 사용할 spec 파일을 지정합니다
  • --sources: SRPM을 빌드하는 데 사용할 소스(단일 파일 또는 파일이 포함된 디렉토리)를 지정합니다 (–-buildsrpm 옵션과 함께 사용됨)
  • --resultdir: 결과 파일이 저장될 경로
  • --buildsrpm: spec(–-spec ...) 파일과 소스(–-sources ...)를 사용하여 SRPM을 빌드합니다
mock -r fedora-40-x86_64 --spec=aln/packaging/aln.spec --sources=. --resultdir=. --buildsrpm

위 명령을 수행하고 나면 현재 디렉토리에 SRPM 파일(aln-0.1.1-1.fc40.src.rpm)이 생성됩니다. 이제 이 파일을 이용해 바이너리 RPM 패키지를 생성할 수 있습니다.

  • --resultdir: 결과 파일이 저장될 경로
  • --rebuild: rebuild the specified SRPM(s)
mock -r fedora-40-x86_64 --resultdir=. --rebuild aln-*.src.rpm

빌드가 끝나면 아래와 같이 생성된 패키지들을 확인할 수 있습니다.

$ ls *.rpm
aln-0.1.1-1.fc40.src.rpm
aln-0.1.1-1.fc40.x86_64.rpm
aln-debuginfo-0.1.1-1.fc40.x86_64.rpm
aln-debugsource-0.1.1-1.fc40.x86_64.rpm
aln-devel-0.1.1-1.fc40.x86_64.rpm
aln-libs-0.1.1-1.fc40.x86_64.rpm
aln-libs-debuginfo-0.1.1-1.fc40.x86_64.rpm

mock troubleshooting

일반적으로 CI/CD 환경 구성을 위해 docker 환경과 Github action을 많이 사용하는데, 패키징을 검증하기 위해 docker 안에서 mock을 실행하거나 Github Action runner안에서 mock을 실행 할 수 있습니다. 아무 이슈 없이 정상적으로 실행되면 좋겠지만, mock에서 overlayfs를 사용해서 chroot를 접근하기 때문에 때때로 문제가 발생합니다.

이를 해결하기 위해서는 기본으로 docker container 실행시 --privileged 옵션이 필요하고, overlayfs로 사용되는 /var/lib/mock 경로를 -v 옵션을 통해 volume으로 설정해야 합니다. 그리고 mock 내부에서 fuse-overlayfs를 사용하도록 추가로 설정이 필요합니다.

docker run -it --rm -v /var/lib/mock --privileged fedora:latest
# (root in Docker)
dnf update -y
dnf install -y mock git fuse-overlayfs

아래를 참고해서 ~/.config/containers/storage.conf 파일을 생성합니다.

# (root in Docker)
$ mkdir -p ~/.config/containers
$ vi ~/.config/containers/storage.conf
[storage]
driver = "overlay"
[storage.options]
mount_program = "/usr/bin/fuse-overlayfs"

이제 mock 명령으로 패키지를 생성할 수 있습니다.

# (root in Docker)
mock -r fedora-40-x86_64 --init
mock -r fedora-40-x86_64 --spec=aln/packaging/aln.spec \
                         --sources=. --resultdir=. --buildsrpm
mock -r fedora-40-x86_64 --resultdir=. --rebuild aln-*.src.rpm

ALN에서는 Github Action을 통해 CI/CD를 사용하는데, Runner 안에서 위와 같이 mock을 실행하기 위한 설정을 사용하고 있습니다. 자세한 내용은 ALN의 Github Action 스크립트(https://github.com/webispy/aln/blob/master/.github/workflows/ci.yaml)를 참고 바랍니다.

배포하기

앞의 과정을 통해 rpm 파일을 정상적으로 만들었으면 이제 배포를 해야 합니다. rpm 파일 자체를 그대로 배포할 수도 있겠지만, 그렇게 하면 매번 파일을 업로드/다운로드 해야 하는 불편함이 있고 의존성 패키지에 대해서도 따로 관리해야 합니다.

일반적인 dnf install 명령을 통해 패키지를 설치하는 것처럼, 우리가 만든 패키지도 동일한 방식으로 설치할 수 있다면 더욱 편리할 것입니다.

dnf 명령은 HTTP/HTTPS를 통해 패키지 저장소 서버에서 패키지 인덱스 정보 파일(repodata)을 가져와 내부에 저장하고 있다가 dnf install로 패키지 설치를 요청 받으면 저장된 인덱스 정보를 이용해 해당 패키지의 다운로드 URL을 얻어서 패키지 파일을 다운로드 받아 설치합니다.

따라서, 우리가 만든 패키지에 대한 정보 파일과 패키지 파일들을 웹서버를 통해 제공하면 dnf install 명령으로 패키지 설치를 가능하게 할 수 있습니다.

createrepo

createrepo 명령은 rpm 패키지들을 분석해서 repodata(패키지 인덱스 디렉토리 및 파일)를 생성합니다.

앞에서 생성한 rpm 패키지들을 한 곳에 모아놓고 다음과 같이 createrepo 명령을 수행하면, 하위에 repodata 디렉토리가 생성되며 그 안에 인덱스 파일들이 생성됩니다.

$ ls
aln-0.1.1-1.fc40.src.rpm
aln-0.1.1-1.fc40.x86_64.rpm
aln-debuginfo-0.1.1-1.fc40.x86_64.rpm
aln-debugsource-0.1.1-1.fc40.x86_64.rpm
aln-devel-0.1.1-1.fc40.x86_64.rpm
aln-libs-0.1.1-1.fc40.x86_64.rpm
aln-libs-debuginfo-0.1.1-1.fc40.x86_64.rpm

$ mkdir -p fedora/40
$ cp *.rpm fedora/40

$ createrepo fedora/40

$ ls fedora/40/repodata/
20bec12d37df5c772df406819e6e6b476ea6faa0f900bcd484ef22e469f289db-filelists.xml.zst
b89ce71877f2ca33ddddddf0a1426a2aee055c2fd5720816c1f8e0bc08670cd4-other.xml.zst
e73db0d79aab240858727aabde5356fb7db40dbb0e940ab69289a013a8d1e7c1-primary.xml.zst
repomd.xml

이제 fedora 디렉토리를 웹서버를 통해 제공하면 됩니다.

ALN의 경우 별도의 웹서버를 따로 운영하지 않고 Github에서 제공하는 정적 웹페이지 서비스인 Github Pages를 통해 배포하고 있습니다. https://github.com/webispy/aln/tree/gh-pages/fedora에서 웹페이지를 통해 제공하는 전체 파일들을 확인할 수 있습니다.

Github Pages를 통해 배포하는 방법에 대해 궁금하시면 ALN Github에 있는 Github Action 스크립트(https://github.com/webispy/aln/blob/master/.github/workflows/ci.yaml)를 참고 바랍니다. 이 스크립트에는 rpm 패키지를 생성하는 과정도 모두 포함하고 있습니다.

/etc/yum.repos.d/aln.repo

웹서버를 통해 정상적으로 rpm 패키지들을 배포하도록 설정 완료했으면 이제 dnf 명령으로 설치가 되는지 확인해 봐야 하는데, Fedora에서는 패키지 서버에 대한 설정을 /etc/yum.repos.d/ 디렉토리에서 관리하고 있습니다.

ALN 패키지 저장소에 대한 설정을 추가하기 위해 /etc/yum.repos.d/aln.repo 파일을 하나 생성합니다:

[aln]
name=aln
baseurl=https://webispy.github.io/aln/fedora/40
enabled=1
gpgcheck=0

참고로, 위에서 생성한 패키지들이 모두 서명 과정을 생략하고 만들었기 때문에 gpgcheck=0 옵션을 추가해야 서명 검증 과정을 건너뛰고 사용할 수 있습니다.

이제 패키지 저장소가 추가되었으니 시스템의 패키지 인덱스 정보를 업데이트 하도록 아래 명령을 실행합니다.

$ sudo dnf update
aln                                                              1.5 kB/s | 1.7 kB     00:01

이제 아래 명령으로 패키지를 설치 및 삭제할 수 있습니다.

sudo dnf install aln aln-devel
sudo dnf remove aln aln-devel

마무리

RPM 패키징은 처음에는 복잡해 보일 수 있지만, 각 단계를 이해하고 실습해보면 충분히 익힐 수 있는 과정입니다. 이 글이 Fedora나 다른 RPM 기반 배포판에서 소프트웨어를 패키징하고 배포하고자 하는 개발자들에게 유용한 가이드가 되길 바랍니다

Clone this wiki locally