From Thin Air to Bootable Images: The tine Build System
빈 환경에서 부팅 이미지까지: Buck2 기반 빌드 시스템 tine
tine은 Buck2를 바탕으로 RPM·Go·Rust 구성요소와 부팅 가능한 운영체제 이미지를 함께 빌드하는 시스템입니다. 입력을 모두 고정하고 빌드 작업을 격리해 재현성을 확보하며, 캐시와 패키지 관리, SBOM 생성도 지원합니다.
- 주제
AI 요약
운영체제 이미지의 무결성을 암호학적으로 검증하려면 빌드 과정부터 입력과 결과를 신뢰할 수 있어야 합니다. amutable의 tine은 Buck2를 기반으로 RPM 패키지, Go·Rust 프로젝트, UKI와 부팅 이미지를 한 빌드 그래프에서 다루는 오픈소스 빌드 시스템입니다. 개발자는 입력을 고정하고, 변경한 구성요소를 여러 이미지에서 곧바로 빌드·테스트할 수 있습니다.
기존 도구를 검토한 이유
개발팀은 먼저 mkosi, Open Build Service(OBS), Apache BuildStream, Antlir를 살펴봤습니다. mkosi는 개별 이미지 제작에는 적합하지만, 서로 다른 여러 이미지와 이미지 외 산출물을 하나의 방식으로 관리하기 어렵다고 판단했습니다. 이미지 제작을 중심에 둔 프레임워크라 Cargo 크레이트 컴파일이나 UKI 빌드 같은 작업을 같은 수준의 규칙으로 구성하기 어렵다는 설명입니다.
OBS는 패키지부터 ISO까지 다양한 결과물을 만들고 의존성을 추적하지만, 중앙 서버를 운영해야 하며 새 산출물 유형을 추가하기 어렵습니다. BuildStream은 YAML 요소를 격리 빌드하고 입력 해시로 결과를 캐시하는 성숙한 도구지만, Python과 컴파일된 확장, 여러 호스트 도구에 의존합니다. YAML에 함수가 없어 설정이 커지면 반복도 생긴다고 봤습니다. Meta의 Antlir는 Buck2를 이미지 빌드에 활용하지만, 내부 저장소에 맞춘 고수준 도구라 그대로 채택하지는 않았습니다. 대신 그 기반 엔진인 Buck2를 선택했습니다.
Buck2 규칙으로 구성하는 빌드
tine은 Buck2 규칙 묶음입니다. Buck2의 BUCK 파일은 Python 계열 언어인 Starlark로 작성하며, 빌드 대상과 규칙을 선언합니다. 규칙은 입력과 명령을 빌드 액션으로 변환하고, 액션은 선언한 입력만 볼 수 있는 샌드박스에서 실행됩니다. Buck2는 파일 수정 시각이 아니라 소스, 도구 바이너리, 플랫폼 설정, 명령줄을 포함한 입력 전체의 해시를 기준으로 작업을 다시 실행할지 결정합니다. 따라서 입력이 같으면 로컬 또는 공유 캐시에서 결과를 가져올 수 있습니다.
tine이 요구하는 호스트 도구는 git, Python 3, 사용자 네임스페이스뿐입니다. Python 3는 tine 자체를 부트스트랩할 때만 쓰며 실제 제품 빌드에는 필요하지 않습니다. 빌드에 필요한 나머지 환경은 고정된 선언에서 부트스트랩합니다. ‘box’는 작업에 필요한 패키지와 환경을 선언한 실행 단위입니다. rpmbuild, Go, Cargo용 box나 QEMU와 systemd-ukify를 포함한 Fedora Rawhide box를 제공하며, 프로젝트별 box도 만들 수 있습니다.
Go 프로그램을 넣은 이미지 만들기
글은 Fedora Rawhide 기반 이미지에 디스크 사용량을 보여주는 Go 도구 duf를 넣어 QEMU에서 실행하는 예제를 단계별로 소개합니다. 먼저 저장소에 tine을 서브모듈로 추가하고 초기화합니다. BUCK 파일에서는 Go 컴파일러가 들어 있는 box를 선언하고, duf 저장소의 특정 Git 커밋을 지정해 입력을 고정합니다. 이어 go.package 규칙으로 바이너리를 빌드합니다.
다음으로 Fedora 패키지 관리자를 이용해 부팅에 필요한 패키지를 설치하는 이미지를 선언하고, 빌드한 duf 바이너리를 /usr/bin/duf에 복사합니다. 이 이미지에 VM 정의를 연결하면 tine 명령 한 번으로 Go 프로젝트와 이미지를 빌드하고 QEMU를 실행합니다. 예제에서는 Fedora Rawhide가 부팅된 뒤 자동 로그인한 셸에서 duf의 도움말을 확인합니다. 저장소의 예제에는 Secure Boot와 verity 서명, Go·Rust 프로젝트 빌드, 통합 테스트 등 추가 사례도 있습니다.
패키지 관리와 SBOM
tine은 Fedora나 Arch 패키지를 가져오고 수정·동기화·병합하는 도구를 제공하며, 의존성 갱신과 패키지 카탈로그 업데이트도 지원합니다. 이미지 서명에는 PKCS#11을 통한 하드웨어 키 또는 로컬에서 만든 키를 쓸 수 있습니다. Syft를 통합해 CycloneDX 형식 SBOM을 생성하는 기능도 포함합니다. 글은 이런 기능 외에 공유 빌드 캐시와 그 위협 모델, 외부 Cargo·Go 프로젝트를 감사 가능한 방식으로 이미지에 포함하는 방법도 문서에서 다룬다고 안내합니다.
Lobsters 반응
- @grohan — 설명이 좋습니다. Starlark, 콘텐츠 주소 지정 액션, 원격 캐시를 선택했다면 자연스러운 후보로 보이는 Bazel은 왜 비교 목록에 없었는지 궁금합니다. Bazel은 로컬 샌드박싱 기능인 linux-sandbox도 기본 제공합니다. Buck2에는 그 기능이 대부분 없고, box가 그 부족한 부분을 어느 정도 보완하는 것 같습니다.
- @trenchant — 첫 번째 기준 때문에 JVM이 탈락한 것 같습니다. 그래도 JVM 설치 프로그램에서 설치된 기기가 수십억 대라고 광고하던 게 아직 기억납니다. 첫 번째 기준은 최소한의 호스트 요구사항입니다. 자체적으로 동작하고 외부 의존성을 줄여 어떤 환경에서든 실행할 수 있어야 한다는 뜻입니다.
원문: amutable / 번역·요약: Trawling