Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
G
gitlab-ce
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
1
Merge Requests
1
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
nexedi
gitlab-ce
Commits
9163bc53
Commit
9163bc53
authored
Feb 05, 2018
by
Sean McGivern
Browse files
Options
Browse Files
Download
Plain Diff
Merge branch 'ee-42547-upload-store-mount-point' into 'master'
Port 42547 to EE See merge request gitlab-org/gitlab-ee!4363
parents
db735398
ecc8326b
Changes
17
Hide whitespace changes
Inline
Side-by-side
Showing
17 changed files
with
123 additions
and
80 deletions
+123
-80
app/controllers/concerns/uploads_actions.rb
app/controllers/concerns/uploads_actions.rb
+1
-1
app/models/upload.rb
app/models/upload.rb
+14
-3
app/uploaders/file_mover.rb
app/uploaders/file_mover.rb
+2
-2
app/uploaders/file_uploader.rb
app/uploaders/file_uploader.rb
+22
-6
app/uploaders/gitlab_uploader.rb
app/uploaders/gitlab_uploader.rb
+4
-0
app/uploaders/records_uploads.rb
app/uploaders/records_uploads.rb
+7
-6
changelogs/unreleased/42547-upload-store-mount-point.yml
changelogs/unreleased/42547-upload-store-mount-point.yml
+5
-0
db/migrate/20180129193323_add_uploads_builder_context.rb
db/migrate/20180129193323_add_uploads_builder_context.rb
+14
-0
db/schema.rb
db/schema.rb
+2
-0
ee/app/uploaders/object_storage.rb
ee/app/uploaders/object_storage.rb
+4
-2
lib/gitlab/gfm/uploads_rewriter.rb
lib/gitlab/gfm/uploads_rewriter.rb
+1
-1
spec/factories/uploads.rb
spec/factories/uploads.rb
+11
-7
spec/lib/file_size_validator_spec.rb
spec/lib/file_size_validator_spec.rb
+1
-1
spec/models/upload_spec.rb
spec/models/upload_spec.rb
+6
-0
spec/support/shared_examples/uploaders/object_storage_shared_examples.rb
...ared_examples/uploaders/object_storage_shared_examples.rb
+0
-49
spec/uploaders/file_uploader_spec.rb
spec/uploaders/file_uploader_spec.rb
+28
-1
spec/uploaders/gitlab_uploader_spec.rb
spec/uploaders/gitlab_uploader_spec.rb
+1
-1
No files found.
app/controllers/concerns/uploads_actions.rb
View file @
9163bc53
...
...
@@ -70,7 +70,7 @@ module UploadsActions
end
def
build_uploader_from_params
uploader
=
uploader_class
.
new
(
model
,
params
[
:secret
])
uploader
=
uploader_class
.
new
(
model
,
secret:
params
[
:secret
])
uploader
.
retrieve_from_store!
(
params
[
:filename
])
uploader
end
...
...
app/models/upload.rb
View file @
9163bc53
...
...
@@ -33,7 +33,7 @@ class Upload < ActiveRecord::Base
end
def
build_uploader
uploader_class
.
new
(
model
).
tap
do
|
uploader
|
uploader_class
.
new
(
model
,
mount_point
,
**
uploader_context
).
tap
do
|
uploader
|
uploader
.
upload
=
self
uploader
.
retrieve_from_store!
(
identifier
)
end
...
...
@@ -43,6 +43,13 @@ class Upload < ActiveRecord::Base
File
.
exist?
(
absolute_path
)
end
def
uploader_context
{
identifier:
identifier
,
secret:
secret
}.
compact
end
private
def
checksummable?
...
...
@@ -67,11 +74,15 @@ class Upload < ActiveRecord::Base
!
path
.
start_with?
(
'/'
)
end
def
uploader_class
Object
.
const_get
(
uploader
)
end
def
identifier
File
.
basename
(
path
)
end
def
uploader_class
Object
.
const_get
(
uploader
)
def
mount_point
super
&
.
to_sym
end
end
app/uploaders/file_mover.rb
View file @
9163bc53
...
...
@@ -46,11 +46,11 @@ class FileMover
end
def
uploader
@uploader
||=
PersonalFileUploader
.
new
(
model
,
secret
)
@uploader
||=
PersonalFileUploader
.
new
(
model
,
secret
:
secret
)
end
def
temp_file_uploader
@temp_file_uploader
||=
PersonalFileUploader
.
new
(
nil
,
secret
)
@temp_file_uploader
||=
PersonalFileUploader
.
new
(
nil
,
secret
:
secret
)
end
def
revert
...
...
app/uploaders/file_uploader.rb
View file @
9163bc53
...
...
@@ -62,9 +62,11 @@ class FileUploader < GitlabUploader
attr_accessor
:model
def
initialize
(
model
,
secret
=
nil
)
def
initialize
(
model
,
mounted_as
=
nil
,
**
uploader_context
)
super
(
model
,
nil
,
**
uploader_context
)
@model
=
model
@secret
=
secret
apply_context!
(
uploader_context
)
end
def
base_dir
...
...
@@ -107,15 +109,17 @@ class FileUploader < GitlabUploader
self
.
file
.
filename
end
# the upload does not hold the secret, but holds the path
# which contains the secret: extract it
def
upload
=
(
value
)
super
return
unless
value
return
if
apply_context!
(
value
.
uploader_context
)
# fallback to the regex based extraction
if
matches
=
DYNAMIC_PATH_PATTERN
.
match
(
value
.
path
)
@secret
=
matches
[
:secret
]
@identifier
=
matches
[
:identifier
]
end
super
end
def
secret
...
...
@@ -124,6 +128,18 @@ class FileUploader < GitlabUploader
private
def
apply_context!
(
uploader_context
)
@secret
,
@identifier
=
uploader_context
.
values_at
(
:secret
,
:identifier
)
!!
(
@secret
&&
@identifier
)
end
def
build_upload
super
.
tap
do
|
upload
|
upload
.
secret
=
secret
end
end
def
markdown_name
(
image_or_video?
?
File
.
basename
(
filename
,
File
.
extname
(
filename
))
:
filename
).
gsub
(
"]"
,
"
\\
]"
)
end
...
...
app/uploaders/gitlab_uploader.rb
View file @
9163bc53
...
...
@@ -29,6 +29,10 @@ class GitlabUploader < CarrierWave::Uploader::Base
delegate
:base_dir
,
:file_storage?
,
to: :class
def
initialize
(
model
,
mounted_as
=
nil
,
**
uploader_context
)
super
(
model
,
mounted_as
)
end
def
file_cache_storage?
cache_storage
.
is_a?
(
CarrierWave
::
Storage
::
File
)
end
...
...
app/uploaders/records_uploads.rb
View file @
9163bc53
...
...
@@ -24,7 +24,7 @@ module RecordsUploads
uploads
.
where
(
path:
upload_path
).
delete_all
upload
.
destroy!
if
upload
self
.
upload
=
build_upload
_from_uploader
(
self
)
self
.
upload
=
build_upload
upload
.
save!
end
end
...
...
@@ -39,12 +39,13 @@ module RecordsUploads
Upload
.
order
(
id: :desc
).
where
(
uploader:
self
.
class
.
to_s
)
end
def
build_upload
_from_uploader
(
uploader
)
def
build_upload
Upload
.
new
(
size:
uploader
.
file
.
size
,
path:
uploader
.
upload_path
,
model:
uploader
.
model
,
uploader:
uploader
.
class
.
to_s
uploader:
self
.
class
.
to_s
,
size:
file
.
size
,
path:
upload_path
,
model:
model
,
mount_point:
mounted_as
)
end
...
...
changelogs/unreleased/42547-upload-store-mount-point.yml
0 → 100644
View file @
9163bc53
---
title
:
Added uploader metadata to the uploads.
merge_request
:
16779
author
:
type
:
added
db/migrate/20180129193323_add_uploads_builder_context.rb
0 → 100644
View file @
9163bc53
# See http://doc.gitlab.com/ce/development/migration_style_guide.html
# for more information on how to write migrations for GitLab.
class
AddUploadsBuilderContext
<
ActiveRecord
::
Migration
include
Gitlab
::
Database
::
MigrationHelpers
# Set this constant to true if this migration requires downtime.
DOWNTIME
=
false
def
change
add_column
:uploads
,
:mount_point
,
:string
add_column
:uploads
,
:secret
,
:string
end
end
db/schema.rb
View file @
9163bc53
...
...
@@ -2255,6 +2255,8 @@ ActiveRecord::Schema.define(version: 20180202111106) do
t
.
string
"uploader"
,
null:
false
t
.
datetime
"created_at"
,
null:
false
t
.
integer
"store"
t
.
string
"mount_point"
t
.
string
"secret"
end
add_index
"uploads"
,
[
"checksum"
],
name:
"index_uploads_on_checksum"
,
using: :btree
...
...
ee/app/uploaders/object_storage.rb
View file @
9163bc53
...
...
@@ -37,8 +37,10 @@ module ObjectStorage
super
end
def
build_upload_from_uploader
(
uploader
)
super
.
tap
{
|
upload
|
upload
.
store
=
object_store
}
def
build_upload
super
.
tap
do
|
upload
|
upload
.
store
=
object_store
end
end
def
upload
=
(
upload
)
...
...
lib/gitlab/gfm/uploads_rewriter.rb
View file @
9163bc53
...
...
@@ -46,7 +46,7 @@ module Gitlab
private
def
find_file
(
project
,
secret
,
file
)
uploader
=
FileUploader
.
new
(
project
,
secret
)
uploader
=
FileUploader
.
new
(
project
,
secret
:
secret
)
uploader
.
retrieve_from_store!
(
file
)
uploader
.
file
end
...
...
spec/factories/uploads.rb
View file @
9163bc53
...
...
@@ -3,26 +3,29 @@ FactoryBot.define do
model
{
build
(
:project
)
}
size
100
.
kilobytes
uploader
"AvatarUploader"
mount_point
:avatar
secret
nil
store
ObjectStorage
::
Store
::
LOCAL
# we should build a mount agnostic upload by default
transient
do
mounted_as
:avatar
secret
SecureRandom
.
hex
filename
'myfile.jpg'
end
# this needs to comply with RecordsUpload::Concern#upload_path
path
{
File
.
join
(
"uploads/-/system"
,
model
.
class
.
to_s
.
underscore
,
mount
ed_as
.
to_s
,
'avatar.jpg'
)
}
path
{
File
.
join
(
"uploads/-/system"
,
model
.
class
.
to_s
.
underscore
,
mount
_point
.
to_s
,
'avatar.jpg'
)
}
trait
:personal_snippet_upload
do
model
{
build
(
:personal_snippet
)
}
path
{
File
.
join
(
secret
,
'myfile.jpg'
)
}
path
{
File
.
join
(
secret
,
filename
)
}
uploader
"PersonalFileUploader"
secret
SecureRandom
.
hex
end
trait
:issuable_upload
do
path
{
File
.
join
(
secret
,
'myfile.jpg'
)
}
path
{
File
.
join
(
secret
,
filename
)
}
uploader
"FileUploader"
secret
SecureRandom
.
hex
end
trait
:object_storage
do
...
...
@@ -31,13 +34,14 @@ FactoryBot.define do
trait
:namespace_upload
do
model
{
build
(
:group
)
}
path
{
File
.
join
(
secret
,
'myfile.jpg'
)
}
path
{
File
.
join
(
secret
,
filename
)
}
uploader
"NamespaceFileUploader"
secret
SecureRandom
.
hex
end
trait
:attachment_upload
do
transient
do
mount
ed_as
:attachment
mount
_point
:attachment
end
model
{
build
(
:note
)
}
...
...
spec/lib/file_size_validator_spec.rb
View file @
9163bc53
...
...
@@ -2,8 +2,8 @@ require 'spec_helper'
describe
FileSizeValidator
do
let
(
:validator
)
{
described_class
.
new
(
options
)
}
let
(
:attachment
)
{
AttachmentUploader
.
new
}
let
(
:note
)
{
create
(
:note
)
}
let
(
:attachment
)
{
AttachmentUploader
.
new
(
note
)
}
describe
'options uses an integer'
do
let
(
:options
)
{
{
maximum:
10
,
attributes:
{
attachment:
attachment
}
}
}
...
...
spec/models/upload_spec.rb
View file @
9163bc53
...
...
@@ -103,4 +103,10 @@ describe Upload do
expect
(
upload
).
not_to
exist
end
end
describe
"#uploader_context"
do
subject
{
create
(
:upload
,
:issuable_upload
,
secret:
'secret'
,
filename:
'file.txt'
)
}
it
{
expect
(
subject
.
uploader_context
).
to
match
(
a_hash_including
(
secret:
'secret'
,
identifier:
'file.txt'
))
}
end
end
spec/support/shared_examples/uploaders/object_storage_shared_examples.rb
View file @
9163bc53
...
...
@@ -75,52 +75,3 @@ shared_examples "migrates" do |to_store:, from_store: nil|
end
end
end
shared_examples
"matches the method pattern"
do
|
method
|
let
(
:target
)
{
subject
}
let
(
:args
)
{
nil
}
let
(
:pattern
)
{
patterns
[
method
]
}
it
do
return
skip
"No pattern provided, skipping."
unless
pattern
expect
(
target
.
method
(
method
).
call
(
*
args
)).
to
match
(
pattern
)
end
end
shared_examples
"builds correct paths"
do
|**
patterns
|
let
(
:patterns
)
{
patterns
}
before
do
allow
(
subject
).
to
receive
(
:filename
).
and_return
(
'<filename>'
)
end
describe
"#store_dir"
do
it_behaves_like
"matches the method pattern"
,
:store_dir
end
describe
"#cache_dir"
do
it_behaves_like
"matches the method pattern"
,
:cache_dir
end
describe
"#work_dir"
do
it_behaves_like
"matches the method pattern"
,
:work_dir
end
describe
"#upload_path"
do
it_behaves_like
"matches the method pattern"
,
:upload_path
end
describe
".absolute_path"
do
it_behaves_like
"matches the method pattern"
,
:absolute_path
do
let
(
:target
)
{
subject
.
class
}
let
(
:args
)
{
[
upload
]
}
end
end
describe
".base_dir"
do
it_behaves_like
"matches the method pattern"
,
:base_dir
do
let
(
:target
)
{
subject
.
class
}
end
end
end
spec/uploaders/file_uploader_spec.rb
View file @
9163bc53
...
...
@@ -51,7 +51,7 @@ describe FileUploader do
end
describe
'initialize'
do
let
(
:uploader
)
{
described_class
.
new
(
double
,
'secret'
)
}
let
(
:uploader
)
{
described_class
.
new
(
double
,
secret:
'secret'
)
}
it
'accepts a secret parameter'
do
expect
(
described_class
).
not_to
receive
(
:generate_secret
)
...
...
@@ -75,4 +75,31 @@ describe FileUploader do
it_behaves_like
"migrates"
,
to_store:
described_class
::
Store
::
REMOTE
it_behaves_like
"migrates"
,
from_store:
described_class
::
Store
::
REMOTE
,
to_store:
described_class
::
Store
::
LOCAL
end
describe
'#upload='
do
let
(
:secret
)
{
SecureRandom
.
hex
}
let
(
:upload
)
{
create
(
:upload
,
:issuable_upload
,
secret:
secret
,
filename:
'file.txt'
)
}
it
'handles nil'
do
expect
(
uploader
).
not_to
receive
(
:apply_context!
)
uploader
.
upload
=
nil
end
it
'extract the uploader context from it'
do
expect
(
uploader
).
to
receive
(
:apply_context!
).
with
(
a_hash_including
(
secret:
secret
,
identifier:
'file.txt'
))
uploader
.
upload
=
upload
end
context
'uploader_context is empty'
do
it
'fallbacks to regex based extraction'
do
expect
(
upload
).
to
receive
(
:uploader_context
).
and_return
({})
uploader
.
upload
=
upload
expect
(
uploader
.
secret
).
to
eq
(
secret
)
expect
(
uploader
.
instance_variable_get
(
:@identifier
)).
to
eq
(
'file.txt'
)
end
end
end
end
spec/uploaders/gitlab_uploader_spec.rb
View file @
9163bc53
...
...
@@ -4,7 +4,7 @@ require 'carrierwave/storage/fog'
describe
GitlabUploader
do
let
(
:uploader_class
)
{
Class
.
new
(
described_class
)
}
subject
{
uploader_class
.
new
}
subject
{
uploader_class
.
new
(
double
)
}
describe
'#file_storage?'
do
context
'when file storage is used'
do
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment