diff options
36 files changed, 319 insertions, 202 deletions
diff --git a/CHANGELOG b/CHANGELOG index fc828847016..a0b56bd3055 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -42,6 +42,8 @@ v 7.12.0 (unreleased) - Add an option to automatically sign-in with an Omniauth provider - Better performance for web editor (switched from satellites to rugged) - GitLab CI service sends .gitlab-ci.yaml in each push call + - When remove project - move repository and schedule it removal + - Improve group removing logic - Trigger create-hooks on backup restore task v 7.11.4 diff --git a/app/assets/stylesheets/generic/typography.scss b/app/assets/stylesheets/generic/typography.scss index e5590897947..66767cb13cb 100644 --- a/app/assets/stylesheets/generic/typography.scss +++ b/app/assets/stylesheets/generic/typography.scss @@ -23,6 +23,13 @@ pre { font-family: $monospace_font; } +code { + &.key-fingerprint { + background: $body-bg; + color: $text-color; + } +} + /** * Wiki typography * diff --git a/app/controllers/admin/deploy_keys_controller.rb b/app/controllers/admin/deploy_keys_controller.rb index c301e61d1c7..285e8495342 100644 --- a/app/controllers/admin/deploy_keys_controller.rb +++ b/app/controllers/admin/deploy_keys_controller.rb @@ -1,13 +1,8 @@ class Admin::DeployKeysController < Admin::ApplicationController before_action :deploy_keys, only: [:index] - before_action :deploy_key, only: [:show, :destroy] + before_action :deploy_key, only: [:destroy] def index - - end - - def show - end def new diff --git a/app/controllers/admin/groups_controller.rb b/app/controllers/admin/groups_controller.rb index 2dfae13ac5c..4d3e48f7f81 100644 --- a/app/controllers/admin/groups_controller.rb +++ b/app/controllers/admin/groups_controller.rb @@ -47,7 +47,7 @@ class Admin::GroupsController < Admin::ApplicationController end def destroy - @group.destroy + DestroyGroupService.new(@group, current_user).execute redirect_to admin_groups_path, notice: 'Group was successfully deleted.' end diff --git a/app/controllers/groups_controller.rb b/app/controllers/groups_controller.rb index 34f0b257db3..2e381822e42 100644 --- a/app/controllers/groups_controller.rb +++ b/app/controllers/groups_controller.rb @@ -82,7 +82,7 @@ class GroupsController < Groups::ApplicationController end def destroy - @group.destroy + DestroyGroupService.new(@group, current_user).execute redirect_to root_path, notice: 'Group was removed.' end diff --git a/app/controllers/projects/deploy_keys_controller.rb b/app/controllers/projects/deploy_keys_controller.rb index 8c1bbf76917..40e2b37912b 100644 --- a/app/controllers/projects/deploy_keys_controller.rb +++ b/app/controllers/projects/deploy_keys_controller.rb @@ -18,10 +18,6 @@ class Projects::DeployKeysController < Projects::ApplicationController @available_public_keys -= @available_project_keys end - def show - @key = @project.deploy_keys.find(params[:id]) - end - def new @key = @project.deploy_keys.new diff --git a/app/controllers/projects_controller.rb b/app/controllers/projects_controller.rb index dc430351551..4ca5fc65459 100644 --- a/app/controllers/projects_controller.rb +++ b/app/controllers/projects_controller.rb @@ -97,18 +97,15 @@ class ProjectsController < ApplicationController return access_denied! unless can?(current_user, :remove_project, @project) ::Projects::DestroyService.new(@project, current_user, {}).execute + flash[:alert] = 'Project deleted.' - respond_to do |format| - format.html do - flash[:alert] = 'Project deleted.' - - if request.referer.include?('/admin') - redirect_to admin_namespaces_projects_path - else - redirect_to dashboard_path - end - end + if request.referer.include?('/admin') + redirect_to admin_namespaces_projects_path + else + redirect_to dashboard_path end + rescue Projects::DestroyService::DestroyError => ex + redirect_to edit_project_path(@project), alert: ex.message end def autocomplete_sources diff --git a/app/models/group.rb b/app/models/group.rb index b4e908c5602..051c672cb33 100644 --- a/app/models/group.rb +++ b/app/models/group.rb @@ -101,10 +101,14 @@ class Group < Namespace end def post_create_hook + Gitlab::AppLogger.info("Group \"#{name}\" was created") + system_hook_service.execute_hooks_for(self, :create) end def post_destroy_hook + Gitlab::AppLogger.info("Group \"#{name}\" was removed") + system_hook_service.execute_hooks_for(self, :destroy) end diff --git a/app/models/namespace.rb b/app/models/namespace.rb index 211dfa76b81..03d2ab165ea 100644 --- a/app/models/namespace.rb +++ b/app/models/namespace.rb @@ -72,7 +72,7 @@ class Namespace < ActiveRecord::Base path.gsub!(/[^a-zA-Z0-9_\-\.]/, "") # Users with the great usernames of "." or ".." would end up with a blank username. - # Work around that by setting their username to "blank", followed by a counter. + # Work around that by setting their username to "blank", followed by a counter. path = "blank" if path.blank? counter = 0 @@ -99,7 +99,18 @@ class Namespace < ActiveRecord::Base end def rm_dir - gitlab_shell.rm_namespace(path) + # Move namespace directory into trash. + # We will remove it later async + new_path = "#{path}+#{id}+deleted" + + if gitlab_shell.mv_namespace(path, new_path) + message = "Namespace directory \"#{path}\" moved to \"#{new_path}\"" + Gitlab::AppLogger.info message + + # Remove namespace directroy async with delay so + # GitLab has time to remove all projects first + GitlabShellWorker.perform_in(5.minutes, :rm_namespace, new_path) + end end def move_dir diff --git a/app/services/delete_user_service.rb b/app/services/delete_user_service.rb index d259b4efca6..9017a63af3b 100644 --- a/app/services/delete_user_service.rb +++ b/app/services/delete_user_service.rb @@ -4,6 +4,12 @@ class DeleteUserService user.errors[:base] << 'You must transfer ownership or delete groups before you can remove user' user else + user.personal_projects.each do |project| + # Skip repository removal because we remove directory with namespace + # that contain all this repositories + ::Projects::DestroyService.new(project, current_user, skip_repo: true).execute + end + user.destroy end end diff --git a/app/services/destroy_group_service.rb b/app/services/destroy_group_service.rb new file mode 100644 index 00000000000..d929a676293 --- /dev/null +++ b/app/services/destroy_group_service.rb @@ -0,0 +1,17 @@ +class DestroyGroupService + attr_accessor :group, :current_user + + def initialize(group, user) + @group, @current_user = group, user + end + + def execute + @group.projects.each do |project| + # Skip repository removal because we remove directory with namespace + # that contain all this repositories + ::Projects::DestroyService.new(project, current_user, skip_repo: true).execute + end + + @group.destroy + end +end diff --git a/app/services/projects/destroy_service.rb b/app/services/projects/destroy_service.rb index 7e1d753b021..403f419ec50 100644 --- a/app/services/projects/destroy_service.rb +++ b/app/services/projects/destroy_service.rb @@ -1,28 +1,69 @@ module Projects class DestroyService < BaseService + include Gitlab::ShellAdapter + + class DestroyError < StandardError; end + + DELETED_FLAG = '+deleted' + def execute return false unless can?(current_user, :remove_project, project) project.team.truncate project.repository.expire_cache unless project.empty_repo? - if project.destroy - GitlabShellWorker.perform_async( - :remove_repository, - project.path_with_namespace - ) + repo_path = project.path_with_namespace + wiki_path = repo_path + '.wiki' - GitlabShellWorker.perform_async( - :remove_repository, - project.path_with_namespace + ".wiki" - ) + Project.transaction do + project.destroy! - project.satellite.destroy + unless remove_repository(repo_path) + raise_error('Failed to remove project repository. Please try again or contact administrator') + end - log_info("Project \"#{project.name}\" was removed") - system_hook_service.execute_hooks_for(project, :destroy) - true + unless remove_repository(wiki_path) + raise_error('Failed to remove wiki repository. Please try again or contact administrator') + end end + + project.satellite.destroy + log_info("Project \"#{project.name}\" was removed") + system_hook_service.execute_hooks_for(project, :destroy) + true + end + + private + + def remove_repository(path) + # Skip repository removal. We use this flag when remove user or group + return true if params[:skip_repo] == true + + # There is a possibility project does not have repository or wiki + return true unless gitlab_shell.exists?(path + '.git') + + new_path = removal_path(path) + + if gitlab_shell.mv_repository(path, new_path) + log_info("Repository \"#{path}\" moved to \"#{new_path}\"") + GitlabShellWorker.perform_in(5.minutes, :remove_repository, new_path) + else + false + end + end + + def raise_error(message) + raise DestroyError.new(message) + end + + # Build a path for removing repositories + # We use `+` because its not allowed by GitLab so user can not create + # project with name cookies+119+deleted and capture someone stalled repository + # + # gitlab/cookies.git -> gitlab/cookies+119+deleted.git + # + def removal_path(path) + "#{path}+#{project.id}#{DELETED_FLAG}" end end end diff --git a/app/views/admin/deploy_keys/index.html.haml b/app/views/admin/deploy_keys/index.html.haml index 367d25cd6a1..6405a69fad3 100644 --- a/app/views/admin/deploy_keys/index.html.haml +++ b/app/views/admin/deploy_keys/index.html.haml @@ -19,8 +19,7 @@ = link_to admin_deploy_key_path(deploy_key) do %strong= deploy_key.title %td - %span - (#{deploy_key.fingerprint}) + %code.key-fingerprint= deploy_key.fingerprint %td %span.cgray added #{time_ago_with_tooltip(deploy_key.created_at)} diff --git a/app/views/admin/deploy_keys/show.html.haml b/app/views/admin/deploy_keys/show.html.haml deleted file mode 100644 index ea361ca4bdb..00000000000 --- a/app/views/admin/deploy_keys/show.html.haml +++ /dev/null @@ -1,35 +0,0 @@ -- page_title @deploy_key.title, "Deploy Keys" -.row - .col-md-4 - .panel.panel-default - .panel-heading - Deploy Key - %ul.well-list - %li - %span.light Title: - %strong= @deploy_key.title - %li - %span.light Created on: - %strong= @deploy_key.created_at.stamp("Aug 21, 2011") - - .panel.panel-default - .panel-heading Projects (#{@deploy_key.deploy_keys_projects.count}) - - if @deploy_key.deploy_keys_projects.any? - %ul.well-list - - @deploy_key.projects.each do |project| - %li - %span - %strong - = link_to project.name_with_namespace, [:admin, project.namespace.becomes(Namespace), project] - .pull-right - = link_to disable_namespace_project_deploy_key_path(project.namespace, project, @deploy_key), data: { confirm: "Are you sure?" }, method: :put, class: "btn-xs btn btn-remove", title: 'Remove deploy key from project' do - %i.fa.fa-times.fa-inverse - - .col-md-8 - %p - %span.light Fingerprint: - %strong= @deploy_key.fingerprint - %pre.well-pre - = @deploy_key.key - .pull-right - = link_to 'Remove', admin_deploy_key_path(@deploy_key), data: {confirm: 'Are you sure?'}, method: :delete, class: "btn btn-remove delete-key" diff --git a/app/views/profiles/keys/_key.html.haml b/app/views/profiles/keys/_key.html.haml index fe5770f45c3..9bbccbc45ea 100644 --- a/app/views/profiles/keys/_key.html.haml +++ b/app/views/profiles/keys/_key.html.haml @@ -3,8 +3,7 @@ = link_to path_to_key(key, is_admin) do %strong= key.title %td - %span - (#{key.fingerprint}) + %code.key-fingerprint= key.fingerprint %td %span.cgray added #{time_ago_with_tooltip(key.created_at)} diff --git a/app/views/profiles/keys/_key_details.html.haml b/app/views/profiles/keys/_key_details.html.haml index 8bac22a2e1a..e0ae4d9720f 100644 --- a/app/views/profiles/keys/_key_details.html.haml +++ b/app/views/profiles/keys/_key_details.html.haml @@ -15,7 +15,7 @@ .col-md-8 %p %span.light Fingerprint: - %strong= @key.fingerprint + %code.key-fingerprint= @key.fingerprint %pre.well-pre = @key.key .pull-right diff --git a/app/views/projects/deploy_keys/_deploy_key.html.haml b/app/views/projects/deploy_keys/_deploy_key.html.haml index c577dfa8d55..8d66bae8cdf 100644 --- a/app/views/projects/deploy_keys/_deploy_key.html.haml +++ b/app/views/projects/deploy_keys/_deploy_key.html.haml @@ -2,24 +2,20 @@ .pull-right - if @available_keys.include?(deploy_key) = link_to enable_namespace_project_deploy_key_path(@project.namespace, @project, deploy_key), class: 'btn btn-sm', method: :put do - %i.fa.fa-plus + = icon('plus') Enable - else - if deploy_key.destroyed_when_orphaned? && deploy_key.almost_orphaned? = link_to 'Remove', disable_namespace_project_deploy_key_path(@project.namespace, @project, deploy_key), data: { confirm: 'You are going to remove deploy key. Are you sure?'}, method: :put, class: "btn btn-remove delete-key btn-sm pull-right" - else = link_to disable_namespace_project_deploy_key_path(@project.namespace, @project, deploy_key), class: 'btn btn-sm', method: :put do - %i.fa.fa-power-off + = icon('power-off') Disable - - if project = project_for_deploy_key(deploy_key) - = link_to namespace_project_deploy_key_path(project.namespace, project, deploy_key) do - %i.fa.fa-key - %strong= deploy_key.title - - else - %i.fa.fa-key - %strong= deploy_key.title - + = icon('key') + %strong= deploy_key.title + %br + %code.key-fingerprint= deploy_key.fingerprint %p.light.prepend-top-10 - if deploy_key.public? diff --git a/app/views/projects/deploy_keys/show.html.haml b/app/views/projects/deploy_keys/show.html.haml deleted file mode 100644 index 7d44652af72..00000000000 --- a/app/views/projects/deploy_keys/show.html.haml +++ /dev/null @@ -1,14 +0,0 @@ -- page_title @key.title, "Deploy Keys" -%h3.page-title - Deploy key: - = @key.title - %small - created on - = @key.created_at.stamp("Aug 21, 2011") -.back-link - = link_to namespace_project_deploy_keys_path(@project.namespace, @project) do - ← To keys list -%hr -%pre= @key.key -.pull-right - = link_to 'Remove', namespace_project_deploy_key_path(@project.namespace, @project, @key), data: { confirm: 'Are you sure?'}, method: :delete, class: "btn-remove btn delete-key" diff --git a/config/routes.rb b/config/routes.rb index b7380254abb..f4a104664f3 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -165,7 +165,7 @@ Gitlab::Application.routes.draw do end end - resources :deploy_keys, only: [:index, :show, :new, :create, :destroy] + resources :deploy_keys, only: [:index, :new, :create, :destroy] resources :hooks, only: [:index, :create, :destroy] do get :test @@ -421,7 +421,7 @@ Gitlab::Application.routes.draw do end end - resources :deploy_keys, constraints: { id: /\d+/ }, only: [:index, :show, :new, :create] do + resources :deploy_keys, constraints: { id: /\d+/ }, only: [:index, :new, :create] do member do put :enable put :disable diff --git a/doc/install/installation.md b/doc/install/installation.md index 1db2b438292..badea4de214 100644 --- a/doc/install/installation.md +++ b/doc/install/installation.md @@ -241,10 +241,7 @@ We recommend using a PostgreSQL database. For MySQL check [MySQL setup guide](da # Copy the example Rack attack config sudo -u git -H cp config/initializers/rack_attack.rb.example config/initializers/rack_attack.rb - # Configure Git global settings for git user, useful when editing via web - # Edit user.email according to what is set in gitlab.yml - sudo -u git -H git config --global user.name "GitLab" - sudo -u git -H git config --global user.email "example@example.com" + # Configure Git global settings for git user, used when editing via web editor sudo -u git -H git config --global core.autocrlf input # Configure Redis connection settings diff --git a/doc/raketasks/maintenance.md b/doc/raketasks/maintenance.md index 41a994f3f68..2aca91d5371 100644 --- a/doc/raketasks/maintenance.md +++ b/doc/raketasks/maintenance.md @@ -47,7 +47,6 @@ Git: /usr/bin/git Runs the following rake tasks: -- `gitlab:env:check` - `gitlab:gitlab_shell:check` - `gitlab:sidekiq:check` - `gitlab:app:check` @@ -147,7 +146,7 @@ Do you want to continue (yes/no)? yes ## Clear redis cache -If for some reason the dashboard shows wrong information you might want to +If for some reason the dashboard shows wrong information you might want to clear Redis' cache. For Omnibus-packages: diff --git a/doc/workflow/2fa.png b/doc/workflow/2fa.png Binary files differnew file mode 100644 index 00000000000..bbf415210d5 --- /dev/null +++ b/doc/workflow/2fa.png diff --git a/doc/workflow/2fa_auth.png b/doc/workflow/2fa_auth.png Binary files differnew file mode 100644 index 00000000000..4a4fbe68984 --- /dev/null +++ b/doc/workflow/2fa_auth.png diff --git a/doc/workflow/README.md b/doc/workflow/README.md index 0fca68f364e..89005e51958 100644 --- a/doc/workflow/README.md +++ b/doc/workflow/README.md @@ -11,7 +11,8 @@ - [Migrating from SVN to GitLab](migrating_from_svn.md) - [Project importing from GitHub to GitLab](import_projects_from_github.md) - [Project importing from GitLab.com to your private GitLab instance](import_projects_from_gitlab_com.md) +- [Two-factor Authentication (2FA)](two_factor_authentication.md) - [Protected branches](protected_branches.md) - [Change your time zone](timezone.md) - [Keyboard shortcuts](shortcuts.md) -- [Web Editor](web_editor.md)
\ No newline at end of file +- [Web Editor](web_editor.md) diff --git a/doc/workflow/two_factor_authentication.md b/doc/workflow/two_factor_authentication.md new file mode 100644 index 00000000000..8ac1ca4b351 --- /dev/null +++ b/doc/workflow/two_factor_authentication.md @@ -0,0 +1,65 @@ +# Two-factor Authentication (2FA) + +Two-factor Authentication (2FA) provides an additional level of security to your +GitLab account. Once enabled, in addition to supplying your username and +password to login, you'll be prompted for a code generated by an application on +your phone. + +By enabling 2FA, the only way someone other than you can log into your account +is to know your username and password *and* have access to your phone. + +## Enabling 2FA + +**In GitLab:** + +1. Log in to your GitLab account. +1. Go to your **Profile Settings**. +1. Go to **Account**. +1. Click **Enable Two-factor Authentication**. + +![Two-factor setup](2fa.png) + +**On your phone:** + +1. Install a compatible application. We recommend [Google Authenticator]. +1. In the application, add a new entry in one of two ways: + * Scan the code with your phone's camera to add the entry automatically. + * Enter the details provided to add the entry manually. + +**In GitLab:** + +1. Enter the six-digit pin number from the entry on your phone into the **Pin + code** field. +1. Click **Submit**. + +If the pin you entered was correct, you'll see a message indicating that +Two-factor Authentication has been enabled, and you'll be presented with a list +of recovery codes. + +## Recovery Codes + +Should you ever lose access to your phone, you can use one of the ten provided +backup codes to login to your account. We suggest copying or printing them for +storage in a safe place. **Each code can be used only once** to log in to your +account. + +If you lose the recovery codes or just want to generate new ones, you can do so +from the **Profile Settings** > **Acount** page where you first enabled 2FA. + +## Logging in with 2FA Enabled + +Logging in with 2FA enabled is only slightly different than a normal login. +Enter your username and password credentials as you normally would, and you'll +be presented with a second prompt for an authentication code. Enter the pin from +your phone's application or a recovery code to log in. + +![Two-factor authentication on sign in](2fa_auth.png) + +## Disabling 2FA + +1. Log in to your GitLab account. +1. Go to your **Profile Settings**. +1. Go to **Acount**. +1. Click **Disable Two-factor Authentication**. + +[Google Authenticator]: https://support.google.com/accounts/answer/1066447?hl=en diff --git a/features/admin/deploy_keys.feature b/features/admin/deploy_keys.feature index 9df47eb51fd..33439cd1e85 100644 --- a/features/admin/deploy_keys.feature +++ b/features/admin/deploy_keys.feature @@ -8,11 +8,6 @@ Feature: Admin Deploy Keys When I visit admin deploy keys page Then I should see all public deploy keys - Scenario: Deploy Keys show - When I visit admin deploy keys page - And I click on first deploy key - Then I should see deploy key details - Scenario: Deploy Keys new When I visit admin deploy keys page And I click 'New Deploy Key' diff --git a/features/steps/admin/deploy_keys.rb b/features/steps/admin/deploy_keys.rb index fb0b611762e..844837d177d 100644 --- a/features/steps/admin/deploy_keys.rb +++ b/features/steps/admin/deploy_keys.rb @@ -14,17 +14,6 @@ class Spinach::Features::AdminDeployKeys < Spinach::FeatureSteps end end - step 'I click on first deploy key' do - click_link DeployKey.are_public.first.title - end - - step 'I should see deploy key details' do - deploy_key = DeployKey.are_public.first - current_path.should == admin_deploy_key_path(deploy_key) - page.should have_content(deploy_key.title) - page.should have_content(deploy_key.key) - end - step 'I visit admin deploy key page' do visit admin_deploy_key_path(deploy_key) end diff --git a/lib/api/groups.rb b/lib/api/groups.rb index f768c750402..e88b6e31775 100644 --- a/lib/api/groups.rb +++ b/lib/api/groups.rb @@ -62,7 +62,7 @@ module API delete ":id" do group = find_group(params[:id]) authorize! :admin_group, group - group.destroy + DestroyGroupService.new(group, current_user).execute end # Transfer a project to the Group namespace diff --git a/lib/gitlab/backend/shell.rb b/lib/gitlab/backend/shell.rb index 530f9d93de4..172d4902add 100644 --- a/lib/gitlab/backend/shell.rb +++ b/lib/gitlab/backend/shell.rb @@ -244,6 +244,16 @@ module Gitlab end end + # Check if such directory exists in repositories. + # + # Usage: + # exists?('gitlab') + # exists?('gitlab/cookies.git') + # + def exists?(dir_name) + File.exists?(full_path(dir_name)) + end + protected def gitlab_shell_path @@ -264,10 +274,6 @@ module Gitlab File.join(repos_path, dir_name) end - def exists?(dir_name) - File.exists?(full_path(dir_name)) - end - def gitlab_shell_projects_path File.join(gitlab_shell_path, 'bin', 'gitlab-projects') end diff --git a/lib/tasks/gitlab/check.rake b/lib/tasks/gitlab/check.rake index 1a6303b6c82..75bd41f2838 100644 --- a/lib/tasks/gitlab/check.rake +++ b/lib/tasks/gitlab/check.rake @@ -1,7 +1,6 @@ namespace :gitlab do desc "GITLAB | Check the configuration of GitLab and its environment" - task check: %w{gitlab:env:check - gitlab:gitlab_shell:check + task check: %w{gitlab:gitlab_shell:check gitlab:sidekiq:check gitlab:ldap:check gitlab:app:check} @@ -14,6 +13,7 @@ namespace :gitlab do warn_user_is_not_gitlab start_checking "GitLab" + check_git_config check_database_config_exists check_database_is_not_sqlite check_migrations_are_up @@ -38,6 +38,36 @@ namespace :gitlab do # Checks ######################## + def check_git_config + print "Git configured with autocrlf=input? ... " + + options = { + "core.autocrlf" => "input" + } + + correct_options = options.map do |name, value| + run(%W(#{Gitlab.config.git.bin_path} config --global --get #{name})).try(:squish) == value + end + + if correct_options.all? + puts "yes".green + else + print "Trying to fix Git error automatically. ..." + + if auto_fix_git_config(options) + puts "Success".green + else + puts "Failed".red + try_fixing_it( + sudo_gitlab("\"#{Gitlab.config.git.bin_path}\" config --global core.autocrlf \"#{options["core.autocrlf"]}\"") + ) + for_more_information( + see_installation_guide_section "GitLab" + ) + end + end + end + def check_database_config_exists print "Database config exists? ... " @@ -298,58 +328,6 @@ namespace :gitlab do end end - - - namespace :env do - desc "GITLAB | Check the configuration of the environment" - task check: :environment do - warn_user_is_not_gitlab - start_checking "Environment" - - check_gitlab_git_config - - finished_checking "Environment" - end - - - # Checks - ######################## - - def check_gitlab_git_config - print "Git configured for #{gitlab_user} user? ... " - - options = { - "user.name" => "GitLab", - "user.email" => Gitlab.config.gitlab.email_from, - "core.autocrlf" => "input" - } - correct_options = options.map do |name, value| - run(%W(#{Gitlab.config.git.bin_path} config --global --get #{name})).try(:squish) == value - end - - if correct_options.all? - puts "yes".green - else - print "Trying to fix Git error automatically. ..." - if auto_fix_git_config(options) - puts "Success".green - else - puts "Failed".red - try_fixing_it( - sudo_gitlab("\"#{Gitlab.config.git.bin_path}\" config --global user.name \"#{options["user.name"]}\""), - sudo_gitlab("\"#{Gitlab.config.git.bin_path}\" config --global user.email \"#{options["user.email"]}\""), - sudo_gitlab("\"#{Gitlab.config.git.bin_path}\" config --global core.autocrlf \"#{options["core.autocrlf"]}\"") - ) - for_more_information( - see_installation_guide_section "GitLab" - ) - end - end - end - end - - - namespace :gitlab_shell do desc "GITLAB | Check the configuration of GitLab Shell" task check: :environment do diff --git a/lib/tasks/gitlab/task_helpers.rake b/lib/tasks/gitlab/task_helpers.rake index 14a130be2ca..c95b6540ebc 100644 --- a/lib/tasks/gitlab/task_helpers.rake +++ b/lib/tasks/gitlab/task_helpers.rake @@ -118,9 +118,9 @@ namespace :gitlab do # Returns true if all subcommands were successfull (according to their exit code) # Returns false if any or all subcommands failed. def auto_fix_git_config(options) - if !@warned_user_not_gitlab && options['user.email'] != 'example@example.com' # default email should be overridden? + if !@warned_user_not_gitlab command_success = options.map do |name, value| - system(%W(#{Gitlab.config.git.bin_path} config --global #{name} #{value})) + system(*%W(#{Gitlab.config.git.bin_path} config --global #{name} #{value})) end command_success.all? diff --git a/spec/features/projects_spec.rb b/spec/features/projects_spec.rb index 56523f6e1a8..f8eea70ec4a 100644 --- a/spec/features/projects_spec.rb +++ b/spec/features/projects_spec.rb @@ -47,13 +47,6 @@ feature 'Project' do it 'should remove project' do expect { remove_project }.to change {Project.count}.by(-1) end - - it 'should delete the project from disk' do - expect(GitlabShellWorker).to receive(:perform_async). - with(:remove_repository, /#{project.path_with_namespace}/).twice - - remove_project - end end def remove_project diff --git a/spec/requests/api/projects_spec.rb b/spec/requests/api/projects_spec.rb index 46cd26eb927..dbfd72e5f19 100644 --- a/spec/requests/api/projects_spec.rb +++ b/spec/requests/api/projects_spec.rb @@ -57,14 +57,14 @@ describe API::API, api: true do expect(json_response.first['name']).to eq(project.name) expect(json_response.first['owner']['username']).to eq(user.username) end - + it 'should include the project labels as the tag_list' do get api('/projects', user) response.status.should == 200 json_response.should be_an Array json_response.first.keys.should include('tag_list') end - + context 'and using search' do it 'should return searched project' do get api('/projects', user), { search: project.name } @@ -792,11 +792,6 @@ describe API::API, api: true do describe 'DELETE /projects/:id' do context 'when authenticated as user' do it 'should remove project' do - expect(GitlabShellWorker).to( - receive(:perform_async).with(:remove_repository, - /#{project.path_with_namespace}/) - ).twice - delete api("/projects/#{project.id}", user) expect(response.status).to eq(200) end diff --git a/spec/routing/project_routing_spec.rb b/spec/routing/project_routing_spec.rb index 3a0d9b88d75..0040718d9be 100644 --- a/spec/routing/project_routing_spec.rb +++ b/spec/routing/project_routing_spec.rb @@ -172,7 +172,7 @@ end # DELETE /:project_id/deploy_keys/:id(.:format) deploy_keys#destroy describe Projects::DeployKeysController, 'routing' do it_behaves_like 'RESTful project resources' do - let(:actions) { [:index, :show, :new, :create] } + let(:actions) { [:index, :new, :create] } let(:controller) { 'deploy_keys' } end end diff --git a/spec/services/destroy_group_service_spec.rb b/spec/services/destroy_group_service_spec.rb new file mode 100644 index 00000000000..24e439503e7 --- /dev/null +++ b/spec/services/destroy_group_service_spec.rb @@ -0,0 +1,44 @@ +require 'spec_helper' + +describe DestroyGroupService do + let!(:user) { create(:user) } + let!(:group) { create(:group) } + let!(:project) { create(:project, namespace: group) } + let!(:gitlab_shell) { Gitlab::Shell.new } + let!(:remove_path) { group.path + "+#{group.id}+deleted" } + + context 'database records' do + before do + destroy_group(group, user) + end + + it { Group.all.should_not include(group) } + it { Project.all.should_not include(project) } + end + + context 'file system' do + context 'Sidekiq inline' do + before do + # Run sidekiq immediatly to check that renamed dir will be removed + Sidekiq::Testing.inline! { destroy_group(group, user) } + end + + it { gitlab_shell.exists?(group.path).should be_falsey } + it { gitlab_shell.exists?(remove_path).should be_falsey } + end + + context 'Sidekiq fake' do + before do + # Dont run sidekiq to check if renamed repository exists + Sidekiq::Testing.fake! { destroy_group(group, user) } + end + + it { gitlab_shell.exists?(group.path).should be_falsey } + it { gitlab_shell.exists?(remove_path).should be_truthy } + end + end + + def destroy_group(group, user) + DestroyGroupService.new(group, user).execute + end +end diff --git a/spec/services/projects/destroy_service_spec.rb b/spec/services/projects/destroy_service_spec.rb new file mode 100644 index 00000000000..cdf576cc0c1 --- /dev/null +++ b/spec/services/projects/destroy_service_spec.rb @@ -0,0 +1,34 @@ +require 'spec_helper' + +describe Projects::DestroyService do + let!(:user) { create(:user) } + let!(:project) { create(:project, namespace: user.namespace) } + let!(:path) { project.repository.path_to_repo } + let!(:remove_path) { path.sub(/\.git\Z/, "+#{project.id}+deleted.git") } + + context 'Sidekiq inline' do + before do + # Run sidekiq immediatly to check that renamed repository will be removed + Sidekiq::Testing.inline! { destroy_project(project, user, {}) } + end + + it { Project.all.should_not include(project) } + it { Dir.exists?(path).should be_falsey } + it { Dir.exists?(remove_path).should be_falsey } + end + + context 'Sidekiq fake' do + before do + # Dont run sidekiq to check if renamed repository exists + Sidekiq::Testing.fake! { destroy_project(project, user, {}) } + end + + it { Project.all.should_not include(project) } + it { Dir.exists?(path).should be_falsey } + it { Dir.exists?(remove_path).should be_truthy } + end + + def destroy_project(project, user, params) + Projects::DestroyService.new(project, user, params).execute + end +end |