Debian 리포지터리
GitLab v19.1이 가이드는 다음 내용을 설명합니다: Debian 패키지 구조에 대한 기본 개요 Debian 패키지를 관리하는 데 사용되는 패키지 관리자, 클라이언트, 도구 GitLab Debian 리포지터리의 동작 방식 Debian 패키지에는 바이너리와 소스, 두 가지 유형이 있습니다.
이 가이드는 다음 내용을 설명합니다:
-
Debian 패키지 구조에 대한 기본 개요
-
Debian 패키지를 관리하는 데 사용되는 패키지 관리자, 클라이언트, 도구
-
GitLab Debian 리포지터리의 동작 방식
Debian 패키지 기본#
Debian 패키지에는 바이너리와 소스, 두 가지 유형이 있습니다.
-
바이너리 - 보통
.deb파일이며 실행 파일, 설정 파일, 기타 데이터를 포함합니다. 바이너리 패키지는 이미 컴파일된 상태이므로 해당 OS 또는 아키텍처와 일치해야 합니다. 일반적으로dpkg를 사용하여 설치합니다. 바이너리 패키지를 설치할 때 의존성이 이미 시스템에 존재해야 합니다. -
소스 - 보통
.dsc파일과 압축된.tar파일로 구성됩니다. 소스 패키지는 사용자 시스템에서 컴파일할 수 있습니다.
패키지는 apt로 가져오고 dpkg로 설치합니다. apt를 사용하면 의존성도 함께 가져와서 설치합니다.
.deb 파일은 <패키지명>_<버전번호>-_.deb 명명 규칙을 따릅니다.
패키지에는 패키지에 대한 메타데이터가 담긴 control file이 포함되어 있습니다. dpkg --info <deb_file>을 사용하여 control file을 볼 수 있습니다.
.changes 파일은 Debian 리포지터리에 패키지 업데이트 처리 방법을 알려주는 데 사용됩니다. 아키텍처, 배포판, 버전 등 패키지에 대한 다양한 메타데이터를 포함합니다. 메타데이터 외에도 Files 섹션에 세 가지 체크섬 목록(sha1, sha256, md5)이 포함됩니다. 이 파일의 구조 예시는 sample_1.2.3~alpha2_amd64.changes를 참조하세요.
Debian 패키지를 어떻게 받을 수 있나요?#
단일 .deb 파일을 다운로드하여 dpkg로 설치할 수도 있지만, 대부분의 사용자는 apt-get을 사용하여 apt로 Debian 패키지를 사용합니다. apt는 dpkg를 래핑하여 의존성 관리와 컴파일 기능을 추가합니다.
Debian 패키지는 어떻게 게시하나요?#
작업하는 Debian 리포지터리 유형에 따라 curl을 사용하여 패키지를 게시하는 경우가 드물지 않습니다. 그러나 .changes 파일을 기반으로 관련 파일을 업로드해 주는 dput-ng를 사용하는 것이 가장 좋습니다.
배포판(distribution)이란 무엇인가요?#
Debian에서 패키지는 독립적으로 존재하지 않습니다. 패키지는 *배포판(distribution)*에 속합니다. 이것은 여러 의미를 가질 수 있지만, 가장 중요한 점은 사용자가 배포판을 지정해야 하는 데 익숙하다는 것입니다.
Debian 리포지터리는 어떻게 생겼나요?#
-
Debian 리포지터리는 여러 릴리즈로 구성됩니다.
-
각 릴리즈에는 안정적인 코드명이 부여됩니다. 공개 Debian 리포지터리에서는 "bullseye"나 "jessie" 같은 이름을 사용합니다.
또한 "stable"이나 "edge" 같은 릴리즈 채널과 동의어로 사용되는 코드명의 별칭인 suite 개념도 있습니다. 시간이 지남에 따라 변경되며 다른 코드명을 가리키게 됩니다.
-
각 릴리즈에는 여러 컴포넌트가 있습니다. 공개 리포지터리에서는 "main", "contrib", "non-free"가 있습니다.
-
각 릴리즈에는 "amd64", "arm64", "i386" 등 여러 아키텍처가 있습니다.
-
각 릴리즈에는 서명된 Release 파일이 있습니다 (GPG 서명에 대한 내용 참조).
표준 디렉터리 기반 Debian 리포지터리는 다음과 같이 구성됩니다:
dists\
|--jessie/
|--bullseye\
|Changelog
|Release
|InRelease
|Release.gpg
|--main\
|--amd64\
|--arm64\
|--contrib\
|--non-free\
pool\
|--this is where the .deb files for all releases live
공개 Debian 리포지터리의 미러는 여기에서 탐색할 수 있습니다: http://ftp.us.debian.org/debian/
공개 Debian 리포지터리에서는 전체 디렉터리 구조, 릴리즈 파일, GPG 키 및 기타 파일이 모두 Debian Archive Kit, 즉 dak라고 불리는 일련의 스크립트에 의해 생성됩니다.
GitLab Debian 리포지터리에서는 특정 파일 디렉터리를 다루지 않습니다. 대신, 코드와 기반 PostgreSQL 데이터베이스를 사용하여 이러한 다양한 요소 간의 관계를 구성합니다.
Debian 리포지터리는 무엇을 하나요?#
Debian 커뮤니티는 오브젝트 스토리지 같은 기술이 존재하기 전에 많은 패키지 리포지터리 시스템을 만들었으며, FTP를 사용하여 원격 서버에 아티팩트를 업로드했습니다. 현재 대부분의 패키지 리포지터리와 레지스트리는 서버 어딘가에 있는 디렉터리에 불과합니다. 공식 Debian 배포판에 추가된 패키지는 오픈 소스 관리자 그룹이 큐레이팅하는 중앙 공개 리포지터리에 존재합니다. 패키지 관리자는 Debian Archive Kit, 즉 dak 스크립트를 사용하여 릴리즈 파일을 생성하고 기타 유지 관리 작업을 수행합니다. 따라서 파일을 저장하고 제공하는 것 외에도, 완전한 Debian 리포지터리는 dak가 제공하는 것과 동일한 동작을 구현해야 합니다. 이 동작이 바로 GitLab Debian 레지스트리가 목표로 하는 것입니다.
GPG 키란 무엇이고 서명된 릴리즈란 무엇인가요?#
GPG 키는 안전한 데이터 전송을 위한 공개/개인 키 쌍입니다. SSH 키와 유사하게 개인 키와 공개 키가 있습니다. 공개 키를 가진 사람은 데이터를 암호화할 수 있고, 개인 키를 가진 사람은 공개 키를 사용하여 암호화된 데이터를 복호화할 수 있습니다. GPG 키를 사용하여 데이터에 서명할 수도 있습니다. 개인 키를 가진 사람은 데이터나 파일에 서명할 수 있고, 공개 키를 가진 사람은 서명을 확인하여 매칭되는 개인 키를 가진 사람으로부터 온 것임을 신뢰할 수 있습니다.
GPG를 사용하여 Debian 패키지의 릴리즈 파일에 서명합니다. 릴리즈 파일은 특정 배포판 내의 모든 패키지와 해당 다이제스트의 인덱스입니다.
GitLab Debian 레지스트리에서는 사용자가 Debian 리포지터리에 새 패키지를 게시할 때마다 백그라운드 프로세스가 새 릴리즈 파일을 생성합니다. 각 배포판마다 GPG 키가 생성됩니다. 사용자가 해당 배포판의 릴리즈를 요청하면 서명된 버전과 해당 릴리즈 파일의 진위성을 검증하기 위한 공개 GPG 키를 요청할 수 있습니다.
GitLab 리포지터리 내부 구조#
파일 업로드가 발생하면:
-
새 "incoming" 패키지 레코드가 검색되거나 생성됩니다. 모든 새 파일은 "incoming" 패키지에 할당됩니다. 이는 파일이 실제로 어떤 패키지와 연관되어 있는지 알게 될 때까지 사용되는 임시 보관 영역입니다.
-
새 "unknown" 파일이 저장됩니다. 이 파일이 기존 패키지에 속하는지 여부를 아직 모르기 때문에 unknown 상태입니다.
파일이 속한 패키지를 알게 되면 해당 패키지와 연결되고, 남아 있는 파일이 없으면 "incoming" 패키지가 제거됩니다. 파일의 "unknown" 상태가 올바른 파일 유형으로 업데이트됩니다.
다음으로, 파일이 .changes 형식인 경우:
-
.changes파일이 파싱되고 그 안에 나열된 파일들이 업데이트됩니다. 업로드된 모든 비.changes파일은 다양한 배포판 및 패키지와 올바르게 연결됩니다. -
::Packages::Debian::GenerateDistributionWorker와 따라서::Packages::Debian::GenerateDistributionService가 실행됩니다.
컴포넌트 파일이 생성되거나 업데이트됩니다. .changes 파일에 나열된 패키지 파일을 방금 업데이트했으므로, 이제 변경된 체크섬 값을 기반으로 컴포넌트/아키텍처 파일을 확인합니다.
- 새 릴리즈가 생성됩니다:
배포판에 대한 GPG 키가 아직 없으면 새 GPG 키가 생성됩니다.
-
Release 파일이 작성되고, GPG 키로 서명된 후 저장됩니다.
-
오래된 컴포넌트 파일이 삭제됩니다.
다음 세 개의 다이어그램은 Debian API에 파일을 업로드한 후 수행되는 경로를 보여줍니다:
sequenceDiagram
autonumber
actor Client
Client->>+DebianProjectPackages: PUT projects/:id/packages/debian/:file_name
Note over DebianProjectPackages: If .changes file or distribution param present
DebianProjectPackages->>+CreateTemporaryPackageService: Create temporary package
Note over DebianProjectPackages: Else
DebianProjectPackages->>+FindOrCreateIncomingService: Create "incoming" package
Note over DebianProjectPackages: Finally
DebianProjectPackages->>+CreatePackageFileService: Create "unknown" file
Note over CreatePackageFileService: If .changes file or distribution param present
CreatePackageFileService->>+ProcessPackageFileWorker: Schedule worker to process the file
DebianProjectPackages->>+Client: 202 Created
ProcessPackageFileWorker->>+ProcessPackageFileService: Start service
ProcessPackageFileWorker 백그라운드 job:
sequenceDiagram
autonumber
ProcessPackageFileWorker->>+ProcessPackageFileService: Start service
ProcessPackageFileService->>+ExtractChangesMetadataService: Extract changes metadata
ExtractChangesMetadataService->>+ExtractMetadataService: Extract file metadata
ExtractMetadataService->>+ParseDebian822Service: run dpkg --field to get control file
ExtractMetadataService->>+ExtractDebMetadataService: If .deb, .udeb or ddeb
ExtractDebMetadataService->>+ParseDebian822Service: run dpkg --field to get control file
ParseDebian822Service-->>-ExtractDebMetadataService: Parse String as Debian RFC822 control data format
ExtractDebMetadataService-->>-ExtractMetadataService: Return the parsed control file
ExtractMetadataService->>+ParseDebian822Service: if .dsc, .changes, or buildinfo
ParseDebian822Service-->>-ExtractMetadataService: Parse String as Debian RFC822 control data format
ExtractMetadataService-->>-ExtractChangesMetadataService: Parse Metadata file
ExtractChangesMetadataService-->>-ProcessPackageFileService: Return list of files and hashes from the .changes file
loop process files listed in .changes
ProcessPackageFileService->>+ExtractMetadataService: Process file
ExtractMetadataService->>+ParseDebian822Service: run dpkg --field to get control file
ExtractMetadataService->>+ExtractDebMetadataService: If .deb, .udeb or ddeb
ExtractDebMetadataService->>+ParseDebian822Service: run dpkg --field to get control file
ParseDebian822Service-->>-ExtractDebMetadataService: Parse String as Debian RFC822 control data format
ExtractDebMetadataService-->>-ExtractMetadataService: Return the parsed control file
ExtractMetadataService->>+ParseDebian822Service: if .dsc, .changes, or buildinfo
ParseDebian822Service-->>-ExtractMetadataService: Parse String as Debian RFC822 control data format
ExtractMetadataService-->>-ProcessPackageFileService: Use parsed metadata to update "unknown" (or known) file
end
ProcessPackageFileService->>+GenerateDistributionWorker: Find distribution and start service
GenerateDistributionWorker->>+GenerateDistributionService: Generate distribution
GenerateDistributionWorker 백그라운드 job:
sequenceDiagram autonumber GenerateDistributionWorker->>+GenerateDistributionService: Generate distribution GenerateDistributionService->>+GenerateDistributionService: generate component files based on new archs and updates from .changes GenerateDistributionService->>+GenerateDistributionKeyService: generate GPG key for distribution GenerateDistributionKeyService-->>-GenerateDistributionService: GPG key GenerateDistributionService-->>-GenerateDistributionService: Generate distribution file GenerateDistributionService->>+SignDistributionService: Sign release file with GPG key SignDistributionService-->>-GenerateDistributionService: Save the signed release file GenerateDistributionService->>+GenerateDistributionService: destroy no longer used component files
배포판(Distributions)#
패키지를 게시하기 전에 배포판을 먼저 생성해야 합니다. 프로젝트 또는 그룹 배포판 API를 사용하여 배포판을 생성하거나 업데이트하면, 데이터베이스에 초기 기반 레코드를 생성하는 것 외에도 위의 시퀀스 다이어그램에 나타난 것처럼 GenerateDistributionService가 실행됩니다.