GitLabのファイルストレージ

ファイルのアップロード、保存、取得にはCarrierWavegemを使っています。

ファイルのアップロードはWorkhorseによって高速化されるはずです。詳細はアップロードの開発ドキュメントを参照してください。

ファイルアップロードが使用される場所は、コンテキストによって様々です:

  • システム
    • インスタンスロゴ (サインイン/サインアップ ページで表示されるロゴ)
    • ヘッダーロゴ(ナビゲーションバーに表示されるロゴ)
  • グループ
    • グループアバター
  • ユーザー
    • ユーザーアバター
    • ユーザースニペット添付ファイル
  • プロジェクト
    • プロジェクトアバター
    • イシュー/MR/ノート Markdown添付ファイル
    • イシュー/MR/ノート レガシー Markdown添付ファイル
    • CIアーティファクト(アーカイブ、メタデータ、トレース)
    • LFS オブジェクト
    • マージリクエストの差分
    • デザイン管理デザインのサムネイル
  • トピック
    • トピックアバター

ディスクストレージ

GitLabはすべてをローカルディスクに保存するようになりました。ディレクトリの場所は以前のバージョンと変わりましたが、まだ100%標準化されているわけではありません。下記をご覧ください:

説明DBで?相対パス(CarrierWave.rootから)アップローダクラスモデルタイプ
インスタンスロゴyesuploads/-/system/appearance/logo/:id/:filenameAttachmentUploader外観
ヘッダーロゴyesuploads/-/system/appearance/header_logo/:id/:filenameAttachmentUploader外観
グループアバターyesuploads/-/system/group/avatar/:id/:filenameAvatarUploaderグループ
ユーザーアバターyesuploads/-/system/user/avatar/:id/:filenameAvatarUploaderユーザー
ユーザースニペット添付ファイルyesuploads/-/system/personal_snippet/:id/:random_hex/:filenamePersonalFileUploaderスニペット
プロジェクトアバターyesuploads/-/system/project/avatar/:id/:filenameAvatarUploaderプロジェクト
トピックアバターyesuploads/-/system/projects/topic/avatar/:id/:filenameAvatarUploaderトピック
イシュー/MR/ノート Markdown添付ファイルyesuploads/:project_path_with_namespace/:random_hex/:filenameFileUploaderプロジェクト
イシュー/MR/ノート レガシー Markdown添付ファイルいいえuploads/-/system/note/attachment/:id/:filenameAttachmentUploaderノート
デザイン管理デザインのサムネイルyesuploads/-/system/design_management/action/image_v432x230/:id/:filenameDesignManagement::DesignV432x230Uploaderデザインマネジメント::アクション
CIアーティファクト(CE)yes shared/artifacts/:disk_hash[0..1]/:disk_hash[2..3]/:disk_hash/:year_:month_:date/:job_id/:job_artifact_id (:disk_hashproject_id の SHA256 ダイジェスト )JobArtifactUploaderCi::JobArtifact
LFS オブジェクト(CE)yesshared/lfs-objects/:hex/:hex/:object_hashLfsObjectUploaderLfsObject
外部マージリクエスト差分yesshared/external-diffs/merge_request_diffs/mr-:parent_id/diff-:idExternalDiffUploaderマージ要求差分
発行可能なメトリクスイメージyesuploads/-/system/issuable_metric_image/file/:id/:filenameIssuableMetricImageUploader発行可能メトリック画像

CIアーティファクトとLFSオブジェクトは、CEとEEで動作が異なります。CEではGitlabUploader 、EEではObjectStorage を継承し、S3 API互換のオブジェクトストアにファイルを格納します。

イシュー/MR/ノートのMarkdown添付ファイルの場合、ハッシュストレージレイアウトを使用する異なるアプローチがあります。プロジェクトが新しいアプローチ(10.2で導入)にマイグレーションする場合、パスを変更可能な変数:project_path_with_namespace 、代わりにプロジェクトIDのハッシュを使用することができます。

すべてのアップロードを一度にオブジェクトストレージにマイグレーションするオールインワンのRakeタスクを提供します。新しいUploaderクラスまたはモデルタイプが導入された場合、それに対応する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 によって格納されたすべてのファイルに対してUpload エントリを作成し、GitlabUploader#dynamic_path を使用してパスの動的部分を永続化します。その後、Upload#build_uploader メソッドを使用してファイルを操作できます。

オブジェクトストレージ

GitlabUploader 派生クラスにObjectStorage::Concern を含めることで、このアップローダのオブジェクトストレージを有効にすることができます。アップローダでオブジェクトストレージを有効にするには、1)RecordsUpload::Concern をインクルードしてObjectStorage::Extension::RecordsUploads をプリペンドするか、2) アップローダをマウントして<mount>_store という名前の新しいフィールドを作成する必要があります。

CarrierWave::Uploader#store_dir

  • GitlabUploader.base_dir +GitlabUploader.dynamic_segment に上書きされます。
  • GitlabUploader.dynamic_segment ストアが REMOTE の場合 (バケツ名が名前空間に使用されます)

テストの拡張ObjectStorage::Extension::RecordsUploads

RecordsUploads::Concern が含まれていない場合は、この懸念が含まれます。

ObjectStorage::Concern アップローダーは、Upload 正しいオブジェクトストアを選択するために Upload一致するものを検索します。各ストア (LOCAL/REMOTE) に対して#store_dirs + identifier UploadUpload使用してマッピングされます。

class SongUploader < GitlabUploader
  include RecordsUploads::Concern
  include ObjectStorage::Concern
  prepend ObjectStorage::Extension::RecordsUploads

  ...
end

class Thing < ActiveRecord::Base
  mount :theme, SongUploader # we have a great theme song!

  ...
end

マウントされたアップローダーの使用

ObjectStorage::Concernmodel.<mount>_store 属性をクエリして、正しいオブジェクトストアを選択します。このカラムはモデルスキーマに存在しなければなりません。

class SongUploader < GitlabUploader
  include ObjectStorage::Concern

  ...
end

class Thing < ActiveRecord::Base
  attr_reader :theme_store # this is an ActiveRecord attribute
  mount :theme, SongUploader # we have a great theme song!

  def theme_store
    super || ObjectStorage::Store::LOCAL
  end

  ...
end