새 패키지 형식 지원 개발

이 문서는 GitLab에 패키지 관리 시스템을 추가하는 방법을 안내합니다.

이미 지원되는 형식은 패키지 및 레지스트리 문서에서 확인할 수 있습니다.

새로운 형식을 추가하는 것은 백엔드 변경만으로 가능합니다. 이 가이드는 표면적이며 코드 작성 방법을 다루지 않습니다. 그러나 다음 Merge Request을 살펴봄으로써 좋은 예제를 찾을 수 있습니다:

일반 정보

기존 데이터베이스 모델은 다음을 요구합니다:

  • 각 패키지는 프로젝트에 속합니다.
  • 각 패키지 파일은 패키지에 속합니다.
  • 패키지는 하나 이상의 패키지 파일을 가질 수 있습니다.
  • 패키지 모델은 패키지 및 해당 버전에 대한 정보를 저장하는 데 기반합니다.

API 엔드포인트

패키지 시스템은 GitLab과 API를 통해 작동합니다. 예를 들어 lib/api/npm_project_packages.rb는 npm 클라이언트와 작업하기 위한 API 엔드포인트를 구현합니다. 따라서 먼저 패키지 시스템 클라이언트가 작동하는 데 필요한 새로운 lib/api/your_name_project_packages.rb 파일을 추가해야 합니다. 일반적으로 다음과 같은 엔드포인트가 필요합니다:

  • 패키지 정보 가져오기.
  • 패키지 파일 내용 가져오기.
  • 패키지 업로드.

패키지는 프로젝트에 속하므로, 프로덕션에서 사용 가능한 프로젝트 수준 엔드포인트(원격)를 가지고 있는 것으로 예상됩니다.

원격 계층

패키지는 다양한 접근 수준 내에서 범위가 지정됩니다. 일반적으로 원격을 설정함으로써 구성됩니다. 프로젝트 수준에서 원격 엔드포인트가 설정되면 해당 프로젝트에 속한 패키지만 볼 수 있습니다. 그러나 그룹 수준 엔드포인트를 사용하여 주어진 그룹의 모든 패키지에 대한 가시성을 허용할 수 있습니다. 마지막으로 인스턴스 수준 엔드포인트를 사용하여 GitLab 인스턴스 전체의 모든 패키지에 대한 가시성을 허용할 수 있습니다.

MVC로서, 프로젝트 수준 엔드포인트로 시작하는 것을 권장합니다. 원격 계층의 전형적인 반복 계획은 다음과 같습니다:

  • 프로젝트에 게시하고 설치하기
  • 그룹에서 설치하기
  • 인스턴스에 게시하고 설치하기(Self-managed 고객을 위해)

인스턴스 수준 엔드포인트 사용에는 더 엄격한 네이밍 규칙이 필요합니다.

네이밍 규칙

인스턴스 수준 엔드포인트의 이름 충돌을 피하기 위해 패키지 네이밍 규칙을 정의해야 합니다. 이는 일반적으로 패키지가 속한 프로젝트를 식별할 수 있는 방법을 제공합니다. 이는 프로젝트 ID나 패키지 경로를 패키지 이름에 사용하는 것을 포함합니다. Conan의 네이밍 규칙을 참조하십시오.

그룹 및 프로젝트 수준 엔드포인트의 경우 네이밍은 덜 제약적일 수 있으며, 그룹 및 프로젝트 구성원이 두 개의 패키지 이름 간에 충돌이 없도록해야 합니다. 그러나 시스템은 특정 범위 내에서 기존 이름을 재사용하는 것을 방지해야 합니다.

그 외에는, 네이밍은 패키지 관리자의 네이밍 규칙을 따르고 해당 패키지 유형에 대한 ‘package.md’ 모델의 유효성 검사를 포함해야 합니다.

서비스 및 탐색기

패키지나 패키지 파일 레코드를 생성하거나 패키지를 찾는 작업과 관련된 로직은 API 파일에 있으면 안 되며, 서비스 및 탐색기에 있어야 합니다. 가능한 경우 기존 서비스와 탐색기를 사용하거나 확장하여 공통 패키지 로직을 최대한 그룹화해야 합니다.

구성

GitLab에는 설정 파일(gitlab.rb 또는 gitlab.yml)에 packages 섹션이 있습니다. 이는 GitLab에서 지원하는 모든 패키지 시스템에 적용됩니다. 보통 여기에 추가할 필요가 없습니다.

