[Backported from EE] Readonly flag for Projects

This is used in EE for the storage migration, and we want to use this
in CE as well to be able to migrate projects to hashed_storage.
This commit is contained in:
Gabriel Mazetto 2017-09-06 04:24:31 +02:00 committed by Nick Thomas
parent e0e49f2f71
commit 38607b48b6
No known key found for this signature in database
GPG key ID: 2A313A47AFADACE9
5 changed files with 50 additions and 10 deletions

View file

@ -0,0 +1,9 @@
class AddRepositoryReadOnlyToProjects < ActiveRecord::Migration
include Gitlab::Database::MigrationHelpers
DOWNTIME = false
def change
add_column :projects, :repository_read_only, :boolean
end
end

View file

@ -1215,6 +1215,7 @@ ActiveRecord::Schema.define(version: 20170921115009) do
t.datetime "last_repository_updated_at" t.datetime "last_repository_updated_at"
t.integer "storage_version", limit: 2 t.integer "storage_version", limit: 2
t.boolean "resolve_outdated_diff_discussions" t.boolean "resolve_outdated_diff_discussions"
t.boolean "repository_read_only"
end end
add_index "projects", ["ci_id"], name: "index_projects_on_ci_id", using: :btree add_index "projects", ["ci_id"], name: "index_projects_on_ci_id", using: :btree

View file

@ -16,7 +16,8 @@ module Gitlab
account_blocked: 'Your account has been blocked.', account_blocked: 'Your account has been blocked.',
command_not_allowed: "The command you're trying to execute is not allowed.", command_not_allowed: "The command you're trying to execute is not allowed.",
upload_pack_disabled_over_http: 'Pulling over HTTP is not allowed.', upload_pack_disabled_over_http: 'Pulling over HTTP is not allowed.',
receive_pack_disabled_over_http: 'Pushing over HTTP is not allowed.' receive_pack_disabled_over_http: 'Pushing over HTTP is not allowed.',
readonly: 'The repository is temporarily read-only. Please try again later.'
}.freeze }.freeze
DOWNLOAD_COMMANDS = %w{ git-upload-pack git-upload-archive }.freeze DOWNLOAD_COMMANDS = %w{ git-upload-pack git-upload-archive }.freeze
@ -159,6 +160,10 @@ module Gitlab
end end
def check_push_access!(changes) def check_push_access!(changes)
if project.repository_read_only?
raise UnauthorizedError, ERROR_MESSAGES[:readonly]
end
if deploy_key if deploy_key
check_deploy_key_push_access! check_deploy_key_push_access!
elsif user elsif user

View file

@ -143,6 +143,10 @@ FactoryGirl.define do
end end
end end
trait :read_only_repository do
repository_read_only true
end
trait :broken_repo do trait :broken_repo do
after(:create) do |project| after(:create) do |project|
raise "Failed to create repository!" unless project.create_repository raise "Failed to create repository!" unless project.create_repository

View file

@ -48,14 +48,35 @@ describe Gitlab::Shell do
end end
end end
describe '#add_key' do describe 'projects commands' do
it 'removes trailing garbage' do let(:gitlab_shell_path) { File.expand_path('tmp/tests/gitlab-shell') }
allow(gitlab_shell).to receive(:gitlab_shell_keys_path).and_return(:gitlab_shell_keys_path) let(:projects_path) { File.join(gitlab_shell_path, 'bin/gitlab-projects') }
expect(gitlab_shell).to receive(:gitlab_shell_fast_execute).with( let(:gitlab_shell_hooks_path) { File.join(gitlab_shell_path, 'hooks') }
[:gitlab_shell_keys_path, 'add-key', 'key-123', 'ssh-rsa foobar']
)
gitlab_shell.add_key('key-123', 'ssh-rsa foobar trailing garbage') before do
allow(Gitlab.config.gitlab_shell).to receive(:path).and_return(gitlab_shell_path)
allow(Gitlab.config.gitlab_shell).to receive(:hooks_path).and_return(gitlab_shell_hooks_path)
allow(Gitlab.config.gitlab_shell).to receive(:git_timeout).and_return(800)
end
describe '#mv_repository' do
it 'executes the command' do
expect(gitlab_shell).to receive(:gitlab_shell_fast_execute).with(
[projects_path, 'mv-project', 'storage/path', 'project/path.git', 'new/path.git']
)
gitlab_shell.mv_repository('storage/path', 'project/path', 'new/path')
end
end
describe '#add_key' do
it 'removes trailing garbage' do
allow(gitlab_shell).to receive(:gitlab_shell_keys_path).and_return(:gitlab_shell_keys_path)
expect(gitlab_shell).to receive(:gitlab_shell_fast_execute).with(
[:gitlab_shell_keys_path, 'add-key', 'key-123', 'ssh-rsa foobar']
)
gitlab_shell.add_key('key-123', 'ssh-rsa foobar trailing garbage')
end
end end
end end
@ -136,7 +157,7 @@ describe Gitlab::Shell do
it 'returns true when the command succeeds' do it 'returns true when the command succeeds' do
expect(Gitlab::Popen).to receive(:popen) expect(Gitlab::Popen).to receive(:popen)
.with([projects_path, 'rm-project', 'current/storage', 'project/path.git'], .with([projects_path, 'rm-project', 'current/storage', 'project/path.git'],
nil, popen_vars).and_return([nil, 0]) nil, popen_vars).and_return([nil, 0])
expect(gitlab_shell.remove_repository('current/storage', 'project/path')).to be true expect(gitlab_shell.remove_repository('current/storage', 'project/path')).to be true
end end
@ -144,7 +165,7 @@ describe Gitlab::Shell do
it 'returns false when the command fails' do it 'returns false when the command fails' do
expect(Gitlab::Popen).to receive(:popen) expect(Gitlab::Popen).to receive(:popen)
.with([projects_path, 'rm-project', 'current/storage', 'project/path.git'], .with([projects_path, 'rm-project', 'current/storage', 'project/path.git'],
nil, popen_vars).and_return(["error", 1]) nil, popen_vars).and_return(["error", 1])
expect(gitlab_shell.remove_repository('current/storage', 'project/path')).to be false expect(gitlab_shell.remove_repository('current/storage', 'project/path')).to be false
end end