From 056c42cca5aa21fb2ebc9e5fc2cbedf18cf8dbbc Mon Sep 17 00:00:00 2001 From: Felipe Artur Date: Tue, 12 Sep 2017 18:07:11 -0300 Subject: Fix project feature being deleted when updating project with invalid visibility level --- app/services/projects/update_service.rb | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'app/services/projects') diff --git a/app/services/projects/update_service.rb b/app/services/projects/update_service.rb index cb4ffcab778..13e292a18bf 100644 --- a/app/services/projects/update_service.rb +++ b/app/services/projects/update_service.rb @@ -24,7 +24,10 @@ module Projects success else - error('Project could not be updated!') + model_errors = project.errors.full_messages.to_sentence + error_message = model_errors.presence || 'Project could not be updated!' + + error(error_message) end end -- cgit v1.2.1 From 57b96eb6db9b860991b035714e65ffd557327b6f Mon Sep 17 00:00:00 2001 From: Yorick Peterse Date: Tue, 19 Sep 2017 13:55:56 +0200 Subject: Fix refreshing of issues/MR count caches This ensures the open issues/MR count caches are refreshed properly when creating new issues or MRs. This MR also includes a change to the cache keys to ensure all caches are rebuilt on the fly. This particular problem was not caught in the test suite due to a null cache being used, resulting in all calls that would use a cache using the underlying data directly. In production the code would fail because a newly saved record returns an empty hash in #changes meaning checks such as `state_changed? || confidential_changed?` would return false for new rows, thus never updating the counters. Fixes https://gitlab.com/gitlab-org/gitlab-ce/issues/38061 --- app/services/projects/count_service.rb | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) (limited to 'app/services/projects') diff --git a/app/services/projects/count_service.rb b/app/services/projects/count_service.rb index 5e633c37bf8..aa034315280 100644 --- a/app/services/projects/count_service.rb +++ b/app/services/projects/count_service.rb @@ -2,6 +2,11 @@ module Projects # Base class for the various service classes that count project data (e.g. # issues or forks). class CountService + # The version of the cache format. This should be bumped whenever the + # underlying logic changes. This removes the need for explicitly flushing + # all caches. + VERSION = 1 + def initialize(project) @project = project end @@ -37,7 +42,7 @@ module Projects end def cache_key - ['projects', @project.id, cache_key_name] + ['projects', 'count_service', VERSION, @project.id, cache_key_name] end end end -- cgit v1.2.1 From f4de14d71f425dc14ee5837d96f4e9f42c7cc239 Mon Sep 17 00:00:00 2001 From: Gabriel Mazetto Date: Wed, 6 Sep 2017 07:16:26 +0200 Subject: Add support to migrate existing projects to Hashed Storage async --- .../projects/hashed_storage_migration_service.rb | 68 ++++++++++++++++++++++ 1 file changed, 68 insertions(+) create mode 100644 app/services/projects/hashed_storage_migration_service.rb (limited to 'app/services/projects') diff --git a/app/services/projects/hashed_storage_migration_service.rb b/app/services/projects/hashed_storage_migration_service.rb new file mode 100644 index 00000000000..41259de3a16 --- /dev/null +++ b/app/services/projects/hashed_storage_migration_service.rb @@ -0,0 +1,68 @@ +module Projects + class HashedStorageMigrationService < BaseService + include Gitlab::ShellAdapter + + attr_reader :old_disk_path, :new_disk_path + + def initialize(project, logger = nil) + @project = project + @logger ||= Rails.logger + end + + def execute + return if project.hashed_storage? + + @old_disk_path = project.disk_path + has_wiki = project.wiki.repository_exists? + + project.storage_version = Storage::HashedProject::STORAGE_VERSION + project.ensure_storage_path_exists + + @new_disk_path = project.disk_path + + result = move_repository(@old_disk_path, @new_disk_path) + + if has_wiki + result &&= move_repository("#{@old_disk_path}.wiki", "#{@new_disk_path}.wiki") + end + + unless result + rollback_folder_move + return + end + + project.repository_read_only = false + project.save! + + block_given? ? yield : result + end + + private + + def move_repository(from_name, to_name) + from_exists = gitlab_shell.exists?(project.repository_storage_path, "#{from_name}.git") + to_exists = gitlab_shell.exists?(project.repository_storage_path, "#{to_name}.git") + + # If we don't find the repository on either original or target we should log that as it could be an issue if the + # project was not originally empty. + if !from_exists && !to_exists + logger.warn "Can't find a repository on either source or target paths for #{project.full_path} (ID=#{project.id}) ..." + return false + elsif !from_exists + # Repository have been moved already. + return true + end + + gitlab_shell.mv_repository(project.repository_storage_path, from_name, to_name) + end + + def rollback_folder_move + move_repository(@new_disk_path, @old_disk_path) + move_repository("#{@new_disk_path}.wiki", "#{@old_disk_path}.wiki") + end + + def logger + @logger + end + end +end -- cgit v1.2.1 From d328007214786c7137c31d2c73e9ee76b025e6ed Mon Sep 17 00:00:00 2001 From: Bob Van Landuyt Date: Thu, 28 Sep 2017 16:38:12 +0200 Subject: Create a fork network when forking a project When no fork network exists for the source projects, we create a new one with the correct source --- app/services/projects/fork_service.rb | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) (limited to 'app/services/projects') diff --git a/app/services/projects/fork_service.rb b/app/services/projects/fork_service.rb index ad67e68a86a..eb5cce5ab98 100644 --- a/app/services/projects/fork_service.rb +++ b/app/services/projects/fork_service.rb @@ -23,11 +23,31 @@ module Projects refresh_forks_count + link_fork_network(new_project) + new_project end private + def fork_network + if @project.fork_network + @project.fork_network + elsif forked_from_project = @project.forked_from_project + # TODO: remove this case when all background migrations have completed + # this only happens when a project had a `forked_project_link` that was + # not migrated to the `fork_network` relation + forked_from_project.fork_network || forked_from_project.create_root_of_fork_network + else + @project.create_root_of_fork_network + end + end + + def link_fork_network(new_project) + fork_network.fork_network_members.create(project: new_project, + forked_from_project: @project) + end + def refresh_forks_count Projects::ForksCountService.new(@project).refresh_cache end -- cgit v1.2.1 From 8160550439d2027c12d5556c8ce1f8afd250628a Mon Sep 17 00:00:00 2001 From: Bob Van Landuyt Date: Sat, 30 Sep 2017 20:21:08 +0200 Subject: Remove membership from fork network when unlinking --- app/services/projects/unlink_fork_service.rb | 1 + 1 file changed, 1 insertion(+) (limited to 'app/services/projects') diff --git a/app/services/projects/unlink_fork_service.rb b/app/services/projects/unlink_fork_service.rb index f30b40423c8..abe414d0c05 100644 --- a/app/services/projects/unlink_fork_service.rb +++ b/app/services/projects/unlink_fork_service.rb @@ -16,6 +16,7 @@ module Projects refresh_forks_count(@project.forked_from_project) @project.forked_project_link.destroy + @project.fork_network_member.destroy end def refresh_forks_count(project) -- cgit v1.2.1 From 14a6cebc9feefc45b587bf9b9b706194b9b5bff9 Mon Sep 17 00:00:00 2001 From: Bob Van Landuyt Date: Tue, 3 Oct 2017 18:27:51 +0200 Subject: Store the name of a project that's a root of a fork network So we can keep showing it to a user in his project page. --- app/services/projects/destroy_service.rb | 7 +++++++ 1 file changed, 7 insertions(+) (limited to 'app/services/projects') diff --git a/app/services/projects/destroy_service.rb b/app/services/projects/destroy_service.rb index 54eb75ab9bf..19d75ff2efa 100644 --- a/app/services/projects/destroy_service.rb +++ b/app/services/projects/destroy_service.rb @@ -22,6 +22,13 @@ module Projects Projects::UnlinkForkService.new(project, current_user).execute + # The project is not necessarily a fork, so update the fork network originating + # from this project + if fork_network = project.root_of_fork_network + fork_network.update(root_project: nil, + deleted_root_project_name: project.full_name) + end + attempt_destroy_transaction(project) system_hook_service.execute_hooks_for(project, :destroy) -- cgit v1.2.1