GitLab의 파일 저장소
우리는 파일 업로드, 저장 및 검색을 처리하기 위해 CarrierWave 젬을 사용합니다.
파일 업로드는 워크호스에 의해 가속화되어야 하며, 자세한 내용은 업로드 개발 문서를 참조하세요.
파일 업로드는 상황에 따라 여러 장소에서 사용됩니다:
- 시스템
- 인스턴스 로고 (로그인/가입 페이지에서 볼 수 있는 로고)
- 헤더 로고 (네비게이션 바에 표시되는 로고)
- 그룹
- 그룹 아바타
- 사용자
- 사용자 아바타
- 사용자 스니펫 첨부파일
- 프로젝트
- 프로젝트 아바타
- 이슈/MR/노트 Markdown 첨부파일
- 이슈/MR/노트 레거시 Markdown 첨부파일
- CI 아티팩트 (아카이브, 메타데이터, 추적)
- LFS 객체
- 병합 요청 차이
- 디자인 관리 디자인 썸네일
- 주제
- 주제 아바타
디스크 저장소
GitLab은 모든 것을 로컬 디스크에 저장하기 시작했습니다. 이전 버전과의 디렉토리 위치는 변경되었지만, 여전히 100% 표준화되어 있지는 않습니다. 아래에서 확인할 수 있습니다:
설명 | 데이터베이스에? | 상대 경로 (CarrierWave.root 기준) | 업로더 클래스 | 모델 유형 |
---|---|---|---|---|
인스턴스 로고 | 예 | uploads/-/system/appearance/logo/:id/:filename |
AttachmentUploader |
Appearance |
헤더 로고 | 예 | uploads/-/system/appearance/header_logo/:id/:filename |
AttachmentUploader |
Appearance |
그룹 아바타 | 예 | uploads/-/system/group/avatar/:id/:filename |
AvatarUploader |
Group |
사용자 아바타 | 예 | uploads/-/system/user/avatar/:id/:filename |
AvatarUploader |
User |
사용자 스니펫 첨부파일 | 예 | uploads/-/system/personal_snippet/:id/:random_hex/:filename |
PersonalFileUploader |
Snippet |
프로젝트 아바타 | 예 | uploads/-/system/project/avatar/:id/:filename |
AvatarUploader |
Project |
주제 아바타 | 예 | uploads/-/system/projects/topic/avatar/:id/:filename |
AvatarUploader |
Topic |
이슈/MR/노트 Markdown 첨부파일 | 예 | uploads/:hash_project_id/:random_hex/:filename |
FileUploader |
Project |
이슈/MR/노트 레거시 Markdown 첨부파일 | 아니오 | uploads/-/system/note/attachment/:id/:filename |
AttachmentUploader |
Note |
디자인 관리 디자인 썸네일 | 예 | uploads/-/system/design_management/action/image_v432x230/:id/:filename |
DesignManagement::DesignV432x230Uploader |
DesignManagement::Action |
CI 아티팩트 (CE) | 예 |
shared/artifacts/:disk_hash[0..1]/:disk_hash[2..3]/:disk_hash/:year_:month_:date/:job_id/:job_artifact_id (:disk_hash 는 project_id 의 SHA256 다이제스트입니다) |
JobArtifactUploader |
Ci::JobArtifact |
LFS 객체 (CE) | 예 | shared/lfs-objects/:hex/:hex/:object_hash |
LfsObjectUploader |
LfsObject |
외부 병합 요청 차이 | 예 | shared/external-diffs/merge_request_diffs/mr-:parent_id/diff-:id |
ExternalDiffUploader |
MergeRequestDiff |
이슈 가능 메트릭 이미지 | 예 | uploads/-/system/issuable_metric_image/file/:id/:filename |
IssuableMetricImageUploader |
IssuableMetricImage |
CI 아티팩트와 LFS 객체는 CE와 EE에서 다르게 동작합니다. CE에서는 GitlabUploader
를 상속받고, EE에서는 ObjectStorage
를 상속받아 S3 API 호환 객체 저장소에 파일을 저장합니다.
Markdown의 이슈, 병합 요청(MR) 및 노트에 대한 첨부파일은 프로젝트 ID의 해시와 함께 해시 저장소를 사용합니다.
우리는 모든 파일을 한 번에 객체 저장소로 마이그레이션하는 Rake 작업을 제공합니다. 새로운 Uploader 클래스나 모델 유형이 도입되면, 이를 해당 카테고리 목록에 추가해야 합니다.
경로 세그먼트
파일은 여러 위치에 저장되며 다양한 경로 체계를 사용합니다.
모든 GitlabUploader
파생 클래스는 이 경로 세그먼트 스키마를 준수해야 합니다:
| GitlabUploader
| ----------------------- + ------------------------- + --------------------------------- + -------------------------------- |
| `<gitlab_root>/public/` | `uploads/-/system/` | `user/avatar/:id/` | `:filename` |
| ----------------------- + ------------------------- + --------------------------------- + -------------------------------- |
| `CarrierWave.root` | `GitlabUploader.base_dir` | `GitlabUploader#dynamic_segment` | `CarrierWave::Uploader#filename` |
| | `CarrierWave::Uploader#store_dir` | |
| FileUploader
| ----------------------- + ------------------------- + --------------------------------- + -------------------------------- |
| `<gitlab_root>/shared/` | `artifacts/` | `:year_:month/:id` | `:filename` |
| `<gitlab_root>/shared/` | `snippets/` | `:secret/` | `:filename` |
| ----------------------- + ------------------------- + --------------------------------- + -------------------------------- |
| `CarrierWave.root` | `GitlabUploader.base_dir` | `GitlabUploader#dynamic_segment` | `CarrierWave::Uploader#filename` |
| | `CarrierWave::Uploader#store_dir` | |
| | | `FileUploader#upload_path` |
| ObjectStore::Concern (store = remote)
| ----------------------- + ------------------------- + ----------------------------------- + -------------------------------- |
| `<bucket_name>` | <ignored> | `user/avatar/:id/` | `:filename` |
| ----------------------- + ------------------------- + ----------------------------------- + -------------------------------- |
| `#fog_dir` | `GitlabUploader.base_dir` | `GitlabUploader#dynamic_segment` | `CarrierWave::Uploader#filename` |
| | | `ObjectStorage::Concern#store_dir` | |
| | | `ObjectStorage::Concern#upload_path` |
RecordsUploads::Concern
은 GitlabUploader
에 의해 저장된 각 파일에 대한 Upload
항목을 생성하여 경로의 동적 부분을 GitlabUploader#dynamic_path
를 사용하여 지속시킵니다. 그런 다음 Upload#build_uploader
메서드를 사용하여 파일을 조작할 수 있습니다.
객체 저장소
GitlabUploader
파생 클래스에 ObjectStorage::Concern
을 포함시키면 이 업로더의 객체 저장소를 활성화할 수 있습니다. 업로더에서 객체 저장소를 활성화하려면 1) RecordsUpload::Concern
을 포함하고 ObjectStorage::Extension::RecordsUploads
를 전면에 추가하거나 2) 업로더를 탑재하고 <mount>_store
라는 새 필드를 생성해야 합니다.
CarrierWave::Uploader#store_dir
는 다음과 같이 재정의됩니다:
- 저장소가 LOCAL일 때
GitlabUploader.base_dir
+GitlabUploader.dynamic_segment
- 저장소가 REMOTE일 때
GitlabUploader.dynamic_segment
(버킷 이름이 네임스페이스로 사용됨)
ObjectStorage::Extension::RecordsUploads
사용하기
이 concern은 이미 포함되지 않은 경우 RecordsUploads::Concern
을 포함합니다.
ObjectStorage::Concern
업로더는 올바른 객체 저장소를 선택하기 위해 일치하는 Upload
를 검색합니다. Upload
는 각 저장소(LOCAL/REMOTE)에 대해 #store_dirs + identifier
를 사용하여 매핑됩니다.
class SongUploader < GitlabUploader
include RecordsUploads::Concern
include ObjectStorage::Concern
prepend ObjectStorage::Extension::RecordsUploads
...
end
class Thing < ActiveRecord::Base
mount :theme, SongUploader # 우리는 훌륭한 테마 송이 있습니다!
...
end
마운트된 업로더 사용하기
ObjectStorage::Concern
은 올바른 객체 저장소를 선택하기 위해 model.<mount>_store
속성을 조회합니다.
이 열은 모델 스키마에 존재해야 합니다.
class SongUploader < GitlabUploader
include ObjectStorage::Concern
...
end
class Thing < ActiveRecord::Base
attr_reader :theme_store # 이는 ActiveRecord 속성입니다.
mount :theme, SongUploader # 우리는 멋진 테마 곡이 있습니다!
def theme_store
super || ObjectStorage::Store::LOCAL
end
...
end