패키지는 객체 리포지터리를 사용하도록 구성할 수 있으므로 코드가 이를 지원해야 합니다.

MVC 접근 방식

GitLab에서 새로운 패키지 시스템을 통합하는 방법은 MVC를 사용하는 것입니다. 따라서 첫 번째 반복은 기본 사용자 작업을 지원해야 합니다:

  • GitLab 작업, 개인 액세스, 프로젝트 액세스 또는 배포 토큰과의 인증
  • 패키지 업로드 및 사용자 인터페이스에서 기본 메타데이터 표시
  • 패키지 가져오기
  • 필수 작업

필수 작업은 해당 패키지 관리자 CLI가 올바르게 작동하도록 GitLab이 처리해야 하는 모든 추가 요청입니다. 검색 기능 또는 패키지에 대한 메타 정보를 제공하는 엔드포인트와 같을 수 있습니다. 예를 들어:

  • NuGet의 경우, 첫 번째 MVC 반복에서 Visual Studio를 지원하기 위해 검색 요청이 구현되었습니다.
  • npm의 경우, npm이 tarball URL을 가져오기 위해 사용하는 메타데이터 엔드포인트가 있습니다.

첫 번째 MVC 반복에서는 원격 계층의 프로젝트 수준에 머물기를 권장합니다. 다른 수준은 향후 Merge Request으로 다룰 수 있습니다.

MVC는 일반적으로 두 단계를 거칩니다:

반복을 작게 유지

새로운 패키지 관리자를 구현할 때 필요한 모든 엔드포인트와 서비스를 포함하는 대규모 Merge Request을 만드는 것은 유혹적일 수 있습니다. 대신:

  1. 각 API 엔드포인트를 피처 플래그 뒤에 두세요.
  2. 각 엔드포인트 또는 동작(다운로드, 업로드 등)을 별도의 Merge Request으로 제출하여 검토 프로세스를 단축하세요.

분석

이 단계에서는 패키지 시스템에서 사용하는 API에 관련된 가능한 많은 정보를 수집하는 것입니다. 다음과 같은 측면이 유용할 수 있습니다:

  • 인증: 사용 가능한 인증 메커니즘(OAuth, 기본 인증, 기타). GitLab 사용자는 자주 자신의 개인 액세스 토큰을 사용하려고 합니다. MVC 첫 반복에서 필요하지는 않지만, 미래에는 CI/CD 작업 토큰을 지원해야 합니다.
  • 요청: 작동하는 MVC를 위해 필요한 요청은 무엇입니까? 이상적으로는 MVC를위한 필요한 모든 요청의 디렉터리을 만들어야 합니다(필수 작업 포함). 추가 조사를 통해 각 요청에 대한 예제 및 요청 및 응답 본문을 제시할 수 있습니다.
  • 업로드: 업로드 프로세스가 어떻게 작동하는 지 신중하게 분석하십시오. 이 요청은 대개 구현하기 가장 복잡할 것입니다. 업로드는 다양한 방식으로 인코딩될 수 있으며 (body 또는 멀티파트) 특정 필드의 Base64 값 인코딩인 JSON 구조와 다른 포맷으로 인코딩될 수도 있습니다. 이러한 다양한 인코딩은 GitLab과 GitLab Workhorse에서 약간 다른 구현으로 이어집니다. 더 자세한 정보는 파일 업로드를 참조하십시오.
  • 엔드포인트: GitLab에 구현 할 엔드포인트 URL 디렉터리을 제안하십시오.
  • 작업 분할: MVC를 점진적으로 빌드하기 위해 수행할 변경 디렉터리을 제안하십시오. 수행해야 할 작업의 양에 대한 좋은 아이디어를 제공합니다. 다음은 케이스별로 조정해야 할 예시 디렉터리입니다:
    1. 빈 파일 구조(API 파일, 이 패키지용 기본 서비스)
    2. “로그인”하여 패키지 관리자에 대한 인증 시스템
    3. 메타데이터 식별 및 적용 가능한 테이블 작성
    4. 객체 리포지터리 직접 업로드를 위한 Workhorse 라우트
    5. 업로드/발행에 필요한 엔드포인트
    6. 설치/다운로드에 필요한 엔드포인트
    7. 필수 작업에 필요한 엔드포인트

분석은 일반적으로 완전한 마일스톤이 소요되지만, 동일한 마일스톤에서 구현을 시작하는 것은 불가능하지 않습니다.

