Commit 380cc283 authored by Rémy Coutable's avatar Rémy Coutable

Merge branch 'ce-to-ee-2018-04-04' into 'master'

CE upstream - 2018-04-04 09:39 UTC

Closes gitaly#1110

See merge request gitlab-org/gitlab-ee!5221
parents 8ba33b5d 5b94a7da
...@@ -97,7 +97,7 @@ GEM ...@@ -97,7 +97,7 @@ GEM
autoprefixer-rails (>= 5.2.1) autoprefixer-rails (>= 5.2.1)
sass (>= 3.3.4) sass (>= 3.3.4)
bootstrap_form (2.7.0) bootstrap_form (2.7.0)
brakeman (3.6.2) brakeman (4.2.1)
browser (2.5.3) browser (2.5.3)
builder (3.2.3) builder (3.2.3)
bullet (5.5.1) bullet (5.5.1)
...@@ -400,7 +400,7 @@ GEM ...@@ -400,7 +400,7 @@ GEM
hipchat (1.5.4) hipchat (1.5.4)
httparty httparty
mimemagic mimemagic
html-pipeline (2.6.0) html-pipeline (2.7.1)
activesupport (>= 2) activesupport (>= 2)
nokogiri (>= 1.4) nokogiri (>= 1.4)
html2text (0.2.1) html2text (0.2.1)
...@@ -1013,7 +1013,7 @@ DEPENDENCIES ...@@ -1013,7 +1013,7 @@ DEPENDENCIES
binding_of_caller (~> 0.7.2) binding_of_caller (~> 0.7.2)
bootstrap-sass (~> 3.3.0) bootstrap-sass (~> 3.3.0)
bootstrap_form (~> 2.7.0) bootstrap_form (~> 2.7.0)
brakeman (~> 3.6.0) brakeman (~> 4.2)
browser (~> 2.2) browser (~> 2.2)
bullet (~> 5.5.0) bullet (~> 5.5.0)
bundler-audit (~> 0.5.0) bundler-audit (~> 0.5.0)
...@@ -1084,7 +1084,7 @@ DEPENDENCIES ...@@ -1084,7 +1084,7 @@ DEPENDENCIES
hashie-forbidden_attributes hashie-forbidden_attributes
health_check (~> 2.6.0) health_check (~> 2.6.0)
hipchat (~> 1.5.0) hipchat (~> 1.5.0)
html-pipeline (~> 2.6.0) html-pipeline (~> 2.7.1)
html2text html2text
httparty (~> 0.13.3) httparty (~> 0.13.3)
influxdb (~> 0.2) influxdb (~> 0.2)
......
...@@ -733,8 +733,8 @@ a.linked-pipeline-mini-item { ...@@ -733,8 +733,8 @@ a.linked-pipeline-mini-item {
// dropdown content for big and mini pipeline // dropdown content for big and mini pipeline
.big-pipeline-graph-dropdown-menu, .big-pipeline-graph-dropdown-menu,
.mini-pipeline-graph-dropdown-menu { .mini-pipeline-graph-dropdown-menu {
width: 195px; width: 240px;
max-width: 195px; max-width: 240px;
.scrollable-menu { .scrollable-menu {
padding: 0; padding: 0;
...@@ -777,7 +777,7 @@ a.linked-pipeline-mini-item { ...@@ -777,7 +777,7 @@ a.linked-pipeline-mini-item {
height: #{$ci-action-icon-size - 6}; height: #{$ci-action-icon-size - 6};
left: -3px; left: -3px;
position: relative; position: relative;
top: -2px; top: -1px;
&.icon-action-stop, &.icon-action-stop,
&.icon-action-cancel { &.icon-action-cancel {
...@@ -958,13 +958,11 @@ a.linked-pipeline-mini-item { ...@@ -958,13 +958,11 @@ a.linked-pipeline-mini-item {
*/ */
&.dropdown-menu { &.dropdown-menu {
transform: translate(-80%, 0); transform: translate(-80%, 0);
min-width: 150px;
@media(min-width: $screen-md-min) { @media(min-width: $screen-md-min) {
transform: translate(-50%, 0); transform: translate(-50%, 0);
right: auto; right: auto;
left: 50%; left: 50%;
min-width: 240px;
} }
} }
} }
......
...@@ -51,7 +51,7 @@ class ProfilesController < Profiles::ApplicationController ...@@ -51,7 +51,7 @@ class ProfilesController < Profiles::ApplicationController
end end
def update_username def update_username
result = Users::UpdateService.new(current_user, user: @user, username: user_params[:username]).execute result = Users::UpdateService.new(current_user, user: @user, username: username_param).execute
options = if result[:status] == :success options = if result[:status] == :success
{ notice: "Username successfully changed" } { notice: "Username successfully changed" }
...@@ -72,6 +72,10 @@ class ProfilesController < Profiles::ApplicationController ...@@ -72,6 +72,10 @@ class ProfilesController < Profiles::ApplicationController
return render_404 unless @user.can_change_username? return render_404 unless @user.can_change_username?
end end
def username_param
@username_param ||= user_params.require(:username)
end
def user_params def user_params
@user_params ||= params.require(:user).permit( @user_params ||= params.require(:user).permit(
:avatar, :avatar,
......
...@@ -340,6 +340,18 @@ class IssuableFinder ...@@ -340,6 +340,18 @@ class IssuableFinder
params[:sort] ? items.sort_by_attribute(params[:sort], excluded_labels: label_names) : items.reorder(id: :desc) params[:sort] ? items.sort_by_attribute(params[:sort], excluded_labels: label_names) : items.reorder(id: :desc)
end end
def by_assignee(items)
if assignee
items = items.where(assignee_id: assignee.id)
elsif no_assignee?
items = items.where(assignee_id: nil)
elsif assignee_id? || assignee_username? # assignee not found
items = items.none
end
items
end
def by_author(items) def by_author(items)
if author if author
items = items.where(author_id: author.id) items = items.where(author_id: author.id)
......
...@@ -577,9 +577,7 @@ class Project < ActiveRecord::Base ...@@ -577,9 +577,7 @@ class Project < ActiveRecord::Base
def add_import_job def add_import_job
job_id = job_id =
if forked? if forked?
RepositoryForkWorker.perform_async(id, RepositoryForkWorker.perform_async(id)
forked_from_project.repository_storage_path,
forked_from_project.disk_path)
elsif gitlab_project_import? elsif gitlab_project_import?
# Do not retry on Import/Export until https://gitlab.com/gitlab-org/gitlab-ce/issues/26189 is solved. # Do not retry on Import/Export until https://gitlab.com/gitlab-org/gitlab-ce/issues/26189 is solved.
RepositoryImportWorker.set(retry: false).perform_async(self.id) RepositoryImportWorker.set(retry: false).perform_async(self.id)
......
...@@ -61,7 +61,7 @@ module Projects ...@@ -61,7 +61,7 @@ module Projects
project.ensure_repository project.ensure_repository
project.repository.fetch_as_mirror(project.import_url, refmap: refmap) project.repository.fetch_as_mirror(project.import_url, refmap: refmap)
else else
gitlab_shell.import_repository(project.repository_storage_path, project.disk_path, project.import_url) gitlab_shell.import_repository(project.repository_storage, project.disk_path, project.import_url)
end end
rescue Gitlab::Shell::Error, Gitlab::Git::RepositoryMirroring::RemoteError => e rescue Gitlab::Shell::Error, Gitlab::Git::RepositoryMirroring::RemoteError => e
# Expire cache to prevent scenarios such as: # Expire cache to prevent scenarios such as:
......
# Gitaly issue: https://gitlab.com/gitlab-org/gitaly/issues/1110
class RepositoryForkWorker class RepositoryForkWorker
include ApplicationWorker include ApplicationWorker
include Gitlab::ShellAdapter include Gitlab::ShellAdapter
include ProjectStartImport include ProjectStartImport
include ProjectImportOptions include ProjectImportOptions
def perform(project_id, forked_from_repository_storage_path, source_disk_path) def perform(*args)
project = Project.find(project_id) target_project_id = args.shift
target_project = Project.find(target_project_id)
return unless start_fork(project) # By v10.8, we should've drained the queue of all jobs using the old arguments.
# We can remove the else clause if we're no longer logging the message in that clause.
# See https://gitlab.com/gitlab-org/gitaly/issues/1110
if args.empty?
source_project = target_project.forked_from_project
return target_project.mark_import_as_failed('Source project cannot be found.') unless source_project
Gitlab::Metrics.add_event(:fork_repository, fork_repository(target_project, source_project.repository_storage, source_project.disk_path)
source_path: source_disk_path, else
target_path: project.disk_path) Rails.logger.info("Project #{target_project.id} is being forked using old-style arguments.")
source_repository_storage_path, source_disk_path = *args
result = gitlab_shell.fork_repository(forked_from_repository_storage_path, source_disk_path, source_repository_storage_name = Gitlab.config.repositories.storages.find do |_, info|
project.repository_storage_path, project.disk_path) info.legacy_disk_path == source_repository_storage_path
raise "Unable to fork project #{project_id} for repository #{source_disk_path} -> #{project.disk_path}" unless result end&.first || raise("no shard found for path '#{source_repository_storage_path}'")
project.after_import fork_repository(target_project, source_repository_storage_name, source_disk_path)
end
end end
private private
def fork_repository(target_project, source_repository_storage_name, source_disk_path)
return unless start_fork(target_project)
Gitlab::Metrics.add_event(:fork_repository,
source_path: source_disk_path,
target_path: target_project.disk_path)
result = gitlab_shell.fork_repository(source_repository_storage_name, source_disk_path,
target_project.repository_storage, target_project.disk_path)
raise "Unable to fork project #{target_project.id} for repository #{source_disk_path} -> #{target_project.disk_path}" unless result
target_project.after_import
end
def start_fork(project) def start_fork(project)
return true if start(project) return true if start(project)
......
---
title: Increase dropdown width in pipeline graph & center action icon
merge_request: 18089
author:
type: fixed
---
title: Add better LDAP connection handling
merge_request: 18039
author:
type: fixed
...@@ -63,7 +63,7 @@ module Gitlab ...@@ -63,7 +63,7 @@ module Gitlab
disk_path = project.wiki.disk_path disk_path = project.wiki.disk_path
import_url = project.import_url.sub(/\.git\z/, ".git/wiki") import_url = project.import_url.sub(/\.git\z/, ".git/wiki")
gitlab_shell.import_repository(project.repository_storage_path, disk_path, import_url) gitlab_shell.import_repository(project.repository_storage, disk_path, import_url)
rescue StandardError => e rescue StandardError => e
errors << { type: :wiki, errors: e.message } errors << { type: :wiki, errors: e.message }
end end
......
...@@ -4,20 +4,14 @@ module Gitlab ...@@ -4,20 +4,14 @@ module Gitlab
include Gitlab::Git::Popen include Gitlab::Git::Popen
include Gitlab::Utils::StrongMemoize include Gitlab::Utils::StrongMemoize
ShardNameNotFoundError = Class.new(StandardError) # Name of shard where repositories are stored.
# Example: nfs-file06
# Absolute path to directory where repositories are stored. attr_reader :shard_name
# Example: /home/git/repositories
attr_reader :shard_path
# Relative path is a directory name for repository with .git at the end. # Relative path is a directory name for repository with .git at the end.
# Example: gitlab-org/gitlab-test.git # Example: gitlab-org/gitlab-test.git
attr_reader :repository_relative_path attr_reader :repository_relative_path
# Absolute path to the repository.
# Example: /home/git/repositorities/gitlab-org/gitlab-test.git
attr_reader :repository_absolute_path
# This is the path at which the gitlab-shell hooks directory can be found. # This is the path at which the gitlab-shell hooks directory can be found.
# It's essential for integration between git and GitLab proper. All new # It's essential for integration between git and GitLab proper. All new
# repositories should have their hooks directory symlinked here. # repositories should have their hooks directory symlinked here.
...@@ -25,13 +19,12 @@ module Gitlab ...@@ -25,13 +19,12 @@ module Gitlab
attr_reader :logger attr_reader :logger
def initialize(shard_path, repository_relative_path, global_hooks_path:, logger:) def initialize(shard_name, repository_relative_path, global_hooks_path:, logger:)
@shard_path = shard_path @shard_name = shard_name
@repository_relative_path = repository_relative_path @repository_relative_path = repository_relative_path
@logger = logger @logger = logger
@global_hooks_path = global_hooks_path @global_hooks_path = global_hooks_path
@repository_absolute_path = File.join(shard_path, repository_relative_path)
@output = StringIO.new @output = StringIO.new
end end
...@@ -41,6 +34,22 @@ module Gitlab ...@@ -41,6 +34,22 @@ module Gitlab
io.read io.read
end end
# Absolute path to the repository.
# Example: /home/git/repositorities/gitlab-org/gitlab-test.git
# Probably will be removed when we fully migrate to Gitaly, part of
# https://gitlab.com/gitlab-org/gitaly/issues/1124.
def repository_absolute_path
strong_memoize(:repository_absolute_path) do
File.join(shard_path, repository_relative_path)
end
end
def shard_path
strong_memoize(:shard_path) do
Gitlab.config.repositories.storages.fetch(shard_name).legacy_disk_path
end
end
# Import project via git clone --bare # Import project via git clone --bare
# URL must be publicly cloneable # URL must be publicly cloneable
def import_project(source, timeout) def import_project(source, timeout)
...@@ -53,12 +62,12 @@ module Gitlab ...@@ -53,12 +62,12 @@ module Gitlab
end end
end end
def fork_repository(new_shard_path, new_repository_relative_path) def fork_repository(new_shard_name, new_repository_relative_path)
Gitlab::GitalyClient.migrate(:fork_repository) do |is_enabled| Gitlab::GitalyClient.migrate(:fork_repository) do |is_enabled|
if is_enabled if is_enabled
gitaly_fork_repository(new_shard_path, new_repository_relative_path) gitaly_fork_repository(new_shard_name, new_repository_relative_path)
else else
git_fork_repository(new_shard_path, new_repository_relative_path) git_fork_repository(new_shard_name, new_repository_relative_path)
end end
end end
end end
...@@ -215,17 +224,6 @@ module Gitlab ...@@ -215,17 +224,6 @@ module Gitlab
private private
def shard_name
strong_memoize(:shard_name) do
shard_name_from_shard_path(shard_path)
end
end
def shard_name_from_shard_path(shard_path)
Gitlab.config.repositories.storages.find { |_, info| info.legacy_disk_path == shard_path }&.first ||
raise(ShardNameNotFoundError, "no shard found for path '#{shard_path}'")
end
def git_import_repository(source, timeout) def git_import_repository(source, timeout)
# Skip import if repo already exists # Skip import if repo already exists
return false if File.exist?(repository_absolute_path) return false if File.exist?(repository_absolute_path)
...@@ -262,8 +260,9 @@ module Gitlab ...@@ -262,8 +260,9 @@ module Gitlab
false false
end end
def git_fork_repository(new_shard_path, new_repository_relative_path) def git_fork_repository(new_shard_name, new_repository_relative_path)
from_path = repository_absolute_path from_path = repository_absolute_path
new_shard_path = Gitlab.config.repositories.storages.fetch(new_shard_name).legacy_disk_path
to_path = File.join(new_shard_path, new_repository_relative_path) to_path = File.join(new_shard_path, new_repository_relative_path)
# The repository cannot already exist # The repository cannot already exist
...@@ -281,8 +280,8 @@ module Gitlab ...@@ -281,8 +280,8 @@ module Gitlab
run(cmd, nil) && Gitlab::Git::Repository.create_hooks(to_path, global_hooks_path) run(cmd, nil) && Gitlab::Git::Repository.create_hooks(to_path, global_hooks_path)
end end
def gitaly_fork_repository(new_shard_path, new_repository_relative_path) def gitaly_fork_repository(new_shard_name, new_repository_relative_path)
target_repository = Gitlab::Git::Repository.new(shard_name_from_shard_path(new_shard_path), new_repository_relative_path, nil) target_repository = Gitlab::Git::Repository.new(new_shard_name, new_repository_relative_path, nil)
raw_repository = Gitlab::Git::Repository.new(shard_name, repository_relative_path, nil) raw_repository = Gitlab::Git::Repository.new(shard_name, repository_relative_path, nil)
Gitlab::GitalyClient::RepositoryService.new(target_repository).fork_repository(raw_repository) Gitlab::GitalyClient::RepositoryService.new(target_repository).fork_repository(raw_repository)
......
...@@ -96,7 +96,7 @@ module Gitlab ...@@ -96,7 +96,7 @@ module Gitlab
storage_path = Gitlab.config.repositories.storages[@storage].legacy_disk_path storage_path = Gitlab.config.repositories.storages[@storage].legacy_disk_path
@gitlab_projects = Gitlab::Git::GitlabProjects.new( @gitlab_projects = Gitlab::Git::GitlabProjects.new(
storage_path, storage,
relative_path, relative_path,
global_hooks_path: Gitlab.config.gitlab_shell.hooks_path, global_hooks_path: Gitlab.config.gitlab_shell.hooks_path,
logger: Rails.logger logger: Rails.logger
......
...@@ -56,9 +56,8 @@ module Gitlab ...@@ -56,9 +56,8 @@ module Gitlab
def import_wiki_repository def import_wiki_repository
wiki_path = "#{project.disk_path}.wiki" wiki_path = "#{project.disk_path}.wiki"
storage_path = project.repository_storage_path
gitlab_shell.import_repository(storage_path, wiki_path, wiki_url) gitlab_shell.import_repository(project.repository_storage, wiki_path, wiki_url)
true true
rescue Gitlab::Shell::Error => e rescue Gitlab::Shell::Error => e
......
...@@ -259,7 +259,7 @@ module Gitlab ...@@ -259,7 +259,7 @@ module Gitlab
def import_wiki def import_wiki
unless project.wiki.repository_exists? unless project.wiki.repository_exists?
wiki = WikiFormatter.new(project) wiki = WikiFormatter.new(project)
gitlab_shell.import_repository(project.repository_storage_path, wiki.disk_path, wiki.import_url) gitlab_shell.import_repository(project.repository_storage, wiki.disk_path, wiki.import_url)
end end
rescue Gitlab::Shell::Error => e rescue Gitlab::Shell::Error => e
# GitHub error message when the wiki repo has not been created, # GitHub error message when the wiki repo has not been created,
......
...@@ -93,12 +93,12 @@ module Gitlab ...@@ -93,12 +93,12 @@ module Gitlab
# Import repository # Import repository
# #
# storage - project's storage path # storage - project's storage name
# name - project disk path # name - project disk path
# url - URL to import from # url - URL to import from
# #
# Ex. # Ex.
# import_repository("/path/to/storage", "gitlab/gitlab-ci", "https://gitlab.com/gitlab-org/gitlab-test.git") # import_repository("nfs-file06", "gitlab/gitlab-ci", "https://gitlab.com/gitlab-org/gitlab-test.git")
# #
# Gitaly migration: https://gitlab.com/gitlab-org/gitaly/issues/874 # Gitaly migration: https://gitlab.com/gitlab-org/gitaly/issues/874
def import_repository(storage, name, url) def import_repository(storage, name, url)
...@@ -131,8 +131,7 @@ module Gitlab ...@@ -131,8 +131,7 @@ module Gitlab
if is_enabled if is_enabled
repository.gitaly_repository_client.fetch_remote(remote, ssh_auth: ssh_auth, forced: forced, no_tags: no_tags, timeout: git_timeout, prune: prune) repository.gitaly_repository_client.fetch_remote(remote, ssh_auth: ssh_auth, forced: forced, no_tags: no_tags, timeout: git_timeout, prune: prune)
else else
storage_path = Gitlab.config.repositories.storages[repository.storage].legacy_disk_path local_fetch_remote(repository.storage, repository.relative_path, remote, ssh_auth: ssh_auth, forced: forced, no_tags: no_tags, prune: prune)
local_fetch_remote(storage_path, repository.relative_path, remote, ssh_auth: ssh_auth, forced: forced, no_tags: no_tags, prune: prune)
end end
end end
end end
...@@ -156,13 +155,13 @@ module Gitlab ...@@ -156,13 +155,13 @@ module Gitlab
end end
# Fork repository to new path # Fork repository to new path
# forked_from_storage - forked-from project's storage path # forked_from_storage - forked-from project's storage name
# forked_from_disk_path - project disk path # forked_from_disk_path - project disk relative path
# forked_to_storage - forked-to project's storage path # forked_to_storage - forked-to project's storage name
# forked_to_disk_path - forked project disk path # forked_to_disk_path - forked project disk relative path
# #
# Ex. # Ex.
# fork_repository("/path/to/forked_from/storage", "gitlab/gitlab-ci", "/path/to/forked_to/storage", "new-namespace/gitlab-ci") # fork_repository("nfs-file06", "gitlab/gitlab-ci", "nfs-file07", "new-namespace/gitlab-ci")
# #
# Gitaly migration: https://gitlab.com/gitlab-org/gitaly/issues/817 # Gitaly migration: https://gitlab.com/gitlab-org/gitaly/issues/817
def fork_repository(forked_from_storage, forked_from_disk_path, forked_to_storage, forked_to_disk_path) def fork_repository(forked_from_storage, forked_from_disk_path, forked_to_storage, forked_to_disk_path)
...@@ -420,16 +419,16 @@ module Gitlab ...@@ -420,16 +419,16 @@ module Gitlab
private private
def gitlab_projects(shard_path, disk_path) def gitlab_projects(shard_name, disk_path)
Gitlab::Git::GitlabProjects.new( Gitlab::Git::GitlabProjects.new(
shard_path, shard_name,
disk_path, disk_path,
global_hooks_path: Gitlab.config.gitlab_shell.hooks_path, global_hooks_path: Gitlab.config.gitlab_shell.hooks_path,
logger: Rails.logger logger: Rails.logger
) )
end end
def local_fetch_remote(storage_path, repository_relative_path, remote, ssh_auth: nil, forced: false, no_tags: false, prune: true) def local_fetch_remote(storage_name, repository_relative_path, remote, ssh_auth: nil, forced: false, no_tags: false, prune: true)
vars = { force: forced, tags: !no_tags, prune: prune } vars = { force: forced, tags: !no_tags, prune: prune }
if ssh_auth&.ssh_import? if ssh_auth&.ssh_import?
...@@ -442,7 +441,7 @@ module Gitlab ...@@ -442,7 +441,7 @@ module Gitlab
end end
end end
cmd = gitlab_projects(storage_path, repository_relative_path) cmd = gitlab_projects(storage_name, repository_relative_path)
success = cmd.fetch_remote(remote, git_timeout, vars) success = cmd.fetch_remote(remote, git_timeout, vars)
......
...@@ -84,6 +84,13 @@ describe ProfilesController, :request_store do ...@@ -84,6 +84,13 @@ describe ProfilesController, :request_store do
expect(user.username).to eq(new_username) expect(user.username).to eq(new_username)
end end
it 'raises a correct error when the username is missing' do
sign_in(user)
expect { put :update_username, user: { gandalf: 'you shall not pass' } }
.to raise_error(ActionController::ParameterMissing)
end
context 'with legacy storage' do context 'with legacy storage' do
it 'moves dependent projects to new namespace' do it 'moves dependent projects to new namespace' do
project = create(:project_empty_repo, :legacy_storage, namespace: namespace) project = create(:project_empty_repo, :legacy_storage, namespace: namespace)
......
...@@ -176,6 +176,22 @@ describe Gitlab::Auth::LDAP::Access do ...@@ -176,6 +176,22 @@ describe Gitlab::Auth::LDAP::Access do
expect(access.allowed?).to be_falsey expect(access.allowed?).to be_falsey
end end
end end
context 'when the connection fails' do
before do
raise_ldap_connection_error
end
it 'does not block the user' do
access.allowed?
expect(user.ldap_blocked?).to be_falsey
end
it 'denies access' do
expect(access.allowed?).to be_falsey
end
end
end end
describe '#block_user' do describe '#block_user' do
......
...@@ -137,7 +137,7 @@ describe Gitlab::BitbucketImport::Importer do ...@@ -137,7 +137,7 @@ describe Gitlab::BitbucketImport::Importer do
it 'imports to the project disk_path' do it 'imports to the project disk_path' do
expect(project.wiki).to receive(:repository_exists?) { false } expect(project.wiki).to receive(:repository_exists?) { false }
expect(importer.gitlab_shell).to receive(:import_repository).with( expect(importer.gitlab_shell).to receive(:import_repository).with(
project.repository_storage_path, project.repository_storage,
project.wiki.disk_path, project.wiki.disk_path,
project.import_url + '/wiki' project.import_url + '/wiki'
) )
......
...@@ -16,7 +16,7 @@ describe Gitlab::Git::GitlabProjects do ...@@ -16,7 +16,7 @@ describe Gitlab::Git::GitlabProjects do
let(:tmp_repos_path) { TestEnv.repos_path } let(:tmp_repos_path) { TestEnv.repos_path }
let(:repo_name) { project.disk_path + '.git' } let(:repo_name) { project.disk_path + '.git' }
let(:tmp_repo_path) { File.join(tmp_repos_path, repo_name) } let(:tmp_repo_path) { File.join(tmp_repos_path, repo_name) }
let(:gl_projects) { build_gitlab_projects(tmp_repos_path, repo_name) } let(:gl_projects) { build_gitlab_projects(TestEnv::REPOS_STORAGE, repo_name) }
describe '#initialize' do describe '#initialize' do
it { expect(gl_projects.shard_path).to eq(tmp_repos_path) } it { expect(gl_projects.shard_path).to eq(tmp_repos_path) }
...@@ -237,11 +237,12 @@ describe Gitlab::Git::GitlabProjects do ...@@ -237,11 +237,12 @@ describe Gitlab::Git::GitlabProjects do
end end
describe '#fork_repository' do describe '#fork_repository' do
let(:dest_repos) { TestEnv::REPOS_STORAGE }
let(:dest_repos_path) { tmp_repos_path } let(:dest_repos_path) { tmp_repos_path }
let(:dest_repo_name) { File.join('@hashed', 'aa', 'bb', 'xyz.git') } let(:dest_repo_name) { File.join('@hashed', 'aa', 'bb', 'xyz.git') }
let(:dest_repo) { File.join(dest_repos_path, dest_repo_name) } let(:dest_repo) { File.join(dest_repos_path, dest_repo_name) }
subject { gl_projects.fork_repository(dest_repos_path, dest_repo_name) } subject { gl_projects.fork_repository(dest_repos, dest_repo_name) }
before do before do
FileUtils.mkdir_p(dest_repos_path) FileUtils.mkdir_p(dest_repos_path)
...@@ -282,7 +283,12 @@ describe Gitlab::Git::GitlabProjects do ...@@ -282,7 +283,12 @@ describe Gitlab::Git::GitlabProjects do
# that is not very straight-forward so I'm leaving this test here for now till # that is not very straight-forward so I'm leaving this test here for now till
# https://gitlab.com/gitlab-org/gitlab-ce/issues/41393 is fixed. # https://gitlab.com/gitlab-org/gitlab-ce/issues/41393 is fixed.
context 'different storages' do context 'different storages' do
let(:dest_repos_path) { File.join(File.dirname(tmp_repos_path), 'alternative') } let(:dest_repos) { 'alternative' }
let(:dest_repos_path) { File.join(File.dirname(tmp_repos_path), dest_repos) }
before do
stub_storage_settings(dest_repos => { 'path' => dest_repos_path })
end
it 'forks the repo' do it 'forks the repo' do
is_expected.to be_truthy is_expected.to be_truthy
......
...@@ -9,7 +9,7 @@ describe Gitlab::GithubImport::Importer::RepositoryImporter do ...@@ -9,7 +9,7 @@ describe Gitlab::GithubImport::Importer::RepositoryImporter do
:project, :project,
import_url: 'foo.git', import_url: 'foo.git',
import_source: 'foo/bar', import_source: 'foo/bar',
repository_storage_path: 'foo', repository_storage: 'foo',
disk_path: 'foo', disk_path: 'foo',
repository: repository, repository: repository,
create_wiki: true create_wiki: true
......
...@@ -14,7 +14,7 @@ describe Gitlab::Shell do ...@@ -14,7 +14,7 @@ describe Gitlab::Shell do
allow(Project).to receive(:find).and_return(project) allow(Project).to receive(:find).and_return(project)
allow(gitlab_shell).to receive(:gitlab_projects) allow(gitlab_shell).to receive(:gitlab_projects)
.with(project.repository_storage_path, project.disk_path + '.git') .with(project.repository_storage, project.disk_path + '.git')
.and_return(gitlab_projects) .and_return(gitlab_projects)
end end
...@@ -487,21 +487,21 @@ describe Gitlab::Shell do ...@@ -487,21 +487,21 @@ describe Gitlab::Shell do
describe '#fork_repository' do describe '#fork_repository' do
subject do subject do
gitlab_shell.fork_repository( gitlab_shell.fork_repository(
project.repository_storage_path, project.repository_storage,
project.disk_path, project.disk_path,
'new/storage', 'nfs-file05',
'fork/path' 'fork/path'
) )
end end
it 'returns true when the command succeeds' do it 'returns true when the command succeeds' do
expect(gitlab_projects).to receive(:fork_repository).with('new/storage', 'fork/path.git') { true } expect(gitlab_projects).to receive(:fork_repository).with('nfs-file05', 'fork/path.git') { true }
is_expected.to be_truthy is_expected.to be_truthy
end end
it 'return false when the command fails' do it 'return false when the command fails' do
expect(gitlab_projects).to receive(:fork_repository).with('new/storage', 'fork/path.git') { false } expect(gitlab_projects).to receive(:fork_repository).with('nfs-file05', 'fork/path.git') { false }
is_expected.to be_falsy is_expected.to be_falsy
end end
...@@ -661,7 +661,7 @@ describe Gitlab::Shell do ...@@ -661,7 +661,7 @@ describe Gitlab::Shell do
it 'returns true when the command succeeds' do it 'returns true when the command succeeds' do
expect(gitlab_projects).to receive(:import_project).with(import_url, timeout) { true } expect(gitlab_projects).to receive(:import_project).with(import_url, timeout) { true }
result = gitlab_shell.import_repository(project.repository_storage_path, project.disk_path, import_url) result = gitlab_shell.import_repository(project.repository_storage, project.disk_path, import_url)
expect(result).to be_truthy expect(result).to be_truthy
end end
...@@ -671,7 +671,7 @@ describe Gitlab::Shell do ...@@ -671,7 +671,7 @@ describe Gitlab::Shell do
expect(gitlab_projects).to receive(:import_project) { false } expect(gitlab_projects).to receive(:import_project) { false }
expect do expect do
gitlab_shell.import_repository(project.repository_storage_path, project.disk_path, import_url) gitlab_shell.import_repository(project.repository_storage, project.disk_path, import_url)
end.to raise_error(Gitlab::Shell::Error, "error") end.to raise_error(Gitlab::Shell::Error, "error")
end end
end end
......
...@@ -1800,7 +1800,7 @@ describe Project do ...@@ -1800,7 +1800,7 @@ describe Project do
before do before do
allow_any_instance_of(Gitlab::Shell).to receive(:import_repository) allow_any_instance_of(Gitlab::Shell).to receive(:import_repository)
.with(project.repository_storage_path, project.disk_path, project.import_url) .with(project.repository_storage, project.disk_path, project.import_url)
.and_return(true) .and_return(true)
expect_any_instance_of(Repository).to receive(:after_import) expect_any_instance_of(Repository).to receive(:after_import)
...@@ -1965,10 +1965,7 @@ describe Project do ...@@ -1965,10 +1965,7 @@ describe Project do
let(:project) { forked_project_link.forked_to_project } let(:project) { forked_project_link.forked_to_project }
it 'schedules a RepositoryForkWorker job' do it 'schedules a RepositoryForkWorker job' do
expect(RepositoryForkWorker).to receive(:perform_async).with( expect(RepositoryForkWorker).to receive(:perform_async).with(project.id).and_return(import_jid)
project.id,
forked_from_project.repository_storage_path,
forked_from_project.disk_path).and_return(import_jid)
expect(project.add_import_job).to eq(import_jid) expect(project.add_import_job).to eq(import_jid)
end end
......
...@@ -122,7 +122,8 @@ RSpec.configure do |config| ...@@ -122,7 +122,8 @@ RSpec.configure do |config|
allow_any_instance_of(Gitlab::Git::GitlabProjects).to receive(:fork_repository).and_wrap_original do |m, *args| allow_any_instance_of(Gitlab::Git::GitlabProjects).to receive(:fork_repository).and_wrap_original do |m, *args|
m.call(*args) m.call(*args)
shard_path, repository_relative_path = args shard_name, repository_relative_path = args
shard_path = Gitlab.config.repositories.storages.fetch(shard_name).legacy_disk_path
# We can't leave the hooks in place after a fork, as those would fail in tests # We can't leave the hooks in place after a fork, as those would fail in tests
# The "internal" API is not available # The "internal" API is not available
FileUtils.rm_rf(File.join(shard_path, repository_relative_path, 'hooks')) FileUtils.rm_rf(File.join(shard_path, repository_relative_path, 'hooks'))
......
...@@ -63,6 +63,7 @@ module TestEnv ...@@ -63,6 +63,7 @@ module TestEnv
}.freeze }.freeze
TMP_TEST_PATH = Rails.root.join('tmp', 'tests', '**') TMP_TEST_PATH = Rails.root.join('tmp', 'tests', '**')
REPOS_STORAGE = 'default'.freeze
# Test environment # Test environment
# #
...@@ -226,7 +227,7 @@ module TestEnv ...@@ -226,7 +227,7 @@ module TestEnv
end end
def repos_path def repos_path
Gitlab.config.repositories.storages.default.legacy_disk_path Gitlab.config.repositories.storages[REPOS_STORAGE].legacy_disk_path
end end
def backup_path def backup_path
......
...@@ -9,70 +9,91 @@ describe RepositoryForkWorker do ...@@ -9,70 +9,91 @@ describe RepositoryForkWorker do
describe "#perform" do describe "#perform" do
let(:project) { create(:project, :repository) } let(:project) { create(:project, :repository) }
let(:fork_project) { create(:project, :repository, :import_scheduled, forked_from_project: project) }
let(:shell) { Gitlab::Shell.new } let(:shell) { Gitlab::Shell.new }
let(:fork_project) { create(:project, :repository, :import_scheduled, forked_from_project: project) }
before do shared_examples 'RepositoryForkWorker performing' do
allow(subject).to receive(:gitlab_shell).and_return(shell) before do
end allow(subject).to receive(:gitlab_shell).and_return(shell)
end
def perform! def expect_fork_repository
subject.perform(fork_project.id, '/test/path', project.disk_path) expect(shell).to receive(:fork_repository).with(
end 'default',
project.disk_path,
fork_project.repository_storage,
fork_project.disk_path
)
end
def expect_fork_repository describe 'when a worker was reset without cleanup' do
expect(shell).to receive(:fork_repository).with( let(:jid) { '12345678' }
'/test/path',
project.disk_path,
fork_project.repository_storage_path,
fork_project.disk_path
)
end
describe 'when a worker was reset without cleanup' do it 'creates a new repository from a fork' do
let(:jid) { '12345678' } allow(subject).to receive(:jid).and_return(jid)
it 'creates a new repository from a fork' do expect_fork_repository.and_return(true)
allow(subject).to receive(:jid).and_return(jid)
perform!
end
end
it "creates a new repository from a fork" do
expect_fork_repository.and_return(true) expect_fork_repository.and_return(true)
perform! perform!
end end
end
it "creates a new repository from a fork" do it 'protects the default branch' do
expect_fork_repository.and_return(true) expect_fork_repository.and_return(true)
perform! perform!
end
expect(fork_project.protected_branches.first.name).to eq(fork_project.default_branch)
end
it 'flushes various caches' do
expect_fork_repository.and_return(true)
it 'protects the default branch' do expect_any_instance_of(Repository).to receive(:expire_emptiness_caches)
expect_fork_repository.and_return(true) .and_call_original
perform! expect_any_instance_of(Repository).to receive(:expire_exists_cache)
.and_call_original
expect(fork_project.protected_branches.first.name).to eq(fork_project.default_branch) perform!
end end
it "handles bad fork" do
error_message = "Unable to fork project #{fork_project.id} for repository #{project.disk_path} -> #{fork_project.disk_path}"
it 'flushes various caches' do expect_fork_repository.and_return(false)
expect_fork_repository.and_return(true)
expect_any_instance_of(Repository).to receive(:expire_emptiness_caches) expect { perform! }.to raise_error(StandardError, error_message)
.and_call_original end
end
expect_any_instance_of(Repository).to receive(:expire_exists_cache) context 'only project ID passed' do
.and_call_original def perform!
subject.perform(fork_project.id)
end
perform! it_behaves_like 'RepositoryForkWorker performing'
end end
it "handles bad fork" do context 'project ID, storage and repo paths passed' do
error_message = "Unable to fork project #{fork_project.id} for repository #{project.disk_path} -> #{fork_project.disk_path}" def perform!
subject.perform(fork_project.id, TestEnv.repos_path, project.disk_path)
end
expect_fork_repository.and_return(false) it_behaves_like 'RepositoryForkWorker performing'
expect { perform! }.to raise_error(StandardError, error_message) it 'logs a message about forking with old-style arguments' do
allow(Rails.logger).to receive(:info).with(anything) # To compensate for other logs
expect(Rails.logger).to receive(:info).with("Project #{fork_project.id} is being forked using old-style arguments.")
perform!
end
end end
end end
end end
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment