diff --git a/Gemfile b/Gemfile index 49fbcad04fcdbb0d9a46c79e9185e10013c00f33..375929a7444ef14e467a29a09863b40ffaf6ae29 100644 --- a/Gemfile +++ b/Gemfile @@ -8,7 +8,7 @@ def linux_only(require_as) RUBY_PLATFORM.include?('linux') && require_as end -gem "rails", "3.2.9" +gem "rails", "3.2.11" # Supported DBs gem "mysql2", group: :mysql diff --git a/Gemfile.lock b/Gemfile.lock index d8be14ba80ab191d6001e601026d27cdfa8fbb54..bf14bd93d7cc4e03e0592e84bdf257f4ad79daac 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -81,12 +81,12 @@ GIT GEM remote: http://rubygems.org/ specs: - actionmailer (3.2.9) - actionpack (= 3.2.9) + actionmailer (3.2.11) + actionpack (= 3.2.11) mail (~> 2.4.4) - actionpack (3.2.9) - activemodel (= 3.2.9) - activesupport (= 3.2.9) + actionpack (3.2.11) + activemodel (= 3.2.11) + activesupport (= 3.2.11) builder (~> 3.0.0) erubis (~> 2.7.0) journey (~> 1.0.4) @@ -94,18 +94,18 @@ GEM rack-cache (~> 1.2) rack-test (~> 0.6.1) sprockets (~> 2.2.1) - activemodel (3.2.9) - activesupport (= 3.2.9) + activemodel (3.2.11) + activesupport (= 3.2.11) builder (~> 3.0.0) - activerecord (3.2.9) - activemodel (= 3.2.9) - activesupport (= 3.2.9) + activerecord (3.2.11) + activemodel (= 3.2.11) + activesupport (= 3.2.11) arel (~> 3.0.2) tzinfo (~> 0.3.29) - activeresource (3.2.9) - activemodel (= 3.2.9) - activesupport (= 3.2.9) - activesupport (3.2.9) + activeresource (3.2.11) + activemodel (= 3.2.11) + activesupport (= 3.2.11) + activesupport (3.2.11) i18n (~> 0.6) multi_json (~> 1.0) acts-as-taggable-on (2.3.3) @@ -240,7 +240,7 @@ GEM jquery-ui-rails (2.0.2) jquery-rails railties (>= 3.1.0) - json (1.7.5) + json (1.7.6) jwt (0.1.5) multi_json (>= 1.0) kaminari (0.14.1) @@ -264,7 +264,7 @@ GEM mime-types (1.19) modernizr (2.6.2) sprockets (~> 2.0) - multi_json (1.3.7) + multi_json (1.5.0) multi_xml (0.5.1) multipart-post (1.1.5) mysql2 (0.3.11) @@ -306,7 +306,7 @@ GEM pyu-ruby-sasl (0.0.3.3) quiet_assets (1.0.1) railties (~> 3.1) - rack (1.4.1) + rack (1.4.3) rack-accept (0.4.5) rack (>= 0.4) rack-cache (1.2) @@ -321,26 +321,26 @@ GEM rack rack-test (0.6.2) rack (>= 1.0) - rails (3.2.9) - actionmailer (= 3.2.9) - actionpack (= 3.2.9) - activerecord (= 3.2.9) - activeresource (= 3.2.9) - activesupport (= 3.2.9) + rails (3.2.11) + actionmailer (= 3.2.11) + actionpack (= 3.2.11) + activerecord (= 3.2.11) + activeresource (= 3.2.11) + activesupport (= 3.2.11) bundler (~> 1.0) - railties (= 3.2.9) + railties (= 3.2.11) rails-dev-tweaks (0.6.1) actionpack (~> 3.1) railties (~> 3.1) - railties (3.2.9) - actionpack (= 3.2.9) - activesupport (= 3.2.9) + railties (3.2.11) + actionpack (= 3.2.11) + activesupport (= 3.2.11) rack-ssl (~> 1.3.2) rake (>= 0.8.7) rdoc (~> 3.4) thor (>= 0.14.6, < 2.0) raindrops (0.10.0) - rake (10.0.1) + rake (10.0.3) raphael-rails (1.5.2) rb-fsevent (0.9.2) rb-inotify (0.8.8) @@ -411,7 +411,7 @@ GEM capybara (~> 1) railties (>= 3) spinach (>= 0.4) - sprockets (2.2.1) + sprockets (2.2.2) hike (~> 1.2) multi_json (~> 1.0) rack (~> 1.0) @@ -506,7 +506,7 @@ DEPENDENCIES pygments.rb! quiet_assets (~> 1.0.1) rack-mini-profiler - rails (= 3.2.9) + rails (= 3.2.11) rails-dev-tweaks raphael-rails (= 1.5.2) rb-fsevent diff --git a/VERSION b/VERSION index fcdb2e109f68cff5600955a73908885fe8599bb4..1454f6ed4b751b190ba93ad2c721979cc0977fbc 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -4.0.0 +4.0.1 diff --git a/app/models/namespace.rb b/app/models/namespace.rb index 8c90f5aee26cb84f8c7053009eddc1fe8623e33b..d34e5a99c796ac8024baca26bbe92bb723b15706 100644 --- a/app/models/namespace.rb +++ b/app/models/namespace.rb @@ -27,10 +27,13 @@ class Namespace < ActiveRecord::Base after_create :ensure_dir_exist after_update :move_dir + after_commit :update_gitolite, on: :update, if: :require_update_gitolite after_destroy :rm_dir scope :root, where('type IS NULL') + attr_accessor :require_update_gitolite + def self.search query where("name LIKE :query OR path LIKE :query", query: "%#{query}%") end @@ -48,8 +51,17 @@ class Namespace < ActiveRecord::Base end def ensure_dir_exist - namespace_dir_path = File.join(Gitlab.config.gitolite.repos_path, path) - system("mkdir -m 770 #{namespace_dir_path}") unless File.exists?(namespace_dir_path) + unless dir_exists? + system("mkdir -m 770 #{namespace_full_path}") + end + end + + def dir_exists? + File.exists?(namespace_full_path) + end + + def namespace_full_path + @namespace_full_path ||= File.join(Gitlab.config.gitolite.repos_path, path) end def move_dir @@ -62,10 +74,18 @@ class Namespace < ActiveRecord::Base if system("mv #{old_path} #{new_path}") send_update_instructions + @require_update_gitolite = true + else + raise "Namespace move error #{old_path} #{new_path}" end end end + def update_gitolite + @require_update_gitolite = false + projects.each(&:update_repository) + end + def rm_dir dir_path = File.join(Gitlab.config.gitolite.repos_path, path) system("rm -rf #{dir_path}") diff --git a/app/observers/user_observer.rb b/app/observers/user_observer.rb index 09b3c1d622fe9033991bb244b00f292677daf795..73a1d00ca3bf6f647b3c8ddaa9e26477c1cd6936 100644 --- a/app/observers/user_observer.rb +++ b/app/observers/user_observer.rb @@ -14,7 +14,7 @@ class UserObserver < ActiveRecord::Observer if user.namespace user.namespace.update_attributes(path: user.username) else - user.create_namespace!(path: user.username, name: user.name) + user.create_namespace!(path: user.username, name: user.username) end end end diff --git a/app/roles/namespaced_project.rb b/app/roles/namespaced_project.rb index 8656890a45690557413b9b6e440ef2bc2bc3e357..dbd533f84947c308d0dcc546eeb46156bb8c637a 100644 --- a/app/roles/namespaced_project.rb +++ b/app/roles/namespaced_project.rb @@ -24,7 +24,7 @@ module NamespacedProject save! end rescue Gitlab::ProjectMover::ProjectMoveError => ex - raise TransferError.new(ex.message) + raise Project::TransferError.new(ex.message) end def name_with_namespace diff --git a/app/views/issues/show.html.haml b/app/views/issues/show.html.haml index 1d4d6a13c2bb33efa7c780e02d307623e95b81e2..7996c317548a5a597a5bb3fc910c6c92c13027e2 100644 --- a/app/views/issues/show.html.haml +++ b/app/views/issues/show.html.haml @@ -6,6 +6,10 @@ = @issue.created_at.stamp("Aug 21, 2011") %span.right + - if can? current_user, :write_issue, @project + = link_to new_project_issue_path(@project, issue: { assignee_id: params[:assignee_id], milestone_id: params[:milestone_id]}), class: "btn grouped" do + %i.icon-plus + New Issue - if can?(current_user, :admin_project, @project) || @issue.author == current_user - if @issue.closed = link_to 'Reopen', project_issue_path(@project, @issue, issue: {closed: false }, status_only: true), method: :put, class: "btn grouped reopen_issue" diff --git a/app/views/layouts/group.html.haml b/app/views/layouts/group.html.haml index d40d9525bb89d42edac9cb70cff303e6822382c0..f47e8b3e9ff882c0fb32392608a1f1c9dad12034 100644 --- a/app/views/layouts/group.html.haml +++ b/app/views/layouts/group.html.haml @@ -15,7 +15,7 @@ = nav_link(path: 'groups#merge_requests') do = link_to merge_requests_group_path(@group) do Merge Requests - %span.count= current_user.cared_merge_requests.of_group(@group).count + %span.count= current_user.cared_merge_requests.opened.of_group(@group).count = nav_link(path: 'groups#search') do = link_to "Search", search_group_path(@group) = nav_link(path: 'groups#people') do diff --git a/app/views/notes/_common_form.html.haml b/app/views/notes/_common_form.html.haml index d76be75bc273a43ef7b90d104b3213845c3c62e6..ae5d72504218c57f24c1be0a8ff7fa5295d2cd3a 100644 --- a/app/views/notes/_common_form.html.haml +++ b/app/views/notes/_common_form.html.haml @@ -22,12 +22,12 @@ .span4.notify_opts %h6.left Notify via email: = label_tag :notify do - = check_box_tag :notify, 1, @note.noteable_type != "Commit" + = check_box_tag :notify, 1, false %span Project team - if @note.notify_only_author?(current_user) = label_tag :notify_author do - = check_box_tag :notify_author, 1 , @note.noteable_type == "Commit" + = check_box_tag :notify_author, 1 , false %span Commit author .span5.attachments %h6.left Attachment: diff --git a/app/views/notes/_per_line_form.html.haml b/app/views/notes/_per_line_form.html.haml index ff80ad4e0d52d9fd279b70154f6afb29fc9a2413..ce391dccae7d2764bb9d4ad9ab3417c610c7e9d7 100644 --- a/app/views/notes/_per_line_form.html.haml +++ b/app/views/notes/_per_line_form.html.haml @@ -23,12 +23,12 @@ %h6.left Notify via email: .labels = label_tag :notify do - = check_box_tag :notify, 1, @note.noteable_type != "Commit" + = check_box_tag :notify, 1, false %span Project team - if @note.notify_only_author?(current_user) = label_tag :notify_author do - = check_box_tag :notify_author, 1 , @note.noteable_type == "Commit" + = check_box_tag :notify_author, 1 , false %span Commit author :javascript diff --git a/config/gitlab.yml.example b/config/gitlab.yml.example index f47625eb132ab304a71e35bf2ccf998fbe413c1f..3aac21d3771062183cb467a9316f32311a6d981e 100644 --- a/config/gitlab.yml.example +++ b/config/gitlab.yml.example @@ -89,6 +89,7 @@ backup: ## Gitolite settings gitolite: admin_uri: git@localhost:gitolite-admin + # repos_path must not be a symlink repos_path: /home/git/repositories/ hooks_path: /home/git/.gitolite/hooks/ admin_key: gitlab diff --git a/config/initializers/1_settings.rb b/config/initializers/1_settings.rb index 4fe3ced4d8d1f7021a4e8cc8064a1ceaf74d65bc..08ea63f7f8d891c4f462f777ad125d7391c3b1e3 100644 --- a/config/initializers/1_settings.rb +++ b/config/initializers/1_settings.rb @@ -324,7 +324,7 @@ Settings.gitlab['email_from'] ||= Settings.pre_40_config ? Settings.email_from : Settings.gitlab['url'] ||= Settings.pre_40_config ? Settings.url : Settings.send(:build_gitlab_url) Settings['gravatar'] ||= Settingslogic.new({}) -Settings.gravatar['enabled'] ||= Settings.pre_40_config ? !Settings.disable_gravatar? : true +Settings.gravatar['enabled'] = Settings.pre_40_config ? !Settings.disable_gravatar? : true if Settings.gravatar['enabled'].nil? Settings.gravatar['plain_url'] ||= Settings.pre_40_config ? Settings.gravatar_url : 'http://www.gravatar.com/avatar/%{hash}?s=%{size}&d=mm' Settings.gravatar['ssl_url'] ||= Settings.pre_40_config ? Settings.gravatar_ssl_url : 'https://secure.gravatar.com/avatar/%{hash}?s=%{size}&d=mm' diff --git a/config/initializers/4_resque.rb b/config/initializers/4_resque.rb index 419dbe0606107554236ba85e1abd556bb03c1dfa..03c2b785fae43020336982a7645ee31f15021fcd 100644 --- a/config/initializers/4_resque.rb +++ b/config/initializers/4_resque.rb @@ -27,3 +27,5 @@ Resque::Server.use Authentication # Mailer Resque::Mailer.excluded_environments = [] + +Resque.before_fork = Proc.new { ActiveRecord::Base.establish_connection } diff --git a/db/migrate/20121218164840_move_noteable_commit_to_own_field.rb b/db/migrate/20121218164840_move_noteable_commit_to_own_field.rb index 6f2da4136a3cad9623e68ce7c6021abbe3358ad2..f6b97390b938cee842fd26d6b95b57dbfe031df3 100644 --- a/db/migrate/20121218164840_move_noteable_commit_to_own_field.rb +++ b/db/migrate/20121218164840_move_noteable_commit_to_own_field.rb @@ -5,7 +5,7 @@ class MoveNoteableCommitToOwnField < ActiveRecord::Migration Note.where(noteable_type: 'Commit').update_all('commit_id = noteable_id') if ActiveRecord::Base.connection.adapter_name == 'PostgreSQL' - Note.where("noteable_type != 'Commit'").update_all('new_noteable_id = CAST (noteable_id AS INTEGER)') + Note.where("noteable_type != 'Commit'").update_all('new_noteable_id = CAST (CASE noteable_id WHEN \'\' THEN NULL ELSE noteable_id END AS INTEGER)') else Note.where("noteable_type != 'Commit'").update_all('new_noteable_id = noteable_id') end diff --git a/doc/install/installation.md b/doc/install/installation.md index 718e4cf6419ad367b1d96b8fcdbc1b12115865ea..26cfc4a112494cafa25384978fa37149490e5f28 100644 --- a/doc/install/installation.md +++ b/doc/install/installation.md @@ -270,33 +270,33 @@ used for the `email.from` setting in `config/gitlab.yml`) sudo -u gitlab -H bundle exec rake gitlab:app:setup RAILS_ENV=production -## Check Application Status +## Install Init Script -Check if GitLab and its environment is configured correctly: +Download the init script (will be /etc/init.d/gitlab): - sudo -u gitlab -H bundle exec rake gitlab:env:info RAILS_ENV=production + sudo wget https://raw.github.com/gitlabhq/gitlab-recipes/4-0-stable/init.d/gitlab -P /etc/init.d/ + sudo chmod +x /etc/init.d/gitlab -To make sure you didn't miss anything run a more thorough check with: +Make GitLab start on boot: - sudo -u gitlab -H bundle exec rake gitlab:check RAILS_ENV=production + sudo update-rc.d gitlab defaults 21 -If you are all green: congratulations, you successfully installed GitLab! -Although this is the case, there are still a few steps to go. +## Check Application Status -## Install Init Script +Check if GitLab and its environment is configured correctly: -Download the init script (will be /etc/init.d/gitlab): + sudo -u gitlab -H bundle exec rake gitlab:env:info RAILS_ENV=production - sudo wget https://raw.github.com/gitlabhq/gitlab-recipes/master/init.d/gitlab -P /etc/init.d/ - sudo chmod +x /etc/init.d/gitlab +To make sure you didn't miss anything run a more thorough check with: -Make GitLab start on boot: + sudo -u gitlab -H bundle exec rake gitlab:check RAILS_ENV=production - sudo update-rc.d gitlab defaults 21 +If all items are green, then congratulations on successfully installing GitLab! +However there are still a few steps left. -Start your GitLab instance: +## Start Your GitLab Instance sudo service gitlab start # or @@ -316,7 +316,7 @@ If you can't or don't want to use Nginx as your web server, have a look at the Download an example site config: - sudo wget https://raw.github.com/gitlabhq/gitlab-recipes/master/nginx/gitlab -P /etc/nginx/sites-available/ + sudo wget https://raw.github.com/gitlabhq/gitlab-recipes/4-0-stable/nginx/gitlab -P /etc/nginx/sites-available/ sudo ln -s /etc/nginx/sites-available/gitlab /etc/nginx/sites-enabled/gitlab Make sure to edit the config file to match your setup: diff --git a/lib/tasks/gitlab/check.rake b/lib/tasks/gitlab/check.rake index 5f1ed080fa582d95ed9e7bdc5afef2504660ba3a..9cf021717c69a80f1a8cda91fcf0dca4abf58391 100644 --- a/lib/tasks/gitlab/check.rake +++ b/lib/tasks/gitlab/check.rake @@ -48,7 +48,7 @@ namespace :gitlab do see_database_guide, "http://guides.rubyonrails.org/getting_started.html#configuring-a-database" ) - check_failed + fix_and_rerun end end @@ -65,7 +65,7 @@ namespace :gitlab do "https://github.com/gitlabhq/gitlabhq/wiki/Migrate-from-SQLite-to-MySQL", see_database_guide ) - check_failed + fix_and_rerun end end @@ -85,7 +85,7 @@ namespace :gitlab do for_more_information( see_installation_guide_section "GitLab" ) - check_failed + fix_and_rerun end end @@ -98,7 +98,7 @@ namespace :gitlab do end # omniauth or ldap could have been deleted from the file - unless Gitlab.config.pre_40_config + unless Gitlab.config['git_host'] puts "no".green else puts "yes".red @@ -110,7 +110,7 @@ namespace :gitlab do for_more_information( see_installation_guide_section "GitLab" ) - check_failed + fix_and_rerun end end @@ -129,7 +129,7 @@ namespace :gitlab do for_more_information( see_installation_guide_section "Install Init Script" ) - check_failed + fix_and_rerun end end @@ -142,7 +142,7 @@ namespace :gitlab do return end - recipe_content = `curl https://raw.github.com/gitlabhq/gitlab-recipes/master/init.d/gitlab 2>/dev/null` + recipe_content = `curl https://raw.github.com/gitlabhq/gitlab-recipes/4-0-stable/init.d/gitlab 2>/dev/null` script_content = File.read(script_path) if recipe_content == script_content @@ -155,7 +155,7 @@ namespace :gitlab do for_more_information( see_installation_guide_section "Install Init Script" ) - check_failed + fix_and_rerun end end @@ -169,9 +169,9 @@ namespace :gitlab do else puts "no".red try_fixing_it( - "sudo -u gitlab -H bundle exec rake db:migrate" + "sudo -u gitlab -H bundle exec rake db:migrate RAILS_ENV=production" ) - check_failed + fix_and_rerun end end @@ -194,14 +194,14 @@ namespace :gitlab do else puts "no".red try_fixing_it( - "sudo -u gitlab -H bundle exec rake gitlab:satellites:create", + "sudo -u gitlab -H bundle exec rake gitlab:satellites:create RAILS_ENV=production", "If necessary, remove the tmp/repo_satellites directory ...", "... and rerun the above command" ) for_more_information( "doc/raketasks/maintenance.md " ) - check_failed + fix_and_rerun end end end @@ -222,7 +222,7 @@ namespace :gitlab do for_more_information( see_installation_guide_section "GitLab" ) - check_failed + fix_and_rerun end end @@ -242,7 +242,7 @@ namespace :gitlab do for_more_information( see_installation_guide_section "GitLab" ) - check_failed + fix_and_rerun end end end @@ -256,7 +256,7 @@ namespace :gitlab do start_checking "Environment" check_gitlab_in_git_group - check_issue_1056_shell_profile_error + check_issue_1059_shell_profile_error check_gitlab_git_config check_python2_exists check_python2_version @@ -290,7 +290,7 @@ namespace :gitlab do for_more_information( see_installation_guide_section "GitLab" ) - check_failed + fix_and_rerun end end @@ -308,16 +308,16 @@ namespace :gitlab do for_more_information( see_installation_guide_section "System Users" ) - check_failed + fix_and_rerun end end # see https://github.com/gitlabhq/gitlabhq/issues/1059 - def check_issue_1056_shell_profile_error + def check_issue_1059_shell_profile_error gitolite_ssh_user = Gitlab.config.gitolite.ssh_user print "Has no \"-e\" in ~#{gitolite_ssh_user}/.profile ... " - profile_file = File.join(gitolite_home, ".profile") + profile_file = File.join(gitolite_user_home, ".profile") unless File.read(profile_file) =~ /^-e PATH/ puts "yes".green @@ -332,7 +332,7 @@ namespace :gitlab do see_installation_guide_section("Gitolite"), "https://github.com/gitlabhq/gitlabhq/issues/1059" ) - check_failed + fix_and_rerun end end @@ -352,7 +352,7 @@ namespace :gitlab do for_more_information( see_installation_guide_section "Packages / Dependencies" ) - check_failed + fix_and_rerun end end @@ -378,7 +378,7 @@ namespace :gitlab do for_more_information( see_installation_guide_section "Packages / Dependencies" ) - check_failed + fix_and_rerun end end end @@ -398,6 +398,7 @@ namespace :gitlab do check_dot_gitolite_user_and_group check_dot_gitolite_permissions check_repo_base_exists + check_repo_base_is_not_symlink check_repo_base_user_and_group check_repo_base_permissions check_can_clone_gitolite_admin @@ -434,7 +435,7 @@ namespace :gitlab do for_more_information( see_installation_guide_section "Gitolite" ) - check_failed + fix_and_rerun end # assumes #check_can_clone_gitolite_admin has been run before @@ -466,7 +467,7 @@ namespace :gitlab do for_more_information( see_installation_guide_section "Gitolite" ) - check_failed + fix_and_rerun ensure FileUtils.rm_rf("/tmp/gitolite_gitlab_test") end @@ -474,7 +475,7 @@ namespace :gitlab do def check_dot_gitolite_exists print "Config directory exists? ... " - gitolite_config_path = File.join(gitolite_home, ".gitolite") + gitolite_config_path = File.join(gitolite_user_home, ".gitolite") if File.directory?(gitolite_config_path) puts "yes".green @@ -488,20 +489,20 @@ namespace :gitlab do for_more_information( see_installation_guide_section "Gitolite" ) - check_failed + fix_and_rerun end end def check_dot_gitolite_permissions print "Config directory access is drwxr-x---? ... " - gitolite_config_path = File.join(gitolite_home, ".gitolite") + gitolite_config_path = File.join(gitolite_user_home, ".gitolite") unless File.exists?(gitolite_config_path) puts "can't check because of previous errors".magenta return end - if `stat --printf %a #{gitolite_config_path}` == "750" + if File.stat(gitolite_config_path).mode.to_s(8).ends_with?("750") puts "yes".green else puts "no".red @@ -511,7 +512,7 @@ namespace :gitlab do for_more_information( see_installation_guide_section "Gitolite" ) - check_failed + fix_and_rerun end end @@ -519,31 +520,30 @@ namespace :gitlab do gitolite_ssh_user = Gitlab.config.gitolite.ssh_user print "Config directory owned by #{gitolite_ssh_user}:#{gitolite_ssh_user} ... " - gitolite_config_path = File.join(gitolite_home, ".gitolite") + gitolite_config_path = File.join(gitolite_user_home, ".gitolite") unless File.exists?(gitolite_config_path) puts "can't check because of previous errors".magenta return end - if `stat --printf %U #{gitolite_config_path}` == gitolite_ssh_user && # user - `stat --printf %G #{gitolite_config_path}` == gitolite_ssh_user #group + if File.stat(gitolite_config_path).uid == uid_for(gitolite_ssh_user) && + File.stat(gitolite_config_path).gid == gid_for(gitolite_ssh_user) puts "yes".green else puts "no".red - puts "#{gitolite_config_path} is not owned by #{gitolite_ssh_user}".red try_fixing_it( "sudo chown -R #{gitolite_ssh_user}:#{gitolite_ssh_user} #{gitolite_config_path}" ) for_more_information( see_installation_guide_section "Gitolite" ) - check_failed + fix_and_rerun end end def check_gitolite_is_up_to_date print "Using recommended version ... " - if gitolite_version.try(:start_with?, "v3.04") + if gitolite_version.try(:start_with?, "v3.2") puts "yes".green else puts "no".red @@ -558,7 +558,7 @@ namespace :gitlab do end def check_gitoliterc_git_config_keys - gitoliterc_path = File.join(gitolite_home, ".gitolite.rc") + gitoliterc_path = File.join(gitolite_user_home, ".gitolite.rc") print "Allow all Git config keys in .gitolite.rc ... " option_name = if has_gitolite3? @@ -567,7 +567,7 @@ namespace :gitlab do else # assume older version # see https://github.com/sitaramc/gitolite/blob/v2.3/conf/example.gitolite.rc#L49 - "$GL_GITCONFIG_KEYS" + "\\$GL_GITCONFIG_KEYS" end option_value = ".*" if open(gitoliterc_path).grep(/#{option_name}\s*=[>]?\s*["']#{option_value}["']/).any? @@ -582,12 +582,12 @@ namespace :gitlab do for_more_information( see_installation_guide_section "Gitolite" ) - check_failed + fix_and_rerun end end def check_gitoliterc_repo_umask - gitoliterc_path = File.join(gitolite_home, ".gitolite.rc") + gitoliterc_path = File.join(gitolite_user_home, ".gitolite.rc") print "Repo umask is 0007 in .gitolite.rc? ... " option_name = if has_gitolite3? @@ -596,7 +596,7 @@ namespace :gitlab do else # assume older version # see https://github.com/sitaramc/gitolite/blob/v2.3/conf/example.gitolite.rc#L32 - "$REPO_UMASK" + "\\$REPO_UMASK" end option_value = "0007" if open(gitoliterc_path).grep(/#{option_name}\s*=[>]?\s*#{option_value}/).any? @@ -611,7 +611,7 @@ namespace :gitlab do for_more_information( see_installation_guide_section "Gitolite" ) - check_failed + fix_and_rerun end end @@ -635,7 +635,7 @@ namespace :gitlab do for_more_information( see_installation_guide_section "Setup GitLab Hooks" ) - check_failed + fix_and_rerun end end @@ -666,7 +666,7 @@ namespace :gitlab do for_more_information( see_installation_guide_section "Setup GitLab Hooks" ) - check_failed + fix_and_rerun end end @@ -688,7 +688,27 @@ namespace :gitlab do for_more_information( see_installation_guide_section "Gitolite" ) - check_failed + fix_and_rerun + end + end + + def check_repo_base_is_not_symlink + print "Repo base directory is a symlink? ... " + + repo_base_path = Gitlab.config.gitolite.repos_path + unless File.exists?(repo_base_path) + puts "can't check because of previous errors".magenta + return + end + + unless File.symlink?(repo_base_path) + puts "no".green + else + puts "yes".red + try_fixing_it( + "Make sure it's set to the real directory in config/gitlab.yml" + ) + fix_and_rerun end end @@ -701,18 +721,17 @@ namespace :gitlab do return end - if `stat --printf %a #{repo_base_path}` == "6770" + if File.stat(repo_base_path).mode.to_s(8).ends_with?("6770") puts "yes".green else puts "no".red - puts "#{repo_base_path} is not writable".red try_fixing_it( "sudo chmod -R ug+rwXs,o-rwx #{repo_base_path}" ) for_more_information( see_installation_guide_section "Gitolite" ) - check_failed + fix_and_rerun end end @@ -726,19 +745,18 @@ namespace :gitlab do return end - if `stat --printf %U #{repo_base_path}` == gitolite_ssh_user && # user - `stat --printf %G #{repo_base_path}` == gitolite_ssh_user #group + if File.stat(repo_base_path).uid == uid_for(gitolite_ssh_user) && + File.stat(repo_base_path).gid == gid_for(gitolite_ssh_user) puts "yes".green else puts "no".red - puts "#{repo_base_path} is not owned by #{gitolite_ssh_user}".red try_fixing_it( "sudo chown -R #{gitolite_ssh_user}:#{gitolite_ssh_user} #{repo_base_path}" ) for_more_information( see_installation_guide_section "Gitolite" ) - check_failed + fix_and_rerun end end @@ -767,12 +785,12 @@ namespace :gitlab do else puts "wrong or missing".red try_fixing_it( - "sudo -u gitlab -H bundle exec rake gitlab:gitolite:update_repos" + "sudo -u gitlab -H bundle exec rake gitlab:gitolite:update_repos RAILS_ENV=production" ) for_more_information( "doc/raketasks/maintenance.md" ) - check_failed + fix_and_rerun end end end @@ -808,11 +826,12 @@ namespace :gitlab do for_more_information( "lib/support/rewrite-hooks.sh" ) - check_failed + fix_and_rerun next end - if run_and_match("stat --format %N #{project_hook_file}", /#{hook_file}.+->.+#{gitolite_hook_file}/) + if File.lstat(project_hook_file).symlink? && + File.realpath(project_hook_file) == File.realpath(gitolite_hook_file) puts "ok".green else puts "not a link to Gitolite's hook".red @@ -822,7 +841,7 @@ namespace :gitlab do for_more_information( "lib/support/rewrite-hooks.sh" ) - check_failed + fix_and_rerun end end end @@ -831,12 +850,12 @@ namespace :gitlab do # Helper methods ######################## - def gitolite_home + def gitolite_user_home File.expand_path("~#{Gitlab.config.gitolite.ssh_user}") end def gitolite_version - gitolite_version_file = "#{gitolite_home}/gitolite/src/VERSION" + gitolite_version_file = "#{gitolite_user_home}/gitolite/src/VERSION" if File.readable?(gitolite_version_file) File.read(gitolite_version_file) end @@ -880,7 +899,7 @@ namespace :gitlab do see_installation_guide_section("Install Init Script"), "see log/resque.log for possible errors" ) - check_failed + fix_and_rerun end end end @@ -889,7 +908,7 @@ namespace :gitlab do # Helper methods ########################## - def check_failed + def fix_and_rerun puts " Please #{"fix the error above"} and rerun the checks.".red end @@ -908,29 +927,6 @@ namespace :gitlab do puts "" end - # Runs the given command - # - # Returns nil if the command was not found - # Returns the output of the command otherwise - # - # see also #run_and_match - def run(command) - unless `#{command} 2>/dev/null`.blank? - `#{command}` - end - end - - # Runs the given command and matches the output agains the given pattern - # - # Returns nil if nothing matched - # Retunrs the MatchData if the pattern matched - # - # see also #run - # see also String#match - def run_and_match(command, pattern) - run(command).try(:match, pattern) - end - def see_database_guide "doc/install/databases.md" end @@ -952,18 +948,4 @@ namespace :gitlab do puts " #{step}" end end - - def warn_user_is_not_gitlab - unless @warned_user_not_gitlab - current_user = run("whoami").chomp - unless current_user == "gitlab" - puts "#{Colored.color(:black)+Colored.color(:on_yellow)} Warning #{Colored.extra(:clear)}" - puts " You are running as user #{current_user.magenta}, we hope you know what you are doing." - puts " Some tests may pass\/fail for the wrong reason." - puts " For meaningful results you should run this as user #{"gitlab".magenta}." - puts "" - end - @warned_user_not_gitlab = true - end - end end diff --git a/lib/tasks/gitlab/cleanup.rake b/lib/tasks/gitlab/cleanup.rake new file mode 100644 index 0000000000000000000000000000000000000000..2a0ffe0f4bdf918e9d8bbeb06acf39b729c0a359 --- /dev/null +++ b/lib/tasks/gitlab/cleanup.rake @@ -0,0 +1,128 @@ +namespace :gitlab do + namespace :cleanup do + desc "GITLAB | Cleanup | Clean gitolite config" + task :config => :environment do + warn_user_is_not_gitlab + + real_repos = Project.all.map(&:path_with_namespace) + real_repos << "gitolite-admin" + real_repos << "@all" + + remove_flag = ENV['REMOVE'] + + puts "Looking for repositories to remove... " + Gitlab::GitoliteConfig.new.apply do |config| + all_repos = [] + garbage_repos = [] + + all_repos = config.conf.repos.keys + garbage_repos = all_repos - real_repos + + garbage_repos.each do |repo_name| + if remove_flag + config.conf.rm_repo(repo_name) + print "to remove...".red + end + + puts repo_name.red + end + end + + unless remove_flag + puts "To cleanup repositories run this command with REMOVE=true".yellow + end + end + + desc "GITLAB | Cleanup | Clean namespaces" + task :dirs => :environment do + warn_user_is_not_gitlab + remove_flag = ENV['REMOVE'] + + + namespaces = Namespace.pluck(:path) + git_base_path = Gitlab.config.gitolite.repos_path + all_dirs = Dir.glob(git_base_path + '/*') + + puts git_base_path.yellow + puts "Looking for directories to remove... " + + all_dirs.reject! do |dir| + # skip if git repo + dir =~ /.git$/ + end + + all_dirs.reject! do |dir| + dir_name = File.basename dir + + # skip if namespace present + namespaces.include?(dir_name) + end + + all_dirs.each do |dir_path| + + if remove_flag + if FileUtils.rm_rf dir_path + puts "Removed...#{dir_path}".red + else + puts "Cannot remove #{dir_path}".red + end + else + puts "Can be removed: #{dir_path}".red + end + end + + unless remove_flag + puts "To cleanup this directories run this command with REMOVE=true".yellow + end + end + + desc "GITLAB | Cleanup | Clean respositories" + task :repos => :environment do + warn_user_is_not_gitlab + remove_flag = ENV['REMOVE'] + + git_base_path = Gitlab.config.gitolite.repos_path + all_dirs = Dir.glob(git_base_path + '/*') + + global_projects = Project.where(namespace_id: nil).pluck(:path) + + puts git_base_path.yellow + puts "Looking for global repos to remove... " + + # skip non git repo + all_dirs.select! do |dir| + dir =~ /.git$/ + end + + # skip existing repos + all_dirs.reject! do |dir| + repo_name = File.basename dir + path = repo_name.gsub(/\.git$/, "") + global_projects.include?(path) + end + + # skip gitolite admin + all_dirs.reject! do |dir| + repo_name = File.basename dir + repo_name == 'gitolite-admin.git' + end + + + all_dirs.each do |dir_path| + if remove_flag + if FileUtils.rm_rf dir_path + puts "Removed...#{dir_path}".red + else + puts "Cannot remove #{dir_path}".red + end + else + puts "Can be removed: #{dir_path}".red + end + end + + unless remove_flag + puts "To cleanup this directories run this command with REMOVE=true".yellow + end + end + end +end diff --git a/lib/tasks/gitlab/enable_namespaces.rake b/lib/tasks/gitlab/enable_namespaces.rake index 1be9ba6469d29860c9a3f62df7002d25136fa0e1..ee80c0905cb4f41a88a677b94636032e0c16c141 100644 --- a/lib/tasks/gitlab/enable_namespaces.rake +++ b/lib/tasks/gitlab/enable_namespaces.rake @@ -1,34 +1,87 @@ namespace :gitlab do desc "GITLAB | Enable usernames and namespaces for user projects" task enable_namespaces: :environment do - print "\nUsernames for users:".yellow + warn_user_is_not_gitlab + migrate_user_namespaces + migrate_groups + migrate_projects + + puts "Rebuild Gitolite ... " + gitolite = Gitlab::Gitolite.new + gitolite.update_repositories(Project.where('namespace_id IS NOT NULL')) + puts "... #{"done".green}" + end + + def migrate_user_namespaces + puts "\nGenerate usernames for users without one: ".blue User.find_each(batch_size: 500) do |user| - next if user.namespace + if user.namespace + print '-'.cyan + next + end - User.transaction do - username = user.email.match(/^[^@]*/)[0] - if user.update_attributes!(username: username) + username = if user.username.present? + # if user already has username filled + user.username + else + build_username(user) + end + + begin + User.transaction do + user.update_attributes!(username: username) print '.'.green - else - print 'F'.red end + rescue + print 'F'.red end end + puts "\nDone" + end + + def build_username(user) + username = nil + + # generate username + username = user.email.match(/^[^@]*/)[0] + username.gsub!("+", ".") + + # return username if no mathes + return username unless User.find_by_username(username) + + # look for same username + (1..10).each do |i| + suffixed_username = "#{username}#{i}" + + return suffixed_username unless User.find_by_username(suffixed_username) + end + end - print "\n\nDirs for groups:".yellow + def migrate_groups + puts "\nCreate directories for groups: ".blue Group.find_each(batch_size: 500) do |group| - if group.ensure_dir_exist - print '.'.green - else + begin + if group.dir_exists? + print '-'.cyan + else + if group.ensure_dir_exist + print '.'.green + else + print 'F'.red + end + end + rescue print 'F'.red end end + puts "\nDone" + end - print "\n\nMove projects from groups under groups dirs:".yellow + def migrate_projects git_path = Gitlab.config.gitolite.repos_path - + puts "\nMove projects in groups into respective directories ... ".blue Project.where('namespace_id IS NOT NULL').find_each(batch_size: 500) do |project| next unless project.group @@ -59,9 +112,6 @@ namespace :gitlab do end end - print "\n\nRebuild gitolite:".yellow - gitolite = Gitlab::Gitolite.new - gitolite.update_repositories(Project.where('namespace_id IS NOT NULL')) - puts "\n" + puts "\nDone" end end diff --git a/lib/tasks/gitlab/info.rake b/lib/tasks/gitlab/info.rake index 85458fe2c43fdd53888671878d2a7afdb64c15f5..4b906684dcd206891f0a4a47c6e2b3ca3235b544 100644 --- a/lib/tasks/gitlab/info.rake +++ b/lib/tasks/gitlab/info.rake @@ -3,17 +3,6 @@ namespace :gitlab do desc "GITLAB | Show information about GitLab and its environment" task info: :environment do - # check which OS is running - os_name = run("lsb_release -irs") - os_name ||= if File.readable?('/etc/system-release') - File.read('/etc/system-release') - end - os_name ||= if File.readable?('/etc/debian_version') - debian_version = File.read('/etc/debian_version') - "Debian #{debian_version}" - end - os_name.squish! - # check if there is an RVM environment rvm_version = run_and_match("rvm --version", /[\d\.]+/).try(:to_s) # check Ruby version @@ -80,31 +69,5 @@ namespace :gitlab do puts "Git:\t\t#{Gitlab.config.git.bin_path}" end - - - # Helper methods - - # Runs the given command and matches the output agains the given pattern - # - # Returns nil if nothing matched - # Retunrs the MatchData if the pattern matched - # - # see also #run - # see also String#match - def run_and_match(command, regexp) - run(command).try(:match, regexp) - end - - # Runs the given command - # - # Returns nil if the command was not found - # Returns the output of the command otherwise - # - # see also #run_and_match - def run(command) - unless `#{command} 2>/dev/null`.blank? - `#{command}` - end - end end end diff --git a/lib/tasks/gitlab/task_helpers.rake b/lib/tasks/gitlab/task_helpers.rake new file mode 100644 index 0000000000000000000000000000000000000000..5dd97fa2f920ddc3288c9837858413c75d86ca55 --- /dev/null +++ b/lib/tasks/gitlab/task_helpers.rake @@ -0,0 +1,70 @@ +namespace :gitlab do + + # Check which OS is running + # + # It will primarily use lsb_relase to determine the OS. + # It has fallbacks to Debian, SuSE and OS X. + def os_name + os_name = run("lsb_release -irs") + os_name ||= if File.readable?('/etc/system-release') + File.read('/etc/system-release') + end + os_name ||= if File.readable?('/etc/debian_version') + debian_version = File.read('/etc/debian_version') + "Debian #{debian_version}" + end + os_name ||= if File.readable?('/etc/SuSE-release') + File.read('/etc/SuSE-release') + end + os_name ||= if os_x_version = run("sw_vers -productVersion") + "Mac OS X #{os_x_version}" + end + os_name.try(:squish!) + end + + # Runs the given command and matches the output agains the given pattern + # + # Returns nil if nothing matched + # Retunrs the MatchData if the pattern matched + # + # see also #run + # see also String#match + def run_and_match(command, regexp) + run(command).try(:match, regexp) + end + + # Runs the given command + # + # Returns nil if the command was not found + # Returns the output of the command otherwise + # + # see also #run_and_match + def run(command) + unless `#{command} 2>/dev/null`.blank? + `#{command}` + end + end + + def uid_for(user_name) + run("id -u #{user_name}").chomp.to_i + end + + def gid_for(group_name) + group_line = File.read("/etc/group").lines.select{|l| l.start_with?("#{group_name}:")}.first + group_line.split(":")[2].to_i + end + + def warn_user_is_not_gitlab + unless @warned_user_not_gitlab + current_user = run("whoami").chomp + unless current_user == "gitlab" + puts "#{Colored.color(:black)+Colored.color(:on_yellow)} Warning #{Colored.extra(:clear)}" + puts " You are running as user #{current_user.magenta}, we hope you know what you are doing." + puts " Things may work\/fail for the wrong reasons." + puts " For correct results you should run this as user #{"gitlab".magenta}." + puts "" + end + @warned_user_not_gitlab = true + end + end +end diff --git a/lib/tasks/resque.rake b/lib/tasks/resque.rake index 0825324a424812fcc902cbf9a4326856ed85332c..bf031403db8ef9209e9911eedfb4ae8a7cf9c4e3 100644 --- a/lib/tasks/resque.rake +++ b/lib/tasks/resque.rake @@ -4,6 +4,7 @@ task "resque:setup" => :environment do Resque.after_fork do Resque.redis.client.reconnect end + Resque.before_fork = Proc.new { ActiveRecord::Base.establish_connection } end desc "Alias for resque:work (To run workers on Heroku)"