특히, 업로드 요청은 GitLab Workhorse 프로젝트에서 일부 요구 사항을 가질 수 있습니다. 이 프로젝트는 Rails 백엔드와 다른 릴리스 주기를 갖습니다. 따라서 업로드 요청 분석이 완료되면 아이ssue를 열어 GitLab Workhorse가 Rails 백엔드에 구현되어 있을 때 바로 사용할 수 있도록 권장합니다.

구현

다른 패키지 시스템 통합에 따라 Merge Request(Merge Requests)의 구현이 다양합니다. 기여자는 구현 단계의 중요한 측면을 고려해야 합니다.

인증

MVC(Minimum Viable Change)는 개인 액세스 토큰을 처음부터 지원해야 합니다. 이러한 토큰에 대해 두 가지 옵션을 지원합니다: OAuth 및 기본 액세스.

OAuth 인증은 이미 지원됩니다. 예시는 npm API에서 확인할 수 있습니다.

기본 액세스 인증은 API 도우미에서 특정 함수를 재정의함으로써 수행됩니다. 이러한 인증 메커니즘의 경우, 일부 클라이언트는 인증되지 않은 요청을 먼저 보내고, 401 Unauthorized 응답과 WWW-Authenticate 필드가 포함된 이 응답을 기다린 후 업데이트된(인증된) 요청을 보낼 수 있습니다. GitLab은 401 Unauthorized 응답을 처리해야 하는 경우가 더 복잡합니다. 이렇게 하는 케이스를 지원하는 것은 NuGet API에서 확인할 수 있습니다.

권한

프로젝트 및 그룹 수준 권한은 read_package, create_package, destroy_package에 대해 존재합니다. 각 endpoint는 계속하기 전에 프로젝트나 그룹에 대한 사용자의 권한을 승인해야 합니다.

데이터베이스 및 메타데이터 처리

현재 데이터베이스 모델을 사용하여 각 패키지에 이름과 버전을 저장할 수 있습니다. 새로운 패키지를 업로드할 때마다 Package의 새 레코드를 만들거나 기존 레코드에 파일을 추가할 수 있습니다. PackageFile은 파일 이름, 위치, sha1 등과 같은 모든 파일 관련 정보를 저장할 수 있어야 합니다.

특정 패키지 시스템 지원을 위해 별도의 메타데이터 모델을 생성해야 하는 경우 별도의 메타데이터 모델을 만들 수 있습니다. 패키지별 데이터의 예로 packages_maven_metadata 테이블과 Packages::Maven::Metadatum 모델을, 그리고 파일별 데이터의 예로 packages_conan_file_metadata 테이블과 Packages::Conan::FileMetadatum 모델을 참조하세요.

특정 패키지 매니저에 대한 패키지별 동작이 있는 경우, 해당 메서드를 메타데이터 모델에 추가하고 패키지 모델에서 위임하세요.

기존 패키지 UI는 packages_packagespackages_package_files 테이블의 정보만 표시합니다. 메타데이터 테이블에 저장된 데이터를 표시해야 하는 경우 ~frontend 변경이 필요합니다.

파일 업로드

파일 업로드는 GitLab Workhorse를 사용하여 처리되어야 합니다. 이는 Workhorse 프록시가 GitLab로 들어오는 모든 요청을 확인하고 업로드 요청을 가로채 파일을 업로드한 후 파일 자체가 아닌 메타데이터와 파일 위치를 포함한 메인 GitLab 코드베이스로 전달해야 함을 의미합니다. 이 프로세스에 대한 개요는 개발 문서에서 확인할 수 있습니다.

이는 코드 측면에서 말하면 각 업로드 endpoint에 대한 GitLab Workhorse 프로젝트에 경로를 추가해야 합니다(인스턴스, 그룹, 프로젝트). 이 MR은 Conan을 위해 Workhorse에 인스턴스 레벨 endpoint를 추가하는 것을 보여줍니다. 같은 파일에서 구현된 Maven 프로젝트 레벨 endpoint를 확인할 수도 있습니다.

경로가 추가된 후 API 파일에 추가적인 /authorize 버전의 업로드 endpoint를 추가해야 합니다. 이 예제는 Maven을 위해 추가된 업로드 endpoint를 보여줍니다. /authorize endpoint는 Workhorse로부터의 요청을 검증하고 승인한 후 일반적인 업로드 endpoint가 아래에 구현되어 Workhorse가 제공한 메타데이터를 사용하여 패키지 레코드를 생성합니다. Workhorse는 종류, 크기, 다양한 체크섬 형식과 같은 다양한 파일 메타데이터를 제공합니다.

