GitLab의 파일 저장소
파일 업로드, 저장 및 검색을 처리하기 위해 CarrierWave gem을 사용합니다.
파일 업로드는 workhorse에 의해 가속화되어야 하며 자세한 내용은 업로드 개발 문서를 참조하십시오.
다음과 같은 맥락에 따라 파일 업로드가 사용되는 많은 곳이 있습니다:
- 시스템
- 인스턴스 로고 (로그인/가입 페이지에 표시되는 로고)
- 헤더 로고 (내비게이션 바에 표시되는 로고)
- 그룹
- 그룹 아바타
- 사용자
- 사용자 아바타
- 사용자 스니펫 첨부 파일
- 프로젝트
- 프로젝트 아바타
- 이슈/MR/노트의 마크다운 첨부 파일
- 이슈/MR/노트의 레거시 마크다운 첨부 파일
- CI 아티팩트 (아카이브, 메타데이터, 트레이스)
- LFS 오브젝트
- 머지 리퀘스트 차이
- 디자인 관리 디자인 섬네일
- 토픽
- 토픽 아바타
디스크 저장
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 |
외부 머지 리퀘스트 차이 | 예 | 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
을 기반으로 하는 대신 프로젝트 ID의 해시를 사용할 수 있습니다. 이 접근 방식은 새로운 접근 방식으로 마이그레이션할 경우(10.2에서 도입됨) 가능합니다.
일괄 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
concern은 GitlabUploader
에 의해 저장된 파일마다 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