GitLab의 파일 리포지터리
파일 업로드, 저장 및 검색을 다루기 위해 CarrierWave gem을 사용합니다.
파일 업로드는 Workhorse에 의해 가속화되어야 하며, 자세한 내용은 업로드 개발 문서를 참조하십시오.
컨텍스트에 따라 파일 업로드가 사용되는 많은 곳이 있습니다:
- 시스템
- 인스턴스 로고 (로그인/가입 페이지에서 표시되는 로고)
- 헤더 로고 (내비게이션 바에 표시되는 로고)
- 그룹
- 그룹 아바타
- 사용자
- 사용자 아바타
- 사용자 스니펫 첨부 파일
- 프로젝트
- 프로젝트 아바타
- 이슈/MR/노트 마크다운 첨부 파일
- 이슈/MR/노트 레거시 마크다운 첨부 파일
- CI 아티팩트 (아카이브, 메타데이터, 추적)
- LFS 오브젝트
- Merge Request 차이
- 디자인 관리 디자인 썸네일
- 토픽
- 토픽 아바타
디스크 리포지터리
GitLab은 모든 것을 로컬 디스크에 저장하기 시작했습니다. 이전 버전과 달리 디렉터리 위치가 변경되었지만, 아직 100% 표준화되지는 않았습니다. 아래에서 확인할 수 있습니다:
설명 | DB에 있음? | 상대 경로 (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/노트 마크다운 첨부 파일 | 예 | uploads/:project_path_with_namespace/:random_hex/:filename
| FileUploader
| Project |
이슈/MR/노트 레거시 마크다운 첨부 파일 | 아니요 | 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 |
외부 Merge Request 차이 | 예 | 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 호환 개체 리포지터리에 파일을 저장합니다.
이슈/MR/노트 마크다운 첨부 파일의 경우, 해시 리포지터리 레이아웃을 사용하여 경로를 기준이 아닌 가변 변수 :project_path_with_namespace
로 대신하는 다른 접근 방식이 있으며, 프로젝트가 새로운 접근 방식으로 마이그레이션하는 경우(10.2에서 소개됨) 프로젝트 ID의 해시를 사용할 수 있습니다.
모든 업로드를 한 번에 객체 리포지터리로 마이그레이션하려면 올인원 Rake 작업을 제공합니다. 새로운 업로더 클래스나 모델 유형이 도입되면 해당하는 Rake 작업 호출을 카테고리 디렉터리에 추가해야 합니다.
경로 세그먼트
파일은 여러 위치에 저장되며 서로 다른 경로 체계를 사용합니다.
모든 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
에 의해 저장된 파일마다 GitlabUploader#dynamic_path
를 사용하여 경로의 동적 부분을 유지하고 Upload
항목을 생성합니다. 그런 다음 Upload#build_uploader
메서드를 사용하여 파일을 조작할 수 있습니다.
객체 리포지터리
GitlabUploader
파생 클래스에 ObjectStorage::Concern
을 포함시킴으로써,이 업로더에 대한 객체 리포지터리를 활성화할 수 있습니다. 객체 리포지터리를 활성화하려면 업로더에 대해 다음 중 하나를 수행해야합니다. 1) RecordsUpload::Concern
을 포함하고 ObjectStorage::Extension::RecordsUploads
를 prepend하거나 2) 업로더를 마운트하고 <mount>_store
라는 새 필드를 만들어야합니다.
CarrierWave::Uploader#store_dir
은 다음과 같이 재정의됩니다.
- 리포지터리가 로컬인 경우
GitlabUploader.base_dir
+GitlabUploader.dynamic_segment
- 리포지터리가 원격인 경우
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