Build RPM Chuẩn Với Mock: Giải Quyết Triệt Để Lỗi ‘Chạy Máy Em Ngon, Máy Server Lỗi’

Fedora tutorial - IT technology blog
Fedora tutorial - IT technology blog

“Máy em chạy ngon mà!” – Nỗi ám ảnh của mọi Packager

Nếu bạn từng đóng gói RPM trên Fedora, kịch bản này chắc chắn rất quen thuộc. Bạn viết file .spec, chạy rpmbuild, mọi thứ ra lò hoàn hảo. Thế nhưng, khi mang file .rpm đó sang một server mới hoặc gửi cho khách hàng, hệ thống báo thiếu thư viện liên tục. Tệ hơn, package cài được nhưng cứ chạy là crash vì xung đột phiên bản.

Là một dev dùng Fedora làm máy chính hơn 2 năm, mình hiểu cái bẫy này. Máy cá nhân thường là một “bãi chiến trường” với đủ loại thư viện devel, plugin và tool build cài thêm. Khi build trực tiếp trên máy host, rpmbuild sẽ tự động “nhận vơ” các thư viện có sẵn đó. Bạn quên khai báo chúng trong BuildRequires, và kết quả là một package “sống tầm gửi” ra đời.

Tại sao môi trường Local luôn là “kẻ phản bội”?

Vấn đề nằm ở sự ô nhiễm môi trường (Environment Pollution). Một hệ điều hành dùng hàng ngày không bao giờ là quy chuẩn để đóng gói vì ba lý do chính.

  • Dư thừa thư viện: Các dependency từ app khác vô tình làm thỏa mãn điều kiện build của package hiện tại. Ví dụ, bạn có sẵn openssl-devel từ một dự án cũ, nên khi build app mới, nó không báo lỗi dù bạn quên ghi vào spec.
  • Cấu hình rác: Các biến môi trường hoặc file config trong /etc đã bị bạn tùy chỉnh quá nhiều.
  • Phiên bản chồng chéo: Bạn có thể đang dùng một bản glibc hoặc thư viện custom mà chính bạn cũng không nhớ đã cài khi nào.

Để package chạy được ở mọi nơi, nó cần một môi trường “sạch” tuyệt đối. Chỉ những gì bạn khai báo rõ ràng mới được phép xuất hiện tại đó.

So sánh các giải pháp cô lập môi trường

Trước khi chọn được công cụ ưng ý, mình đã kinh qua đủ loại phương pháp:

  1. Máy ảo (VM): Cài Fedora mới tinh lên VirtualBox mỗi lần build. Cách này cực kỳ sạch nhưng lại rất nặng nề. Việc chờ đợi boot OS và setup lại môi trường tốn ít nhất 15-20 phút mỗi lần.
  2. Container (Podman/Docker): Nhanh hơn VM đáng kể. Tuy nhiên, việc quản lý quyền user, mount point và giả lập các kiến trúc khác nhau (như build cho RHEL trên Fedora) vẫn khá lỉnh kỉnh.
  3. Sử dụng Mock: Đây là tiêu chuẩn vàng của các maintainer Fedora. Mock tạo ra môi trường chroot tối giản, tự động tải dependency và dọn dẹp sạch sẽ ngay sau khi xong việc.

Mock – Cứu cánh cho các Packager chuyên nghiệp

Sau 6 tháng dùng Mock đóng gói tool nội bộ, mình thấy đây là quy trình chuyên nghiệp nhất. Mock không chỉ build sạch mà còn hỗ trợ build chéo phiên bản. Bạn đang dùng Fedora 40 nhưng vẫn có thể build cho Fedora 39 hoặc AlmaLinux 9 chỉ với một câu lệnh duy nhất.

1. Cài đặt và cấu hình nhanh

Trên Fedora, Mock có sẵn trong repo chính thức. Bạn chỉ cần chạy lệnh sau:

sudo dnf install mock

Để sử dụng Mock mà không cần dùng sudo liên tục, hãy thêm user của bạn vào group mock:

sudo usermod -a -G mock $USER
newgrp mock

Lệnh newgrp sẽ áp dụng quyền ngay lập tức. Nếu vẫn chưa được, bạn chỉ cần logout và login lại là xong.

2. Tạo Source RPM (SRPM)

Mock không build trực tiếp từ file .spec. Nó cần đầu vào là một file .src.rpm. Hãy tạo nó bằng lệnh:

rpmbuild -bs my-package.spec

File này thường nằm trong thư mục ~/rpmbuild/SRPMS/.

3. Thực hiện Build với Mock

Bây giờ là lúc Mock thể hiện sức mạnh. Giả sử bạn muốn build cho Fedora 40 kiến trúc x86_64, hãy chạy:

mock -r fedora-40-x86_64 --rebuild ~/rpmbuild/SRPMS/my-package-1.0-1.fc40.src.rpm

Quy trình tự động của Mock bao gồm:

  • Tạo một thư mục chroot mới và tải các package core (bash, dnf, coreutils).
  • Phân tích file spec để xác định danh sách BuildRequires.
  • Tự động cài đặt các dependency đó vào môi trường cô lập.
  • Tiến hành compile, đóng gói và xuất file RPM thành phẩm.

4. Kiểm tra log và Debug

Kết quả build sẽ nằm tại /var/lib/mock/fedora-40-x86_64/result/. Bạn cần chú ý hai file log quan trọng:

  • build.log: Nơi ghi lại quá trình compile. Nếu code lỗi, hãy check ở đây.
  • root.log: Ghi lại quá trình cài dependency. Nếu Mock không tìm thấy thư viện bạn yêu cầu, file này sẽ cho biết lý do.

Mẹo tối ưu: Tăng tốc build gấp 3 lần

Nhược điểm của Mock là tốn thời gian tải package và giải nén chroot. Để khắc phục, mình luôn sử dụng tmpfs để build trên RAM thay vì ổ cứng. Điều này giúp giảm thời gian build một package trung bình từ 5 phút xuống còn chưa đầy 2 phút.

Sử dụng flag sau để kích hoạt tmpfs:

mock -r fedora-40-x86_64 --plugin-option=tmpfs:max_size=4G --rebuild my-package.src.rpm

Ngoài ra, nếu bạn thường xuyên build cho các distro khác như CentOS Stream hay RHEL (qua EPEL), Mock hỗ trợ cực tốt. Chỉ cần thay đổi giá trị sau flag -r (ví dụ: epel-9-x86_64) là bạn đã có môi trường chuẩn RHEL ngay trên máy Fedora.

Lời kết

Dùng Mock không chỉ là tuân thủ tiêu chuẩn mà còn là cách tự bảo vệ mình. Nó giúp bạn loại bỏ hoàn toàn những lỗi ngớ ngẩn do môi trường cá nhân gây ra. Nếu bạn định đưa ứng dụng lên COPR hoặc đóng góp cho kho phần mềm Fedora, Mock là kỹ năng không thể thiếu. Đừng để môi trường local đánh lừa bạn thêm lần nào nữa!

Share: