diff options
author | Robert Speicher <robert@gitlab.com> | 2016-08-30 23:01:26 +0000 |
---|---|---|
committer | Robert Speicher <robert@gitlab.com> | 2016-08-30 23:01:26 +0000 |
commit | 88295e07426698ce2af32af73ac0c34e540a0ba0 (patch) | |
tree | 4f2a54fd0bd29130b92500b9d33c5c1f6b3c28c6 | |
parent | 1e08429d2c9aa72918a0a3328d070f0768478463 (diff) | |
parent | cf37d623e197dae5cc7efb021c1b1d85ca9674ee (diff) | |
download | gitlab-ce-88295e07426698ce2af32af73ac0c34e540a0ba0.tar.gz |
Merge branch 'project-specific-lfs' into 'master'
Added project specific enable/disable setting for LFS
## What does this MR do?
Adds project specific enable/disable setting for LFS
## What are the relevant issue numbers?
Needed for #18092
See merge request !5997
-rw-r--r-- | CHANGELOG | 1 | ||||
-rw-r--r-- | app/assets/stylesheets/pages/projects.scss | 8 | ||||
-rw-r--r-- | app/controllers/projects_controller.rb | 2 | ||||
-rw-r--r-- | app/helpers/lfs_helper.rb | 4 | ||||
-rw-r--r-- | app/helpers/projects_helper.rb | 12 | ||||
-rw-r--r-- | app/models/project.rb | 7 | ||||
-rw-r--r-- | app/views/admin/projects/show.html.haml | 6 | ||||
-rw-r--r-- | app/views/projects/edit.html.haml | 10 | ||||
-rw-r--r-- | db/migrate/20160823213309_add_lfs_enabled_to_projects.rb | 29 | ||||
-rw-r--r-- | db/schema.rb | 1 | ||||
-rw-r--r-- | doc/api/projects.md | 3 | ||||
-rw-r--r-- | doc/workflow/project_features.md | 10 | ||||
-rw-r--r-- | lib/api/entities.rb | 2 | ||||
-rw-r--r-- | lib/api/projects.rb | 12 | ||||
-rw-r--r-- | spec/requests/lfs_http_spec.rb | 107 |
15 files changed, 208 insertions, 6 deletions
diff --git a/CHANGELOG b/CHANGELOG index c07e194358d..c8d224bb0b9 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -25,6 +25,7 @@ v 8.12.0 (unreleased) - Add horizontal scrolling to all sub-navs on mobile viewports (ClemMakesApps) - Fix markdown help references (ClemMakesApps) - Add last commit time to repo view (ClemMakesApps) + - Added project specific enable/disable setting for LFS !5997 - Added tests for diff notes - Add a button to download latest successful artifacts for branches and tags !5142 - Add delimiter to project stars and forks count (ClemMakesApps) diff --git a/app/assets/stylesheets/pages/projects.scss b/app/assets/stylesheets/pages/projects.scss index 83500a687bb..f2db373da52 100644 --- a/app/assets/stylesheets/pages/projects.scss +++ b/app/assets/stylesheets/pages/projects.scss @@ -311,6 +311,14 @@ a.deploy-project-label { color: $gl-success; } +.lfs-enabled { + color: $gl-success; +} + +.lfs-disabled { + color: $gl-warning; +} + .breadcrumb.repo-breadcrumb { padding: 0; background: transparent; diff --git a/app/controllers/projects_controller.rb b/app/controllers/projects_controller.rb index fc52cd2f367..84d6b106cd7 100644 --- a/app/controllers/projects_controller.rb +++ b/app/controllers/projects_controller.rb @@ -309,7 +309,7 @@ class ProjectsController < Projects::ApplicationController :issues_tracker_id, :default_branch, :wiki_enabled, :visibility_level, :import_url, :last_activity_at, :namespace_id, :avatar, :builds_enabled, :build_allow_git_fetch, :build_timeout_in_minutes, :build_coverage_regex, - :public_builds, :only_allow_merge_if_build_succeeds, :request_access_enabled + :public_builds, :only_allow_merge_if_build_succeeds, :request_access_enabled, :lfs_enabled ) end diff --git a/app/helpers/lfs_helper.rb b/app/helpers/lfs_helper.rb index eb651e3687e..5d82abfca79 100644 --- a/app/helpers/lfs_helper.rb +++ b/app/helpers/lfs_helper.rb @@ -23,10 +23,14 @@ module LfsHelper end def lfs_download_access? + return false unless project.lfs_enabled? + project.public? || ci? || (user && user.can?(:download_code, project)) end def lfs_upload_access? + return false unless project.lfs_enabled? + user && user.can?(:push_code, project) end diff --git a/app/helpers/projects_helper.rb b/app/helpers/projects_helper.rb index 356f27f2d5d..f07077bd133 100644 --- a/app/helpers/projects_helper.rb +++ b/app/helpers/projects_helper.rb @@ -187,6 +187,18 @@ module ProjectsHelper nav_tabs.flatten end + def project_lfs_status(project) + if project.lfs_enabled? + content_tag(:span, class: 'lfs-enabled') do + 'Enabled' + end + else + content_tag(:span, class: 'lfs-disabled') do + 'Disabled' + end + end + end + def git_user_name if current_user current_user.name diff --git a/app/models/project.rb b/app/models/project.rb index c34064f96ce..e5027af4a0e 100644 --- a/app/models/project.rb +++ b/app/models/project.rb @@ -390,6 +390,13 @@ class Project < ActiveRecord::Base end end + def lfs_enabled? + return false unless Gitlab.config.lfs.enabled + return Gitlab.config.lfs.enabled if self[:lfs_enabled].nil? + + self[:lfs_enabled] + end + def repository_storage_path Gitlab.config.repositories.storages[repository_storage] end diff --git a/app/views/admin/projects/show.html.haml b/app/views/admin/projects/show.html.haml index b2c607361b3..6c7c3c48604 100644 --- a/app/views/admin/projects/show.html.haml +++ b/app/views/admin/projects/show.html.haml @@ -73,6 +73,12 @@ %span.light last commit: %strong = last_commit(@project) + + %li + %span.light Git LFS status: + %strong + = project_lfs_status(@project) + = link_to icon('question-circle'), help_page_path('workflow/lfs/manage_large_binaries_with_git_lfs') - else %li %span.light repository: diff --git a/app/views/projects/edit.html.haml b/app/views/projects/edit.html.haml index b282aa52b25..836c6d7b83f 100644 --- a/app/views/projects/edit.html.haml +++ b/app/views/projects/edit.html.haml @@ -80,6 +80,16 @@ %strong Snippets %br %span.descr Share code pastes with others out of git repository + - if Gitlab.config.lfs.enabled && current_user.admin? + .form-group + .checkbox + = f.label :lfs_enabled do + = f.check_box :lfs_enabled, checked: @project.lfs_enabled? + %strong LFS + %br + %span.descr + Git Large File Storage + = link_to icon('question-circle'), help_page_path('workflow/lfs/manage_large_binaries_with_git_lfs') - if Gitlab.config.registry.enabled .form-group .checkbox diff --git a/db/migrate/20160823213309_add_lfs_enabled_to_projects.rb b/db/migrate/20160823213309_add_lfs_enabled_to_projects.rb new file mode 100644 index 00000000000..c169084e976 --- /dev/null +++ b/db/migrate/20160823213309_add_lfs_enabled_to_projects.rb @@ -0,0 +1,29 @@ +# See http://doc.gitlab.com/ce/development/migration_style_guide.html +# for more information on how to write migrations for GitLab. + +class AddLfsEnabledToProjects < ActiveRecord::Migration + include Gitlab::Database::MigrationHelpers + + # Set this constant to true if this migration requires downtime. + DOWNTIME = false + + # When a migration requires downtime you **must** uncomment the following + # constant and define a short and easy to understand explanation as to why the + # migration requires downtime. + # DOWNTIME_REASON = '' + + # When using the methods "add_concurrent_index" or "add_column_with_default" + # you must disable the use of transactions as these methods can not run in an + # existing transaction. When using "add_concurrent_index" make sure that this + # method is the _only_ method called in the migration, any other changes + # should go in a separate migration. This ensures that upon failure _only_ the + # index creation fails and can be retried or reverted easily. + # + # To disable transactions uncomment the following line and remove these + # comments: + # disable_ddl_transaction! + + def change + add_column :projects, :lfs_enabled, :boolean + end +end diff --git a/db/schema.rb b/db/schema.rb index 0cd8648da2e..e1ce7085c62 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -825,6 +825,7 @@ ActiveRecord::Schema.define(version: 20160827011312) do t.string "repository_storage", default: "default", null: false t.boolean "request_access_enabled", default: true, null: false t.boolean "has_external_wiki" + t.boolean "lfs_enabled" end add_index "projects", ["ci_id"], name: "index_projects_on_ci_id", using: :btree diff --git a/doc/api/projects.md b/doc/api/projects.md index 3136c493b48..0d5aa61aa74 100644 --- a/doc/api/projects.md +++ b/doc/api/projects.md @@ -452,6 +452,7 @@ Parameters: - `import_url` (optional) - `public_builds` (optional) - `only_allow_merge_if_build_succeeds` (optional) +- `lfs_enabled` (optional) ### Create project for user @@ -478,6 +479,7 @@ Parameters: - `import_url` (optional) - `public_builds` (optional) - `only_allow_merge_if_build_succeeds` (optional) +- `lfs_enabled` (optional) ### Edit project @@ -505,6 +507,7 @@ Parameters: - `visibility_level` (optional) - `public_builds` (optional) - `only_allow_merge_if_build_succeeds` (optional) +- `lfs_enabled` (optional) On success, method returns 200 with the updated project. If parameters are invalid, 400 is returned. diff --git a/doc/workflow/project_features.md b/doc/workflow/project_features.md index a523b3facbe..f19e7df8c9a 100644 --- a/doc/workflow/project_features.md +++ b/doc/workflow/project_features.md @@ -32,4 +32,12 @@ Snippets are little bits of code or text. This is a nice place to put code or text that is used semi-regularly within the project, but does not belong in source control. -For example, a specific config file that is used by > the team that is only valid for the people that work on the code. +For example, a specific config file that is used by the team that is only valid for the people that work on the code. + +## Git LFS + +>**Note:** Project-specific LFS setting was added on 8.12 and is available only to admins. + +Git Large File Storage allows you to easily manage large binary files with Git. +With this setting admins can better control which projects are allowed to use +LFS. diff --git a/lib/api/entities.rb b/lib/api/entities.rb index cbb324dd06d..4335e3055ef 100644 --- a/lib/api/entities.rb +++ b/lib/api/entities.rb @@ -78,7 +78,7 @@ module API expose :path, :path_with_namespace expose :issues_enabled, :merge_requests_enabled, :wiki_enabled, :builds_enabled, :snippets_enabled, :container_registry_enabled expose :created_at, :last_activity_at - expose :shared_runners_enabled + expose :shared_runners_enabled, :lfs_enabled expose :creator_id expose :namespace expose :forked_from_project, using: Entities::BasicProjectDetails, if: lambda{ |project, options| project.forked? } diff --git a/lib/api/projects.rb b/lib/api/projects.rb index 71efd4f33ca..f8979a1cc29 100644 --- a/lib/api/projects.rb +++ b/lib/api/projects.rb @@ -105,6 +105,7 @@ module API # visibility_level (optional) - 0 by default # import_url (optional) # public_builds (optional) + # lfs_enabled (optional) # Example Request # POST /projects post do @@ -124,7 +125,8 @@ module API :visibility_level, :import_url, :public_builds, - :only_allow_merge_if_build_succeeds] + :only_allow_merge_if_build_succeeds, + :lfs_enabled] attrs = map_public_to_visibility_level(attrs) @project = ::Projects::CreateService.new(current_user, attrs).execute if @project.saved? @@ -156,6 +158,7 @@ module API # visibility_level (optional) # import_url (optional) # public_builds (optional) + # lfs_enabled (optional) # Example Request # POST /projects/user/:user_id post "user/:user_id" do @@ -174,7 +177,8 @@ module API :visibility_level, :import_url, :public_builds, - :only_allow_merge_if_build_succeeds] + :only_allow_merge_if_build_succeeds, + :lfs_enabled] attrs = map_public_to_visibility_level(attrs) @project = ::Projects::CreateService.new(user, attrs).execute if @project.saved? @@ -220,6 +224,7 @@ module API # public (optional) - if true same as setting visibility_level = 20 # visibility_level (optional) - visibility level of a project # public_builds (optional) + # lfs_enabled (optional) # Example Request # PUT /projects/:id put ':id' do @@ -237,7 +242,8 @@ module API :public, :visibility_level, :public_builds, - :only_allow_merge_if_build_succeeds] + :only_allow_merge_if_build_succeeds, + :lfs_enabled] attrs = map_public_to_visibility_level(attrs) authorize_admin_project authorize! :rename_project, user_project if attrs[:name].present? diff --git a/spec/requests/lfs_http_spec.rb b/spec/requests/lfs_http_spec.rb index 4c9b4a8ba42..fcd6521317a 100644 --- a/spec/requests/lfs_http_spec.rb +++ b/spec/requests/lfs_http_spec.rb @@ -44,6 +44,113 @@ describe 'Git LFS API and storage' do end end + context 'project specific LFS settings' do + let(:project) { create(:empty_project) } + let(:body) do + { + 'objects' => [ + { 'oid' => '91eff75a492a3ed0dfcb544d7f31326bc4014c8551849c192fd1e48d4dd2c897', + 'size' => 1575078 + }, + { 'oid' => sample_oid, + 'size' => sample_size + } + ], + 'operation' => 'upload' + } + end + let(:authorization) { authorize_user } + + context 'with LFS disabled globally' do + before do + project.team << [user, :master] + allow(Gitlab.config.lfs).to receive(:enabled).and_return(false) + end + + describe 'LFS disabled in project' do + before do + project.update_attribute(:lfs_enabled, false) + end + + it 'responds with a 501 message on upload' do + post_lfs_json "#{project.http_url_to_repo}/info/lfs/objects/batch", body, headers + + expect(response).to have_http_status(501) + end + + it 'responds with a 501 message on download' do + get "#{project.http_url_to_repo}/gitlab-lfs/objects/#{sample_oid}", nil, headers + + expect(response).to have_http_status(501) + end + end + + describe 'LFS enabled in project' do + before do + project.update_attribute(:lfs_enabled, true) + end + + it 'responds with a 501 message on upload' do + post_lfs_json "#{project.http_url_to_repo}/info/lfs/objects/batch", body, headers + + expect(response).to have_http_status(501) + end + + it 'responds with a 501 message on download' do + get "#{project.http_url_to_repo}/gitlab-lfs/objects/#{sample_oid}", nil, headers + + expect(response).to have_http_status(501) + end + end + end + + context 'with LFS enabled globally' do + before do + project.team << [user, :master] + enable_lfs + end + + describe 'LFS disabled in project' do + before do + project.update_attribute(:lfs_enabled, false) + end + + it 'responds with a 403 message on upload' do + post_lfs_json "#{project.http_url_to_repo}/info/lfs/objects/batch", body, headers + + expect(response).to have_http_status(403) + expect(json_response).to include('message' => 'Access forbidden. Check your access level.') + end + + it 'responds with a 403 message on download' do + get "#{project.http_url_to_repo}/gitlab-lfs/objects/#{sample_oid}", nil, headers + + expect(response).to have_http_status(403) + expect(json_response).to include('message' => 'Access forbidden. Check your access level.') + end + end + + describe 'LFS enabled in project' do + before do + project.update_attribute(:lfs_enabled, true) + end + + it 'responds with a 200 message on upload' do + post_lfs_json "#{project.http_url_to_repo}/info/lfs/objects/batch", body, headers + + expect(response).to have_http_status(200) + expect(json_response['objects'].first['size']).to eq(1575078) + end + + it 'responds with a 200 message on download' do + get "#{project.http_url_to_repo}/gitlab-lfs/objects/#{sample_oid}", nil, headers + + expect(response).to have_http_status(200) + end + end + end + end + describe 'deprecated API' do let(:project) { create(:empty_project) } |