테스트 목적으로 로컬 개발 환경에서 객체 리포지터리를 활성화할 수 있습니다.

파일 크기 제한

GitLab 패키지 레지스트리에 업로드된 파일은 형식별로 제한됩니다. GitLab.com에서는 시간 초과 문제 및 남용을 방지하기 위해 일반적으로 5GB로 설정됩니다.

Packages::Package 모델에 새로운 패키지 유형이 추가되면 이 예시와 같이 크기 제한을 추가해야 하거나, 파일 크기 제한이 적용되지 않는 경우 관련된 테스트를 업데이트해야 합니다(적용되지 않는 경우, 패키지 형식이 패키지 파일을 업로드하고 저장하지 않는 것이 기본적인 이유입니다).

GitLab.com의 요율 제한

패키지 매니저 클라이언트는 GitLab.com 특정 API 요율 제한을 초과하는 빠른 요청을 보낼 수 있습니다. 이는 429 Too Many Requests 오류로 이어집니다.

우리는 확장된 패키지 요율 제한을 활용할 수 있도록 특정 경로를 열어놓았습니다. 이러한 경로 접두어는 더 높은 요율 제한을 보장합니다.

/api/v4/packages/
/api/v4/projects/:project_id/packages/
/api/v4/groups/:group_id/-/packages/

MVC 체크리스트

새로운 패키지 매니저에 대한 GitLab 지원을 추가할 때 첫 번째 이터레이션에는 다음 기능이 포함되어야 합니다. 필요에 따라 여러 Merge Request을 통해 기능을 추가할 수 있지만, 피처 플래그가 제거될 때 모든 기능이 구현되어 있어야 합니다.

  • 프로젝트 수준 API
  • Push 이벤트 추적
  • Pull 이벤트 추적
  • 개인 액세스 토큰을 사용한 인증
  • Job 토큰을 사용한 인증
  • Deploy 토큰을 사용한 인증(그룹 및 프로젝트)
  • 파일 크기 제한
  • 파일 포맷 가드(패키지 유형에 대해 유효한 파일 형식만 허용)
  • 유효성 검사를 포함한 이름 정규식
  • 유효성 검사를 포함한 버전 정규식
  • 가속화된 업로드를 위한 Workhorse 경로
  • 패키지 메타데이터 추출을 위한 백그라운드 작업(해당하는 경우)
  • 문서(기능 사용 방법)
  • API 문서(개별 엔드포인트와 curl 예제)
  • db/fixtures/development/26_packages.rb에 시딩
  • Grafana 차트를 위한 런북 업데이트
  • (최소한) 패키지 게시 및 설치를 위한 종단간 기능 테스트

향후 작업

MVC 작업 중에 기여자들은 MVC에 필수적이지는 않지만 사용자 경험을 향상시킬 수 있는 기능들을 발견할 수 있습니다. 이러한 기능들을 주시하고 이슈를 열어두는 것이 일반적으로 좋은 아이디어입니다.

다음은 몇 가지 예시입니다.

  1. 검색에 필요한 엔드포인트
  2. 추가적인 패키지 정보 및 메타데이터를 표시하기 위한 프론트엔드 업데이트
  3. 파일 크기 제한
  4. 메트릭을 추적하기 위한 기능
  5. 패키지에서 더 많은 메타데이터 필드를 읽어와 이를 프론트엔드에서 사용할 수 있도록 함. 예를 들어, 패키지에 태그를 달 수 있는 것은 일반적입니다. 이러한 태그는 백엔드에서 읽혀 저장되어 패키지 UI에 표시될 수 있습니다.
  6. 원격 계층 구조의 상위 수준을 위한 엔드포인트. 이 단계에서는 명명 규칙을 만드는 것이 필요할 수 있습니다.

예외 사항

본 설명서는 기존 구조와 논리를 충족시키기 위한 패키지 관리자를 구현하는 방법에 대한 지침일 뿐입니다. 구조는 특정 패키지 관리자를 위한 제약 사항이나 요구에 따라 벗어나야 하는 합리적인 이유가 있다면, 해당 사항은 구현 이슈나 Merge Request에서 제기되어 효율적인 결과를 위해 논의되어져야 합니다.