Creating distro build tooling for a small community
작은 커뮤니티를 위한 배포판 빌드 도구 만들기
Chimera Linux 개발자가 패키지 도구 cbuild의 설계 원칙과 빌드 인프라를 설명합니다. 모든 개발자가 로컬에서 원격 빌드를 재현하고, 샌드박스·검사·의존성 정렬을 도구에 맡기는 방식으로 작은 커뮤니티의 유지보수 부담을 줄입니다.
- 주제
AI 요약
Chimera Linux는 작은 커뮤니티가 직접 유지하는 배포판입니다. 개발자는 패키지 관리의 번거로운 작업을 자동화하고, 누구나 낮은 진입 장벽으로 패키저가 되도록 빌드 도구 cbuild를 만들었습니다. 도구는 패키지 작성부터 빌드 환경 구성, 저장소 생성과 서명, 버전 갱신, 의존성 검사까지 맡습니다. 원격 빌드 머신과 개발자 컴퓨터가 같은 명령을 실행하며, 원격 인프라의 작업도 로컬에서 재현할 수 있도록 설계했습니다.
Void Linux에서 확인한 한계
개발자는 2018년부터 Void Linux의 POWER 포트를 관리하며 패키징 도구 xbps-src를 깊이 사용했습니다. xbps-src는 Bash 스크립트 기반이라 저장소 전체 템플릿을 읽는 데 최대 30분이 걸리기도 했습니다. 빌드 중 네트워크 접근을 막지 않고, 빌드 컨테이너의 파일시스템도 일관되게 보호하지 않았습니다. 추가 검사 도구가 별도 저장소에 있어 필수 절차로 보장되지 않았고, 템플릿에는 임시 sed 수정이나 느슨하게 적용되는 패치가 남기도 했습니다. 빌드 머신에서 패키지별 테스트를 실행하지 않는 점, 여러 아키텍처를 크로스 컴파일하면서 생기는 품질 문제, 대량 재빌드와 저장소 스테이징의 불편도 개선 과제로 꼽았습니다.
cbuild의 설계
Chimera는 2021년에 cbuild와 패키지 저장소 cports 개발을 시작했습니다. 첫 목표는 속도와 엄격성입니다. 수천 개 템플릿의 메타데이터를 1초 안에 읽고, 빌드 설정 단계부터 네트워크 접근을 차단합니다. 빌드 디렉터리와 설치 단계의 대상 디렉터리만 쓰기 가능하게 제한하며, Bubblewrap(bwrap)과 Linux 네임스페이스로 샌드박스를 구성합니다. 도구 본체는 호스트에서 실행하고, 실제 빌드 명령만 샌드박스 안에서 실행합니다.
Python 표준 라이브러리, Bubblewrap, Git, 패키지 관리자만 있으면 어느 Linux에서도 cports를 사용할 수 있습니다. 패키지 템플릿은 Python으로 작성하지만, 도구가 잘못된 동작을 검사하고 형식, 의존성, 메타데이터, SPDX 라이선스 표현식까지 확인합니다. 빌드 스타일을 이용하면 Autotools, Meson, Cargo 같은 시스템의 공통 작업을 선언적으로 처리합니다. 단위 테스트는 기본으로 실행하며, 빌드 결과물은 서명된 패키지로 만듭니다.
일반적인 작업은 저장소를 복제한 뒤 ./cbuild keygen으로 서명 키를 만들고, ./cbuild bootstrap으로 빌드 환경을 준비하는 순서입니다. 패키지는 ./cbuild pkg 패키지명으로 빌드하고, ./cbuild commit 패키지명으로 필요한 파일을 포함한 커밋을 생성합니다. 기존 패키지는 버전 갱신, 업그레이드 준비, 재빌드, 커밋을 차례로 진행합니다. update-check로 새 버전을 확인하고, bulk-pkg에 Git 변경 범위나 오래된 패키지 목록을 지정해 여러 패키지를 한꺼번에 빌드할 수도 있습니다.
apk와 저장소 처리
Chimera는 초기에는 xbps를 사용했지만 이후 apk로 전환했습니다. apk에는 실제 의존성 해결기가 있어 패키지 간 관계를 더 일관되게 처리합니다. xbps가 공유 라이브러리 이름과 패키지 이름을 별도 메타데이터로 관리하고 중앙 매핑 파일에 의존하는 반면, apk는 so:libfoo.so.1 같은 가상 패키지를 사용합니다. 명령 이름을 나타내는 cmd:foo도 가상 패키지로 다룰 수 있습니다. apk의 트리거는 파일 변경을 모아 트랜잭션 끝에 실행합니다. xbps-src는 패키지 스크립트로 이를 흉내 내기 때문에 여러 패키지가 같은 캐시 갱신 작업을 반복하고, 변경 도중 트랜잭션이 끊길 수 있다고 설명합니다.
원격 빌드 인프라
Chimera의 빌드 인프라는 Buildbot을 사용하지만, 빌더는 cbuild 외의 작업을 거의 하지 않습니다. 저장소 변경 알림을 받은 작업자가 cports를 직접 가져오고 bootstrap-update로 빌드 환경을 갱신합니다. 이어 bulk-print-ver status:unbuilt으로 저장소에 아직 빌드되지 않은 패키지를 찾고, 의존성 순서에 맞춰 빌드합니다. cbuild는 전체 템플릿을 빠르게 다시 읽어 중간 의존성까지 반영한 정렬을 수행하므로, 오케스트레이터가 별도 정렬 로직을 가질 필요가 없습니다.
새 패키지는 먼저 스테이징 영역에 들어갑니다. 새 버전이 공유 라이브러리 제공자를 바꿨는데 이전 제공자를 필요로 하는 패키지가 남아 있으면 게시를 중단합니다. 필요한 역의존 패키지를 재빌드한 뒤에야 스테이징 내용을 저장소에 합칩니다. 저장소를 정리하고 미러에 동기화할 때도 새 패키지를 올리고 인덱스를 교체한 다음 오래된 패키지를 삭제해, 인덱스가 아직 없는 패키지를 가리키지 않게 합니다.
빌드 머신은 아키텍처별로 나뉘며 x86_64, aarch64, ppc64le, loongarch64, riscv64를 대상으로 운영합니다. 대부분 Chimera 호스트를 쓰지만 riscv64 빌더는 Fedora에서 실행합니다. 개발자는 이 모든 절차를 로컬에서 실행할 수 있으며, 원격 빌드 환경을 재현하는 데도 몇 분에서 한 시간 정도면 충분하다고 설명합니다.
Lobsters 반응
- @hawski — Void Linux를 오래 사용했고, 과거에 Void를 기반으로 배포판을 만드는 일도 조금 해봐서 이 글이 무척 흥미로웠습니다. 제 경험으로는 xtools 검사가 패키지 승인 전에 보통 실행되므로 사실상 필요합니다. Void는 단순하고 빠르며 패키지를 만들기도 꽤 쉽지만, 스테이징이나 트리거처럼 겉으로 드러나지 않는 복잡성도 있습니다. 저는 재현성을 어느 정도 목표로 수정 시각을 안정적으로 유지하는 불변 배포판을 만들려다 이 부분을 조금 살펴봤습니다. 단순해서 부트스트랩하기 쉽기도 합니다. Python은 전통적으로 부트스트랩하기 훨씬 어려웠지만, 요즘은 어느 정도 해결하는 방법이 있는 것 같습니다. 가끔 다른 배포판을 살펴보는데 Alpine과 Chimera에도 다시 관심이 생겼습니다. 불변 배포판을 선택하더라도 컨테이너 안에는 쓰기 가능한 배포판을 둘 것 같습니다. 노트북에서 Chimera는 어떤가요? “Merchant of the Void”라는 노래를 아시는 분 있나요?
- @q66 — 부트스트랩의 의미에 따라 다릅니다. 다른 Linux 배포판에서 소스 코드를 컴파일한다는 뜻이라면 Python은 stage0 부트스트랩 경로에 포함되지 않으므로 차이가 없습니다. 완전히 처음부터 부트스트랩한다는 뜻이라면 Python은 더 작은 문제 중 하나입니다. Python은 빌드가 간단하고 의존성도 최소한이며, 필요한 경우에도 이미 갖췄을 법한 것들입니다. Autotools와 zlib, bz2, zstd, expat, openssl, sqlite, libffi가 해당합니다. 대부분 환경에서 libedit이나 readline도 선택 사항입니다. Chimera는 노트북에서도 잘 작동합니다. 저는 최신 Panther Lake 노트북에서 쓰고 있으며 모든 것이 예상대로 작동합니다.
- @dkarvik — 좋은 글입니다. Void가 독특하고 함께 작업하기 좋은 이유를 잘 담았습니다. 패키징 품질이 높으면서도 개선할 부분이 남아 있다는 점도 좋습니다. apk가 xbps로 해결하지 못한 문제를 더 알고 싶습니다. 의존성 해결 외에는 가상 의존성을 기본으로 더 강하게 적용하는 점이 전부인가요? 주제와 조금 벗어나지만 dinit과 musl을 선택한 이유도 궁금합니다. musl 때문에 Chimera를 더 오래 써보지 않았습니다. Zoom 같은 Linux 바이너리가 필요할 때 막힐까 걱정됩니다. runit도 흥미롭지만 nitro를 보면 크게 개선할 여지가 있어 보입니다. dinit을 선택한 배경은 무엇인가요? 빌드 플래그, 변형 패키지,
-git패키지도 설계 과정에서 고려했나요? 호기심으로 brave-bin을, 실용성 때문에 neovim-git을 원합니다. Void에 .NET이 없어 *arr 스택을 쓸 수 없는 점도 답답합니다. Chimera의 설계로 이런 문제를 해결할 수 있을지 궁금합니다. turnstile을 설정에 넣어 써보니 systemd 없이도 잘 작동한다는 점이 좋았습니다.
원문: Lobsters / 번역·요약: Trawling